Esempio n. 1
0
    def on_dnd_received(self, treeview, drag_context, x, y, selection, _info,
                        timestamp):
        drop_info = treeview.get_dest_row_at_pos(x, y)

        if selection.get_data():
            if not os.path.isdir(
                    self.config.musicdir[self.config.profile_num]):
                return
            # DND from outside sonata:
            uri = selection.get_data().strip().decode('utf-8')
            path = urllib.request.url2pathname(uri)
            paths = path.rsplit('\n')
            mpdpaths = []
            # Strip off paranthesis so that we can DND entire music dir
            # if we wish.
            musicdir = self.config.musicdir[self.config.profile_num][:-1]
            for i, path in enumerate(paths):
                paths[i] = path.rstrip('\r')
                if paths[i].startswith('file://'):
                    paths[i] = paths[i][7:]
                elif paths[i].startswith('file:'):
                    paths[i] = paths[i][5:]
                if paths[i].startswith(musicdir):
                    paths[i] = paths[i][len(musicdir):]
                    if len(paths[i]) == 0:
                        paths[i] = "/"
                    listallinfo = self.mpd.listallinfo(paths[i])
                    for item in listallinfo:
                        if 'file' in item:
                            mpdpaths.append(item['file'])

                # Add local file, available in mpd 0.14. This currently
                # work because python-mpd does not support unix socket
                # paths, won't which is needed for authentication for
                # local files. It's also therefore untested.
                if os.path.isdir(paths[i]):
                    filenames = misc.get_files_recursively(paths[i])
                else:
                    filenames = [paths[i]]
                for filename in filenames:
                    if os.path.exists(filename):
                        mpdpaths.append("file://" +
                                        urllib.parse.quote(filename))
            if len(mpdpaths) > 0:
                # Items found, add to list at drop position:
                if drop_info:
                    destpath, position = drop_info
                    if position in (Gtk.TreeViewDropPosition.BEFORE,
                                    Gtk.TreeViewDropPosition.INTO_OR_BEFORE):
                        songid = destpath[0]
                    else:
                        songid = destpath[0] + 1
                else:
                    songid = len(self.store)
                for mpdpath in mpdpaths:
                    self.mpd.addid(mpdpath, songid)
            self.iterate_now()
            return

        # Otherwise, it's a DND just within the current playlist
        model = self.store
        _foobar, selected = self.selection.get_selected_rows()

        # calculate all this now before we start moving stuff
        drag_sources = []
        for path in selected:
            index = path[0]
            treeiter = model.get_iter(path)
            songid = self.get_songid(treeiter, model)
            drag_sources.append([index, treeiter, songid])

        # Keep track of the moved iters so we can select them afterwards
        moved_iters = []

        # Will manipulate model to prevent the entire playlist from refreshing
        offset = 0
        self.mpd.command_list_ok_begin()
        for index, treeiter, songid in drag_sources:
            if drop_info:
                destpath, position = drop_info
                dest = destpath[0] + offset
                if dest < index:
                    offset = offset + 1
                pop_from = index
                move_to = dest
                if position in (Gtk.TreeViewDropPosition.BEFORE,
                                Gtk.TreeViewDropPosition.INTO_OR_BEFORE):
                    insert_to = dest
                    if dest < index + 1:
                        pop_from = index + 1
                    else:
                        move_to = dest - 1
                else:
                    insert_to = dest + 1
                    if dest < index:
                        pop_from = index + 1
                        move_to = insert_to
            else:
                dest = len(self.store) - 1
                insert_to = dest + 1

            self.mpd.moveid(songid, move_to)
            moved_iters.append(model.insert(insert_to, tuple(model[index])))
            model.remove(treeiter)

            # now fixup
            for source in drag_sources:
                if dest < index:
                    # we moved it back, so all indexes inbetween increased by 1
                    if dest < source[0] < index:
                        source[0] += 1
                else:
                    # we moved it ahead, so all indexes inbetween
                    # decreased by 1
                    if index < source[0] < dest:
                        source[0] -= 1
        self.mpd.command_list_end()

        # we are manipulating the model manually for speed, so...
        self.update_skip = True

        # Gdk.DragContext.get_action() returns a bitmask of actions
        if drag_context.get_actions() & Gdk.DragAction.MOVE:
            Gdk.drag_finish(drag_context, True, True, timestamp)
            self.header_hide_all_indicators(self.view, False)
        self.iterate_now()

        selection = treeview.get_selection()
        selection.unselect_all()
        for i in moved_iters:
            selection.select_iter(i)

        if moved_iters:
            treeview.scroll_to_cell(model.get_path(moved_iters[0]), None)
