[pygobject] Atomic inserts in Gtk.{List,Tree}Store overrides
- From: Martin Pitt <martinpitt src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] Atomic inserts in Gtk.{List,Tree}Store overrides
- Date: Mon, 19 Mar 2012 13:30:16 +0000 (UTC)
commit bf8c95836e1cc1e1629937cbc69ea3027fb82746
Author: Martin Pitt <martin pitt ubuntu com>
Date: Thu Mar 15 09:48:10 2012 +0100
Atomic inserts in Gtk.{List,Tree}Store overrides
Gtk.{List,Tree}Store's overrides provide append(), insert() etc. methods which
take an optional data row array. If this is given, use insert_with_valuesv()
instead of creating a new iter and then filling it with data. The latter sent a
row-added signal, at which time the row was still empty, and a subsequent
row-changed signal. With this we only get a single row-added signal with
complete row data.
Note that this does not change insert_{before,after}(), as there is no
counterpart of insert_with_valuesv() which takes a TreeIter instead of a
position. For those you will still get two signals, and have to deal with None
values.
https://bugzilla.gnome.org/show_bug.cgi?id=671610
gi/overrides/Gtk.py | 81 +++++++++++++++++++++++++++++------------------
tests/test_overrides.py | 74 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 124 insertions(+), 31 deletions(-)
---
diff --git a/gi/overrides/Gtk.py b/gi/overrides/Gtk.py
index c2fd233..cb1a77a 100644
--- a/gi/overrides/Gtk.py
+++ b/gi/overrides/Gtk.py
@@ -785,7 +785,7 @@ class TreeModel(Gtk.TreeModel):
if success:
return parent_iter
- def set_row(self, treeiter, row):
+ def _convert_row(self, row):
# TODO: Accept a dictionary for row
# model.append(None,{COLUMN_ICON: icon, COLUMN_NAME: name})
if isinstance(row, str):
@@ -795,16 +795,24 @@ class TreeModel(Gtk.TreeModel):
if len(row) != n_columns:
raise ValueError('row sequence has the incorrect number of elements')
+ result = []
for i in range(n_columns):
value = row[i]
+ result.append(self._convert_value(i, value))
+ return result
+
+ def set_row(self, treeiter, row):
+ converted_row = self._convert_row(row)
+ for i in range(self.get_n_columns()):
+ value = row[i]
if value is None:
continue # None means skip this row
self.set_value(treeiter, i, value)
- def _convert_value(self, treeiter, column, value):
+ def _convert_value(self, column, value):
if value is None:
- return
+ return None
# we may need to convert to a basic type
type_ = self.get_column_type(column)
@@ -926,22 +934,32 @@ class ListStore(Gtk.ListStore, TreeModel, TreeSortable):
Gtk.ListStore.__init__(self)
self.set_column_types(column_types)
- def append(self, row=None):
- treeiter = Gtk.ListStore.append(self)
-
+ def _do_insert(self, position, row):
if row is not None:
- self.set_row(treeiter, row)
+ row = self._convert_row(row)
+ columns = range(len(row))
+ treeiter = self.insert_with_valuesv(position, columns, row)
+ else:
+ treeiter = Gtk.ListStore.insert(self, position)
return treeiter
- def insert(self, position, row=None):
- treeiter = Gtk.ListStore.insert(self, position)
+ def append(self, row=None):
+ if row:
+ return self._do_insert(-1, row)
+ # gtk_list_store_insert() does not know about the "position == -1"
+ # case, so use append() here
+ else:
+ return Gtk.ListStore.append(self)
- if row is not None:
- self.set_row(treeiter, row)
+ def prepend(self, row=None):
+ return self._do_insert(0, row)
- return treeiter
+ def insert(self, position, row=None):
+ return self._do_insert(position, row)
+ # FIXME: sends two signals; check if this can use an atomic
+ # insert_with_valuesv()
def insert_before(self, sibling, row=None):
treeiter = Gtk.ListStore.insert_before(self, sibling)
@@ -950,6 +968,8 @@ class ListStore(Gtk.ListStore, TreeModel, TreeSortable):
return treeiter
+ # FIXME: sends two signals; check if this can use an atomic
+ # insert_with_valuesv()
def insert_after(self, sibling, row=None):
treeiter = Gtk.ListStore.insert_after(self, sibling)
@@ -958,16 +978,8 @@ class ListStore(Gtk.ListStore, TreeModel, TreeSortable):
return treeiter
- def prepend(self, row=None):
- treeiter = Gtk.ListStore.prepend(self)
-
- if row is not None:
- self.set_row(treeiter, row)
-
- return treeiter
-
def set_value(self, treeiter, column, value):
- value = self._convert_value(treeiter, column, value)
+ value = self._convert_value(column, value)
Gtk.ListStore.set_value(self, treeiter, column, value)
def set(self, treeiter, *args):
@@ -1152,22 +1164,27 @@ class TreeStore(Gtk.TreeStore, TreeModel, TreeSortable):
Gtk.TreeStore.__init__(self)
self.set_column_types(column_types)
- def append(self, parent, row=None):
- treeiter = Gtk.TreeStore.append(self, parent)
-
+ def _do_insert(self, parent, position, row):
if row is not None:
- self.set_row(treeiter, row)
+ row = self._convert_row(row)
+ columns = range(len(row))
+ treeiter = self.insert_with_values(parent, position, columns, row)
+ else:
+ treeiter = Gtk.TreeStore.insert(self, parent, position)
return treeiter
- def insert(self, parent, position, row=None):
- treeiter = Gtk.TreeStore.insert(self, parent, position)
+ def append(self, parent, row=None):
+ return self._do_insert(parent, -1, row)
- if row is not None:
- self.set_row(treeiter, row)
+ def prepend(self, parent, row=None):
+ return self._do_insert(parent, 0, row)
- return treeiter
+ def insert(self, parent, position, row=None):
+ return self._do_insert(parent, position, row)
+ # FIXME: sends two signals; check if this can use an atomic
+ # insert_with_valuesv()
def insert_before(self, parent, sibling, row=None):
treeiter = Gtk.TreeStore.insert_before(self, parent, sibling)
@@ -1176,6 +1193,8 @@ class TreeStore(Gtk.TreeStore, TreeModel, TreeSortable):
return treeiter
+ # FIXME: sends two signals; check if this can use an atomic
+ # insert_with_valuesv()
def insert_after(self, parent, sibling, row=None):
treeiter = Gtk.TreeStore.insert_after(self, parent, sibling)
@@ -1185,7 +1204,7 @@ class TreeStore(Gtk.TreeStore, TreeModel, TreeSortable):
return treeiter
def set_value(self, treeiter, column, value):
- value = self._convert_value(treeiter, column, value)
+ value = self._convert_value(column, value)
Gtk.TreeStore.set_value(self, treeiter, column, value)
def set(self, treeiter, *args):
diff --git a/tests/test_overrides.py b/tests/test_overrides.py
index 1613c6d..5ea02e7 100644
--- a/tests/test_overrides.py
+++ b/tests/test_overrides.py
@@ -999,6 +999,43 @@ class TestGtk(unittest.TestCase):
self.assertEquals(i, 99)
+ def test_tree_store_signals(self):
+ tree_store = Gtk.TreeStore(int, bool)
+
+ def on_row_inserted(tree_store, tree_path, tree_iter, signal_list):
+ signal_list.append('row-inserted')
+
+ def on_row_changed(tree_store, tree_path, tree_iter, signal_list):
+ signal_list.append('row-changed')
+
+ signals = []
+ tree_store.connect('row-inserted', on_row_inserted, signals)
+ tree_store.connect('row-changed', on_row_changed, signals)
+
+ # adding rows with and without data should only call one signal
+ tree_store.append(None, (0, False))
+ self.assertEqual(signals, ['row-inserted'])
+
+ signals.pop()
+ tree_store.append(None)
+ self.assertEqual(signals, ['row-inserted'])
+
+ signals.pop()
+ tree_store.prepend(None, (0, False))
+ self.assertEqual(signals, ['row-inserted'])
+
+ signals.pop()
+ tree_store.prepend(None)
+ self.assertEqual(signals, ['row-inserted'])
+
+ signals.pop()
+ tree_store.insert(None, 1, (0, False))
+ self.assertEqual(signals, ['row-inserted'])
+
+ signals.pop()
+ tree_store.insert(None, 1)
+ self.assertEqual(signals, ['row-inserted'])
+
def test_list_store(self):
class TestPyObject(object):
pass
@@ -1188,6 +1225,43 @@ class TestGtk(unittest.TestCase):
self.assertEquals(i, 102)
+ def test_list_store_signals(self):
+ list_store = Gtk.ListStore(int, bool)
+
+ def on_row_inserted(list_store, tree_path, tree_iter, signal_list):
+ signal_list.append('row-inserted')
+
+ def on_row_changed(list_store, tree_path, tree_iter, signal_list):
+ signal_list.append('row-changed')
+
+ signals = []
+ list_store.connect('row-inserted', on_row_inserted, signals)
+ list_store.connect('row-changed', on_row_changed, signals)
+
+ # adding rows with and without data should only call one signal
+ list_store.append((0, False))
+ self.assertEqual(signals, ['row-inserted'])
+
+ signals.pop()
+ list_store.append()
+ self.assertEqual(signals, ['row-inserted'])
+
+ signals.pop()
+ list_store.prepend((0, False))
+ self.assertEqual(signals, ['row-inserted'])
+
+ signals.pop()
+ list_store.prepend()
+ self.assertEqual(signals, ['row-inserted'])
+
+ signals.pop()
+ list_store.insert(1, (0, False))
+ self.assertEqual(signals, ['row-inserted'])
+
+ signals.pop()
+ list_store.insert(1)
+ self.assertEqual(signals, ['row-inserted'])
+
def test_tree_path(self):
p1 = Gtk.TreePath()
p2 = Gtk.TreePath.new_first()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]