Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/jarabe/frame/activitiestray.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/jarabe/frame/activitiestray.py')
-rw-r--r--src/jarabe/frame/activitiestray.py308
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)