Beispiel #1
0
    def on_drag_data_received(self,
                              widget,
                              context,
                              x,
                              y,
                              data,
                              info,
                              time,
                              user_data=None):
        if not self.pulse.online:
            print("not online")
            Gdk.drag_status(context, 0, time)
            return

        if not self.dropping:
            if self.blocking_new_sends:
                Gdk.drag_status(context, 0, time)
            else:
                Gdk.drag_status(context, Gdk.DragAction.COPY, time)
            return
        if data:
            if context.get_selected_action() == Gdk.DragAction.COPY:
                uris = data.get_uris()
                self.file_sender.send_files(uris)

        Gtk.drag_finish(context, True, False, time)
        self.dropping = False
Beispiel #2
0
    def onDragDataReceived(self, oWidget, oDragContext, nX, nY, oSelectionData, nInfo, nTime):

        if nInfo == 0:

            oModel = oWidget.get_model()
            oPath, nPosition = self.set_drag_dest(nX, nY)
            lstPaths = oSelectionData.get_data()

            if oPath.get_indices()[0] not in lstPaths:

                oDestIter = oModel.get_iter(oPath)

                for oIter in [oModel.get_iter_from_string(str(nPath)) for nPath in lstPaths]:

                    if nPosition == Gtk.TreeViewDropPosition.AFTER:

                        oModel.move_after(oIter, oDestIter)
                        oDestIter = oIter

                    else:

                        oModel.move_before(oIter, oDestIter)

            oWidget.set_drag_dest_row(None, Gtk.TreeViewDropPosition.AFTER)
            Gtk.drag_finish(oDragContext, True, True, nTime)

        else:

            strFunc = Gtk.Buildable.get_name(oWidget)
            strFunc = 'on' + strFunc[:1].upper() + strFunc[1:] + 'DragDataReceived'

            getattr(self.oClass, strFunc)(oSelectionData.get_uris())
            Gtk.drag_finish(oDragContext, True, False, nTime)
Beispiel #3
0
    def __dragDropCb(self, unused_widget, context, x, y, timestamp):
        success = False

        target = self.drag_dest_find_target(context, None)
        if not target:
            return False

        if target.name() == EFFECT_TARGET_ENTRY.target:
            self.info("Adding effect %s", self.timeline.dropData)
            self.timeline.resetSelectionGroup()
            self.timeline.current_group.add(self.ges_clip)
            self.timeline.selection.setSelection([self.ges_clip], SELECT)
            self.app.gui.switchContextTab(self.ges_clip)

            effect_info = self.app.effects.getInfo(self.timeline.dropData)
            pipeline = self.timeline.ges_timeline.get_parent()
            with self.app.action_log.started(
                    "add effect",
                    finalizing_action=CommitTimelineFinalizingAction(pipeline),
                    toplevel=True):
                self.add_effect(effect_info)
            self.timeline.cleanDropData()
            success = True

        Gtk.drag_finish(context, success, False, timestamp)

        return success
Beispiel #4
0
    def __dragDropCb(self, unused_widget, context, x, y, timestamp):
        success = False

        target = self.drag_dest_find_target(context, None)
        if not target:
            return False

        if target.name() == EFFECT_TARGET_ENTRY.target:
            self.info("Adding effect %s", self.timeline.dropData)
            self.timeline.resetSelectionGroup()
            self.timeline.selection.setSelection([self.ges_clip], SELECT)
            self.app.gui.switchContextTab(self.ges_clip)

            effect_info = self.app.effects.getInfo(self.timeline.dropData)
            pipeline = self.timeline.ges_timeline.get_parent()
            with self.app.action_log.started("add effect",
                                             finalizing_action=CommitTimelineFinalizingAction(pipeline),
                                             toplevel=True):
                self.add_effect(effect_info)
            self.timeline.cleanDropData()
            success = True

        Gtk.drag_finish(context, success, False, timestamp)

        return success
Beispiel #5
0
    def __drag_data_received(self, widget, ctx, x, y, sel, tid, etime):
        assert tid == DND_URI_LIST

        uris = sel.get_uris()

        dirs = []
        error = False
        for uri in uris:
            try:
                uri = URI(uri)
            except ValueError:
                continue

            if uri.is_filename:
                loc = os.path.normpath(uri.filename)
                if os.path.isdir(loc):
                    dirs.append(loc)
                else:
                    loc = os.path.realpath(loc)
                    if loc not in self.__library:
                        self.__library.add_filename(loc)
            elif app.player.can_play_uri(uri):
                if uri not in self.__library:
                    self.__library.add([RemoteFile(uri)])
            else:
                error = True
                break
        Gtk.drag_finish(ctx, not error, False, etime)
        if error:
            ErrorMessage(self, _("Unable to add songs"), _("%s uses an unsupported protocol.") % util.bold(uri)).run()
        else:
            if dirs:
                copool.add(self.__library.scan, dirs, cofuncid="library", funcid="library")
Beispiel #6
0
    def handle_new_group_drop(self, widget, context, x, y, time):
        old_group = self.get_current_group()
        old_list = self.file_handler.get_note_list(old_group)

        def on_created(group_name):
            if group_name is None:
                group_name = old_group
            else:
                old_list.remove(self.dragged_note)

                new_list = self.file_handler.get_note_list(group_name)
                new_list.append(self.dragged_note)

                self.file_handler.update_note_list(new_list, group_name)
                self.file_handler.update_note_list(old_list, old_group)

            self.dragged_note = None

            for row in self.group_list.get_children():
                if row.item.name == group_name:
                    self.group_list.select_row(row)
                    return

        self.create_new_group(on_created)

        Gtk.drag_finish(context, True, False, time)
