fix next/previous in entry view
[vuplus_dvbapp-plugin] / simplerss / src / RSSScreens.py
index 8038388..fea8a5e 100644 (file)
@@ -1,26 +1,57 @@
+# for localized messages
+from . import _
+
 from enigma import eTimer
 
 from Screens.Screen import Screen
 from Screens.MessageBox import MessageBox
-from Screens.ChoiceBox import ChoiceBox
-
-from Components.Scanner import openList
 
 from Components.ActionMap import ActionMap
-from Components.Label import Label
 from Components.ScrollLabel import ScrollLabel
+from Components.Sources.List import List
+from Components.Sources.StaticText import StaticText
 
-from RSSList import RSSFeedList, RSSEntryList
-from RSSSetup import RSSSetup
+from RSSList import RSSFeedList
+
+class RSSSummary(Screen):
+       skin = """
+       <screen position="0,0" size="132,64">
+               <widget source="parent.title" render="Label" position="6,4" size="120,21" font="Regular;18" />
+               <widget source="entry" render="Label" position="6,25" size="120,21" font="Regular;16" />
+               <widget source="global.CurrentTime" render="Label" position="56,46" size="82,18" font="Regular;16" >
+                       <convert type="ClockToText">WithSeconds</convert>
+               </widget>
+       </screen>"""
+
+       def __init__(self, session, parent):
+               Screen.__init__(self, session, parent = parent)
+               self["entry"] = StaticText("")
+               parent.onChangedEntry.append(self.selectionChanged)
+               self.onShow.append(parent.updateInfo)
+               self.onClose.append(self.removeWatcher)
+
+       def removeWatcher(self):
+               self.parent.onChangedEntry.remove(self.selectionChanged)
+
+       def selectionChanged(self, text):
+               self["entry"].text = text
 
 class RSSBaseView(Screen):
        """Base Screen for all Screens used in SimpleRSS"""
 
-       def __init__(self, session, poller, parent=None):
-               Screen.__init__(self, session)
+       def __init__(self, session, poller, parent = None):
+               Screen.__init__(self, session, parent)
+               self["title"] = StaticText()
+               self.onChangedEntry = []
                self.rssPoller = poller
                self.pollDialog = None
-               self.parent = parent
+
+       def createSummary(self):
+               return RSSSummary
+
+       def setTitle(self, title):
+               Screen.setTitle(self, title)
+               self["title"].text = title
 
        def errorPolling(self, errmsg = ""):
                # An error occured while polling
@@ -62,19 +93,22 @@ class RSSBaseView(Screen):
                if enclosures is None:
                        return
 
+               from Components.Scanner import openList
+
                if not openList(self.session, enclosures):
                        self.session.open(
                                MessageBox,
                                _("Found no Enclosure we can display."),
-                               type = MessageBox.TYPE_INFO, 
+                               type = MessageBox.TYPE_INFO,
                                timeout = 5
                        )
 
 class RSSEntryView(RSSBaseView):
        """Shows a RSS Item"""
+
        skin = """
-               <screen position="100,100" size="460,420" title="Simple RSS Reader" >
-                       <widget name="info" position="0,0" size="460, 20" halign="right" font="Regular; 18" />
+               <screen position="center,center" size="460,420" title="Simple RSS Reader" >
+                       <widget source="info" render="Label" position="0,0" size="460, 20" halign="right" font="Regular; 18" />
                        <widget name="content" position="0,20" size="460,400" font="Regular; 22" />
                </screen>"""
 
@@ -87,12 +121,12 @@ class RSSEntryView(RSSBaseView):
                self.entries = entries
 
                if cur_idx is not None and entries is not None:
-                       self["info"] = Label(_("Entry %s/%s") % (cur_idx+1, entries))
+                       self["info"] = StaticText(_("Entry %s/%s") % (cur_idx+1, entries))
                else:
-                       self["info"] = Label()
+                       self["info"] = StaticText()
 
