1 # -*- Mode: Python; py-indent-offset: 4 -*-
2 # vim: tabstop=4 shiftwidth=4 expandtab
6 from compathelper import _unicode, _bytes
10 from gi.repository import GLib, GObject
13 from gi.repository import GdkPixbuf, Gdk, Gtk
19 @unittest.skipUnless(Gtk, 'Gtk not available')
20 class TestGtk(unittest.TestCase):
21 def test_container(self):
23 self.assertTrue(isinstance(box, Gtk.Box))
24 self.assertTrue(isinstance(box, Gtk.Container))
25 self.assertTrue(isinstance(box, Gtk.Widget))
31 self.assertTrue(label in box)
32 self.assertTrue(label2 in box)
33 self.assertEqual(len(box), 2)
36 self.assertEqual(l, [label, label2])
38 def test_actions(self):
39 self.assertEqual(Gtk.Action, gi.overrides.Gtk.Action)
40 self.assertRaises(TypeError, Gtk.Action)
41 action = Gtk.Action("test", "Test", "Test Action", Gtk.STOCK_COPY)
42 self.assertEqual(action.get_name(), "test")
43 self.assertEqual(action.get_label(), "Test")
44 self.assertEqual(action.get_tooltip(), "Test Action")
45 self.assertEqual(action.get_stock_id(), Gtk.STOCK_COPY)
47 self.assertEqual(Gtk.RadioAction, gi.overrides.Gtk.RadioAction)
48 self.assertRaises(TypeError, Gtk.RadioAction)
49 action = Gtk.RadioAction("test", "Test", "Test Action", Gtk.STOCK_COPY, 1)
50 self.assertEqual(action.get_name(), "test")
51 self.assertEqual(action.get_label(), "Test")
52 self.assertEqual(action.get_tooltip(), "Test Action")
53 self.assertEqual(action.get_stock_id(), Gtk.STOCK_COPY)
54 self.assertEqual(action.get_current_value(), 1)
56 def test_actiongroup(self):
57 self.assertEqual(Gtk.ActionGroup, gi.overrides.Gtk.ActionGroup)
58 self.assertRaises(TypeError, Gtk.ActionGroup)
60 action_group = Gtk.ActionGroup(name='TestActionGroup')
61 callback_data = "callback data"
63 def test_action_callback_data(action, user_data):
64 self.assertEqual(user_data, callback_data)
66 def test_radio_action_callback_data(action, current, user_data):
67 self.assertEqual(user_data, callback_data)
69 action_group.add_actions([
70 ('test-action1', None, 'Test Action 1',
71 None, None, test_action_callback_data),
72 ('test-action2', Gtk.STOCK_COPY, 'Test Action 2',
73 None, None, test_action_callback_data)], callback_data)
74 action_group.add_toggle_actions([
75 ('test-toggle-action1', None, 'Test Toggle Action 1',
76 None, None, test_action_callback_data, False),
77 ('test-toggle-action2', Gtk.STOCK_COPY, 'Test Toggle Action 2',
78 None, None, test_action_callback_data, True)], callback_data)
79 action_group.add_radio_actions([
80 ('test-radio-action1', None, 'Test Radio Action 1'),
81 ('test-radio-action2', Gtk.STOCK_COPY, 'Test Radio Action 2')], 1,
82 test_radio_action_callback_data,
85 expected_results = [('test-action1', Gtk.Action),
86 ('test-action2', Gtk.Action),
87 ('test-toggle-action1', Gtk.ToggleAction),
88 ('test-toggle-action2', Gtk.ToggleAction),
89 ('test-radio-action1', Gtk.RadioAction),
90 ('test-radio-action2', Gtk.RadioAction)]
92 for action in action_group.list_actions():
93 a = (action.get_name(), type(action))
94 self.assertTrue(a in expected_results)
95 expected_results.remove(a)
98 def test_uimanager(self):
99 self.assertEqual(Gtk.UIManager, gi.overrides.Gtk.UIManager)
101 ui.add_ui_from_string("""<ui>
102 <menubar name="menubar1"></menubar>
106 menubar = ui.get_widget("/menubar1")
107 self.assertEqual(type(menubar), Gtk.MenuBar)
109 ag = Gtk.ActionGroup(name="ag1")
110 ui.insert_action_group(ag)
111 ag2 = Gtk.ActionGroup(name="ag2")
112 ui.insert_action_group(ag2)
113 groups = ui.get_action_groups()
114 self.assertEqual(ag, groups[-2])
115 self.assertEqual(ag2, groups[-1])
117 def test_builder(self):
118 self.assertEqual(Gtk.Builder, gi.overrides.Gtk.Builder)
120 class SignalTest(GObject.GObject):
121 __gtype_name__ = "GIOverrideSignalTest"
123 "test-signal": (GObject.SignalFlags.RUN_FIRST,
131 self.after_sentinel = 0
133 def on_signal_1(self, *args):
135 self.after_sentinel += 1
137 def on_signal_3(self, *args):
140 def on_signal_after(self, *args):
141 if self.after_sentinel == 1:
142 self.after_sentinel += 1
144 signal_checker = SignalCheck()
145 builder = Gtk.Builder()
147 # add object1 to the builder
148 builder.add_from_string("""
150 <object class="GIOverrideSignalTest" id="object1">
151 <signal name="test-signal" after="yes" handler="on_signal_after" />
152 <signal name="test-signal" handler="on_signal_1" />
157 # only add object3 to the builder
158 builder.add_objects_from_string("""
160 <object class="GIOverrideSignalTest" id="object2">
161 <signal name="test-signal" handler="on_signal_2" />
163 <object class="GIOverrideSignalTest" id="object3">
164 <signal name="test-signal" handler="on_signal_3" />
166 <object class="GIOverrideSignalTest" id="object4">
167 <signal name="test-signal" handler="on_signal_4" />
173 builder.connect_signals(signal_checker)
175 # call their notify signals and check sentinel
176 objects = builder.get_objects()
177 self.assertEqual(len(objects), 2)
179 obj.emit('test-signal')
181 self.assertEqual(signal_checker.sentinel, 4)
182 self.assertEqual(signal_checker.after_sentinel, 2)
184 def test_window(self):
187 self.assertEqual(w.get_property('type'), Gtk.WindowType.TOPLEVEL)
189 # type works as keyword argument
190 w = Gtk.Window(type=Gtk.WindowType.POPUP)
191 self.assertEqual(w.get_property('type'), Gtk.WindowType.POPUP)
193 # pygtk compatible positional argument
194 w = Gtk.Window(Gtk.WindowType.POPUP)
195 self.assertEqual(w.get_property('type'), Gtk.WindowType.POPUP)
197 class TestWindow(Gtk.Window):
198 __gtype_name__ = "TestWindow"
201 builder = Gtk.Builder()
202 builder.add_from_string('''
204 <object class="GtkWindow" id="win">
205 <property name="type">popup</property>
207 <object class="TestWindow" id="testwin">
209 <object class="TestWindow" id="testpop">
210 <property name="type">popup</property>
213 self.assertEqual(builder.get_object('win').get_property('type'),
214 Gtk.WindowType.POPUP)
215 self.assertEqual(builder.get_object('testwin').get_property('type'),
216 Gtk.WindowType.TOPLEVEL)
217 self.assertEqual(builder.get_object('testpop').get_property('type'),
218 Gtk.WindowType.POPUP)
220 def test_dialogs(self):
221 self.assertEqual(Gtk.Dialog, gi.overrides.Gtk.Dialog)
222 self.assertEqual(Gtk.AboutDialog, gi.overrides.Gtk.AboutDialog)
223 self.assertEqual(Gtk.MessageDialog, gi.overrides.Gtk.MessageDialog)
224 self.assertEqual(Gtk.ColorSelectionDialog, gi.overrides.Gtk.ColorSelectionDialog)
225 self.assertEqual(Gtk.FileChooserDialog, gi.overrides.Gtk.FileChooserDialog)
226 self.assertEqual(Gtk.FontSelectionDialog, gi.overrides.Gtk.FontSelectionDialog)
227 self.assertEqual(Gtk.RecentChooserDialog, gi.overrides.Gtk.RecentChooserDialog)
230 dialog = Gtk.Dialog(title='Foo',
231 flags=Gtk.DialogFlags.MODAL,
232 buttons=('test-button1', 1))
233 self.assertTrue(isinstance(dialog, Gtk.Dialog))
234 self.assertTrue(isinstance(dialog, Gtk.Window))
236 dialog.add_buttons('test-button2', 2, Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE)
238 self.assertEqual('Foo', dialog.get_title())
239 self.assertTrue(dialog.get_modal())
240 button = dialog.get_widget_for_response(1)
241 self.assertEqual('test-button1', button.get_label())
242 button = dialog.get_widget_for_response(2)
243 self.assertEqual('test-button2', button.get_label())
244 button = dialog.get_widget_for_response(Gtk.ResponseType.CLOSE)
245 self.assertEqual(Gtk.STOCK_CLOSE, button.get_label())
248 dialog = Gtk.AboutDialog()
249 self.assertTrue(isinstance(dialog, Gtk.Dialog))
250 self.assertTrue(isinstance(dialog, Gtk.Window))
253 dialog = Gtk.MessageDialog(title='message dialog test',
254 flags=Gtk.DialogFlags.MODAL,
255 buttons=Gtk.ButtonsType.OK,
256 message_format='dude!')
257 self.assertTrue(isinstance(dialog, Gtk.Dialog))
258 self.assertTrue(isinstance(dialog, Gtk.Window))
260 self.assertEqual('message dialog test', dialog.get_title())
261 self.assertTrue(dialog.get_modal())
262 text = dialog.get_property('text')
263 self.assertEqual('dude!', text)
265 dialog.format_secondary_text('2nd text')
266 self.assertEqual(dialog.get_property('secondary-text'), '2nd text')
267 self.assertFalse(dialog.get_property('secondary-use-markup'))
269 dialog.format_secondary_markup('2nd markup')
270 self.assertEqual(dialog.get_property('secondary-text'), '2nd markup')
271 self.assertTrue(dialog.get_property('secondary-use-markup'))
273 # Gtk.ColorSelectionDialog
274 dialog = Gtk.ColorSelectionDialog("color selection dialog test")
275 self.assertTrue(isinstance(dialog, Gtk.Dialog))
276 self.assertTrue(isinstance(dialog, Gtk.Window))
277 self.assertEqual('color selection dialog test', dialog.get_title())
279 # Gtk.FileChooserDialog
280 # might cause a GVFS warning, do not break on this
281 old_mask = GLib.log_set_always_fatal(
282 GLib.LogLevelFlags.LEVEL_CRITICAL | GLib.LogLevelFlags.LEVEL_ERROR)
284 dialog = Gtk.FileChooserDialog(title='file chooser dialog test',
285 buttons=('test-button1', 1),
286 action=Gtk.FileChooserAction.SAVE)
288 GLib.log_set_always_fatal(old_mask)
289 self.assertTrue(isinstance(dialog, Gtk.Dialog))
290 self.assertTrue(isinstance(dialog, Gtk.Window))
292 dialog.add_buttons('test-button2', 2, Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE)
293 self.assertEqual('file chooser dialog test', dialog.get_title())
294 button = dialog.get_widget_for_response(1)
295 self.assertEqual('test-button1', button.get_label())
296 button = dialog.get_widget_for_response(2)
297 self.assertEqual('test-button2', button.get_label())
298 button = dialog.get_widget_for_response(Gtk.ResponseType.CLOSE)
299 self.assertEqual(Gtk.STOCK_CLOSE, button.get_label())
300 action = dialog.get_property('action')
301 self.assertEqual(Gtk.FileChooserAction.SAVE, action)
303 # Gtk.FontSelectionDialog
304 dialog = Gtk.ColorSelectionDialog("font selection dialog test")
305 self.assertTrue(isinstance(dialog, Gtk.Dialog))
306 self.assertTrue(isinstance(dialog, Gtk.Window))
307 self.assertEqual('font selection dialog test', dialog.get_title())
309 # Gtk.RecentChooserDialog
310 test_manager = Gtk.RecentManager()
311 dialog = Gtk.RecentChooserDialog(title='recent chooser dialog test',
312 buttons=('test-button1', 1),
313 manager=test_manager)
314 self.assertTrue(isinstance(dialog, Gtk.Dialog))
315 self.assertTrue(isinstance(dialog, Gtk.Window))
317 dialog.add_buttons('test-button2', 2, Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE)
318 self.assertEqual('recent chooser dialog test', dialog.get_title())
319 button = dialog.get_widget_for_response(1)
320 self.assertEqual('test-button1', button.get_label())
321 button = dialog.get_widget_for_response(2)
322 self.assertEqual('test-button2', button.get_label())
323 button = dialog.get_widget_for_response(Gtk.ResponseType.CLOSE)
324 self.assertEqual(Gtk.STOCK_CLOSE, button.get_label())
326 class TestClass(GObject.GObject):
327 __gtype_name__ = "GIOverrideTreeAPITest"
329 def __init__(self, tester, int_value, string_value):
330 super(TestGtk.TestClass, self).__init__()
332 self.int_value = int_value
333 self.string_value = string_value
335 def check(self, int_value, string_value):
336 self.tester.assertEqual(int_value, self.int_value)
337 self.tester.assertEqual(string_value, self.string_value)
339 def test_buttons(self):
340 self.assertEqual(Gtk.Button, gi.overrides.Gtk.Button)
343 button = Gtk.Button()
344 self.assertTrue(isinstance(button, Gtk.Button))
345 self.assertTrue(isinstance(button, Gtk.Container))
346 self.assertTrue(isinstance(button, Gtk.Widget))
347 button = Gtk.Button(stock=Gtk.STOCK_CLOSE)
348 self.assertEqual(Gtk.STOCK_CLOSE, button.get_label())
349 self.assertTrue(button.get_use_stock())
350 self.assertTrue(button.get_use_underline())
352 # test Gtk.Button use_stock
353 button = Gtk.Button(label=Gtk.STOCK_CLOSE, use_stock=True, use_underline=True)
354 self.assertEqual(Gtk.STOCK_CLOSE, button.get_label())
355 self.assertTrue(button.get_use_stock())
356 self.assertTrue(button.get_use_underline())
358 # test Gtk.LinkButton
359 self.assertRaises(TypeError, Gtk.LinkButton)
360 button = Gtk.LinkButton('http://www.Gtk.org', 'Gtk')
361 self.assertTrue(isinstance(button, Gtk.Button))
362 self.assertTrue(isinstance(button, Gtk.Container))
363 self.assertTrue(isinstance(button, Gtk.Widget))
364 self.assertEqual('http://www.Gtk.org', button.get_uri())
365 self.assertEqual('Gtk', button.get_label())
367 def test_inheritance(self):
368 for name in gi.overrides.Gtk.__all__:
369 over = getattr(gi.overrides.Gtk, name)
370 for element in dir(Gtk):
372 klass = getattr(Gtk, element)
373 info = klass.__info__
374 except (NotImplementedError, AttributeError):
377 # Get all parent classes and interfaces klass inherits from
378 if isinstance(info, gi.types.ObjectInfo):
379 classes = list(info.get_interfaces())
380 parent = info.get_parent()
381 while parent.get_name() != "Object":
382 classes.append(parent)
383 parent = parent.get_parent()
384 classes = [kl for kl in classes if kl.get_namespace() == "Gtk"]
389 if kl.get_name() == name:
390 self.assertTrue(issubclass(klass, over,),
391 "%r does not inherit from override %r" % (klass, over,))
393 def test_editable(self):
394 self.assertEqual(Gtk.Editable, gi.overrides.Gtk.Editable)
396 # need to use Gtk.Entry because Editable is an interface
398 pos = entry.insert_text('HeWorld', 0)
399 self.assertEqual(pos, 7)
400 pos = entry.insert_text('llo ', 2)
401 self.assertEqual(pos, 6)
402 text = entry.get_chars(0, 11)
403 self.assertEqual('Hello World', text)
405 def test_label(self):
406 label = Gtk.Label(label='Hello')
407 self.assertTrue(isinstance(label, Gtk.Widget))
408 self.assertEqual(label.get_text(), 'Hello')
410 def adjustment_check(self, adjustment, value=0.0, lower=0.0, upper=0.0,
411 step_increment=0.0, page_increment=0.0, page_size=0.0):
412 self.assertEqual(adjustment.get_value(), value)
413 self.assertEqual(adjustment.get_lower(), lower)
414 self.assertEqual(adjustment.get_upper(), upper)
415 self.assertEqual(adjustment.get_step_increment(), step_increment)
416 self.assertEqual(adjustment.get_page_increment(), page_increment)
417 self.assertEqual(adjustment.get_page_size(), page_size)
419 def test_adjustment(self):
420 adjustment = Gtk.Adjustment(1, 0, 6, 4, 5, 3)
421 self.adjustment_check(adjustment, 1, 0, 6, 4, 5, 3)
423 adjustment = Gtk.Adjustment(1, 0, 6, 4, 5)
424 self.adjustment_check(adjustment, 1, 0, 6, 4, 5)
426 adjustment = Gtk.Adjustment(1, 0, 6, 4)
427 self.adjustment_check(adjustment, 1, 0, 6, 4)
429 adjustment = Gtk.Adjustment(1, 0, 6)
430 self.adjustment_check(adjustment, 1, 0, 6)
432 adjustment = Gtk.Adjustment()
433 self.adjustment_check(adjustment)
435 adjustment = Gtk.Adjustment(value=1, lower=0, upper=6,
436 step_increment=4, page_increment=5, page_size=3)
437 self.adjustment_check(adjustment, 1, 0, 6, 4, 5, 3)
439 def test_table(self):
441 self.assertTrue(isinstance(table, Gtk.Table))
442 self.assertTrue(isinstance(table, Gtk.Container))
443 self.assertTrue(isinstance(table, Gtk.Widget))
444 self.assertEqual(table.get_size(), (1, 1))
445 self.assertEqual(table.get_homogeneous(), False)
446 table = Gtk.Table(2, 3)
447 self.assertEqual(table.get_size(), (2, 3))
448 self.assertEqual(table.get_homogeneous(), False)
449 table = Gtk.Table(2, 3, True)
450 self.assertEqual(table.get_size(), (2, 3))
451 self.assertEqual(table.get_homogeneous(), True)
453 # Test PyGTK interface
454 table = Gtk.Table(rows=3, columns=2)
455 self.assertEqual(table.get_size(), (3, 2))
456 # Test using the actual property names
457 table = Gtk.Table(n_rows=2, n_columns=3, homogeneous=True)
458 self.assertEqual(table.get_size(), (2, 3))
459 self.assertEqual(table.get_homogeneous(), True)
461 label = Gtk.Label(label='Hello')
462 self.assertTrue(isinstance(label, Gtk.Widget))
463 table.attach(label, 0, 1, 0, 1)
464 self.assertEqual(label, table.get_children()[0])
466 def test_scrolledwindow(self):
467 sw = Gtk.ScrolledWindow()
468 self.assertTrue(isinstance(sw, Gtk.ScrolledWindow))
469 self.assertTrue(isinstance(sw, Gtk.Container))
470 self.assertTrue(isinstance(sw, Gtk.Widget))
471 sb = sw.get_hscrollbar()
472 self.assertEqual(sw.get_hadjustment(), sb.get_adjustment())
473 sb = sw.get_vscrollbar()
474 self.assertEqual(sw.get_vadjustment(), sb.get_adjustment())
476 def test_widget_drag_methods(self):
477 widget = Gtk.Button()
479 # here we are not checking functionality, only that the methods exist
480 # and except the right number of arguments
482 widget.drag_check_threshold(0, 0, 0, 0)
485 widget.drag_dest_set(Gtk.DestDefaults.DROP, None, Gdk.DragAction.COPY)
486 widget.drag_dest_add_image_targets()
487 widget.drag_dest_add_text_targets()
488 widget.drag_dest_add_uri_targets()
489 widget.drag_dest_get_track_motion()
490 widget.drag_dest_set_track_motion(True)
491 widget.drag_dest_get_target_list()
492 widget.drag_dest_set_target_list(Gtk.TargetList.new([Gtk.TargetEntry.new('test', 0, 0)]))
493 widget.drag_dest_unset()
495 widget.drag_highlight()
496 widget.drag_unhighlight()
498 # drag_source_ methods
499 widget.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, None, Gdk.DragAction.MOVE)
500 widget.drag_source_add_image_targets()
501 widget.drag_source_add_text_targets()
502 widget.drag_source_add_uri_targets()
503 widget.drag_source_set_icon_name("")
504 widget.drag_source_set_icon_pixbuf(GdkPixbuf.Pixbuf())
505 widget.drag_source_set_icon_stock("")
506 widget.drag_source_get_target_list()
507 widget.drag_source_set_target_list(Gtk.TargetList.new([Gtk.TargetEntry.new('test', 0, 0)]))
508 widget.drag_source_unset()
510 # these methods cannot be called because they require a valid drag on
511 # a real GdkWindow. So we only check that they exist and are callable.
512 self.assertTrue(hasattr(widget.drag_dest_set_proxy, '__call__'))
513 self.assertTrue(hasattr(widget.drag_get_data, '__call__'))
515 def test_scrollbar(self):
517 adjustment = Gtk.Adjustment()
519 hscrollbar = Gtk.HScrollbar()
520 vscrollbar = Gtk.VScrollbar()
521 self.assertNotEqual(hscrollbar.props.adjustment, adjustment)
522 self.assertNotEqual(vscrollbar.props.adjustment, adjustment)
524 hscrollbar = Gtk.HScrollbar(adjustment)
525 vscrollbar = Gtk.VScrollbar(adjustment)
526 self.assertEqual(hscrollbar.props.adjustment, adjustment)
527 self.assertEqual(vscrollbar.props.adjustment, adjustment)
529 def test_iconview(self):
531 iconview = Gtk.IconView()
532 self.assertEqual(iconview.props.model, None)
534 model = Gtk.ListStore(str)
535 iconview = Gtk.IconView(model)
536 self.assertEqual(iconview.props.model, model)
538 def test_toolbutton(self):
540 button = Gtk.ToolButton()
541 self.assertEqual(button.props.stock_id, None)
543 button = Gtk.ToolButton('gtk-new')
544 self.assertEqual(button.props.stock_id, 'gtk-new')
546 icon = Gtk.Image.new_from_stock(Gtk.STOCK_OPEN, Gtk.IconSize.SMALL_TOOLBAR)
548 button = Gtk.ToolButton(label='mylabel', icon_widget=icon)
549 self.assertEqual(button.props.label, 'mylabel')
550 self.assertEqual(button.props.icon_widget, icon)
552 def test_iconset(self):
555 pixbuf = GdkPixbuf.Pixbuf()
558 def test_viewport(self):
560 vadjustment = Gtk.Adjustment()
561 hadjustment = Gtk.Adjustment()
563 viewport = Gtk.Viewport(hadjustment=hadjustment,
564 vadjustment=vadjustment)
566 self.assertEqual(viewport.props.vadjustment, vadjustment)
567 self.assertEqual(viewport.props.hadjustment, hadjustment)
570 @unittest.skipUnless(Gtk, 'Gtk not available')
571 class TestTreeModel(unittest.TestCase):
572 def test_tree_model_sort(self):
573 self.assertEqual(Gtk.TreeModelSort, gi.overrides.Gtk.TreeModelSort)
574 self.assertRaises(TypeError, Gtk.TreeModelSort)
575 model = Gtk.TreeStore(int, bool)
576 model_sort = Gtk.TreeModelSort(model)
577 self.assertEqual(model_sort.get_model(), model)
579 def test_tree_store(self):
580 self.assertEqual(Gtk.TreeStore, gi.overrides.Gtk.TreeStore)
581 self.assertEqual(Gtk.ListStore, gi.overrides.Gtk.ListStore)
582 self.assertEqual(Gtk.TreeModel, gi.overrides.Gtk.TreeModel)
583 self.assertEqual(Gtk.TreeViewColumn, gi.overrides.Gtk.TreeViewColumn)
585 class TestPyObject(object):
588 test_pyobj = TestPyObject()
589 test_pydict = {1: 1, "2": 2, "3": "3"}
590 test_pylist = [1, "2", "3"]
591 tree_store = Gtk.TreeStore(int,
594 GObject.TYPE_PYOBJECT,
609 label = 'this is child #%d' % i
610 testobj = TestGtk.TestClass(self, i, label)
611 parent = tree_store.append(parent, (i,
628 parent = tree_store.append(parent)
630 label = 'this is child #%d' % i
631 testobj = TestGtk.TestClass(self, i, label)
632 tree_store.set(parent,
643 10, GObject.G_MAXULONG,
644 11, GObject.G_MININT64,
645 12, 0xffffffffffffffff,
649 parent = tree_store.append(parent)
651 label = 'this is child #%d' % i
652 testobj = TestGtk.TestClass(self, i, label)
653 tree_store.set(parent, {0: i,
663 10: GObject.G_MAXULONG,
664 11: GObject.G_MININT64,
665 12: 0xffffffffffffffff,
669 parent = tree_store.append(parent)
671 label = 'this is child #%d' % i
672 testobj = TestGtk.TestClass(self, i, label)
673 tree_store.set(parent, (0, 2, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14),
690 # len gets the number of children in the root node
691 # since we kept appending to the previous node
692 # there should only be one child of the root
693 self.assertEqual(len(tree_store), 1)
695 # walk the tree to see if the values were stored correctly
699 treeiter = tree_store.iter_children(parent)
701 i = tree_store.get_value(treeiter, 0)
702 s = tree_store.get_value(treeiter, 1)
703 obj = tree_store.get_value(treeiter, 2)
705 obj2 = tree_store.get_value(treeiter, 3)
706 self.assertEqual(obj, obj2)
708 pyobj = tree_store.get_value(treeiter, 4)
709 self.assertEqual(pyobj, test_pyobj)
710 pydict = tree_store.get_value(treeiter, 5)
711 self.assertEqual(pydict, test_pydict)
712 pylist = tree_store.get_value(treeiter, 6)
713 self.assertEqual(pylist, test_pylist)
715 bool_1 = tree_store.get_value(treeiter, 7)
716 bool_2 = tree_store.get_value(treeiter, 8)
717 self.assertEqual(bool_1, bool_2)
718 self.assertTrue(isinstance(bool_1, bool))
719 self.assertTrue(isinstance(bool_2, bool))
721 uint_ = tree_store.get_value(treeiter, 9)
722 self.assertEqual(uint_, i)
723 ulong_ = tree_store.get_value(treeiter, 10)
724 self.assertEqual(ulong_, GObject.G_MAXULONG)
725 int64_ = tree_store.get_value(treeiter, 11)
726 self.assertEqual(int64_, GObject.G_MININT64)
727 uint64_ = tree_store.get_value(treeiter, 12)
728 self.assertEqual(uint64_, 0xffffffffffffffff)
729 uchar_ = tree_store.get_value(treeiter, 13)
730 self.assertEqual(ord(uchar_), 254)
731 char_ = tree_store.get_value(treeiter, 14)
732 self.assertEqual(char_, 'a')
735 treeiter = tree_store.iter_children(parent)
737 self.assertEqual(i, 99)
739 def test_tree_store_signals(self):
740 tree_store = Gtk.TreeStore(int, bool)
742 def on_row_inserted(tree_store, tree_path, tree_iter, signal_list):
743 signal_list.append('row-inserted')
745 def on_row_changed(tree_store, tree_path, tree_iter, signal_list):
746 signal_list.append('row-changed')
749 tree_store.connect('row-inserted', on_row_inserted, signals)
750 tree_store.connect('row-changed', on_row_changed, signals)
752 # adding rows with and without data should only call one signal
753 tree_store.append(None, (0, False))
754 self.assertEqual(signals, ['row-inserted'])
757 tree_store.append(None)
758 self.assertEqual(signals, ['row-inserted'])
761 tree_store.prepend(None, (0, False))
762 self.assertEqual(signals, ['row-inserted'])
765 tree_store.prepend(None)
766 self.assertEqual(signals, ['row-inserted'])
769 tree_store.insert(None, 1, (0, False))
770 self.assertEqual(signals, ['row-inserted'])
773 tree_store.insert(None, 1)
774 self.assertEqual(signals, ['row-inserted'])
776 def test_list_store(self):
777 class TestPyObject(object):
780 test_pyobj = TestPyObject()
781 test_pydict = {1: 1, "2": 2, "3": "3"}
782 test_pylist = [1, "2", "3"]
784 list_store = Gtk.ListStore(int, str, 'GIOverrideTreeAPITest', object, object, object, bool, bool)
785 for i in range(1, 93):
786 label = 'this is row #%d' % i
787 testobj = TestGtk.TestClass(self, i, label)
788 list_store.append((i,
798 label = _unicode('this is row #93')
799 treeiter = list_store.append()
800 list_store.set_value(treeiter, 0, i)
801 list_store.set_value(treeiter, 1, label)
802 list_store.set_value(treeiter, 2, TestGtk.TestClass(self, i, label))
803 list_store.set_value(treeiter, 3, test_pyobj)
804 list_store.set_value(treeiter, 4, test_pydict)
805 list_store.set_value(treeiter, 5, test_pylist)
806 list_store.set_value(treeiter, 6, 1)
807 list_store.set_value(treeiter, 7, True)
810 label = 'this is row #0'
811 list_store.prepend((0,
813 TestGtk.TestClass(self, 0, label),
820 # test automatic unicode->str conversion
822 label = _unicode('this is row #94')
823 treeiter = list_store.append((i,
825 TestGtk.TestClass(self, i, label),
832 # add sorted items out of order to test insert* apis
833 # also test sending in None to not set a column
835 label = 'this is row #97'
836 treeiter = list_store.append((None,
845 list_store.set_value(treeiter, 0, i)
846 list_store.set_value(treeiter, 1, label)
847 list_store.set_value(treeiter, 2, TestGtk.TestClass(self, i, label))
848 list_store.set_value(treeiter, 4, test_pydict)
849 list_store.set_value(treeiter, 7, True)
853 label = 'this is row #99'
854 list_store.insert(9999, (i,
856 TestGtk.TestClass(self, i, label),
864 label = 'this is row #96'
865 list_store.insert_before(treeiter, (i,
867 TestGtk.TestClass(self, i, label),
875 label = 'this is row #98'
876 list_store.insert_after(treeiter, (i,
878 TestGtk.TestClass(self, i, label),
886 label = 'this is row #95'
887 list_store.insert(95, (i,
889 TestGtk.TestClass(self, i, label),
897 label = 'this is row #100'
898 treeiter = list_store.append()
899 list_store.set(treeiter,
902 2, TestGtk.TestClass(self, i, label),
909 label = 'this is row #101'
910 treeiter = list_store.append()
911 list_store.set(treeiter, {1: label,
913 2: TestGtk.TestClass(self, i, label),
920 label = 'this is row #102'
921 treeiter = list_store.append()
922 list_store.set(treeiter, (1, 0, 2, 3, 4, 5, 6, 7),
925 TestGtk.TestClass(self, i, label),
932 self.assertEqual(len(list_store), 103)
934 # walk the list to see if the values were stored correctly
936 treeiter = list_store.get_iter_first()
940 i = list_store.get_value(treeiter, 0)
941 self.assertEqual(i, counter)
942 s = list_store.get_value(treeiter, 1)
943 obj = list_store.get_value(treeiter, 2)
946 pyobj = list_store.get_value(treeiter, 3)
947 self.assertEqual(pyobj, test_pyobj)
948 pydict = list_store.get_value(treeiter, 4)
949 self.assertEqual(pydict, test_pydict)
950 pylist = list_store.get_value(treeiter, 5)
951 self.assertEqual(pylist, test_pylist)
953 bool_1 = list_store.get_value(treeiter, 6)
954 bool_2 = list_store.get_value(treeiter, 7)
955 self.assertEqual(bool_1, bool_2)
956 self.assertTrue(isinstance(bool_1, bool))
957 self.assertTrue(isinstance(bool_2, bool))
959 treeiter = list_store.iter_next(treeiter)
963 self.assertEqual(i, 102)
965 def test_list_store_sort(self):
966 def comp1(model, row1, row2, user_data):
970 # make "m" smaller than anything else
971 if v1.startswith('m') and not v2.startswith('m'):
973 if v2.startswith('m') and not v1.startswith('m'):
975 return (v1 > v2) - (v1 < v2)
977 list_store = Gtk.ListStore(int, str)
978 list_store.set_sort_func(2, comp1, None)
979 list_store.append((1, 'apples'))
980 list_store.append((3, 'oranges'))
981 list_store.append((2, 'mango'))
983 # not sorted yet, should be original order
984 self.assertEqual([list(i) for i in list_store],
985 [[1, 'apples'], [3, 'oranges'], [2, 'mango']])
987 # sort with our custom function
988 list_store.set_sort_column_id(2, Gtk.SortType.ASCENDING)
989 self.assertEqual([list(i) for i in list_store],
990 [[2, 'mango'], [1, 'apples'], [3, 'oranges']])
992 list_store.set_sort_column_id(2, Gtk.SortType.DESCENDING)
993 self.assertEqual([list(i) for i in list_store],
994 [[3, 'oranges'], [1, 'apples'], [2, 'mango']])
996 def test_list_store_signals(self):
997 list_store = Gtk.ListStore(int, bool)
999 def on_row_inserted(list_store, tree_path, tree_iter, signal_list):
1000 signal_list.append('row-inserted')
1002 def on_row_changed(list_store, tree_path, tree_iter, signal_list):
1003 signal_list.append('row-changed')
1006 list_store.connect('row-inserted', on_row_inserted, signals)
1007 list_store.connect('row-changed', on_row_changed, signals)
1009 # adding rows with and without data should only call one signal
1010 list_store.append((0, False))
1011 self.assertEqual(signals, ['row-inserted'])
1015 self.assertEqual(signals, ['row-inserted'])
1018 list_store.prepend((0, False))
1019 self.assertEqual(signals, ['row-inserted'])
1022 list_store.prepend()
1023 self.assertEqual(signals, ['row-inserted'])
1026 list_store.insert(1, (0, False))
1027 self.assertEqual(signals, ['row-inserted'])
1030 list_store.insert(1)
1031 self.assertEqual(signals, ['row-inserted'])
1033 def test_tree_path(self):
1035 p2 = Gtk.TreePath.new_first()
1036 self.assertEqual(p1, p2)
1037 self.assertEqual(str(p1), '0')
1038 self.assertEqual(len(p1), 1)
1039 p1 = Gtk.TreePath(2)
1040 p2 = Gtk.TreePath.new_from_string('2')
1041 self.assertEqual(p1, p2)
1042 self.assertEqual(str(p1), '2')
1043 self.assertEqual(len(p1), 1)
1044 p1 = Gtk.TreePath('1:2:3')
1045 p2 = Gtk.TreePath.new_from_string('1:2:3')
1046 self.assertEqual(p1, p2)
1047 self.assertEqual(str(p1), '1:2:3')
1048 self.assertEqual(len(p1), 3)
1049 p1 = Gtk.TreePath((1, 2, 3))
1050 p2 = Gtk.TreePath.new_from_string('1:2:3')
1051 self.assertEqual(p1, p2)
1052 self.assertEqual(str(p1), '1:2:3')
1053 self.assertEqual(len(p1), 3)
1054 self.assertNotEqual(p1, None)
1055 self.assertTrue(p1 > None)
1056 self.assertTrue(p1 >= None)
1057 self.assertFalse(p1 < None)
1058 self.assertFalse(p1 <= None)
1060 self.assertEqual(tuple(p1), (1, 2, 3))
1061 self.assertEqual(p1[0], 1)
1062 self.assertEqual(p1[1], 2)
1063 self.assertEqual(p1[2], 3)
1064 self.assertRaises(IndexError, p1.__getitem__, 3)
1066 def test_tree_model(self):
1067 tree_store = Gtk.TreeStore(int, str)
1069 self.assertTrue(tree_store)
1070 self.assertEqual(len(tree_store), 0)
1071 self.assertEqual(tree_store.get_iter_first(), None)
1073 def get_by_index(row, col=None):
1075 return tree_store[row][col]
1077 return tree_store[row]
1079 self.assertRaises(TypeError, get_by_index, None)
1080 self.assertRaises(TypeError, get_by_index, "")
1081 self.assertRaises(TypeError, get_by_index, ())
1083 self.assertRaises(IndexError, get_by_index, "0")
1084 self.assertRaises(IndexError, get_by_index, 0)
1085 self.assertRaises(IndexError, get_by_index, (0,))
1087 self.assertRaises(ValueError, tree_store.get_iter, "0")
1088 self.assertRaises(ValueError, tree_store.get_iter, 0)
1089 self.assertRaises(ValueError, tree_store.get_iter, (0,))
1091 self.assertRaises(ValueError, tree_store.get_iter_from_string, "0")
1093 for row in tree_store:
1094 self.fail("Should not be reached")
1096 class DerivedIntType(int):
1099 class DerivedStrType(str):
1102 for i in range(100):
1103 label = 'this is row #%d' % i
1104 parent = tree_store.append(None, (DerivedIntType(i), DerivedStrType(label),))
1105 self.assertNotEqual(parent, None)
1107 label = 'this is child #%d of node #%d' % (j, i)
1108 child = tree_store.append(parent, (j, label,))
1109 self.assertNotEqual(child, None)
1111 self.assertTrue(tree_store)
1112 self.assertEqual(len(tree_store), 100)
1114 self.assertEqual(tree_store.iter_previous(tree_store.get_iter(0)), None)
1116 for i, row in enumerate(tree_store):
1117 self.assertEqual(row.model, tree_store)
1118 self.assertEqual(row.parent, None)
1120 self.assertEqual(tree_store[i].path, row.path)
1121 self.assertEqual(tree_store[str(i)].path, row.path)
1122 self.assertEqual(tree_store[(i,)].path, row.path)
1124 self.assertEqual(tree_store[i][0], i)
1125 self.assertEqual(tree_store[i][1], "this is row #%d" % i)
1127 aiter = tree_store.get_iter(i)
1128 self.assertEqual(tree_store.get_path(aiter), row.path)
1130 aiter = tree_store.get_iter(str(i))
1131 self.assertEqual(tree_store.get_path(aiter), row.path)
1133 aiter = tree_store.get_iter((i,))
1134 self.assertEqual(tree_store.get_path(aiter), row.path)
1136 self.assertEqual(tree_store.iter_parent(aiter), row.parent)
1138 next = tree_store.iter_next(aiter)
1139 if i < len(tree_store) - 1:
1140 self.assertEqual(tree_store.get_path(next), row.next.path)
1141 self.assertEqual(tree_store.get_path(tree_store.iter_previous(next)),
1142 tree_store.get_path(aiter))
1144 self.assertEqual(next, None)
1146 self.assertEqual(tree_store.iter_n_children(row.iter), 20)
1148 child = tree_store.iter_children(row.iter)
1149 for j, childrow in enumerate(row.iterchildren()):
1150 child_path = tree_store.get_path(child)
1151 self.assertEqual(childrow.path, child_path)
1152 self.assertEqual(childrow.parent.path, row.path)
1153 self.assertEqual(childrow.path, tree_store[child].path)
1154 self.assertEqual(childrow.path, tree_store[child_path].path)
1156 self.assertEqual(childrow[0], tree_store[child][0])
1157 self.assertEqual(childrow[0], j)
1158 self.assertEqual(childrow[1], tree_store[child][1])
1159 self.assertEqual(childrow[1], 'this is child #%d of node #%d' % (j, i))
1161 self.assertRaises(IndexError, get_by_index, child, 2)
1163 tree_store[child][1] = 'this was child #%d of node #%d' % (j, i)
1164 self.assertEqual(childrow[1], 'this was child #%d of node #%d' % (j, i))
1166 nth_child = tree_store.iter_nth_child(row.iter, j)
1167 self.assertEqual(childrow.path, tree_store.get_path(nth_child))
1169 childrow2 = tree_store["%d:%d" % (i, j)]
1170 self.assertEqual(childrow.path, childrow2.path)
1172 childrow2 = tree_store[(i, j,)]
1173 self.assertEqual(childrow.path, childrow2.path)
1175 child = tree_store.iter_next(child)
1177 self.assertEqual(childrow.next.path, tree_store.get_path(child))
1179 self.assertEqual(child, childrow.next)
1180 self.assertEqual(child, None)
1182 self.assertEqual(j, 19)
1184 self.assertEqual(i, 99)
1187 for i in range(-1, -100, -1):
1189 self.assertEqual(tree_store[i][0], i_real)
1192 for j in range(-1, -20, -1):
1194 path = (i_real, j_real,)
1196 self.assertEqual(tree_store[path][-2], j_real)
1198 label = 'this was child #%d of node #%d' % (j_real, i_real)
1199 self.assertEqual(tree_store[path][-1], label)
1201 new_label = 'this still is child #%d of node #%d' % (j_real, i_real)
1202 tree_store[path][-1] = new_label
1203 self.assertEqual(tree_store[path][-1], new_label)
1205 self.assertRaises(IndexError, get_by_index, path, -3)
1207 self.assertRaises(IndexError, get_by_index, -101)
1209 last_row = tree_store[99]
1210 self.assertNotEqual(last_row, None)
1212 for i, childrow in enumerate(last_row.iterchildren()):
1214 self.assertTrue(tree_store.remove(childrow.iter))
1216 self.assertFalse(tree_store.remove(childrow.iter))
1218 self.assertEqual(i, 19)
1220 self.assertEqual(tree_store.iter_n_children(last_row.iter), 0)
1221 for childrow in last_row.iterchildren():
1222 self.fail("Should not be reached")
1224 aiter = tree_store.get_iter(10)
1225 self.assertRaises(TypeError, tree_store.get, aiter, 1, 'a')
1226 self.assertRaises(ValueError, tree_store.get, aiter, 1, -1)
1227 self.assertRaises(ValueError, tree_store.get, aiter, 1, 100)
1228 self.assertEqual(tree_store.get(aiter, 0, 1), (10, 'this is row #10'))
1231 self.assertEqual(len(tree_store), 100)
1232 aiter = tree_store.get_iter(10)
1233 del tree_store[aiter]
1234 self.assertEqual(len(tree_store), 99)
1235 self.assertRaises(TypeError, tree_store.__delitem__, None)
1236 self.assertRaises(IndexError, tree_store.__delitem__, -101)
1237 self.assertRaises(IndexError, tree_store.__delitem__, 101)
1239 def test_tree_model_get_iter_fail(self):
1240 # TreeModel class with a failing get_iter()
1241 class MyTreeModel(GObject.GObject, Gtk.TreeModel):
1242 def do_get_iter(self, iter):
1243 return (False, None)
1246 self.assertEqual(tm.get_iter_first(), None)
1248 def test_tree_model_edit(self):
1249 model = Gtk.ListStore(int, str, float)
1250 model.append([1, "one", -0.1])
1251 model.append([2, "two", -0.2])
1256 self.assertRaises(TypeError, set_row, 3)
1257 self.assertRaises(TypeError, set_row, "three")
1258 self.assertRaises(ValueError, set_row, [])
1259 self.assertRaises(ValueError, set_row, [3, "three"])
1261 model[0] = (3, "three", -0.3)
1263 def test_tree_row_slice(self):
1264 model = Gtk.ListStore(int, str, float)
1265 model.append([1, "one", -0.1])
1267 self.assertEqual([1, "one", -0.1], model[0][:])
1268 self.assertEqual([1, "one"], model[0][:2])
1269 self.assertEqual(["one", -0.1], model[0][1:])
1270 self.assertEqual(["one"], model[0][1:-1])
1271 self.assertEqual([1], model[0][:-2])
1272 self.assertEqual([], model[0][5:])
1273 self.assertEqual([1, -0.1], model[0][0:3:2])
1275 model[0][:] = (2, "two", -0.2)
1276 self.assertEqual([2, "two", -0.2], model[0][:])
1278 model[0][:2] = (3, "three")
1279 self.assertEqual([3, "three", -0.2], model[0][:])
1281 model[0][1:] = ("four", -0.4)
1282 self.assertEqual([3, "four", -0.4], model[0][:])
1284 model[0][1:-1] = ("five",)
1285 self.assertEqual([3, "five", -0.4], model[0][:])
1287 model[0][0:3:2] = (6, -0.6)
1288 self.assertEqual([6, "five", -0.6], model[0][:])
1291 model[0][5:] = ("doesn't", "matter",)
1293 self.assertRaises(ValueError, set_row1)
1296 model[0][:1] = (0, "zero", 0)
1298 self.assertRaises(ValueError, set_row2)
1301 model[0][:2] = ("0", 0)
1303 self.assertRaises(ValueError, set_row3)
1306 @unittest.skipUnless(Gtk, 'Gtk not available')
1307 class TestTreeView(unittest.TestCase):
1308 def test_tree_view(self):
1309 store = Gtk.ListStore(int, str)
1310 store.append((0, "foo"))
1311 store.append((1, "bar"))
1312 view = Gtk.TreeView()
1313 # FIXME: We can't easily call get_cursor() to make sure this works as
1314 # expected as we need to realize and focus the column; the following
1315 # will raise a Gtk-CRITICAL which we ignore for now
1316 old_mask = GLib.log_set_always_fatal(
1317 GLib.LogLevelFlags.LEVEL_WARNING | GLib.LogLevelFlags.LEVEL_ERROR)
1319 view.set_cursor(store[1].path)
1320 view.set_cursor(str(store[1].path))
1322 view.get_cell_area(store[1].path)
1323 view.get_cell_area(str(store[1].path))
1325 GLib.log_set_always_fatal(old_mask)
1327 def test_tree_view_column(self):
1328 cell = Gtk.CellRendererText()
1329 Gtk.TreeViewColumn(title='This is just a test',
1334 def test_tree_view_add_column_with_attributes(self):
1335 model = Gtk.ListStore(str, str, str)
1336 # deliberately use out-of-order sorting here; we assign column 0 to
1337 # model index 2, etc.
1338 model.append(['cell13', 'cell11', 'cell12'])
1339 model.append(['cell23', 'cell21', 'cell22'])
1341 tree = Gtk.TreeView(model)
1342 cell1 = Gtk.CellRendererText()
1343 cell2 = Gtk.CellRendererText()
1344 cell3 = Gtk.CellRendererText()
1345 cell4 = Gtk.CellRendererText()
1347 tree.insert_column_with_attributes(0, 'Head2', cell2, text=2)
1348 tree.insert_column_with_attributes(0, 'Head1', cell1, text=1)
1349 tree.insert_column_with_attributes(-1, 'Head3', cell3, text=0)
1351 tree.insert_column_with_attributes(-1, 'Head4', cell4)
1353 # might cause a Pango warning, do not break on this
1354 old_mask = GLib.log_set_always_fatal(
1355 GLib.LogLevelFlags.LEVEL_CRITICAL | GLib.LogLevelFlags.LEVEL_ERROR)
1357 # causes the widget to get realized and cellN.props.text receive a
1358 # value, otherwise it will be None.
1359 tree.get_preferred_size()
1361 GLib.log_set_always_fatal(old_mask)
1363 self.assertEqual(tree.get_column(0).get_title(), 'Head1')
1364 self.assertEqual(tree.get_column(1).get_title(), 'Head2')
1365 self.assertEqual(tree.get_column(2).get_title(), 'Head3')
1366 self.assertEqual(tree.get_column(3).get_title(), 'Head4')
1368 # cursor should be at the first row
1369 self.assertEqual(cell1.props.text, 'cell11')
1370 self.assertEqual(cell2.props.text, 'cell12')
1371 self.assertEqual(cell3.props.text, 'cell13')
1372 self.assertEqual(cell4.props.text, None)
1374 def test_tree_view_column_set_attributes(self):
1375 store = Gtk.ListStore(int, str)
1376 directors = ['Fellini', 'Tarantino', 'Tarkovskiy']
1377 for i, director in enumerate(directors):
1378 store.append([i, director])
1380 treeview = Gtk.TreeView()
1381 treeview.set_model(store)
1383 column = Gtk.TreeViewColumn()
1384 treeview.append_column(column)
1386 cell = Gtk.CellRendererText()
1387 column.pack_start(cell, expand=True)
1388 column.set_attributes(cell, text=1)
1390 # might cause a Pango warning, do not break on this
1391 old_mask = GLib.log_set_always_fatal(
1392 GLib.LogLevelFlags.LEVEL_CRITICAL | GLib.LogLevelFlags.LEVEL_ERROR)
1394 # This will make cell.props.text receive a value, otherwise it
1396 treeview.get_preferred_size()
1398 GLib.log_set_always_fatal(old_mask)
1400 self.assertTrue(cell.props.text in directors)
1402 def test_tree_selection(self):
1403 store = Gtk.ListStore(int, str)
1405 store.append((i, "foo"))
1406 view = Gtk.TreeView()
1407 view.set_model(store)
1408 firstpath = store.get_path(store.get_iter_first())
1409 sel = view.get_selection()
1411 sel.select_path(firstpath)
1412 (m, s) = sel.get_selected()
1413 self.assertEqual(m, store)
1414 self.assertEqual(store.get_path(s), firstpath)
1417 (m, s) = sel.get_selected()
1418 self.assertEqual(m, store)
1419 self.assertEqual(store.get_path(s), firstpath)
1421 sel.select_path("0:0")
1422 (m, s) = sel.get_selected()
1423 self.assertEqual(m, store)
1424 self.assertEqual(store.get_path(s), firstpath)
1426 sel.select_path((0, 0))
1427 (m, s) = sel.get_selected()
1428 self.assertEqual(m, store)
1429 self.assertEqual(store.get_path(s), firstpath)
1432 @unittest.skipUnless(Gtk, 'Gtk not available')
1433 class TestTextBuffer(unittest.TestCase):
1434 def test_text_buffer(self):
1435 self.assertEqual(Gtk.TextBuffer, gi.overrides.Gtk.TextBuffer)
1436 buffer = Gtk.TextBuffer()
1437 tag = buffer.create_tag('title', font='Sans 18')
1439 self.assertEqual(tag.props.name, 'title')
1440 self.assertEqual(tag.props.font, 'Sans 18')
1442 (start, end) = buffer.get_bounds()
1444 mark = buffer.create_mark(None, start)
1445 self.assertFalse(mark.get_left_gravity())
1447 buffer.set_text('Hello Jane Hello Bob')
1448 (start, end) = buffer.get_bounds()
1449 text = buffer.get_text(start, end, False)
1450 self.assertEqual(text, 'Hello Jane Hello Bob')
1453 (start, end) = buffer.get_bounds()
1454 text = buffer.get_text(start, end, False)
1455 self.assertEqual(text, '')
1457 buffer.insert(end, 'HelloHello')
1458 buffer.insert(end, ' Bob')
1460 cursor_iter = end.copy()
1461 cursor_iter.backward_chars(9)
1462 buffer.place_cursor(cursor_iter)
1463 buffer.insert_at_cursor(' Jane ')
1465 (start, end) = buffer.get_bounds()
1466 text = buffer.get_text(start, end, False)
1467 self.assertEqual(text, 'Hello Jane Hello Bob')
1469 sel = buffer.get_selection_bounds()
1470 self.assertEqual(sel, ())
1471 buffer.select_range(start, end)
1472 sel = buffer.get_selection_bounds()
1473 self.assertTrue(sel[0].equal(start))
1474 self.assertTrue(sel[1].equal(end))
1477 buffer.insert_with_tags(buffer.get_start_iter(), 'HelloHello', tag)
1478 (start, end) = buffer.get_bounds()
1479 self.assertTrue(start.begins_tag(tag))
1480 self.assertTrue(start.has_tag(tag))
1483 buffer.insert_with_tags_by_name(buffer.get_start_iter(), 'HelloHello', 'title')
1484 (start, end) = buffer.get_bounds()
1485 self.assertTrue(start.begins_tag(tag))
1486 self.assertTrue(start.has_tag(tag))
1488 self.assertRaises(ValueError, buffer.insert_with_tags_by_name,
1489 buffer.get_start_iter(), 'HelloHello', 'unknowntag')
1491 def test_text_iter(self):
1492 self.assertEqual(Gtk.TextIter, gi.overrides.Gtk.TextIter)
1493 buffer = Gtk.TextBuffer()
1494 buffer.set_text('Hello Jane Hello Bob')
1495 tag = buffer.create_tag('title', font='Sans 18')
1496 (start, end) = buffer.get_bounds()
1497 start.forward_chars(10)
1498 buffer.apply_tag(tag, start, end)
1499 self.assertTrue(start.begins_tag())
1500 self.assertTrue(end.ends_tag())
1501 self.assertTrue(start.toggles_tag())
1502 self.assertTrue(end.toggles_tag())
1503 start.backward_chars(1)
1504 self.assertFalse(start.begins_tag())
1505 self.assertFalse(start.ends_tag())
1506 self.assertFalse(start.toggles_tag())
1508 def test_text_buffer_search(self):
1509 buffer = Gtk.TextBuffer()
1510 buffer.set_text('Hello World Hello GNOME')
1512 i = buffer.get_iter_at_offset(0)
1513 self.assertTrue(isinstance(i, Gtk.TextIter))
1515 self.assertEqual(i.forward_search('world', 0, None), None)
1517 (start, end) = i.forward_search('World', 0, None)
1518 self.assertEqual(start.get_offset(), 6)
1519 self.assertEqual(end.get_offset(), 11)
1521 (start, end) = i.forward_search('world',
1522 Gtk.TextSearchFlags.CASE_INSENSITIVE,
1524 self.assertEqual(start.get_offset(), 6)
1525 self.assertEqual(end.get_offset(), 11)