Beispiel #7
0
    def on_drag_drop(self, widget, context, x, y, time):
        is_self_source = context.get_source_window() is self.drag_start_win
        is_external_add = self.is_external_add()
        # if reorder or append
        if is_self_source or is_external_add:
            found = self.list_view.get_dest_row_at_pos(x, y)
            if found:
                path, pos = found
                pos = self.fix_drag_pos(pos)
                insert_pos = int(str(path)) + (1 if pos is Gtk.TreeViewDropPosition.AFTER else 0)
            else:
                insert_pos = None

            if is_self_source:
                selection = self.list_view.get_selection()
                store, list = selection.get_selected_rows()

                result_pos = self.app.queue.reorder([int(str(path)) for path in list], insert_pos)

                # select reordered rows
                selection.unselect_all()
                for i in range(len(list)):
                    path = Gtk.TreePath.new_from_string(str(i + result_pos))
                    selection.select_path(path)

                Gtk.drag_finish(context, True, True, time)
            else:
                targets = [target for target in context.list_targets() if target.name() == 'text/uri-list']
                if len(targets) == 0:
                    return False
                self.drag_insert_pos = insert_pos
                self.list_view.drag_get_data(context, targets[0], time)

            return True
    def on_drag_data_received(self, text_view, drag_context, _x, _y, data,
                              info, time):
        """Handle drag and drop events"""

        text_buffer = text_view.get_buffer()

        if info == TARGET_URI:
            uris = data.get_uris()
            for uri in uris:
                name = basename(urllib.parse.unquote_plus(uri))
                mime = mimetypes.guess_type(uri)

                if mime[0] is not None and mime[0].startswith('image/'):
                    if uri.startswith("file://"):
                        uri = uri[7:]
                    text = "![{}]({})".format(name, uri)
                    limit_left = 2
                    limit_right = len(name)
                else:
                    text = "[{}]({})".format(name, uri)
                    limit_left = 1
                    limit_right = len(name)

        elif info == TARGET_TEXT:
            text = data.get_text()

            # delete automatically added DnD text
            insert_mark = text_buffer.get_insert()
            cursor_iter_r = text_buffer.get_iter_at_mark(insert_mark)
            cursor_iter_l = cursor_iter_r.copy()
            cursor_iter_l.backward_chars(len(data.get_text()))

            text_buffer.delete(cursor_iter_l, cursor_iter_r)

            if text.startswith(("http://", "https://", "www.")):
                print("web")
                text = "[{}]({})".format(_("web page"), text)
                limit_left = 1
                limit_right = len(_("web page"))
            else:
                limit_left = 0
                limit_right = 0

        text_buffer.place_cursor(
            text_buffer.get_iter_at_mark(
                text_buffer.get_mark('gtk_drag_target')))
        text_buffer.insert_at_cursor(text)
        insert_mark = text_buffer.get_insert()
        selection_bound = text_buffer.get_selection_bound()
        cursor_iter = text_buffer.get_iter_at_mark(insert_mark)
        cursor_iter.backward_chars(len(text) - limit_left)
        text_buffer.move_mark(insert_mark, cursor_iter)
        cursor_iter.forward_chars(limit_right)
        text_buffer.move_mark(selection_bound, cursor_iter)

        Gtk.drag_finish(drag_context, True, True, time)
        text_view.get_toplevel().present_with_time(time)
        return False
Beispiel #9
0
 def __drag_data_received(self, view, ctx, x, y, sel, tid, etime, library):
     # TreeModelSort doesn't support GtkTreeDragDestDrop.
     view.emit_stop_by_name('drag-data-received')
     model = view.get_model()
     if tid == DND_QL:
         filenames = qltk.selection_get_filenames(sel)
         songs = list(filter(None, [library.get(f) for f in filenames]))
         if not songs:
             Gtk.drag_finish(ctx, False, False, etime)
             return
         try:
             path, pos = view.get_dest_row_at_pos(x, y)
         except TypeError:
             playlist = XSPFBackedPlaylist.from_songs(PLAYLISTS, songs,
                                                      library)
             GLib.idle_add(self._select_playlist, playlist)
         else:
             playlist = model[path][0]
             playlist.extend(songs)
         self.changed(playlist)
         Gtk.drag_finish(ctx, True, False, etime)
         # Cause a refresh to the dragged-to playlist if it is selected
         # so that the dragged (duplicate) track(s) appears
         if playlist is self.__get_name_of_current_selected_playlist():
             model, plist_iter = self.__selected_playlists()
             songlist = qltk.get_top_parent(self).songlist
             self.activate(resort=not songlist.is_sorted())
     else:
         if tid == DND_URI_LIST:
             uri = sel.get_uris()[0]
             name = os.path.basename(uri)
         elif tid == DND_MOZ_URL:
             data = sel.get_data()
             uri, name = data.decode('utf16', 'replace').split('\n')
         else:
             Gtk.drag_finish(ctx, False, False, etime)
             return
         name = _name_for(name or os.path.basename(uri))
         try:
             sock = urlopen(uri)
             if uri.lower().endswith('.pls'):
                 playlist = parse_pls(sock, name, library=library)
             elif (uri.lower().endswith('.m3u') or
                     uri.lower().endswith('.m3u8')):
                 playlist = parse_m3u(sock, name, library=library)
             else:
                 raise IOError
             library.add(playlist.songs)
             self.changed(playlist)
             Gtk.drag_finish(ctx, True, False, etime)
         except IOError:
             Gtk.drag_finish(ctx, False, False, etime)
             qltk.ErrorMessage(
                 qltk.get_top_parent(self),
                 _("Unable to import playlist"),
                 _("Quod Libet can only import playlists in the M3U/M3U8 "
                   "and PLS formats.")).run()
Beispiel #10
0
 def __drag_data_received(self, view, ctx, x, y, sel, tid, etime, library):
     # TreeModelSort doesn't support GtkTreeDragDestDrop.
     view.emit_stop_by_name('drag-data-received')
     model = view.get_model()
     if tid == DND_QL:
         filenames = qltk.selection_get_filenames(sel)
         songs = list(filter(None, [library.get(f) for f in filenames]))
         if not songs:
             Gtk.drag_finish(ctx, False, False, etime)
             return
         try:
             path, pos = view.get_dest_row_at_pos(x, y)
         except TypeError:
             playlist = FileBackedPlaylist.from_songs(PLAYLISTS, songs,
                                                      library)
             GLib.idle_add(self._select_playlist, playlist)
         else:
             playlist = model[path][0]
             playlist.extend(songs)
         self.changed(playlist)
         Gtk.drag_finish(ctx, True, False, etime)
         # Cause a refresh to the dragged-to playlist if it is selected
         # so that the dragged (duplicate) track(s) appears
         if playlist is self.__get_name_of_current_selected_playlist():
             model, plist_iter = self.__selected_playlists()
             songlist = qltk.get_top_parent(self).songlist
             self.activate(resort=not songlist.is_sorted())
     else:
         if tid == DND_URI_LIST:
             uri = sel.get_uris()[0]
             name = os.path.basename(uri)
         elif tid == DND_MOZ_URL:
             data = sel.get_data()
             uri, name = data.decode('utf16', 'replace').split('\n')
         else:
             Gtk.drag_finish(ctx, False, False, etime)
             return
         name = _name_for(name or os.path.basename(uri))
         try:
             sock = urlopen(uri)
             if uri.lower().endswith('.pls'):
                 playlist = parse_pls(sock, name, library=library)
             elif (uri.lower().endswith('.m3u') or
                     uri.lower().endswith('.m3u8')):
                 playlist = parse_m3u(sock, name, library=library)
             else:
                 raise IOError
             library.add(playlist.songs)
             self.changed(playlist)
             Gtk.drag_finish(ctx, True, False, etime)
         except IOError:
             Gtk.drag_finish(ctx, False, False, etime)
             qltk.ErrorMessage(
                 qltk.get_top_parent(self),
                 _("Unable to import playlist"),
                 _("Quod Libet can only import playlists in the M3U/M3U8 "
                   "and PLS formats.")).run()
