diff --git a/deluge/ui/gtkui/addtorrentdialog.py b/deluge/ui/gtkui/addtorrentdialog.py index 5eb9d0714..a8f64f552 100644 --- a/deluge/ui/gtkui/addtorrentdialog.py +++ b/deluge/ui/gtkui/addtorrentdialog.py @@ -24,7 +24,7 @@ from deluge.configmanager import ConfigManager from deluge.httpdownloader import download_file from deluge.ui.client import client from deluge.ui.common import TorrentInfo -from deluge.ui.gtkui.common import reparent_iter +from deluge.ui.gtkui.common import listview_replace_treestore, reparent_iter from deluge.ui.gtkui.dialogs import ErrorDialog from deluge.ui.gtkui.path_chooser import PathChooser from deluge.ui.gtkui.torrentview_data_funcs import cell_data_size @@ -275,17 +275,13 @@ class AddTorrentDialog(component.Component): self.save_torrent_options() def prepare_file_store(self, files): - self.listview_files.set_model(None) - self.files_treestore.clear() - split_files = {} - i = 0 - for file in files: - self.prepare_file( - file, file["path"], i, file["download"], split_files - ) - i += 1 - self.add_files(None, split_files) - self.listview_files.set_model(self.files_treestore) + with listview_replace_treestore(self.listview_files): + split_files = {} + for i, file in enumerate(files): + self.prepare_file( + file, file["path"], i, file["download"], split_files + ) + self.add_files(None, split_files) self.listview_files.expand_row("0", False) def prepare_file(self, file, file_name, file_num, download, files_storage): diff --git a/deluge/ui/gtkui/common.py b/deluge/ui/gtkui/common.py index ddaad1749..a90ab1071 100644 --- a/deluge/ui/gtkui/common.py +++ b/deluge/ui/gtkui/common.py @@ -8,6 +8,7 @@ # """Common functions for various parts of gtkui to use.""" +import contextlib import cPickle import logging import os @@ -267,3 +268,29 @@ def load_pickled_state_file(filename): else: log.info("Successfully loaded %s: %s", filename, _filepath) return state + + +@contextlib.contextmanager +def listview_replace_treestore(listview): + """Prepare a listview's treestore to be entirely replaced. + + Params: + listview: a listview backed by a treestore + """ + # From http://faq.pygtk.org/index.py?req=show&file=faq13.043.htp + # "tips for improving performance when adding many rows to a Treeview" + listview.freeze_child_notify() + treestore = listview.get_model() + listview.set_model(None) + treestore.clear() + treestore.set_default_sort_func(lambda *args: 0) + original_sort = treestore.get_sort_column_id() + treestore.set_sort_column_id(-1, gtk.SORT_ASCENDING) + + yield + + if original_sort != (None, None): + treestore.set_sort_column_id(*original_sort) + + listview.set_model(treestore) + listview.thaw_child_notify() diff --git a/deluge/ui/gtkui/files_tab.py b/deluge/ui/gtkui/files_tab.py index 5fc3b0de2..bd3a80282 100644 --- a/deluge/ui/gtkui/files_tab.py +++ b/deluge/ui/gtkui/files_tab.py @@ -18,7 +18,8 @@ import gtk.gdk import deluge.component as component from deluge.common import FILE_PRIORITY, open_file, show_file from deluge.ui.client import client -from deluge.ui.gtkui.common import load_pickled_state_file, reparent_iter, save_pickled_state_file +from deluge.ui.gtkui.common import (listview_replace_treestore, load_pickled_state_file, reparent_iter, + save_pickled_state_file) from deluge.ui.gtkui.torrentdetails import Tab from deluge.ui.gtkui.torrentview_data_funcs import cell_data_size @@ -376,8 +377,8 @@ class FilesTab(Tab): return ret def update_files(self): - self.treestore.clear() - self.prepare_file_store(self.files_list[self.torrent_id]) + with listview_replace_treestore(self.listview): + self.prepare_file_store(self.files_list[self.torrent_id]) self.listview.expand_row("0", False) def get_selected_files(self):