Making text on lists more thumb friendly
[watersofshiloah] / src / windows / magazines.py
index aa6bead..32c72d5 100644 (file)
@@ -18,18 +18,28 @@ _moduleLogger = logging.getLogger(__name__)
 
 class MagazinesWindow(windows._base.ListWindow):
 
-       def __init__(self, player, store, node):
-               windows._base.ListWindow.__init__(self, player, store, node)
+       def __init__(self, app, player, store, node):
+               windows._base.ListWindow.__init__(self, app, player, store, node)
                self._window.set_title(self._node.title)
 
        @classmethod
        def _get_columns(cls):
                yield gobject.TYPE_PYOBJECT, None
 
+               pixrenderer = gtk.CellRendererPixbuf()
+               column = gtk.TreeViewColumn("Covers")
+               column.set_property("sizing", gtk.TREE_VIEW_COLUMN_FIXED)
+               column.set_property("fixed-width", 96)
+               column.pack_start(pixrenderer, expand=True)
+               column.add_attribute(pixrenderer, "pixbuf", 1)
+               yield gobject.TYPE_OBJECT, column
+
                textrenderer = gtk.CellRendererText()
+               hildonize.set_cell_thumb_selectable(textrenderer)
                column = gtk.TreeViewColumn("Magazine")
+               column.set_property("sizing", gtk.TREE_VIEW_COLUMN_FIXED)
                column.pack_start(textrenderer, expand=True)
-               column.add_attribute(textrenderer, "text", 1)
+               column.add_attribute(textrenderer, "text", 2)
                yield gobject.TYPE_STRING, column
 
        def _refresh(self):
@@ -46,20 +56,45 @@ class MagazinesWindow(windows._base.ListWindow):
                        return
 
                self._hide_loading()
-               for programNode in programs:
+               for i, programNode in enumerate(programs):
                        program = programNode.get_properties()
-                       row = programNode, program["title"]
+                       img = self._store.get_pixbuf_from_store(self._store.STORE_LOOKUP["nomagazineimage"])
+                       row = programNode, img, program["title"]
                        self._model.append(row)
 
+                       programNode.get_children(self._create_on_issues(i), self._on_error)
+
                self._select_row()
 
+       def _create_on_issues(self, row):
+               return lambda issues: self._on_issues(row, issues)
+
+       @misc_utils.log_exception(_moduleLogger)
+       def _on_issues(self, row, issues):
+               for issue in issues:
+                       self._store.get_pixbuf_from_url(
+                               issue.get_properties()["pictureURL"],
+                               lambda pix: self._on_image(row, pix),
+                               self._on_error,
+                       )
+                       break
+               else:
+                       _moduleLogger.info("No issues for magazine %s" % row)
+
+       @misc_utils.log_exception(_moduleLogger)
+       def _on_image(self, row, pix):
+               treeiter = self._model.iter_nth_child(None, row)
+               self._model.set_value(treeiter, 1, pix)
+               treeiter = self._model.iter_nth_child(None, row)
+               self._model.row_changed((row, ), treeiter)
+
        @misc_utils.log_exception(_moduleLogger)
        def _on_error(self, exception):
                self._hide_loading()
                self._errorBanner.push_message(str(exception))
 
        def _window_from_node(self, node):
-               issuesWindow = MagazineIssuesWindow(self._player, self._store, node)
+               issuesWindow = MagazineIssuesWindow(self._app, self._player, self._store, node)
                issuesWindow.window.set_modal(True)
                issuesWindow.window.set_transient_for(self._window)
                issuesWindow.window.set_default_size(*self._window.get_size())
@@ -81,18 +116,28 @@ gobject.type_register(MagazinesWindow)
 
 class MagazineIssuesWindow(windows._base.ListWindow):
 
-       def __init__(self, player, store, node):
-               windows._base.ListWindow.__init__(self, player, store, node)
+       def __init__(self, app, player, store, node):
+               windows._base.ListWindow.__init__(self, app, player, store, node)
                self._window.set_title(self._node.title)
 
        @classmethod
        def _get_columns(cls):
                yield gobject.TYPE_PYOBJECT, None
 
+               pixrenderer = gtk.CellRendererPixbuf()
+               column = gtk.TreeViewColumn("Covers")
+               column.set_property("sizing", gtk.TREE_VIEW_COLUMN_FIXED)
+               column.set_property("fixed-width", 96)
+               column.pack_start(pixrenderer, expand=True)
+               column.add_attribute(pixrenderer, "pixbuf", 1)
+               yield gobject.TYPE_OBJECT, column
+
                textrenderer = gtk.CellRendererText()
+               hildonize.set_cell_thumb_selectable(textrenderer)
                column = gtk.TreeViewColumn("Issue")
+               column.set_property("sizing", gtk.TREE_VIEW_COLUMN_FIXED)
                column.pack_start(textrenderer, expand=True)
-               column.add_attribute(textrenderer, "text", 1)
+               column.add_attribute(textrenderer, "text", 2)
                yield gobject.TYPE_STRING, column
 
        def _refresh(self):