Esempio n. 2
0
    def on_dnd(self, treeview, drag_context, x, y, selection, _info,
               timestamp):
        drop_info = treeview.get_dest_row_at_pos(x, y)

        if selection.data is not None:
            if not os.path.isdir(self.config.musicdir[self.config.profile_num]):
                return
            # DND from outside sonata:
            uri = selection.data.strip()
            path = urllib.request.url2pathname(uri)
            paths = path.rsplit('\n')
            mpdpaths = []
            # Strip off paranthesis so that we can DND entire music dir
            # if we wish.
            musicdir = self.config.musicdir[self.config.profile_num][:-1]
            for i, path in enumerate(paths):
                paths[i] = path.rstrip('\r')
                if paths[i].startswith('file://'):
                    paths[i] = paths[i][7:]
                elif paths[i].startswith('file:'):
                    paths[i] = paths[i][5:]
                if paths[i].startswith(musicdir):
                    paths[i] = paths[i][len(musicdir):]
                    if len(paths[i]) == 0:
                        paths[i] = "/"
                    listallinfo = self.mpd.listallinfo(paths[i])
                    for item in listallinfo:
                        if 'file' in item:
                            mpdpaths.append(item['file'])

                # Add local file, available in mpd 0.14. This currently
                # work because python-mpd does not support unix socket
                # paths, won't which is needed for authentication for
                # local files. It's also therefore untested.
                if os.path.isdir(paths[i]):
                    filenames = misc.get_files_recursively(paths[i])
                else:
                    filenames = [paths[i]]
                for filename in filenames:
                    if os.path.exists(filename):
                        mpdpaths.append("file://" + urllib.parse.quote(filename))
            if len(mpdpaths) > 0:
                # Items found, add to list at drop position:
                if drop_info:
                    destpath, position = drop_info
                    if position in (Gtk.TreeViewDropPosition.BEFORE,
                                    Gtk.TreeViewDropPosition.INTO_OR_BEFORE):
                        songid = destpath[0]
                    else:
                        songid = destpath[0] + 1
                else:
                    songid = len(self.currentdata)
                for mpdpath in mpdpaths:
                    self.mpd.addid(mpdpath, songid)
            self.iterate_now()
            return

        # Otherwise, it's a DND just within the current playlist
        model = treeview.get_model()
        _foobar, selected = self.current_selection.get_selected_rows()

        # calculate all this now before we start moving stuff
        drag_sources = []
        for path in selected:
            index = path[0]
            i = model.get_iter(path)
            songid = self.current_get_songid(i, model)
            text = model.get_value(i, 1)
            drag_sources.append([index, i, songid, text])

        # Keep track of the moved iters so we can select them afterwards
        moved_iters = []

        # We will manipulate self.current_songs and model to prevent
        # the entire playlist from refreshing
        offset = 0
        self.mpd.command_list_ok_begin()
        for source in drag_sources:
            index, i, songid, text = source
            if drop_info:
                destpath, position = drop_info
                dest = destpath[0] + offset
                if dest < index:
                    offset = offset + 1
                if position in (Gtk.TreeViewDropPosition.BEFORE,
                                Gtk.TreeViewDropPosition.INTO_OR_BEFORE):
                    self.current_songs.insert(dest, self.current_songs[index])
                    if dest < index + 1:
                        self.current_songs.pop(index + 1)
                        self.mpd.moveid(songid, dest)
                    else:
                        self.current_songs.pop(index)
                        self.mpd.moveid(songid, dest - 1)
                    model.insert(dest, model[index])
                    moved_iters += [model.get_iter((dest,))]
                    model.remove(i)
                else:
                    self.current_songs.insert(dest + 1,
                                              self.current_songs[index])
                    if dest < index:
                        self.current_songs.pop(index + 1)
                        self.mpd.moveid(songid, dest + 1)
                    else:
                        self.current_songs.pop(index)
                        self.mpd.moveid(songid, dest)
                    model.insert(dest + 1, model[index])
                    moved_iters += [model.get_iter((dest + 1,))]
                    model.remove(i)
            else:
                #dest = int(self.status['playlistlength']) - 1
                dest = len(self.currentdata) - 1
                self.mpd.moveid(songid, dest)
                self.current_songs.insert(dest + 1, self.current_songs[index])
                self.current_songs.pop(index)
                model.insert(dest + 1, model[index])
                moved_iters += [model.get_iter((dest + 1,))]
                model.remove(i)
            # now fixup
            for source in drag_sources:
                if dest < index:
                    # we moved it back, so all indexes inbetween increased by 1
                    if dest < source[0] < index:
                        source[0] += 1
                else:
                    # we moved it ahead, so all indexes inbetween
                    # decreased by 1
                    if index < source[0] < dest:
                        source[0] -= 1
        self.mpd.command_list_end()

        # we are manipulating the model manually for speed, so...
        self.current_update_skip = True

        if drag_context.action == Gdk.DragAction.MOVE:
            drag_context.finish(True, True, timestamp)
            self.header_hide_all_indicators(self.current, False)
        self.iterate_now()

        GLib.idle_add(self.dnd_retain_selection, treeview.get_selection(),
                      moved_iters)
