diff options
-rw-r--r-- | AbiWordActivity.py | 204 | ||||
-rw-r--r-- | toolbar.py | 35 |
2 files changed, 229 insertions, 10 deletions
diff --git a/AbiWordActivity.py b/AbiWordActivity.py index ec950a3..1c06878 100644 --- a/AbiWordActivity.py +++ b/AbiWordActivity.py @@ -15,28 +15,37 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + from gettext import gettext as _ import logging import os import time +import dbus import gtk +import telepathy +import telepathy.client -from sugar.activity import activity -from abiword import Canvas +from sugar.activity.activity import Activity, ActivityToolbox, EditToolbar + +from sugar.presence import presenceservice +#from buddiespanel import BuddiesPanel +from abiword import Canvas from toolbar import TextToolbar, ImageToolbar, TableToolbar, ViewToolbar -class AbiWordActivity (activity.Activity): +logger = logging.getLogger('write-activity') + +class AbiWordActivity (Activity): def __init__ (self, handle): - activity.Activity.__init__ (self, handle) + Activity.__init__ (self, handle) self.set_title ("Write") # abiword uses the current directory for all its file dialogs os.chdir(os.path.expanduser('~')) - toolbox = activity.ActivityToolbox(self) + toolbox = ActivityToolbox(self) self.set_toolbox(toolbox) toolbox.show() @@ -48,7 +57,7 @@ class AbiWordActivity (activity.Activity): self.abiword_canvas.connect("can-undo", self._can_undo_cb) self.abiword_canvas.connect("can-redo", self._can_redo_cb) - self._edit_toolbar = activity.EditToolbar() + self._edit_toolbar = EditToolbar() self._edit_toolbar.undo.set_sensitive(False) self._edit_toolbar.undo.connect('clicked', self._undo_cb) @@ -76,18 +85,193 @@ class AbiWordActivity (activity.Activity): view_toolbar.show() self.set_canvas(self.abiword_canvas) - - # FIXME: we need to load_file('') before show(), why? - self.abiword_canvas.load_file('') self.abiword_canvas.show() if not self.jobject['title']: self.jobject['title'] = _('Text document') - + + self.abiword_canvas.connect('map', self._map_cb) + + def _map_cb(self, activity): + logger.debug('_map_cb') + # FIXME: this should be called by activity.Activity on realize if self.jobject.file_path: self.read_file() + # activity sharing + pservice = presenceservice.get_instance() + + bus = dbus.Bus() + name, path = pservice.get_preferred_connection() + self.conn = telepathy.client.Connection(name, path) + self.initiating = None + self.joined = False + + self.connect('shared', self._shared_cb) + + if self._shared_activity: + # we are joining the activity + print "We are joining an activity" + self.connect('joined', self._joined_cb) + self._shared_activity.connect('buddy-joined', self._buddy_joined_cb) + self._shared_activity.connect('buddy-left', self._buddy_left_cb) + if self.get_shared(): +# # oh, OK, we've already joined + self._joined_cb() + else: + # we are creating the activity + print "We are creating an activity" + + owner = pservice.get_owner() + + + def _shared_cb(self, activity): + logger.debug('My Write activity was shared') + self.initiating = True + self._setup() + + self._shared_activity.connect('buddy-joined', self._buddy_joined_cb) + self._shared_activity.connect('buddy-left', self._buddy_left_cb) + + logger.debug('This is my activity: offering a tube...') + id = self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].OfferTube( + telepathy.TUBE_TYPE_DBUS, "com.abisource.abiword.abicollab", {}) + logger.debug('Tube address: %s', self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].GetDBusServerAddress(id)) + + def _setup(self): + logger.debug("_setup()") + + if self._shared_activity is None: + logger.error('Failed to share or join activity') + return + + bus_name, conn_path, channel_paths = self._shared_activity.get_channels() + + # Work out what our room is called and whether we have Tubes already + room = None + tubes_chan = None + text_chan = None + for channel_path in channel_paths: + channel = telepathy.client.Channel(bus_name, channel_path) + htype, handle = channel.GetHandle() + if htype == telepathy.HANDLE_TYPE_ROOM: + logger.debug('Found our room: it has handle#%d "%s"', + handle, self.conn.InspectHandles(htype, [handle])[0]) + room = handle + ctype = channel.GetChannelType() + if ctype == telepathy.CHANNEL_TYPE_TUBES: + logger.debug('Found our Tubes channel at %s', channel_path) + tubes_chan = channel + elif ctype == telepathy.CHANNEL_TYPE_TEXT: + logger.debug('Found our Text channel at %s', channel_path) + text_chan = channel + + if room is None: + logger.error("Presence service didn't create a room") + return + if text_chan is None: + logger.error("Presence service didn't create a text channel") + return + + # Make sure we have a Tubes channel - PS doesn't yet provide one + if tubes_chan is None: + logger.debug("Didn't find our Tubes negotation channel, requesting one...") + tubes_chan = self.conn.request_channel(telepathy.CHANNEL_TYPE_TUBES, + telepathy.HANDLE_TYPE_ROOM, room, True) + logger.debug("Got our tubes negotiation channel") + + self.tubes_chan = tubes_chan + self.text_chan = text_chan + + tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal('NewTube', + self._new_tube_cb) + + def _list_tubes_reply_cb(self, tubes): + for tube_info in tubes: + self._new_tube_cb(*tube_info) + + def _list_tubes_error_cb(self, e): + logger.error('ListTubes() failed: %s', e) + + def _joined_cb(self, activity): + logger.debug("_joined_cb()") + if not self._shared_activity: + return + + self.joined = True + logger.debug('Joined an existing Write session') + self._setup() + + logger.debug('This is not my activity: waiting for a tube...') + self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].ListTubes( + reply_handler=self._list_tubes_reply_cb, + error_handler=self._list_tubes_error_cb) + + def _new_tube_cb(self, id, initiator, type, service, params, state): + logger.debug('New tube: ID=%d initiator=%d type=%d service=%s ' + 'params=%r state=%d', id, initiator, type, service, + params, state) + + if (type == telepathy.TUBE_TYPE_DBUS and + service == "com.abisource.abiword.abicollab"): + if state == telepathy.TUBE_STATE_LOCAL_PENDING: + self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].AcceptTube(id) + + initiator_path = None; + contacts = self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].GetDBusNames(id) + print 'dbus contact mapping',self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].GetDBusNames(id) + for i, struct in enumerate(contacts): + print 'mapping i',i + handle, path = struct + if handle == initiator: + print 'found initiator dbus path:',path + initiator_path = path + break; + + if initiator_path is None: + logger.error('Unable to get the dbus path of the tube initiator') + else: + # pass this tube to abicollab + address = self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].GetDBusServerAddress(id) + if self.joined: + print 'Passing tube address to abicollab (join)', address + self.abiword_canvas.invoke_cmd('com.abisource.abiword.abicollab.olpc.joinTube', address, 0, 0) + if initiator_path is not None: + logger.debug('Adding the initiator to the session: %s', initiator_path) + self.abiword_canvas.invoke_cmd('com.abisource.abiword.abicollab.olpc.buddyJoined', initiator_path, 0, 0) + else: + logger.debug('Passing tube address to abicollab (offer): %s', address) + self.abiword_canvas.invoke_cmd('com.abisource.abiword.abicollab.olpc.offerTube', address, 0, 0) + + self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal('DBusNamesChanged', + self._on_dbus_names_changed) + + def _on_dbus_names_changed(self, tube_id, added, removed): + logger.debug('_on_dbus_names_changed') +# if tube_id == self.tube_id: + for handle, bus_name in added: + logger.debug('added handle: %s, with dbus_name: %s', handle, bus_name) + self.abiword_canvas.invoke_cmd('com.abisource.abiword.abicollab.olpc.buddyJoined', bus_name, 0, 0) + +# if handle == self.self_handle: + # I've just joined - set my unique name +# print 'i\'ve just joined' +# self.set_unique_name(bus_name) +# self.participants[handle] = bus_name +# self.bus_name_to_handle[bus_name] = handle + + for handle, bus_name in removed: + logger.debug('removed handle: %s, with dbus name: %s', handle, bus_name) + + def _buddy_joined_cb (self, activity, buddy): + print 'buddy joined with object path: %s',buddy.object_path() +# self.abiword_canvas.invoke_cmd('com.abisource.abiword.abicollab.olpc.buddyJoined', buddy.object_path(), 0, 0) + + def _buddy_left_cb (self, activity, buddy): + logger.debug('buddy left with object path: %s', buddy.object_path()) + self.abiword_canvas.invoke_cmd('com.abisource.abiword.abicollab.olpc.buddyLeft', buddy.object_path(), 0, 0) + def read_file(self): logging.debug('AbiWordActivity.read_file') self.abiword_canvas.load_file('file://' + self.jobject.file_path) @@ -296,6 +296,23 @@ class ViewToolbar(gtk.Toolbar): self.insert(tool_item_zoom, -1) tool_item_zoom.show() + separator = gtk.SeparatorToolItem() + separator.set_draw(True) + self.insert(separator, -1) + + self._page_spin_adj = gtk.Adjustment(0, 1, 0, 1, 1, 0) + self._page_spin = gtk.SpinButton(self._page_spin_adj, 0, 0) + self._page_spin_id = self._page_spin.connect('value-changed', self._page_spin_cb) + self._page_spin.set_numeric(True) + self._page_spin.show() + tool_item_page = gtk.ToolItem() + tool_item_page.add(self._page_spin) + self.insert(tool_item_page, -1) + tool_item_page.show() + + self._abiword_canvas.connect("page-count", self._page_count_cb) + self._abiword_canvas.connect("current-page", self._current_page_cb) + def set_zoom_percentage(self, zoom): self._zoom_percentage = zoom #print 'new zoom percentage:',self._zoom_percentage @@ -319,3 +336,21 @@ class ViewToolbar(gtk.Toolbar): self._zoom_percentage = self._zoom_spin.get_value_as_int() self._abiword_canvas.set_zoom_percentage(self._zoom_percentage) + def _page_spin_cb(self, button): + print "page spin" + self._page_num = self._page_spin.get_value_as_int() +# TODO + + def _page_count_cb(self, canvas, count): + print "page count:",count + current_page = canvas.get_current_page_num() + self._page_spin_adj.set_all(current_page, 1, count, 1, 1, 0) + + def _current_page_cb(self, canvas, num): + print "current page:",num + self._page_spin.handler_block(self._page_spin_id) + try: + self._page_spin.set_value(num) + finally: + self._page_spin.handler_unblock(self._page_spin_id) + |