@@ -111,9 +156,16 @@ class MagazineIssuesWindow(windows._base.ListWindow):
                self._hide_loading()
                for programNode in programs:
                        program = programNode.get_properties()
-                       row = programNode, program["title"]
+                       img = self._store.get_pixbuf_from_store(self._store.STORE_LOOKUP["nomagazineimage"])
+                       row = programNode, img, program["title"]
                        self._model.append(row)
 
+                       self._store.get_pixbuf_from_url(
+                               program["pictureURL"],
+                               self._create_on_image(programNode),
+                               self._on_error,
+                       )
+
                self._select_row()
 
        @misc_utils.log_exception(_moduleLogger)
@@ -121,8 +173,23 @@ class MagazineIssuesWindow(windows._base.ListWindow):
                self._hide_loading()
                self._errorBanner.push_message(str(exception))
 
+       def _create_on_image(self, programNode):
+               return lambda pix: self._on_image(programNode, pix)
+
+       @misc_utils.log_exception(_moduleLogger)
+       def _on_image(self, childNode, pix):
+               for i, row in enumerate(self._model):
+                       if row[0] is childNode:
+                               break
+               else:
+                       raise RuntimeError("Could not find %r" % childNode)
+               treeiter = self._model.iter_nth_child(None, i)
+               self._model.set_value(treeiter, 1, pix)
+               treeiter = self._model.iter_nth_child(None, i)
+               self._model.row_changed((i, ), treeiter)
+
        def _window_from_node(self, node):
-               issuesWindow = MagazineArticlesWindow(self._player, self._store, node)
+               issuesWindow = MagazineArticlesWindow(self._app, self._player, self._store, node)
                issuesWindow.window.set_modal(True)
                issuesWindow.window.set_transient_for(self._window)
                issuesWindow.window.set_default_size(*self._window.get_size())
@@ -144,8 +211,8 @@ gobject.type_register(MagazineIssuesWindow)
 
 class MagazineArticlesWindow(windows._base.ListWindow):
 
-       def __init__(self, player, store, node):
-               windows._base.ListWindow.__init__(self, player, store, node)
+       def __init__(self, app, player, store, node):
+               windows._base.ListWindow.__init__(self, app, player, store, node)
                self._window.set_title(self._node.title)
 
        @classmethod
@@ -153,7 +220,9 @@ class MagazineArticlesWindow(windows._base.ListWindow):
                yield gobject.TYPE_PYOBJECT, None
 
                textrenderer = gtk.CellRendererText()
+               hildonize.set_cell_thumb_selectable(textrenderer)
                column = gtk.TreeViewColumn("Article")
+               column.set_property("sizing", gtk.TREE_VIEW_COLUMN_FIXED)
                column.pack_start(textrenderer, expand=True)
                column.add_attribute(textrenderer, "text", 1)
                yield gobject.TYPE_STRING, column
@@ -185,7 +254,7 @@ class MagazineArticlesWindow(windows._base.ListWindow):
                self._errorBanner.push_message(str(exception))
 
        def _window_from_node(self, node):
-               issuesWindow = MagazineArticleWindow(self._player, self._store, node)
+               issuesWindow = MagazineArticleWindow(self._app, self._player, self._store, node)
                issuesWindow.window.set_modal(True)
                issuesWindow.window.set_transient_for(self._window)
                issuesWindow.window.set_default_size(*self._window.get_size())
@@ -207,8 +276,8 @@ gobject.type_register(MagazineArticlesWindow)
 
 class MagazineArticleWindow(windows._base.BasicWindow):
 
-       def __init__(self, player, store, node):
-               windows._base.BasicWindow.__init__(self, player, store)
+       def __init__(self, app, player, store, node):
+               windows._base.BasicWindow.__init__(self, app, player, store)
                self._node = node
                self._playerNode = self._player.node
                self._nextSearch = None
@@ -282,20 +351,23 @@ class MagazineArticleWindow(windows._base.BasicWindow):
 
        @misc_utils.log_exception(_moduleLogger)
        def _on_player_update_seek(self):
+               if self._isDestroyed:
+                       return False
                self._seekbar.set_value(self._player.percent_elapsed * 100)
-               return True if not self._isDestroyed else False
+               return True
 
        @misc_utils.log_exception(_moduleLogger)
        def _on_player_state_change(self, player, newState):
                if self._active and self._player.state == self._player.STATE_PLAY:
                        self._seekbar.show()
                        assert self._updateSeek is None
-                       self._updateSeek = go_utils.Timeout(self._updateSeek, once=False)
-                       self._updateSeek.start(seconds=30)
+                       self._updateSeek = go_utils.Timeout(self._on_player_update_seek, once=False)
+                       self._updateSeek.start(seconds=1)
                else:
                        self._seekbar.hide()
-                       self._updateSeek.cancel()
-                       self._updateSeek = None
+                       if self._updateSeek is not None:
+                               self._updateSeek.cancel()
+                               self._updateSeek = None
 
                if not self._presenterNavigation.is_active():
                        self._set_context(newState)