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.
This commit is contained in:
Chase Sterling 2012-11-01 00:25:00 -04:00
parent 8d25a5e691
commit db502253c9
2 changed files with 43 additions and 22 deletions

View File

@ -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

View File

@ -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()