Fix drag n' dropping in the files tab

This commit is contained in:
Andrew Resch 2008-12-07 12:42:09 +00:00
parent 983c07f869
commit 253b8a857f
3 changed files with 131 additions and 42 deletions

View File

@ -119,8 +119,10 @@ class Torrent:
self.waiting_on_resume_data = False
# Keep a list of file indexes we're waiting for file_rename alerts on
# This also includes the old_folder and new_folder to know what signal to send
# This is so we can send one folder_renamed signal instead of multiple
# file_renamed signals.
# [(old_folder, new_folder, [*indexes]), ...]
self.waiting_on_folder_rename = []
# We store the filename just in case we need to make a copy of the torrentfile
@ -824,8 +826,10 @@ class Torrent:
if new_folder[-1:] != "/":
new_folder += "/"
wait_on_folder = (folder, new_folder, [])
for f in self.get_files():
if f["path"].startswith(folder):
# Keep a list of filerenames we're waiting on
self.waiting_on_folder_rename.append(f["index"])
wait_on_folder[2].append(f["index"])
self.handle.rename_file(f["index"], f["path"].replace(folder, new_folder, 1))
self.waiting_on_folder_rename.append(wait_on_folder)

View File

@ -757,16 +757,23 @@ class TorrentManager(component.Component):
log.debug("index: %s name: %s", alert.index, alert.name)
torrent_id = str(alert.handle.info_hash())
torrent = self.torrents[torrent_id]
old_folder = os.path.split(torrent.files[alert.index]["path"])[0]
new_folder = os.path.split(alert.name)[0]
torrent.files[alert.index]["path"] = alert.name
if alert.index in torrent.waiting_on_folder_rename:
if torrent.waiting_on_folder_rename == [alert.index]:
# This is the last alert we were waiting for, time to send signal
component.get("SignalManager").emit("torrent_folder_renamed", torrent_id, old_folder, new_folder)
torrent.waiting_on_folder_rename.remove(alert.index)
else:
# We need to see if this file index is in a waiting_on_folder list
folder_rename = False
for i, wait_on_folder in enumerate(torrent.waiting_on_folder_rename):
if alert.index in wait_on_folder[2]:
folder_rename = True
if len(wait_on_folder[2]) == 1:
# This is the last alert we were waiting for, time to send signal
component.get("SignalManager").emit("torrent_folder_renamed", torrent_id, wait_on_folder[0], wait_on_folder[1])
del torrent.waiting_on_folder_rename[i]
break
# This isn't the last file to be renamed in this folder, so just
# remove the index and continue
torrent.waiting_on_folder_rename[i][2].remove(alert.index)
if not folder_rename:
# This is just a regular file rename so send the signal
component.get("SignalManager").emit("torrent_file_renamed", torrent_id, alert.index, alert.name)

View File

