diff options
Diffstat (limited to 'src/jarabe/frame/activitiestray.py')
-rw-r--r-- | src/jarabe/frame/activitiestray.py | 308 |
1 files changed, 98 insertions, 210 deletions
diff --git a/src/jarabe/frame/activitiestray.py b/src/jarabe/frame/activitiestray.py index b5762ee..6e08fc0 100644 --- a/src/jarabe/frame/activitiestray.py +++ b/src/jarabe/frame/activitiestray.py @@ -1,5 +1,6 @@ # Copyright (C) 2006-2007 Red Hat, Inc. # Copyright (C) 2008 One Laptop Per Child +# Copyright (C) 2010 Collabora Ltd. <http://www.collabora.co.uk/> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -33,20 +34,16 @@ from sugar.graphics.toolbutton import ToolButton from sugar.graphics.icon import Icon, get_icon_file_name from sugar.graphics.palette import Palette, WidgetInvoker from sugar.graphics.menuitem import MenuItem -from sugar.activity.activityhandle import ActivityHandle -from sugar.activity import activityfactory from sugar.datastore import datastore from sugar import mime from sugar import env from jarabe.model import shell -from jarabe.model import neighborhood -from jarabe.model import owner +from jarabe.model import invites from jarabe.model import bundleregistry from jarabe.model import filetransfer from jarabe.view.palettes import JournalPalette, CurrentActivityPalette from jarabe.view.pulsingicon import PulsingIcon -from jarabe.view import launcher from jarabe.frame.frameinvoker import FrameWidgetInvoker from jarabe.frame.notification import NotificationIcon import jarabe.frame @@ -59,6 +56,7 @@ class ActivityButton(RadioToolButton): self.set_palette_invoker(FrameWidgetInvoker(self)) self._home_activity = home_activity + self._notify_launch_hid = None self._icon = PulsingIcon() self._icon.props.base_color = home_activity.get_icon_color() @@ -72,13 +70,12 @@ class ActivityButton(RadioToolButton): self.set_icon_widget(self._icon) self._icon.show() - if home_activity.props.launching: + if home_activity.props.launch_status == shell.Activity.LAUNCHING: self._icon.props.pulsing = True - self._notify_launching_hid = home_activity.connect( \ - 'notify::launching', self.__notify_launching_cb) - else: - self._notify_launching_hid = None - self._notif_icon = None + self._notify_launch_hid = home_activity.connect( \ + 'notify::launch-status', self.__notify_launch_status_cb) + elif home_activity.props.launch_status == shell.Activity.LAUNCH_FAILED: + self._on_failed_launch() def create_palette(self): if self._home_activity.is_journal(): @@ -88,26 +85,64 @@ class ActivityButton(RadioToolButton): palette.set_group_id('frame') self.set_palette(palette) - def __notify_launching_cb(self, home_activity, pspec): - if not home_activity.props.launching: + def _on_failed_launch(self): + # TODO http://bugs.sugarlabs.org/ticket/2007 + pass + + def __notify_launch_status_cb(self, home_activity, pspec): + home_activity.disconnect(self._notify_launch_hid) + self._notify_launch_hid = None + if home_activity.props.launch_status == shell.Activity.LAUNCH_FAILED: + self._on_failed_launch() + else: self._icon.props.pulsing = False - home_activity.disconnect(self._notify_launching_hid) -class BaseInviteButton(ToolButton): + +class InviteButton(ToolButton): + """Invite to shared activity""" def __init__(self, invite): ToolButton.__init__(self) + self._invite = invite + self.connect('clicked', self.__clicked_cb) + self.connect('destroy', self.__destroy_cb) + + bundle_registry = bundleregistry.get_registry() + bundle = bundle_registry.get_bundle(invite.get_bundle_id()) + self._icon = Icon() + self._icon.props.xo_color = invite.get_color() + if bundle is not None: + self._icon.props.file = bundle.get_icon() + else: + self._icon.props.icon_name = 'image-missing' self.set_icon_widget(self._icon) self._icon.show() - self.connect('clicked', self.__clicked_cb) - self.connect('destroy', self.__destroy_cb) + palette = InvitePalette(invite) + palette.props.invoker = FrameWidgetInvoker(self) + palette.set_group_id('frame') + self.set_palette(palette) + self._notif_icon = NotificationIcon() self._notif_icon.connect('button-release-event', self.__button_release_event_cb) + self._notif_icon.props.xo_color = invite.get_color() + if bundle is not None: + self._notif_icon.props.icon_filename = bundle.get_icon() + else: + self._notif_icon.props.icon_name = 'image-missing' + + palette = InvitePalette(invite) + palette.props.invoker = WidgetInvoker(self._notif_icon) + palette.set_group_id('frame') + self._notif_icon.palette = palette + + frame = jarabe.frame.get_view() + frame.add_notification(self._notif_icon, gtk.CORNER_TOP_LEFT) + def __button_release_event_cb(self, icon, event): self.emit('clicked') @@ -118,118 +153,23 @@ class BaseInviteButton(ToolButton): self._notif_icon = None self._launch() - def _launch(self): - """Launch the target of the invite""" - raise NotImplementedError - def __destroy_cb(self, button): frame = jarabe.frame.get_view() frame.remove_notification(self._notif_icon) -class ActivityInviteButton(BaseInviteButton): - """Invite to shared activity""" - def __init__(self, invite): - BaseInviteButton.__init__(self, invite) - mesh = neighborhood.get_model() - activity_model = mesh.get_activity(invite.get_activity_id()) - self._activity_model = activity_model - self._bundle_id = activity_model.get_bundle_id() - - self._icon.props.xo_color = activity_model.get_color() - if activity_model.get_icon_name(): - self._icon.props.file = activity_model.get_icon_name() - else: - self._icon.props.icon_name = 'image-missing' - - palette = ActivityInvitePalette(invite) - palette.props.invoker = FrameWidgetInvoker(self) - palette.set_group_id('frame') - self.set_palette(palette) - - self._notif_icon.props.xo_color = activity_model.get_color() - if activity_model.get_icon_name(): - icon_name = activity_model.get_icon_name() - self._notif_icon.props.icon_filename = icon_name - else: - self._notif_icon.props.icon_name = 'image-missing' - - palette = ActivityInvitePalette(invite) - palette.props.invoker = WidgetInvoker(self._notif_icon) - palette.set_group_id('frame') - self._notif_icon.palette = palette - - frame = jarabe.frame.get_view() - frame.add_notification(self._notif_icon, - gtk.CORNER_TOP_LEFT) - def _launch(self): """Join the activity in the invite.""" + self._invite.join() - shell_model = shell.get_model() - activity = shell_model.get_activity_by_id(self._activity_model.get_id()) - if activity: - activity.get_window().activate(gtk.get_current_event_time()) - return - - registry = bundleregistry.get_registry() - bundle = registry.get_bundle(self._bundle_id) - - launcher.add_launcher(self._activity_model.get_id(), - bundle.get_icon(), - self._activity_model.get_color()) - handle = ActivityHandle(self._activity_model.get_id()) - activityfactory.create(bundle, handle) +class InvitePalette(Palette): + """Palette for frame or notification icon for invites.""" -class PrivateInviteButton(BaseInviteButton): - """Invite to a private one to one channel""" def __init__(self, invite): - BaseInviteButton.__init__(self, invite) - self._private_channel = invite.get_private_channel() - self._bundle_id = invite.get_bundle_id() - - client = gconf.client_get_default() - color = XoColor(client.get_string('/desktop/sugar/user/color')) - - self._icon.props.xo_color = color - registry = bundleregistry.get_registry() - self._bundle = registry.get_bundle(self._bundle_id) - - if self._bundle: - self._icon.props.file = self._bundle.get_icon() - else: - self._icon.props.icon_name = 'image-missing' - - palette = PrivateInvitePalette(invite) - palette.props.invoker = FrameWidgetInvoker(self) - palette.set_group_id('frame') - self.set_palette(palette) - - self._notif_icon.props.xo_color = color - - if self._bundle: - self._notif_icon.props.icon_filename = self._bundle.get_icon() - else: - self._notif_icon.props.icon_name = 'image-missing' - - palette = PrivateInvitePalette(invite) - palette.props.invoker = WidgetInvoker(self._notif_icon) - palette.set_group_id('frame') - self._notif_icon.palette = palette - - frame = jarabe.frame.get_view() - frame.add_notification(self._notif_icon, - gtk.CORNER_TOP_LEFT) - - def _launch(self): - """Start the activity with private channel.""" - activityfactory.create_with_uri(self._bundle, self._private_channel) - -class BaseInvitePalette(Palette): - """Palette for frame or notification icon for invites.""" - def __init__(self): Palette.__init__(self, '') + self._invite = invite + menu_item = MenuItem(_('Join'), icon_name='dialog-ok') menu_item.connect('activate', self.__join_activate_cb) self.menu.append(menu_item) @@ -240,72 +180,22 @@ class BaseInvitePalette(Palette): self.menu.append(menu_item) menu_item.show() - def __join_activate_cb(self, menu_item): - self._join() - - def __decline_activate_cb(self, menu_item): - self._decline() - - def _join(self): - raise NotImplementedError - - def _decline(self): - raise NotImplementedError - - -class ActivityInvitePalette(BaseInvitePalette): - """Palette for shared activity invites.""" - - def __init__(self, invite): - BaseInvitePalette.__init__(self) - - mesh = neighborhood.get_model() - activity_model = mesh.get_activity(invite.get_activity_id()) - self._activity_model = activity_model - self._bundle_id = activity_model.get_bundle_id() + bundle_id = invite.get_bundle_id() registry = bundleregistry.get_registry() - self._bundle = registry.get_bundle(self._bundle_id) + self._bundle = registry.get_bundle(bundle_id) if self._bundle: self.set_primary_text(self._bundle.get_name()) else: - self.set_primary_text(self._bundle_id) + self.set_primary_text(bundle_id) - def _join(self): - handle = ActivityHandle(self._activity_model.get_id()) - activityfactory.create(self._bundle, handle) + def __join_activate_cb(self, menu_item): + self._invite.join() - def _decline(self): - invites = owner.get_model().get_invites() + def __decline_activate_cb(self, menu_item): + invites_model = invites.get_instance() activity_id = self._activity_model.get_id() - invites.remove_activity(activity_id) - - -class PrivateInvitePalette(BaseInvitePalette): - """Palette for private channel invites.""" - - def __init__(self, invite): - BaseInvitePalette.__init__(self) - - self._private_channel = invite.get_private_channel() - self._bundle_id = invite.get_bundle_id() - - registry = bundleregistry.get_registry() - self._bundle = registry.get_bundle(self._bundle_id) - if self._bundle: - self.set_primary_text(self._bundle.get_name()) - else: - self.set_primary_text(self._bundle_id) - - def _join(self): - activityfactory.create_with_uri(self._bundle, self._private_channel) - - invites = owner.get_model().get_invites() - invites.remove_private_channel(self._private_channel) - - def _decline(self): - invites = owner.get_model().get_invites() - invites.remove_private_channel(self._private_channel) + invites_model.remove_activity(activity_id) class ActivitiesTray(HTray): @@ -318,13 +208,14 @@ class ActivitiesTray(HTray): self._home_model = shell.get_model() self._home_model.connect('activity-added', self.__activity_added_cb) - self._home_model.connect('activity-removed', self.__activity_removed_cb) + self._home_model.connect('activity-removed', + self.__activity_removed_cb) self._home_model.connect('active-activity-changed', self.__activity_changed_cb) self._home_model.connect('tabbing-activity-changed', self.__tabbing_activity_changed_cb) - self._invites = owner.get_model().get_invites() + self._invites = invites.get_instance() for invite in self._invites: self._add_invite(invite) self._invites.connect('invite-added', self.__invite_added_cb) @@ -388,32 +279,22 @@ class ActivitiesTray(HTray): window.activate(gtk.get_current_event_time()) def __invite_clicked_cb(self, icon, invite): - if hasattr(invite, 'get_activity_id'): - self._invites.remove_invite(invite) - else: - self._invites.remove_private_invite(invite) + self._invites.remove_invite(invite) - def __invite_added_cb(self, invites, invite): + def __invite_added_cb(self, invites_model, invite): self._add_invite(invite) - def __invite_removed_cb(self, invites, invite): + def __invite_removed_cb(self, invites_model, invite): self._remove_invite(invite) def _add_invite(self, invite): - """Add an invite (SugarInvite or PrivateInvite)""" - item = None - if hasattr(invite, 'get_activity_id'): - mesh = neighborhood.get_model() - activity_model = mesh.get_activity(invite.get_activity_id()) - if activity_model is not None: - item = ActivityInviteButton(invite) - else: - item = PrivateInviteButton(invite) - if item is not None: - item.connect('clicked', self.__invite_clicked_cb, invite) - self.add_item(item) - item.show() - self._invite_to_item[invite] = item + """Add an invite""" + item = InviteButton(invite) + item.connect('clicked', self.__invite_clicked_cb, invite) + self.add_item(item) + item.show() + + self._invite_to_item[invite] = item def _remove_invite(self, invite): self.remove_item(self._invite_to_item[invite]) @@ -432,6 +313,7 @@ class ActivitiesTray(HTray): self.add_item(button) button.show() + class BaseTransferButton(ToolButton): """Button with a notification attached """ @@ -468,6 +350,7 @@ class BaseTransferButton(ToolButton): filetransfer.FT_REASON_LOCAL_STOPPED: self.remove() + class IncomingTransferButton(BaseTransferButton): """UI element representing an ongoing incoming file transfer """ @@ -490,7 +373,7 @@ class IncomingTransferButton(BaseTransferButton): self.notif_icon.props.icon_name = icon_name break - icon_color = XoColor(file_transfer.buddy.props.color) + icon_color = file_transfer.buddy.props.color self.props.icon_widget.props.xo_color = icon_color self.notif_icon.props.xo_color = icon_color @@ -515,18 +398,18 @@ class IncomingTransferButton(BaseTransferButton): self._ds_object.metadata['buddies'] = '' self._ds_object.metadata['preview'] = '' self._ds_object.metadata['icon-color'] = \ - file_transfer.buddy.props.color + file_transfer.buddy.props.color.to_string() self._ds_object.metadata['mime_type'] = file_transfer.mime_type elif file_transfer.props.state == filetransfer.FT_STATE_COMPLETED: logging.debug('__notify_state_cb COMPLETED') self._ds_object.metadata['progress'] = '100' self._ds_object.file_path = file_transfer.destination_path - datastore.write(self._ds_jobject, transfer_ownership=True, + datastore.write(self._ds_object, transfer_ownership=True, reply_handler=self.__reply_handler_cb, error_handler=self.__error_handler_cb) elif file_transfer.props.state == filetransfer.FT_STATE_CANCELLED: logging.debug('__notify_state_cb CANCELLED') - object_id = self._jobject.object_id + object_id = self._ds_object.object_id if object_id is not None: self._ds_object.destroy() datastore.delete(object_id) @@ -536,17 +419,19 @@ class IncomingTransferButton(BaseTransferButton): progress = file_transfer.props.transferred_bytes / \ file_transfer.file_size self._ds_object.metadata['progress'] = str(progress * 100) - datastore.write(self._ds_object.object_id, update_mtime=False) + datastore.write(self._ds_object, update_mtime=False) def __reply_handler_cb(self): - logging.debug('__reply_handler_cb %r', self._object_id) + logging.debug('__reply_handler_cb %r', self._ds_object.object_id) def __error_handler_cb(self, error): - logging.debug('__error_handler_cb %r %s', self._object_id, error) + logging.debug('__error_handler_cb %r %s', self._ds_object.object_id, + error) def __dismiss_clicked_cb(self, palette): self.remove() + class OutgoingTransferButton(BaseTransferButton): """UI element representing an ongoing outgoing file transfer """ @@ -564,7 +449,7 @@ class OutgoingTransferButton(BaseTransferButton): break client = gconf.client_get_default() - icon_color = XoColor(client.get_string("/desktop/sugar/user/color")) + icon_color = XoColor(client.get_string('/desktop/sugar/user/color')) self.props.icon_widget.props.xo_color = icon_color self.notif_icon.props.xo_color = icon_color @@ -582,14 +467,14 @@ class OutgoingTransferButton(BaseTransferButton): def __dismiss_clicked_cb(self, palette): self.remove() + class BaseTransferPalette(Palette): """Base palette class for frame or notification icon for file transfers """ - __gtype_name__ = "SugarBaseTransferPalette" + __gtype_name__ = 'SugarBaseTransferPalette' __gsignals__ = { - 'dismiss-clicked': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([])), + 'dismiss-clicked': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), } def __init__(self, file_transfer): @@ -644,10 +529,12 @@ class BaseTransferPalette(Palette): total = self._format_size(self.file_transfer.file_size) self.progress_label.props.label = _('%s of %s') % (transferred, total) + class IncomingTransferPalette(BaseTransferPalette): """Palette for frame or notification icon for incoming file transfers """ - __gtype_name__ = "SugarIncomingTransferPalette" + __gtype_name__ = 'SugarIncomingTransferPalette' + def __init__(self, file_transfer): BaseTransferPalette.__init__(self, file_transfer) @@ -770,10 +657,11 @@ class IncomingTransferPalette(BaseTransferPalette): def __dismiss_activate_cb(self, menu_item): self.emit('dismiss-clicked') + class OutgoingTransferPalette(BaseTransferPalette): """Palette for frame or notification icon for outgoing file transfers """ - __gtype_name__ = "SugarOutgoingTransferPalette" + __gtype_name__ = 'SugarOutgoingTransferPalette' def __init__(self, file_transfer): BaseTransferPalette.__init__(self, file_transfer) |