Add an option for saving clipboard objects to the Journal.

This commit is contained in:
Tomeu Vizoso 2007-06-17 20:55:16 +02:00
parent d4323957a1
commit 1afe9273a1
8 changed files with 184 additions and 60 deletions

View File

@ -71,5 +71,5 @@ class Format:
def _set_data(self, data): def _set_data(self, data):
self._data = data self._data = data
def get_on_disk(self): def is_on_disk(self):
return self._on_disk return self._on_disk

View File

@ -31,6 +31,10 @@ PREVIEW_KEY = 'PREVIEW'
ACTIVITY_KEY = 'ACTIVITY' ACTIVITY_KEY = 'ACTIVITY'
FORMATS_KEY = 'FORMATS' FORMATS_KEY = 'FORMATS'
TYPE_KEY = 'TYPE'
DATA_KEY = 'DATA'
ON_DISK_KEY = 'ON_DISK'
class ClipboardService(dbus.service.Object): class ClipboardService(dbus.service.Object):
_CLIPBOARD_DBUS_INTERFACE = "org.laptop.Clipboard" _CLIPBOARD_DBUS_INTERFACE = "org.laptop.Clipboard"
@ -58,7 +62,7 @@ class ClipboardService(dbus.service.Object):
return return
format = formats.values()[0] format = formats.values()[0]
if not format.get_on_disk(): if not format.is_on_disk():
return return
if not len(cb_object.get_activity()): if not len(cb_object.get_activity()):
@ -154,11 +158,14 @@ class ClipboardService(dbus.service.Object):
return dbus.Dictionary(result_dict) return dbus.Dictionary(result_dict)
@dbus.service.method(_CLIPBOARD_DBUS_INTERFACE, @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): def get_object_data(self, object_path, format_type):
cb_object = self._objects[str(object_path)] cb_object = self._objects[str(object_path)]
formats = cb_object.get_formats() format = cb_object.get_formats()[format_type]
return dbus.ByteArray(formats[format_type].get_data()) 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 signals
@dbus.service.signal(_CLIPBOARD_DBUS_INTERFACE, signature="os") @dbus.service.signal(_CLIPBOARD_DBUS_INTERFACE, signature="os")

View File