Beispiel #11
0
 def __drag_data_received(self, view, ctx, x, y, sel, tid, etime, library):
     # TreeModelSort doesn't support GtkTreeDragDestDrop.
     view.emit_stop_by_name('drag-data-received')
     model = view.get_model()
     if tid == DND_QL:
         filenames = qltk.selection_get_filenames(sel)
         songs = filter(None, map(library.get, filenames))
         if not songs:
             Gtk.drag_finish(ctx, False, False, etime)
             return
         try:
             path, pos = view.get_dest_row_at_pos(x, y)
         except TypeError:
             playlist = FileBackedPlaylist.from_songs(PLAYLISTS, songs,
                                                      library)
             GLib.idle_add(self._select_playlist, playlist)
         else:
             playlist = model[path][0]
             playlist.extend(songs)
         PlaylistsBrowser.changed(playlist)
         Gtk.drag_finish(ctx, True, False, etime)
     else:
         if tid == DND_URI_LIST:
             uri = sel.get_uris()[0]
             name = os.path.basename(uri)
         elif tid == DND_MOZ_URL:
             data = sel.get_data()
             uri, name = data.decode('utf16', 'replace').split('\n')
         else:
             Gtk.drag_finish(ctx, False, False, etime)
             return
         name = name or os.path.basename(uri) or _("New Playlist")
         uri = uri.encode('utf-8')
         try:
             sock = urllib.urlopen(uri)
             f = NamedTemporaryFile()
             f.write(sock.read())
             f.flush()
             if uri.lower().endswith('.pls'):
                 playlist = parse_pls(f.name, library=library)
             elif uri.lower().endswith('.m3u'):
                 playlist = parse_m3u(f.name, library=library)
             else:
                 raise IOError
             library.add_filename(playlist)
             if name:
                 playlist.rename(name)
             PlaylistsBrowser.changed(playlist)
             Gtk.drag_finish(ctx, True, False, etime)
         except IOError:
             Gtk.drag_finish(ctx, False, False, etime)
             qltk.ErrorMessage(
                 qltk.get_top_parent(self),
                 _("Unable to import playlist"),
                 _("Quod Libet can only import playlists in the M3U "
                   "and PLS formats.")).run()
Beispiel #12
0
 def __drag_data_received(self, view, ctx, x, y, sel, tid, etime, library):
     # TreeModelSort doesn't support GtkTreeDragDestDrop.
     view.emit_stop_by_name('drag-data-received')
     model = view.get_model()
     if tid == DND_QL:
         filenames = qltk.selection_get_filenames(sel)
         songs = listfilter(None, [library.get(f) for f in filenames])
         if not songs:
             Gtk.drag_finish(ctx, False, False, etime)
             return
         try:
             path, pos = view.get_dest_row_at_pos(x, y)
         except TypeError:
             playlist = FileBackedPlaylist.from_songs(PLAYLISTS, songs,
                                                      library)
             GLib.idle_add(self._select_playlist, playlist)
         else:
             playlist = model[path][0]
             playlist.extend(songs)
         self.changed(playlist)
         Gtk.drag_finish(ctx, True, False, etime)
     else:
         if tid == DND_URI_LIST:
             uri = sel.get_uris()[0]
             name = os.path.basename(uri)
         elif tid == DND_MOZ_URL:
             data = sel.get_data()
             uri, name = data.decode('utf16', 'replace').split('\n')
         else:
             Gtk.drag_finish(ctx, False, False, etime)
             return
         name = name or os.path.basename(uri) or _("New Playlist")
         uri = uri.encode('utf-8')
         try:
             sock = urlopen(uri)
             f = NamedTemporaryFile()
             f.write(sock.read())
             f.flush()
             if uri.lower().endswith('.pls'):
                 playlist = parse_pls(f.name, library=library)
             elif uri.lower().endswith('.m3u'):
                 playlist = parse_m3u(f.name, library=library)
             else:
                 raise IOError
             library.add_filename(playlist)
             if name:
                 playlist.rename(name)
             self.changed(playlist)
             Gtk.drag_finish(ctx, True, False, etime)
         except IOError:
             Gtk.drag_finish(ctx, False, False, etime)
             qltk.ErrorMessage(
                 qltk.get_top_parent(self),
                 _("Unable to import playlist"),
                 _("Quod Libet can only import playlists in the M3U "
                   "and PLS formats.")).run()
Beispiel #13
0
 def do_drag_data_received(self, drag_context, x, y, data, info, time):
     if info == self.TARGET_URI_LIST:
         self.feed_child(' '.join([
             "'" + Gio.file_new_for_uri(item).get_path() + "'"
             for item in Gedit.utils_drop_get_uris(data)
         ]).encode('utf-8'))
         Gtk.drag_finish(drag_context, True, False, time)
     else:
         Vte.Terminal.do_drag_data_received(self, drag_context, x, y, data,
                                            info, time)
Beispiel #14
0
    def _on_drag_data_received(self, widget, context, x, y, data, info, time):
        success = False

        for uri in data.get_data().split():
            with suppress(UnicodeDecodeError):
                uri = uri.decode('utf-8')
                if uri.endswith('.torrent'):
                    self._add_action.activate(GLib.Variant('s', uri))
                    success = True

        Gtk.drag_finish(context, success, success, time)
    def _on_drag_data_received(self, widget, context, x, y, data, info, time):
        success = False

        for uri in data.get_data().split():
            with suppress(UnicodeDecodeError):
                uri = uri.decode('utf-8')
                if uri.endswith('.torrent'):
                    self._add_action.activate(GLib.Variant('s', uri))
                    success = True

        Gtk.drag_finish(context, success, success, time)