-               if data is not None:
-                       self["content"] = ScrollLabel("\n\n".join([data[0], data[2], " ".join([str(len(data[3])), "Enclosures"])]))
+               if data:
+                       self["content"] = ScrollLabel(''.join((data[0], '\n\n', data[2], '\n\n', str(len(data[3])), ' ',  _("Enclosures"))))
                else:
                        self["content"] = ScrollLabel()
 
@@ -112,7 +146,19 @@ class RSSEntryView(RSSBaseView):
                self.onLayoutFinish.append(self.setConditionalTitle)
 
        def setConditionalTitle(self):
-               self.setTitle(': '.join(["Simple RSS Reader", self.feedTitle]))
+               self.setTitle(_("Simple RSS Reader: %s") % (self.feedTitle))
+
+       def updateInfo(self):
+               if self.data:
+                       text = self.data[0]
+               else:
+                       text = _("No such Item.")
+
+               for x in self.onChangedEntry:
+                       try:
+                               x(text)
+                       except Exception:
+                               pass
 
        def up(self):
                self["content"].pageUp()
@@ -162,13 +208,15 @@ class RSSEntryView(RSSBaseView):
 
        def setContent(self):
                if self.cur_idx is not None and self.entries is not None:
-                       self["info"].setText(_("Entry %s/%s") % (self.cur_idx+1, self.entries))
+                       self["info"].text = _("Entry %s/%s") % (self.cur_idx+1, self.entries)
                else:
-                       self["info"].setText("")
-               if self.data is not None:
-                       self["content"].setText("\n\n".join([self.data[0], self.data[2], " ".join([str(len(self.data[3])), _("Enclosures")])]))
+                       self["info"].text = ""
+               data = self.data
+               if data:
+                       self["content"].setText(''.join((data[0], '\n\n', data[2], '\n\n', str(len(data[3])), ' ',  _("Enclosures"))))
                else:
                        self["content"].setText(_("No such Item."))
+               self.updateInfo()
 
        def selectEnclosure(self):
                if self.data is not None:
@@ -176,11 +224,21 @@ class RSSEntryView(RSSBaseView):
 
 class RSSFeedView(RSSBaseView):
        """Shows a RSS-Feed"""
+
        skin = """
-               <screen position="100,100" size="460,415" title="Simple RSS Reader" >
-                       <widget name="info" position="0,0" size="460,20" halign="right" font="Regular; 18" />
-                       <widget name="content" position="0,20" size="460,300" scrollbarMode="showOnDemand" />
-                       <widget name="summary" position="0,320" size="460,95" font="Regular;16" />
+               <screen position="center,center" size="460,415" title="Simple RSS Reader" >
+                       <widget source="info" render="Label" position="0,0" size="460,20" halign="right" font="Regular; 18" />
+                       <widget source="content" render="Listbox" position="0,20" size="460,300" scrollbarMode="showOnDemand">
+                               <convert type="TemplatedMultiContent">
+                                       {"template": [
+                                                       MultiContentEntryText(pos=(0, 3), size=(460, 294), font=0, flags = RT_HALIGN_LEFT|RT_WRAP, text = 0)
+                                               ],
+                                        "fonts": [gFont("Regular", 22)],
+                                        "itemHeight": 50
+                                       }
+                               </convert>
+                       </widget>
+                       <widget source="summary" render="Label" position="0,320" size="460,95" font="Regular;16" />
                </screen>"""
 
        def __init__(self, session, feed=None, newItems=False, parent=None, rssPoller=None,id=None):
@@ -190,12 +248,12 @@ class RSSFeedView(RSSBaseView):
                self.newItems = newItems
                self.id = id
 
-               self["content"] = RSSEntryList(self.feed.history)
-               self["summary"] = Label()
-               self["info"] = Label()
+               self["content"] = List(self.feed.history)
+               self["summary"] = StaticText()
+               self["info"] = StaticText()
 
                if not newItems:
