1 # @todo Add icons to buttons/rows to indicate that the currently playing track is coming from that
12 import util.misc as misc_utils
19 _moduleLogger = logging.getLogger(__name__)
22 class BasicWindow(gobject.GObject):
26 gobject.SIGNAL_RUN_LAST,
31 gobject.SIGNAL_RUN_LAST,
36 gobject.SIGNAL_RUN_LAST,
38 (gobject.TYPE_BOOLEAN, ),
41 gobject.SIGNAL_RUN_LAST,
43 (gobject.TYPE_BOOLEAN, ),
47 def __init__(self, player, store):
48 gobject.GObject.__init__(self)
49 self._isDestroyed = False
54 self._clipboard = gtk.clipboard_get()
55 self._windowInFullscreen = False
57 self._errorBanner = banners.StackingBanner()
59 self._layout = gtk.VBox()
60 self._layout.pack_start(self._errorBanner.toplevel, False, True)
62 self._window = gtk.Window()
63 self._window.add(self._layout)
64 self._window = hildonize.hildonize_window(self, self._window)
66 self._window.set_icon(self._store.get_pixbuf_from_store(self._store.STORE_LOOKUP["icon"]))
67 self._window.connect("key-press-event", self._on_key_press)
68 self._window.connect("window-state-event", self._on_window_state_change)
69 self._window.connect("destroy", self._on_destroy)
76 self._window.show_all()
78 def save_settings(self, config, sectionName):
79 config.add_section(sectionName)
80 config.set(sectionName, "fullscreen", str(self._windowInFullscreen))
82 def load_settings(self, config, sectionName):
84 self._windowInFullscreen = config.getboolean(sectionName, "fullscreen")
85 except ConfigParser.NoSectionError, e:
87 "Settings file %s is missing section %s" % (
88 constants._user_settings_,
93 if self._windowInFullscreen:
94 self._window.fullscreen()
96 self._window.unfullscreen()
98 @misc_utils.log_exception(_moduleLogger)
99 def _on_destroy(self, *args):
100 self._isDestroyed = True
102 @misc_utils.log_exception(_moduleLogger)
103 def _on_window_state_change(self, widget, event, *args):
104 if event.new_window_state & gtk.gdk.WINDOW_STATE_FULLSCREEN:
105 self._windowInFullscreen = True
107 self._windowInFullscreen = False
108 self.emit("fullscreen", self._windowInFullscreen)
110 @misc_utils.log_exception(_moduleLogger)
111 def _on_key_press(self, widget, event, *args):
112 RETURN_TYPES = (gtk.keysyms.Return, gtk.keysyms.ISO_Enter, gtk.keysyms.KP_Enter)
113 isCtrl = bool(event.get_state() & gtk.gdk.CONTROL_MASK)
115 event.keyval == gtk.keysyms.F6 or
116 event.keyval in RETURN_TYPES and isCtrl
118 # The "Full screen" hardware key has been pressed
119 if self._windowInFullscreen:
120 self._window.unfullscreen ()
122 self._window.fullscreen ()
125 event.keyval in (gtk.keysyms.w, ) and
126 event.get_state() & gtk.gdk.CONTROL_MASK
128 self._window.destroy()
130 event.keyval in (gtk.keysyms.q, ) and
131 event.get_state() & gtk.gdk.CONTROL_MASK
134 elif event.keyval == gtk.keysyms.l and event.get_state() & gtk.gdk.CONTROL_MASK:
135 with open(constants._user_logpath_, "r") as f:
136 logLines = f.xreadlines()
137 log = "".join(logLines)
138 self._clipboard.set_text(str(log))
141 @misc_utils.log_exception(_moduleLogger)
142 def _on_home(self, *args):
144 self._window.destroy()
146 @misc_utils.log_exception(_moduleLogger)
147 def _on_quit(self, *args):
149 self._window.destroy()
152 class SourceSelector(BasicWindow):
154 def __init__(self, player, store, index):
155 BasicWindow.__init__(self, player, store)
159 self._loadingBanner = banners.GenericBanner()
161 self._radioButton = self._create_button("radio", "Radio")
162 self._radioButton.connect("clicked", self._on_source_selected, RadioWindow, "radio")
163 self._radioWrapper = gtk.VBox()
164 self._radioWrapper.pack_start(self._radioButton, False, True)
166 self._conferenceButton = self._create_button("conferences", "Conferences")
167 self._conferenceButton.connect("clicked", self._on_source_selected, ConferencesWindow, "conferences")
168 self._conferenceWrapper = gtk.VBox()
169 self._conferenceWrapper.pack_start(self._conferenceButton, False, True)
171 self._magazineButton = self._create_button("magazines", "Magazines")
172 #self._magazineButton.connect("clicked", self._on_source_selected)
173 self._magazineWrapper = gtk.VBox()
174 self._magazineWrapper.pack_start(self._magazineButton, False, True)
176 self._scriptureButton = self._create_button("scriptures", "Scriptures")
177 #self._scriptureButton.connect("clicked", self._on_source_selected)
178 self._scriptureWrapper = gtk.VBox()
179 self._scriptureWrapper.pack_start(self._scriptureButton, False, True)
181 self._buttonLayout = gtk.VButtonBox()
182 self._buttonLayout.set_layout(gtk.BUTTONBOX_SPREAD)
183 self._buttonLayout.pack_start(self._radioWrapper, True, True)
184 self._buttonLayout.pack_start(self._conferenceWrapper, True, True)
185 self._buttonLayout.pack_start(self._magazineWrapper, True, True)
186 self._buttonLayout.pack_start(self._scriptureWrapper, True, True)
188 self._playcontrol = playcontrol.PlayControl(player, store)
190 self._layout.pack_start(self._loadingBanner.toplevel, False, False)
191 self._layout.pack_start(self._buttonLayout, True, True)
192 self._layout.pack_start(self._playcontrol.toplevel, False, True)
194 self._window.set_title(constants.__pretty_app_name__)
197 BasicWindow.show(self)
199 self._errorBanner.toplevel.hide()
200 self._playcontrol.toplevel.hide()
204 def _show_loading(self):
205 animationPath = self._store.STORE_LOOKUP["loading"]
206 animation = self._store.get_pixbuf_animation_from_store(animationPath)
207 self._loadingBanner.show(animation, "Loading...")
208 self._buttonLayout.set_sensitive(False)
210 def _hide_loading(self):
211 self._loadingBanner.hide()
212 self._buttonLayout.set_sensitive(True)
216 self._index.get_languages(self._on_languages, self._on_error)
218 def _create_button(self, icon, message):
219 image = self._store.get_image_from_store(self._store.STORE_LOOKUP[icon])
222 label.set_text(message)
224 buttonLayout = gtk.HBox(False, 5)
225 buttonLayout.pack_start(image, False, False)
226 buttonLayout.pack_start(label, False, True)
227 button = gtk.Button()
228 button.add(buttonLayout)
232 @misc_utils.log_exception(_moduleLogger)
233 def _on_languages(self, languages):
235 self._languages = list(languages)
237 @misc_utils.log_exception(_moduleLogger)
238 def _on_error(self, exception):
240 self._errorBanner.push_message(str(exception))
242 @misc_utils.log_exception(_moduleLogger)
243 def _on_source_selected(self, widget, Source, nodeName):
244 node = self._index.get_source(nodeName, self._languages[0]["id"])
245 sourceWindow = Source(self._player, self._store, node)
246 sourceWindow.window.set_modal(True)
247 sourceWindow.window.set_transient_for(self._window)
248 sourceWindow.window.set_default_size(*self._window.get_size())
249 sourceWindow.connect("quit", self._on_quit)
253 gobject.type_register(SourceSelector)
256 class RadioWindow(BasicWindow):
258 def __init__(self, player, store, node):
259 BasicWindow.__init__(self, player, store)
261 self._childNode = None
263 self._player.connect("state-change", self._on_player_state_change)
264 self._player.connect("title-change", self._on_player_title_change)
266 self._loadingBanner = banners.GenericBanner()
268 headerPath = self._store.STORE_LOOKUP["radio_header"]
269 self._header = self._store.get_image_from_store(headerPath)
270 self._headerNavigation = presenter.NavigationBox()
271 self._headerNavigation.toplevel.add(self._header)
272 self._headerNavigation.connect("action", self._on_nav_action)
273 self._headerNavigation.connect("navigating", self._on_navigating)
275 self._programmingModel = gtk.ListStore(
280 textrenderer = gtk.CellRendererText()
281 timeColumn = gtk.TreeViewColumn("Time")
282 timeColumn.pack_start(textrenderer, expand=True)
283 timeColumn.add_attribute(textrenderer, "text", 0)
285 textrenderer = gtk.CellRendererText()
286 titleColumn = gtk.TreeViewColumn("Program")
287 titleColumn.pack_start(textrenderer, expand=True)
288 titleColumn.add_attribute(textrenderer, "text", 1)
290 self._treeView = gtk.TreeView()
291 self._treeView.set_headers_visible(False)
292 self._treeView.set_model(self._programmingModel)
293 self._treeView.append_column(timeColumn)
294 self._treeView.append_column(titleColumn)
295 self._treeView.get_selection().connect("changed", self._on_row_changed)
297 self._treeScroller = gtk.ScrolledWindow()
298 self._treeScroller.add(self._treeView)
299 self._treeScroller.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
301 self._presenter = presenter.StreamMiniPresenter(self._store)
302 if self._player.state == "play":
303 self._presenter.set_state(self._store.STORE_LOOKUP["play"])
305 self._presenter.set_state(self._store.STORE_LOOKUP["pause"])
306 self._presenterNavigation = presenter.NavigationBox()
307 self._presenterNavigation.toplevel.add(self._presenter.toplevel)
308 self._presenterNavigation.connect("action", self._on_nav_action)
309 self._presenterNavigation.connect("navigating", self._on_navigating)
311 self._radioLayout = gtk.VBox(False)
312 self._radioLayout.pack_start(self._headerNavigation.toplevel, False, False)
313 self._radioLayout.pack_start(self._treeScroller, True, True)
314 self._radioLayout.pack_start(self._presenterNavigation.toplevel, False, True)
316 self._layout.pack_start(self._loadingBanner.toplevel, False, False)
317 self._layout.pack_start(self._radioLayout, True, True)
319 self._window.set_title("Radio")
320 self._dateShown = datetime.datetime.now()
323 BasicWindow.show(self)
325 self._errorBanner.toplevel.hide()
326 self._loadingBanner.toplevel.hide()
330 def _show_loading(self):
331 animationPath = self._store.STORE_LOOKUP["loading"]
332 animation = self._store.get_pixbuf_animation_from_store(animationPath)
333 self._loadingBanner.show(animation, "Loading...")
335 def _hide_loading(self):
336 self._loadingBanner.hide()
340 self._programmingModel.clear()
341 self._node.get_children(
346 def _get_current_row(self):
347 nowTime = self._dateShown.strftime("%H:%M:%S")
349 for i, row in enumerate(self._programmingModel):
358 @misc_utils.log_exception(_moduleLogger)
359 def _on_player_state_change(self, player, newState):
360 if self._headerNavigation.is_active() or self._presenterNavigation.is_active():
363 if newState == "play":
364 self._presenter.set_state(self._store.STORE_LOOKUP["play"])
365 elif newState == "pause":
366 self._presenter.set_state(self._store.STORE_LOOKUP["pause"])
368 _moduleLogger.info("Unhandled player state %s" % newState)
369 self._presenter.set_state(self._store.STORE_LOOKUP["pause"])
371 @misc_utils.log_exception(_moduleLogger)
372 def _on_player_title_change(self, player, newState):
373 _moduleLogger.info("Player title magically changed to %s" % player.title)
376 @misc_utils.log_exception(_moduleLogger)
377 def _on_navigating(self, widget, navState):
378 if navState == "clicking":
379 if self._player.state == "play":
383 elif navState == "down":
385 elif navState == "up":
387 elif navState == "left":
389 elif navState == "right":
392 self._presenter.set_state(self._store.STORE_LOOKUP[imageName])
394 @misc_utils.log_exception(_moduleLogger)
395 def _on_nav_action(self, widget, navState):
396 if self._player.state == "play":
397 self._presenter.set_state(self._store.STORE_LOOKUP["play"])
399 self._presenter.set_state(self._store.STORE_LOOKUP["pause"])
401 if navState == "clicking":
402 if self._player.state == "play":
406 elif navState == "down":
407 self.window.destroy()
408 elif navState == "up":
410 elif navState == "left":
411 self._dateShown += datetime.timedelta(days=1)
413 elif navState == "right":
414 self._dateShown -= datetime.timedelta(days=1)
417 @misc_utils.log_exception(_moduleLogger)
418 def _on_channels(self, channels):
419 if self._isDestroyed:
420 _moduleLogger.info("Download complete but window destroyed")
424 if 1 < len(channels):
425 _moduleLogger.warning("More channels now available!")
426 self._childNode = channels[0]
427 self._childNode.get_programming(
433 @misc_utils.log_exception(_moduleLogger)
434 def _on_channel(self, programs):
435 if self._isDestroyed:
436 _moduleLogger.info("Download complete but window destroyed")
440 for program in programs:
441 row = program["time"], program["title"]
442 self._programmingModel.append(row)
444 path = (self._get_current_row(), )
445 self._treeView.scroll_to_cell(path)
446 self._treeView.get_selection().select_path(path)
448 @misc_utils.log_exception(_moduleLogger)
449 def _on_load_error(self, exception):
451 self._errorBanner.push_message(str(exception))
453 @misc_utils.log_exception(_moduleLogger)
454 def _on_row_changed(self, selection):
455 if len(self._programmingModel) == 0:
458 rowIndex = self._get_current_row()
460 if not selection.path_is_selected(path):
461 # Undo the user's changing of the selection
462 selection.select_path(path)
465 gobject.type_register(RadioWindow)
468 class ListWindow(BasicWindow):
470 def __init__(self, player, store, node):
471 BasicWindow.__init__(self, player, store)
474 self._loadingBanner = banners.GenericBanner()
476 modelTypes, columns = zip(*self._get_columns())
478 self._model = gtk.ListStore(*modelTypes)
480 self._treeView = gtk.TreeView()
481 self._treeView.connect("row-activated", self._on_row_activated)
482 self._treeView.set_headers_visible(False)
483 self._treeView.set_model(self._model)
484 for column in columns:
485 if column is not None:
486 self._treeView.append_column(column)
488 self._treeScroller = gtk.ScrolledWindow()
489 self._treeScroller.add(self._treeView)
490 self._treeScroller.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
492 self._playcontrol = playcontrol.PlayControl(self._player, self._store)
494 self._contentLayout = gtk.VBox(False)
495 self._contentLayout.pack_start(self._treeScroller, True, True)
496 self._contentLayout.pack_start(self._playcontrol.toplevel, False, True)
498 self._layout.pack_start(self._loadingBanner.toplevel, False, False)
499 self._layout.pack_start(self._contentLayout, True, True)
502 BasicWindow.show(self)
504 self._errorBanner.toplevel.hide()
505 self._loadingBanner.toplevel.hide()
508 self._playcontrol.refresh()
511 def _get_columns(cls):
512 raise NotImplementedError("")
514 def _get_current_row(self):
515 raise NotImplementedError("")
517 @misc_utils.log_exception(_moduleLogger)
518 def _on_row_activated(self, view, path, column):
519 raise NotImplementedError("")
521 def _show_loading(self):
522 animationPath = self._store.STORE_LOOKUP["loading"]
523 animation = self._store.get_pixbuf_animation_from_store(animationPath)
524 self._loadingBanner.show(animation, "Loading...")
526 def _hide_loading(self):
527 self._loadingBanner.hide()
533 def _select_row(self):
534 path = (self._get_current_row(), )
535 self._treeView.scroll_to_cell(path)
536 self._treeView.get_selection().select_path(path)
539 class ConferencesWindow(ListWindow):
541 def __init__(self, player, store, node):
542 ListWindow.__init__(self, player, store, node)
543 self._window.set_title("Conferences")
546 def _get_columns(cls):
547 yield gobject.TYPE_PYOBJECT, None
549 textrenderer = gtk.CellRendererText()
550 column = gtk.TreeViewColumn("Date")
551 column.pack_start(textrenderer, expand=True)
552 column.add_attribute(textrenderer, "text", 1)
553 yield gobject.TYPE_STRING, column
555 textrenderer = gtk.CellRendererText()
556 column = gtk.TreeViewColumn("Conference")
557 column.pack_start(textrenderer, expand=True)
558 column.add_attribute(textrenderer, "text", 2)
559 yield gobject.TYPE_STRING, column
561 def _get_current_row(self):
562 # @todo Not implemented yet
566 ListWindow._refresh(self)
567 self._node.get_children(
568 self._on_conferences,
572 @misc_utils.log_exception(_moduleLogger)
573 def _on_conferences(self, programs):
574 if self._isDestroyed:
575 _moduleLogger.info("Download complete but window destroyed")
579 for programNode in programs:
580 program = programNode.get_properties()
581 row = programNode, program["title"], program["full_title"]
582 self._model.append(row)
584 path = (self._get_current_row(), )
585 self._treeView.scroll_to_cell(path)
586 self._treeView.get_selection().select_path(path)
588 @misc_utils.log_exception(_moduleLogger)
589 def _on_error(self, exception):
591 self._errorBanner.push_message(str(exception))
593 @misc_utils.log_exception(_moduleLogger)
594 def _on_row_activated(self, view, path, column):
595 itr = self._model.get_iter(path)
596 node = self._model.get_value(itr, 0)
598 sessionsWindow = ConferenceSessionsWindow(self._player, self._store, node)
599 sessionsWindow.window.set_modal(True)
600 sessionsWindow.window.set_transient_for(self._window)
601 sessionsWindow.window.set_default_size(*self._window.get_size())
602 sessionsWindow.connect("quit", self._on_quit)
603 sessionsWindow.connect("home", self._on_home)
604 sessionsWindow.show()
607 gobject.type_register(ConferencesWindow)
610 class ConferenceSessionsWindow(ListWindow):
612 def __init__(self, player, store, node):
613 ListWindow.__init__(self, player, store, node)
614 self._window.set_title("Sessions")
617 def _get_columns(cls):
618 yield gobject.TYPE_PYOBJECT, None
620 textrenderer = gtk.CellRendererText()
621 column = gtk.TreeViewColumn("Session")
622 column.pack_start(textrenderer, expand=True)
623 column.add_attribute(textrenderer, "text", 1)
624 yield gobject.TYPE_STRING, column
626 def _get_current_row(self):
627 # @todo Not implemented yet
631 ListWindow._refresh(self)
632 self._node.get_children(
633 self._on_conference_sessions,
637 @misc_utils.log_exception(_moduleLogger)
638 def _on_conference_sessions(self, programs):
639 if self._isDestroyed:
640 _moduleLogger.info("Download complete but window destroyed")
644 for programNode in programs:
645 program = programNode.get_properties()
646 row = programNode, program["title"]
647 self._model.append(row)
649 path = (self._get_current_row(), )
650 self._treeView.scroll_to_cell(path)
651 self._treeView.get_selection().select_path(path)
653 @misc_utils.log_exception(_moduleLogger)
654 def _on_error(self, exception):
656 self._errorBanner.push_message(str(exception))
658 @misc_utils.log_exception(_moduleLogger)
659 def _on_row_activated(self, view, path, column):
660 itr = self._model.get_iter(path)
661 node = self._model.get_value(itr, 0)
663 sessionsWindow = ConferenceTalksWindow(self._player, self._store, node)
664 sessionsWindow.window.set_modal(True)
665 sessionsWindow.window.set_transient_for(self._window)
666 sessionsWindow.window.set_default_size(*self._window.get_size())
667 sessionsWindow.connect("quit", self._on_quit)
668 sessionsWindow.connect("home", self._on_home)
669 sessionsWindow.show()
672 gobject.type_register(ConferenceSessionsWindow)
675 class ConferenceTalksWindow(ListWindow):
677 def __init__(self, player, store, node):
678 ListWindow.__init__(self, player, store, node)
679 self._window.set_title("Talks")
682 def _get_columns(cls):
683 yield gobject.TYPE_PYOBJECT, None
685 textrenderer = gtk.CellRendererText()
686 column = gtk.TreeViewColumn("Talk")
687 column.pack_start(textrenderer, expand=True)
688 column.add_attribute(textrenderer, "text", 1)
689 yield gobject.TYPE_STRING, column
691 def _get_current_row(self):
692 # @todo Not implemented yet
696 ListWindow._refresh(self)
697 self._node.get_children(
698 self._on_conference_talks,
702 @misc_utils.log_exception(_moduleLogger)
703 def _on_conference_talks(self, programs):
704 if self._isDestroyed:
705 _moduleLogger.info("Download complete but window destroyed")
709 for programNode in programs:
710 program = programNode.get_properties()
711 row = programNode, "%s\n%s" % (program["title"], program["speaker"])
712 self._model.append(row)
714 path = (self._get_current_row(), )
715 self._treeView.scroll_to_cell(path)
716 self._treeView.get_selection().select_path(path)
718 @misc_utils.log_exception(_moduleLogger)
719 def _on_error(self, exception):
721 self._errorBanner.push_message(str(exception))
723 @misc_utils.log_exception(_moduleLogger)
724 def _on_row_activated(self, view, path, column):
725 itr = self._model.get_iter(path)
726 node = self._model.get_value(itr, 0)
728 sessionsWindow = ConferenceTalkWindow(self._player, self._store, node)
729 sessionsWindow.window.set_modal(True)
730 sessionsWindow.window.set_transient_for(self._window)
731 sessionsWindow.window.set_default_size(*self._window.get_size())
732 sessionsWindow.connect("quit", self._on_quit)
733 sessionsWindow.connect("home", self._on_home)
734 sessionsWindow.show()
737 gobject.type_register(ConferenceTalksWindow)
740 class ConferenceTalkWindow(BasicWindow):
742 def __init__(self, player, store, node):
743 BasicWindow.__init__(self, player, store)
745 self._player.connect("state-change", self._on_player_state_change)
746 self._player.connect("title-change", self._on_player_title_change)
748 self._loadingBanner = banners.GenericBanner()
750 self._presenter = presenter.StreamPresenter(self._store)
751 self._presenterNavigation = presenter.NavigationBox()
752 self._presenterNavigation.toplevel.add(self._presenter.toplevel)
753 self._presenterNavigation.connect("action", self._on_nav_action)
754 self._presenterNavigation.connect("navigating", self._on_navigating)
756 self._layout.pack_start(self._loadingBanner.toplevel, False, False)
757 self._layout.pack_start(self._presenterNavigation.toplevel, True, True)
759 self._window.set_title("Talk")
762 BasicWindow.show(self)
763 self._window.show_all()
764 self._errorBanner.toplevel.hide()
765 self._loadingBanner.toplevel.hide()
767 self._presenter.set_context(
768 self._store.STORE_LOOKUP["conference_background"],
770 self._player.subtitle,
772 if self._player.state == "play":
773 self._presenter.set_state(self._store.STORE_LOOKUP["play"])
775 self._presenter.set_state(self._store.STORE_LOOKUP["pause"])
777 def _show_loading(self):
778 animationPath = self._store.STORE_LOOKUP["loading"]
779 animation = self._store.get_pixbuf_animation_from_store(animationPath)
780 self._loadingBanner.show(animation, "Loading...")
782 def _hide_loading(self):
783 self._loadingBanner.hide()
785 @misc_utils.log_exception(_moduleLogger)
786 def _on_player_state_change(self, player, newState):
787 if self._headerNavigation.is_active() or self._presenterNavigation.is_active():
790 if newState == "play":
791 self._presenter.set_state(self._store.STORE_LOOKUP["play"])
792 elif newState == "pause":
793 self._presenter.set_state(self._store.STORE_LOOKUP["pause"])
795 _moduleLogger.info("Unhandled player state %s" % newState)
796 self._presenter.set_state(self._store.STORE_LOOKUP["pause"])
798 @misc_utils.log_exception(_moduleLogger)
799 def _on_player_title_change(self, player, newState):
800 self._presenter.set_context(
801 self._store.STORE_LOOKUP["conference_background"],
803 self._player.subtitle,
806 @misc_utils.log_exception(_moduleLogger)
807 def _on_navigating(self, widget, navState):
808 if navState == "clicking":
809 if self._player.state == "play":
813 elif navState == "down":
815 elif navState == "up":
817 elif navState == "left":
819 elif navState == "right":
822 self._presenter.set_state(self._store.STORE_LOOKUP[imageName])
824 @misc_utils.log_exception(_moduleLogger)
825 def _on_nav_action(self, widget, navState):
826 if self._player.state == "play":
827 self._presenter.set_state(self._store.STORE_LOOKUP["play"])
829 self._presenter.set_state(self._store.STORE_LOOKUP["pause"])
831 if navState == "clicking":
832 if self._player.state == "play":
836 elif navState == "down":
838 self._window.destroy()
839 elif navState == "up":
841 elif navState == "left":
843 elif navState == "right":
847 gobject.type_register(ConferenceTalkWindow)