Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorflavio <fdanesse@gmail.com>2012-12-04 18:18:11 (GMT)
committer flavio <fdanesse@gmail.com>2012-12-04 18:18:11 (GMT)
commite393db2c8fdee35ba472d5ce337585e18c29f61a (patch)
treec02f1bce422b11a21f504526f186a9b4e207bdfe
parent229786ba9aeeba958a878406a935d3f31bd9895b (diff)
The activity starts.
-rw-r--r--edit_app.py110
-rw-r--r--groupthink/gtk_tools.py89
-rw-r--r--groupthink/sugar_tools.py3
3 files changed, 134 insertions, 68 deletions
diff --git a/edit_app.py b/edit_app.py
index 7f08b09..12360a8 100644
--- a/edit_app.py
+++ b/edit_app.py
@@ -3,34 +3,29 @@ Written mostly by Nate Theis
Some GTK code borrowed from Pippy
'''
-from groupthink import sugar_tools, gtk_tools
-
+import time
from gettext import gettext as _
from gi.repository import Gtk
from gi.repository import Pango
-import time
from gi.repository import GtkSource
-from sugar3.activity import activity
-
-try: # Can use 'New' toolbar design?
- from sugar3.graphics.toolbarbox import ToolbarBox
- _HAVE_TOOLBOX = True
-except ImportError:
- _HAVE_TOOLBOX = False
-
-if _HAVE_TOOLBOX:
- from sugar3.activity.widgets import ActivityToolbarButton, StopButton
- from sugar3.graphics.toolbarbox import ToolbarButton
+from groupthink.sugar_tools import GroupActivity
+# Fixme: There is an error that I have not even given: TextBufferSharePoint
+#from groupthink.gtk_tools import TextBufferSharePoint
+from sugar3.activity import activity
+from sugar3.graphics.toolbarbox import ToolbarBox
+from sugar3.activity.widgets import ActivityToolbarButton
+from sugar3.activity.widgets import StopButton
+from sugar3.graphics.toolbarbox import ToolbarButton
from sugar3.graphics import style
-from sugar3.activity.activity import EditToolbar
+from sugar3.activity.widgets import EditToolbar
import mdnames
-class EditActivity(sugar_tools.GroupActivity):
+class EditActivity(GroupActivity):
'''A text editor for Sugar
pylint says I need a docstring. Here you go.
'''
@@ -57,12 +52,13 @@ class EditActivity(sugar_tools.GroupActivity):
self.buffer = GtkSource.Buffer()
self.refresh_buffer = False
- self.text_view = GtkSource.View(self.buffer)
+ self.text_view = GtkSource.View()
+ self.text_view.set_buffer(self.buffer)
self.scrollwindow = Gtk.ScrolledWindow()
- self.scrollwindow.add(self.text_view)
+ self.scrollwindow.add_with_viewport(self.text_view)
- sugar_tools.GroupActivity.__init__(self, handle)
+ GroupActivity.__init__(self, handle)
def fix_mimetype(self):
'''We must have a mimetype. Sometimes, we don't (when we get launched
@@ -73,68 +69,60 @@ class EditActivity(sugar_tools.GroupActivity):
def setup_toolbar(self):
'''Setup the top toolbar. Groupthink needs some work here.'''
+
+ toolbox = ToolbarBox()
+
+ activity_button = ActivityToolbarButton(self)
+ toolbox.toolbar.insert(activity_button, 0)
+ activity_button.show()
+
+ self.set_toolbar_box(toolbox)
+ toolbox.show()
+ toolbar = toolbox.toolbar
- if _HAVE_TOOLBOX: # 'New' Sugar toolbar design
- toolbox = ToolbarBox()
-
- activity_button = ActivityToolbarButton(self)
- toolbox.toolbar.insert(activity_button, 0)
- activity_button.show()
-
- self.set_toolbar_box(toolbox)
- toolbox.show()
- toolbar = toolbox.toolbar
-
- self.edit_toolbar = EditToolbar()
- edit_toolbar_button = ToolbarButton(
- page=self.edit_toolbar,
- icon_name='toolbar-edit')
- self.edit_toolbar.show()
- toolbar.insert(edit_toolbar_button, -1)
- edit_toolbar_button.show()
-
- else: # 'Old' Sugar toolbar design
- self.edit_toolbar = EditToolbar()
- toolbox = activity.ActivityToolbox(self)
- self.set_toolbox(toolbox)
- toolbox.add_toolbar(_('Edit'), self.edit_toolbar)
- toolbox.show()
- toolbox.set_current_toolbar(1)
- toolbar = self.edit_toolbar
+ self.edit_toolbar = EditToolbar()
+ edit_toolbar_button = ToolbarButton(
+ page=self.edit_toolbar,
+ icon_name='toolbar-edit')
+ self.edit_toolbar.show()
+ toolbar.insert(edit_toolbar_button, -1)
+ edit_toolbar_button.show()
self.edit_toolbar.undo.connect('clicked', self.undobutton_cb)
self.edit_toolbar.redo.connect('clicked', self.redobutton_cb)
self.edit_toolbar.copy.connect('clicked', self.copybutton_cb)
self.edit_toolbar.paste.connect('clicked', self.pastebutton_cb)
-
- if _HAVE_TOOLBOX:
- separator = Gtk.SeparatorToolItem()
- separator.props.draw = False
- separator.set_expand(True)
- toolbar.insert(separator, -1)
- separator.show()
-
- stop_button = StopButton(self)
- stop_button.props.accelerator = '<Ctrl>q'
- toolbox.toolbar.insert(stop_button, -1)
- stop_button.show()
+
+ separator = Gtk.SeparatorToolItem()
+ separator.props.draw = False
+ separator.set_expand(True)
+ toolbar.insert(separator, -1)
+ separator.show()
+
+ stop_button = StopButton(self)
+ stop_button.props.accelerator = '<Ctrl>q'
+ toolbox.toolbar.insert(stop_button, -1)
+ stop_button.show()
def initialize_display(self):
'''Set up GTK and friends'''
self.fix_mimetype()
-
- self.cloud.shared_buffer = gtk_tools.TextBufferSharePoint(self.buffer)
+ # Fixme: There is an error that I have not even given: TextBufferSharePoint
+ #self.cloud.shared_buffer = TextBufferSharePoint(self.buffer)
self.setup_toolbar()
#Some graphics code borrowed from Pippy
lang_manager = GtkSource.LanguageManager.get_default()
+
if hasattr(lang_manager, 'list_languages'):
langs = lang_manager.list_languages()
+
else:
lang_ids = lang_manager.get_language_ids()
langs = [lang_manager.get_language(lang_id) \
for lang_id in lang_ids]
+
for lang in langs:
for mtype in lang.get_mime_types():
if mtype == self.metadata[mdnames.mimetype_md]:
@@ -149,9 +137,11 @@ class EditActivity(sugar_tools.GroupActivity):
self.text_view.set_wrap_mode(Gtk.WrapMode.WORD)
font = Pango.FontDescription("Bitstream Vera Sans " +
str(style.FONT_SIZE))
+
else:
if hasattr(self.buffer, 'set_highlight'):
self.buffer.set_highlight(True)
+
else:
self.buffer.set_highlight_syntax(True)
diff --git a/groupthink/gtk_tools.py b/groupthink/gtk_tools.py
index c88d27e..938c7a0 100644
--- a/groupthink/gtk_tools.py
+++ b/groupthink/gtk_tools.py
@@ -1,3 +1,4 @@
+import gi
from gi.repository import Gtk
import groupthink_base as groupthink
import logging
@@ -6,8 +7,11 @@ import stringtree
class RecentEntry(groupthink.UnorderedHandlerAcceptor, Gtk.Entry):
"""RecentEntry is an extension of gtk.Entry that, when attached to a group,
creates a unified Entry field for all participants"""
- def __init__(self, *args, **kargs):
- Gtk.Entry.__init__(self, *args, **kargs)
+
+ def __init__(self):
+
+ Gtk.Entry.__init__(self)
+
self.logger = logging.getLogger('RecentEntry')
self.add_events(Gdk.EventMask.PROPERTY_CHANGE_MASK)
self._text_changed_handler = self.connect('changed', self._local_change_cb)
@@ -23,7 +27,9 @@ class RecentEntry(groupthink.UnorderedHandlerAcceptor, Gtk.Entry):
self._recent.set_handler(handler)
def _remote_change_cb(self, text):
+
self.logger.debug("_remote_change_cb(%s)" % text)
+
if self.get_text() != text:
#The following code will break if running in any thread other than
#the main thread. I do not know how to make code that works with
@@ -33,11 +39,15 @@ class RecentEntry(groupthink.UnorderedHandlerAcceptor, Gtk.Entry):
self.handler_unblock(self._text_changed_handler)
class SharedTreeStore(groupthink.CausalHandlerAcceptor, Gtk.TreeModel):
+
def __init__(self, columntypes=(), translators=()):
+
self._columntypes = columntypes
self._causaltree = groupthink.CausalTree()
+
if len(translators) != 0 and len(translators) != len(columntypes):
raise #Error: translators must be empty or match columntypes in length
+
if len(translators) == len(self._columntypes):
self._columndicts = [groupthink.CausalDict(
key_translator = self._causaltree.node_trans,
@@ -47,12 +57,16 @@ class SharedTreeStore(groupthink.CausalHandlerAcceptor, Gtk.TreeModel):
self._columndicts = [groupthink.CausalDict(
key_translator = self._causaltree.node_trans)
for i in xrange(len(translators))]
+
self._causaltree.register_listener(self._tree_listener)
+
for i in xrange(len(self._columndicts)):
self._columndicts[i].register_listener(self._generate_dictlistener(i))
def set_handler(self, handler):
+
self._causaltree.set_handler(handler)
+
for i in xrange(len(self._columndicts)):
#Make a new handler for each columndict
#Not very future-proof: how do we serialize out and reconstitute
@@ -63,7 +77,7 @@ class SharedTreeStore(groupthink.CausalHandlerAcceptor, Gtk.TreeModel):
### Methods necessary to implement gtk.GenericTreeModel ###
def on_get_flags(self):
- return Gtk.TREE_MODEL_ITERS_PERSIST
+ return Gtk.TreeModelFlags.ITERS_PERSIST
def on_get_n_columns(self):
return len(self._columntypes)
@@ -72,19 +86,26 @@ class SharedTreeStore(groupthink.CausalHandlerAcceptor, Gtk.TreeModel):
return self._columntypes[index]
def on_get_iter(self, path):
+
node = self._causaltree.ROOT
+
for k in path:
c = list(self._causaltree.get_children(node))
+
if len(c) <= k:
return None #Invalid path
+
else:
c.sort()
node = c[k]
+
return node
def on_get_path(self, rowref):
+
revpath = []
node = rowref
+
if rowref in self._causaltree:
while node != self._causaltree.ROOT:
p = self._causaltree.get_parent(node)
@@ -92,29 +113,38 @@ class SharedTreeStore(groupthink.CausalHandlerAcceptor, Gtk.TreeModel):
c.sort()
revpath.append(c.index(node)) # could be done "faster" using bisect
node = p
+
return tuple(revpath[::-1])
+
else:
return None
-
+
def on_get_value(self, rowref, column):
return self._columndicts[column][rowref]
def on_iter_next(self, rowref):
+
p = self._causaltree.get_parent(rowref)
c = list(self._causaltree.get_children(p))
c.sort()
i = c.index(rowref) + 1
+
if i < len(c):
return c[i]
+
else:
return None
def on_iter_children(self, parent):
+
if parent is None:
parent = self._causaltree.ROOT
+
c = self._causaltree.get_children(parent)
+
if len(c) > 0:
return min(c)
+
else:
return None
@@ -125,39 +155,50 @@ class SharedTreeStore(groupthink.CausalHandlerAcceptor, Gtk.TreeModel):
return len(self._causaltree.get_children(rowref))
def on_iter_nth_child(self, parent, n):
+
if parent is None:
parent = self._causaltree.ROOT
+
c = self._causaltree.get_children(parent)
+
if len(c) > n:
c = list(c)
c.sort()
return c[n]
+
else:
return None
-
+
def on_iter_parent(self, child):
+
p = self._causaltree.get_parent(child)
if p == self._causaltree.ROOT:
return None
+
else:
return p
### Methods for passing changes from remote users ###
def _dict_listener(self, i, added, removed):
+
s = set()
s.update(added.keys())
s.update(removed.keys())
+
for node in s:
path = self.on_get_path(node)
if path is not None:
it = self.create_tree_iter(node)
self.row_changed(path, it)
+
self.emit('changed')
def _generate_dict_listener(self, i):
+
def temp(added,removed):
self._dict_listener(i,added,removed)
+
return temp
def _tree_listener(self, forward, reverse):
@@ -183,8 +224,10 @@ class SharedTreeStore(groupthink.CausalHandlerAcceptor, Gtk.TreeModel):
inserted.add(cmd[1])
else:
unknown_change = True
+
for cmd in reverse:
clean = True
+
if cmd[0] == self._causaltree.SET_PARENT:
if (clean and
cmd[2] in self._causaltree and
@@ -205,18 +248,22 @@ class SharedTreeStore(groupthink.CausalHandlerAcceptor, Gtk.TreeModel):
self.row_deleted(p)
else:
unknown_change = True
+
if unknown_change:
self.emit('unknown-change')
+
for node in inserted:
path = self.on_get_path(node)
if path is not None:
it = self.create_tree_iter(node)
self.row_inserted(path, it)
+
for node in haschild:
path = self.on_get_path(node)
if path is not None:
it = self.create_tree_iter(node)
self.row_has_child_toggled(path, it)
+
self.emit('changed')
### Methods for resembling gtk.TreeStore ###
@@ -225,7 +272,7 @@ class SharedTreeStore(groupthink.CausalHandlerAcceptor, Gtk.TreeModel):
node = self.get_user_data(it)
self._columndicts[i][node] = value
- def set(self, it, *args):
+ def set(self, it):
for i in xrange(0,len(args),2):
self.set_value(it,args[i],args[i+1])
@@ -237,41 +284,56 @@ class SharedTreeStore(groupthink.CausalHandlerAcceptor, Gtk.TreeModel):
del d[node]
def append(self, parent, row=None):
+
if parent is not None:
node = self.get_user_data(it)
+
else:
node = self._causaltree.ROOT
+
node = self._causaltree.new_child(node)
+
if row is not None:
if len(row) != len(columndicts):
raise IndexError("row had the wrong length")
+
else:
for i in xrange(len(row)):
self._columndicts[i][node] = row[i]
+
return self.create_tree_iter(node)
def is_ancestor(self, it, descendant):
+
node = self.get_user_data(it)
d = self.get_user_data(descendant)
d = self._causaltree.get_parent(d)
+
while d != self._causaltree.ROOT:
if d == node:
return True
+
else:
d = self._causaltree.get_parent(d)
+
return False
def iter_depth(self, it):
+
node = self.get_user_data(it)
i = 0
node = self._causaltree.get_parent(node)
+
while node != self._causaltree.ROOT:
i = i + 1
node = self._causaltree.get_parent(node)
+
return i
def clear(self):
+
self._causaltree.clear()
+
for d in self._columndicts:
d.clear()
@@ -281,12 +343,15 @@ class SharedTreeStore(groupthink.CausalHandlerAcceptor, Gtk.TreeModel):
### Additional Methods ###
def move(self, it, newparent):
+
node = self.get_user_data(row)
p = self.get_user_data(newparent)
self._causaltree.change_parent(node,p)
class TextBufferUnorderedStringLinker:
+
def __init__(self,tb,us):
+
self._tb = tb
self._us = us
self._us.register_listener(self._netupdate_cb)
@@ -295,34 +360,42 @@ class TextBufferUnorderedStringLinker:
self._logger = logging.getLogger('the Linker')
def _insert_cb(self, tb, itr, text, length):
+
self._logger.debug('user insert: %s' % text)
pos = itr.get_offset()
self._us.insert(text,pos)
def _delete_cb(self, tb, start_itr, end_itr):
+
self._logger.debug('user delete')
k = start_itr.get_offset()
n = end_itr.get_offset()-k
self._us.delete(k,n)
def _netupdate_cb(self, edits):
+
self._logger.debug('update from network: %s' % str(edits))
self._tb.handler_block(self._insert_handler)
self._tb.handler_block(self._delete_handler)
+
for e in edits:
if isinstance(e, stringtree.Insertion):
itr = self._tb.get_iter_at_offset(e.position)
self._tb.insert(itr, e.text)
+
elif isinstance(e, stringtree.Deletion):
itr1 = self._tb.get_iter_at_offset(e.position)
itr2 = self._tb.get_iter_at_offset(e.position + e.length)
self._tb.delete(itr1,itr2)
+
self._tb.handler_unblock(self._insert_handler)
self._tb.handler_unblock(self._delete_handler)
class TextBufferSharePoint(groupthink.UnorderedHandlerAcceptor):
+
def __init__(self, buff):
+
self._us = groupthink.UnorderedString(buff.get_text(buff.get_start_iter(), buff.get_end_iter()))
self._linker = TextBufferUnorderedStringLinker(buff, self._us)
@@ -330,8 +403,10 @@ class TextBufferSharePoint(groupthink.UnorderedHandlerAcceptor):
self._us.set_handler(handler)
class SharedTextView(groupthink.UnorderedHandlerAcceptor, Gtk.TextView):
+
def __init__(self, *args, **kargs):
- Gtk.TextView.__init__(self, *args, **kargs)
+
+ Gtk.TextView.__init__(self)
self._link = TextBufferSharePoint(self.get_buffer())
def set_handler(self, handler):
diff --git a/groupthink/sugar_tools.py b/groupthink/sugar_tools.py
index 14a8cee..fdd4d98 100644
--- a/groupthink/sugar_tools.py
+++ b/groupthink/sugar_tools.py
@@ -26,6 +26,7 @@ from sugar3.presence.tubeconn import TubeConnection
from sugar3.graphics.window import Window
from gi.repository import Gtk
+from gi.repository import Gdk
from gi.repository import GObject
import groupthink_base as groupthink
@@ -72,7 +73,7 @@ class GroupActivity(Activity):
# top toolbar with share and close buttons:
toolbox = ToolbarBox(self)
- self.set_toolbox(toolbox)
+ self.toolbox = toolbox
toolbox.show()
v = Gtk.VBox()