Beispiel #16
0
 def do_drag_data_received(self, drag_context, x, y, data, info, time):
     if info == self.TARGET_URI_LIST:
         self.feed_child(
             " ".join(
                 ["'" + Gio.file_new_for_uri(item).get_path() + "'" for item in Gedit.utils_drop_get_uris(data)]
             ),
             -1,
         )
         Gtk.drag_finish(drag_context, True, False, time)
     else:
         Vte.Terminal.do_drag_data_received(self, drag_context, x, y, data, info, time)
    def drag_received_handler(self, widget, context, x, y, data, info, time):

        uuid = data.get_text()
        source = DragSource.registry[uuid]

        print(x, y)

        # parent = source.get_parent()
        # parent.remove(source)
        # widget.pack_start(source, False, False, 0)

        Gtk.drag_finish(context, True, True, time)
Beispiel #18
0
 def _drag_drop_cb(self, view, context, x, y, t):
     self._stop_hover_expand_timer()
     dest_treepath, drop_pos = self._get_checked_dest_row_at_pos(x, y)
     if dest_treepath is not None:
         src_path = self._drag_src_path
         dest_insert_path = self._get_insert_path_for_dest_row(dest_treepath, drop_pos)
         if not lib.layer.path_startswith(dest_insert_path, src_path):
             logger.debug("drag-drop: move %r to insert at %r", src_path, dest_insert_path)
             self._docmodel.restack_layer(src_path, dest_insert_path)
         Gtk.drag_finish(context, True, False, t)
         return True
     return False
Beispiel #19
0
 def __drag_data_received(self, widget, drag_ctx, x, y, data, info, time):
     if info == 42:
         uris = data.get_uris()
         if uris:
             try:
                 filename = URI(uris[0]).filename
             except ValueError:
                 pass
             else:
                 self.go_to(filename)
                 Gtk.drag_finish(drag_ctx, True, False, time)
                 return
     Gtk.drag_finish(drag_ctx, False, False, time)
Beispiel #20
0
 def __drag_data_received(self, widget, drag_ctx, x, y, data, info, time):
     if info == 42:
         uris = data.get_uris()
         if uris:
             try:
                 filename = uri2fsn(uris[0])
             except ValueError:
                 pass
             else:
                 self.go_to(filename)
                 Gtk.drag_finish(drag_ctx, True, False, time)
                 return
     Gtk.drag_finish(drag_ctx, False, False, time)
Beispiel #21
0
    def _dragDataReceivedCb(self, widget, context, x, y, data, info, time):
        if not self.dropDataReady:
            if data.get_length() > 0:
                if not self.dropOccured:
                    self.timeline.resetGhostClips()
                self.dropData = data.get_uris()
                self.dropDataReady = True

        if self.dropOccured:
            self.dropOccured = False
            Gtk.drag_finish(context, True, False, time)
            self._dragLeaveCb(widget, context, time)
        else:
            self.isDraggedClip = True
Beispiel #22
0
    def handle_drop(self, widget, context, x, y, time):
        new_group = widget.item.name
        new_list = self.file_handler.get_note_list(new_group)
        new_list.append(self.dragged_note)

        old_group = self.get_current_group()
        old_list = self.file_handler.get_note_list(old_group)
        old_list.remove(self.dragged_note)

        self.file_handler.update_note_list(new_list, new_group)
        self.file_handler.update_note_list(old_list, old_group)

        self.dragged_note = None

        Gtk.drag_finish(context, True, False, time)
Beispiel #23
0
    def traceTreeview_drag_data_received_cb(self, treeView, drag_context, x, y, data, info, time):
        self.log.info("Just receive DND data: {0}".format(data.get_text()))

        currentTrace = self.currentTrace

        # Find the dest trace
        model = treeView.get_model()
        path, pos = treeView.get_dest_row_at_pos(x, y)

        row = model[path]
        parentRow = row.get_parent()

        if parentRow is not None:
            destTrace = self.workspace.getImportedTrace(parentRow[0])
            destSession = destTrace.getSession(row[0])

            for messageId in data.get_text().split(";"):
                receivedMessage = currentTrace.getMessageByID(messageId)
                currentSession = receivedMessage.getSession()

                if destSession.id == currentSession.id:
                    self.log.error("Source and destination sessions are the same {0} == {1}".format(destSession.id, currentSession.id))
                    Gtk.drag_finish(drag_context, False, False, time)

                else:
                    self.log.info("Message {0} moved from trace {1} to {2} (session={3})".format(messageId,
                                                                                                 currentTrace.id,
                                                                                                 destTrace.id,
                                                                                                 destSession.id))

                    # Move message if requested
                    if drag_context.get_selected_action() == Gdk.DragAction.MOVE:
                        currentSession.removeMessage(receivedMessage)
                        currentTrace.removeMessage(receivedMessage.id)

                    message = receivedMessage.copy()
                    destSession.addMessage(message)
                    destTrace.addMessage(message)
                    message.setSession(destSession)

            # We force rewrite of the two traces (source and dest) and
            # update the left treeview.
            updatedTraces = [destTrace.id, currentTrace.id]
            self.workspace.saveConfigFile(overrideTraces=updatedTraces)
            self._refreshTraceList(traceListIds=updatedTraces)

            # Everything went file, we can tell the source to delete
            # data, if asked by the drag.
            if drag_context.get_selected_action() == Gdk.DragAction.MOVE:
                Gtk.drag_finish(drag_context, True, True, time)
            else:
                Gtk.drag_finish(drag_context, True, False, time)

        else:
            self.log.error("Messages can only be moved to a session. Traces can't be destination")
            Gtk.drag_finish(drag_context, False, False, time)
Beispiel #24
0
    def drop_event_cb(self, widget, context, x, y, selection, info, time):
        self.logger.debug('drop_event')
        if info != self.TARGET_TYPE_TEXT:
            Gtk.drag_finish(context, False, False, time)
            return False

        buf = selection.get_text().strip()
        if '\r\n' in buf:
            paths = buf.split('\r\n')
        else:
            paths = buf.split('\n')
        self.logger.debug("dropped filename(s): %s" % (str(paths)))

        self.make_ui_callback('drag-drop', paths)

        Gtk.drag_finish(context, True, False, time)
        return True
Beispiel #25
0
    def drop_event_cb(self, widget, context, x, y, selection, info, time):
        self.logger.debug('drop_event')
        if info != self.TARGET_TYPE_TEXT:
            Gtk.drag_finish(context, False, False, time)
            return False

        buf = selection.get_text().strip()
        if '\r\n' in buf:
            paths = buf.split('\r\n')
        else:
            paths = buf.split('\n')
        self.logger.debug("dropped filename(s): %s" % (str(paths)))

        self.make_ui_callback('drag-drop', paths)

        Gtk.drag_finish(context, True, False, time)
        return True
