Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTomeu Vizoso <tomeu@tomeuvizoso.net>2008-09-15 11:29:54 (GMT)
committer Tomeu Vizoso <tomeu@tomeuvizoso.net>2008-09-16 13:17:52 (GMT)
commit09021f0b8e97835e06e28e2612f94affc05956f6 (patch)
tree9b7f80c309d394de22298e3b2f8c042b7e177f35 /src
parent46e88bd0953eb5372ca064bad9adc8d1935c8c3c (diff)
Move clipboard from the shell service into the shell process
Diffstat (limited to 'src')
-rw-r--r--src/journal/palettes.py4
-rw-r--r--src/model/Makefile.am2
-rw-r--r--src/model/clipboard.py149
-rw-r--r--src/model/clipboardobject.py117
-rw-r--r--src/view/Shell.py25
-rw-r--r--src/view/clipboardicon.py85
-rw-r--r--src/view/clipboardmenu.py109
-rw-r--r--src/view/frame/clipboardpanelwindow.py13
-rw-r--r--src/view/frame/clipboardtray.py26
9 files changed, 386 insertions, 144 deletions
diff --git a/src/journal/palettes.py b/src/journal/palettes.py
index f186c68..81efc03 100644
--- a/src/journal/palettes.py
+++ b/src/journal/palettes.py
@@ -15,7 +15,8 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
from gettext import gettext as _
-
+import logging
+
import gtk
from sugar import profile
@@ -86,6 +87,7 @@ class ObjectPalette(Palette):
self.__clipboard_clear_func_cb)
def __clipboard_get_func_cb(self, clipboard, selection_data, info, data):
+ logging.debug('__clipboard_get_func_cb %r' % self._jobject.file_path)
selection_data.set_uris(['file://' + self._jobject.file_path])
def __clipboard_clear_func_cb(self, clipboard, data):
diff --git a/src/model/Makefile.am b/src/model/Makefile.am
index 0b7d14c..9447b03 100644
--- a/src/model/Makefile.am
+++ b/src/model/Makefile.am
@@ -5,6 +5,8 @@ sugar_PYTHON = \
__init__.py \
accesspointmodel.py \
BuddyModel.py \
+ clipboard.py \
+ clipboardobject.py \
Friends.py \
Invites.py \
Owner.py \
diff --git a/src/model/clipboard.py b/src/model/clipboard.py
new file mode 100644
index 0000000..bde6535
--- /dev/null
+++ b/src/model/clipboard.py
@@ -0,0 +1,149 @@
+# Copyright (C) 2006, Red Hat, Inc.
+#
+# 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 os
+import shutil
+import urlparse
+import tempfile
+
+import gobject
+
+from sugar import mime
+
+from model.clipboardobject import ClipboardObject, Format
+
+class Clipboard(gobject.GObject):
+
+ __gsignals__ = {
+ 'object-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([object])),
+ 'object-deleted': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([int])),
+ 'object-state-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([object])),
+ }
+
+ def __init__(self):
+ gobject.GObject.__init__(self)
+
+ self._objects = {}
+ self._next_id = 0
+
+ def _get_next_object_id(self):
+ self._next_id += 1
+ return self._next_id
+
+ def add_object(self, name):
+ logging.debug('Clipboard.add_object')
+ object_id = self._get_next_object_id()
+ self._objects[object_id] = ClipboardObject(object_id, name)
+ self.emit('object-added', self._objects[object_id])
+ return object_id
+
+ def add_object_format(self, object_id, format_type, data, on_disk):
+ logging.debug('Clipboard.add_object_format')
+ cb_object = self._objects[object_id]
+
+ if format_type == 'XdndDirectSave0':
+ format = Format('text/uri-list', data + '\r\n', on_disk)
+ format.owns_disk_data = True
+ cb_object.add_format(format)
+ elif on_disk and cb_object.get_percent() == 100:
+ new_uri = self._copy_file(data)
+ cb_object.add_format(Format(format_type, new_uri, on_disk))
+ logging.debug('Added format of type ' + format_type
+ + ' with path at ' + new_uri)
+ else:
+ cb_object.add_format(Format(format_type, data, on_disk))
+ logging.debug('Added in-memory format of type ' + format_type + '.')
+
+ self.emit('object-state-changed', cb_object)
+
+ def delete_object(self, object_id):
+ cb_object = self._objects.pop(object_id)
+ cb_object.destroy()
+ self.emit('object-deleted', object_id)
+ logging.debug('Deleted object with object_id %r' % object_id)
+
+ def set_object_percent(self, object_id, percent):
+ cb_object = self._objects[object_id]
+ if percent < 0 or percent > 100:
+ raise ValueError("invalid percentage")
+ if cb_object.get_percent() > percent:
+ raise ValueError("invalid percentage; less than current percent")
+ if cb_object.get_percent() == percent:
+ # ignore setting same percentage
+ return
+
+ cb_object.set_percent(percent)
+
+ if percent == 100:
+ self._process_object(cb_object)
+
+ self.emit('object-state-changed', cb_object)
+
+ def _process_object(self, cb_object):
+ formats = cb_object.get_formats()
+ for format_name, format in formats.iteritems():
+ if format.is_on_disk() and not format.owns_disk_data:
+ new_uri = self._copy_file(format.get_data())
+ format.set_data(new_uri)
+
+ # Add a text/plain format to objects that are text but lack it
+ if 'text/plain' not in formats.keys():
+ if 'UTF8_STRING' in formats.keys():
+ self.add_object_format(
+ cb_object.get_id(), 'text/plain',
+ data=formats['UTF8_STRING'].get_data(), on_disk=False)
+ elif 'text/unicode' in formats.keys():
+ self.add_object_format(
+ cb_object.get_id(), 'text/plain',
+ data=formats['UTF8_STRING'].get_data(), on_disk=False)
+
+ def get_object(self, object_id):
+ logging.debug('Clipboard.get_object')
+ return self._objects[object_id]
+
+ def get_object_data(self, object_id, format_type):
+ logging.debug('Clipboard.get_object_data')
+ cb_object = self._objects[object_id]
+ format = cb_object.get_formats()[format_type]
+ return format
+
+ def _copy_file(self, original_uri):
+ uri = urlparse.urlparse(original_uri)
+ path_, file_name = os.path.split(uri.path)
+
+ root, ext = os.path.splitext(file_name)
+ if not ext or ext == '.':
+ mime_type = mime.get_for_file(uri.path)
+ ext = '.' + mime.get_primary_extension(mime_type)
+
+ f_, new_file_path = tempfile.mkstemp(ext, root)
+ del f_
+ shutil.copyfile(uri.path, new_file_path)
+ os.chmod(new_file_path, 0644)
+
+ return 'file://' + new_file_path
+
+_instance = None
+
+def get_instance():
+ global _instance
+ if not _instance:
+ _instance = Clipboard()
+ return _instance
diff --git a/src/model/clipboardobject.py b/src/model/clipboardobject.py
new file mode 100644
index 0000000..850e937
--- /dev/null
+++ b/src/model/clipboardobject.py
@@ -0,0 +1,117 @@
+# 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 os
+import logging
+import urlparse
+
+from sugar import mime
+from sugar.bundle.activitybundle import ActivityBundle
+
+class ClipboardObject:
+
+ def __init__(self, object_path, name):
+ self._id = object_path
+ self._name = name
+ self._percent = 0
+ self._formats = {}
+
+ def destroy(self):
+ for format in self._formats.itervalues():
+ format.destroy()
+
+ def get_id(self):
+ return self._id
+
+ def get_name(self):
+ name = self._name
+ if not name:
+ name = mime.get_mime_description(self.get_mime_type())
+ if not name:
+ name = ''
+ return name
+
+ def get_icon(self):
+ return mime.get_mime_icon(self.get_mime_type())
+
+ def get_preview(self):
+ # TODO: should previews really be here?
+ #return self._get_type_info().get_preview()
+ return ''
+
+ def is_bundle(self):
+ # A bundle will have only one format.
+ if not self._formats:
+ return False
+ else:
+ return self._formats.keys()[0] in [ActivityBundle.MIME_TYPE,
+ ActivityBundle.DEPRECATED_MIME_TYPE]
+
+ def get_percent(self):
+ return self._percent
+
+ def set_percent(self, percent):
+ self._percent = percent
+
+ def add_format(self, format):
+ self._formats[format.get_type()] = format
+
+ def get_formats(self):
+ return self._formats
+
+ def get_mime_type(self):
+ if not self._formats:
+ return ''
+
+ format = mime.choose_most_significant(self._formats.keys())
+ if format == 'text/uri-list':
+ data = self._formats['text/uri-list'].get_data()
+ uri = urlparse.urlparse(mime.split_uri_list(data)[0], 'file')
+ if uri.scheme == 'file':
+ if os.path.exists(uri.path):
+ format = mime.get_for_file(uri.path)
+ else:
+ format = mime.get_from_file_name(uri.path)
+ logging.debug('Choosed %r!' % format)
+
+ return format
+
+class Format:
+
+ def __init__(self, mime_type, data, on_disk):
+ self.owns_disk_data = False
+
+ self._type = mime_type
+ self._data = data
+ self._on_disk = on_disk
+
+ def destroy(self):
+ if self._on_disk:
+ uri = urlparse.urlparse(self._data)
+ if os.path.isfile(uri.path):
+ os.remove(uri.path)
+
+ def get_type(self):
+ return self._type
+
+ def get_data(self):
+ return self._data
+
+ def set_data(self, data):
+ self._data = data
+
+ def is_on_disk(self):
+ return self._on_disk
diff --git a/src/view/Shell.py b/src/view/Shell.py
index 33dcbc0..26a66e6 100644
--- a/src/view/Shell.py
+++ b/src/view/Shell.py
@@ -251,22 +251,19 @@ class Shell(gobject.GObject):
screenshot.get_from_drawable(window, window.get_colormap(), x_orig,
y_orig, 0, 0, width, height)
screenshot.save(file_path, "png")
+ jobject = datastore.create()
try:
- jobject = datastore.create()
- try:
- jobject.metadata['title'] = _('Screenshot')
- jobject.metadata['keep'] = '0'
- jobject.metadata['buddies'] = ''
- jobject.metadata['preview'] = ''
- jobject.metadata['icon-color'] = profile.get_color().to_string()
- jobject.metadata['mime_type'] = 'image/png'
- jobject.file_path = file_path
- datastore.write(jobject)
- finally:
- jobject.destroy()
- del jobject
+ jobject.metadata['title'] = _('Screenshot')
+ jobject.metadata['keep'] = '0'
+ jobject.metadata['buddies'] = ''
+ jobject.metadata['preview'] = ''
+ jobject.metadata['icon-color'] = profile.get_color().to_string()
+ jobject.metadata['mime_type'] = 'image/png'
+ jobject.file_path = file_path
+ datastore.write(jobject, transfer_ownership=True)
finally:
- os.remove(file_path)
+ jobject.destroy()
+ del jobject
_instance = None
diff --git a/src/view/clipboardicon.py b/src/view/clipboardicon.py
index 729b97d..c5b6ae7 100644
--- a/src/view/clipboardicon.py
+++ b/src/view/clipboardicon.py
@@ -21,10 +21,9 @@ import gtk
from sugar.graphics.radiotoolbutton import RadioToolButton
from sugar.graphics.icon import Icon
from sugar.graphics.xocolor import XoColor
-from sugar.clipboard import clipboardservice
-from sugar.bundle.activitybundle import ActivityBundle
from sugar import profile
+from model import clipboard
from view.clipboardmenu import ClipboardMenu
from view.frame.frameinvoker import FrameWidgetInvoker
from view.frame.notification import NotificationIcon
@@ -33,66 +32,51 @@ import view.frame.frame
class ClipboardIcon(RadioToolButton):
__gtype_name__ = 'SugarClipboardIcon'
- def __init__(self, object_id, name, group):
+ def __init__(self, cb_object, group):
RadioToolButton.__init__(self, group=group)
- self._object_id = object_id
- self._name = name
- self._percent = 0
- self._preview = None
- self._activity = None
+ self._cb_object = cb_object
self.owns_clipboard = False
self.props.sensitive = False
self.props.active = False
self._notif_icon = None
+ self._current_percent = None
self._icon = Icon()
self._icon.props.xo_color = profile.get_color()
self.set_icon_widget(self._icon)
self._icon.show()
- cb_service = clipboardservice.get_instance()
+ cb_service = clipboard.get_instance()
cb_service.connect('object-state-changed',
self._object_state_changed_cb)
- obj = cb_service.get_object(self._object_id)
- self.palette = ClipboardMenu(self._object_id, self._name, self._percent,
- self._preview, self._activity,
- self._is_bundle(obj['FORMATS']))
+ self.palette = ClipboardMenu(cb_object)
self.palette.props.invoker = FrameWidgetInvoker(self)
child = self.get_child()
child.connect('drag_data_get', self._drag_data_get_cb)
self.connect('notify::active', self._notify_active_cb)
- def _is_bundle(self, formats):
- # A bundle will have only one format.
- return formats and formats[0] in [ActivityBundle.MIME_TYPE,
- ActivityBundle.DEPRECATED_MIME_TYPE]
-
def get_object_id(self):
- return self._object_id
+ return self._cb_object.get_id()
- def _drag_data_get_cb(self, widget, context, selection,
- targetType, eventTime):
+ def _drag_data_get_cb(self, widget, context, selection, target_type,
+ event_time):
logging.debug('_drag_data_get_cb: requested target ' + selection.target)
-
- cb_service = clipboardservice.get_instance()
- data = cb_service.get_object_data(self._object_id,
- selection.target)['DATA']
-
+ data = self._cb_object.get_formats()[selection.target].get_data()
selection.set(selection.target, 8, data)
def _put_in_clipboard(self):
logging.debug('ClipboardIcon._put_in_clipboard')
- if self._percent < 100:
+ if self._cb_object.get_percent() < 100:
raise ValueError('Object is not complete,' \
' cannot be put into the clipboard.')
targets = self._get_targets()
if targets:
- clipboard = gtk.Clipboard()
- if not clipboard.set_with_data(targets,
+ x_clipboard = gtk.Clipboard()
+ if not x_clipboard.set_with_data(targets,
self._clipboard_data_get_cb,
self._clipboard_clear_cb,
targets):
@@ -100,32 +84,24 @@ class ClipboardIcon(RadioToolButton):
else:
self.owns_clipboard = True
- def _clipboard_data_get_cb(self, clipboard, selection, info, targets):
+ def _clipboard_data_get_cb(self, x_clipboard, selection, info, targets):
if not selection.target in [target[0] for target in targets]:
logging.warning('ClipboardIcon._clipboard_data_get_cb: asked %s' \
' but only have %r.' % (selection.target, targets))
return
- cb_service = clipboardservice.get_instance()
- data = cb_service.get_object_data(self._object_id,
- selection.target)['DATA']
-
+ data = self._cb_object.get_formats()[selection.target].get_data()
selection.set(selection.target, 8, data)
- def _clipboard_clear_cb(self, clipboard, targets):
+ def _clipboard_clear_cb(self, x_clipboard, targets):
logging.debug('ClipboardIcon._clipboard_clear_cb')
self.owns_clipboard = False
- def _object_state_changed_cb(self, cb_service, object_id, name, percent,
- icon_name, preview, activity):
-
- if object_id != self._object_id:
+ def _object_state_changed_cb(self, cb_service, cb_object):
+ if cb_object != self._cb_object:
return
- cb_service = clipboardservice.get_instance()
- obj = cb_service.get_object(self._object_id)
-
- if icon_name:
- self._icon.props.icon_name = icon_name
+ if cb_object.get_icon():
+ self._icon.props.icon_name = cb_object.get_icon()
else:
self._icon.props.icon_name = 'application-octet-stream'
@@ -135,19 +111,11 @@ class ClipboardIcon(RadioToolButton):
gtk.gdk.ACTION_COPY)
child.drag_source_set_icon_name(self._icon.props.icon_name)
- self._name = name
- self._preview = preview
- self._activity = activity
- self.palette.update_state(name, percent, preview, activity,
- self._is_bundle(obj['FORMATS']))
-
- old_percent = self._percent
- self._percent = percent
- if self._percent == 100:
+ if cb_object.get_percent() == 100:
self.props.sensitive = True
# Clipboard object became complete. Make it the active one.
- if old_percent < 100 and self._percent == 100:
+ if self._current_percent < 100 and cb_object.get_percent() == 100:
self.props.active = True
self._notif_icon = NotificationIcon()
@@ -158,6 +126,7 @@ class ClipboardIcon(RadioToolButton):
frame = view.frame.frame.get_instance()
frame.add_notification(self._notif_icon,
view.frame.frame.BOTTOM_LEFT)
+ self._current_percent = cb_object.get_percent()
def _notify_active_cb(self, widget, pspec):
if self.props.active:
@@ -166,14 +135,8 @@ class ClipboardIcon(RadioToolButton):
self.owns_clipboard = False
def _get_targets(self):
- cb_service = clipboardservice.get_instance()
-
- attrs = cb_service.get_object(self._object_id)
- format_types = attrs[clipboardservice.FORMATS_KEY]
-
targets = []
- for format_type in format_types:
+ for format_type in self._cb_object.get_formats().keys():
targets.append((format_type, 0, 0))
-
return targets
diff --git a/src/view/clipboardmenu.py b/src/view/clipboardmenu.py
index f036aeb..5d55041 100644
--- a/src/view/clipboardmenu.py
+++ b/src/view/clipboardmenu.py
@@ -25,24 +25,26 @@ import gtk
from sugar.graphics.palette import Palette
from sugar.graphics.menuitem import MenuItem
from sugar.graphics.icon import Icon
-from sugar.clipboard import clipboardservice
from sugar.datastore import datastore
from sugar import mime
from sugar import profile
from sugar import activity
+from model import clipboard
+
class ClipboardMenu(Palette):
- def __init__(self, object_id, name, percent, preview,
- activities, installable):
- Palette.__init__(self, name)
+ def __init__(self, cb_object):
+ Palette.__init__(self, cb_object.get_name())
- self._object_id = object_id
- self._percent = percent
- self._activities = activities
+ self._cb_object = cb_object
self.set_group_id('frame')
+ cb_service = clipboard.get_instance()
+ cb_service.connect('object-state-changed',
+ self._object_state_changed_cb)
+
self._progress_bar = None
self._remove_item = MenuItem(_('Remove'), 'list-remove')
@@ -55,11 +57,6 @@ class ClipboardMenu(Palette):
self.menu.append(self._open_item)
self._open_item.show()
- #self._stop_item = MenuItem(_('Stop download'), 'stock-close')
- # TODO: Implement stopping downloads
- #self._stop_item.connect('activate', self._stop_item_activate_cb)
- #self.append_menu_item(self._stop_item)
-
self._journal_item = MenuItem(_('Keep'))
icon = Icon(icon_name='document-save', icon_size=gtk.ICON_SIZE_MENU,
xo_color=profile.get_color())
@@ -69,13 +66,14 @@ class ClipboardMenu(Palette):
self.menu.append(self._journal_item)
self._journal_item.show()
- self._update_items_visibility(installable)
+ self._update_items_visibility()
self._update_open_submenu()
def _update_open_submenu(self):
- logging.debug('_update_open_submenu: %r' % self._activities)
+ activities = self._get_activities()
+ logging.debug('_update_open_submenu: %r' % activities)
child = self._open_item.get_child()
- if self._activities is None or len(self._activities) <= 1:
+ if activities is None or len(activities) <= 1:
child.set_text(_('Open'))
if self._open_item.get_submenu() is not None:
self._open_item.remove_submenu()
@@ -91,7 +89,7 @@ class ClipboardMenu(Palette):
for item in submenu.get_children():
submenu.remove(item)
- for service_name in self._activities:
+ for service_name in activities:
registry = activity.get_registry()
activity_info = registry.get_activity(service_name)
@@ -104,29 +102,41 @@ class ClipboardMenu(Palette):
submenu.append(item)
item.show()
- def _update_items_visibility(self, installable):
- if self._percent == 100 and (self._activities or installable):
+ def _update_items_visibility(self):
+ activities = self._get_activities()
+ installable = self._cb_object.is_bundle()
+ percent = self._cb_object.get_percent()
+
+ if percent == 100 and (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._activities and not installable):
+ elif percent == 100 and (not activities and not installable):
self._remove_item.props.sensitive = True
self._open_item.props.sensitive = False
- #self._stop_item.props.sensitive = False
self._journal_item.props.sensitive = True
else:
self._remove_item.props.sensitive = True
self._open_item.props.sensitive = False
- # TODO: reenable the stop item when we implement stoping downloads.
- #self._stop_item.props.sensitive = True
self._journal_item.props.sensitive = False
self._update_progress_bar()
+ def _get_activities(self):
+ mime_type = self._cb_object.get_mime_type()
+ if not mime_type:
+ return ''
+
+ registry = activity.get_registry()
+ activities = registry.get_activities_for_type(mime_type)
+ if activities:
+ return [activity_info.bundle_id for activity_info in activities]
+ else:
+ return ''
+
def _update_progress_bar(self):
- if self._percent == 100.0:
+ percent = self._cb_object.get_percent()
+ if percent == 100.0:
if self._progress_bar:
self._progress_bar = None
self.set_content(None)
@@ -136,20 +146,21 @@ class ClipboardMenu(Palette):
self._progress_bar.show()
self.set_content(self._progress_bar)
- self._progress_bar.props.fraction = self._percent / 100.0
- self._progress_bar.props.text = '%.2f %%' % self._percent
+ self._progress_bar.props.fraction = percent / 100.0
+ self._progress_bar.props.text = '%.2f %%' % percent
- def update_state(self, name, percent, preview, activities, installable):
- self.set_primary_text(name)
- self._percent = percent
- self._activities = activities
+ def _object_state_changed_cb(self, cb_service, cb_object):
+ if cb_object != self._cb_object:
+ return
+ self.set_primary_text(cb_object.get_name())
self._update_progress_bar()
- self._update_items_visibility(installable)
+ self._update_items_visibility()
self._update_open_submenu()
def _open_item_activate_cb(self, menu_item):
logging.debug('_open_item_activate_cb')
- if self._percent < 100 or menu_item.get_submenu() is not None:
+ percent = self._cb_object.get_percent()
+ if percent < 100 or menu_item.get_submenu() is not None:
return
jobject = self._copy_to_journal()
jobject.resume(self._activities[0])
@@ -157,15 +168,16 @@ class ClipboardMenu(Palette):
def _open_submenu_item_activate_cb(self, menu_item, service_name):
logging.debug('_open_submenu_item_activate_cb')
- if self._percent < 100:
+ percent = self._cb_object.get_percent()
+ if percent < 100:
return
jobject = self._copy_to_journal()
jobject.resume(service_name)
jobject.destroy()
def _remove_item_activate_cb(self, menu_item):
- cb_service = clipboardservice.get_instance()
- cb_service.delete_object(self._object_id)
+ cb_service = clipboard.get_instance()
+ cb_service.delete_object(self._cb_object.get_id())
def _journal_item_activate_cb(self, menu_item):
logging.debug('_journal_item_activate_cb')
@@ -181,39 +193,38 @@ class ClipboardMenu(Palette):
return file_path
def _copy_to_journal(self):
- cb_service = clipboardservice.get_instance()
- obj = cb_service.get_object(self._object_id)
-
- format = mime.choose_most_significant(obj['FORMATS'])
- data = cb_service.get_object_data(self._object_id, format)
+ formats = self._cb_object.get_formats().keys()
+ most_significant_mime_type = mime.choose_most_significant(formats)
+ format = self._cb_object.get_formats()[most_significant_mime_type]
transfer_ownership = False
- if format == 'text/uri-list':
- uris = mime.split_uri_list(data['DATA'])
+ if most_significant_mime_type == 'text/uri-list':
+ uris = mime.split_uri_list(format.get_data())
if len(uris) == 1 and uris[0].startswith('file://'):
file_path = urlparse.urlparse(uris[0]).path
transfer_ownership = False
mime_type = mime.get_for_file(file_path)
else:
- file_path = self._write_to_temp_file(data['DATA'])
+ file_path = self._write_to_temp_file(format.get_data())
transfer_ownership = True
mime_type = 'text/uri-list'
else:
- if data['ON_DISK']:
- file_path = urlparse.urlparse(data['DATA']).path
+ if format.is_on_disk():
+ file_path = urlparse.urlparse(format.get_data()).path
transfer_ownership = False
mime_type = mime.get_for_file(file_path)
else:
- file_path = self._write_to_temp_file(data['DATA'])
+ file_path = self._write_to_temp_file(format.get_data())
transfer_ownership = True
sniffed_mime_type = mime.get_for_file(file_path)
if sniffed_mime_type == 'application/octet-stream':
- mime_type = format
+ mime_type = most_significant_mime_type
else:
mime_type = sniffed_mime_type
+ name = self._cb_object.get_name()
jobject = datastore.create()
- jobject.metadata['title'] = _('Clipboard object: %s.') % obj['NAME']
+ jobject.metadata['title'] = _('Clipboard object: %s.') % name
jobject.metadata['keep'] = '0'
jobject.metadata['buddies'] = ''
jobject.metadata['preview'] = ''
diff --git a/src/view/frame/clipboardpanelwindow.py b/src/view/frame/clipboardpanelwindow.py
index 10b234b..08794b8 100644
--- a/src/view/frame/clipboardpanelwindow.py
+++ b/src/view/frame/clipboardpanelwindow.py
@@ -22,7 +22,8 @@ import hippo
from view.frame.framewindow import FrameWindow
from view.frame.clipboardtray import ClipboardTray
-from sugar.clipboard import clipboardservice
+
+from model import clipboard
class ClipboardPanelWindow(FrameWindow):
def __init__(self, frame, orientation):
@@ -47,22 +48,22 @@ class ClipboardPanelWindow(FrameWindow):
self.connect("drag_data_received",
self._clipboard_tray.drag_data_received_cb)
- def _owner_change_cb(self, clipboard, event):
+ def _owner_change_cb(self, x_clipboard, event):
logging.debug("owner_change_cb")
if self._clipboard_tray.owns_clipboard():
return
- cb_service = clipboardservice.get_instance()
+ cb_service = clipboard.get_instance()
key = cb_service.add_object(name="")
cb_service.set_object_percent(key, percent=0)
- targets = clipboard.wait_for_targets()
+ targets = x_clipboard.wait_for_targets()
for target in targets:
if target not in ('TIMESTAMP', 'TARGETS',
'MULTIPLE', 'SAVE_TARGETS'):
logging.debug('Asking for target %s.' % target)
- selection = clipboard.wait_for_contents(target)
+ selection = x_clipboard.wait_for_contents(target)
if not selection:
logging.warning('no data for selection target %s.' % target)
continue
@@ -77,7 +78,7 @@ class ClipboardPanelWindow(FrameWindow):
logging.debug('adding type ' + selection.type + '.')
- cb_service = clipboardservice.get_instance()
+ cb_service = clipboard.get_instance()
if selection.type == 'text/uri-list':
uris = selection.get_uris()
diff --git a/src/view/frame/clipboardtray.py b/src/view/frame/clipboardtray.py
index b5ba093..94dcc3d 100644
--- a/src/view/frame/clipboardtray.py
+++ b/src/view/frame/clipboardtray.py
@@ -21,10 +21,10 @@ import tempfile
import gtk
from sugar import util
-from sugar.clipboard import clipboardservice
from sugar.graphics import tray
from sugar.graphics import style
+from model import clipboard
from view.clipboardicon import ClipboardIcon
class _ContextMap:
@@ -65,7 +65,7 @@ class ClipboardTray(tray.VTray):
self._icons = {}
self._context_map = _ContextMap()
- cb_service = clipboardservice.get_instance()
+ cb_service = clipboard.get_instance()
cb_service.connect('object-added', self._object_added_cb)
cb_service.connect('object-deleted', self._object_deleted_cb)
@@ -79,9 +79,9 @@ class ClipboardTray(tray.VTray):
if not selection.data:
return
- logging.debug('ClipboardTray: adding type ' + selection.type)
+ logging.debug('ClipboardTray: adding type %r' % selection.type)
- cb_service = clipboardservice.get_instance()
+ cb_service = clipboard.get_instance()
if selection.type == 'text/uri-list':
uris = selection.data.split('\n')
if len(uris) > 1:
@@ -98,30 +98,30 @@ class ClipboardTray(tray.VTray):
selection.data,
on_disk=False)
- def _object_added_cb(self, cb_service, object_id, name):
+ def _object_added_cb(self, cb_service, cb_object):
if self._icons:
group = self._icons.values()[0]
else:
group = None
- icon = ClipboardIcon(object_id, name, group)
+ icon = ClipboardIcon(cb_object, group)
self.add_item(icon)
icon.show()
- self._icons[object_id] = icon
+ self._icons[cb_object.get_id()] = icon
objects_to_delete = self.get_children()[:-self.MAX_ITEMS]
for icon in objects_to_delete:
logging.debug('ClipboardTray: deleting surplus object')
- cb_service = clipboardservice.get_instance()
+ cb_service = clipboard.get_instance()
cb_service.delete_object(icon.get_object_id())
- logging.debug('ClipboardTray: ' + object_id + ' was added.')
+ logging.debug('ClipboardTray: %r was added' % cb_object.get_id())
def _object_deleted_cb(self, cb_service, object_id):
icon = self._icons[object_id]
self.remove_item(icon)
del self._icons[object_id]
- logging.debug('ClipboardTray: ' + object_id + ' was deleted.')
+ logging.debug('ClipboardTray: %r was deleted' % object_id)
def drag_motion_cb(self, widget, context, x, y, time):
logging.debug('ClipboardTray._drag_motion_cb')
@@ -130,7 +130,7 @@ class ClipboardTray(tray.VTray):
def drag_drop_cb(self, widget, context, x, y, time):
logging.debug('ClipboardTray._drag_drop_cb')
- cb_service = clipboardservice.get_instance()
+ cb_service = clipboard.get_instance()
object_id = cb_service.add_object(name="")
self._context_map.add_context(context, object_id, len(context.targets))
@@ -179,8 +179,8 @@ class ClipboardTray(tray.VTray):
prop_type, format_, dest = \
window.property_get('XdndDirectSave0', 'text/plain')
- clipboard = clipboardservice.get_instance()
- clipboard.add_object_format( \
+ clipboardservice = clipboard.get_instance()
+ clipboardservice.add_object_format( \
object_id, 'XdndDirectSave0', dest, on_disk=True)
else:
self._add_selection(object_id, selection)