diff --git a/NEWS b/NEWS index 822af1da..9f539a5d 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +* #3003 Make image drags on the clipboard work consistently. (marco) + Snapshot 8ef6c57f8b * #3478 Fix handling of non-default types. (bertf) diff --git a/services/shell/clipboardobject.py b/services/shell/clipboardobject.py index c3cdab35..ea5a9a11 100644 --- a/services/shell/clipboardobject.py +++ b/services/shell/clipboardobject.py @@ -95,17 +95,21 @@ class ClipboardObject: format = mime.choose_most_significant(self._formats.keys()) - if format == 'text/uri-list': + uri = None + if format == 'XdndDirectSave0': + uri = self._formats['XdndDirectSave0'].get_data() + elif format == 'text/uri-list': data = self._formats['text/uri-list'].get_data() - uris = data.split('\n') - if len(uris) == 1 or not uris[1]: - uri = urlparse.urlparse(uris[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) + uri = data.split('\n')[0] + + if uri: + uri = urlparse.urlparse(uri, '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 diff --git a/services/shell/clipboardservice.py b/services/shell/clipboardservice.py index 6671fbfb..f0b2baa2 100644 --- a/services/shell/clipboardservice.py +++ b/services/shell/clipboardservice.py @@ -75,7 +75,9 @@ class ClipboardService(dbus.service.Object): logging.debug('ClipboardService.add_object_format') cb_object = self._objects[str(object_path)] - if on_disk and cb_object.get_percent() == 100: + if format_type == 'XdndDirectSave0': + cb_object.add_format(Format(format_type, data, on_disk)) + 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) @@ -114,7 +116,7 @@ class ClipboardService(dbus.service.Object): if percent == 100: formats = cb_object.get_formats() for format_name, format in formats.iteritems(): - if format.is_on_disk(): + if format.is_on_disk() and format_name != 'XdndDirectSave0': new_uri = self._copy_file(format.get_data()) format.set_data(new_uri) diff --git a/shell/view/frame/clipboardbox.py b/shell/view/frame/clipboardbox.py index 9c6d8591..1195c022 100644 --- a/shell/view/frame/clipboardbox.py +++ b/shell/view/frame/clipboardbox.py @@ -16,6 +16,7 @@ import os import logging +import tempfile import hippo import gtk @@ -137,9 +138,28 @@ class ClipboardBox(hippo.CanvasBox): self._context_map.add_context(context, object_id, len(context.targets)) - for target in context.targets: - if str(target) not in ('TIMESTAMP', 'TARGETS', 'MULTIPLE'): - widget.drag_get_data(context, target, time) + if 'XdndDirectSave0' in context.targets: + window = context.source_window + prop_type, format, filename = \ + window.property_get('XdndDirectSave0','text/plain') + + # FIXME query the clipboard service for a filename? + base_dir = tempfile.gettempdir() + dest_filename = util.unique_id() + + name, dot, extension = filename.rpartition('.') + dest_filename += dot + extension + + dest_uri = 'file://' + os.path.join(base_dir, dest_filename) + + window.property_change('XdndDirectSave0', prop_type, format, + gtk.gdk.PROP_MODE_REPLACE, dest_uri) + + widget.drag_get_data(context, 'XdndDirectSave0', time) + else: + for target in context.targets: + if str(target) not in ('TIMESTAMP', 'TARGETS', 'MULTIPLE'): + widget.drag_get_data(context, target, time) cb_service.set_object_percent(object_id, percent=100) @@ -147,12 +167,24 @@ class ClipboardBox(hippo.CanvasBox): def drag_data_received_cb(self, widget, context, x, y, selection, targetType, time): logging.debug('ClipboardBox: got data for target %r' % selection.target) + + object_id = self._context_map.get_object_id(context) try: - if selection: - object_id = self._context_map.get_object_id(context) - self._add_selection(object_id, selection) - else: + if selection is None: logging.warn('ClipboardBox: empty selection for target ' + selection.target) + elif selection.target == 'XdndDirectSave0': + if selection.data == 'S': + window = context.source_window + + prop_type, format, dest = \ + window.property_get('XdndDirectSave0','text/plain') + + clipboard = clipboardservice.get_instance() + clipboard.add_object_format( + object_id, 'XdndDirectSave0', dest, on_disk=True) + else: + self._add_selection(object_id, selection) + finally: # If it's the last target to be processed, finish the dnd transaction if not self._context_map.has_context(context):