Beispiel #26
0
 def _drag_drop_cb(self, view, context, x, y, t):
     self._stop_hover_expand_timer()
     dest_treepath, drop_pos = self._get_checked_dest_row_at_pos(x, y)
     if dest_treepath is not None:
         src_path = self._drag_src_path
         dest_insert_path = self._get_insert_path_for_dest_row(
             dest_treepath,
             drop_pos,
         )
         if not lib.layer.path_startswith(dest_insert_path, src_path):
             logger.debug(
                 "drag-drop: move %r to insert at %r",
                 src_path,
                 dest_insert_path,
             )
             self._docmodel.restack_layer(src_path, dest_insert_path)
         Gtk.drag_finish(context, True, False, t)
         return True
     return False
    def on_drag_data_received(self, widget, drag_context, x, y,
                              data, info, time):
        """Handle drag and drop events"""
        if info == 1:
            # uri target
            uris = data.get_uris()
            print(uris)
            for uri in uris:
                uri = urllib.parse.unquote_plus(uri)
                mime = mimetypes.guess_type(uri)

                if mime[0] is not None and mime[0].startswith('image'):
                    if uri.startswith("file://"):
                        uri = uri[7:]
                    text = "![Insert image title here](%s)" % uri
                    ll = 2
                    lr = 23
                else:
                    text = "[Insert link title here](%s)" % uri
                    ll = 1
                    lr = 22
                self.TextBuffer.place_cursor(self.TextBuffer.get_iter_at_mark(
                    self.TextBuffer.get_mark('gtk_drag_target')))
                self.TextBuffer.insert_at_cursor(text)
                insert_mark = self.TextBuffer.get_insert()
                selection_bound = self.TextBuffer.get_selection_bound()
                cursor_iter = self.TextBuffer.get_iter_at_mark(insert_mark)
                cursor_iter.backward_chars(len(text) - ll)
                print('move_cursor')
                self.TextBuffer.move_mark(insert_mark, cursor_iter)
                cursor_iter.forward_chars(lr)
                self.TextBuffer.move_mark(selection_bound, cursor_iter)
                print('move selection')
       
        elif info == 2:
            # Text target
            self.TextBuffer.place_cursor(self.TextBuffer.get_iter_at_mark(
                self.TextBuffer.get_mark('gtk_drag_target')))
            self.TextBuffer.insert_at_cursor(data.get_text())
        Gtk.drag_finish(drag_context, True, True, time)
        self.present()
        print("returning true")
        return False
    def on_drag_data_received(self, text_view, drag_context, _x, _y, data,
                              info, time):
        """Handle drag and drop events"""

        text_buffer = text_view.get_buffer()
        if info == TARGET_URI:
            uris = data.get_uris()
            for uri in uris:
                uri = urllib.parse.unquote_plus(uri)
                mime = mimetypes.guess_type(uri)

                if mime[0] is not None and mime[0].startswith('image'):
                    if uri.startswith("file://"):
                        uri = uri[7:]
                    text = "![Image caption](%s)" % uri
                    limit_left = 2
                    limit_right = 23
                else:
                    text = "[Link description](%s)" % uri
                    limit_left = 1
                    limit_right = 22
                text_buffer.place_cursor(
                    text_buffer.get_iter_at_mark(
                        text_buffer.get_mark('gtk_drag_target')))
                text_buffer.insert_at_cursor(text)
                insert_mark = text_buffer.get_insert()
                selection_bound = text_buffer.get_selection_bound()
                cursor_iter = text_buffer.get_iter_at_mark(insert_mark)
                cursor_iter.backward_chars(len(text) - limit_left)
                text_buffer.move_mark(insert_mark, cursor_iter)
                cursor_iter.forward_chars(limit_right)
                text_buffer.move_mark(selection_bound, cursor_iter)

        elif info == TARGET_TEXT:
            text_buffer.place_cursor(
                text_buffer.get_iter_at_mark(
                    text_buffer.get_mark('gtk_drag_target')))
            text_buffer.insert_at_cursor(data.get_text())

        Gtk.drag_finish(drag_context, True, True, time)
        text_view.get_window().present_with_time(time)
        return False
Beispiel #29
0
    def __dragDropCb(self, unused_widget, context, x, y, timestamp):
        success = False

        target = self.drag_dest_find_target(context, None)
        if not target:
            return False

        if target.name() == ui.EFFECT_TARGET_ENTRY.target:
            self.info("Adding effect %s", self.timeline.dropData)
            self.app.gui.clipconfig.effect_expander.addEffectToClip(self.bClip,
                                                                    self.timeline.dropData)
            self.timeline.resetSelectionGroup()
            self.timeline.selection.setSelection([self.bClip], timelineUtils.SELECT)
            self.app.gui.switchContextTab(self.bClip)
            self.timeline.cleanDropData()
            success = True

        Gtk.drag_finish(context, success, True, timestamp)

        return success
Beispiel #30
0
    def do_drag_received(self, canvas, context, x, y, data, info, time):
        component = self.app.components[data.get_text()]
        Gtk.drag_finish(context, True, False, time)

        event_box = Gtk.EventBox()
        event_box.set_visible_window(False)
        event_box.add_events(Gdk.EventMask.POINTER_MOTION_HINT_MASK
                             | Gdk.EventMask.BUTTON_MOTION_MASK
                             | Gdk.EventMask.BUTTON_PRESS_MASK
                             | Gdk.EventMask.BUTTON_RELEASE_MASK)
        event_box.connect('button-press-event', self.do_child_press)
        event_box.connect('button-release-event', self.do_child_release)

        drawer = ComponentDrawer(self.app.builder, component(), False)
        event_box.add(drawer)
        drawer.set_visible(True)
        event_box.set_visible(True)
        canvas.put(event_box, x - ComponentDrawer.CANVAS_WIDTH / 2,
                   y - ComponentDrawer.CANVAS_HEIGHT / 2)

        canvas.get_window().invalidate_rect(None, True)
