From 8f71b8d5c6eab187cb963a064629efcd88badf29 Mon Sep 17 00:00:00 2001 From: Chase Sterling Date: Wed, 7 Nov 2012 00:16:24 -0500 Subject: [PATCH] Revert stable sort and speedup commits. --- ChangeLog | 4 +- deluge/ui/gtkui/listview.py | 72 +++------------------ deluge/ui/gtkui/torrentview.py | 110 ++++++++++----------------------- 3 files changed, 45 insertions(+), 141 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4dd7f16d6..c8a4b28fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,10 +2,8 @@ ==== Core ==== * Catch & log KeyError when removing a torrent from the queued torrents set -=== GtkUI === +==== GtkUI ==== * Add move completed option to add torrent dialog - * Remove jitter in torrent list order, make order stable between sorts - * Improve update speed and responsiveness (especially with large number of torrents) === Deluge 1.3.5 (09 April 2012) === ==== Core ==== diff --git a/deluge/ui/gtkui/listview.py b/deluge/ui/gtkui/listview.py index e50ac1b16..72613b3ed 100644 --- a/deluge/ui/gtkui/listview.py +++ b/deluge/ui/gtkui/listview.py @@ -213,11 +213,6 @@ class ListView: # their columns prior to having the state list saved on shutdown. self.removed_columns_state = [] - # 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) @@ -236,49 +231,15 @@ class ListView: if sort_info and sort_info[0] and sort_info[1] > -1: self.model_filter.set_sort_column_id(sort_info[0], sort_info[1]) self.set_sort_functions() - self.model_filter.connect("sort-column-changed", self.on_model_sort_changed) - self.model_filter.connect("row-inserted", self.on_model_row_inserted) self.treeview.set_model(self.model_filter) - def on_model_sort_changed(self, model): - 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): - 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 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 - - def generic_sort_func(self, model, iter1, iter2, data): - return cmp(model[iter1][data], model[iter2][data]) - def set_sort_functions(self): - self.model_filter.set_default_sort_func(None) for column in self.columns.values(): - sort_func = column.sort_func or self.generic_sort_func - self.model_filter.set_sort_func( - column.sort_id, - self.stabilize_sort_func(sort_func), - column.sort_id) + if column.sort_func: + self.model_filter.set_sort_func( + column.sort_id, + column.sort_func, + column.sort_id) def create_column_state(self, column, position=None): if not position: @@ -480,8 +441,7 @@ 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, unique=False, - default_sort=False): + column_type=None, sort_func=None, default=True): """Adds a column to the ListView""" # Add the column types to liststore_columns column_indices = [] @@ -506,11 +466,6 @@ 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() @@ -563,10 +518,6 @@ 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: @@ -604,15 +555,13 @@ 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, unique=False, - default_sort=False): + sort_func=None, default=True): """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, unique=unique, - default_sort=default_sort) + sort_func=sort_func, default=default) return True @@ -655,15 +604,14 @@ 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_sort=False): + default=True): """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, - default_sort=default_sort) + function=function, pixbuf=0, text=1, default=default) return True diff --git a/deluge/ui/gtkui/torrentview.py b/deluge/ui/gtkui/torrentview.py index 36a67594d..0634e465e 100644 --- a/deluge/ui/gtkui/torrentview.py +++ b/deluge/ui/gtkui/torrentview.py @@ -228,15 +228,14 @@ 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, unique=True) + self.add_text_column("torrent_id", hidden=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, - default_sort=True) + function=cell_data_statusicon) self.add_func_column(_("Size"), listview.cell_data_size, [gobject.TYPE_UINT64], status_field=["total_wanted"]) @@ -314,12 +313,18 @@ class TorrentView(listview.ListView, component.Component): component.get("SessionProxy").get_torrents_status({}, []).addCallback(self._on_session_state) def _on_session_state(self, state): - self.add_rows(state) + self.treeview.freeze_child_notify() + model = self.treeview.get_model() + for torrent_id in state: + self.add_row(torrent_id, update=False) + self.mark_dirty(torrent_id) + self.treeview.set_model(model) + self.treeview.thaw_child_notify() self.got_state = True # Update the view right away with our status self.status = state self.set_columns_to_update() - self.update_view(first_run=True) + self.update_view() def stop(self): """Stops the torrentview""" @@ -394,78 +399,40 @@ class TorrentView(listview.ListView, component.Component): # Send a status request gobject.idle_add(self.send_status_request) - - def update_view(self, first_run=False): - """Update the view.""" + def update_view(self, columns=None): + """Update the view. If columns is not None, it will attempt to only + update those columns selected. + """ filter_column = self.columns["filter"].column_indices[0] + # Update the torrent view model with data we've received status = self.status - sort_settings = (None, None) - model = self.treeview.get_model() - - self.treeview.freeze_child_notify() - - 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 - fields_to_update = [] - for column in self.columns_to_update: - column_index = self.get_column_index(column) - for i, status_field in enumerate(self.columns[column].status_field): - fields_to_update.append((column_index[i], status_field)) for row in self.liststore: torrent_id = row[self.columns["torrent_id"].column_indices[0]] - # Do not test if the torrent_id is in status. Instead - # we expect the torrent_id to be in status and prev_status, - # as it will be as long as the list isn't changed by the user - torrent_id_in_status = False - try: - torrent_status = status[torrent_id] - torrent_id_in_status = True - if torrent_status == self.prev_status[torrent_id]: - if row[filter_column] is False: - row[filter_column] = True - # The status dict is the same, so do not update this torrent - continue - except KeyError: - pass - if not torrent_id_in_status: - if row[filter_column] is True: - row[filter_column] = False + if not torrent_id in status.keys(): + row[filter_column] = False else: - if row[filter_column] is False: - row[filter_column] = True - to_update = [] - # Add all the values that have changed to the list - for i, status_field in fields_to_update: - try: - if not status[torrent_id].has_key(status_field): - continue - row_value = status[torrent_id][status_field] - if row[i] != row_value: - to_update.append(i) - to_update.append(row_value) - except KeyError, e: - # if status_field in status[torrent_id] -> False - pass - except Exception, e: - log.debug("%s", e) - # Update all the changed values of the row - if to_update: - self.liststore.set(row.iter, *to_update) + row[filter_column] = True + if torrent_id in self.prev_status and status[torrent_id] == self.prev_status[torrent_id]: + # The status dict is the same, so do not update + continue - if sort_settings[0] is not None: - # Reenable sorting - model.set_sort_column_id(*sort_settings) - model.set_default_sort_func(None) + # Set values for each column in the row + for column in self.columns_to_update: + column_index = self.get_column_index(column) + for i, status_field in enumerate(self.columns[column].status_field): + if status_field in status[torrent_id]: + try: + # Only update if different + row_value = status[torrent_id][status_field] + if row[column_index[i]] != row_value: + row[column_index[i]] = row_value + except Exception, e: + log.debug("%s", e) - self.treeview.thaw_child_notify() component.get("MenuBar").update_menu() + self.prev_status = status def _on_get_torrents_status(self, status): @@ -495,15 +462,6 @@ class TorrentView(listview.ListView, component.Component): if update: self.update() - def add_rows(self, state): - """Adds all the torrents from state to self.liststore""" - torrent_id_column = self.columns["torrent_id"].column_indices[0] - dirty_column = self.columns["dirty"].column_indices[0] - for i, torrent_id in enumerate(state): - # Insert a new row to the liststore - row = self.liststore.append() - self.liststore.set(row, torrent_id_column, torrent_id, dirty_column, True) - def remove_row(self, torrent_id): """Removes a row with torrent_id""" for row in self.liststore: