Setting app name to FMRadio allows playback during silent mode
[nqaap] / src / opt / Nqa-Audiobook-player / hildonize.py
1 #!/usr/bin/env python
2
3 """
4 Open Issues
5         @bug not all of a message is shown
6         @bug Buttons are too small
7 """
8
9
10 import gobject
11 import gtk
12 import dbus
13
14
15 class _NullHildonModule(object):
16         pass
17
18
19 try:
20         import hildon as _hildon
21         hildon  = _hildon # Dumb but gets around pyflakiness
22 except (ImportError, OSError):
23         hildon = _NullHildonModule
24
25
26 IS_HILDON_SUPPORTED = hildon is not _NullHildonModule
27
28
29 class _NullHildonProgram(object):
30
31         def add_window(self, window):
32                 pass
33
34
35 def _hildon_get_app_class():
36         return hildon.Program
37
38
39 def _null_get_app_class():
40         return _NullHildonProgram
41
42
43 try:
44         hildon.Program
45         get_app_class = _hildon_get_app_class
46 except AttributeError:
47         get_app_class = _null_get_app_class
48
49
50 def _hildon_set_application_name(name):
51         gtk.set_application_name(name)
52
53
54 def _null_set_application_name(name):
55         pass
56
57
58 try:
59         gtk.set_application_name
60         set_application_name = _hildon_set_application_name
61 except AttributeError:
62         set_application_name = _null_set_application_name
63
64
65 def _fremantle_hildonize_window(app, window):
66         oldWindow = window
67         newWindow = hildon.StackableWindow()
68         if oldWindow.get_child() is not None:
69                 oldWindow.get_child().reparent(newWindow)
70         app.add_window(newWindow)
71         return newWindow
72
73
74 def _hildon_hildonize_window(app, window):
75         oldWindow = window
76         newWindow = hildon.Window()
77         if oldWindow.get_child() is not None:
78                 oldWindow.get_child().reparent(newWindow)
79         app.add_window(newWindow)
80         return newWindow
81
82
83 def _null_hildonize_window(app, window):
84         return window
85
86
87 try:
88         hildon.StackableWindow
89         hildonize_window = _fremantle_hildonize_window
90 except AttributeError:
91         try:
92                 hildon.Window
93                 hildonize_window = _hildon_hildonize_window
94         except AttributeError:
95                 hildonize_window = _null_hildonize_window
96
97
98 def _fremantle_hildonize_menu(window, gtkMenu):
99         appMenu = hildon.AppMenu()
100         window.set_app_menu(appMenu)
101         gtkMenu.get_parent().remove(gtkMenu)
102         return appMenu
103
104
105 def _hildon_hildonize_menu(window, gtkMenu):
106         hildonMenu = gtk.Menu()
107         for child in gtkMenu.get_children():
108                 child.reparent(hildonMenu)
109         window.set_menu(hildonMenu)
110         gtkMenu.destroy()
111         return hildonMenu
112
113
114 def _null_hildonize_menu(window, gtkMenu):
115         return gtkMenu
116
117
118 try:
119         hildon.AppMenu
120         GTK_MENU_USED = False
121         IS_FREMANTLE_SUPPORTED = True
122         hildonize_menu = _fremantle_hildonize_menu
123 except AttributeError:
124         GTK_MENU_USED = True
125         IS_FREMANTLE_SUPPORTED = False
126         if IS_HILDON_SUPPORTED:
127                 hildonize_menu = _hildon_hildonize_menu
128         else:
129                 hildonize_menu = _null_hildonize_menu
130
131
132 def _hildon_set_button_auto_selectable(button):
133         button.set_theme_size(hildon.HILDON_SIZE_AUTO_HEIGHT)
134
135
136 def _null_set_button_auto_selectable(button):
137         pass
138
139
140 try:
141         hildon.HILDON_SIZE_AUTO_HEIGHT
142         gtk.Button.set_theme_size
143         set_button_auto_selectable = _hildon_set_button_auto_selectable
144 except AttributeError:
145         set_button_auto_selectable = _null_set_button_auto_selectable
146
147
148 def _hildon_set_button_finger_selectable(button):
149         button.set_theme_size(hildon.HILDON_SIZE_FINGER_HEIGHT)
150
151
152 def _null_set_button_finger_selectable(button):
153         pass
154
155
156 try:
157         hildon.HILDON_SIZE_FINGER_HEIGHT
158         gtk.Button.set_theme_size
159         set_button_finger_selectable = _hildon_set_button_finger_selectable
160 except AttributeError:
161         set_button_finger_selectable = _null_set_button_finger_selectable
162
163
164 def _hildon_set_button_thumb_selectable(button):
165         button.set_theme_size(hildon.HILDON_SIZE_THUMB_HEIGHT)
166
167
168 def _null_set_button_thumb_selectable(button):
169         pass
170
171
172 try:
173         hildon.HILDON_SIZE_THUMB_HEIGHT
174         gtk.Button.set_theme_size
175         set_button_thumb_selectable = _hildon_set_button_thumb_selectable
176 except AttributeError:
177         set_button_thumb_selectable = _null_set_button_thumb_selectable
178
179
180 def _hildon_set_cell_thumb_selectable(renderer):
181         renderer.set_property("scale", 1.5)
182
183
184 def _null_set_cell_thumb_selectable(renderer):
185         pass
186
187
188 if IS_HILDON_SUPPORTED:
189         set_cell_thumb_selectable = _hildon_set_cell_thumb_selectable
190 else:
191         set_cell_thumb_selectable = _null_set_cell_thumb_selectable
192
193
194 def _hildon_set_pix_cell_thumb_selectable(renderer):
195         renderer.set_property("stock-size", 48)
196
197
198 def _null_set_pix_cell_thumb_selectable(renderer):
199         pass
200
201
202 if IS_HILDON_SUPPORTED:
203         set_pix_cell_thumb_selectable = _hildon_set_pix_cell_thumb_selectable
204 else:
205         set_pix_cell_thumb_selectable = _null_set_pix_cell_thumb_selectable
206
207
208 def _fremantle_show_information_banner(parent, message):
209         hildon.hildon_banner_show_information(parent, "", message)
210
211
212 def _hildon_show_information_banner(parent, message):
213         hildon.hildon_banner_show_information(parent, None, message)
214
215
216 def _null_show_information_banner(parent, message):
217         pass
218
219
220 if IS_FREMANTLE_SUPPORTED:
221         show_information_banner = _fremantle_show_information_banner
222 else:
223         try:
224                 hildon.hildon_banner_show_information
225                 show_information_banner = _hildon_show_information_banner
226         except AttributeError:
227                 show_information_banner = _null_show_information_banner
228
229
230 def _fremantle_show_busy_banner_start(parent, message):
231         hildon.hildon_gtk_window_set_progress_indicator(parent, True)
232         return parent
233
234
235 def _fremantle_show_busy_banner_end(banner):
236         hildon.hildon_gtk_window_set_progress_indicator(banner, False)
237
238
239 def _hildon_show_busy_banner_start(parent, message):
240         return hildon.hildon_banner_show_animation(parent, None, message)
241
242
243 def _hildon_show_busy_banner_end(banner):
244         banner.destroy()
245
246
247 def _null_show_busy_banner_start(parent, message):
248         return None
249
250
251 def _null_show_busy_banner_end(banner):
252         assert banner is None
253
254
255 try:
256         hildon.hildon_gtk_window_set_progress_indicator
257         show_busy_banner_start = _fremantle_show_busy_banner_start
258         show_busy_banner_end = _fremantle_show_busy_banner_end
259 except AttributeError:
260         try:
261                 hildon.hildon_banner_show_animation
262                 show_busy_banner_start = _hildon_show_busy_banner_start
263                 show_busy_banner_end = _hildon_show_busy_banner_end
264         except AttributeError:
265                 show_busy_banner_start = _null_show_busy_banner_start
266                 show_busy_banner_end = _null_show_busy_banner_end
267
268
269 def _hildon_hildonize_text_entry(textEntry):
270         textEntry.set_property('hildon-input-mode', 7)
271
272
273 def _null_hildonize_text_entry(textEntry):
274         pass
275
276
277 if IS_HILDON_SUPPORTED:
278         hildonize_text_entry = _hildon_hildonize_text_entry
279 else:
280         hildonize_text_entry = _null_hildonize_text_entry
281
282
283 def _hildon_window_to_portrait(window):
284         # gtk documentation is unclear whether this does a "=" or a "|="
285         flags = hildon.PORTRAIT_MODE_SUPPORT | hildon.PORTRAIT_MODE_REQUEST
286         hildon.hildon_gtk_window_set_portrait_flags(window, flags)
287
288
289 def _hildon_window_to_landscape(window):
290         # gtk documentation is unclear whether this does a "=" or a "&= ~"
291         flags = hildon.PORTRAIT_MODE_SUPPORT
292         hildon.hildon_gtk_window_set_portrait_flags(window, flags)
293
294
295 def _null_window_to_portrait(window):
296         pass
297
298
299 def _null_window_to_landscape(window):
300         pass
301
302
303 try:
304         hildon.PORTRAIT_MODE_SUPPORT
305         hildon.PORTRAIT_MODE_REQUEST
306         hildon.hildon_gtk_window_set_portrait_flags
307
308         window_to_portrait = _hildon_window_to_portrait
309         window_to_landscape = _hildon_window_to_landscape
310 except AttributeError:
311         window_to_portrait = _null_window_to_portrait
312         window_to_landscape = _null_window_to_landscape
313
314
315 def get_device_orientation():
316         bus = dbus.SystemBus()
317         try:
318                 rawMceRequest = bus.get_object("com.nokia.mce", "/com/nokia/mce/request")
319                 mceRequest = dbus.Interface(rawMceRequest, dbus_interface="com.nokia.mce.request")
320                 orientation, standState, faceState, xAxis, yAxis, zAxis = mceRequest.get_device_orientation()
321         except dbus.exception.DBusException:
322                 # catching for documentation purposes that when a system doesn't
323                 # support this, this is what to expect
324                 raise
325
326         if orientation == "":
327                 return gtk.ORIENTATION_HORIZONTAL
328         elif orientation == "":
329                 return gtk.ORIENTATION_VERTICAL
330         else:
331                 raise RuntimeError("Unknown orientation: %s" % orientation)
332
333
334 def _hildon_hildonize_password_entry(textEntry):
335         textEntry.set_property('hildon-input-mode', 7 | (1 << 29))
336
337
338 def _null_hildonize_password_entry(textEntry):
339         pass
340
341
342 if IS_HILDON_SUPPORTED:
343         hildonize_password_entry = _hildon_hildonize_password_entry
344 else:
345         hildonize_password_entry = _null_hildonize_password_entry
346
347
348 def _hildon_hildonize_combo_entry(comboEntry):
349         comboEntry.set_property('hildon-input-mode', 1 << 4)
350
351
352 def _null_hildonize_combo_entry(textEntry):
353         pass
354
355
356 if IS_HILDON_SUPPORTED:
357         hildonize_combo_entry = _hildon_hildonize_combo_entry
358 else:
359         hildonize_combo_entry = _null_hildonize_combo_entry
360
361
362 def _fremantle_hildonize_scrollwindow(scrolledWindow):
363         pannableWindow = hildon.PannableArea()
364
365         child = scrolledWindow.get_child()
366         scrolledWindow.remove(child)
367         pannableWindow.add(child)
368
369         parent = scrolledWindow.get_parent()
370         if parent is not None:
371                 parent.remove(scrolledWindow)
372                 parent.add(pannableWindow)
373
374         return pannableWindow
375
376
377 def _hildon_hildonize_scrollwindow(scrolledWindow):
378         hildon.hildon_helper_set_thumb_scrollbar(scrolledWindow, True)
379         return scrolledWindow
380
381
382 def _null_hildonize_scrollwindow(scrolledWindow):
383         return scrolledWindow
384
385
386 try:
387         hildon.PannableArea
388         hildonize_scrollwindow = _fremantle_hildonize_scrollwindow
389         hildonize_scrollwindow_with_viewport = _hildon_hildonize_scrollwindow
390 except AttributeError:
391         try:
392                 hildon.hildon_helper_set_thumb_scrollbar
393                 hildonize_scrollwindow = _hildon_hildonize_scrollwindow
394                 hildonize_scrollwindow_with_viewport = _hildon_hildonize_scrollwindow
395         except AttributeError:
396                 hildonize_scrollwindow = _null_hildonize_scrollwindow
397                 hildonize_scrollwindow_with_viewport = _null_hildonize_scrollwindow
398
399
400 def _hildon_request_number(parent, title, range, default):
401         spinner = hildon.NumberEditor(*range)
402         spinner.set_value(default)
403
404         dialog = gtk.Dialog(
405                 title,
406                 parent,
407                 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
408                 (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
409         )
410         dialog.set_default_response(gtk.RESPONSE_CANCEL)
411         dialog.get_child().add(spinner)
412
413         try:
414                 dialog.show_all()
415                 response = dialog.run()
416
417                 if response == gtk.RESPONSE_OK:
418                         return spinner.get_value()
419                 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
420                         raise RuntimeError("User cancelled request")
421                 else:
422                         raise RuntimeError("Unrecognized response %r", response)
423         finally:
424                 dialog.hide()
425                 dialog.destroy()
426
427
428 def _null_request_number(parent, title, range, default):
429         adjustment = gtk.Adjustment(default, range[0], range[1], 1, 5, 0)
430         spinner = gtk.SpinButton(adjustment, 0, 0)
431         spinner.set_wrap(False)
432
433         dialog = gtk.Dialog(
434                 title,
435                 parent,
436                 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
437                 (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
438         )
439         dialog.set_default_response(gtk.RESPONSE_CANCEL)
440         dialog.get_child().add(spinner)
441
442         try:
443                 dialog.show_all()
444                 response = dialog.run()
445
446                 if response == gtk.RESPONSE_OK:
447                         return spinner.get_value_as_int()
448                 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
449                         raise RuntimeError("User cancelled request")
450                 else:
451                         raise RuntimeError("Unrecognized response %r", response)
452         finally:
453                 dialog.hide()
454                 dialog.destroy()
455
456
457 try:
458         hildon.NumberEditor # TODO deprecated in fremantle
459         request_number = _hildon_request_number
460 except AttributeError:
461         request_number = _null_request_number
462
463
464 def _hildon_touch_selector(parent, title, items, defaultIndex):
465         model = gtk.ListStore(gobject.TYPE_STRING)
466         for item in items:
467                 model.append((item, ))
468
469         selector = hildon.TouchSelector()
470         selector.append_text_column(model, True)
471         selector.set_column_selection_mode(hildon.TOUCH_SELECTOR_SELECTION_MODE_SINGLE)
472         selector.set_active(0, defaultIndex)
473
474         dialog = hildon.PickerDialog(parent)
475         dialog.set_selector(selector)
476
477         try:
478                 dialog.show_all()
479                 response = dialog.run()
480
481                 if response == gtk.RESPONSE_OK:
482                         return selector.get_active(0)
483                 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
484                         raise RuntimeError("User cancelled request")
485                 else:
486                         raise RuntimeError("Unrecognized response %r", response)
487         finally:
488                 dialog.hide()
489                 dialog.destroy()
490
491
492 def _on_null_touch_selector_activated(treeView, path, column, dialog, pathData):
493         dialog.response(gtk.RESPONSE_OK)
494         pathData[0] = path
495
496
497 def _null_touch_selector(parent, title, items, defaultIndex = -1):
498         parentSize = parent.get_size()
499
500         model = gtk.ListStore(gobject.TYPE_STRING)
501         for item in items:
502                 model.append((item, ))
503
504         cell = gtk.CellRendererText()
505         set_cell_thumb_selectable(cell)
506         column = gtk.TreeViewColumn(title)
507         column.pack_start(cell, expand=True)
508         column.add_attribute(cell, "text", 0)
509
510         treeView = gtk.TreeView()
511         treeView.set_model(model)
512         treeView.append_column(column)
513         selection = treeView.get_selection()
514         selection.set_mode(gtk.SELECTION_SINGLE)
515         if 0 < defaultIndex:
516                 selection.select_path((defaultIndex, ))
517
518         scrolledWin = gtk.ScrolledWindow()
519         scrolledWin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
520         scrolledWin.add(treeView)
521
522         dialog = gtk.Dialog(
523                 title,
524                 parent,
525                 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
526                 (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
527         )
528         dialog.set_default_response(gtk.RESPONSE_CANCEL)
529         dialog.get_child().add(scrolledWin)
530         dialog.resize(parentSize[0], max(parentSize[1]-100, 100))
531
532         scrolledWin = hildonize_scrollwindow(scrolledWin)
533         pathData = [None]
534         treeView.connect("row-activated", _on_null_touch_selector_activated, dialog, pathData)
535
536         try:
537                 dialog.show_all()
538                 response = dialog.run()
539
540                 if response == gtk.RESPONSE_OK:
541                         if pathData[0] is None:
542                                 raise RuntimeError("No selection made")
543                         return pathData[0][0]
544                 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
545                         raise RuntimeError("User cancelled request")
546                 else:
547                         raise RuntimeError("Unrecognized response %r", response)
548         finally:
549                 dialog.hide()
550                 dialog.destroy()
551
552
553 try:
554         hildon.PickerDialog
555         hildon.TouchSelector
556         touch_selector = _hildon_touch_selector
557 except AttributeError:
558         touch_selector = _null_touch_selector
559
560
561 def _hildon_touch_selector_entry(parent, title, items, defaultItem):
562         # Got a segfault when using append_text_column with TouchSelectorEntry, so using this way
563         try:
564                 selector = hildon.TouchSelectorEntry(text=True)
565         except TypeError:
566                 selector = hildon.hildon_touch_selector_entry_new_text()
567         defaultIndex = -1
568         for i, item in enumerate(items):
569                 selector.append_text(item)
570                 if item == defaultItem:
571                         defaultIndex = i
572
573         dialog = hildon.PickerDialog(parent)
574         dialog.set_selector(selector)
575
576         if 0 < defaultIndex:
577                 selector.set_active(0, defaultIndex)
578         else:
579                 selector.get_entry().set_text(defaultItem)
580
581         try:
582                 dialog.show_all()
583                 response = dialog.run()
584         finally:
585                 dialog.hide()
586
587         if response == gtk.RESPONSE_OK:
588                 return selector.get_entry().get_text()
589         elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
590                 raise RuntimeError("User cancelled request")
591         else:
592                 raise RuntimeError("Unrecognized response %r", response)
593
594
595 def _on_null_touch_selector_entry_entry_changed(entry, result, selection, defaultIndex):
596         custom = entry.get_text().strip()
597         if custom:
598                 result[0] = custom
599                 selection.unselect_all()
600         else:
601                 result[0] = None
602                 selection.select_path((defaultIndex, ))
603
604
605 def _on_null_touch_selector_entry_entry_activated(customEntry, dialog, result):
606         dialog.response(gtk.RESPONSE_OK)
607         result[0] = customEntry.get_text()
608
609
610 def _on_null_touch_selector_entry_tree_activated(treeView, path, column, dialog, result):
611         dialog.response(gtk.RESPONSE_OK)
612         model = treeView.get_model()
613         itr = model.get_iter(path)
614         if itr is not None:
615                 result[0] = model.get_value(itr, 0)
616
617
618 def _null_touch_selector_entry(parent, title, items, defaultItem):
619         parentSize = parent.get_size()
620
621         model = gtk.ListStore(gobject.TYPE_STRING)
622         defaultIndex = -1
623         for i, item in enumerate(items):
624                 model.append((item, ))
625                 if item == defaultItem:
626                         defaultIndex = i
627
628         cell = gtk.CellRendererText()
629         set_cell_thumb_selectable(cell)
630         column = gtk.TreeViewColumn(title)
631         column.pack_start(cell, expand=True)
632         column.add_attribute(cell, "text", 0)
633
634         treeView = gtk.TreeView()
635         treeView.set_model(model)
636         treeView.append_column(column)
637         selection = treeView.get_selection()
638         selection.set_mode(gtk.SELECTION_SINGLE)
639
640         scrolledWin = gtk.ScrolledWindow()
641         scrolledWin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
642         scrolledWin.add(treeView)
643
644         customEntry = gtk.Entry()
645
646         layout = gtk.VBox()
647         layout.pack_start(customEntry, expand=False)
648         layout.pack_start(scrolledWin)
649
650         dialog = gtk.Dialog(
651                 title,
652                 parent,
653                 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
654                 (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
655         )
656         dialog.set_default_response(gtk.RESPONSE_CANCEL)
657         dialog.get_child().add(layout)
658         dialog.resize(parentSize[0], max(parentSize[1]-100, 100))
659
660         scrolledWin = hildonize_scrollwindow(scrolledWin)
661
662         result = [None]
663         if 0 < defaultIndex:
664                 selection.select_path((defaultIndex, ))
665                 result[0] = defaultItem
666         else:
667                 customEntry.set_text(defaultItem)
668
669         customEntry.connect("activate", _on_null_touch_selector_entry_entry_activated, dialog, result)
670         customEntry.connect("changed", _on_null_touch_selector_entry_entry_changed, result, selection, defaultIndex)
671         treeView.connect("row-activated", _on_null_touch_selector_entry_tree_activated, dialog, result)
672
673         try:
674                 dialog.show_all()
675                 response = dialog.run()
676
677                 if response == gtk.RESPONSE_OK:
678                         _, itr = selection.get_selected()
679                         if itr is not None:
680                                 return model.get_value(itr, 0)
681                         else:
682                                 enteredText = customEntry.get_text().strip()
683                                 if enteredText:
684                                         return enteredText
685                                 elif result[0] is not None:
686                                         return result[0]
687                                 else:
688                                         raise RuntimeError("No selection made")
689                 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
690                         raise RuntimeError("User cancelled request")
691                 else:
692                         raise RuntimeError("Unrecognized response %r", response)
693         finally:
694                 dialog.hide()
695                 dialog.destroy()
696
697
698 try:
699         hildon.PickerDialog
700         hildon.TouchSelectorEntry
701         touch_selector_entry = _hildon_touch_selector_entry
702 except AttributeError:
703         touch_selector_entry = _null_touch_selector_entry
704
705
706 if __name__ == "__main__":
707         app = get_app_class()()
708
709         label = gtk.Label("Hello World from a Label!")
710
711         win = gtk.Window()
712         win.add(label)
713         win = hildonize_window(app, win)
714         if False and IS_FREMANTLE_SUPPORTED:
715                 appMenu = hildon.AppMenu()
716                 for i in xrange(5):
717                         b = gtk.Button(str(i))
718                         appMenu.append(b)
719                 win.set_app_menu(appMenu)
720                 win.show_all()
721                 appMenu.show_all()
722                 gtk.main()
723         elif False:
724                 print touch_selector(win, "Test", ["A", "B", "C", "D"], 2)
725         elif False:
726                 print touch_selector_entry(win, "Test", ["A", "B", "C", "D"], "C")
727                 print touch_selector_entry(win, "Test", ["A", "B", "C", "D"], "Blah")
728         elif False:
729                 import pprint
730                 name, value = "", ""
731                 goodLocals = [
732                         (name, value) for (name, value) in locals().iteritems()
733                         if not name.startswith("_")
734                 ]
735                 pprint.pprint(goodLocals)
736         elif False:
737                 import time
738                 show_information_banner(win, "Hello World")
739                 time.sleep(5)
740         elif False:
741                 import time
742                 banner = show_busy_banner_start(win, "Hello World")
743                 time.sleep(5)
744                 show_busy_banner_end(banner)