Beispiel #31
0
    def __dragDropCb(self, unused_widget, context, x, y, timestamp):
        success = False

        target = self.drag_dest_find_target(context, None)
        if not target:
            return False

        if target.name() == ui.EFFECT_TARGET_ENTRY.target:
            self.info("Adding effect %s", self.timeline.dropData)
            self.timeline.resetSelectionGroup()
            self.timeline.selection.setSelection([self.ges_clip], SELECT)
            self.app.gui.switchContextTab(self.ges_clip)

            self.app.gui.clipconfig.effect_expander.addEffectToClip(
                self.ges_clip, self.timeline.dropData)
            self.timeline.cleanDropData()
            success = True

        Gtk.drag_finish(context, success, True, timestamp)

        return success
    def on_drag_data_received(self, text_view, drag_context, _x, _y, data, info, time):
        """Handle drag and drop events"""

        text_buffer = text_view.get_buffer()
        if info == TARGET_URI:
            uris = data.get_uris()
            for uri in uris:
                uri = urllib.parse.unquote_plus(uri)
                mime = mimetypes.guess_type(uri)

                if mime[0] is not None and mime[0].startswith('image'):
                    if uri.startswith("file://"):
                        uri = uri[7:]
                    text = "![Image caption](%s)" % uri
                    limit_left = 2
                    limit_right = 23
                else:
                    text = "[Link description](%s)" % uri
                    limit_left = 1
                    limit_right = 22
                text_buffer.place_cursor(text_buffer.get_iter_at_mark(
                    text_buffer.get_mark('gtk_drag_target')))
                text_buffer.insert_at_cursor(text)
                insert_mark = text_buffer.get_insert()
                selection_bound = text_buffer.get_selection_bound()
                cursor_iter = text_buffer.get_iter_at_mark(insert_mark)
                cursor_iter.backward_chars(len(text) - limit_left)
                text_buffer.move_mark(insert_mark, cursor_iter)
                cursor_iter.forward_chars(limit_right)
                text_buffer.move_mark(selection_bound, cursor_iter)

        elif info == TARGET_TEXT:
            text_buffer.place_cursor(text_buffer.get_iter_at_mark(
                text_buffer.get_mark('gtk_drag_target')))
            text_buffer.insert_at_cursor(data.get_text())

        Gtk.drag_finish(drag_context, True, True, time)
        text_view.get_window().present_with_time(time)
        return False
Beispiel #33
0
    def do_drag_received(self, canvas, context, x, y, data, info, time):
        component = self.app.components[data.get_text()]
        Gtk.drag_finish(context, True, False, time)

        event_box = Gtk.EventBox()
        event_box.set_visible_window(False)
        event_box.add_events(Gdk.EventMask.POINTER_MOTION_HINT_MASK
                        | Gdk.EventMask.BUTTON_MOTION_MASK
                        | Gdk.EventMask.BUTTON_PRESS_MASK
                        | Gdk.EventMask.BUTTON_RELEASE_MASK)
        event_box.connect('button-press-event', self.do_child_press)
        event_box.connect('button-release-event', self.do_child_release)

        drawer = ComponentDrawer(self.app.builder, component(), False)
        event_box.add(drawer)
        drawer.set_visible(True)
        event_box.set_visible(True)
        canvas.put(event_box,
                   x - ComponentDrawer.CANVAS_WIDTH / 2,
                   y - ComponentDrawer.CANVAS_HEIGHT/ 2)

        canvas.get_window().invalidate_rect(None, True)
Beispiel #34
0
    def __drag_data_received(self, widget, ctx, x, y, sel, tid, etime):
        assert tid == DND_URI_LIST

        uris = sel.get_uris()

        dirs = []
        error = False
        for uri in uris:
            try:
                uri = URI(uri)
            except ValueError:
                continue

            if uri.is_filename:
                loc = os.path.normpath(uri.filename)
                if os.path.isdir(loc):
                    dirs.append(loc)
                else:
                    loc = os.path.realpath(loc)
                    if loc not in self.__library:
                        self.__library.add_filename(loc)
            elif app.player.can_play_uri(uri):
                if uri not in self.__library:
                    self.__library.add([RemoteFile(uri)])
            else:
                error = True
                break
        Gtk.drag_finish(ctx, not error, False, etime)
        if error:
            ErrorMessage(
                self, _("Unable to add songs"),
                _("%s uses an unsupported protocol.") % util.bold(uri)).run()
        else:
            if dirs:
                copool.add(self.__library.scan,
                           dirs,
                           cofuncid="library",
                           funcid="library")
Beispiel #35
0
 def on_drag_data_received(self, widget, drag_context, x, y, data, info,
                           time):
     pb = data.get_pixbuf()
     if pb:
         print("Got a pixbuf")
         Gtk.drag_finish(drag_context, True, False, time)
         self.show_image_pixbuf(pb)
     else:
         uris = data.get_uris()
         if uris and len(uris) == 1:
             print("Got URIs", uris)
             self.show_image_uri(uris[0])
             Gtk.drag_finish(drag_context, True, False, time)
         else:
             print("Got nothing")
             Gtk.drag_finish(drag_context, False, False, time)
Beispiel #36
0
    def __drag_data_received(self, view, ctx, x, y, sel, info, etime, library):
        model = view.get_model()
        if info == DND_QL:
            filenames = qltk.selection_get_filenames(sel)
            move = bool(ctx.get_selected_action() & Gdk.DragAction.MOVE)
        elif info == DND_URI_LIST:
            def to_filename(s):
                try:
                    return uri2fsn(s)
                except ValueError:
                    return None

            filenames = list(filter(None, map(
                to_filename, sel.get_uris())))
            move = False
        else:
            Gtk.drag_finish(ctx, False, False, etime)
            return

        to_add = []
        for filename in filenames:
            if filename not in library.librarian:
                library.add_filename(filename)
            elif filename not in library:
                to_add.append(library.librarian[filename])
        library.add(to_add)
        songs = list(filter(None, map(library.get, filenames)))
        if not songs:
            Gtk.drag_finish(ctx, bool(not filenames), False, etime)
            return

        if not self.__drop_by_row:
            success = self.__drag_data_browser_dropped(songs)
            Gtk.drag_finish(ctx, success, False, etime)
            return

        try:
            path, position = view.get_dest_row_at_pos(x, y)
        except TypeError:
            path = max(0, len(model) - 1)
            position = Gtk.TreeViewDropPosition.AFTER

        if move and Gtk.drag_get_source_widget(ctx) == view:
            iter = model.get_iter(path) # model can't be empty, we're moving
            if position in (Gtk.TreeViewDropPosition.BEFORE,
                            Gtk.TreeViewDropPosition.INTO_OR_BEFORE):
                while self.__drag_iters:
                    model.move_before(self.__drag_iters.pop(0), iter)
            else:
                while self.__drag_iters:
                    model.move_after(self.__drag_iters.pop(), iter)
            Gtk.drag_finish(ctx, True, False, etime)
        else:
            song = songs.pop(0)
            try:
                iter = model.get_iter(path)
            except ValueError:
                iter = model.append(row=[song]) # empty model
            else:
                if position in (Gtk.TreeViewDropPosition.BEFORE,
                                Gtk.TreeViewDropPosition.INTO_OR_BEFORE):
                    iter = model.insert_before(iter, [song])
                else:
                    iter = model.insert_after(iter, [song])
            for song in songs:
                iter = model.insert_after(iter, [song])
            Gtk.drag_finish(ctx, True, move, etime)