-                       self["actions"] = ActionMap([ "OkCancelActions", "ChannelSelectBaseActions", "MenuActions", "ColorActions" ], 
+                       self["actions"] = ActionMap([ "OkCancelActions", "ChannelSelectBaseActions", "MenuActions", "ColorActions" ],
                        {
                                "ok": self.showCurrentEntry,
                                "cancel": self.close,
@@ -209,7 +267,7 @@ class RSSFeedView(RSSBaseView):
 
                        self.timer = None
                else:
-                       self["actions"] = ActionMap([ "OkCancelActions" ], 
+                       self["actions"] = ActionMap([ "OkCancelActions" ],
                        {
                                "cancel": self.close,
                        })
@@ -218,15 +276,17 @@ class RSSFeedView(RSSBaseView):
                        self.timer.callback.append(self.timerTick)
                        self.onExecBegin.append(self.startTimer)
 
-               self["content"].connectSelChanged(self.updateInfo)
-               self.onLayoutFinish.extend([self.updateInfo, self.setConditionalTitle])
+               self["content"].onSelectionChanged.append(self.updateInfo)
+               self.onLayoutFinish.extend((
+                       self.updateInfo,
+                       self.setConditionalTitle
+               ))
 
        def startTimer(self):
                self.timer.startLongTimer(5)
 
        def timerTick(self):
                self.timer.callback.remove(self.timerTick)
-               self.timer = None
 
                self.close()
 
@@ -243,50 +303,51 @@ class RSSFeedView(RSSBaseView):
                print "[SimpleRSS] SimpleRSSFeed called back"
 
                if id is None or id+1 == self.id:
-                       # TODO: do we really need this?
-                       current_entry = self["content"].getCurrentEntry()
-                       self["content"].moveToEntry(current_entry)
-
-                       self["content"].invalidate()
+                       self["content"].updateList(self.feed.history)
                        self.setConditionalTitle()
                        self.updateInfo()
 
        def setConditionalTitle(self):
-               self.setTitle(': '.join(["Simple RSS Reader", self.feed.title]))
+               self.setTitle(_("Simple RSS Reader: %s") % (self.feed.title))
 
        def updateInfo(self):
-               current_entry = self["content"].getCurrentEntry()
+               current_entry = self["content"].current
                if current_entry:
-                       self["summary"].setText(current_entry[2])
+                       self["summary"].text = current_entry[2]
 
-                       cur_idx = self["content"].getCurrentIndex()
-                       self["info"].setText(_("Entry %s/%s") % (cur_idx+1, len(self.feed.history)))
+                       cur_idx = self["content"].index
+                       self["info"].text = _("Entry %s/%s") % (cur_idx+1, len(self.feed.history))
+                       summary_text = current_entry[0]
                else:
-                       self["summary"].setText(_("Feed is empty."))
-                       self["info"].setText("")
+                       self["summary"].text = _("Feed is empty.")
+                       self["info"].text = ""
+                       summary_text = _("Feed is empty.")
+
+               for x in self.onChangedEntry:
+                       try:
+                               x(summary_text)
+                       except Exception:
+                               pass
 
        def menu(self):
                if self.id > 0:
                        self.singleUpdate(self.id-1)
 
        def nextEntry(self):
-               self["content"].moveDown()
-               return (self["content"].getCurrentEntry(), self["content"].getCurrentIndex(), len(self.feed.history))
+               self["content"].selectNext()
+               return (self["content"].current, self["content"].index, len(self.feed.history))
 
        def previousEntry(self):
-               self["content"].moveUp()
-               return (self["content"].getCurrentEntry(), self["content"].getCurrentIndex(), len(self.feed.history))
+               self["content"].selectPrevious()
+               return (self["content"].current, self["content"].index, len(self.feed.history))
 
-       # TODO: Fix moving back to previously marked entry (same goes for self.previous)
        def next(self):
                # Show next Feed
                if self.parent is not None:
                        (self.feed, self.id) = self.parent.nextFeed()
-                       #current_entry = self["content"].getCurrentEntry()
-                       self["content"].l.setList(self.feed.history) # Update list
-                       self["content"].moveToIndex(0)
-                       #self["content"].moveToEntry(current_entry)
-                       self.updateInfo() # In case entry is no longer in history
+                       self["content"].list = self.feed.history
+                       self["content"].index = 0
+                       self.updateInfo()
                        self.setConditionalTitle() # Update title
                        return (self.feed.title, self.feed.history, self.id)
                return (self.feed.title, self.feed.history, self.id)
@@ -295,11 +356,9 @@ class RSSFeedView(RSSBaseView):
                # Show previous Feed
                if self.parent is not None:
                        (self.feed, self.id) = self.parent.previousFeed()
-                       #current_entry = self["content"].getCurrentEntry()
-                       self["content"].l.setList(self.feed.history) # Update list
-                       self["content"].moveToIndex(0)
-                       #self["content"].moveToEntry(current_entry)
-                       self.updateInfo() # In case entry is no longer in history
+                       self["content"].list = self.feed.history
+                       self["content"].index = 0
+                       self.updateInfo()
                        self.setConditionalTitle() # Update title
                        return (self.feed.title, self.feed.history, self.id)
                return (self.feed.title, self.feed.history, self.id)
@@ -309,40 +368,41 @@ class RSSFeedView(RSSBaseView):
                        self.singleUpdate(self.id-1)
 
        def showCurrentEntry(self):
-               current_entry = self["content"].getCurrentEntry()
-               if current_entry is None: # empty list
+               current_entry = self["content"].current
+               if not current_entry: # empty list
                        return
 
                self.session.openWithCallback(
                        self.updateInfo,
                        RSSEntryView,
                        current_entry,
-                       cur_idx=self["content"].getCurrentIndex(),
-                       entries=len(self.feed.history),
-                       feedTitle=self.feed.title,
-                       parent=self
+                       cur_idx = self["content"].index,
+                       entries = len(self.feed.history),
+                       feedTitle = self.feed.title,
+                       parent = self
                )
 
        def selectEnclosure(self):
-               current_entry = self["content"].getCurrentEntry()
-               if current_entry is None: # empty list
+               current_entry = self["content"].current
+               if not current_entry: # empty list
                        return
 
                RSSBaseView.selectEnclosure(self, current_entry[3])
 
 class RSSOverview(RSSBaseView):
        """Shows an Overview over all RSS-Feeds known to rssPoller"""
+
        skin = """
-               <screen position="100,100" size="460,415" title="Simple RSS Reader" >
-                       <widget name="info" position="0,0" size="460,20" halign="right" font="Regular; 18" />
+               <screen position="center,center" size="460,415" title="Simple RSS Reader" >
+                       <widget source="info" render="Label" position="0,0" size="460,20" halign="right" font="Regular; 18" />
                        <widget name="content" position="0,20" size="460,300" scrollbarMode="showOnDemand" />
-                       <widget name="summary" position="0,320" size="460,95" font="Regular;16" />
+                       <widget source="summary" render="Label" position="0,320" size="460,95" font="Regular;16" />
                </screen>"""
 
        def __init__(self, session, poller):
                RSSBaseView.__init__(self, session, poller)
 
-               self["actions"] = ActionMap([ "OkCancelActions", "MenuActions", "ColorActions" ], 
+               self["actions"] = ActionMap([ "OkCancelActions", "MenuActions", "ColorActions" ],
                {
                        "ok": self.showCurrentEntry,
                        "cancel": self.close,
@@ -354,8 +414,8 @@ class RSSOverview(RSSBaseView):
 
                # We always have at least "New Items"-Feed
                self["content"] = RSSFeedList(self.feeds)
-               self["summary"] = Label(' '.join([str(len(self.feeds[0][0].history)), _("Entries")]))
-               self["info"] = Label(_("Feed %s/%s") % (1, len(self.feeds)))
+               self["summary"] = StaticText(' '.join((str(len(self.feeds[0][0].history)), _("Entries"))))
+               self["info"] = StaticText(_("Feed %s/%s") % (1, len(self.feeds)))
 
                self["content"].connectSelChanged(self.updateInfo)
                self.onLayoutFinish.append(self.__show)
@@ -363,6 +423,7 @@ class RSSOverview(RSSBaseView):
 
        def __show(self):
                self.rssPoller.addCallback(self.pollCallback)
+               self.setTitle(_("Simple RSS Reader"))
 
        def __close(self):
                self.rssPoller.removeCallback(self.pollCallback)
@@ -378,37 +439,49 @@ class RSSOverview(RSSBaseView):
                self["content"].invalidate()
 
        def updateInfo(self):
-               current_entry = self["content"].getCurrentEntry()
-               self["summary"].setText(' '.join([str(len(current_entry.history)), _("Entries")]))
-               self["info"].setText(_("Feed %s/%s") % (self["content"].getCurrentIndex()+1, len(self.feeds)))
+               current_entry = self["content"].getCurrent()
+               self["summary"].text = ' '.join((str(len(current_entry.history)), _("Entries")))
+               self["info"].text = _("Feed %s/%s") % (self["content"].getSelectedIndex()+1, len(self.feeds))
+               summary_text = current_entry.title
+
+               for x in self.onChangedEntry:
+                       try:
+                               x(summary_text)
+                       except Exception:
+                               pass
 
        def menu(self):
-               cur_idx = self["content"].getCurrentIndex()
+               from Screens.ChoiceBox import ChoiceBox
+
+               cur_idx = self["content"].getSelectedIndex()
                if cur_idx > 0:
-                       possible_actions = [
+                       possible_actions = (
                                (_("Update Feed"), "update"),
                                (_("Setup"), "setup"),
                                (_("Close"), "close")
-                       ]
+                       )
                else:
-                       possible_actions = [
+                       possible_actions = (
                                (_("Setup"), "setup"),
                                (_("Close"), "close")
-                       ]
+                       )
+
                self.session.openWithCallback(
                        self.menuChoice,
                        ChoiceBox,
-                       "What to do?",
+                       _("What to do?"),
                        possible_actions
                )
 
        def menuChoice(self, result):
                if result:
                        if result[1] == "update":
-                               cur_idx = self["content"].getCurrentIndex()
+                               cur_idx = self["content"].getSelectedIndex()
                                if cur_idx > 0:
                                        self.singleUpdate(cur_idx-1)
                        elif result[1] == "setup":
+                               from RSSSetup import RSSSetup
+
                                self.session.openWithCallback(
                                        self.refresh,
                                        RSSSetup,
@@ -418,36 +491,37 @@ class RSSOverview(RSSBaseView):
                                self.close()
 
        def refresh(self):
-               current_entry = self["content"].getCurrentEntry()
+               current_entry = self["content"].getCurrent()
 
                self.fillFeeds()
-               self["content"].l.setList(self.feeds)
+               self["content"].setList(self.feeds)
 
                self["content"].moveToEntry(current_entry)
                self.updateInfo()
 
        def nextFeed(self):
-               self["content"].moveUp()
-               return (self["content"].getCurrentEntry(), self["content"].getCurrentIndex())
+               self["content"].up()
+               return (self["content"].getCurrent(), self["content"].getSelectedIndex())
 
        def previousFeed(self):
-               self["content"].moveDown()
-               return (self["content"].getCurrentEntry(), self["content"].getCurrentIndex())
+               self["content"].down()
+               return (self["content"].getCurrent(), self["content"].getSelectedIndex())
 
        def showCurrentEntry(self):
-               current_entry = self["content"].getCurrentEntry()
+               current_entry = self["content"].getCurrent()
                self.session.openWithCallback(
                        self.updateInfo,
                        RSSFeedView,
                        feed=current_entry,
                        parent=self,
                        rssPoller=self.rssPoller,
-                       id=self["content"].getCurrentIndex()
+                       id=self["content"].getSelectedIndex()
                )
 
        def selectEnclosure(self):
                # Build a list of all enclosures in this feed
                enclosures = []
-               for entry in self["content"].getCurrentEntry().history:
+               for entry in self["content"].getCurrent().history:
                                enclosures.extend(entry[3])
                RSSBaseView.selectEnclosure(self, enclosures)
+