diff options
-rw-r--r-- | services/clipboard/clipboardobject.py | 2 | ||||
-rw-r--r-- | services/clipboard/clipboardservice.py | 17 | ||||
-rw-r--r-- | services/clipboard/objecttypeservice.py | 2 | ||||
-rw-r--r-- | shell/view/clipboardicon.py | 55 | ||||
-rw-r--r-- | shell/view/clipboardmenu.py | 123 | ||||
-rw-r--r-- | shell/view/frame/clipboardbox.py | 19 | ||||
-rw-r--r-- | shell/view/frame/clipboardpanelwindow.py | 15 | ||||
-rw-r--r-- | sugar/clipboard/clipboardservice.py | 11 |
8 files changed, 184 insertions, 60 deletions
diff --git a/services/clipboard/clipboardobject.py b/services/clipboard/clipboardobject.py index d712e09..6505f1d 100644 --- a/services/clipboard/clipboardobject.py +++ b/services/clipboard/clipboardobject.py @@ -71,5 +71,5 @@ class Format: def _set_data(self, data): self._data = data - def get_on_disk(self): + def is_on_disk(self): return self._on_disk diff --git a/services/clipboard/clipboardservice.py b/services/clipboard/clipboardservice.py index 8b2d836..aab97de 100644 --- a/services/clipboard/clipboardservice.py +++ b/services/clipboard/clipboardservice.py @@ -31,6 +31,10 @@ PREVIEW_KEY = 'PREVIEW' ACTIVITY_KEY = 'ACTIVITY' FORMATS_KEY = 'FORMATS' +TYPE_KEY = 'TYPE' +DATA_KEY = 'DATA' +ON_DISK_KEY = 'ON_DISK' + class ClipboardService(dbus.service.Object): _CLIPBOARD_DBUS_INTERFACE = "org.laptop.Clipboard" @@ -58,7 +62,7 @@ class ClipboardService(dbus.service.Object): return format = formats.values()[0] - if not format.get_on_disk(): + if not format.is_on_disk(): return if not len(cb_object.get_activity()): @@ -154,12 +158,15 @@ class ClipboardService(dbus.service.Object): return dbus.Dictionary(result_dict) @dbus.service.method(_CLIPBOARD_DBUS_INTERFACE, - in_signature="os", out_signature="ay") + in_signature="os", out_signature="a{sv}") def get_object_data(self, object_path, format_type): cb_object = self._objects[str(object_path)] - formats = cb_object.get_formats() - return dbus.ByteArray(formats[format_type].get_data()) - + format = cb_object.get_formats()[format_type] + result_dict = {TYPE_KEY: format.get_type(), + DATA_KEY: dbus.ByteArray(format.get_data()), + ON_DISK_KEY: format.is_on_disk()} + return dbus.Dictionary(result_dict) + # dbus signals @dbus.service.signal(_CLIPBOARD_DBUS_INTERFACE, signature="os") def object_added(self, object_path, name): diff --git a/services/clipboard/objecttypeservice.py b/services/clipboard/objecttypeservice.py index d1bcd49..f24640a 100644 --- a/services/clipboard/objecttypeservice.py +++ b/services/clipboard/objecttypeservice.py @@ -33,7 +33,7 @@ class ObjectTypeRegistry(dbus.service.Object): [ 'text/plain', 'text/rtf', 'application/pdf', 'application/x-pdf' ]) self._add_primitive('Image', _('Image'), 'theme:object-image', - [ 'image/png' ]) + [ 'image/png', 'image/gif', 'image/jpeg' ]) def _add_primitive(self, type_id, name, icon, mime_types): object_type = {'type_id': type_id, diff --git a/shell/view/clipboardicon.py b/shell/view/clipboardicon.py index 02edb65..31110ea 100644 --- a/shell/view/clipboardicon.py +++ b/shell/view/clipboardicon.py @@ -18,6 +18,8 @@ import logging import os import urlparse +import tempfile +from gettext import gettext as _ import gobject @@ -27,8 +29,12 @@ from sugar.graphics.xocolor import XoColor from sugar.graphics import units from sugar.graphics import color from sugar.activity import activityfactory +from sugar.activity.bundle import Bundle from sugar.clipboard import clipboardservice from sugar import util +from sugar.datastore import datastore +from sugar.objects import mime +from sugar import profile class ClipboardIcon(CanvasIcon): __gtype_name__ = 'SugarClipboardIcon' @@ -124,7 +130,7 @@ class ClipboardIcon(CanvasIcon): not formats[0] == 'application/vnd.olpc-x-sugar': return - uri = cb_service.get_object_data(self._object_id, formats[0]) + uri = cb_service.get_object_data(self._object_id, formats[0])['DATA'] if not uri.startswith('file://'): return @@ -154,7 +160,9 @@ class ClipboardIcon(CanvasIcon): cb_service.delete_object(self._object_id) elif action == ClipboardMenu.ACTION_OPEN: self._open_file() - + elif action == ClipboardMenu.ACTION_SAVE_TO_JOURNAL: + self._save_to_journal() + def get_object_id(self): return self._object_id @@ -170,7 +178,42 @@ class ClipboardIcon(CanvasIcon): self.props.background_color = color.TOOLBAR_BACKGROUND.get_int() def _install_xo(self, path): - logging.debug('mec') - if os.spawnlp(os.P_WAIT, 'sugar-install-bundle', 'sugar-install-bundle', - path): - raise RuntimeError, 'An error occurred while extracting the .xo contents.' + bundle = Bundle(path) + if not bundle.is_installed(): + bundle.install() + + def _save_to_journal(self): + cb_service = clipboardservice.get_instance() + obj = cb_service.get_object(self._object_id) + + if len(obj['FORMATS']) == 0: + return + + if 'text/uri-list' in obj['FORMATS']: + data = cb_service.get_object_data(self._object_id, 'text/uri-list') + file_path = urlparse.urlparse(data['DATA']).path + mime_type = mime.get_for_file(file_path) + else: + # TODO: Find a way to choose the best mime-type from all the available. + mime_type = obj['FORMATS'][0] + + data = cb_service.get_object_data(self._object_id, mime_type) + if data['ON_DISK']: + file_path = urlparse.urlparse(data['DATA']).path + else: + f, file_path = tempfile.mkstemp() + try: + os.write(f, data['data']) + finally: + os.close(f) + + jobject = datastore.create() + jobject.metadata['title'] = _('Clipboard object: %s.') % obj['NAME'] + jobject.metadata['keep'] = '0' + jobject.metadata['buddies'] = '' + jobject.metadata['preview'] = '' + jobject.metadata['icon-color'] = profile.get_color().to_string() + jobject.metadata['mime_type'] = mime_type + jobject.file_path = file_path + datastore.write(jobject) + diff --git a/shell/view/clipboardmenu.py b/shell/view/clipboardmenu.py index 0d1549c..f17bf23 100644 --- a/shell/view/clipboardmenu.py +++ b/shell/view/clipboardmenu.py @@ -1,3 +1,18 @@ +# Copyright (C) 2007, One Laptop Per Child +# +# 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 +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# 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 hippo @@ -33,6 +48,7 @@ class ClipboardMenu(Menu): ACTION_DELETE = 0 ACTION_OPEN = 1 ACTION_STOP_DOWNLOAD = 2 + ACTION_SAVE_TO_JOURNAL = 3 def __init__(self, name, percent, preview, activity, installable): Menu.__init__(self, name) @@ -47,6 +63,7 @@ class ClipboardMenu(Menu): self._remove_item = None self._open_item = None self._stop_item = None + self._journal_item = None if preview: self._preview_text = hippo.CanvasText(text=preview, @@ -54,57 +71,77 @@ class ClipboardMenu(Menu): self._preview_text.props.color = color.LABEL_TEXT.get_int() self._preview_text.props.font_desc = font.DEFAULT.get_pango_desc() self.append(self._preview_text) - + self._update_icons(percent, activity, installable) - + def _update_icons(self, percent, activity, installable): if percent == 100 and (activity or installable): - if not self._remove_item: - self._remove_item = MenuItem(ClipboardMenu.ACTION_DELETE, - _('Remove'), - 'theme:stock-remove') - self.add_item(self._remove_item) - - if not self._open_item: - self._open_item = MenuItem(ClipboardMenu.ACTION_OPEN, - _('Open'), - 'theme:stock-keep') - self.add_item(self._open_item) - - if self._stop_item: - self.remove_item(self._stop_item) - self._stop_item = None + self._add_remove_item() + self._add_open_item() + self._remove_stop_item() + self._add_journal_item() elif percent == 100 and (not activity and not installable): - if not self._remove_item: - self._remove_item = MenuItem(ClipboardMenu.ACTION_DELETE, - _('Remove'), - 'theme:stock-remove') - self.add_item(self._remove_item) - - if self._open_item: - self.remove_item(self._open_item) - self._open_item = None - - if self._stop_item: - self.remove_item(self._stop_item) - self._stop_item = None + self._add_remove_item() + self._remove_open_item() + self._remove_stop_item() + self._add_journal_item() else: - if not self._stop_item: - self._stop_item = MenuItem(ClipboardMenu.ACTION_STOP_DOWNLOAD, - _('Stop download'), - 'theme:stock-close') - self.add_item(self._stop_item) - - if self._remove_item: - self.remove_item(self._remove_item) - self._remove_item = None - - if self._open_item: - self.remove_item(self._open_item) - self._open_item = None + self._remove_remove_item() + self._remove_open_item() + self._add_stop_item() + self._remove_journal_item() def set_state(self, name, percent, preview, activity, installable): self.set_title(name) if self._progress_bar: self._progress_bar.set_property('percent', percent) self._update_icons(percent, activity, installable) + + def _add_remove_item(self): + if not self._remove_item: + self._remove_item = MenuItem(ClipboardMenu.ACTION_DELETE, + _('Remove'), + 'theme:stock-remove') + self.add_item(self._remove_item) + + def _add_open_item(self): + if not self._open_item: + self._open_item = MenuItem(ClipboardMenu.ACTION_OPEN, + _('Open'), + 'theme:stock-keep') + self.add_item(self._open_item) + + def _add_stop_item(self): + if not self._stop_item: + self._stop_item = MenuItem(ClipboardMenu.ACTION_STOP_DOWNLOAD, + _('Stop download'), + 'theme:stock-close') + self.add_item(self._stop_item) + + def _add_journal_item(self): + if not self._journal_item: + self._journal_item = MenuItem(ClipboardMenu.ACTION_SAVE_TO_JOURNAL, + _('Add to journal'), + 'theme:stock-save') + self.add_item(self._journal_item) + + def _remove_open_item(self): + if self._open_item: + self.remove_item(self._open_item) + self._open_item = None + + def _remove_stop_item(self): + if self._stop_item: + self.remove_item(self._stop_item) + self._stop_item = None + + def _remove_remove_item(self): + if self._remove_item: + self.remove_item(self._remove_item) + self._remove_item = None + + def _remove_journal_item(self): + if self._journal_item: + self.remove_item(self._journal_item) + self._journal_item = None + diff --git a/shell/view/frame/clipboardbox.py b/shell/view/frame/clipboardbox.py index 8eab85f..1eb1684 100644 --- a/shell/view/frame/clipboardbox.py +++ b/shell/view/frame/clipboardbox.py @@ -1,3 +1,18 @@ +# Copyright (C) 2007, One Laptop Per Child +# +# 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 +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# 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 import shutil import os import logging @@ -135,7 +150,7 @@ class ClipboardBox(hippo.CanvasBox): def _clipboard_data_get_cb(self, clipboard, selection, info, data): object_id = self._selected_icon.get_object_id() cb_service = clipboardservice.get_instance() - data = cb_service.get_object_data(object_id, selection.target) + data = cb_service.get_object_data(object_id, selection.target)['DATA'] selection.set(selection.target, 8, data) @@ -204,7 +219,7 @@ class ClipboardBox(hippo.CanvasBox): object_id = self._last_clicked_icon.get_object_id() cb_service = clipboardservice.get_instance() - data = cb_service.get_object_data(object_id, selection.target) + data = cb_service.get_object_data(object_id, selection.target)['DATA'] selection.set(selection.target, 8, data) diff --git a/shell/view/frame/clipboardpanelwindow.py b/shell/view/frame/clipboardpanelwindow.py index 69c6aec..a7fba17 100644 --- a/shell/view/frame/clipboardpanelwindow.py +++ b/shell/view/frame/clipboardpanelwindow.py @@ -1,3 +1,18 @@ +# Copyright (C) 2007, One Laptop Per Child +# +# 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 +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# 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 import logging import gtk import hippo diff --git a/sugar/clipboard/clipboardservice.py b/sugar/clipboard/clipboardservice.py index e144fae..5215812 100644 --- a/sugar/clipboard/clipboardservice.py +++ b/sugar/clipboard/clipboardservice.py @@ -10,6 +10,10 @@ PREVIEW_KEY = 'PREVIEW' ACTIVITY_KEY = 'ACTIVITY' FORMATS_KEY = 'FORMATS' +TYPE_KEY = 'TYPE' +DATA_KEY = 'DATA' +ON_DISK_KEY = 'ON_DISK' + DBUS_SERVICE = "org.laptop.Clipboard" DBUS_INTERFACE = "org.laptop.Clipboard" DBUS_PATH = "/org/laptop/Clipboard" @@ -184,12 +188,15 @@ class ClipboardService(gobject.GObject): object_id -- dbus path as returned from add_object formatType -- format specifier XXX of what description - returns data as a string + returns dictionary with + TYPE_KEY: str, + DATA_KEY: str, + ON_DISK_KEY: bool """ return self._dbus_service.get_object_data(dbus.ObjectPath(object_id), formatType, byte_arrays=True) - + _clipboard_service = None def get_instance(): """Retrieve this process's interface to the clipboard service""" |