Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarco Pesenti Gritti <mpg@redhat.com>2007-08-15 19:18:58 (GMT)
committer Marco Pesenti Gritti <mpg@redhat.com>2007-08-15 19:18:58 (GMT)
commit3bb86e0cbbbd5f93b14f0672a88a43776ec47d94 (patch)
treec9280615bc0fad5153b27f8b27a0d255326e8690
parent4f1986e8a4e3ce567595404a9d425a58f16f4f1c (diff)
parent26c5ad6ad05d5d1eba9bfefb092ad2245caa5a94 (diff)
Merge branch 'master' of git+ssh://dev.laptop.org/git/sugar
-rw-r--r--NEWS2
-rw-r--r--services/shell/clipboardobject.py5
-rw-r--r--services/shell/clipboardservice.py8
-rw-r--r--shell/view/clipboardmenu.py60
-rw-r--r--sugar/clipboard/clipboardservice.py10
-rw-r--r--sugar/datastore/datastore.py3
-rw-r--r--sugar/datastore/dbus_helpers.py38
7 files changed, 91 insertions, 35 deletions
diff --git a/NEWS b/NEWS
index 0068c95..52999cb 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,5 @@
+* #2543: Offer multiple activities for opening clipboard objects.
+
Snapshot d93122bf5e
* #2751 Add keybindings for max/min brightness/volume
diff --git a/services/shell/clipboardobject.py b/services/shell/clipboardobject.py
index bc51f47..65f3bc5 100644
--- a/services/shell/clipboardobject.py
+++ b/services/shell/clipboardobject.py
@@ -65,16 +65,15 @@ class ClipboardObject:
#return self._get_type_info().get_preview()
return ''
- def get_activity(self):
+ def get_activities(self):
mime = self.get_mime_type()
if not mime:
return ''
registry = bundleregistry.get_registry()
activities = registry.get_activities_for_type(self.get_mime_type())
- # TODO: should we return several activities?
if activities:
- return activities[0].get_service_name()
+ return [activity.get_service_name() for activity in activities]
else:
return ''
diff --git a/services/shell/clipboardservice.py b/services/shell/clipboardservice.py
index 19958a7..90e1b8e 100644
--- a/services/shell/clipboardservice.py
+++ b/services/shell/clipboardservice.py
@@ -33,7 +33,7 @@ NAME_KEY = 'NAME'
PERCENT_KEY = 'PERCENT'
ICON_KEY = 'ICON'
PREVIEW_KEY = 'PREVIEW'
-ACTIVITY_KEY = 'ACTIVITY'
+ACTIVITIES_KEY = 'ACTIVITIES'
FORMATS_KEY = 'FORMATS'
TYPE_KEY = 'TYPE'
@@ -87,7 +87,7 @@ class ClipboardService(dbus.service.Object):
PERCENT_KEY: cb_object.get_percent(),
ICON_KEY: cb_object.get_icon(),
PREVIEW_KEY: cb_object.get_preview(),
- ACTIVITY_KEY: cb_object.get_activity()})
+ ACTIVITIES_KEY: cb_object.get_activities()})
@dbus.service.method(_CLIPBOARD_DBUS_INTERFACE,
in_signature="o", out_signature="")
@@ -121,7 +121,7 @@ class ClipboardService(dbus.service.Object):
PERCENT_KEY: percent,
ICON_KEY: cb_object.get_icon(),
PREVIEW_KEY: cb_object.get_preview(),
- ACTIVITY_KEY: cb_object.get_activity()})
+ ACTIVITIES_KEY: cb_object.get_activities()})
@dbus.service.method(_CLIPBOARD_DBUS_INTERFACE,
in_signature="o", out_signature="a{sv}")
@@ -142,7 +142,7 @@ class ClipboardService(dbus.service.Object):
PERCENT_KEY: cb_object.get_percent(),
ICON_KEY: cb_object.get_icon(),
PREVIEW_KEY: cb_object.get_preview(),
- ACTIVITY_KEY: cb_object.get_activity(),
+ ACTIVITIES_KEY: cb_object.get_activities(),
FORMATS_KEY: format_types}
return dbus.Dictionary(result_dict)
diff --git a/shell/view/clipboardmenu.py b/shell/view/clipboardmenu.py
index 28ea0bb..3acf90e 100644
--- a/shell/view/clipboardmenu.py
+++ b/shell/view/clipboardmenu.py
@@ -30,16 +30,17 @@ from sugar.clipboard import clipboardservice
from sugar.datastore import datastore
from sugar.objects import mime
from sugar import profile
+from sugar import activity
class ClipboardMenu(Palette):
- def __init__(self, object_id, name, percent, preview, activity, installable):
+ def __init__(self, object_id, name, percent, preview, activities, installable):
Palette.__init__(self, name)
self.props.position = Palette.RIGHT
self._object_id = object_id
self._percent = percent
- self._activity = activity
+ self._activities = activities
self.set_group_id('frame')
@@ -68,7 +69,8 @@ class ClipboardMenu(Palette):
self._remove_item.show()
self._open_item = MenuItem(_('Open'), 'stock-keep')
- self._open_item.connect('activate', self._open_item_activate_cb)
+ self._open_item_activate_sid = self._open_item.connect('activate',
+ self._open_item_activate_cb)
self.menu.append(self._open_item)
self._open_item.show()
@@ -83,14 +85,49 @@ class ClipboardMenu(Palette):
self._journal_item.show()
self._update_items_visibility(installable)
+ self._update_open_submenu()
+
+ def _update_open_submenu(self):
+ submenu = self._open_item.get_submenu()
+ if submenu:
+ for item in submenu.get_children():
+ submenu.remove(item)
+
+ if self._activities is None or len(self._activities) <= 1:
+ if self._open_item_activate_sid is None:
+ self._open_item_activate_sid = self._open_item.connect(
+ 'activate',
+ self._open_item_activate_cb)
+ return
+ else:
+ if self._open_item_activate_sid is not None:
+ self._open_item.disconnect(self._open_item_activate_sid)
+ self._open_item_activate_sid = None
+
+ if not submenu:
+ submenu = gtk.Menu()
+ self._open_item.set_submenu(submenu)
+ submenu.show()
+
+ for service_name in self._activities:
+ registry = activity.get_registry()
+ activity_info = registry.get_activity(service_name)
+
+ if not activity_info:
+ logging.warning('Activity %s is unknown.' % service_name)
+
+ item = gtk.MenuItem(activity_info.name)
+ item.connect('activate', self._open_submenu_item_activate_cb, service_name)
+ submenu.append(item)
+ item.show()
def _update_items_visibility(self, installable):
- if self._percent == 100 and (self._activity or installable):
+ if self._percent == 100 and (self._activities or installable):
self._remove_item.props.sensitive = True
self._open_item.props.sensitive = True
#self._stop_item.props.sensitive = False
self._journal_item.props.sensitive = True
- elif self._percent == 100 and (not self._activity and not installable):
+ elif self._percent == 100 and (not self._activities and not installable):
self._remove_item.props.sensitive = True
self._open_item.props.sensitive = False
#self._stop_item.props.sensitive = False
@@ -112,19 +149,26 @@ class ClipboardMenu(Palette):
self._progress_bar.props.fraction = self._percent / 100.0
self._progress_bar.props.text = '%.2f %%' % self._percent
- def set_state(self, name, percent, preview, activity, installable):
+ def set_state(self, name, percent, preview, activities, installable):
self.set_primary_text(name)
self._percent = percent
- self._activity = activity
+ self._activities = activities
if self._progress_bar:
self._update_progress_bar()
self._update_items_visibility(installable)
+ self._update_open_submenu()
def _open_item_activate_cb(self, menu_item):
if self._percent < 100:
return
jobject = self._copy_to_journal()
- jobject.resume()
+ jobject.resume(self._activities[0])
+
+ def _open_submenu_item_activate_cb(self, menu_item, service_name):
+ if self._percent < 100:
+ return
+ jobject = self._copy_to_journal()
+ jobject.resume(service_name)
def _remove_item_activate_cb(self, menu_item):
cb_service = clipboardservice.get_instance()
diff --git a/sugar/clipboard/clipboardservice.py b/sugar/clipboard/clipboardservice.py
index dbdf41d..0e357fe 100644
--- a/sugar/clipboard/clipboardservice.py
+++ b/sugar/clipboard/clipboardservice.py
@@ -23,7 +23,7 @@ NAME_KEY = 'NAME'
PERCENT_KEY = 'PERCENT'
ICON_KEY = 'ICON'
PREVIEW_KEY = 'PREVIEW'
-ACTIVITY_KEY = 'ACTIVITY'
+ACTIVITIES_KEY = 'ACTIVITIES'
FORMATS_KEY = 'FORMATS'
TYPE_KEY = 'TYPE'
@@ -51,7 +51,7 @@ class ClipboardService(gobject.GObject):
'object-deleted': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([str])),
'object-state-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([str, str, int, str, str, str])),
+ ([str, str, int, str, str, object])),
}
def __init__(self):
@@ -118,13 +118,13 @@ class ClipboardService(gobject.GObject):
percent
icon
preview
- activity
+ activities
From the ClipboardObject instance which is being described.
"""
self.emit('object-state-changed', str(object_id), values[NAME_KEY],
values[PERCENT_KEY], values[ICON_KEY], values[PREVIEW_KEY],
- values[ACTIVITY_KEY])
+ values[ACTIVITIES_KEY])
def add_object(self, name):
"""Add a new object to the path
@@ -193,7 +193,7 @@ class ClipboardService(gobject.GObject):
PERCENT_KEY: number,
ICON_KEY: str,
PREVIEW_KEY: XXX what is it?,
- ACTIVITY_KEY: source activity id,
+ ACTIVITIES_KEY: activities that can open this object,
FORMATS_KEY: list of XXX what is it?
"""
return self._dbus_service.get_object(dbus.ObjectPath(object_id),)
diff --git a/sugar/datastore/datastore.py b/sugar/datastore/datastore.py
index 5ba994d..0dbe35b 100644
--- a/sugar/datastore/datastore.py
+++ b/sugar/datastore/datastore.py
@@ -120,6 +120,9 @@ class DSObject(object):
def resume(self, service_name=None):
if self.is_bundle():
+ if service_name is not None:
+ raise ValueError('Object is a bundle, cannot be resumed as an activity.')
+
bundle = Bundle(self.file_path)
if not bundle.is_installed():
bundle.install()
diff --git a/sugar/datastore/dbus_helpers.py b/sugar/datastore/dbus_helpers.py
index f0cfa3b..442a35d 100644
--- a/sugar/datastore/dbus_helpers.py
+++ b/sugar/datastore/dbus_helpers.py
@@ -28,55 +28,63 @@ DS_DBUS_SERVICE = "org.laptop.sugar.DataStore"
DS_DBUS_INTERFACE = "org.laptop.sugar.DataStore"
DS_DBUS_PATH = "/org/laptop/sugar/DataStore"
-_bus = dbus.SessionBus()
-_data_store = dbus.Interface(_bus.get_object(DS_DBUS_SERVICE, DS_DBUS_PATH),
- DS_DBUS_INTERFACE)
+_data_store = None
+
+def _get_data_store():
+ global _data_store
+
+ if not _data_store:
+ _bus = dbus.SessionBus()
+ _data_store = dbus.Interface(_bus.get_object(DS_DBUS_SERVICE,
+ DS_DBUS_PATH),
+ DS_DBUS_INTERFACE)
+ return _data_store
def create(properties, filename):
- object_id = _data_store.create(dbus.Dictionary(properties), filename)
+ object_id = _get_data_store().create(dbus.Dictionary(properties), filename)
logging.debug('dbus_helpers.create: ' + object_id)
return object_id
def update(uid, properties, filename, reply_handler=None, error_handler=None, timeout=-1):
logging.debug('dbus_helpers.update: %s, %s, %s' % (uid, filename, properties))
if reply_handler and error_handler:
- _data_store.update(uid, dbus.Dictionary(properties), filename,
+ _get_data_store().update(uid, dbus.Dictionary(properties), filename,
reply_handler=reply_handler,
error_handler=error_handler,
timeout=timeout)
else:
- _data_store.update(uid, dbus.Dictionary(properties), filename)
+ _get_data_store().update(uid, dbus.Dictionary(properties), filename)
def delete(uid):
logging.debug('dbus_helpers.delete: %r' % uid)
- _data_store.delete(uid)
+ _get_data_store().delete(uid)
def get_properties(uid):
logging.debug('dbus_helpers.get_properties: %s' % uid)
- return _data_store.get_properties(uid)
+ return _get_data_store().get_properties(uid)
def get_filename(uid):
- filename = _data_store.get_filename(uid)
+ filename = _get_data_store().get_filename(uid)
logging.debug('dbus_helpers.get_filename: %s, %s' % (uid, filename))
return filename
def find(query, reply_handler, error_handler):
logging.debug('dbus_helpers.find: %r' % query)
if reply_handler and error_handler:
- return _data_store.find(query, reply_handler=reply_handler,
+ return _get_data_store().find(query, reply_handler=reply_handler,
error_handler=error_handler)
else:
- return _data_store.find(query)
+ return _get_data_store().find(query)
def mount(uri, options):
- return _data_store.mount(uri, options)
+ return _get_data_store().mount(uri, options)
def unmount(mount_point_id):
- _data_store.unmount(mount_point_id)
+ _get_data_store().unmount(mount_point_id)
def mounts():
- return _data_store.mounts()
+ return _get_data_store().mounts()
def get_unique_values(key):
- return _data_store.get_uniquevaluesfor(key, dbus.Dictionary({}, signature='ss'))
+ return _get_data_store().get_uniquevaluesfor(key, dbus.Dictionary({}, signature='ss'))