Ticket #3819: 0001-Bring-back-dragging-of-elements-from-the-activities-.patch

File 0001-Bring-back-dragging-of-elements-from-the-activities-.patch, 7.5 KB (added by manuq, 11 years ago)
  • src/jarabe/frame/clipboardtray.py

    From 589700e59ee1f613ec0edc5a9a18a12e64fdca55 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= <manuq@laptop.org>
    Date: Tue, 2 Apr 2013 22:56:05 -0300
    Subject: [PATCH] Bring back dragging of elements from the activities to the
     frame clipboard - SL #3819
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    Mail-Followup-To: <sugar-devel@lists.sugarlabs.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@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 b class ClipboardTray(tray.VTray): 
    7676        return False
    7777
    7878    def _add_selection(self, object_id, selection):
    79         if not selection.data:
     79        if not selection.get_data():
    8080            return
    8181
    82         logging.debug('ClipboardTray: adding type %r', selection.type)
     82        selection_data = selection.get_data()
     83        selection_type = selection.get_data_type()
     84
     85        # The type comes as a Gdk.Atom but we need it as str to
     86        # compare it.
     87        assert isinstance(selection_type, Gdk.Atom)
     88        selection_type = str(selection_type)
     89
     90        logging.debug('ClipboardTray: adding type %r', selection_type)
    8391
    8492        cb_service = clipboard.get_instance()
    85         if selection.type == 'text/uri-list':
    86             uris = selection.data.split('\n')
     93        if selection_type == 'text/uri-list':
     94            # For 'text/uri-list' type, last character is '\x00'.  This
     95            # wasn't the case in GTK2.
     96            assert selection_data[-1] == '\x00'
     97            selection_data = selection_data[:-1]
     98
     99            uris = selection_data.split('\n')
    87100            if len(uris) > 1:
    88101                raise NotImplementedError('Multiple uris in text/uri-list' \
    89102                                          ' still not supported.')
    90103
    91104            cb_service.add_object_format(object_id,
    92                                          selection.type,
     105                                         selection_type,
    93106                                         uris[0],
    94107                                         on_disk=True)
    95108        else:
    96109            cb_service.add_object_format(object_id,
    97                                          selection.type,
    98                                          selection.data,
     110                                         selection_type,
     111                                         selection_data,
    99112                                         on_disk=False)
    100113
    101114    def _object_added_cb(self, cb_service, cb_object):
    class ClipboardTray(tray.VTray): 
    132145        logging.debug('ClipboardTray._drag_motion_cb')
    133146
    134147        if self._internal_drag(context):
    135             context.drag_status(Gdk.DragAction.MOVE, time)
     148            Gdk.drag_status(context, Gdk.DragAction.MOVE, time)
    136149        else:
    137             context.drag_status(Gdk.DragAction.COPY, time)
     150            Gdk.drag_status(context, Gdk.DragAction.COPY, time)
    138151            self.props.drag_active = True
    139152
    140153        return True
    class ClipboardTray(tray.VTray): 
    148161        if self._internal_drag(context):
    149162            # TODO: We should move the object within the clipboard here
    150163            if not self._context_map.has_context(context):
    151                 context.drop_finish(False, Gtk.get_current_event_time())
     164                Gdk.drop_finish(context, False, Gtk.get_current_event_time())
    152165            return False
    153166
    154167        cb_service = clipboard.get_instance()
    155168        object_id = cb_service.add_object(name="")
    156169
    157         self._context_map.add_context(context, object_id, len(context.targets))
     170        context_targets = context.list_targets()
     171        self._context_map.add_context(context, object_id, len(context_targets))
    158172
    159         for target in context.targets:
     173        for target in context_targets:
    160174            if str(target) not in ('TIMESTAMP', 'TARGETS', 'MULTIPLE'):
    161175                widget.drag_get_data(context, target, time)
    162176
    class ClipboardTray(tray.VTray): 
    167181    def drag_data_received_cb(self, widget, context, x, y, selection,
    168182                              targetType, time):
    169183        logging.debug('ClipboardTray: got data for target %r',
    170             selection.target)
     184            selection.get_target())
    171185
    172186        object_id = self._context_map.get_object_id(context)
    173187        try:
    174188            if selection is None:
    175189                logging.warn('ClipboardTray: empty selection for target %s',
    176                     selection.target)
     190                    selection.get_target())
    177191            else:
    178192                self._add_selection(object_id, selection)
    179193
    class ClipboardTray(tray.VTray): 
    181195            # If it's the last target to be processed, finish
    182196            # the dnd transaction
    183197            if not self._context_map.has_context(context):
    184                 context.drop_finish(True, Gtk.get_current_event_time())
     198                Gdk.drop_finish(context, True, Gtk.get_current_event_time())
    185199
    186200    def _internal_drag(self, context):
    187         source_widget = context.get_source_widget()
     201        source_widget = Gtk.drag_get_source_widget(context)
    188202        if source_widget is None:
    189203            return False
    190204        view_ancestor = source_widget.get_ancestor(Gtk.Viewport)