Merge branch 'master' of git+ssh://dev.laptop.org/git/sugar
This commit is contained in:
commit
3bb86e0cbb
2
NEWS
2
NEWS
@ -1,3 +1,5 @@
|
|||||||
|
* #2543: Offer multiple activities for opening clipboard objects.
|
||||||
|
|
||||||
Snapshot d93122bf5e
|
Snapshot d93122bf5e
|
||||||
|
|
||||||
* #2751 Add keybindings for max/min brightness/volume
|
* #2751 Add keybindings for max/min brightness/volume
|
||||||
|
@ -65,16 +65,15 @@ class ClipboardObject:
|
|||||||
#return self._get_type_info().get_preview()
|
#return self._get_type_info().get_preview()
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def get_activity(self):
|
def get_activities(self):
|
||||||
mime = self.get_mime_type()
|
mime = self.get_mime_type()
|
||||||
if not mime:
|
if not mime:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
registry = bundleregistry.get_registry()
|
registry = bundleregistry.get_registry()
|
||||||
activities = registry.get_activities_for_type(self.get_mime_type())
|
activities = registry.get_activities_for_type(self.get_mime_type())
|
||||||
# TODO: should we return several activities?
|
|
||||||
if activities:
|
if activities:
|
||||||
return activities[0].get_service_name()
|
return [activity.get_service_name() for activity in activities]
|
||||||
else:
|
else:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ NAME_KEY = 'NAME'
|
|||||||
PERCENT_KEY = 'PERCENT'
|
PERCENT_KEY = 'PERCENT'
|
||||||
ICON_KEY = 'ICON'
|
ICON_KEY = 'ICON'
|
||||||
PREVIEW_KEY = 'PREVIEW'
|
PREVIEW_KEY = 'PREVIEW'
|
||||||
ACTIVITY_KEY = 'ACTIVITY'
|
ACTIVITIES_KEY = 'ACTIVITIES'
|
||||||
FORMATS_KEY = 'FORMATS'
|
FORMATS_KEY = 'FORMATS'
|
||||||
|
|
||||||
TYPE_KEY = 'TYPE'
|
TYPE_KEY = 'TYPE'
|
||||||
@ -87,7 +87,7 @@ class ClipboardService(dbus.service.Object):
|
|||||||
PERCENT_KEY: cb_object.get_percent(),
|
PERCENT_KEY: cb_object.get_percent(),
|
||||||
ICON_KEY: cb_object.get_icon(),
|
ICON_KEY: cb_object.get_icon(),
|
||||||
PREVIEW_KEY: cb_object.get_preview(),
|
PREVIEW_KEY: cb_object.get_preview(),
|
||||||
ACTIVITY_KEY: cb_object.get_activity()})
|
ACTIVITIES_KEY: cb_object.get_activities()})
|
||||||
|
|
||||||
@dbus.service.method(_CLIPBOARD_DBUS_INTERFACE,
|
@dbus.service.method(_CLIPBOARD_DBUS_INTERFACE,
|
||||||
in_signature="o", out_signature="")
|
in_signature="o", out_signature="")
|
||||||
@ -121,7 +121,7 @@ class ClipboardService(dbus.service.Object):
|
|||||||
PERCENT_KEY: percent,
|
PERCENT_KEY: percent,
|
||||||
ICON_KEY: cb_object.get_icon(),
|
ICON_KEY: cb_object.get_icon(),
|
||||||
PREVIEW_KEY: cb_object.get_preview(),
|
PREVIEW_KEY: cb_object.get_preview(),
|
||||||
ACTIVITY_KEY: cb_object.get_activity()})
|
ACTIVITIES_KEY: cb_object.get_activities()})
|
||||||
|
|
||||||
@dbus.service.method(_CLIPBOARD_DBUS_INTERFACE,
|
@dbus.service.method(_CLIPBOARD_DBUS_INTERFACE,
|
||||||
in_signature="o", out_signature="a{sv}")
|
in_signature="o", out_signature="a{sv}")
|
||||||
@ -142,7 +142,7 @@ class ClipboardService(dbus.service.Object):
|
|||||||
PERCENT_KEY: cb_object.get_percent(),
|
PERCENT_KEY: cb_object.get_percent(),
|
||||||
ICON_KEY: cb_object.get_icon(),
|
ICON_KEY: cb_object.get_icon(),
|
||||||
PREVIEW_KEY: cb_object.get_preview(),
|
PREVIEW_KEY: cb_object.get_preview(),
|
||||||
ACTIVITY_KEY: cb_object.get_activity(),
|
ACTIVITIES_KEY: cb_object.get_activities(),
|
||||||
FORMATS_KEY: format_types}
|
FORMATS_KEY: format_types}
|
||||||
return dbus.Dictionary(result_dict)
|
return dbus.Dictionary(result_dict)
|
||||||
|
|
||||||
|
@ -30,16 +30,17 @@ from sugar.clipboard import clipboardservice
|
|||||||
from sugar.datastore import datastore
|
from sugar.datastore import datastore
|
||||||
from sugar.objects import mime
|
from sugar.objects import mime
|
||||||
from sugar import profile
|
from sugar import profile
|
||||||
|
from sugar import activity
|
||||||
|
|
||||||
class ClipboardMenu(Palette):
|
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)
|
Palette.__init__(self, name)
|
||||||
|
|
||||||
self.props.position = Palette.RIGHT
|
self.props.position = Palette.RIGHT
|
||||||
self._object_id = object_id
|
self._object_id = object_id
|
||||||
self._percent = percent
|
self._percent = percent
|
||||||
self._activity = activity
|
self._activities = activities
|
||||||
|
|
||||||
self.set_group_id('frame')
|
self.set_group_id('frame')
|
||||||
|
|
||||||
@ -68,7 +69,8 @@ class ClipboardMenu(Palette):
|
|||||||
self._remove_item.show()
|
self._remove_item.show()
|
||||||
|
|
||||||
self._open_item = MenuItem(_('Open'), 'stock-keep')
|
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.menu.append(self._open_item)
|
||||||
self._open_item.show()
|
self._open_item.show()
|
||||||
|
|
||||||
@ -83,14 +85,49 @@ class ClipboardMenu(Palette):
|
|||||||
self._journal_item.show()
|
self._journal_item.show()
|
||||||
|
|
||||||
self._update_items_visibility(installable)
|
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):
|
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._remove_item.props.sensitive = True
|
||||||
self._open_item.props.sensitive = True
|
self._open_item.props.sensitive = True
|
||||||
#self._stop_item.props.sensitive = False
|
#self._stop_item.props.sensitive = False
|
||||||
self._journal_item.props.sensitive = True
|
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._remove_item.props.sensitive = True
|
||||||
self._open_item.props.sensitive = False
|
self._open_item.props.sensitive = False
|
||||||
#self._stop_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.fraction = self._percent / 100.0
|
||||||
self._progress_bar.props.text = '%.2f %%' % self._percent
|
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.set_primary_text(name)
|
||||||
self._percent = percent
|
self._percent = percent
|
||||||
self._activity = activity
|
self._activities = activities
|
||||||
if self._progress_bar:
|
if self._progress_bar:
|
||||||
self._update_progress_bar()
|
self._update_progress_bar()
|
||||||
self._update_items_visibility(installable)
|
self._update_items_visibility(installable)
|
||||||
|
self._update_open_submenu()
|
||||||
|
|
||||||
def _open_item_activate_cb(self, menu_item):
|
def _open_item_activate_cb(self, menu_item):
|
||||||
if self._percent < 100:
|
if self._percent < 100:
|
||||||
return
|
return
|
||||||
jobject = self._copy_to_journal()
|
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):
|
def _remove_item_activate_cb(self, menu_item):
|
||||||
cb_service = clipboardservice.get_instance()
|
cb_service = clipboardservice.get_instance()
|
||||||
|
@ -23,7 +23,7 @@ NAME_KEY = 'NAME'
|
|||||||
PERCENT_KEY = 'PERCENT'
|
PERCENT_KEY = 'PERCENT'
|
||||||
ICON_KEY = 'ICON'
|
ICON_KEY = 'ICON'
|
||||||
PREVIEW_KEY = 'PREVIEW'
|
PREVIEW_KEY = 'PREVIEW'
|
||||||
ACTIVITY_KEY = 'ACTIVITY'
|
ACTIVITIES_KEY = 'ACTIVITIES'
|
||||||
FORMATS_KEY = 'FORMATS'
|
FORMATS_KEY = 'FORMATS'
|
||||||
|
|
||||||
TYPE_KEY = 'TYPE'
|
TYPE_KEY = 'TYPE'
|
||||||
@ -51,7 +51,7 @@ class ClipboardService(gobject.GObject):
|
|||||||
'object-deleted': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
|
'object-deleted': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
|
||||||
([str])),
|
([str])),
|
||||||
'object-state-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
|
'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):
|
def __init__(self):
|
||||||
@ -118,13 +118,13 @@ class ClipboardService(gobject.GObject):
|
|||||||
percent
|
percent
|
||||||
icon
|
icon
|
||||||
preview
|
preview
|
||||||
activity
|
activities
|
||||||
|
|
||||||
From the ClipboardObject instance which is being described.
|
From the ClipboardObject instance which is being described.
|
||||||
"""
|
"""
|
||||||
self.emit('object-state-changed', str(object_id), values[NAME_KEY],
|
self.emit('object-state-changed', str(object_id), values[NAME_KEY],
|
||||||
values[PERCENT_KEY], values[ICON_KEY], values[PREVIEW_KEY],
|
values[PERCENT_KEY], values[ICON_KEY], values[PREVIEW_KEY],
|
||||||
values[ACTIVITY_KEY])
|
values[ACTIVITIES_KEY])
|
||||||
|
|
||||||
def add_object(self, name):
|
def add_object(self, name):
|
||||||
"""Add a new object to the path
|
"""Add a new object to the path
|
||||||
@ -193,7 +193,7 @@ class ClipboardService(gobject.GObject):
|
|||||||
PERCENT_KEY: number,
|
PERCENT_KEY: number,
|
||||||
ICON_KEY: str,
|
ICON_KEY: str,
|
||||||
PREVIEW_KEY: XXX what is it?,
|
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?
|
FORMATS_KEY: list of XXX what is it?
|
||||||
"""
|
"""
|
||||||
return self._dbus_service.get_object(dbus.ObjectPath(object_id),)
|
return self._dbus_service.get_object(dbus.ObjectPath(object_id),)
|
||||||
|
@ -120,6 +120,9 @@ class DSObject(object):
|
|||||||
|
|
||||||
def resume(self, service_name=None):
|
def resume(self, service_name=None):
|
||||||
if self.is_bundle():
|
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)
|
bundle = Bundle(self.file_path)
|
||||||
if not bundle.is_installed():
|
if not bundle.is_installed():
|
||||||
bundle.install()
|
bundle.install()
|
||||||
|
@ -28,55 +28,63 @@ DS_DBUS_SERVICE = "org.laptop.sugar.DataStore"
|
|||||||
DS_DBUS_INTERFACE = "org.laptop.sugar.DataStore"
|
DS_DBUS_INTERFACE = "org.laptop.sugar.DataStore"
|
||||||
DS_DBUS_PATH = "/org/laptop/sugar/DataStore"
|
DS_DBUS_PATH = "/org/laptop/sugar/DataStore"
|
||||||
|
|
||||||
_bus = dbus.SessionBus()
|
_data_store = None
|
||||||
_data_store = dbus.Interface(_bus.get_object(DS_DBUS_SERVICE, DS_DBUS_PATH),
|
|
||||||
DS_DBUS_INTERFACE)
|
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):
|
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)
|
logging.debug('dbus_helpers.create: ' + object_id)
|
||||||
return object_id
|
return object_id
|
||||||
|
|
||||||
def update(uid, properties, filename, reply_handler=None, error_handler=None, timeout=-1):
|
def update(uid, properties, filename, reply_handler=None, error_handler=None, timeout=-1):
|
||||||
logging.debug('dbus_helpers.update: %s, %s, %s' % (uid, filename, properties))
|
logging.debug('dbus_helpers.update: %s, %s, %s' % (uid, filename, properties))
|
||||||
if reply_handler and error_handler:
|
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,
|
reply_handler=reply_handler,
|
||||||
error_handler=error_handler,
|
error_handler=error_handler,
|
||||||
timeout=timeout)
|
timeout=timeout)
|
||||||
else:
|
else:
|
||||||
_data_store.update(uid, dbus.Dictionary(properties), filename)
|
_get_data_store().update(uid, dbus.Dictionary(properties), filename)
|
||||||
|
|
||||||
def delete(uid):
|
def delete(uid):
|
||||||
logging.debug('dbus_helpers.delete: %r' % uid)
|
logging.debug('dbus_helpers.delete: %r' % uid)
|
||||||
_data_store.delete(uid)
|
_get_data_store().delete(uid)
|
||||||
|
|
||||||
def get_properties(uid):
|
def get_properties(uid):
|
||||||
logging.debug('dbus_helpers.get_properties: %s' % 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):
|
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))
|
logging.debug('dbus_helpers.get_filename: %s, %s' % (uid, filename))
|
||||||
return filename
|
return filename
|
||||||
|
|
||||||
def find(query, reply_handler, error_handler):
|
def find(query, reply_handler, error_handler):
|
||||||
logging.debug('dbus_helpers.find: %r' % query)
|
logging.debug('dbus_helpers.find: %r' % query)
|
||||||
if reply_handler and error_handler:
|
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)
|
error_handler=error_handler)
|
||||||
else:
|
else:
|
||||||
return _data_store.find(query)
|
return _get_data_store().find(query)
|
||||||
|
|
||||||
def mount(uri, options):
|
def mount(uri, options):
|
||||||
return _data_store.mount(uri, options)
|
return _get_data_store().mount(uri, options)
|
||||||
|
|
||||||
def unmount(mount_point_id):
|
def unmount(mount_point_id):
|
||||||
_data_store.unmount(mount_point_id)
|
_get_data_store().unmount(mount_point_id)
|
||||||
|
|
||||||
def mounts():
|
def mounts():
|
||||||
return _data_store.mounts()
|
return _get_data_store().mounts()
|
||||||
|
|
||||||
def get_unique_values(key):
|
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'))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user