Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomeu Vizoso <tomeu@tomeuvizoso.net>2007-06-17 18:55:16 (GMT)
committer Tomeu Vizoso <tomeu@tomeuvizoso.net>2007-06-17 18:55:16 (GMT)
commit1afe9273a1722938c4457d1c8512e6fd57619123 (patch)
treee31b4f03972b7bfe057ff2fa7db22ef01d5c063a
parentd4323957a17f5bdd068550c393e855b754890ee6 (diff)
Add an option for saving clipboard objects to the Journal.
-rw-r--r--services/clipboard/clipboardobject.py2
-rw-r--r--services/clipboard/clipboardservice.py17
-rw-r--r--services/clipboard/objecttypeservice.py2
-rw-r--r--shell/view/clipboardicon.py55
-rw-r--r--shell/view/clipboardmenu.py123
-rw-r--r--shell/view/frame/clipboardbox.py19
-rw-r--r--shell/view/frame/clipboardpanelwindow.py15
-rw-r--r--sugar/clipboard/clipboardservice.py11
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"""