@ -484,6 +484,7 @@ class FilesTab(Tab):
def _on_filename_edited(self, renderer, path, new_text):
index = self.treestore[path][5]
log.debug("new_text: %s", new_text)
# Don't do anything if the text hasn't changed
if new_text == self.treestore[path][0]:
@ -494,17 +495,17 @@ class FilesTab(Tab):
# We are renaming a file
itr = self.treestore.get_iter(path)
# Recurse through the treestore to get the actual path of the file
def get_filepath(i, fp):
if self.treestore.iter_parent(i):
fp = get_filepath(self.treestore.iter_parent(i), fp)
else:
fp += self.treestore[i][0]
return fp
def get_filepath(i):
ip = self.treestore.iter_parent(i)
fp = ""
while ip:
fp = self.treestore[ip][0] + fp
ip = self.treestore.iter_parent(ip)
return fp
# Only recurse if file is in a folder..
if self.treestore.iter_parent(itr):
filepath = get_filepath(itr, str()) + new_text
filepath = get_filepath(itr) + new_text
else:
filepath = new_text
@ -579,7 +580,9 @@ class FilesTab(Tab):
parent_iter,
self.treestore.get(itr,
*xrange(self.treestore.get_n_columns())))
itr_parent = self.treestore.iter_parent(itr)
self.treestore.remove(itr)
self.remove_childless_folders(itr_parent)
return True
self.treestore.foreach(get_file_iter, None)
@ -598,7 +601,73 @@ class FilesTab(Tab):
return True
self.treestore.foreach(set_file_name, None)
def get_iter_at_path(self, filepath):
"""
Returns the gtkTreeIter for filepath
"""
log.debug("get_iter_at_path: %s", filepath)
is_dir = False
if filepath[-1] == "/":
is_dir = True
filepath = filepath.split("/")
if "" in filepath:
filepath.remove("")
path_iter = None
itr = self.treestore.iter_children(None)
level = 0
while itr:
ipath = self.treestore[itr][0]
if (level + 1) != len(filepath) and ipath == filepath[level] + "/":
# We're not at the last index, but we do have a match
itr = self.treestore.iter_children(itr)
level += 1
continue
elif (level + 1) == len(filepath) and ipath == filepath[level] + "/" if is_dir else filepath[level]:
# This is the iter we've been searching for
path_iter = itr
break
else:
itr = self.treestore.iter_next(itr)
continue
return path_iter
def reparent_iter(self, itr, parent, move_siblings=False):
"""
This effectively moves itr plus it's children to be a child of parent
If move_siblings is True, it will move all itr's siblings to parent
"""
src = itr
def move_children(i, dest):
while i:
n = self.treestore.append(dest, self.treestore.get(i, *xrange(self.treestore.get_n_columns())))
to_remove = i
if self.treestore.iter_children(i):
move_children(self.treestore.iter_children(i), n)
if i != src:
i = self.treestore.iter_next(i)
else:
# This is the source iter, we don't want other iters in it's level
if not move_siblings:
i = None
self.treestore.remove(to_remove)
move_children(itr, parent)
def remove_childless_folders(self, itr):
"""
Goes up the tree removing childless itrs starting at itr
"""
while not self.treestore.iter_children(itr):
parent = self.treestore.iter_parent(itr)
self.treestore.remove(itr)
itr = parent
def _on_torrent_folder_renamed_signal(self, torrent_id, old_folder, new_folder):
log.debug("on_torrent_folder_renamed_signal")
log.debug("old_folder: %s new_folder: %s", old_folder, new_folder)
if old_folder[-1] != "/":
@ -624,27 +693,32 @@ class FilesTab(Tab):
except:
pass
itr = None
for i, old in enumerate(old_split):
itr = self.treestore.iter_children(itr)
while itr:
if self.treestore[itr][0] == old + "/":
if old != new_split[i]:
# we need to change this one
self.treestore[itr][0] = new_split[i] + "/"
break
itr = self.treestore.iter_next(itr)
old_folder_iter = self.get_iter_at_path(old_folder)
old_folder_iter_parent = self.treestore.iter_parent(old_folder_iter)
new_folder_iter = self.get_iter_at_path(new_folder)
if new_folder_iter:
# This means that a folder by this name already exists
self.reparent_iter(self.treestore.iter_children(old_folder_iter), new_folder_iter)
else:
new_folder_iter = self.get_iter_at_path("/".join(new_split[:-1]) + "/")
self.reparent_iter(old_folder_iter, new_folder_iter)
# We need to check if the old_folder_iter_parent no longer has children
# and if so, we delete it
self.remove_childless_folders(old_folder_iter_parent)
def _on_torrent_removed_signal(self, torrent_id):
if torrent_id in self.files_list:
del self.files_list[torrent_id]
def _on_drag_data_get_data(self, treeview, context, selection, target_id, etime):
indexes = self.get_selected_files()
selection.set_text(",".join([str(x) for x in indexes]))
paths = self.listview.get_selection().get_selected_rows()[1]
selection.set_text(cPickle.dumps(paths))
def _on_drag_data_received_data(self, treeview, context, x, y, selection, info, etime):
log.debug("selection.data: %s", selection.data)
selected = cPickle.loads(selection.data)
log.debug("selection.data: %s", selected)
drop_info = treeview.get_dest_row_at_pos(x, y)
model = treeview.get_model()
if drop_info:
@ -658,16 +732,20 @@ class FilesTab(Tab):
parent_path = model[parent_iter][0] + parent_path
parent_iter = model.iter_parent(parent_iter)
#[(index, filepath), ...]
to_rename = []
selected = [int(x) for x in selection.data.split(",")]
def find_file(model, path, itr, user_data):
if model[itr][5] in selected:
to_rename.append((model[itr][5], parent_path + model[itr][0]))
if len(to_rename) == len(selected):
return True
model.foreach(find_file, None)
log.debug("to_rename: %s", to_rename)
client.rename_files(self.torrent_id, to_rename)
if model[selected[0]][5] == -1:
log.debug("parent_path: %s", parent_path)
log.debug("rename_to: %s", parent_path + model[selected[0]][0])
# Get the full path of the folder we want to rename
pp = ""
itr = self.treestore.iter_parent(self.treestore.get_iter(selected[0]))
while itr:
pp = self.treestore[itr][0] + pp
itr = self.treestore.iter_parent(itr)
client.rename_folder(self.torrent_id, pp + model[selected[0]][0], parent_path + model[selected[0]][0])
else:
#[(index, filepath), ...]
to_rename = []
for s in selected:
to_rename.append((model[s][5], parent_path + model[s][0]))
log.debug("to_rename: %s", to_rename)
client.rename_files(self.torrent_id, to_rename)