1 # -*- Mode: Python; py-indent-offset: 4 -*-
3 # vim: tabstop=4 shiftwidth=4 expandtab
10 from compathelper import _unicode, _bytes
14 from gi.repository import GLib, GObject
17 from gi.repository import GdkPixbuf, Gdk, Gtk
23 @contextlib.contextmanager
25 """Makes sure the widget is realized.
32 if isinstance(widget, Gtk.Window):
35 toplevel = widget.get_parent_window()
42 while Gtk.events_pending():
44 assert widget.get_realized()
51 while Gtk.events_pending():
55 @unittest.skipUnless(Gtk, 'Gtk not available')
56 class TestGtk(unittest.TestCase):
57 def test_container(self):
59 self.assertTrue(isinstance(box, Gtk.Box))
60 self.assertTrue(isinstance(box, Gtk.Container))
61 self.assertTrue(isinstance(box, Gtk.Widget))
67 self.assertTrue(label in box)
68 self.assertTrue(label2 in box)
69 self.assertEqual(len(box), 2)
72 self.assertEqual(l, [label, label2])
74 def test_actions(self):
75 self.assertEqual(Gtk.Action, gi.overrides.Gtk.Action)
76 self.assertRaises(TypeError, Gtk.Action)
77 action = Gtk.Action("test", "Test", "Test Action", Gtk.STOCK_COPY)
78 self.assertEqual(action.get_name(), "test")
79 self.assertEqual(action.get_label(), "Test")
80 self.assertEqual(action.get_tooltip(), "Test Action")
81 self.assertEqual(action.get_stock_id(), Gtk.STOCK_COPY)
83 self.assertEqual(Gtk.RadioAction, gi.overrides.Gtk.RadioAction)
84 self.assertRaises(TypeError, Gtk.RadioAction)
85 action = Gtk.RadioAction("test", "Test", "Test Action", Gtk.STOCK_COPY, 1)
86 self.assertEqual(action.get_name(), "test")
87 self.assertEqual(action.get_label(), "Test")
88 self.assertEqual(action.get_tooltip(), "Test Action")
89 self.assertEqual(action.get_stock_id(), Gtk.STOCK_COPY)
90 self.assertEqual(action.get_current_value(), 1)
92 def test_actiongroup(self):
93 self.assertEqual(Gtk.ActionGroup, gi.overrides.Gtk.ActionGroup)
94 self.assertRaises(TypeError, Gtk.ActionGroup)
96 action_group = Gtk.ActionGroup(name='TestActionGroup')
97 callback_data = "callback data"
99 def test_action_callback_data(action, user_data):
100 self.assertEqual(user_data, callback_data)
102 def test_radio_action_callback_data(action, current, user_data):
103 self.assertEqual(user_data, callback_data)
105 action_group.add_actions([
106 ('test-action1', None, 'Test Action 1',
107 None, None, test_action_callback_data),
108 ('test-action2', Gtk.STOCK_COPY, 'Test Action 2',
109 None, None, test_action_callback_data)], callback_data)
110 action_group.add_toggle_actions([
111 ('test-toggle-action1', None, 'Test Toggle Action 1',
112 None, None, test_action_callback_data, False),
113 ('test-toggle-action2', Gtk.STOCK_COPY, 'Test Toggle Action 2',
114 None, None, test_action_callback_data, True)], callback_data)
115 action_group.add_radio_actions([
116 ('test-radio-action1', None, 'Test Radio Action 1'),
117 ('test-radio-action2', Gtk.STOCK_COPY, 'Test Radio Action 2')], 1,
118 test_radio_action_callback_data,
121 expected_results = [('test-action1', Gtk.Action),
122 ('test-action2', Gtk.Action),
123 ('test-toggle-action1', Gtk.ToggleAction),
124 ('test-toggle-action2', Gtk.ToggleAction),
125 ('test-radio-action1', Gtk.RadioAction),
126 ('test-radio-action2', Gtk.RadioAction)]
128 for action in action_group.list_actions():
129 a = (action.get_name(), type(action))
130 self.assertTrue(a in expected_results)
131 expected_results.remove(a)
134 def test_uimanager(self):
135 self.assertEqual(Gtk.UIManager, gi.overrides.Gtk.UIManager)
137 ui.add_ui_from_string("""<ui>
138 <menubar name="menubar1"></menubar>
142 menubar = ui.get_widget("/menubar1")
143 self.assertEqual(type(menubar), Gtk.MenuBar)
145 ag = Gtk.ActionGroup(name="ag1")
146 ui.insert_action_group(ag)
147 ag2 = Gtk.ActionGroup(name="ag2")
148 ui.insert_action_group(ag2)
149 groups = ui.get_action_groups()
150 self.assertEqual(ag, groups[-2])
151 self.assertEqual(ag2, groups[-1])
153 def test_uimanager_nonascii(self):
155 ui.add_ui_from_string(b'<ui><menubar name="menub\xc3\xa6r1" /></ui>'.decode('UTF-8'))
156 mi = ui.get_widget("/menubær1")
157 self.assertEqual(type(mi), Gtk.MenuBar)
159 def test_window(self):
162 self.assertEqual(w.get_property('type'), Gtk.WindowType.TOPLEVEL)
164 # type works as keyword argument
165 w = Gtk.Window(type=Gtk.WindowType.POPUP)
166 self.assertEqual(w.get_property('type'), Gtk.WindowType.POPUP)
168 # pygtk compatible positional argument
169 w = Gtk.Window(Gtk.WindowType.POPUP)
170 self.assertEqual(w.get_property('type'), Gtk.WindowType.POPUP)
172 class TestWindow(Gtk.Window):
173 __gtype_name__ = "TestWindow"
176 builder = Gtk.Builder()
177 builder.add_from_string('''
179 <object class="GtkWindow" id="win">
180 <property name="type">popup</property>
182 <object class="TestWindow" id="testwin">
184 <object class="TestWindow" id="testpop">
185 <property name="type">popup</property>
188 self.assertEqual(builder.get_object('win').get_property('type'),
189 Gtk.WindowType.POPUP)
190 self.assertEqual(builder.get_object('testwin').get_property('type'),
191 Gtk.WindowType.TOPLEVEL)
192 self.assertEqual(builder.get_object('testpop').get_property('type'),
193 Gtk.WindowType.POPUP)
195 def test_dialogs(self):
196 self.assertEqual(Gtk.Dialog, gi.overrides.Gtk.Dialog)
197 self.assertEqual(Gtk.AboutDialog, gi.overrides.Gtk.AboutDialog)
198 self.assertEqual(Gtk.MessageDialog, gi.overrides.Gtk.MessageDialog)
199 self.assertEqual(Gtk.ColorSelectionDialog, gi.overrides.Gtk.ColorSelectionDialog)
200 self.assertEqual(Gtk.FileChooserDialog, gi.overrides.Gtk.FileChooserDialog)
201 self.assertEqual(Gtk.FontSelectionDialog, gi.overrides.Gtk.FontSelectionDialog)
202 self.assertEqual(Gtk.RecentChooserDialog, gi.overrides.Gtk.RecentChooserDialog)
205 dialog = Gtk.Dialog(title='Foo',
206 flags=Gtk.DialogFlags.MODAL,
207 buttons=('test-button1', 1))
208 self.assertTrue(isinstance(dialog, Gtk.Dialog))
209 self.assertTrue(isinstance(dialog, Gtk.Window))
211 dialog.add_buttons('test-button2', 2, Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE)
213 self.assertEqual('Foo', dialog.get_title())
214 self.assertTrue(dialog.get_modal())
215 button = dialog.get_widget_for_response(1)
216 self.assertEqual('test-button1', button.get_label())
217 button = dialog.get_widget_for_response(2)
218 self.assertEqual('test-button2', button.get_label())
219 button = dialog.get_widget_for_response(Gtk.ResponseType.CLOSE)
220 self.assertEqual(Gtk.STOCK_CLOSE, button.get_label())
223 dialog = Gtk.AboutDialog()
224 self.assertTrue(isinstance(dialog, Gtk.Dialog))
225 self.assertTrue(isinstance(dialog, Gtk.Window))
228 dialog = Gtk.MessageDialog(title='message dialog test',
229 flags=Gtk.DialogFlags.MODAL,
230 buttons=Gtk.ButtonsType.OK,
231 message_format='dude!')
232 self.assertTrue(isinstance(dialog, Gtk.Dialog))
233 self.assertTrue(isinstance(dialog, Gtk.Window))
235 self.assertEqual('message dialog test', dialog.get_title())
236 self.assertTrue(dialog.get_modal())
237 text = dialog.get_property('text')
238 self.assertEqual('dude!', text)
240 dialog.format_secondary_text('2nd text')
241 self.assertEqual(dialog.get_property('secondary-text'), '2nd text')
242 self.assertFalse(dialog.get_property('secondary-use-markup'))
244 dialog.format_secondary_markup('2nd markup')
245 self.assertEqual(dialog.get_property('secondary-text'), '2nd markup')
246 self.assertTrue(dialog.get_property('secondary-use-markup'))
248 # Gtk.ColorSelectionDialog
249 dialog = Gtk.ColorSelectionDialog("color selection dialog test")
250 self.assertTrue(isinstance(dialog, Gtk.Dialog))
251 self.assertTrue(isinstance(dialog, Gtk.Window))
252 self.assertEqual('color selection dialog test', dialog.get_title())
254 # Gtk.FileChooserDialog
255 # might cause a GVFS warning, do not break on this
256 old_mask = GLib.log_set_always_fatal(
257 GLib.LogLevelFlags.LEVEL_CRITICAL | GLib.LogLevelFlags.LEVEL_ERROR)
259 dialog = Gtk.FileChooserDialog(title='file chooser dialog test',
260 buttons=('test-button1', 1),
261 action=Gtk.FileChooserAction.SAVE)
263 GLib.log_set_always_fatal(old_mask)
264 self.assertTrue(isinstance(dialog, Gtk.Dialog))
265 self.assertTrue(isinstance(dialog, Gtk.Window))
267 dialog.add_buttons('test-button2', 2, Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE)
268 self.assertEqual('file chooser dialog test', dialog.get_title())
269 button = dialog.get_widget_for_response(1)
270 self.assertEqual('test-button1', button.get_label())
271 button = dialog.get_widget_for_response(2)
272 self.assertEqual('test-button2', button.get_label())
273 button = dialog.get_widget_for_response(Gtk.ResponseType.CLOSE)
274 self.assertEqual(Gtk.STOCK_CLOSE, button.get_label())
275 action = dialog.get_property('action')
276 self.assertEqual(Gtk.FileChooserAction.SAVE, action)
278 # Gtk.FontSelectionDialog
279 dialog = Gtk.ColorSelectionDialog("font selection dialog test")
280 self.assertTrue(isinstance(dialog, Gtk.Dialog))
281 self.assertTrue(isinstance(dialog, Gtk.Window))
282 self.assertEqual('font selection dialog test', dialog.get_title())
284 # Gtk.RecentChooserDialog
285 test_manager = Gtk.RecentManager()
286 dialog = Gtk.RecentChooserDialog(title='recent chooser dialog test',
287 buttons=('test-button1', 1),
288 manager=test_manager)
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('recent 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())
301 class TestClass(GObject.GObject):
302 __gtype_name__ = "GIOverrideTreeAPITest"
304 def __init__(self, tester, int_value, string_value):
305 super(TestGtk.TestClass, self).__init__()
307 self.int_value = int_value
308 self.string_value = string_value
310 def check(self, int_value, string_value):
311 self.tester.assertEqual(int_value, self.int_value)
312 self.tester.assertEqual(string_value, self.string_value)
314 def test_buttons(self):
315 self.assertEqual(Gtk.Button, gi.overrides.Gtk.Button)
318 button = Gtk.Button()
319 self.assertTrue(isinstance(button, Gtk.Button))
320 self.assertTrue(isinstance(button, Gtk.Container))
321 self.assertTrue(isinstance(button, Gtk.Widget))
322 button = Gtk.Button(stock=Gtk.STOCK_CLOSE)
323 self.assertEqual(Gtk.STOCK_CLOSE, button.get_label())
324 self.assertTrue(button.get_use_stock())
325 self.assertTrue(button.get_use_underline())
327 # test Gtk.Button use_stock
328 button = Gtk.Button(label=Gtk.STOCK_CLOSE, use_stock=True, use_underline=True)
329 self.assertEqual(Gtk.STOCK_CLOSE, button.get_label())
330 self.assertTrue(button.get_use_stock())
331 self.assertTrue(button.get_use_underline())
333 # test Gtk.LinkButton
334 self.assertRaises(TypeError, Gtk.LinkButton)
335 button = Gtk.LinkButton('http://www.Gtk.org', 'Gtk')
336 self.assertTrue(isinstance(button, Gtk.Button))
337 self.assertTrue(isinstance(button, Gtk.Container))
338 self.assertTrue(isinstance(button, Gtk.Widget))
339 self.assertEqual('http://www.Gtk.org', button.get_uri())
340 self.assertEqual('Gtk', button.get_label())
342 def test_inheritance(self):
343 for name in gi.overrides.Gtk.__all__:
344 over = getattr(gi.overrides.Gtk, name)
345 for element in dir(Gtk):
347 klass = getattr(Gtk, element)
348 info = klass.__info__
349 except (NotImplementedError, AttributeError):
352 # Get all parent classes and interfaces klass inherits from
353 if isinstance(info, gi.types.ObjectInfo):
354 classes = list(info.get_interfaces())
355 parent = info.get_parent()
356 while parent.get_name() != "Object":
357 classes.append(parent)
358 parent = parent.get_parent()
359 classes = [kl for kl in classes if kl.get_namespace() == "Gtk"]
364 if kl.get_name() == name:
365 self.assertTrue(issubclass(klass, over,),
366 "%r does not inherit from override %r" % (klass, over,))
368 def test_editable(self):
369 self.assertEqual(Gtk.Editable, gi.overrides.Gtk.Editable)
371 # need to use Gtk.Entry because Editable is an interface
373 pos = entry.insert_text('HeWorld', 0)
374 self.assertEqual(pos, 7)
375 pos = entry.insert_text('llo ', 2)
376 self.assertEqual(pos, 6)
377 text = entry.get_chars(0, 11)
378 self.assertEqual('Hello World', text)
380 def test_label(self):
381 label = Gtk.Label(label='Hello')
382 self.assertTrue(isinstance(label, Gtk.Widget))
383 self.assertEqual(label.get_text(), 'Hello')
385 def adjustment_check(self, adjustment, value=0.0, lower=0.0, upper=0.0,
386 step_increment=0.0, page_increment=0.0, page_size=0.0):
387 self.assertEqual(adjustment.get_value(), value)
388 self.assertEqual(adjustment.get_lower(), lower)
389 self.assertEqual(adjustment.get_upper(), upper)
390 self.assertEqual(adjustment.get_step_increment(), step_increment)
391 self.assertEqual(adjustment.get_page_increment(), page_increment)
392 self.assertEqual(adjustment.get_page_size(), page_size)
394 def test_adjustment(self):
395 adjustment = Gtk.Adjustment(1, 0, 6, 4, 5, 3)
396 self.adjustment_check(adjustment, 1, 0, 6, 4, 5, 3)
398 adjustment = Gtk.Adjustment(1, 0, 6, 4, 5)
399 self.adjustment_check(adjustment, 1, 0, 6, 4, 5)
401 adjustment = Gtk.Adjustment(1, 0, 6, 4)
402 self.adjustment_check(adjustment, 1, 0, 6, 4)
404 adjustment = Gtk.Adjustment(1, 0, 6)
405 self.adjustment_check(adjustment, 1, 0, 6)
407 adjustment = Gtk.Adjustment()
408 self.adjustment_check(adjustment)
410 adjustment = Gtk.Adjustment(value=1, lower=0, upper=6,
411 step_increment=4, page_increment=5, page_size=3)
412 self.adjustment_check(adjustment, 1, 0, 6, 4, 5, 3)
414 def test_table(self):
416 self.assertTrue(isinstance(table, Gtk.Table))
417 self.assertTrue(isinstance(table, Gtk.Container))
418 self.assertTrue(isinstance(table, Gtk.Widget))
419 self.assertEqual(table.get_size(), (1, 1))
420 self.assertEqual(table.get_homogeneous(), False)
421 table = Gtk.Table(2, 3)
422 self.assertEqual(table.get_size(), (2, 3))
423 self.assertEqual(table.get_homogeneous(), False)
424 table = Gtk.Table(2, 3, True)
425 self.assertEqual(table.get_size(), (2, 3))
426 self.assertEqual(table.get_homogeneous(), True)
428 # Test PyGTK interface
429 table = Gtk.Table(rows=3, columns=2)
430 self.assertEqual(table.get_size(), (3, 2))
431 # Test using the actual property names
432 table = Gtk.Table(n_rows=2, n_columns=3, homogeneous=True)
433 self.assertEqual(table.get_size(), (2, 3))
434 self.assertEqual(table.get_homogeneous(), True)
436 label = Gtk.Label(label='Hello')
437 self.assertTrue(isinstance(label, Gtk.Widget))
438 table.attach(label, 0, 1, 0, 1)
439 self.assertEqual(label, table.get_children()[0])
441 def test_scrolledwindow(self):
442 sw = Gtk.ScrolledWindow()
443 self.assertTrue(isinstance(sw, Gtk.ScrolledWindow))
444 self.assertTrue(isinstance(sw, Gtk.Container))
445 self.assertTrue(isinstance(sw, Gtk.Widget))
446 sb = sw.get_hscrollbar()
447 self.assertEqual(sw.get_hadjustment(), sb.get_adjustment())
448 sb = sw.get_vscrollbar()
449 self.assertEqual(sw.get_vadjustment(), sb.get_adjustment())
451 def test_widget_drag_methods(self):
452 widget = Gtk.Button()
454 # here we are not checking functionality, only that the methods exist
455 # and except the right number of arguments
457 widget.drag_check_threshold(0, 0, 0, 0)
460 widget.drag_dest_set(Gtk.DestDefaults.DROP, None, Gdk.DragAction.COPY)
461 widget.drag_dest_add_image_targets()
462 widget.drag_dest_add_text_targets()
463 widget.drag_dest_add_uri_targets()
464 widget.drag_dest_get_track_motion()
465 widget.drag_dest_set_track_motion(True)
466 widget.drag_dest_get_target_list()
467 widget.drag_dest_set_target_list(Gtk.TargetList.new([Gtk.TargetEntry.new('test', 0, 0)]))
468 widget.drag_dest_unset()
470 widget.drag_highlight()
471 widget.drag_unhighlight()
473 # drag_source_ methods
474 widget.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, None, Gdk.DragAction.MOVE)
475 widget.drag_source_add_image_targets()
476 widget.drag_source_add_text_targets()
477 widget.drag_source_add_uri_targets()
478 widget.drag_source_set_icon_name("")
479 widget.drag_source_set_icon_pixbuf(GdkPixbuf.Pixbuf())
480 widget.drag_source_set_icon_stock("")
481 widget.drag_source_get_target_list()
482 widget.drag_source_set_target_list(Gtk.TargetList.new([Gtk.TargetEntry.new('test', 0, 0)]))
483 widget.drag_source_unset()
485 # these methods cannot be called because they require a valid drag on
486 # a real GdkWindow. So we only check that they exist and are callable.
487 self.assertTrue(hasattr(widget, 'drag_dest_set_proxy'))
488 self.assertTrue(hasattr(widget, 'drag_get_data'))
490 def test_drag_target_list(self):
491 mixed_target_list = [Gtk.TargetEntry.new('test0', 0, 0),
493 Gtk.TargetEntry.new('test2', 2, 2),
496 def _test_target_list(targets):
497 for i, target in enumerate(targets):
498 self.assertTrue(isinstance(target, Gtk.TargetEntry))
499 self.assertEqual(target.target, 'test' + str(i))
500 self.assertEqual(target.flags, i)
501 self.assertEqual(target.info, i)
503 _test_target_list(Gtk._construct_target_list(mixed_target_list))
505 widget = Gtk.Button()
506 widget.drag_dest_set(Gtk.DestDefaults.DROP, None, Gdk.DragAction.COPY)
507 widget.drag_dest_set_target_list(mixed_target_list)
508 widget.drag_dest_get_target_list()
510 widget.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, None, Gdk.DragAction.MOVE)
511 widget.drag_source_set_target_list(mixed_target_list)
512 widget.drag_source_get_target_list()
514 treeview = Gtk.TreeView()
515 treeview.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK,
517 Gdk.DragAction.DEFAULT | Gdk.DragAction.MOVE)
519 treeview.enable_model_drag_dest(mixed_target_list,
520 Gdk.DragAction.DEFAULT | Gdk.DragAction.MOVE)
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)
576 def test_stock_lookup(self):
577 l = Gtk.stock_lookup('gtk-ok')
578 self.assertEqual(type(l), Gtk.StockItem)
579 self.assertEqual(l.stock_id, 'gtk-ok')
580 self.assertEqual(Gtk.stock_lookup('nosuchthing'), None)
582 def test_gtk_main(self):
584 GLib.timeout_add(100, Gtk.main_quit)
587 # overridden function ignores its arguments
588 GLib.timeout_add(100, Gtk.main_quit, 'hello')
592 @unittest.skipUnless(Gtk, 'Gtk not available')
593 class TestBuilder(unittest.TestCase):
594 class SignalTest(GObject.GObject):
595 __gtype_name__ = "GIOverrideSignalTest"
597 "test-signal": (GObject.SignalFlags.RUN_FIRST,
602 def test_extract_handler_and_args_object(self):
607 obj.foo = lambda: None
609 handler, args = Gtk.Builder._extract_handler_and_args(obj, 'foo')
610 self.assertEqual(handler, obj.foo)
611 self.assertEqual(len(args), 0)
613 def test_extract_handler_and_args_dict(self):
614 obj = {'foo': lambda: None}
616 handler, args = Gtk.Builder._extract_handler_and_args(obj, 'foo')
617 self.assertEqual(handler, obj['foo'])
618 self.assertEqual(len(args), 0)
620 def test_extract_handler_and_args_with_seq(self):
621 obj = {'foo': (lambda: None, 1, 2)}
623 handler, args = Gtk.Builder._extract_handler_and_args(obj, 'foo')
624 self.assertEqual(handler, obj['foo'][0])
625 self.assertSequenceEqual(args, [1, 2])
627 def test_extract_handler_and_args_no_handler_error(self):
628 obj = dict(foo=lambda: None)
629 self.assertRaises(AttributeError,
630 Gtk.Builder._extract_handler_and_args,
631 obj, 'not_a_handler')
633 def test_builder_with_handler_and_args(self):
634 builder = Gtk.Builder()
635 builder.add_from_string("""
637 <object class="GIOverrideSignalTest" id="object_sig_test">
638 <signal name="test-signal" handler="on_signal1" />
639 <signal name="test-signal" handler="on_signal2" after="yes" />
646 def on_signal(*args):
647 args_collector.append(args)
649 builder.connect_signals({'on_signal1': (on_signal, 1, 2),
650 'on_signal2': on_signal})
652 objects = builder.get_objects()
653 self.assertEqual(len(objects), 1)
655 obj.emit('test-signal')
657 self.assertEqual(len(args_collector), 2)
658 self.assertSequenceEqual(args_collector[0], (obj, 1, 2))
659 self.assertSequenceEqual(args_collector[1], (obj, ))
661 def test_builder(self):
662 self.assertEqual(Gtk.Builder, gi.overrides.Gtk.Builder)
667 self.after_sentinel = 0
669 def on_signal_1(self, *args):
671 self.after_sentinel += 1
673 def on_signal_3(self, *args):
676 def on_signal_after(self, *args):
677 if self.after_sentinel == 1:
678 self.after_sentinel += 1
680 signal_checker = SignalCheck()
681 builder = Gtk.Builder()
683 # add object1 to the builder
684 builder.add_from_string("""
686 <object class="GIOverrideSignalTest" id="object1">
687 <signal name="test-signal" after="yes" handler="on_signal_after" />
688 <signal name="test-signal" handler="on_signal_1" />
693 # only add object3 to the builder
694 builder.add_objects_from_string("""
696 <object class="GIOverrideSignalTest" id="object2">
697 <signal name="test-signal" handler="on_signal_2" />
699 <object class="GIOverrideSignalTest" id="object3">
700 <signal name="test-signal" handler="on_signal_3" />
702 <object class="GIOverrideSignalTest" id="object4">
703 <signal name="test-signal" handler="on_signal_4" />
709 builder.connect_signals(signal_checker)
711 # call their notify signals and check sentinel
712 objects = builder.get_objects()
713 self.assertEqual(len(objects), 2)
715 obj.emit('test-signal')
717 self.assertEqual(signal_checker.sentinel, 4)
718 self.assertEqual(signal_checker.after_sentinel, 2)
721 @unittest.skipUnless(Gtk, 'Gtk not available')
722 class TestTreeModel(unittest.TestCase):
723 def test_tree_model_sort(self):
724 self.assertEqual(Gtk.TreeModelSort, gi.overrides.Gtk.TreeModelSort)
725 self.assertRaises(TypeError, Gtk.TreeModelSort)
726 model = Gtk.TreeStore(int, bool)
727 model_sort = Gtk.TreeModelSort(model)
728 self.assertEqual(model_sort.get_model(), model)
730 def test_tree_store(self):
731 self.assertEqual(Gtk.TreeStore, gi.overrides.Gtk.TreeStore)
732 self.assertEqual(Gtk.ListStore, gi.overrides.Gtk.ListStore)
733 self.assertEqual(Gtk.TreeModel, gi.overrides.Gtk.TreeModel)
734 self.assertEqual(Gtk.TreeViewColumn, gi.overrides.Gtk.TreeViewColumn)
736 class TestPyObject(object):
739 test_pyobj = TestPyObject()
740 test_pydict = {1: 1, "2": 2, "3": "3"}
741 test_pylist = [1, "2", "3"]
742 tree_store = Gtk.TreeStore(int,
745 GObject.TYPE_PYOBJECT,
760 label = 'this is child #%d' % i
761 testobj = TestGtk.TestClass(self, i, label)
762 parent = tree_store.append(parent, (i,
779 parent = tree_store.append(parent)
781 label = 'this is child #%d' % i
782 testobj = TestGtk.TestClass(self, i, label)
783 tree_store.set(parent,
794 10, GObject.G_MAXULONG,
795 11, GObject.G_MININT64,
796 12, 0xffffffffffffffff,
800 parent = tree_store.append(parent)
802 label = 'this is child #%d' % i
803 testobj = TestGtk.TestClass(self, i, label)
804 tree_store.set(parent, {0: i,
814 10: GObject.G_MAXULONG,
815 11: GObject.G_MININT64,
816 12: 0xffffffffffffffff,
820 parent = tree_store.append(parent)
822 label = 'this is child #%d' % i
823 testobj = TestGtk.TestClass(self, i, label)
824 tree_store.set(parent, (0, 2, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14),
841 # len gets the number of children in the root node
842 # since we kept appending to the previous node
843 # there should only be one child of the root
844 self.assertEqual(len(tree_store), 1)
846 # walk the tree to see if the values were stored correctly
850 treeiter = tree_store.iter_children(parent)
852 i = tree_store.get_value(treeiter, 0)
853 s = tree_store.get_value(treeiter, 1)
854 obj = tree_store.get_value(treeiter, 2)
856 obj2 = tree_store.get_value(treeiter, 3)
857 self.assertEqual(obj, obj2)
859 pyobj = tree_store.get_value(treeiter, 4)
860 self.assertEqual(pyobj, test_pyobj)
861 pydict = tree_store.get_value(treeiter, 5)
862 self.assertEqual(pydict, test_pydict)
863 pylist = tree_store.get_value(treeiter, 6)
864 self.assertEqual(pylist, test_pylist)
866 bool_1 = tree_store.get_value(treeiter, 7)
867 bool_2 = tree_store.get_value(treeiter, 8)
868 self.assertEqual(bool_1, bool_2)
869 self.assertTrue(isinstance(bool_1, bool))
870 self.assertTrue(isinstance(bool_2, bool))
872 uint_ = tree_store.get_value(treeiter, 9)
873 self.assertEqual(uint_, i)
874 ulong_ = tree_store.get_value(treeiter, 10)
875 self.assertEqual(ulong_, GObject.G_MAXULONG)
876 int64_ = tree_store.get_value(treeiter, 11)
877 self.assertEqual(int64_, GObject.G_MININT64)
878 uint64_ = tree_store.get_value(treeiter, 12)
879 self.assertEqual(uint64_, 0xffffffffffffffff)
880 uchar_ = tree_store.get_value(treeiter, 13)
881 self.assertEqual(ord(uchar_), 254)
882 char_ = tree_store.get_value(treeiter, 14)
883 self.assertEqual(char_, 'a')
886 treeiter = tree_store.iter_children(parent)
888 self.assertEqual(i, 99)
890 def test_tree_store_signals(self):
891 tree_store = Gtk.TreeStore(int, bool)
893 def on_row_inserted(tree_store, tree_path, tree_iter, signal_list):
894 signal_list.append('row-inserted')
896 def on_row_changed(tree_store, tree_path, tree_iter, signal_list):
897 signal_list.append('row-changed')
900 tree_store.connect('row-inserted', on_row_inserted, signals)
901 tree_store.connect('row-changed', on_row_changed, signals)
903 # adding rows with and without data should only call one signal
904 tree_store.append(None, (0, False))
905 self.assertEqual(signals, ['row-inserted'])
908 tree_store.append(None)
909 self.assertEqual(signals, ['row-inserted'])
912 tree_store.prepend(None, (0, False))
913 self.assertEqual(signals, ['row-inserted'])
916 tree_store.prepend(None)
917 self.assertEqual(signals, ['row-inserted'])
920 tree_store.insert(None, 1, (0, False))
921 self.assertEqual(signals, ['row-inserted'])
924 tree_store.insert(None, 1)
925 self.assertEqual(signals, ['row-inserted'])
927 def test_list_store(self):
928 class TestPyObject(object):
931 test_pyobj = TestPyObject()
932 test_pydict = {1: 1, "2": 2, "3": "3"}
933 test_pylist = [1, "2", "3"]
935 list_store = Gtk.ListStore(int, str, 'GIOverrideTreeAPITest', object, object, object, bool, bool)
936 for i in range(1, 93):
937 label = 'this is row #%d' % i
938 testobj = TestGtk.TestClass(self, i, label)
939 list_store.append((i,
949 label = _unicode('this is row #93')
950 treeiter = list_store.append()
951 list_store.set_value(treeiter, 0, i)
952 list_store.set_value(treeiter, 1, label)
953 list_store.set_value(treeiter, 2, TestGtk.TestClass(self, i, label))
954 list_store.set_value(treeiter, 3, test_pyobj)
955 list_store.set_value(treeiter, 4, test_pydict)
956 list_store.set_value(treeiter, 5, test_pylist)
957 list_store.set_value(treeiter, 6, 1)
958 list_store.set_value(treeiter, 7, True)
961 label = 'this is row #0'
962 list_store.prepend((0,
964 TestGtk.TestClass(self, 0, label),
971 # test automatic unicode->str conversion
973 label = _unicode('this is row #94')
974 treeiter = list_store.append((i,
976 TestGtk.TestClass(self, i, label),
983 # add sorted items out of order to test insert* apis
984 # also test sending in None to not set a column
986 label = 'this is row #97'
987 treeiter = list_store.append((None,
996 list_store.set_value(treeiter, 0, i)
997 list_store.set_value(treeiter, 1, label)
998 list_store.set_value(treeiter, 2, TestGtk.TestClass(self, i, label))
999 list_store.set_value(treeiter, 4, test_pydict)
1000 list_store.set_value(treeiter, 7, True)
1002 # this should append
1004 label = 'this is row #99'
1005 list_store.insert(9999, (i,
1007 TestGtk.TestClass(self, i, label),
1015 label = 'this is row #96'
1016 list_store.insert_before(treeiter, (i,
1018 TestGtk.TestClass(self, i, label),
1026 label = 'this is row #98'
1027 list_store.insert_after(treeiter, (i,
1029 TestGtk.TestClass(self, i, label),
1037 label = 'this is row #95'
1038 list_store.insert(95, (i,
1040 TestGtk.TestClass(self, i, label),
1048 label = 'this is row #100'
1049 treeiter = list_store.append()
1050 list_store.set(treeiter,
1053 2, TestGtk.TestClass(self, i, label),
1060 label = 'this is row #101'
1061 treeiter = list_store.append()
1062 list_store.set(treeiter, {1: label,
1064 2: TestGtk.TestClass(self, i, label),
1071 label = 'this is row #102'
1072 treeiter = list_store.append()
1073 list_store.set(treeiter, (1, 0, 2, 3, 4, 5, 6, 7),
1076 TestGtk.TestClass(self, i, label),
1083 self.assertEqual(len(list_store), 103)
1085 # walk the list to see if the values were stored correctly
1087 treeiter = list_store.get_iter_first()
1091 i = list_store.get_value(treeiter, 0)
1092 self.assertEqual(i, counter)
1093 s = list_store.get_value(treeiter, 1)
1094 obj = list_store.get_value(treeiter, 2)
1097 pyobj = list_store.get_value(treeiter, 3)
1098 self.assertEqual(pyobj, test_pyobj)
1099 pydict = list_store.get_value(treeiter, 4)
1100 self.assertEqual(pydict, test_pydict)
1101 pylist = list_store.get_value(treeiter, 5)
1102 self.assertEqual(pylist, test_pylist)
1104 bool_1 = list_store.get_value(treeiter, 6)
1105 bool_2 = list_store.get_value(treeiter, 7)
1106 self.assertEqual(bool_1, bool_2)
1107 self.assertTrue(isinstance(bool_1, bool))
1108 self.assertTrue(isinstance(bool_2, bool))
1110 treeiter = list_store.iter_next(treeiter)
1114 self.assertEqual(i, 102)
1116 def test_list_store_sort(self):
1117 def comp1(model, row1, row2, user_data):
1121 # make "m" smaller than anything else
1122 if v1.startswith('m') and not v2.startswith('m'):
1124 if v2.startswith('m') and not v1.startswith('m'):
1126 return (v1 > v2) - (v1 < v2)
1128 list_store = Gtk.ListStore(int, str)
1129 list_store.set_sort_func(2, comp1, None)
1130 list_store.append((1, 'apples'))
1131 list_store.append((3, 'oranges'))
1132 list_store.append((2, 'mango'))
1134 # not sorted yet, should be original order
1135 self.assertEqual([list(i) for i in list_store],
1136 [[1, 'apples'], [3, 'oranges'], [2, 'mango']])
1138 # sort with our custom function
1139 list_store.set_sort_column_id(2, Gtk.SortType.ASCENDING)
1140 self.assertEqual([list(i) for i in list_store],
1141 [[2, 'mango'], [1, 'apples'], [3, 'oranges']])
1143 list_store.set_sort_column_id(2, Gtk.SortType.DESCENDING)
1144 self.assertEqual([list(i) for i in list_store],
1145 [[3, 'oranges'], [1, 'apples'], [2, 'mango']])
1147 def test_list_store_signals(self):
1148 list_store = Gtk.ListStore(int, bool)
1150 def on_row_inserted(list_store, tree_path, tree_iter, signal_list):
1151 signal_list.append('row-inserted')
1153 def on_row_changed(list_store, tree_path, tree_iter, signal_list):
1154 signal_list.append('row-changed')
1157 list_store.connect('row-inserted', on_row_inserted, signals)
1158 list_store.connect('row-changed', on_row_changed, signals)
1160 # adding rows with and without data should only call one signal
1161 list_store.append((0, False))
1162 self.assertEqual(signals, ['row-inserted'])
1166 self.assertEqual(signals, ['row-inserted'])
1169 list_store.prepend((0, False))
1170 self.assertEqual(signals, ['row-inserted'])
1173 list_store.prepend()
1174 self.assertEqual(signals, ['row-inserted'])
1177 list_store.insert(1, (0, False))
1178 self.assertEqual(signals, ['row-inserted'])
1181 list_store.insert(1)
1182 self.assertEqual(signals, ['row-inserted'])
1184 def test_tree_path(self):
1186 p2 = Gtk.TreePath.new_first()
1187 self.assertEqual(p1, p2)
1188 self.assertEqual(str(p1), '0')
1189 self.assertEqual(len(p1), 1)
1190 p1 = Gtk.TreePath(2)
1191 p2 = Gtk.TreePath.new_from_string('2')
1192 self.assertEqual(p1, p2)
1193 self.assertEqual(str(p1), '2')
1194 self.assertEqual(len(p1), 1)
1195 p1 = Gtk.TreePath('1:2:3')
1196 p2 = Gtk.TreePath.new_from_string('1:2:3')
1197 self.assertEqual(p1, p2)
1198 self.assertEqual(str(p1), '1:2:3')
1199 self.assertEqual(len(p1), 3)
1200 p1 = Gtk.TreePath((1, 2, 3))
1201 p2 = Gtk.TreePath.new_from_string('1:2:3')
1202 self.assertEqual(p1, p2)
1203 self.assertEqual(str(p1), '1:2:3')
1204 self.assertEqual(len(p1), 3)
1205 self.assertNotEqual(p1, None)
1206 self.assertTrue(p1 > None)
1207 self.assertTrue(p1 >= None)
1208 self.assertFalse(p1 < None)
1209 self.assertFalse(p1 <= None)
1211 self.assertEqual(tuple(p1), (1, 2, 3))
1212 self.assertEqual(p1[0], 1)
1213 self.assertEqual(p1[1], 2)
1214 self.assertEqual(p1[2], 3)
1215 self.assertRaises(IndexError, p1.__getitem__, 3)
1217 def test_tree_model(self):
1218 tree_store = Gtk.TreeStore(int, str)
1220 self.assertTrue(tree_store)
1221 self.assertEqual(len(tree_store), 0)
1222 self.assertEqual(tree_store.get_iter_first(), None)
1224 def get_by_index(row, col=None):
1226 return tree_store[row][col]
1228 return tree_store[row]
1230 self.assertRaises(TypeError, get_by_index, None)
1231 self.assertRaises(TypeError, get_by_index, "")
1232 self.assertRaises(TypeError, get_by_index, ())
1234 self.assertRaises(IndexError, get_by_index, "0")
1235 self.assertRaises(IndexError, get_by_index, 0)
1236 self.assertRaises(IndexError, get_by_index, (0,))
1238 self.assertRaises(ValueError, tree_store.get_iter, "0")
1239 self.assertRaises(ValueError, tree_store.get_iter, 0)
1240 self.assertRaises(ValueError, tree_store.get_iter, (0,))
1242 self.assertRaises(ValueError, tree_store.get_iter_from_string, "0")
1244 for row in tree_store:
1245 self.fail("Should not be reached")
1247 class DerivedIntType(int):
1250 class DerivedStrType(str):
1253 for i in range(100):
1254 label = 'this is row #%d' % i
1255 parent = tree_store.append(None, (DerivedIntType(i), DerivedStrType(label),))
1256 self.assertNotEqual(parent, None)
1258 label = 'this is child #%d of node #%d' % (j, i)
1259 child = tree_store.append(parent, (j, label,))
1260 self.assertNotEqual(child, None)
1262 self.assertTrue(tree_store)
1263 self.assertEqual(len(tree_store), 100)
1265 self.assertEqual(tree_store.iter_previous(tree_store.get_iter(0)), None)
1267 for i, row in enumerate(tree_store):
1268 self.assertEqual(row.model, tree_store)
1269 self.assertEqual(row.parent, None)
1271 self.assertEqual(tree_store[i].path, row.path)
1272 self.assertEqual(tree_store[str(i)].path, row.path)
1273 self.assertEqual(tree_store[(i,)].path, row.path)
1275 self.assertEqual(tree_store[i][0], i)
1276 self.assertEqual(tree_store[i][1], "this is row #%d" % i)
1278 aiter = tree_store.get_iter(i)
1279 self.assertEqual(tree_store.get_path(aiter), row.path)
1281 aiter = tree_store.get_iter(str(i))
1282 self.assertEqual(tree_store.get_path(aiter), row.path)
1284 aiter = tree_store.get_iter((i,))
1285 self.assertEqual(tree_store.get_path(aiter), row.path)
1287 self.assertEqual(tree_store.iter_parent(aiter), row.parent)
1289 next = tree_store.iter_next(aiter)
1290 if i < len(tree_store) - 1:
1291 self.assertEqual(tree_store.get_path(next), row.next.path)
1292 self.assertEqual(tree_store.get_path(tree_store.iter_previous(next)),
1293 tree_store.get_path(aiter))
1295 self.assertEqual(next, None)
1297 self.assertEqual(tree_store.iter_n_children(row.iter), 20)
1299 child = tree_store.iter_children(row.iter)
1300 for j, childrow in enumerate(row.iterchildren()):
1301 child_path = tree_store.get_path(child)
1302 self.assertEqual(childrow.path, child_path)
1303 self.assertEqual(childrow.parent.path, row.path)
1304 self.assertEqual(childrow.path, tree_store[child].path)
1305 self.assertEqual(childrow.path, tree_store[child_path].path)
1307 self.assertEqual(childrow[0], tree_store[child][0])
1308 self.assertEqual(childrow[0], j)
1309 self.assertEqual(childrow[1], tree_store[child][1])
1310 self.assertEqual(childrow[1], 'this is child #%d of node #%d' % (j, i))
1312 self.assertRaises(IndexError, get_by_index, child, 2)
1314 tree_store[child][1] = 'this was child #%d of node #%d' % (j, i)
1315 self.assertEqual(childrow[1], 'this was child #%d of node #%d' % (j, i))
1317 nth_child = tree_store.iter_nth_child(row.iter, j)
1318 self.assertEqual(childrow.path, tree_store.get_path(nth_child))
1320 childrow2 = tree_store["%d:%d" % (i, j)]
1321 self.assertEqual(childrow.path, childrow2.path)
1323 childrow2 = tree_store[(i, j,)]
1324 self.assertEqual(childrow.path, childrow2.path)
1326 child = tree_store.iter_next(child)
1328 self.assertEqual(childrow.next.path, tree_store.get_path(child))
1330 self.assertEqual(child, childrow.next)
1331 self.assertEqual(child, None)
1333 self.assertEqual(j, 19)
1335 self.assertEqual(i, 99)
1338 for i in range(-1, -100, -1):
1340 self.assertEqual(tree_store[i][0], i_real)
1343 for j in range(-1, -20, -1):
1345 path = (i_real, j_real,)
1347 self.assertEqual(tree_store[path][-2], j_real)
1349 label = 'this was child #%d of node #%d' % (j_real, i_real)
1350 self.assertEqual(tree_store[path][-1], label)
1352 new_label = 'this still is child #%d of node #%d' % (j_real, i_real)
1353 tree_store[path][-1] = new_label
1354 self.assertEqual(tree_store[path][-1], new_label)
1356 self.assertRaises(IndexError, get_by_index, path, -3)
1358 self.assertRaises(IndexError, get_by_index, -101)
1360 last_row = tree_store[99]
1361 self.assertNotEqual(last_row, None)
1363 for i, childrow in enumerate(last_row.iterchildren()):
1365 self.assertTrue(tree_store.remove(childrow.iter))
1367 self.assertFalse(tree_store.remove(childrow.iter))
1369 self.assertEqual(i, 19)
1371 self.assertEqual(tree_store.iter_n_children(last_row.iter), 0)
1372 for childrow in last_row.iterchildren():
1373 self.fail("Should not be reached")
1375 aiter = tree_store.get_iter(10)
1376 self.assertRaises(TypeError, tree_store.get, aiter, 1, 'a')
1377 self.assertRaises(ValueError, tree_store.get, aiter, 1, -1)
1378 self.assertRaises(ValueError, tree_store.get, aiter, 1, 100)
1379 self.assertEqual(tree_store.get(aiter, 0, 1), (10, 'this is row #10'))
1382 self.assertEqual(len(tree_store), 100)
1383 aiter = tree_store.get_iter(10)
1384 del tree_store[aiter]
1385 self.assertEqual(len(tree_store), 99)
1386 self.assertRaises(TypeError, tree_store.__delitem__, None)
1387 self.assertRaises(IndexError, tree_store.__delitem__, -101)
1388 self.assertRaises(IndexError, tree_store.__delitem__, 101)
1390 def test_tree_model_get_iter_fail(self):
1391 # TreeModel class with a failing get_iter()
1392 class MyTreeModel(GObject.GObject, Gtk.TreeModel):
1393 def do_get_iter(self, iter):
1394 return (False, None)
1397 self.assertEqual(tm.get_iter_first(), None)
1399 def test_tree_model_edit(self):
1400 model = Gtk.ListStore(int, str, float)
1401 model.append([1, "one", -0.1])
1402 model.append([2, "two", -0.2])
1407 self.assertRaises(TypeError, set_row, 3)
1408 self.assertRaises(TypeError, set_row, "three")
1409 self.assertRaises(ValueError, set_row, [])
1410 self.assertRaises(ValueError, set_row, [3, "three"])
1412 model[0] = (3, "three", -0.3)
1414 def test_tree_row_slice(self):
1415 model = Gtk.ListStore(int, str, float)
1416 model.append([1, "one", -0.1])
1418 self.assertEqual([1, "one", -0.1], model[0][:])
1419 self.assertEqual([1, "one"], model[0][:2])
1420 self.assertEqual(["one", -0.1], model[0][1:])
1421 self.assertEqual(["one"], model[0][1:-1])
1422 self.assertEqual([1], model[0][:-2])
1423 self.assertEqual([], model[0][5:])
1424 self.assertEqual([1, -0.1], model[0][0:3:2])
1426 model[0][:] = (2, "two", -0.2)
1427 self.assertEqual([2, "two", -0.2], model[0][:])
1429 model[0][:2] = (3, "three")
1430 self.assertEqual([3, "three", -0.2], model[0][:])
1432 model[0][1:] = ("four", -0.4)
1433 self.assertEqual([3, "four", -0.4], model[0][:])
1435 model[0][1:-1] = ("five",)
1436 self.assertEqual([3, "five", -0.4], model[0][:])
1438 model[0][0:3:2] = (6, -0.6)
1439 self.assertEqual([6, "five", -0.6], model[0][:])
1442 model[0][5:] = ("doesn't", "matter",)
1444 self.assertRaises(ValueError, set_row1)
1447 model[0][:1] = (0, "zero", 0)
1449 self.assertRaises(ValueError, set_row2)
1452 model[0][:2] = ("0", 0)
1454 self.assertRaises(TypeError, set_row3)
1456 def test_tree_model_set_value_to_none(self):
1457 # Tests allowing the usage of None to set an empty value on a model.
1458 store = Gtk.ListStore(str)
1459 row = store.append(['test'])
1460 self.assertSequenceEqual(store[0][:], ['test'])
1461 store.set_value(row, 0, None)
1462 self.assertSequenceEqual(store[0][:], [None])
1464 def test_signal_emission_tree_path_coerce(self):
1465 class Model(GObject.Object, Gtk.TreeModel):
1471 def on_any_signal(model, path, *args):
1472 tree_paths.append(path.to_string())
1474 model.connect('row-changed', on_any_signal)
1475 model.connect('row-deleted', on_any_signal)
1476 model.connect('row-has-child-toggled', on_any_signal)
1477 model.connect('row-inserted', on_any_signal)
1479 model.row_changed('0', Gtk.TreeIter())
1480 self.assertEqual(tree_paths[-1], '0')
1482 model.row_deleted('1')
1483 self.assertEqual(tree_paths[-1], '1')
1485 model.row_has_child_toggled('2', Gtk.TreeIter())
1486 self.assertEqual(tree_paths[-1], '2')
1488 model.row_inserted('3', Gtk.TreeIter())
1489 self.assertEqual(tree_paths[-1], '3')
1491 def test_tree_model_filter(self):
1492 model = Gtk.ListStore(int, str, float)
1493 model.append([1, "one", -0.1])
1494 model.append([2, "two", -0.2])
1496 filtered = Gtk.TreeModelFilter(child_model=model)
1498 self.assertEqual(filtered[0][1], 'one')
1499 filtered[0][1] = 'ONE'
1500 self.assertEqual(filtered[0][1], 'ONE')
1502 def test_list_store_performance(self):
1503 model = Gtk.ListStore(int, str)
1506 start = time.clock()
1509 model.append([1, 'hello'])
1512 sys.stderr.write('[%.0f µs/append] ' % ((end - start) * 1000000 / iterations))
1515 @unittest.skipUnless(Gtk, 'Gtk not available')
1516 class TestTreeView(unittest.TestCase):
1517 def test_tree_view(self):
1518 store = Gtk.ListStore(int, str)
1519 store.append((0, "foo"))
1520 store.append((1, "bar"))
1521 view = Gtk.TreeView()
1523 with realized(view):
1524 view.set_cursor(store[1].path)
1525 view.set_cursor(str(store[1].path))
1527 view.get_cell_area(store[1].path)
1528 view.get_cell_area(str(store[1].path))
1530 def test_tree_view_column(self):
1531 cell = Gtk.CellRendererText()
1532 Gtk.TreeViewColumn(title='This is just a test',
1537 def test_tree_view_add_column_with_attributes(self):
1538 model = Gtk.ListStore(str, str, str)
1539 # deliberately use out-of-order sorting here; we assign column 0 to
1540 # model index 2, etc.
1541 model.append(['cell13', 'cell11', 'cell12'])
1542 model.append(['cell23', 'cell21', 'cell22'])
1544 tree = Gtk.TreeView(model)
1545 cell1 = Gtk.CellRendererText()
1546 cell2 = Gtk.CellRendererText()
1547 cell3 = Gtk.CellRendererText()
1548 cell4 = Gtk.CellRendererText()
1550 tree.insert_column_with_attributes(0, 'Head2', cell2, text=2)
1551 tree.insert_column_with_attributes(0, 'Head1', cell1, text=1)
1552 tree.insert_column_with_attributes(-1, 'Head3', cell3, text=0)
1554 tree.insert_column_with_attributes(-1, 'Head4', cell4)
1556 with realized(tree):
1557 tree.set_cursor(model[0].path)
1558 while Gtk.events_pending():
1559 Gtk.main_iteration()
1561 self.assertEqual(tree.get_column(0).get_title(), 'Head1')
1562 self.assertEqual(tree.get_column(1).get_title(), 'Head2')
1563 self.assertEqual(tree.get_column(2).get_title(), 'Head3')
1564 self.assertEqual(tree.get_column(3).get_title(), 'Head4')
1566 # cursor should be at the first row
1567 self.assertEqual(cell1.props.text, 'cell11')
1568 self.assertEqual(cell2.props.text, 'cell12')
1569 self.assertEqual(cell3.props.text, 'cell13')
1570 self.assertEqual(cell4.props.text, None)
1572 def test_tree_view_column_set_attributes(self):
1573 store = Gtk.ListStore(int, str)
1574 directors = ['Fellini', 'Tarantino', 'Tarkovskiy']
1575 for i, director in enumerate(directors):
1576 store.append([i, director])
1578 treeview = Gtk.TreeView()
1579 treeview.set_model(store)
1581 column = Gtk.TreeViewColumn()
1582 treeview.append_column(column)
1584 cell = Gtk.CellRendererText()
1585 column.pack_start(cell, expand=True)
1586 column.set_attributes(cell, text=1)
1588 with realized(treeview):
1589 self.assertTrue(cell.props.text in directors)
1591 def test_tree_selection(self):
1592 store = Gtk.ListStore(int, str)
1594 store.append((i, "foo"))
1595 view = Gtk.TreeView()
1596 view.set_model(store)
1597 firstpath = store.get_path(store.get_iter_first())
1598 sel = view.get_selection()
1600 sel.select_path(firstpath)
1601 (m, s) = sel.get_selected()
1602 self.assertEqual(m, store)
1603 self.assertEqual(store.get_path(s), firstpath)
1606 (m, s) = sel.get_selected()
1607 self.assertEqual(m, store)
1608 self.assertEqual(store.get_path(s), firstpath)
1610 sel.select_path("0:0")
1611 (m, s) = sel.get_selected()
1612 self.assertEqual(m, store)
1613 self.assertEqual(store.get_path(s), firstpath)
1615 sel.select_path((0, 0))
1616 (m, s) = sel.get_selected()
1617 self.assertEqual(m, store)
1618 self.assertEqual(store.get_path(s), firstpath)
1621 @unittest.skipUnless(Gtk, 'Gtk not available')
1622 class TestTextBuffer(unittest.TestCase):
1623 def test_text_buffer(self):
1624 self.assertEqual(Gtk.TextBuffer, gi.overrides.Gtk.TextBuffer)
1625 buffer = Gtk.TextBuffer()
1626 tag = buffer.create_tag('title', font='Sans 18')
1628 self.assertEqual(tag.props.name, 'title')
1629 self.assertEqual(tag.props.font, 'Sans 18')
1631 (start, end) = buffer.get_bounds()
1633 mark = buffer.create_mark(None, start)
1634 self.assertFalse(mark.get_left_gravity())
1636 buffer.set_text('Hello Jane Hello Bob')
1637 (start, end) = buffer.get_bounds()
1638 text = buffer.get_text(start, end, False)
1639 self.assertEqual(text, 'Hello Jane Hello Bob')
1642 (start, end) = buffer.get_bounds()
1643 text = buffer.get_text(start, end, False)
1644 self.assertEqual(text, '')
1646 buffer.insert(end, 'HelloHello')
1647 buffer.insert(end, ' Bob')
1649 cursor_iter = end.copy()
1650 cursor_iter.backward_chars(9)
1651 buffer.place_cursor(cursor_iter)
1652 buffer.insert_at_cursor(' Jane ')
1654 (start, end) = buffer.get_bounds()
1655 text = buffer.get_text(start, end, False)
1656 self.assertEqual(text, 'Hello Jane Hello Bob')
1658 sel = buffer.get_selection_bounds()
1659 self.assertEqual(sel, ())
1660 buffer.select_range(start, end)
1661 sel = buffer.get_selection_bounds()
1662 self.assertTrue(sel[0].equal(start))
1663 self.assertTrue(sel[1].equal(end))
1666 buffer.insert_with_tags(buffer.get_start_iter(), 'HelloHello', tag)
1667 (start, end) = buffer.get_bounds()
1668 self.assertTrue(start.begins_tag(tag))
1669 self.assertTrue(start.has_tag(tag))
1672 buffer.insert_with_tags_by_name(buffer.get_start_iter(), 'HelloHello', 'title')
1673 (start, end) = buffer.get_bounds()
1674 self.assertTrue(start.begins_tag(tag))
1675 self.assertTrue(start.has_tag(tag))
1677 self.assertRaises(ValueError, buffer.insert_with_tags_by_name,
1678 buffer.get_start_iter(), 'HelloHello', 'unknowntag')
1680 def test_text_iter(self):
1681 self.assertEqual(Gtk.TextIter, gi.overrides.Gtk.TextIter)
1682 buffer = Gtk.TextBuffer()
1683 buffer.set_text('Hello Jane Hello Bob')
1684 tag = buffer.create_tag('title', font='Sans 18')
1685 (start, end) = buffer.get_bounds()
1686 start.forward_chars(10)
1687 buffer.apply_tag(tag, start, end)
1688 self.assertTrue(start.begins_tag())
1689 self.assertTrue(end.ends_tag())
1690 self.assertTrue(start.toggles_tag())
1691 self.assertTrue(end.toggles_tag())
1692 start.backward_chars(1)
1693 self.assertFalse(start.begins_tag())
1694 self.assertFalse(start.ends_tag())
1695 self.assertFalse(start.toggles_tag())
1697 def test_text_buffer_search(self):
1698 buffer = Gtk.TextBuffer()
1699 buffer.set_text('Hello World Hello GNOME')
1701 i = buffer.get_iter_at_offset(0)
1702 self.assertTrue(isinstance(i, Gtk.TextIter))
1704 self.assertEqual(i.forward_search('world', 0, None), None)
1706 (start, end) = i.forward_search('World', 0, None)
1707 self.assertEqual(start.get_offset(), 6)
1708 self.assertEqual(end.get_offset(), 11)
1710 (start, end) = i.forward_search('world',
1711 Gtk.TextSearchFlags.CASE_INSENSITIVE,
1713 self.assertEqual(start.get_offset(), 6)
1714 self.assertEqual(end.get_offset(), 11)