Beispiel #37
0
    def on_drag_data_received(self, widget: Gtk.Widget,
                              drag_context: Gdk.DragContext, x: int, y: int,
                              data: Gtk.SelectionData, info: int,
                              time: int) -> None:

        print(f'Drag info: {info}')

        # Handle normal dnd from other apps with files as a target
        if info == TARGET_ENTRY_TEXT:
            uris = data.get_text().split('\n')

            print(data.get_text())
            for uri in uris:
                # Skip empty items
                if not uri:
                    continue

                p = urlparse(unquote_plus(uri))
                filename = os.path.abspath(os.path.join(p.netloc, p.path))
                self.emit('document-import', filename)

        # Handle reordering and moving inside Norka's virtual filesystem
        elif info == TARGET_ENTRY_REORDER:
            origin_item = self.selected_folder if self.is_folder_selected else self.selected_document

            dest_path = self.view.get_path_at_pos(x, y)
            if not dest_path:
                print("No dest path")
                return

            dest_iter = self.model.get_iter(dest_path)
            dest_item_id = self.model.get_value(dest_iter, 3)

            if dest_item_id == -1:
                dest_item = Folder(title=self.model.get_value(dest_iter, 1),
                                   path=self.model.get_value(dest_iter, 2))
            else:
                dest_item = self.storage.get(dest_item_id)

            # Don't move item to itself :)
            if origin_item.absolute_path == dest_item.absolute_path:
                print("Don't move item to itself")
                return

            # Create folders when doc dropped onto doc
            # After creation rename dialog should appear
            if isinstance(dest_item, Document):
                folder_id = self.create_folder(
                    f'{origin_item.title} + {dest_item.title}',
                    self.current_folder_path)

                if folder_id:
                    folder = self.storage.get_folder(folder_id)
                    self.storage.move(origin_item.document_id,
                                      folder.absolute_path)
                    self.storage.move(dest_item.document_id,
                                      folder.absolute_path)
                    self.reload_items()
                return

                # For folders, we have to move folder and its content to destination
            if isinstance(origin_item, Folder):
                print(
                    f'Folder "{origin_item.title}": "{origin_item.path}" -> "{dest_item.absolute_path}"'
                )

                self.storage.move_folder(origin_item, dest_item.absolute_path)
                self.reload_items()
            # For regular documents it is easy to move - just update the `path`.
            else:
                if self.storage.update(origin_item.document_id,
                                       {'path': dest_item.absolute_path}):
                    print(
                        f'Moved {origin_item.title} to {dest_item.absolute_path}'
                    )
                    self.reload_items()

        Gtk.drag_finish(
            drag_context, True,
            drag_context.get_selected_action() == Gdk.DragAction.MOVE, time)
Beispiel #38
0
def drop_cb(wid, context, xpos, ypos, time_stamp):
    """
    DND callback that finishes the DND operation
    """
    Gtk.drag_finish(context, True, False, time_stamp)
    return True
Beispiel #39
0
 def on_wmain_window_drag_data_received(self, widget, drag_context, x, y,
                                        data, info, time):
     uris = data.get_uris()
     self.add_several_files(uris)
     Gtk.drag_finish(drag_context, True, Gdk.DragAction.COPY, time)
Beispiel #40
0
 def do_drag_drop(self, context, x, y, time, user_data=None):
     Gtk.drag_finish(context, True, False, time)
Beispiel #41
0
 def on_wmain_window_drag_data_received(self, widget, drag_context, x, y, data, info, time):
     uris = data.get_uris()
     self.add_several_files(uris)
     Gtk.drag_finish(drag_context, True, Gdk.DragAction.COPY, time)
Beispiel #42
0
 def on_drag_data_received(self, widget, context, x, y, data, info,
                           timestamp):
     self.add_to_stash(data.get_target(), data)
     Gtk.drag_finish(context, True, False, timestamp)
    def traceTreeview_drag_data_received_cb(self, treeView, drag_context, x, y,
                                            data, info, time):
        self.log.info("Just receive DND data: {0}".format(data.get_text()))

        currentTrace = self.currentTrace

        # Find the dest trace
        model = treeView.get_model()
        path, pos = treeView.get_dest_row_at_pos(x, y)

        row = model[path]
        parentRow = row.get_parent()

        if parentRow is not None:
            destTrace = self.workspace.getImportedTrace(parentRow[0])
            destSession = destTrace.getSession(row[0])

            for messageId in data.get_text().split(";"):
                receivedMessage = currentTrace.getMessageByID(messageId)
                currentSession = receivedMessage.getSession()

                if destSession.id == currentSession.id:
                    self.log.error(
                        "Source and destination sessions are the same {0} == {1}"
                        .format(destSession.id, currentSession.id))
                    Gtk.drag_finish(drag_context, False, False, time)

                else:
                    self.log.info(
                        "Message {0} moved from trace {1} to {2} (session={3})"
                        .format(messageId, currentTrace.id, destTrace.id,
                                destSession.id))

                    # Move message if requested
                    if drag_context.get_selected_action(
                    ) == Gdk.DragAction.MOVE:
                        currentSession.removeMessage(receivedMessage)
                        currentTrace.removeMessage(receivedMessage.id)

                    message = receivedMessage.copy()
                    destSession.addMessage(message)
                    destTrace.addMessage(message)
                    message.setSession(destSession)

            # We force rewrite of the two traces (source and dest) and
            # update the left treeview.
            updatedTraces = [destTrace.id, currentTrace.id]
            self.workspace.saveConfigFile(overrideTraces=updatedTraces)
            self._refreshTraceList(traceListIds=updatedTraces)

            # Everything went file, we can tell the source to delete
            # data, if asked by the drag.
            if drag_context.get_selected_action() == Gdk.DragAction.MOVE:
                Gtk.drag_finish(drag_context, True, True, time)
            else:
                Gtk.drag_finish(drag_context, True, False, time)

        else:
            self.log.error(
                "Messages can only be moved to a session. Traces can't be destination"
            )
            Gtk.drag_finish(drag_context, False, False, time)
Beispiel #44
0
def drop_cb(wid, context, xpos, ypos, time_stamp):
    """
    DND callback that finishes the DND operation
    """
    Gtk.drag_finish(context, True, False, time_stamp)
    return True
