1 # -*- Mode: Python; py-indent-offset: 4 -*-
3 # vim: tabstop=4 shiftwidth=4 expandtab
7 from compathelper import _unicode, _bytes
11 from gi.repository import GLib, GObject
14 from gi.repository import GdkPixbuf, Gdk, Gtk
20 @unittest.skipUnless(Gtk, 'Gtk not available')
21 class TestGtk(unittest.TestCase):
22 def test_container(self):
24 self.assertTrue(isinstance(box, Gtk.Box))
25 self.assertTrue(isinstance(box, Gtk.Container))
26 self.assertTrue(isinstance(box, Gtk.Widget))
32 self.assertTrue(label in box)
33 self.assertTrue(label2 in box)
34 self.assertEqual(len(box), 2)
37 self.assertEqual(l, [label, label2])
39 def test_actions(self):
40 self.assertEqual(Gtk.Action, gi.overrides.Gtk.Action)
41 self.assertRaises(TypeError, Gtk.Action)
42 action = Gtk.Action("test", "Test", "Test Action", Gtk.STOCK_COPY)
43 self.assertEqual(action.get_name(), "test")
44 self.assertEqual(action.get_label(), "Test")
45 self.assertEqual(action.get_tooltip(), "Test Action")
46 self.assertEqual(action.get_stock_id(), Gtk.STOCK_COPY)
48 self.assertEqual(Gtk.RadioAction, gi.overrides.Gtk.RadioAction)
49 self.assertRaises(TypeError, Gtk.RadioAction)
50 action = Gtk.RadioAction("test", "Test", "Test Action", Gtk.STOCK_COPY, 1)
51 self.assertEqual(action.get_name(), "test")
52 self.assertEqual(action.get_label(), "Test")
53 self.assertEqual(action.get_tooltip(), "Test Action")
54 self.assertEqual(action.get_stock_id(), Gtk.STOCK_COPY)
55 self.assertEqual(action.get_current_value(), 1)
57 def test_actiongroup(self):
58 self.assertEqual(Gtk.ActionGroup, gi.overrides.Gtk.ActionGroup)
59 self.assertRaises(TypeError, Gtk.ActionGroup)
61 action_group = Gtk.ActionGroup(name='TestActionGroup')
62 callback_data = "callback data"
64 def test_action_callback_data(action, user_data):
65 self.assertEqual(user_data, callback_data)
67 def test_radio_action_callback_data(action, current, user_data):
68 self.assertEqual(user_data, callback_data)
70 action_group.add_actions([
71 ('test-action1', None, 'Test Action 1',
72 None, None, test_action_callback_data),
73 ('test-action2', Gtk.STOCK_COPY, 'Test Action 2',
74 None, None, test_action_callback_data)], callback_data)
75 action_group.add_toggle_actions([
76 ('test-toggle-action1', None, 'Test Toggle Action 1',
77 None, None, test_action_callback_data, False),
78 ('test-toggle-action2', Gtk.STOCK_COPY, 'Test Toggle Action 2',
79 None, None, test_action_callback_data, True)], callback_data)
80 action_group.add_radio_actions([
81 ('test-radio-action1', None, 'Test Radio Action 1'),
82 ('test-radio-action2', Gtk.STOCK_COPY, 'Test Radio Action 2')], 1,
83 test_radio_action_callback_data,
86 expected_results = [('test-action1', Gtk.Action),
87 ('test-action2', Gtk.Action),
88 ('test-toggle-action1', Gtk.ToggleAction),
89 ('test-toggle-action2', Gtk.ToggleAction),
90 ('test-radio-action1', Gtk.RadioAction),
91 ('test-radio-action2', Gtk.RadioAction)]
93 for action in action_group.list_actions():
94 a = (action.get_name(), type(action))
95 self.assertTrue(a in expected_results)
96 expected_results.remove(a)
99 def test_uimanager(self):
100 self.assertEqual(Gtk.UIManager, gi.overrides.Gtk.UIManager)
102 ui.add_ui_from_string("""<ui>
103 <menubar name="menubar1"></menubar>
107 menubar = ui.get_widget("/menubar1")
108 self.assertEqual(type(menubar), Gtk.MenuBar)
110 ag = Gtk.ActionGroup(name="ag1")
111 ui.insert_action_group(ag)
112 ag2 = Gtk.ActionGroup(name="ag2")
113 ui.insert_action_group(ag2)
114 groups = ui.get_action_groups()
115 self.assertEqual(ag, groups[-2])
116 self.assertEqual(ag2, groups[-1])
118 def test_uimanager_nonascii(self):
120 ui.add_ui_from_string(b'<ui><menubar name="menub\xc3\xa6r1" /></ui>'.decode('UTF-8'))
121 mi = ui.get_widget("/menubær1")
122 self.assertEqual(type(mi), Gtk.MenuBar)
124 def test_builder(self):
125 self.assertEqual(Gtk.Builder, gi.overrides.Gtk.Builder)
127 class SignalTest(GObject.GObject):
128 __gtype_name__ = "GIOverrideSignalTest"
130 "test-signal": (GObject.SignalFlags.RUN_FIRST,
138 self.after_sentinel = 0
140 def on_signal_1(self, *args):
142 self.after_sentinel += 1
144 def on_signal_3(self, *args):
147 def on_signal_after(self, *args):
148 if self.after_sentinel == 1:
149 self.after_sentinel += 1
151 signal_checker = SignalCheck()
152 builder = Gtk.Builder()
154 # add object1 to the builder
155 builder.add_from_string("""
157 <object class="GIOverrideSignalTest" id="object1">
158 <signal name="test-signal" after="yes" handler="on_signal_after" />
159 <signal name="test-signal" handler="on_signal_1" />
164 # only add object3 to the builder
165 builder.add_objects_from_string("""
167 <object class="GIOverrideSignalTest" id="object2">
168 <signal name="test-signal" handler="on_signal_2" />
170 <object class="GIOverrideSignalTest" id="object3">
171 <signal name="test-signal" handler="on_signal_3" />
173 <object class="GIOverrideSignalTest" id="object4">
174 <signal name="test-signal" handler="on_signal_4" />
180 builder.connect_signals(signal_checker)
182 # call their notify signals and check sentinel
183 objects = builder.get_objects()
184 self.assertEqual(len(objects), 2)
186 obj.emit('test-signal')
188 self.assertEqual(signal_checker.sentinel, 4)
189 self.assertEqual(signal_checker.after_sentinel, 2)
191 def test_window(self):
194 self.assertEqual(w.get_property('type'), Gtk.WindowType.TOPLEVEL)
196 # type works as keyword argument
197 w = Gtk.Window(type=Gtk.WindowType.POPUP)
198 self.assertEqual(w.get_property('type'), Gtk.WindowType.POPUP)
200 # pygtk compatible positional argument
201 w = Gtk.Window(Gtk.WindowType.POPUP)
202 self.assertEqual(w.get_property('type'), Gtk.WindowType.POPUP)
204 class TestWindow(Gtk.Window):
205 __gtype_name__ = "TestWindow"
208 builder = Gtk.Builder()
209 builder.add_from_string('''
211 <object class="GtkWindow" id="win">
212 <property name="type">popup</property>
214 <object class="TestWindow" id="testwin">
216 <object class="TestWindow" id="testpop">
217 <property name="type">popup</property>
220 self.assertEqual(builder.get_object('win').get_property('type'),
221 Gtk.WindowType.POPUP)
222 self.assertEqual(builder.get_object('testwin').get_property('type'),
223 Gtk.WindowType.TOPLEVEL)
224 self.assertEqual(builder.get_object('testpop').get_property('type'),
225 Gtk.WindowType.POPUP)
227 def test_dialogs(self):
228 self.assertEqual(Gtk.Dialog, gi.overrides.Gtk.Dialog)
229 self.assertEqual(Gtk.AboutDialog, gi.overrides.Gtk.AboutDialog)
230 self.assertEqual(Gtk.MessageDialog, gi.overrides.Gtk.MessageDialog)
231 self.assertEqual(Gtk.ColorSelectionDialog, gi.overrides.Gtk.ColorSelectionDialog)
232 self.assertEqual(Gtk.FileChooserDialog, gi.overrides.Gtk.FileChooserDialog)
233 self.assertEqual(Gtk.FontSelectionDialog, gi.overrides.Gtk.FontSelectionDialog)
234 self.assertEqual(Gtk.RecentChooserDialog, gi.overrides.Gtk.RecentChooserDialog)
237 dialog = Gtk.Dialog(title='Foo',
238 flags=Gtk.DialogFlags.MODAL,
239 buttons=('test-button1', 1))
240 self.assertTrue(isinstance(dialog, Gtk.Dialog))
241 self.assertTrue(isinstance(dialog, Gtk.Window))
243 dialog.add_buttons('test-button2', 2, Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE)
245 self.assertEqual('Foo', dialog.get_title())
246 self.assertTrue(dialog.get_modal())
247 button = dialog.get_widget_for_response(1)
248 self.assertEqual('test-button1', button.get_label())
249 button = dialog.get_widget_for_response(2)
250 self.assertEqual('test-button2', button.get_label())
251 button = dialog.get_widget_for_response(Gtk.ResponseType.CLOSE)
252 self.assertEqual(Gtk.STOCK_CLOSE, button.get_label())
255 dialog = Gtk.AboutDialog()
256 self.assertTrue(isinstance(dialog, Gtk.Dialog))
257 self.assertTrue(isinstance(dialog, Gtk.Window))
260 dialog = Gtk.MessageDialog(title='message dialog test',
261 flags=Gtk.DialogFlags.MODAL,
262 buttons=Gtk.ButtonsType.OK,
263 message_format='dude!')
264 self.assertTrue(isinstance(dialog, Gtk.Dialog))
265 self.assertTrue(isinstance(dialog, Gtk.Window))
267 self.assertEqual('message dialog test', dialog.get_title())
268 self.assertTrue(dialog.get_modal())
269 text = dialog.get_property('text')
270 self.assertEqual('dude!', text)
272 dialog.format_secondary_text('2nd text')
273 self.assertEqual(dialog.get_property('secondary-text'), '2nd text')
274 self.assertFalse(dialog.get_property('secondary-use-markup'))
276 dialog.format_secondary_markup('2nd markup')
277 self.assertEqual(dialog.get_property('secondary-text'), '2nd markup')
278 self.assertTrue(dialog.get_property('secondary-use-markup'))
280 # Gtk.ColorSelectionDialog
281 dialog = Gtk.ColorSelectionDialog("color selection dialog test")
282 self.assertTrue(isinstance(dialog, Gtk.Dialog))
283 self.assertTrue(isinstance(dialog, Gtk.Window))
284 self.assertEqual('color selection dialog test', dialog.get_title())
286 # Gtk.FileChooserDialog
287 # might cause a GVFS warning, do not break on this
288 old_mask = GLib.log_set_always_fatal(
289 GLib.LogLevelFlags.LEVEL_CRITICAL | GLib.LogLevelFlags.LEVEL_ERROR)
291 dialog = Gtk.FileChooserDialog(title='file chooser dialog test',
292 buttons=('test-button1', 1),
293 action=Gtk.FileChooserAction.SAVE)
295 GLib.log_set_always_fatal(old_mask)
296 self.assertTrue(isinstance(dialog, Gtk.Dialog))
297 self.assertTrue(isinstance(dialog, Gtk.Window))
299 dialog.add_buttons('test-button2', 2, Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE)
300 self.assertEqual('file chooser dialog test', dialog.get_title())
301 button = dialog.get_widget_for_response(1)
302 self.assertEqual('test-button1', button.get_label())
303 button = dialog.get_widget_for_response(2)
304 self.assertEqual('test-button2', button.get_label())
305 button = dialog.get_widget_for_response(Gtk.ResponseType.CLOSE)
306 self.assertEqual(Gtk.STOCK_CLOSE, button.get_label())
307 action = dialog.get_property('action')
308 self.assertEqual(Gtk.FileChooserAction.SAVE, action)
310 # Gtk.FontSelectionDialog
311 dialog = Gtk.ColorSelectionDialog("font selection dialog test")
312 self.assertTrue(isinstance(dialog, Gtk.Dialog))
313 self.assertTrue(isinstance(dialog, Gtk.Window))
314 self.assertEqual('font selection dialog test', dialog.get_title())
316 # Gtk.RecentChooserDialog
317 test_manager = Gtk.RecentManager()
318 dialog = Gtk.RecentChooserDialog(title='recent chooser dialog test',
319 buttons=('test-button1', 1),
320 manager=test_manager)
321 self.assertTrue(isinstance(dialog, Gtk.Dialog))
322 self.assertTrue(isinstance(dialog, Gtk.Window))
324 dialog.add_buttons('test-button2', 2, Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE)
325 self.assertEqual('recent chooser dialog test', dialog.get_title())
326 button = dialog.get_widget_for_response(1)
327 self.assertEqual('test-button1', button.get_label())
328 button = dialog.get_widget_for_response(2)
329 self.assertEqual('test-button2', button.get_label())
330 button = dialog.get_widget_for_response(Gtk.ResponseType.CLOSE)
331 self.assertEqual(Gtk.STOCK_CLOSE, button.get_label())
333 class TestClass(GObject.GObject):
334 __gtype_name__ = "GIOverrideTreeAPITest"
336 def __init__(self, tester, int_value, string_value):
337 super(TestGtk.TestClass, self).__init__()
339 self.int_value = int_value
340 self.string_value = string_value
342 def check(self, int_value, string_value):
343 self.tester.assertEqual(int_value, self.int_value)
344 self.tester.assertEqual(string_value, self.string_value)
346 def test_buttons(self):
347 self.assertEqual(Gtk.Button, gi.overrides.Gtk.Button)
350 button = Gtk.Button()
351 self.assertTrue(isinstance(button, Gtk.Button))
352 self.assertTrue(isinstance(button, Gtk.Container))
353 self.assertTrue(isinstance(button, Gtk.Widget))
354 button = Gtk.Button(stock=Gtk.STOCK_CLOSE)
355 self.assertEqual(Gtk.STOCK_CLOSE, button.get_label())
356 self.assertTrue(button.get_use_stock())
357 self.assertTrue(button.get_use_underline())
359 # test Gtk.Button use_stock
360 button = Gtk.Button(label=Gtk.STOCK_CLOSE, use_stock=True, use_underline=True)
361 self.assertEqual(Gtk.STOCK_CLOSE, button.get_label())
362 self.assertTrue(button.get_use_stock())
363 self.assertTrue(button.get_use_underline())
365 # test Gtk.LinkButton
366 self.assertRaises(TypeError, Gtk.LinkButton)
367 button = Gtk.LinkButton('http://www.Gtk.org', 'Gtk')
368 self.assertTrue(isinstance(button, Gtk.Button))
369 self.assertTrue(isinstance(button, Gtk.Container))
370 self.assertTrue(isinstance(button, Gtk.Widget))
371 self.assertEqual('http://www.Gtk.org', button.get_uri())
372 self.assertEqual('Gtk', button.get_label())
374 def test_inheritance(self):
375 for name in gi.overrides.Gtk.__all__:
376 over = getattr(gi.overrides.Gtk, name)
377 for element in dir(Gtk):
379 klass = getattr(Gtk, element)
380 info = klass.__info__
381 except (NotImplementedError, AttributeError):
384 # Get all parent classes and interfaces klass inherits from
385 if isinstance(info, gi.types.ObjectInfo):
386 classes = list(info.get_interfaces())
387 parent = info.get_parent()
388 while parent.get_name() != "Object":
389 classes.append(parent)
390 parent = parent.get_parent()
391 classes = [kl for kl in classes if kl.get_namespace() == "Gtk"]
396 if kl.get_name() == name:
397 self.assertTrue(issubclass(klass, over,),
398 "%r does not inherit from override %r" % (klass, over,))
400 def test_editable(self):
401 self.assertEqual(Gtk.Editable, gi.overrides.Gtk.Editable)
403 # need to use Gtk.Entry because Editable is an interface
405 pos = entry.insert_text('HeWorld', 0)
406 self.assertEqual(pos, 7)
407 pos = entry.insert_text('llo ', 2)
408 self.assertEqual(pos, 6)
409 text = entry.get_chars(0, 11)
410 self.assertEqual('Hello World', text)
412 def test_label(self):
413 label = Gtk.Label(label='Hello')
414 self.assertTrue(isinstance(label, Gtk.Widget))
415 self.assertEqual(label.get_text(), 'Hello')
417 def adjustment_check(self, adjustment, value=0.0, lower=0.0, upper=0.0,
418 step_increment=0.0, page_increment=0.0, page_size=0.0):
419 self.assertEqual(adjustment.get_value(), value)
420 self.assertEqual(adjustment.get_lower(), lower)
421 self.assertEqual(adjustment.get_upper(), upper)
422 self.assertEqual(adjustment.get_step_increment(), step_increment)
423 self.assertEqual(adjustment.get_page_increment(), page_increment)
424 self.assertEqual(adjustment.get_page_size(), page_size)
426 def test_adjustment(self):
427 adjustment = Gtk.Adjustment(1, 0, 6, 4, 5, 3)
428 self.adjustment_check(adjustment, 1, 0, 6, 4, 5, 3)
430 adjustment = Gtk.Adjustment(1, 0, 6, 4, 5)
431 self.adjustment_check(adjustment, 1, 0, 6, 4, 5)
433 adjustment = Gtk.Adjustment(1, 0, 6, 4)
434 self.adjustment_check(adjustment, 1, 0, 6, 4)
436 adjustment = Gtk.Adjustment(1, 0, 6)
437 self.adjustment_check(adjustment, 1, 0, 6)
439 adjustment = Gtk.Adjustment()
440 self.adjustment_check(adjustment)
442 adjustment = Gtk.Adjustment(value=1, lower=0, upper=6,
443 step_increment=4, page_increment=5, page_size=3)
444 self.adjustment_check(adjustment, 1, 0, 6, 4, 5, 3)
446 def test_table(self):
448 self.assertTrue(isinstance(table, Gtk.Table))
449 self.assertTrue(isinstance(table, Gtk.Container))
450 self.assertTrue(isinstance(table, Gtk.Widget))
451 self.assertEqual(table.get_size(), (1, 1))
452 self.assertEqual(table.get_homogeneous(), False)
453 table = Gtk.Table(2, 3)
454 self.assertEqual(table.get_size(), (2, 3))
455 self.assertEqual(table.get_homogeneous(), False)
456 table = Gtk.Table(2, 3, True)
457 self.assertEqual(table.get_size(), (2, 3))
458 self.assertEqual(table.get_homogeneous(), True)
460 # Test PyGTK interface
461 table = Gtk.Table(rows=3, columns=2)
462 self.assertEqual(table.get_size(), (3, 2))
463 # Test using the actual property names
464 table = Gtk.Table(n_rows=2, n_columns=3, homogeneous=True)
465 self.assertEqual(table.get_size(), (2, 3))
466 self.assertEqual(table.get_homogeneous(), True)
468 label = Gtk.Label(label='Hello')
469 self.assertTrue(isinstance(label, Gtk.Widget))
470 table.attach(label, 0, 1, 0, 1)
471 self.assertEqual(label, table.get_children()[0])
473 def test_scrolledwindow(self):
474 sw = Gtk.ScrolledWindow()
475 self.assertTrue(isinstance(sw, Gtk.ScrolledWindow))
476 self.assertTrue(isinstance(sw, Gtk.Container))
477 self.assertTrue(isinstance(sw, Gtk.Widget))
478 sb = sw.get_hscrollbar()
479 self.assertEqual(sw.get_hadjustment(), sb.get_adjustment())
480 sb = sw.get_vscrollbar()
481 self.assertEqual(sw.get_vadjustment(), sb.get_adjustment())
483 def test_widget_drag_methods(self):
484 widget = Gtk.Button()
486 # here we are not checking functionality, only that the methods exist
487 # and except the right number of arguments
489 widget.drag_check_threshold(0, 0, 0, 0)
492 widget.drag_dest_set(Gtk.DestDefaults.DROP, None, Gdk.DragAction.COPY)
493 widget.drag_dest_add_image_targets()
494 widget.drag_dest_add_text_targets()
495 widget.drag_dest_add_uri_targets()
496 widget.drag_dest_get_track_motion()
497 widget.drag_dest_set_track_motion(True)
498 widget.drag_dest_get_target_list()
499 widget.drag_dest_set_target_list(Gtk.TargetList.new([Gtk.TargetEntry.new('test', 0, 0)]))
500 widget.drag_dest_unset()
502 widget.drag_highlight()
503 widget.drag_unhighlight()
505 # drag_source_ methods
506 widget.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, None, Gdk.DragAction.MOVE)
507 widget.drag_source_add_image_targets()
508 widget.drag_source_add_text_targets()
509 widget.drag_source_add_uri_targets()
510 widget.drag_source_set_icon_name("")
511 widget.drag_source_set_icon_pixbuf(GdkPixbuf.Pixbuf())
512 widget.drag_source_set_icon_stock("")
513 widget.drag_source_get_target_list()
514 widget.drag_source_set_target_list(Gtk.TargetList.new([Gtk.TargetEntry.new('test', 0, 0)]))
515 widget.drag_source_unset()
517 # these methods cannot be called because they require a valid drag on
518 # a real GdkWindow. So we only check that they exist and are callable.
519 self.assertTrue(hasattr(widget.drag_dest_set_proxy, '__call__'))
520 self.assertTrue(hasattr(widget.drag_get_data, '__call__'))
522 def test_scrollbar(self):
524 adjustment = Gtk.Adjustment()
526 hscrollbar = Gtk.HScrollbar()
527 vscrollbar = Gtk.VScrollbar()
528 self.assertNotEqual(hscrollbar.props.adjustment, adjustment)
529 self.assertNotEqual(vscrollbar.props.adjustment, adjustment)
531 hscrollbar = Gtk.HScrollbar(adjustment)
532 vscrollbar = Gtk.VScrollbar(adjustment)
533 self.assertEqual(hscrollbar.props.adjustment, adjustment)
534 self.assertEqual(vscrollbar.props.adjustment, adjustment)
536 def test_iconview(self):
538 iconview = Gtk.IconView()
539 self.assertEqual(iconview.props.model, None)
541 model = Gtk.ListStore(str)
542 iconview = Gtk.IconView(model)
543 self.assertEqual(iconview.props.model, model)
545 def test_toolbutton(self):
547 button = Gtk.ToolButton()
548 self.assertEqual(button.props.stock_id, None)
550 button = Gtk.ToolButton('gtk-new')
551 self.assertEqual(button.props.stock_id, 'gtk-new')
553 icon = Gtk.Image.new_from_stock(Gtk.STOCK_OPEN, Gtk.IconSize.SMALL_TOOLBAR)
555 button = Gtk.ToolButton(label='mylabel', icon_widget=icon)
556 self.assertEqual(button.props.label, 'mylabel')
557 self.assertEqual(button.props.icon_widget, icon)
559 def test_iconset(self):
562 pixbuf = GdkPixbuf.Pixbuf()
565 def test_viewport(self):
567 vadjustment = Gtk.Adjustment()
568 hadjustment = Gtk.Adjustment()
570 viewport = Gtk.Viewport(hadjustment=hadjustment,
571 vadjustment=vadjustment)
573 self.assertEqual(viewport.props.vadjustment, vadjustment)
574 self.assertEqual(viewport.props.hadjustment, hadjustment)
577 @unittest.skipUnless(Gtk, 'Gtk not available')
578 class TestTreeModel(unittest.TestCase):
579 def test_tree_model_sort(self):
580 self.assertEqual(Gtk.TreeModelSort, gi.overrides.Gtk.TreeModelSort)
581 self.assertRaises(TypeError, Gtk.TreeModelSort)
582 model = Gtk.TreeStore(int, bool)
583 model_sort = Gtk.TreeModelSort(model)
584 self.assertEqual(model_sort.get_model(), model)
586 def test_tree_store(self):
587 self.assertEqual(Gtk.TreeStore, gi.overrides.Gtk.TreeStore)
588 self.assertEqual(Gtk.ListStore, gi.overrides.Gtk.ListStore)
589 self.assertEqual(Gtk.TreeModel, gi.overrides.Gtk.TreeModel)
590 self.assertEqual(Gtk.TreeViewColumn, gi.overrides.Gtk.TreeViewColumn)
592 class TestPyObject(object):
595 test_pyobj = TestPyObject()
596 test_pydict = {1: 1, "2": 2, "3": "3"}
597 test_pylist = [1, "2", "3"]
598 tree_store = Gtk.TreeStore(int,
601 GObject.TYPE_PYOBJECT,
616 label = 'this is child #%d' % i
617 testobj = TestGtk.TestClass(self, i, label)
618 parent = tree_store.append(parent, (i,
635 parent = tree_store.append(parent)
637 label = 'this is child #%d' % i
638 testobj = TestGtk.TestClass(self, i, label)
639 tree_store.set(parent,
650 10, GObject.G_MAXULONG,
651 11, GObject.G_MININT64,
652 12, 0xffffffffffffffff,
656 parent = tree_store.append(parent)
658 label = 'this is child #%d' % i
659 testobj = TestGtk.TestClass(self, i, label)
660 tree_store.set(parent, {0: i,
670 10: GObject.G_MAXULONG,
671 11: GObject.G_MININT64,
672 12: 0xffffffffffffffff,
676 parent = tree_store.append(parent)
678 label = 'this is child #%d' % i
679 testobj = TestGtk.TestClass(self, i, label)
680 tree_store.set(parent, (0, 2, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14),
697 # len gets the number of children in the root node
698 # since we kept appending to the previous node
699 # there should only be one child of the root
700 self.assertEqual(len(tree_store), 1)
702 # walk the tree to see if the values were stored correctly
706 treeiter = tree_store.iter_children(parent)
708 i = tree_store.get_value(treeiter, 0)
709 s = tree_store.get_value(treeiter, 1)
710 obj = tree_store.get_value(treeiter, 2)
712 obj2 = tree_store.get_value(treeiter, 3)
713 self.assertEqual(obj, obj2)
715 pyobj = tree_store.get_value(treeiter, 4)
716 self.assertEqual(pyobj, test_pyobj)
717 pydict = tree_store.get_value(treeiter, 5)
718 self.assertEqual(pydict, test_pydict)
719 pylist = tree_store.get_value(treeiter, 6)
720 self.assertEqual(pylist, test_pylist)
722 bool_1 = tree_store.get_value(treeiter, 7)
723 bool_2 = tree_store.get_value(treeiter, 8)
724 self.assertEqual(bool_1, bool_2)
725 self.assertTrue(isinstance(bool_1, bool))
726 self.assertTrue(isinstance(bool_2, bool))
728 uint_ = tree_store.get_value(treeiter, 9)
729 self.assertEqual(uint_, i)
730 ulong_ = tree_store.get_value(treeiter, 10)
731 self.assertEqual(ulong_, GObject.G_MAXULONG)
732 int64_ = tree_store.get_value(treeiter, 11)
733 self.assertEqual(int64_, GObject.G_MININT64)
734 uint64_ = tree_store.get_value(treeiter, 12)
735 self.assertEqual(uint64_, 0xffffffffffffffff)
736 uchar_ = tree_store.get_value(treeiter, 13)
737 self.assertEqual(ord(uchar_), 254)
738 char_ = tree_store.get_value(treeiter, 14)
739 self.assertEqual(char_, 'a')
742 treeiter = tree_store.iter_children(parent)
744 self.assertEqual(i, 99)
746 def test_tree_store_signals(self):
747 tree_store = Gtk.TreeStore(int, bool)
749 def on_row_inserted(tree_store, tree_path, tree_iter, signal_list):
750 signal_list.append('row-inserted')
752 def on_row_changed(tree_store, tree_path, tree_iter, signal_list):
753 signal_list.append('row-changed')
756 tree_store.connect('row-inserted', on_row_inserted, signals)
757 tree_store.connect('row-changed', on_row_changed, signals)
759 # adding rows with and without data should only call one signal
760 tree_store.append(None, (0, False))
761 self.assertEqual(signals, ['row-inserted'])
764 tree_store.append(None)
765 self.assertEqual(signals, ['row-inserted'])
768 tree_store.prepend(None, (0, False))
769 self.assertEqual(signals, ['row-inserted'])
772 tree_store.prepend(None)
773 self.assertEqual(signals, ['row-inserted'])
776 tree_store.insert(None, 1, (0, False))
777 self.assertEqual(signals, ['row-inserted'])
780 tree_store.insert(None, 1)
781 self.assertEqual(signals, ['row-inserted'])
783 def test_list_store(self):
784 class TestPyObject(object):
787 test_pyobj = TestPyObject()
788 test_pydict = {1: 1, "2": 2, "3": "3"}
789 test_pylist = [1, "2", "3"]
791 list_store = Gtk.ListStore(int, str, 'GIOverrideTreeAPITest', object, object, object, bool, bool)
792 for i in range(1, 93):
793 label = 'this is row #%d' % i
794 testobj = TestGtk.TestClass(self, i, label)
795 list_store.append((i,
805 label = _unicode('this is row #93')
806 treeiter = list_store.append()
807 list_store.set_value(treeiter, 0, i)
808 list_store.set_value(treeiter, 1, label)
809 list_store.set_value(treeiter, 2, TestGtk.TestClass(self, i, label))
810 list_store.set_value(treeiter, 3, test_pyobj)
811 list_store.set_value(treeiter, 4, test_pydict)
812 list_store.set_value(treeiter, 5, test_pylist)
813 list_store.set_value(treeiter, 6, 1)
814 list_store.set_value(treeiter, 7, True)
817 label = 'this is row #0'
818 list_store.prepend((0,
820 TestGtk.TestClass(self, 0, label),
827 # test automatic unicode->str conversion
829 label = _unicode('this is row #94')
830 treeiter = list_store.append((i,
832 TestGtk.TestClass(self, i, label),
839 # add sorted items out of order to test insert* apis
840 # also test sending in None to not set a column
842 label = 'this is row #97'
843 treeiter = list_store.append((None,
852 list_store.set_value(treeiter, 0, i)
853 list_store.set_value(treeiter, 1, label)
854 list_store.set_value(treeiter, 2, TestGtk.TestClass(self, i, label))
855 list_store.set_value(treeiter, 4, test_pydict)
856 list_store.set_value(treeiter, 7, True)
860 label = 'this is row #99'
861 list_store.insert(9999, (i,
863 TestGtk.TestClass(self, i, label),
871 label = 'this is row #96'
872 list_store.insert_before(treeiter, (i,
874 TestGtk.TestClass(self, i, label),
882 label = 'this is row #98'
883 list_store.insert_after(treeiter, (i,
885 TestGtk.TestClass(self, i, label),
893 label = 'this is row #95'
894 list_store.insert(95, (i,
896 TestGtk.TestClass(self, i, label),
904 label = 'this is row #100'
905 treeiter = list_store.append()
906 list_store.set(treeiter,
909 2, TestGtk.TestClass(self, i, label),
916 label = 'this is row #101'
917 treeiter = list_store.append()
918 list_store.set(treeiter, {1: label,
920 2: TestGtk.TestClass(self, i, label),
927 label = 'this is row #102'
928 treeiter = list_store.append()
929 list_store.set(treeiter, (1, 0, 2, 3, 4, 5, 6, 7),
932 TestGtk.TestClass(self, i, label),
939 self.assertEqual(len(list_store), 103)
941 # walk the list to see if the values were stored correctly
943 treeiter = list_store.get_iter_first()
947 i = list_store.get_value(treeiter, 0)
948 self.assertEqual(i, counter)
949 s = list_store.get_value(treeiter, 1)
950 obj = list_store.get_value(treeiter, 2)
953 pyobj = list_store.get_value(treeiter, 3)
954 self.assertEqual(pyobj, test_pyobj)
955 pydict = list_store.get_value(treeiter, 4)
956 self.assertEqual(pydict, test_pydict)
957 pylist = list_store.get_value(treeiter, 5)
958 self.assertEqual(pylist, test_pylist)
960 bool_1 = list_store.get_value(treeiter, 6)
961 bool_2 = list_store.get_value(treeiter, 7)
962 self.assertEqual(bool_1, bool_2)
963 self.assertTrue(isinstance(bool_1, bool))
964 self.assertTrue(isinstance(bool_2, bool))
966 treeiter = list_store.iter_next(treeiter)
970 self.assertEqual(i, 102)
972 def test_list_store_sort(self):
973 def comp1(model, row1, row2, user_data):
977 # make "m" smaller than anything else
978 if v1.startswith('m') and not v2.startswith('m'):
980 if v2.startswith('m') and not v1.startswith('m'):
982 return (v1 > v2) - (v1 < v2)
984 list_store = Gtk.ListStore(int, str)
985 list_store.set_sort_func(2, comp1, None)
986 list_store.append((1, 'apples'))
987 list_store.append((3, 'oranges'))
988 list_store.append((2, 'mango'))
990 # not sorted yet, should be original order
991 self.assertEqual([list(i) for i in list_store],
992 [[1, 'apples'], [3, 'oranges'], [2, 'mango']])
994 # sort with our custom function
995 list_store.set_sort_column_id(2, Gtk.SortType.ASCENDING)
996 self.assertEqual([list(i) for i in list_store],
997 [[2, 'mango'], [1, 'apples'], [3, 'oranges']])
999 list_store.set_sort_column_id(2, Gtk.SortType.DESCENDING)
1000 self.assertEqual([list(i) for i in list_store],
1001 [[3, 'oranges'], [1, 'apples'], [2, 'mango']])
1003 def test_list_store_signals(self):
1004 list_store = Gtk.ListStore(int, bool)
1006 def on_row_inserted(list_store, tree_path, tree_iter, signal_list):
1007 signal_list.append('row-inserted')
1009 def on_row_changed(list_store, tree_path, tree_iter, signal_list):
1010 signal_list.append('row-changed')
1013 list_store.connect('row-inserted', on_row_inserted, signals)
1014 list_store.connect('row-changed', on_row_changed, signals)
1016 # adding rows with and without data should only call one signal
1017 list_store.append((0, False))
1018 self.assertEqual(signals, ['row-inserted'])
1022 self.assertEqual(signals, ['row-inserted'])
1025 list_store.prepend((0, False))
1026 self.assertEqual(signals, ['row-inserted'])
1029 list_store.prepend()
1030 self.assertEqual(signals, ['row-inserted'])
1033 list_store.insert(1, (0, False))
1034 self.assertEqual(signals, ['row-inserted'])
1037 list_store.insert(1)
1038 self.assertEqual(signals, ['row-inserted'])
1040 def test_tree_path(self):
1042 p2 = Gtk.TreePath.new_first()
1043 self.assertEqual(p1, p2)
1044 self.assertEqual(str(p1), '0')
1045 self.assertEqual(len(p1), 1)
1046 p1 = Gtk.TreePath(2)
1047 p2 = Gtk.TreePath.new_from_string('2')
1048 self.assertEqual(p1, p2)
1049 self.assertEqual(str(p1), '2')
1050 self.assertEqual(len(p1), 1)
1051 p1 = Gtk.TreePath('1:2:3')
1052 p2 = Gtk.TreePath.new_from_string('1:2:3')
1053 self.assertEqual(p1, p2)
1054 self.assertEqual(str(p1), '1:2:3')
1055 self.assertEqual(len(p1), 3)
1056 p1 = Gtk.TreePath((1, 2, 3))
1057 p2 = Gtk.TreePath.new_from_string('1:2:3')
1058 self.assertEqual(p1, p2)
1059 self.assertEqual(str(p1), '1:2:3')
1060 self.assertEqual(len(p1), 3)
1061 self.assertNotEqual(p1, None)
1062 self.assertTrue(p1 > None)
1063 self.assertTrue(p1 >= None)
1064 self.assertFalse(p1 < None)
1065 self.assertFalse(p1 <= None)
1067 self.assertEqual(tuple(p1), (1, 2, 3))
1068 self.assertEqual(p1[0], 1)
1069 self.assertEqual(p1[1], 2)
1070 self.assertEqual(p1[2], 3)
1071 self.assertRaises(IndexError, p1.__getitem__, 3)
1073 def test_tree_model(self):
1074 tree_store = Gtk.TreeStore(int, str)
1076 self.assertTrue(tree_store)
1077 self.assertEqual(len(tree_store), 0)
1078 self.assertEqual(tree_store.get_iter_first(), None)
1080 def get_by_index(row, col=None):
1082 return tree_store[row][col]
1084 return tree_store[row]
1086 self.assertRaises(TypeError, get_by_index, None)
1087 self.assertRaises(TypeError, get_by_index, "")
1088 self.assertRaises(TypeError, get_by_index, ())
1090 self.assertRaises(IndexError, get_by_index, "0")
1091 self.assertRaises(IndexError, get_by_index, 0)
1092 self.assertRaises(IndexError, get_by_index, (0,))
1094 self.assertRaises(ValueError, tree_store.get_iter, "0")
1095 self.assertRaises(ValueError, tree_store.get_iter, 0)
1096 self.assertRaises(ValueError, tree_store.get_iter, (0,))
1098 self.assertRaises(ValueError, tree_store.get_iter_from_string, "0")
1100 for row in tree_store:
1101 self.fail("Should not be reached")
1103 class DerivedIntType(int):
1106 class DerivedStrType(str):
1109 for i in range(100):
1110 label = 'this is row #%d' % i
1111 parent = tree_store.append(None, (DerivedIntType(i), DerivedStrType(label),))
1112 self.assertNotEqual(parent, None)
1114 label = 'this is child #%d of node #%d' % (j, i)
1115 child = tree_store.append(parent, (j, label,))
1116 self.assertNotEqual(child, None)
1118 self.assertTrue(tree_store)
1119 self.assertEqual(len(tree_store), 100)
1121 self.assertEqual(tree_store.iter_previous(tree_store.get_iter(0)), None)
1123 for i, row in enumerate(tree_store):
1124 self.assertEqual(row.model, tree_store)
1125 self.assertEqual(row.parent, None)
1127 self.assertEqual(tree_store[i].path, row.path)
1128 self.assertEqual(tree_store[str(i)].path, row.path)
1129 self.assertEqual(tree_store[(i,)].path, row.path)
1131 self.assertEqual(tree_store[i][0], i)
1132 self.assertEqual(tree_store[i][1], "this is row #%d" % i)
1134 aiter = tree_store.get_iter(i)
1135 self.assertEqual(tree_store.get_path(aiter), row.path)
1137 aiter = tree_store.get_iter(str(i))
1138 self.assertEqual(tree_store.get_path(aiter), row.path)
1140 aiter = tree_store.get_iter((i,))
1141 self.assertEqual(tree_store.get_path(aiter), row.path)
1143 self.assertEqual(tree_store.iter_parent(aiter), row.parent)
1145 next = tree_store.iter_next(aiter)
1146 if i < len(tree_store) - 1:
1147 self.assertEqual(tree_store.get_path(next), row.next.path)
1148 self.assertEqual(tree_store.get_path(tree_store.iter_previous(next)),
1149 tree_store.get_path(aiter))
1151 self.assertEqual(next, None)
1153 self.assertEqual(tree_store.iter_n_children(row.iter), 20)
1155 child = tree_store.iter_children(row.iter)
1156 for j, childrow in enumerate(row.iterchildren()):
1157 child_path = tree_store.get_path(child)
1158 self.assertEqual(childrow.path, child_path)
1159 self.assertEqual(childrow.parent.path, row.path)
1160 self.assertEqual(childrow.path, tree_store[child].path)
1161 self.assertEqual(childrow.path, tree_store[child_path].path)
1163 self.assertEqual(childrow[0], tree_store[child][0])
1164 self.assertEqual(childrow[0], j)
1165 self.assertEqual(childrow[1], tree_store[child][1])
1166 self.assertEqual(childrow[1], 'this is child #%d of node #%d' % (j, i))
1168 self.assertRaises(IndexError, get_by_index, child, 2)
1170 tree_store[child][1] = 'this was child #%d of node #%d' % (j, i)
1171 self.assertEqual(childrow[1], 'this was child #%d of node #%d' % (j, i))
1173 nth_child = tree_store.iter_nth_child(row.iter, j)
1174 self.assertEqual(childrow.path, tree_store.get_path(nth_child))
1176 childrow2 = tree_store["%d:%d" % (i, j)]
1177 self.assertEqual(childrow.path, childrow2.path)
1179 childrow2 = tree_store[(i, j,)]
1180 self.assertEqual(childrow.path, childrow2.path)
1182 child = tree_store.iter_next(child)
1184 self.assertEqual(childrow.next.path, tree_store.get_path(child))
1186 self.assertEqual(child, childrow.next)
1187 self.assertEqual(child, None)
1189 self.assertEqual(j, 19)
1191 self.assertEqual(i, 99)
1194 for i in range(-1, -100, -1):
1196 self.assertEqual(tree_store[i][0], i_real)
1199 for j in range(-1, -20, -1):
1201 path = (i_real, j_real,)
1203 self.assertEqual(tree_store[path][-2], j_real)
1205 label = 'this was child #%d of node #%d' % (j_real, i_real)
1206 self.assertEqual(tree_store[path][-1], label)
1208 new_label = 'this still is child #%d of node #%d' % (j_real, i_real)
1209 tree_store[path][-1] = new_label
1210 self.assertEqual(tree_store[path][-1], new_label)
1212 self.assertRaises(IndexError, get_by_index, path, -3)
1214 self.assertRaises(IndexError, get_by_index, -101)
1216 last_row = tree_store[99]
1217 self.assertNotEqual(last_row, None)
1219 for i, childrow in enumerate(last_row.iterchildren()):
1221 self.assertTrue(tree_store.remove(childrow.iter))
1223 self.assertFalse(tree_store.remove(childrow.iter))
1225 self.assertEqual(i, 19)
1227 self.assertEqual(tree_store.iter_n_children(last_row.iter), 0)
1228 for childrow in last_row.iterchildren():
1229 self.fail("Should not be reached")
1231 aiter = tree_store.get_iter(10)
1232 self.assertRaises(TypeError, tree_store.get, aiter, 1, 'a')
1233 self.assertRaises(ValueError, tree_store.get, aiter, 1, -1)
1234 self.assertRaises(ValueError, tree_store.get, aiter, 1, 100)
1235 self.assertEqual(tree_store.get(aiter, 0, 1), (10, 'this is row #10'))
1238 self.assertEqual(len(tree_store), 100)
1239 aiter = tree_store.get_iter(10)
1240 del tree_store[aiter]
1241 self.assertEqual(len(tree_store), 99)
1242 self.assertRaises(TypeError, tree_store.__delitem__, None)
1243 self.assertRaises(IndexError, tree_store.__delitem__, -101)
1244 self.assertRaises(IndexError, tree_store.__delitem__, 101)
1246 def test_tree_model_get_iter_fail(self):
1247 # TreeModel class with a failing get_iter()
1248 class MyTreeModel(GObject.GObject, Gtk.TreeModel):
1249 def do_get_iter(self, iter):
1250 return (False, None)
1253 self.assertEqual(tm.get_iter_first(), None)
1255 def test_tree_model_edit(self):
1256 model = Gtk.ListStore(int, str, float)
1257 model.append([1, "one", -0.1])
1258 model.append([2, "two", -0.2])
1263 self.assertRaises(TypeError, set_row, 3)
1264 self.assertRaises(TypeError, set_row, "three")
1265 self.assertRaises(ValueError, set_row, [])
1266 self.assertRaises(ValueError, set_row, [3, "three"])
1268 model[0] = (3, "three", -0.3)
1270 def test_tree_row_slice(self):
1271 model = Gtk.ListStore(int, str, float)
1272 model.append([1, "one", -0.1])
1274 self.assertEqual([1, "one", -0.1], model[0][:])
1275 self.assertEqual([1, "one"], model[0][:2])
1276 self.assertEqual(["one", -0.1], model[0][1:])
1277 self.assertEqual(["one"], model[0][1:-1])
1278 self.assertEqual([1], model[0][:-2])
1279 self.assertEqual([], model[0][5:])
1280 self.assertEqual([1, -0.1], model[0][0:3:2])
1282 model[0][:] = (2, "two", -0.2)
1283 self.assertEqual([2, "two", -0.2], model[0][:])
1285 model[0][:2] = (3, "three")
1286 self.assertEqual([3, "three", -0.2], model[0][:])
1288 model[0][1:] = ("four", -0.4)
1289 self.assertEqual([3, "four", -0.4], model[0][:])
1291 model[0][1:-1] = ("five",)
1292 self.assertEqual([3, "five", -0.4], model[0][:])
1294 model[0][0:3:2] = (6, -0.6)
1295 self.assertEqual([6, "five", -0.6], model[0][:])
1298 model[0][5:] = ("doesn't", "matter",)
1300 self.assertRaises(ValueError, set_row1)
1303 model[0][:1] = (0, "zero", 0)
1305 self.assertRaises(ValueError, set_row2)
1308 model[0][:2] = ("0", 0)
1310 self.assertRaises(TypeError, set_row3)
1312 def test_tree_model_set_value_to_none(self):
1313 # Tests allowing the usage of None to set an empty value on a model.
1314 store = Gtk.ListStore(str)
1315 row = store.append(['test'])
1316 self.assertSequenceEqual(store[0][:], ['test'])
1317 store.set_value(row, 0, None)
1318 self.assertSequenceEqual(store[0][:], [None])
1320 def test_signal_emission_tree_path_coerce(self):
1321 class Model(GObject.Object, Gtk.TreeModel):
1327 def on_any_signal(model, path, *args):
1328 tree_paths.append(path.to_string())
1330 model.connect('row-changed', on_any_signal)
1331 model.connect('row-deleted', on_any_signal)
1332 model.connect('row-has-child-toggled', on_any_signal)
1333 model.connect('row-inserted', on_any_signal)
1335 model.row_changed('0', Gtk.TreeIter())
1336 self.assertEqual(tree_paths[-1], '0')
1338 model.row_deleted('1')
1339 self.assertEqual(tree_paths[-1], '1')
1341 model.row_has_child_toggled('2', Gtk.TreeIter())
1342 self.assertEqual(tree_paths[-1], '2')
1344 model.row_inserted('3', Gtk.TreeIter())
1345 self.assertEqual(tree_paths[-1], '3')
1347 def test_tree_model_filter(self):
1348 model = Gtk.ListStore(int, str, float)
1349 model.append([1, "one", -0.1])
1350 model.append([2, "two", -0.2])
1352 filtered = Gtk.TreeModelFilter(child_model=model)
1354 self.assertEqual(filtered[0][1], 'one')
1355 filtered[0][1] = 'ONE'
1356 self.assertEqual(filtered[0][1], 'ONE')
1359 @unittest.skipUnless(Gtk, 'Gtk not available')
1360 class TestTreeView(unittest.TestCase):
1361 def test_tree_view(self):
1362 store = Gtk.ListStore(int, str)
1363 store.append((0, "foo"))
1364 store.append((1, "bar"))
1365 view = Gtk.TreeView()
1366 # FIXME: We can't easily call get_cursor() to make sure this works as
1367 # expected as we need to realize and focus the column; the following
1368 # will raise a Gtk-CRITICAL which we ignore for now
1369 old_mask = GLib.log_set_always_fatal(
1370 GLib.LogLevelFlags.LEVEL_WARNING | GLib.LogLevelFlags.LEVEL_ERROR)
1372 view.set_cursor(store[1].path)
1373 view.set_cursor(str(store[1].path))
1375 view.get_cell_area(store[1].path)
1376 view.get_cell_area(str(store[1].path))
1378 GLib.log_set_always_fatal(old_mask)
1380 def test_tree_view_column(self):
1381 cell = Gtk.CellRendererText()
1382 Gtk.TreeViewColumn(title='This is just a test',
1387 def test_tree_view_add_column_with_attributes(self):
1388 model = Gtk.ListStore(str, str, str)
1389 # deliberately use out-of-order sorting here; we assign column 0 to
1390 # model index 2, etc.
1391 model.append(['cell13', 'cell11', 'cell12'])
1392 model.append(['cell23', 'cell21', 'cell22'])
1394 tree = Gtk.TreeView(model)
1395 cell1 = Gtk.CellRendererText()
1396 cell2 = Gtk.CellRendererText()
1397 cell3 = Gtk.CellRendererText()
1398 cell4 = Gtk.CellRendererText()
1400 tree.insert_column_with_attributes(0, 'Head2', cell2, text=2)
1401 tree.insert_column_with_attributes(0, 'Head1', cell1, text=1)
1402 tree.insert_column_with_attributes(-1, 'Head3', cell3, text=0)
1404 tree.insert_column_with_attributes(-1, 'Head4', cell4)
1406 # might cause a Pango warning, do not break on this
1407 old_mask = GLib.log_set_always_fatal(
1408 GLib.LogLevelFlags.LEVEL_CRITICAL | GLib.LogLevelFlags.LEVEL_ERROR)
1410 # causes the widget to get realized and cellN.props.text receive a
1411 # value, otherwise it will be None.
1412 tree.get_preferred_size()
1414 GLib.log_set_always_fatal(old_mask)
1416 self.assertEqual(tree.get_column(0).get_title(), 'Head1')
1417 self.assertEqual(tree.get_column(1).get_title(), 'Head2')
1418 self.assertEqual(tree.get_column(2).get_title(), 'Head3')
1419 self.assertEqual(tree.get_column(3).get_title(), 'Head4')
1421 # cursor should be at the first row
1422 self.assertEqual(cell1.props.text, 'cell11')
1423 self.assertEqual(cell2.props.text, 'cell12')
1424 self.assertEqual(cell3.props.text, 'cell13')
1425 self.assertEqual(cell4.props.text, None)
1427 def test_tree_view_column_set_attributes(self):
1428 store = Gtk.ListStore(int, str)
1429 directors = ['Fellini', 'Tarantino', 'Tarkovskiy']
1430 for i, director in enumerate(directors):
1431 store.append([i, director])
1433 treeview = Gtk.TreeView()
1434 treeview.set_model(store)
1436 column = Gtk.TreeViewColumn()
1437 treeview.append_column(column)
1439 cell = Gtk.CellRendererText()
1440 column.pack_start(cell, expand=True)
1441 column.set_attributes(cell, text=1)
1443 # might cause a Pango warning, do not break on this
1444 old_mask = GLib.log_set_always_fatal(
1445 GLib.LogLevelFlags.LEVEL_CRITICAL | GLib.LogLevelFlags.LEVEL_ERROR)
1447 # This will make cell.props.text receive a value, otherwise it
1449 treeview.get_preferred_size()
1451 GLib.log_set_always_fatal(old_mask)
1453 self.assertTrue(cell.props.text in directors)
1455 def test_tree_selection(self):
1456 store = Gtk.ListStore(int, str)
1458 store.append((i, "foo"))
1459 view = Gtk.TreeView()
1460 view.set_model(store)
1461 firstpath = store.get_path(store.get_iter_first())
1462 sel = view.get_selection()
1464 sel.select_path(firstpath)
1465 (m, s) = sel.get_selected()
1466 self.assertEqual(m, store)
1467 self.assertEqual(store.get_path(s), firstpath)
1470 (m, s) = sel.get_selected()
1471 self.assertEqual(m, store)
1472 self.assertEqual(store.get_path(s), firstpath)
1474 sel.select_path("0:0")
1475 (m, s) = sel.get_selected()
1476 self.assertEqual(m, store)
1477 self.assertEqual(store.get_path(s), firstpath)
1479 sel.select_path((0, 0))
1480 (m, s) = sel.get_selected()
1481 self.assertEqual(m, store)
1482 self.assertEqual(store.get_path(s), firstpath)
1485 @unittest.skipUnless(Gtk, 'Gtk not available')
1486 class TestTextBuffer(unittest.TestCase):
1487 def test_text_buffer(self):
1488 self.assertEqual(Gtk.TextBuffer, gi.overrides.Gtk.TextBuffer)
1489 buffer = Gtk.TextBuffer()
1490 tag = buffer.create_tag('title', font='Sans 18')
1492 self.assertEqual(tag.props.name, 'title')
1493 self.assertEqual(tag.props.font, 'Sans 18')
1495 (start, end) = buffer.get_bounds()
1497 mark = buffer.create_mark(None, start)
1498 self.assertFalse(mark.get_left_gravity())
1500 buffer.set_text('Hello Jane Hello Bob')
1501 (start, end) = buffer.get_bounds()
1502 text = buffer.get_text(start, end, False)
1503 self.assertEqual(text, 'Hello Jane Hello Bob')
1506 (start, end) = buffer.get_bounds()
1507 text = buffer.get_text(start, end, False)
1508 self.assertEqual(text, '')
1510 buffer.insert(end, 'HelloHello')
1511 buffer.insert(end, ' Bob')
1513 cursor_iter = end.copy()
1514 cursor_iter.backward_chars(9)
1515 buffer.place_cursor(cursor_iter)
1516 buffer.insert_at_cursor(' Jane ')
1518 (start, end) = buffer.get_bounds()
1519 text = buffer.get_text(start, end, False)
1520 self.assertEqual(text, 'Hello Jane Hello Bob')
1522 sel = buffer.get_selection_bounds()
1523 self.assertEqual(sel, ())
1524 buffer.select_range(start, end)
1525 sel = buffer.get_selection_bounds()
1526 self.assertTrue(sel[0].equal(start))
1527 self.assertTrue(sel[1].equal(end))
1530 buffer.insert_with_tags(buffer.get_start_iter(), 'HelloHello', tag)
1531 (start, end) = buffer.get_bounds()
1532 self.assertTrue(start.begins_tag(tag))
1533 self.assertTrue(start.has_tag(tag))
1536 buffer.insert_with_tags_by_name(buffer.get_start_iter(), 'HelloHello', 'title')
1537 (start, end) = buffer.get_bounds()
1538 self.assertTrue(start.begins_tag(tag))
1539 self.assertTrue(start.has_tag(tag))
1541 self.assertRaises(ValueError, buffer.insert_with_tags_by_name,
1542 buffer.get_start_iter(), 'HelloHello', 'unknowntag')
1544 def test_text_iter(self):
1545 self.assertEqual(Gtk.TextIter, gi.overrides.Gtk.TextIter)
1546 buffer = Gtk.TextBuffer()
1547 buffer.set_text('Hello Jane Hello Bob')
1548 tag = buffer.create_tag('title', font='Sans 18')
1549 (start, end) = buffer.get_bounds()
1550 start.forward_chars(10)
1551 buffer.apply_tag(tag, start, end)
1552 self.assertTrue(start.begins_tag())
1553 self.assertTrue(end.ends_tag())
1554 self.assertTrue(start.toggles_tag())
1555 self.assertTrue(end.toggles_tag())
1556 start.backward_chars(1)
1557 self.assertFalse(start.begins_tag())
1558 self.assertFalse(start.ends_tag())
1559 self.assertFalse(start.toggles_tag())
1561 def test_text_buffer_search(self):
1562 buffer = Gtk.TextBuffer()
1563 buffer.set_text('Hello World Hello GNOME')
1565 i = buffer.get_iter_at_offset(0)
1566 self.assertTrue(isinstance(i, Gtk.TextIter))
1568 self.assertEqual(i.forward_search('world', 0, None), None)
1570 (start, end) = i.forward_search('World', 0, None)
1571 self.assertEqual(start.get_offset(), 6)
1572 self.assertEqual(end.get_offset(), 11)
1574 (start, end) = i.forward_search('world',
1575 Gtk.TextSearchFlags.CASE_INSENSITIVE,
1577 self.assertEqual(start.get_offset(), 6)
1578 self.assertEqual(end.get_offset(), 11)