Esempio n. 3
0
    def on_dnd_received(self, treeview, drag_context, x, y, selection, _info, timestamp):
        drop_info = treeview.get_dest_row_at_pos(x, y)

        if selection.get_data():
            if not os.path.isdir(self.config.current_musicdir):
                return
            # DND from outside sonata:
            uri = selection.get_data().strip().decode('utf-8')
            path = urllib.request.url2pathname(uri)
            paths = path.rsplit('\n')
            mpdpaths = []
            # Strip off paranthesis so that we can DND entire music dir
            # if we wish.
            musicdir = self.config.current_musicdir[:-1]
            for i, path in enumerate(paths):
                paths[i] = path.rstrip('\r')
                if paths[i].startswith('file://'):
                    paths[i] = paths[i][7:]
                elif paths[i].startswith('file:'):
                    paths[i] = paths[i][5:]
                if paths[i].startswith(musicdir):
                    paths[i] = paths[i][len(musicdir):]
                    if len(paths[i]) == 0:
                        paths[i] = "/"
                    listallinfo = self.mpd.listallinfo(paths[i])
                    for item in listallinfo:
                        if 'file' in item:
                            mpdpaths.append(item['file'])

                # Add local file, available in mpd 0.14. This currently
                # work because python-mpd does not support unix socket
                # paths, won't which is needed for authentication for
                # local files. It's also therefore untested.
                if os.path.isdir(paths[i]):
                    filenames = misc.get_files_recursively(paths[i])
                else:
                    filenames = [paths[i]]
                for filename in filenames:
                    if os.path.exists(filename):
                        mpdpaths.append("file://" + urllib.parse.quote(filename))
            if len(mpdpaths) > 0:
                # Items found, add to list at drop position:
                if drop_info:
                    destpath, position = drop_info
                    if position in (Gtk.TreeViewDropPosition.BEFORE,
                                    Gtk.TreeViewDropPosition.INTO_OR_BEFORE):
                        songid = destpath[0]
                    else:
                        songid = destpath[0] + 1
                else:
                    songid = len(self.store)
                for mpdpath in mpdpaths:
                    self.mpd.addid(mpdpath, songid)
            self.iterate_now()
            return

        # Otherwise, it's a DND just within the current playlist
        model = self.store
        _foobar, selected = self.selection.get_selected_rows()

        # calculate all this now before we start moving stuff
        drag_sources = []
        for path in selected:
            index = path[0]
            treeiter = model.get_iter(path)
            songid = self.get_songid(treeiter, model)
            drag_sources.append([index, treeiter, songid])

        # Keep track of the moved iters so we can select them afterwards
        moved_iters = []

        # Will manipulate model to prevent the entire playlist from refreshing
        offset = 0
        self.mpd.command_list_ok_begin()
        for index, treeiter, songid in drag_sources:
            if drop_info:
                destpath, position = drop_info
                dest = destpath[0] + offset
                if dest < index:
                    offset = offset + 1
                pop_from = index
                move_to = dest
                if position in (Gtk.TreeViewDropPosition.BEFORE,
                                Gtk.TreeViewDropPosition.INTO_OR_BEFORE):
                    insert_to = dest
                    if dest < index + 1:
                        pop_from = index + 1
                    else:
                        move_to = dest - 1
                else:
                    insert_to = dest + 1
                    if dest < index:
                        pop_from = index + 1
                        move_to = insert_to
            else:
                dest = len(self.store) - 1
                insert_to = dest + 1

            self.mpd.moveid(songid, move_to)
            moved_iters.append(model.insert(insert_to, tuple(model[index])))
            model.remove(treeiter)

            # now fixup
            for source in drag_sources:
                if dest < index:
                    # we moved it back, so all indexes inbetween increased by 1
                    if dest < source[0] < index:
                        source[0] += 1
                else:
                    # we moved it ahead, so all indexes inbetween
                    # decreased by 1
                    if index < source[0] < dest:
                        source[0] -= 1
        self.mpd.command_list_end()

        # we are manipulating the model manually for speed, so...
        self.update_skip = True

        # Gdk.DragContext.get_action() returns a bitmask of actions
        if drag_context.get_actions() & Gdk.DragAction.MOVE:
            Gdk.drag_finish(drag_context, True, True, timestamp)
            self.header_hide_all_indicators(self.view, False)
        self.iterate_now()

        selection = treeview.get_selection()
        selection.unselect_all()
        for i in moved_iters:
            selection.select_iter(i)

        if moved_iters:
            treeview.scroll_to_cell(model.get_path(moved_iters[0]), None)