From db502253c968b6afd143c80e78e5553ecc88ed11 Mon Sep 17 00:00:00 2001 From: Chase Sterling Date: Thu, 1 Nov 2012 00:25:00 -0400 Subject: [PATCH] Generalize stable sorting to use unique column set for the ListView. Add a default sorting to the ListView. Switch gtk speedup patch for new sorting. --- deluge/ui/gtkui/listview.py | 57 ++++++++++++++++++++++------------ deluge/ui/gtkui/torrentview.py | 8 +++-- 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/deluge/ui/gtkui/listview.py b/deluge/ui/gtkui/listview.py index b5208fd88..e50ac1b16 100644 --- a/deluge/ui/gtkui/listview.py +++ b/deluge/ui/gtkui/listview.py @@ -215,6 +215,8 @@ class ListView: # Since gtk TreeModelSort doesn't do stable sort, remember last sort order so we can self.last_sort_order = {} + self.unique_column_id = None + self.default_sort_column_id = None # Create the model filter and column self.add_bool_column("filter", hidden=True) @@ -239,26 +241,30 @@ class ListView: self.treeview.set_model(self.model_filter) def on_model_sort_changed(self, model): - self.last_sort_order = {} - def record_position(model, path, iter, data): - self.last_sort_order[model[iter][1]] = path[0] - model.foreach(record_position, None) + if self.unique_column_id: + self.last_sort_order = {} + def record_position(model, path, iter, data): + self.last_sort_order[model[iter][self.unique_column_id]] = path[0] + model.foreach(record_position, None) def on_model_row_inserted(self, model, path, iter): - self.last_sort_order.setdefault(model[iter][1], len(model) - 1) + if self.unique_column_id: + self.last_sort_order.setdefault( + model[iter][self.unique_column_id], len(model) - 1) def stabilize_sort_func(self, sort_func): def stabilized(model, iter1, iter2, data): result = sort_func(model, iter1, iter2, data) - if result == 0: - hash1 = model[iter1][1] - hash2 = model[iter2][1] - if hash1 not in self.last_sort_order: - return 1 - elif hash2 not in self.last_sort_order: - return -1 - result = cmp(self.last_sort_order[hash1], - self.last_sort_order[hash2]) + if result == 0 and self.unique_column_id: + hash1 = model[iter1][self.unique_column_id] + hash2 = model[iter2][self.unique_column_id] + if hash1 in self.last_sort_order and hash2 in self.last_sort_order: + result = cmp(self.last_sort_order[hash1], + self.last_sort_order[hash2]) + if result == 0 and self.default_sort_column_id: + result = cmp(model[iter1][self.default_sort_column_id], + model[iter2][self.default_sort_column_id]) + return result return stabilized @@ -474,7 +480,8 @@ class ListView: def add_column(self, header, render, col_types, hidden, position, status_field, sortid, text=0, value=0, pixbuf=0, function=None, - column_type=None, sort_func=None, default=True): + column_type=None, sort_func=None, default=True, unique=False, + default_sort=False): """Adds a column to the ListView""" # Add the column types to liststore_columns column_indices = [] @@ -499,6 +506,11 @@ class ListView: self.columns[header].sort_func = sort_func self.columns[header].sort_id = column_indices[sortid] + if unique: + self.unique_column_id = column_indices[sortid] + if default_sort: + self.default_sort_column_id = column_indices[sortid] + # Create a new list with the added column self.create_new_liststore() @@ -551,6 +563,10 @@ class ListView: column.connect('button-press-event', self.on_treeview_header_right_clicked) + if default_sort: + if self.model_filter.get_sort_column_id()[0] is None: + self.model_filter.set_sort_column_id(column_indices[sortid], + gtk.SORT_ASCENDING) # Check for loaded state and apply column_in_state = False if self.state != None: @@ -588,13 +604,15 @@ class ListView: def add_text_column(self, header, col_type=str, hidden=False, position=None, status_field=None, sortid=0, column_type="text", - sort_func=None, default=True): + sort_func=None, default=True, unique=False, + default_sort=False): """Add a text column to the listview. Only the header name is required. """ render = gtk.CellRendererText() self.add_column(header, render, col_type, hidden, position, status_field, sortid, column_type=column_type, - sort_func=sort_func, default=default) + sort_func=sort_func, default=default, unique=unique, + default_sort=default_sort) return True @@ -637,14 +655,15 @@ class ListView: def add_texticon_column(self, header, col_types=[str, str], sortid=1, hidden=False, position=None, status_field=None, column_type="texticon", function=None, - default=True): + default=True, default_sort=False): """Adds a texticon column to the listview.""" render1 = gtk.CellRendererPixbuf() render2 = gtk.CellRendererText() self.add_column(header, (render1, render2), col_types, hidden, position, status_field, sortid, column_type=column_type, - function=function, pixbuf=0, text=1, default=default) + function=function, pixbuf=0, text=1, default=default, + default_sort=default_sort) return True diff --git a/deluge/ui/gtkui/torrentview.py b/deluge/ui/gtkui/torrentview.py index efcc59ac1..36a67594d 100644 --- a/deluge/ui/gtkui/torrentview.py +++ b/deluge/ui/gtkui/torrentview.py @@ -228,14 +228,15 @@ class TorrentView(listview.ListView, component.Component): self.window.main_glade.get_widget("menu_columns")) # Add the columns to the listview - self.add_text_column("torrent_id", hidden=True) + self.add_text_column("torrent_id", hidden=True, unique=True) self.add_bool_column("dirty", hidden=True) self.add_func_column("#", cell_data_queue, [int], status_field=["queue"], sort_func=queue_column_sort) self.add_texticon_column(_("Name"), status_field=["state", "name"], - function=cell_data_statusicon) + function=cell_data_statusicon, + default_sort=True) self.add_func_column(_("Size"), listview.cell_data_size, [gobject.TYPE_UINT64], status_field=["total_wanted"]) @@ -406,6 +407,7 @@ class TorrentView(listview.ListView, component.Component): if first_run: # Disable sort if it's the first run. sort_settings = model.get_sort_column_id() + model.set_default_sort_func(lambda *unused: 0) model.set_sort_column_id(-1, gtk.SORT_ASCENDING) # Create a list of tuples with the index of the column, and the column name @@ -450,7 +452,6 @@ class TorrentView(listview.ListView, component.Component): to_update.append(row_value) except KeyError, e: # if status_field in status[torrent_id] -> False - field_value_key_error_count += 1 pass except Exception, e: log.debug("%s", e) @@ -461,6 +462,7 @@ class TorrentView(listview.ListView, component.Component): if sort_settings[0] is not None: # Reenable sorting model.set_sort_column_id(*sort_settings) + model.set_default_sort_func(None) self.treeview.thaw_child_notify() component.get("MenuBar").update_menu()