Beispiel #45
0
    def receiveCallback(self, widget, context, x, y, selection, targetType, time, data):
        self.dnd_data_received = True

        if selection.get_text() != "samuel":
            print "invalid selection data. ignored"
            return False

        x, y = data
        # convert the x, y co-ords into the gui checkers representation
        gc_loc = self.board.get_gc_loc(x, y)
        self.dst = gc_loc
        board_position = engine.hmove(self.src, self.dst)
        self.board.set_board_position(board_position)
        self.board.set_board_status()

        # fixme
        if self.game.legalmove == 0:
            # illegal move so set piece back at source square
            zx, zy = self.board.get_x_y(self.src)
            pce = self.board.get_piece_at_square(zx, zy)
            self.board.set_piece_at_square(self.src, pce)
            self.board.display_board()
            return False

        # Set piece at dest square as dragged piece
        pce = self.board.get_piece_at_square(x, y)
        self.board.set_piece_at_square(gc_loc, pce)

        # if move was a jump then set the square jumped over to empty
        diff = self.dst - self.src
        if diff < 0:
            diff = -diff
        hdiff = diff / 2

        # 8 or 10 is a jump
        # 4 or 5 is normal move
        if diff > 5:
            if self.dst > self.src:
                gc_loc = self.src + hdiff
            else:
                gc_loc = self.src - hdiff
            self.board.set_piece_at_square(gc_loc, 0)
            zx, zy = self.board.get_x_y(gc_loc)
            self.eb[zx][zy].queue_draw()

        Gtk.drag_finish(context, True, True, time)

        # fixme
        if self.game.legalmove == 2000:
            # double jump not yet completed - don't call computer move
            self.init_all_dnd()
            return False

        stm = self.game.get_side_to_move()
        red_player, white_player = self.game.get_players()

        self.init_all_dnd()

        # If human is playing both sides (i.e. computer is off) then return
        # now without calling the engine
        if stm == RED and red_player != COMPUTER:
            return False

        if stm == WHITE and white_player != COMPUTER:
            return False

        # kick off computer move
        self.game.comp_move()

        return False
Beispiel #46
0
    def receiveCallback(self, widget, context, x, y, selection, targetType,
                        time, data):
        self.dnd_data_received = True

        if selection.get_text() != "samuel":
            print("invalid selection data. ignored")
            return False

        x, y = data
        # convert the x, y co-ords into the gui checkers representation
        gc_loc = self.board.get_gc_loc(x, y)
        self.dst = gc_loc
        board_position = engine.hmove(self.src, self.dst)
        self.board.set_board_position(board_position)
        self.board.set_board_status()

        # fixme
        if self.game.legalmove == 0:
            # illegal move so set piece back at source square
            zx, zy = self.board.get_x_y(self.src)
            pce = self.board.get_piece_at_square(zx, zy)
            self.board.set_piece_at_square(self.src, pce)
            self.board.display_board()
            return False

        # Set piece at dest square as dragged piece
        pce = self.board.get_piece_at_square(x, y)
        self.board.set_piece_at_square(gc_loc, pce)

        # if move was a jump then set the square jumped over to empty
        diff = self.dst - self.src
        if diff < 0: diff = -diff
        hdiff = diff / 2

        # 8 or 10 is a jump
        # 4 or 5 is normal move
        if diff > 5:
            if self.dst > self.src:
                gc_loc = self.src + hdiff
            else:
                gc_loc = self.src - hdiff
            self.board.set_piece_at_square(gc_loc, 0)
            zx, zy = self.board.get_x_y(gc_loc)
            self.eb[zx][zy].queue_draw()

        Gtk.drag_finish(context, True, True, time)

        # fixme
        if self.game.legalmove == 2000:
            # double jump not yet completed - don't call computer move
            self.init_all_dnd()
            return False

        stm = self.game.get_side_to_move()
        red_player, white_player = self.game.get_players()

        self.init_all_dnd()

        # If human is playing both sides (i.e. computer is off) then return
        # now without calling the engine
        if stm == RED and red_player != COMPUTER:
            return False

        if stm == WHITE and white_player != COMPUTER:
            return False

        # kick off computer move
        GLib.timeout_add(1000, self.game.comp_move)
        self.board.display_board()
        return False
Beispiel #47
0
    def __drag_data_received(self, view, ctx, x, y, sel, info, etime, library):
        model = view.get_model()
        if info == DND_QL:
            filenames = qltk.selection_get_filenames(sel)
            move = (Gtk.drag_get_source_widget(ctx) == view)
        elif info == DND_URI_LIST:
            def to_filename(s):
                try:
                    return URI(s).filename
                except ValueError:
                    return None

            filenames = filter(None, map(to_filename, sel.get_uris()))
            move = False
        else:
            Gtk.drag_finish(ctx, False, False, etime)
            return

        to_add = []
        for filename in filenames:
            if filename not in library.librarian:
                library.add_filename(filename)
            elif filename not in library:
                to_add.append(library.librarian[filename])
        library.add(to_add)
        songs = filter(None, map(library.get, filenames))
        if not songs:
            Gtk.drag_finish(ctx, bool(not filenames), False, etime)
            return

        if not self.__drop_by_row:
            success = self.__drag_data_browser_dropped(songs)
            Gtk.drag_finish(ctx, success, False, etime)
            return

        try:
            path, position = view.get_dest_row_at_pos(x, y)
        except TypeError:
            path = max(0, len(model) - 1)
            position = Gtk.TreeViewDropPosition.AFTER

        if move and Gtk.drag_get_source_widget(ctx) == view:
            iter = model.get_iter(path) # model can't be empty, we're moving
            if position in (Gtk.TreeViewDropPosition.BEFORE,
                            Gtk.TreeViewDropPosition.INTO_OR_BEFORE):
                while self.__drag_iters:
                    model.move_before(self.__drag_iters.pop(0), iter)
            else:
                while self.__drag_iters:
                    model.move_after(self.__drag_iters.pop(), iter)
            Gtk.drag_finish(ctx, True, False, etime)
        else:
            song = songs.pop(0)
            try:
                iter = model.get_iter(path)
            except ValueError:
                iter = model.append(row=[song]) # empty model
            else:
                if position in (Gtk.TreeViewDropPosition.BEFORE,
                                Gtk.TreeViewDropPosition.INTO_OR_BEFORE):
                    iter = model.insert_before(iter, [song])
                else:
                    iter = model.insert_after(iter, [song])
            for song in songs:
                iter = model.insert_after(iter, [song])
            Gtk.drag_finish(ctx, True, move, etime)