7 import util.go_utils as go_utils
8 import util.misc as misc_utils
16 _moduleLogger = logging.getLogger(__name__)
19 class ConferencesWindow(windows._base.ListWindow):
21 def __init__(self, player, store, node):
22 windows._base.ListWindow.__init__(self, player, store, node)
23 self._window.set_title(self._node.title)
26 def _get_columns(cls):
27 yield gobject.TYPE_PYOBJECT, None
29 textrenderer = gtk.CellRendererText()
30 column = gtk.TreeViewColumn("Date")
31 column.pack_start(textrenderer, expand=True)
32 column.add_attribute(textrenderer, "text", 1)
33 yield gobject.TYPE_STRING, column
35 textrenderer = gtk.CellRendererText()
36 column = gtk.TreeViewColumn("Conference")
37 column.pack_start(textrenderer, expand=True)
38 column.add_attribute(textrenderer, "text", 2)
39 yield gobject.TYPE_STRING, column
42 windows._base.ListWindow._refresh(self)
43 self._node.get_children(
48 @misc_utils.log_exception(_moduleLogger)
49 def _on_conferences(self, programs):
51 _moduleLogger.info("Download complete but window destroyed")
55 for programNode in programs:
56 program = programNode.get_properties()
57 row = programNode, program["title"], program["full_title"]
58 self._model.append(row)
62 @misc_utils.log_exception(_moduleLogger)
63 def _on_error(self, exception):
65 self._errorBanner.push_message(str(exception))
67 def _window_from_node(self, node):
68 sessionsWindow = ConferenceSessionsWindow(self._player, self._store, node)
69 sessionsWindow.window.set_modal(True)
70 sessionsWindow.window.set_transient_for(self._window)
71 sessionsWindow.window.set_default_size(*self._window.get_size())
72 sessionsWindow.connect("quit", self._on_quit)
73 sessionsWindow.connect("home", self._on_home)
74 sessionsWindow.connect("jump-to", self._on_jump)
78 @misc_utils.log_exception(_moduleLogger)
79 def _on_row_activated(self, view, path, column):
80 itr = self._model.get_iter(path)
81 node = self._model.get_value(itr, 0)
82 self._window_from_node(node)
85 gobject.type_register(ConferencesWindow)
88 class ConferenceSessionsWindow(windows._base.ListWindow):
90 def __init__(self, player, store, node):
91 windows._base.ListWindow.__init__(self, player, store, node)
92 self._window.set_title(self._node.title)
95 def _get_columns(cls):
96 yield gobject.TYPE_PYOBJECT, None
98 textrenderer = gtk.CellRendererText()
99 column = gtk.TreeViewColumn("Session")
100 column.pack_start(textrenderer, expand=True)
101 column.add_attribute(textrenderer, "text", 1)
102 yield gobject.TYPE_STRING, column
105 windows._base.ListWindow._refresh(self)
106 self._node.get_children(
107 self._on_conference_sessions,
111 @misc_utils.log_exception(_moduleLogger)
112 def _on_conference_sessions(self, programs):
113 if self._isDestroyed:
114 _moduleLogger.info("Download complete but window destroyed")
118 for programNode in programs:
119 program = programNode.get_properties()
120 row = programNode, program["title"]
121 self._model.append(row)
125 @misc_utils.log_exception(_moduleLogger)
126 def _on_error(self, exception):
128 self._errorBanner.push_message(str(exception))
130 def _window_from_node(self, node):
131 sessionsWindow = ConferenceTalksWindow(self._player, self._store, node)
132 sessionsWindow.window.set_modal(True)
133 sessionsWindow.window.set_transient_for(self._window)
134 sessionsWindow.window.set_default_size(*self._window.get_size())
135 sessionsWindow.connect("quit", self._on_quit)
136 sessionsWindow.connect("home", self._on_home)
137 sessionsWindow.connect("jump-to", self._on_jump)
138 sessionsWindow.show()
139 return sessionsWindow
141 @misc_utils.log_exception(_moduleLogger)
142 def _on_row_activated(self, view, path, column):
143 itr = self._model.get_iter(path)
144 node = self._model.get_value(itr, 0)
145 self._window_from_node(node)
148 gobject.type_register(ConferenceSessionsWindow)
151 class ConferenceTalksWindow(windows._base.ListWindow):
153 def __init__(self, player, store, node):
154 windows._base.ListWindow.__init__(self, player, store, node)
155 self._window.set_title(self._node.title)
158 def _get_columns(cls):
159 yield gobject.TYPE_PYOBJECT, None
161 textrenderer = gtk.CellRendererText()
162 column = gtk.TreeViewColumn("Talk")
163 column.pack_start(textrenderer, expand=True)
164 column.add_attribute(textrenderer, "text", 1)
165 yield gobject.TYPE_STRING, column
168 windows._base.ListWindow._refresh(self)
169 self._node.get_children(
170 self._on_conference_talks,
174 @misc_utils.log_exception(_moduleLogger)
175 def _on_conference_talks(self, programs):
176 if self._isDestroyed:
177 _moduleLogger.info("Download complete but window destroyed")
181 for programNode in programs:
182 program = programNode.get_properties()
183 row = programNode, "%s\n%s" % (program["title"], program["speaker"])
184 self._model.append(row)
188 @misc_utils.log_exception(_moduleLogger)
189 def _on_error(self, exception):
191 self._errorBanner.push_message(str(exception))
193 def _window_from_node(self, node):
194 sessionsWindow = ConferenceTalkWindow(self._player, self._store, node)
195 sessionsWindow.window.set_modal(True)
196 sessionsWindow.window.set_transient_for(self._window)
197 sessionsWindow.window.set_default_size(*self._window.get_size())
198 sessionsWindow.connect("quit", self._on_quit)
199 sessionsWindow.connect("home", self._on_home)
200 sessionsWindow.connect("jump-to", self._on_jump)
201 sessionsWindow.show()
202 return sessionsWindow
204 @misc_utils.log_exception(_moduleLogger)
205 def _on_row_activated(self, view, path, column):
206 itr = self._model.get_iter(path)
207 node = self._model.get_value(itr, 0)
208 self._window_from_node(node)
211 gobject.type_register(ConferenceTalksWindow)
214 class ConferenceTalkWindow(windows._base.BasicWindow):
216 def __init__(self, player, store, node):
217 windows._base.BasicWindow.__init__(self, player, store)
219 self._playerNode = self._player.node
220 self._nextSearch = None
221 self._updateSeek = None
223 self.connect_auto(self._player, "state-change", self._on_player_state_change)
224 self.connect_auto(self._player, "title-change", self._on_player_title_change)
225 self.connect_auto(self._player, "error", self._on_player_error)
227 self._loadingBanner = banners.GenericBanner()
229 self._presenter = presenter.StreamPresenter(self._store)
230 self._presenter.set_context(
231 self._store.STORE_LOOKUP["conference_background"],
235 self._presenterNavigation = presenter.NavigationBox()
236 self._presenterNavigation.toplevel.add(self._presenter.toplevel)
237 self._presenterNavigation.connect("action", self._on_nav_action)
238 self._presenterNavigation.connect("navigating", self._on_navigating)
240 self._seekbar = hildonize.create_seekbar()
241 self._seekbar.connect("change-value", self._on_user_seek)
243 self._layout.pack_start(self._loadingBanner.toplevel, False, False)
244 self._layout.pack_start(self._presenterNavigation.toplevel, True, True)
245 self._layout.pack_start(self._seekbar, False, False)
247 self._window.set_title(self._node.title)
250 windows._base.BasicWindow.show(self)
251 self._window.show_all()
252 self._errorBanner.toplevel.hide()
253 self._loadingBanner.toplevel.hide()
254 self._set_context(self._player.state)
257 def jump_to(self, node):
258 assert self._node is node
262 return self._playerNode is self._node
264 def _show_loading(self):
265 animationPath = self._store.STORE_LOOKUP["loading"]
266 animation = self._store.get_pixbuf_animation_from_store(animationPath)
267 self._loadingBanner.show(animation, "Loading...")
269 def _hide_loading(self):
270 self._loadingBanner.hide()
272 def _set_context(self, state):
273 if state == self._player.STATE_PLAY:
275 self._presenter.set_state(self._store.STORE_LOOKUP["pause"])
277 self._presenter.set_state(self._store.STORE_LOOKUP["play"])
278 elif state == self._player.STATE_PAUSE:
279 self._presenter.set_state(self._store.STORE_LOOKUP["play"])
280 elif state == self._player.STATE_STOP:
281 self._presenter.set_state(self._store.STORE_LOOKUP["play"])
283 _moduleLogger.info("Unhandled player state %s" % state)
285 @misc_utils.log_exception(_moduleLogger)
286 def _on_user_seek(self, widget, scroll, value):
287 self._player.seek(value / 100.0)
289 @misc_utils.log_exception(_moduleLogger)
290 def _on_player_update_seek(self):
291 if self._isDestroyed:
293 self._seekbar.set_value(self._player.percent_elapsed * 100)
296 @misc_utils.log_exception(_moduleLogger)
297 def _on_player_state_change(self, player, newState):
298 if self._active and self._player.state == self._player.STATE_PLAY:
300 assert self._updateSeek is None
301 self._updateSeek = go_utils.Timeout(self._on_player_update_seek, once=False)
302 self._updateSeek.start(seconds=1)
305 self._updateSeek.cancel()
306 self._updateSeek = None
308 if not self._presenterNavigation.is_active():
309 self._set_context(newState)
311 @misc_utils.log_exception(_moduleLogger)
312 def _on_player_title_change(self, player, node):
313 if not self._active or node in [None, self._node]:
314 self._playerNode = player.node
316 self._playerNode = player.node
317 self.emit("jump-to", node)
318 self._window.destroy()
320 @misc_utils.log_exception(_moduleLogger)
321 def _on_player_error(self, player, err, debug):
322 _moduleLogger.error("%r - %r" % (err, debug))
324 @misc_utils.log_exception(_moduleLogger)
325 def _on_navigating(self, widget, navState):
326 if navState == "clicking":
327 if self._player.state == self._player.STATE_PLAY:
329 imageName = "pause_pressed"
331 imageName = "play_pressed"
332 elif self._player.state == self._player.STATE_PAUSE:
333 imageName = "play_pressed"
334 elif self._player.state == self._player.STATE_STOP:
335 imageName = "play_pressed"
337 _moduleLogger.info("Unhandled player state %s" % self._player.state)
338 elif navState == "down":
340 elif navState == "up":
341 if self._player.state == self._player.STATE_PLAY:
346 elif self._player.state == self._player.STATE_PAUSE:
348 elif self._player.state == self._player.STATE_STOP:
351 _moduleLogger.info("Unhandled player state %s" % self._player.state)
352 elif navState == "left":
354 elif navState == "right":
357 self._presenter.set_state(self._store.STORE_LOOKUP[imageName])
359 @misc_utils.log_exception(_moduleLogger)
360 def _on_nav_action(self, widget, navState):
361 self._set_context(self._player.state)
363 if navState == "clicking":
364 if self._player.state == self._player.STATE_PLAY:
368 self._player.set_piece_by_node(self._node)
370 elif self._player.state == self._player.STATE_PAUSE:
372 elif self._player.state == self._player.STATE_STOP:
373 self._player.set_piece_by_node(self._node)
376 _moduleLogger.info("Unhandled player state %s" % self._player.state)
377 elif navState == "down":
379 self._window.destroy()
380 elif navState == "up":
382 elif navState == "left":
386 assert self._nextSearch is None
387 self._nextSearch = stream_index.AsyncWalker(stream_index.get_next)
388 self._nextSearch.start(self._node, self._on_next_node, self._on_node_search_error)
389 elif navState == "right":
393 assert self._nextSearch is None
394 self._nextSearch = stream_index.AsyncWalker(stream_index.get_previous)
395 self._nextSearch.start(self._node, self._on_next_node, self._on_node_search_error)
397 @misc_utils.log_exception(_moduleLogger)
398 def _on_next_node(self, node):
399 self._nextSearch = None
400 self.emit("jump-to", node)
401 self._window.destroy()
403 @misc_utils.log_exception(_moduleLogger)
404 def _on_node_search_error(self, e):
405 self._nextSearch = None
406 self._errorBanner.push_message(str(e))
409 gobject.type_register(ConferenceTalkWindow)