[Sugar-devel] [PATCH] Bring back dragging of elements from the activities to the frame clipboard - SL #3819
Manuel Quiñones
manuq at laptop.org
Thu Apr 4 11:00:42 EDT 2013
Note I have also applied this as a pull request to the github experiment:
https://github.com/sugarlabs/sugar/pull/14
2013/4/4 Manuel Quiñones <manuq at laptop.org>:
> TestCase:
>
> - open an activity like Browse, Read, Log (not Write, is a special case)
> - bring up the frame
> - drag things to the left side panel of the frame (images, links, or selected text)
>
> The elements should be added to the clipboard which is inside the
> panel. They should have the proper icon and they should popup a
> palette to act on them.
>
> Note: if the dragged object is a link from Browse, Sugar tries to copy
> the html to the disk. But the current implementation looks wrong. I
> have opened #4477 to track it: http://bugs.sugarlabs.org/ticket/4477
>
> Note: this doesn't solve the inverse operation: drag from the
> clipboard to the activity. This will be done in another patch.
>
> API fixes:
>
> - gtk.SelectionData.type -> Gtk.SelectionData.get_data_type() [1]
> - gtk.SelectionData.data -> Gtk.SelectionData.get_data() [2]
> - gtk.SelectionData.target -> Gtk.SelectionData.get_target() [3]
> - context.targets -> context.list_targets() [4]
> - context.drop_finish(...) -> Gdk.drop_finish(context, ...) [5]
> - context.drag_status(...) -> Gdk.drag_status(context, ...) [6]
> - context.get_source_widget() -> Gdk.drag_get_source_widget(context) [7]
>
> [1] https://developer.gnome.org/gtk3/3.5/gtk3-Selections.html#gtk-selection-data-get-data-type
> [2] https://developer.gnome.org/gtk3/3.5/gtk3-Selections.html#gtk-selection-data-get-data
> [3] https://developer.gnome.org/gtk3/3.5/gtk3-Selections.html#gtk-selection-data-get-target
> [4] https://developer.gnome.org/gdk/stable/gdk-Drag-and-Drop.html#gdk-drag-context-list-targets
> [5] https://developer.gnome.org/gdk/stable/gdk-Drag-and-Drop.html#gdk-drop-finish
> [6] https://developer.gnome.org/gdk/stable/gdk-Drag-and-Drop.html#gdk-drag-status
> [7] https://developer.gnome.org/gtk3/stable/gtk3-Drag-and-Drop.html#gtk-drag-get-source-widget
>
> Cast the type of the Gtk.SelectionData from Gdk.Atom to str. Our code
> treats it as str in sugar3.mime and asks methods like startswith which
> fails if it is not a str-like object.
>
> The data for the type 'text/uri-list' comes with a character '\x00' at
> the end now. Remove it so our functions like
> sugar3.mime.split_uri_list don't break.
>
> Signed-off-by: Manuel Quiñones <manuq at laptop.org>
> ---
> src/jarabe/frame/clipboardtray.py | 46 +++++++++++++++++++++++++--------------
> 1 file changed, 30 insertions(+), 16 deletions(-)
>
> diff --git a/src/jarabe/frame/clipboardtray.py b/src/jarabe/frame/clipboardtray.py
> index abc885e..5115d61 100644
> --- a/src/jarabe/frame/clipboardtray.py
> +++ b/src/jarabe/frame/clipboardtray.py
> @@ -76,26 +76,39 @@ class ClipboardTray(tray.VTray):
> return False
>
> def _add_selection(self, object_id, selection):
> - if not selection.data:
> + if not selection.get_data():
> return
>
> - logging.debug('ClipboardTray: adding type %r', selection.type)
> + selection_data = selection.get_data()
> + selection_type = selection.get_data_type()
> +
> + # The type comes as a Gdk.Atom but we need it as str to
> + # compare it.
> + assert isinstance(selection_type, Gdk.Atom)
> + selection_type = str(selection_type)
> +
> + logging.debug('ClipboardTray: adding type %r', selection_type)
>
> cb_service = clipboard.get_instance()
> - if selection.type == 'text/uri-list':
> - uris = selection.data.split('\n')
> + if selection_type == 'text/uri-list':
> + # For 'text/uri-list' type, last character is '\x00'. This
> + # wasn't the case in GTK2.
> + assert selection_data[-1] == '\x00'
> + selection_data = selection_data[:-1]
> +
> + uris = selection_data.split('\n')
> if len(uris) > 1:
> raise NotImplementedError('Multiple uris in text/uri-list' \
> ' still not supported.')
>
> cb_service.add_object_format(object_id,
> - selection.type,
> + selection_type,
> uris[0],
> on_disk=True)
> else:
> cb_service.add_object_format(object_id,
> - selection.type,
> - selection.data,
> + selection_type,
> + selection_data,
> on_disk=False)
>
> def _object_added_cb(self, cb_service, cb_object):
> @@ -132,9 +145,9 @@ class ClipboardTray(tray.VTray):
> logging.debug('ClipboardTray._drag_motion_cb')
>
> if self._internal_drag(context):
> - context.drag_status(Gdk.DragAction.MOVE, time)
> + Gdk.drag_status(context, Gdk.DragAction.MOVE, time)
> else:
> - context.drag_status(Gdk.DragAction.COPY, time)
> + Gdk.drag_status(context, Gdk.DragAction.COPY, time)
> self.props.drag_active = True
>
> return True
> @@ -148,15 +161,16 @@ class ClipboardTray(tray.VTray):
> if self._internal_drag(context):
> # TODO: We should move the object within the clipboard here
> if not self._context_map.has_context(context):
> - context.drop_finish(False, Gtk.get_current_event_time())
> + Gdk.drop_finish(context, False, Gtk.get_current_event_time())
> return False
>
> cb_service = clipboard.get_instance()
> object_id = cb_service.add_object(name="")
>
> - self._context_map.add_context(context, object_id, len(context.targets))
> + context_targets = context.list_targets()
> + self._context_map.add_context(context, object_id, len(context_targets))
>
> - for target in context.targets:
> + for target in context_targets:
> if str(target) not in ('TIMESTAMP', 'TARGETS', 'MULTIPLE'):
> widget.drag_get_data(context, target, time)
>
> @@ -167,13 +181,13 @@ class ClipboardTray(tray.VTray):
> def drag_data_received_cb(self, widget, context, x, y, selection,
> targetType, time):
> logging.debug('ClipboardTray: got data for target %r',
> - selection.target)
> + selection.get_target())
>
> object_id = self._context_map.get_object_id(context)
> try:
> if selection is None:
> logging.warn('ClipboardTray: empty selection for target %s',
> - selection.target)
> + selection.get_target())
> else:
> self._add_selection(object_id, selection)
>
> @@ -181,10 +195,10 @@ class ClipboardTray(tray.VTray):
> # If it's the last target to be processed, finish
> # the dnd transaction
> if not self._context_map.has_context(context):
> - context.drop_finish(True, Gtk.get_current_event_time())
> + Gdk.drop_finish(context, True, Gtk.get_current_event_time())
>
> def _internal_drag(self, context):
> - source_widget = context.get_source_widget()
> + source_widget = Gtk.drag_get_source_widget(context)
> if source_widget is None:
> return False
> view_ancestor = source_widget.get_ancestor(Gtk.Viewport)
> --
> 1.8.1.4
>
--
.. manuq ..
More information about the Sugar-devel
mailing list