@ -33,7 +33,7 @@ class ObjectTypeRegistry(dbus.service.Object):
[ 'text/plain', 'text/rtf', 'application/pdf', [ 'text/plain', 'text/rtf', 'application/pdf',
'application/x-pdf' ]) 'application/x-pdf' ])
self._add_primitive('Image', _('Image'), 'theme:object-image', 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): def _add_primitive(self, type_id, name, icon, mime_types):
object_type = {'type_id': type_id, object_type = {'type_id': type_id,

View File

@ -18,6 +18,8 @@
import logging import logging
import os import os
import urlparse import urlparse
import tempfile
from gettext import gettext as _
import gobject import gobject
@ -27,8 +29,12 @@ from sugar.graphics.xocolor import XoColor
from sugar.graphics import units from sugar.graphics import units
from sugar.graphics import color from sugar.graphics import color
from sugar.activity import activityfactory from sugar.activity import activityfactory
from sugar.activity.bundle import Bundle
from sugar.clipboard import clipboardservice from sugar.clipboard import clipboardservice
from sugar import util from sugar import util
from sugar.datastore import datastore
from sugar.objects import mime
from sugar import profile
class ClipboardIcon(CanvasIcon): class ClipboardIcon(CanvasIcon):
__gtype_name__ = 'SugarClipboardIcon' __gtype_name__ = 'SugarClipboardIcon'
@ -124,7 +130,7 @@ class ClipboardIcon(CanvasIcon):
not formats[0] == 'application/vnd.olpc-x-sugar': not formats[0] == 'application/vnd.olpc-x-sugar':
return 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://'): if not uri.startswith('file://'):
return return
@ -154,6 +160,8 @@ class ClipboardIcon(CanvasIcon):
cb_service.delete_object(self._object_id) cb_service.delete_object(self._object_id)
elif action == ClipboardMenu.ACTION_OPEN: elif action == ClipboardMenu.ACTION_OPEN:
self._open_file() self._open_file()
elif action == ClipboardMenu.ACTION_SAVE_TO_JOURNAL:
self._save_to_journal()
def get_object_id(self): def get_object_id(self):
return self._object_id return self._object_id
@ -170,7 +178,42 @@ class ClipboardIcon(CanvasIcon):
self.props.background_color = color.TOOLBAR_BACKGROUND.get_int() self.props.background_color = color.TOOLBAR_BACKGROUND.get_int()
def _install_xo(self, path): def _install_xo(self, path):
logging.debug('mec') bundle = Bundle(path)
if os.spawnlp(os.P_WAIT, 'sugar-install-bundle', 'sugar-install-bundle', if not bundle.is_installed():
path): bundle.install()
raise RuntimeError, 'An error occurred while extracting the .xo contents.'
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)

View File

@ -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 _ from gettext import gettext as _
import hippo import hippo
@ -33,6 +48,7 @@ class ClipboardMenu(Menu):
ACTION_DELETE = 0 ACTION_DELETE = 0
ACTION_OPEN = 1 ACTION_OPEN = 1
ACTION_STOP_DOWNLOAD = 2 ACTION_STOP_DOWNLOAD = 2
ACTION_SAVE_TO_JOURNAL = 3
def __init__(self, name, percent, preview, activity, installable): def __init__(self, name, percent, preview, activity, installable):
Menu.__init__(self, name) Menu.__init__(self, name)
@ -47,6 +63,7 @@ class ClipboardMenu(Menu):
self._remove_item = None self._remove_item = None
self._open_item = None self._open_item = None
self._stop_item = None self._stop_item = None
self._journal_item = None
if preview: if preview:
self._preview_text = hippo.CanvasText(text=preview, self._preview_text = hippo.CanvasText(text=preview,
@ -59,52 +76,72 @@ class ClipboardMenu(Menu):
def _update_icons(self, percent, activity, installable): def _update_icons(self, percent, activity, installable):
if percent == 100 and (activity or installable): if percent == 100 and (activity or installable):
if not self._remove_item: self._add_remove_item()
self._remove_item = MenuItem(ClipboardMenu.ACTION_DELETE, self._add_open_item()
_('Remove'), self._remove_stop_item()
'theme:stock-remove') self._add_journal_item()
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
elif percent == 100 and (not activity and not installable): elif percent == 100 and (not activity and not installable):
if not self._remove_item: self._add_remove_item()
self._remove_item = MenuItem(ClipboardMenu.ACTION_DELETE, self._remove_open_item()
_('Remove'), self._remove_stop_item()
'theme:stock-remove') self._add_journal_item()
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
else: else:
if not self._stop_item: self._remove_remove_item()
self._stop_item = MenuItem(ClipboardMenu.ACTION_STOP_DOWNLOAD, self._remove_open_item()
_('Stop download'), self._add_stop_item()
'theme:stock-close') self._remove_journal_item()
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
def set_state(self, name, percent, preview, activity, installable): def set_state(self, name, percent, preview, activity, installable):
self.set_title(name) self.set_title(name)
if self._progress_bar: if self._progress_bar:
self._progress_bar.set_property('percent', percent) self._progress_bar.set_property('percent', percent)
self._update_icons(percent, activity, installable) 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

View File

@ -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 shutil
import os import os
import logging import logging
@ -135,7 +150,7 @@ class ClipboardBox(hippo.CanvasBox):
def _clipboard_data_get_cb(self, clipboard, selection, info, data): def _clipboard_data_get_cb(self, clipboard, selection, info, data):
object_id = self._selected_icon.get_object_id() object_id = self._selected_icon.get_object_id()
cb_service = clipboardservice.get_instance() 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) selection.set(selection.target, 8, data)
@ -204,7 +219,7 @@ class ClipboardBox(hippo.CanvasBox):
object_id = self._last_clicked_icon.get_object_id() object_id = self._last_clicked_icon.get_object_id()
cb_service = clipboardservice.get_instance() 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) selection.set(selection.target, 8, data)

View File

@ -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 logging
import gtk import gtk
import hippo import hippo

View File

@ -10,6 +10,10 @@ PREVIEW_KEY = 'PREVIEW'
ACTIVITY_KEY = 'ACTIVITY' ACTIVITY_KEY = 'ACTIVITY'
FORMATS_KEY = 'FORMATS' FORMATS_KEY = 'FORMATS'
TYPE_KEY = 'TYPE'
DATA_KEY = 'DATA'
ON_DISK_KEY = 'ON_DISK'
DBUS_SERVICE = "org.laptop.Clipboard" DBUS_SERVICE = "org.laptop.Clipboard"
DBUS_INTERFACE = "org.laptop.Clipboard" DBUS_INTERFACE = "org.laptop.Clipboard"
DBUS_PATH = "/org/laptop/Clipboard" DBUS_PATH = "/org/laptop/Clipboard"
@ -184,7 +188,10 @@ class ClipboardService(gobject.GObject):
object_id -- dbus path as returned from add_object object_id -- dbus path as returned from add_object
formatType -- format specifier XXX of what description 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), return self._dbus_service.get_object_data(dbus.ObjectPath(object_id),
formatType, formatType,