diff --git a/deluge/ui/gtkui/listview.py b/deluge/ui/gtkui/listview.py index 747c7002a..5bdbd005c 100644 --- a/deluge/ui/gtkui/listview.py +++ b/deluge/ui/gtkui/listview.py @@ -223,15 +223,16 @@ class ListView: model_filter = self.liststore.filter_new() model_filter.set_visible_column( self.columns["filter"].column_indices[0]) - sort_info = None - if self.model_filter: - sort_info = self.model_filter.get_sort_column_id() - self.model_filter = gtk.TreeModelSort(model_filter) - 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.treeview.set_model(self.model_filter) + self.set_sort_functions() + self.set_model_sort() + + def set_model_sort(self): + for column_state in self.state: + if column_state.sort is not None and column_state.sort > -1: + self.treeview.get_model().set_sort_column_id(column_state.sort, column_state.sort_order) + break def stabilize_sort_func(self, sort_func): def stabilized(model, iter1, iter2, data): @@ -261,10 +262,10 @@ class ListView: position = index break sort = None - sort_id, order = self.model_filter.get_sort_column_id() - if self.get_column_name(sort_id) == column.get_title(): - sort = sort_id - + if self.model_filter: # Will be None if no list was ever loaded (never connected to server) + sort_id, order = self.model_filter.get_sort_column_id() + if self.get_column_name(sort_id) == column.get_title(): + sort = sort_id return ListViewColumnState(column.get_title(), position, column.get_width(), column.get_visible(), sort, int(column.get_sort_order())) @@ -411,11 +412,7 @@ class ListView: # Do the actual row copy if self.liststore is not None: self.liststore.foreach(copy_row, (new_list, self.columns)) - self.liststore = new_list - # Create the model - self.create_model_filter() - return def remove_column(self, header): @@ -540,9 +537,6 @@ class ListView: if column_state.width > 0: column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) column.set_fixed_width(column_state.width) - - if column_state.sort is not None and column_state.sort > -1: - self.model_filter.set_sort_column_id(column_state.sort, column_state.sort_order) column.set_visible(column_state.visible) position = column_state.position break diff --git a/deluge/ui/gtkui/torrentview.py b/deluge/ui/gtkui/torrentview.py index 97a68b662..4df620d18 100644 --- a/deluge/ui/gtkui/torrentview.py +++ b/deluge/ui/gtkui/torrentview.py @@ -323,18 +323,12 @@ class TorrentView(listview.ListView, component.Component): component.get("SessionProxy").get_torrents_status({}, []).addCallback(self._on_session_state) def _on_session_state(self, 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.add_rows(state) self.got_state = True # Update the view right away with our status self.status = state self.set_columns_to_update() - self.update_view() + self.update_view(load_new_list=True) def stop(self): """Stops the torrentview""" @@ -409,43 +403,66 @@ class TorrentView(listview.ListView, component.Component): # Send a status request gobject.idle_add(self.send_status_request) - def update_view(self, columns=None): - """Update the view. If columns is not None, it will attempt to only - update those columns selected. - """ + def update_view(self, load_new_list=False): + """Update the torrent view model with data we've received.""" filter_column = self.columns["filter"].column_indices[0] - # Update the torrent view model with data we've received status = self.status - status_keys = status.keys() + + if not load_new_list: + # Freeze notications while updating + self.treeview.freeze_child_notify() + + # Get the columns to update from one of the torrents + if status: + torrent_id = status.keys()[0] + 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): + # Only use columns that the torrent has in the state + if status_field in status[torrent_id]: + fields_to_update.append((column_index[i], status_field)) for row in self.liststore: torrent_id = row[self.columns["torrent_id"].column_indices[0]] + # 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 - if not torrent_id in status_keys: + torrent_id_in_status = False + try: + torrent_status = status[torrent_id] + torrent_id_in_status = True + if torrent_status == self.prev_status[torrent_id]: + # The status dict is the same, so do nothing to update for this torrent + continue + except KeyError, e: + pass + + if not torrent_id_in_status: if row[filter_column] is True: row[filter_column] = False else: if row[filter_column] is False: 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 - # 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) + # Find the fields to update + to_update = [] + for i, status_field in fields_to_update: + row_value = status[torrent_id][status_field] + if row[i] != row_value: + to_update.append(i) + to_update.append(row_value) + # Update fields in the liststore + if to_update: + self.liststore.set(row.iter, *to_update) + + if load_new_list: + # Create the model filter. This sets the model for the treeview and enables sorting. + self.create_model_filter() + else: + self.treeview.thaw_child_notify() component.get("MenuBar").update_menu() - self.prev_status = status def _on_get_torrents_status(self, status): @@ -475,6 +492,16 @@ 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] + filter_column = self.columns["filter"].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, filter_column, True) + def remove_row(self, torrent_id): """Removes a row with torrent_id""" for row in self.liststore: