summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--deluge/ui/gtkui/gtkui.py8
-rw-r--r--deluge/ui/gtkui/listview.py116
-rw-r--r--tests/test_torrentview.py51
3 files changed, 132 insertions, 43 deletions
diff --git a/deluge/ui/gtkui/gtkui.py b/deluge/ui/gtkui/gtkui.py
index 30755b160..fab40ebfd 100644
--- a/deluge/ui/gtkui/gtkui.py
+++ b/deluge/ui/gtkui/gtkui.py
@@ -39,7 +39,13 @@ gobject.set_prgname("deluge")
# Install the twisted reactor
from twisted.internet import gtk2reactor
-reactor = gtk2reactor.install()
+from twisted.internet.error import ReactorAlreadyInstalledError
+
+try:
+ reactor = gtk2reactor.install()
+except ReactorAlreadyInstalledError, e:
+ # Running unit tests so trial already installed a rector
+ pass
import gettext
import locale
diff --git a/deluge/ui/gtkui/listview.py b/deluge/ui/gtkui/listview.py
index 37bb39599..e17b552f6 100644
--- a/deluge/ui/gtkui/listview.py
+++ b/deluge/ui/gtkui/listview.py
@@ -146,6 +146,13 @@ class ListView:
# If this is set, it is used to sort the model
self.sort_func = None
self.sort_id = None
+ # Values needed to update TreeViewColumns
+ self.column_type = None
+ self.renderer = None
+ self.text_index = 0
+ self.value_index = 0
+ self.pixbuf_index = 0
+ self.data_func = None
class TreeviewColumn(gtk.TreeViewColumn):
"""
@@ -173,6 +180,14 @@ class ListView:
def onButtonPressed(self, widget, event):
self.emit('button-press-event', event)
+ def set_col_attributes(self, renderer, add=True, **kw):
+ """Helper function to add and set attributes"""
+ if add is True:
+ for attr, value in kw.iteritems():
+ self.add_attribute(renderer, attr, value)
+ else:
+ self.set_attributes(renderer, **kw)
+
def __init__(self, treeview_widget=None, state_file=None):
log.debug("ListView initialized..")
@@ -417,6 +432,49 @@ class ListView:
self.create_model_filter()
return
+ def update_treeview_column(self, header, add=True):
+ """Update TreeViewColumn based on ListView column mappings"""
+ column = self.columns[header]
+ tree_column = self.columns[header].column
+
+ if column.column_type == "text":
+ if add:
+ tree_column.pack_start(column.renderer)
+ tree_column.set_col_attributes(column.renderer, add=add,
+ text=column.column_indices[column.text_index])
+ elif column.column_type == "bool":
+ if add:
+ tree_column.pack_start(column.renderer)
+ tree_column.set_col_attributes(column.renderer, active=column.column_indices[0])
+ elif column.column_type == "func":
+ if add:
+ tree_column.pack_start(column.renderer, True)
+ indice_arg = column.column_indices[0]
+ if len(column.column_indices) > 1:
+ indice_arg = tuple(column.column_indices)
+ tree_column.set_cell_data_func(column.renderer, column.data_func, indice_arg)
+ elif column.column_type == "progress":
+ if add:
+ tree_column.pack_start(column.renderer)
+ if column.data_func is None:
+ tree_column.set_col_attributes(column.renderer, add=add,
+ text=column.column_indices[column.text_index],
+ value=column.column_indices[column.value_index])
+ else:
+ tree_column.set_cell_data_func(column.renderer, column.data_func,
+ tuple(column.column_indices))
+ elif column.column_type == "texticon":
+ if add:
+ tree_column.pack_start(column.renderer[column.pixbuf_index], False)
+ tree_column.pack_start(column.renderer[column.text_index], True)
+ tree_column.set_col_attributes(column.renderer[column.text_index], add=add,
+ text=column.column_indices[column.text_index])
+ if column.data_func is not None:
+ tree_column.set_cell_data_func(
+ column.renderer[column.pixbuf_index], column.data_func,
+ column.column_indices[column.pixbuf_index])
+ return True
+
def remove_column(self, header):
"""Removes the column with the name 'header' from the listview"""
# Store a copy of this columns state in case it's re-added
@@ -435,13 +493,14 @@ class ListView:
for column in self.columns.values():
if column.column_indices[0] > column_indices[0]:
# We need to shift this column_indices
- for index in column.column_indices:
- index = index - len(column_indices)
+ for i, index in enumerate(column.column_indices):
+ column.column_indices[i] = index - len(column_indices)
+ # Update the associated TreeViewColumn
+ self.update_treeview_column(column.name, add=False)
# Remove from the liststore columns list
for index in column_indices:
del self.liststore_columns[index]
-
# Create a new liststore
self.create_new_liststore()
@@ -471,54 +530,28 @@ class ListView:
self.column_index.append(header)
# Create a new column object and add it to the list
+ column = self.TreeviewColumn(header)
self.columns[header] = self.ListViewColumn(header, column_indices)
-
+ self.columns[header].column = column
self.columns[header].status_field = status_field
self.columns[header].sort_func = sort_func
self.columns[header].sort_id = column_indices[sortid]
+ # Store creation details
+ self.columns[header].column_type = column_type
+ self.columns[header].renderer = render
+ self.columns[header].text_index = text
+ self.columns[header].value_index = value
+ self.columns[header].pixbuf_index = pixbuf
+ self.columns[header].data_func = function
# Create a new list with the added column
self.create_new_liststore()
- column = self.TreeviewColumn(header)
-
- if column_type == "text":
- column.pack_start(render)
- column.add_attribute(render, "text",
- self.columns[header].column_indices[text])
- elif column_type == "bool":
- column.pack_start(render)
- column.add_attribute(render, "active",
- self.columns[header].column_indices[0])
- elif column_type == "func":
- column.pack_start(render, True)
- if len(self.columns[header].column_indices) > 1:
- column.set_cell_data_func(render, function,
- tuple(self.columns[header].column_indices))
- else:
- column.set_cell_data_func(render, function,
- self.columns[header].column_indices[0])
- elif column_type == "progress":
- column.pack_start(render)
- if function is None:
- column.add_attribute(render, "text",
- self.columns[header].column_indices[text])
- column.add_attribute(render, "value",
- self.columns[header].column_indices[value])
- else:
- column.set_cell_data_func(render, function,
- tuple(self.columns[header].column_indices))
- elif column_type == "texticon":
- column.pack_start(render[pixbuf], False)
- if function is not None:
- column.set_cell_data_func(render[pixbuf], function,
- self.columns[header].column_indices[pixbuf])
- column.pack_start(render[text], True)
- column.add_attribute(render[text], "text",
- self.columns[header].column_indices[text])
- elif column_type == None:
+ if column_type == None:
return
+ self.update_treeview_column(header)
+
column.set_sort_column_id(self.columns[header].column_indices[sortid])
column.set_clickable(True)
column.set_resizable(True)
@@ -555,7 +588,6 @@ class ListView:
# Set hidden in the column
self.columns[header].hidden = hidden
- self.columns[header].column = column
# Re-create the menu item because of the new column
self.create_checklist_menu()
diff --git a/tests/test_torrentview.py b/tests/test_torrentview.py
new file mode 100644
index 000000000..dd974bc10
--- /dev/null
+++ b/tests/test_torrentview.py
@@ -0,0 +1,51 @@
+import gobject
+
+from twisted.trial import unittest
+
+from deluge.ui.gtkui.torrentview import TorrentView
+from deluge.ui.gtkui.mainwindow import MainWindow
+from deluge.ui.gtkui.torrentdetails import TorrentDetails
+from deluge.ui.gtkui.menubar import MenuBar
+
+
+
+class TorrentviewTestCase(unittest.TestCase):
+
+ def setUp(self): # NOQA
+ pass
+
+ def tearDown(self): # NOQA
+ pass
+
+ def test_torrentview_columns(self):
+ self.mainwindow = MainWindow()
+ self.torrentview = TorrentView()
+ self.torrentdetails = TorrentDetails()
+ self.menubar = MenuBar()
+
+ default_column_index = ['filter', 'torrent_id', 'dirty', '#', 'Name', 'Size', 'Downloaded', 'Uploaded', 'Progress', 'Seeders', 'Peers', 'Seeders/Peers', 'Down Speed', 'Up Speed', 'Down Limit', 'Up Limit', 'ETA', 'Ratio', 'Avail', 'Added', 'Tracker', 'Save Path']
+ default_liststore_columns = [bool, str, bool, int, str, str, gobject.TYPE_UINT64, gobject.TYPE_UINT64, gobject.TYPE_UINT64, float, str, int, int, int, int, float, float, float, float, float, int, float, float, float, str, str, str]
+
+ self.assertEquals(self.torrentview.column_index, default_column_index)
+ self.assertEquals(self.torrentview.liststore_columns, default_liststore_columns)
+
+ self.assertEquals(self.torrentview.columns["Save Path"].column_indices, [26])
+ test_col = "Test column"
+ self.torrentview.add_text_column(test_col, status_field=["label"])
+ self.assertEquals(len(self.torrentview.liststore_columns), 28)
+ self.assertEquals(len(self.torrentview.column_index), 23)
+ self.assertEquals(self.torrentview.column_index[-1], test_col)
+ self.assertEquals(self.torrentview.columns[test_col].column_indices, [27])
+
+ test_col2 = "Test column2"
+ self.torrentview.add_text_column(test_col2, status_field=["label2"])
+ self.assertEquals(len(self.torrentview.liststore_columns), 29)
+ self.assertEquals(len(self.torrentview.column_index), 24)
+ self.assertEquals(self.torrentview.column_index[-1], test_col2)
+ self.assertEquals(self.torrentview.columns[test_col2].column_indices, [28])
+
+ self.torrentview.remove_column(test_col)
+ self.assertEquals(len(self.torrentview.liststore_columns), 28)
+ self.assertEquals(len(self.torrentview.column_index), 23)
+ self.assertEquals(self.torrentview.column_index[-1], test_col2)
+ self.assertEquals(self.torrentview.columns[test_col2].column_indices, [27])