add fpupgrade plugin
[enigma2.git] / lib / python / Screens / ChannelSelection.py
index 4c8b2486198bb3bab2e7e9bddc2fffa2f62106d7..c7c1b968edaa87d72207f6071fdf9116d5fbe4b0 100644 (file)
@@ -2,6 +2,7 @@ from Screen import Screen
 from Components.Button import Button
 from Components.ServiceList import ServiceList
 from Components.ActionMap import NumberActionMap, ActionMap
 from Components.Button import Button
 from Components.ServiceList import ServiceList
 from Components.ActionMap import NumberActionMap, ActionMap
+from Components.MenuList import MenuList
 from EpgSelection import EPGSelection
 from enigma import eServiceReference, eEPGCache, eEPGCachePtr, eServiceCenter, eServiceCenterPtr, iMutableServiceListPtr, iStaticServiceInformationPtr, eTimer, eDVBDB
 from Components.config import config, configElement, ConfigSubsection, configText, currentConfigSelectionElement
 from EpgSelection import EPGSelection
 from enigma import eServiceReference, eEPGCache, eEPGCachePtr, eServiceCenter, eServiceCenterPtr, iMutableServiceListPtr, iStaticServiceInformationPtr, eTimer, eDVBDB
 from Components.config import config, configElement, ConfigSubsection, configText, currentConfigSelectionElement
@@ -17,22 +18,38 @@ from os import remove
 
 import xml.dom.minidom
 
 
 import xml.dom.minidom
 
-class BouquetSelector(FixedMenu):
+class BouquetSelector(Screen):
        def __init__(self, session, bouquets, selectedFunc):
        def __init__(self, session, bouquets, selectedFunc):
+               Screen.__init__(self, session)
+
                self.selectedFunc=selectedFunc
                self.selectedFunc=selectedFunc
+
+               self["actions"] = ActionMap(["OkCancelActions"],
+                       {
+                               "ok": self.okbuttonClick,
+                               "cancel": self.cancelClick
+                       })
                entrys = [ ]
                for x in bouquets:
                entrys = [ ]
                for x in bouquets:
-                       entrys.append((x[0], self.bouquetSelected, x[1]))
-               FixedMenu.__init__(self, session, "Bouquetlist", entrys)
-               self.skinName = "Menu"
+                       entrys.append((x[0], x[1]))
+               self["menu"] = MenuList(entrys)
 
 
-       def bouquetSelected(self):
-               self.selectedFunc(self["menu"].getCurrent()[2])
+       def okbuttonClick(self):
+               self.selectedFunc(self["menu"].getCurrent()[1])
 
 
-class ChannelContextMenu(FixedMenu):
+       def cancelClick(self):
+               self.close(False)
+
+class ChannelContextMenu(Screen):
        def __init__(self, session, csel):
        def __init__(self, session, csel):
+               Screen.__init__(self, session)
                self.csel = csel
 
                self.csel = csel
 
+               self["actions"] = ActionMap(["OkCancelActions"],
+                       {
+                               "ok": self.okbuttonClick,
+                               "cancel": self.cancelClick
+                       })
                menu = [ ]
 
                inBouquetRootList = csel.getRoot().getPath().find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
                menu = [ ]
 
                inBouquetRootList = csel.getRoot().getPath().find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
@@ -73,10 +90,14 @@ class ChannelContextMenu(FixedMenu):
                                        menu.append((_("end favourites edit"), self.bouquetMarkEnd))
                                        menu.append((_("abort favourites edit"), self.bouquetMarkAbort))
 
                                        menu.append((_("end favourites edit"), self.bouquetMarkEnd))
                                        menu.append((_("abort favourites edit"), self.bouquetMarkAbort))
 
-               menu.append((_("back"), self.close))
+               menu.append((_("back"), self.cancelClick))
+               self["menu"] = MenuList(menu)
+
+       def okbuttonClick(self):
+               self["menu"].getCurrent()[1]()
 
 
-               FixedMenu.__init__(self, session, _("Channel Selection"), menu)
-               self.skinName = "Menu"
+       def cancelClick(self):
+               self.close(False)
 
        def addServiceToBouquetSelected(self):
                bouquets = self.csel.getBouquetList()
 
        def addServiceToBouquetSelected(self):
                bouquets = self.csel.getBouquetList()
@@ -85,12 +106,16 @@ class ChannelContextMenu(FixedMenu):
                else:
                        cnt = len(bouquets)
                if cnt > 1: # show bouquet list
                else:
                        cnt = len(bouquets)
                if cnt > 1: # show bouquet list
-                       self.session.open(BouquetSelector, bouquets, self.addCurrentServiceToBouquet)
+                       self.session.openWithCallback(self.bouquetSelClosed, BouquetSelector, bouquets, self.addCurrentServiceToBouquet)
                elif cnt == 1: # add to only one existing bouquet
                        self.addCurrentServiceToBouquet(bouquets[0][1])
                else: #no bouquets in root.. so assume only one favourite list is used
                        self.addCurrentServiceToBouquet(self.csel.bouquet_root)
 
                elif cnt == 1: # add to only one existing bouquet
                        self.addCurrentServiceToBouquet(bouquets[0][1])
                else: #no bouquets in root.. so assume only one favourite list is used
                        self.addCurrentServiceToBouquet(self.csel.bouquet_root)
 
+       def bouquetSelClosed(self, recursive):
+               if recursive:
+                       self.close(False)
+
        def copyCurrentToBouquetList(self):
                self.csel.copyCurrentToBouquetList()
                self.close()
        def copyCurrentToBouquetList(self):
                self.csel.copyCurrentToBouquetList()
                self.close()
@@ -101,7 +126,7 @@ class ChannelContextMenu(FixedMenu):
 
        def addCurrentServiceToBouquet(self, dest):
                self.csel.addCurrentServiceToBouquet(dest)
 
        def addCurrentServiceToBouquet(self, dest):
                self.csel.addCurrentServiceToBouquet(dest)
-               self.close()
+               self.close(True) # close bouquet selection
 
        def removeCurrentService(self):
                self.csel.removeCurrentService()
 
        def removeCurrentService(self):
                self.csel.removeCurrentService()
@@ -197,6 +222,7 @@ class ChannelSelectionEdit:
                                str = '1:7:2:0:0:0:0:0:0:0:(type == 2) FROM BOUQUET \"userbouquet.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(providerName))
                        new_bouquet_ref = eServiceReference(str)
                        if not mutableBouquetList.addService(new_bouquet_ref):
                                str = '1:7:2:0:0:0:0:0:0:0:(type == 2) FROM BOUQUET \"userbouquet.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(providerName))
                        new_bouquet_ref = eServiceReference(str)
                        if not mutableBouquetList.addService(new_bouquet_ref):
+                               self.bouquetNumOffsetCache = { }
                                mutableBouquetList.flushChanges()
                                eDVBDB.getInstance().reloadBouquets()
                                mutableBouquet = serviceHandler.list(new_bouquet_ref).startEdit()
                                mutableBouquetList.flushChanges()
                                eDVBDB.getInstance().reloadBouquets()
                                mutableBouquet = serviceHandler.list(new_bouquet_ref).startEdit()
@@ -223,10 +249,10 @@ class ChannelSelectionEdit:
 
        def removeBouquet(self):
                refstr = self.getCurrentSelection().toString()
 
        def removeBouquet(self):
                refstr = self.getCurrentSelection().toString()
+               self.bouquetNumOffsetCache = { }
                pos = refstr.find('FROM BOUQUET "')
                if pos != -1:
                        refstr = refstr[pos+14:]
                pos = refstr.find('FROM BOUQUET "')
                if pos != -1:
                        refstr = refstr[pos+14:]
-                       print refstr
                        pos = refstr.find('"')
                        if pos != -1:
                                filename = '/etc/enigma2/' + refstr[:pos] # FIXMEEE !!! HARDCODED /etc/enigma2
                        pos = refstr.find('"')
                        if pos != -1:
                                filename = '/etc/enigma2/' + refstr[:pos] # FIXMEEE !!! HARDCODED /etc/enigma2
@@ -238,10 +264,10 @@ class ChannelSelectionEdit:
        def startMarkedEdit(self):
                self.mutableList = self.getMutableList()
                # add all services from the current list to internal marked set in listboxservicecontent
        def startMarkedEdit(self):
                self.mutableList = self.getMutableList()
                # add all services from the current list to internal marked set in listboxservicecontent
-               self.bouquetRoot = self.getRoot()
                self.clearMarks() # this clears the internal marked set in the listboxservicecontent
                self.saved_title = self.instance.getTitle()
                self.clearMarks() # this clears the internal marked set in the listboxservicecontent
                self.saved_title = self.instance.getTitle()
-               new_title = self.saved_title
+               pos = self.saved_title.find(')')
+               new_title = self.saved_title[:pos+1]
                if self.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') != -1:
                        new_title += ' ' + _("[bouquet edit]")
                else:
                if self.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') != -1:
                        new_title += ' ' + _("[bouquet edit]")
                else:
@@ -251,11 +277,12 @@ class ChannelSelectionEdit:
                self.__marked = self.servicelist.getRootServices()
                for x in self.__marked:
                        self.servicelist.addMarked(eServiceReference(x))
                self.__marked = self.servicelist.getRootServices()
                for x in self.__marked:
                        self.servicelist.addMarked(eServiceReference(x))
-               self.saved_root = self.getRoot()
+               self.savedPath = self.servicePath[:]
                self.showAllServices()
 
        def endMarkedEdit(self, abort):
                if not abort and self.mutableList is not None:
                self.showAllServices()
 
        def endMarkedEdit(self, abort):
                if not abort and self.mutableList is not None:
+                       self.bouquetNumOffsetCache = { }
                        new_marked = set(self.servicelist.getMarked())
                        old_marked = set(self.__marked)
                        removed = old_marked - new_marked
                        new_marked = set(self.servicelist.getMarked())
                        old_marked = set(self.__marked)
                        removed = old_marked - new_marked
@@ -272,11 +299,12 @@ class ChannelSelectionEdit:
                self.__marked = []
                self.clearMarks()
                self.bouquet_mark_edit = False
                self.__marked = []
                self.clearMarks()
                self.bouquet_mark_edit = False
-               self.bouquetRoot = None
                self.mutableList = None
                self.instance.setTitle(self.saved_title)
                self.saved_title = None
                self.mutableList = None
                self.instance.setTitle(self.saved_title)
                self.saved_title = None
-               self.setRoot(self.saved_root)
+               self.servicePath = self.savedPath[:]
+               del self.savedPath
+               self.setRoot(self.servicePath[len(self.servicePath)-1])
 
        def clearMarks(self):
                self.servicelist.clearMarks()
 
        def clearMarks(self):
                self.servicelist.clearMarks()
@@ -293,6 +321,7 @@ class ChannelSelectionEdit:
                mutableList = self.getMutableList()
                if ref.valid() and mutableList is not None:
                        if not mutableList.removeService(ref):
                mutableList = self.getMutableList()
                if ref.valid() and mutableList is not None:
                        if not mutableList.removeService(ref):
+                               self.bouquetNumOffsetCache = { }
                                currentIndex = self.servicelist.getCurrentIndex()
                                self.servicelist.moveDown()
                                if self.servicelist.getCurrentIndex() == currentIndex:
                                currentIndex = self.servicelist.getCurrentIndex()
                                self.servicelist.moveDown()
                                if self.servicelist.getCurrentIndex() == currentIndex:
@@ -305,6 +334,7 @@ class ChannelSelectionEdit:
                mutableList = self.getMutableList(dest)
                if not mutableList is None:
                        if not mutableList.addService(self.servicelist.getCurrent()):
                mutableList = self.getMutableList(dest)
                if not mutableList is None:
                        if not mutableList.addService(self.servicelist.getCurrent()):
+                               self.bouquetNumOffsetCache = { }
                                mutableList.flushChanges()
                self.close()
 
                                mutableList.flushChanges()
                self.close()
 
@@ -318,13 +348,16 @@ class ChannelSelectionEdit:
                        self.mutableList = None
                        self.instance.setTitle(self.saved_title)
                        self.saved_title = None
                        self.mutableList = None
                        self.instance.setTitle(self.saved_title)
                        self.saved_title = None
+                       if self.getRoot() == self.bouquet_root:
+                               self.bouquetNumOffsetCache = { }
                else:
                        self.mutableList = self.getMutableList()
                        self.movemode = True
                        self.pathChangedDisabled = True # no path change allowed in movemode
                        self.saved_title = self.instance.getTitle()
                        new_title = self.saved_title
                else:
                        self.mutableList = self.getMutableList()
                        self.movemode = True
                        self.pathChangedDisabled = True # no path change allowed in movemode
                        self.saved_title = self.instance.getTitle()
                        new_title = self.saved_title
-                       new_title += ' ' + _("[move mode]");
+                       pos = self.saved_title.find(')')
+                       new_title = self.saved_title[:pos+1] + ' ' + _("[move mode]") + self.saved_title[pos+1:]
                        self.instance.setTitle(new_title);
 
        def handleEditCancel(self):
                        self.instance.setTitle(new_title);
 
        def handleEditCancel(self):
@@ -368,9 +401,12 @@ class ChannelSelectionBase(Screen):
 
                self.servicePathTV = [ ]
                self.servicePathRadio = [ ]
 
                self.servicePathTV = [ ]
                self.servicePathRadio = [ ]
+               self.servicePath = None
 
                self.pathChangedDisabled = False
 
 
                self.pathChangedDisabled = False
 
+               self.bouquetNumOffsetCache = { }
+
                self["ChannelSelectBaseActions"] = NumberActionMap(["ChannelSelectBaseActions", "NumberActions"],
                        {
                                "showFavourites": self.showFavourites,
                self["ChannelSelectBaseActions"] = NumberActionMap(["ChannelSelectBaseActions", "NumberActions"],
                        {
                                "showFavourites": self.showFavourites,
@@ -399,29 +435,33 @@ class ChannelSelectionBase(Screen):
                return ref
 
        def getBouquetNumOffset(self, bouquet):
                return ref
 
        def getBouquetNumOffset(self, bouquet):
-               bouquet = self.appendDVBTypes(bouquet)
                if self.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') == -1: #FIXME HACK
                        return 0
                if self.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') == -1: #FIXME HACK
                        return 0
-               offsetCount = 0
-               serviceHandler = eServiceCenter.getInstance()
-               bouquetlist = serviceHandler.list(self.bouquet_root)
-               if not bouquetlist is None:
-                       while True:
-                               bouquetIterator = self.appendDVBTypes(bouquetlist.getNext())
-                               if not bouquetIterator.valid() or bouquetIterator == bouquet: #end of list or bouquet found
-                                       break
-                               if ((bouquetIterator.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
-                                       continue
-                               servicelist = serviceHandler.list(bouquetIterator)
-                               if not servicelist is None:
-                                       while True:
-                                               serviceIterator = servicelist.getNext()
-                                               if not serviceIterator.valid(): #check if end of list
-                                                       break
-                                               if serviceIterator.flags: #playable services have no flags
-                                                       continue
-                                               offsetCount += 1
-               return offsetCount
+               bouquet = self.appendDVBTypes(bouquet)
+               try:
+                       return self.bouquetNumOffsetCache[bouquet.toString()]
+               except:
+                       offsetCount = 0
+                       serviceHandler = eServiceCenter.getInstance()
+                       bouquetlist = serviceHandler.list(self.bouquet_root)
+                       if not bouquetlist is None:
+                               while True:
+                                       bouquetIterator = self.appendDVBTypes(bouquetlist.getNext())
+                                       if not bouquetIterator.valid(): #end of list
+                                               break
+                                       self.bouquetNumOffsetCache[bouquetIterator.toString()]=offsetCount
+                                       if ((bouquetIterator.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
+                                               continue
+                                       servicelist = serviceHandler.list(bouquetIterator)
+                                       if not servicelist is None:
+                                               while True:
+                                                       serviceIterator = servicelist.getNext()
+                                                       if not serviceIterator.valid(): #check if end of list
+                                                               break
+                                                       if serviceIterator.flags: #playable services have no flags
+                                                               continue
+                                                       offsetCount += 1
+               return self.bouquetNumOffsetCache.get(bouquet.toString(), offsetCount)
 
        def recallBouquetMode(self):
                if self.mode == MODE_TV:
 
        def recallBouquetMode(self):
                if self.mode == MODE_TV:
@@ -439,24 +479,26 @@ class ChannelSelectionBase(Screen):
                self.bouquet_root = eServiceReference(self.bouquet_rootstr)
 
        def setTvMode(self):
                self.bouquet_root = eServiceReference(self.bouquet_rootstr)
 
        def setTvMode(self):
+               self.mode = MODE_TV
+               self.servicePath = self.servicePathTV
+               self.recallBouquetMode()
                title = self.instance.getTitle()
                pos = title.find(" (")
                if pos != -1:
                        title = title[:pos]
                title += " (TV)"
                self.instance.setTitle(title)
                title = self.instance.getTitle()
                pos = title.find(" (")
                if pos != -1:
                        title = title[:pos]
                title += " (TV)"
                self.instance.setTitle(title)
-               self.mode = MODE_TV
-               self.recallBouquetMode()
 
        def setRadioMode(self):
 
        def setRadioMode(self):
+               self.mode = MODE_RADIO
+               self.servicePath = self.servicePathRadio
+               self.recallBouquetMode()
                title = self.instance.getTitle()
                pos = title.find(" (")
                if pos != -1:
                        title = title[:pos]
                title += " (Radio)"
                self.instance.setTitle(title)
                title = self.instance.getTitle()
                pos = title.find(" (")
                if pos != -1:
                        title = title[:pos]
                title += " (Radio)"
                self.instance.setTitle(title)
-               self.mode = MODE_RADIO
-               self.recallBouquetMode()
 
        def setRoot(self, root, justSet=False):
                path = root.getPath()
 
        def setRoot(self, root, justSet=False):
                path = root.getPath()
@@ -471,6 +513,53 @@ class ChannelSelectionBase(Screen):
                else:
                        self.servicelist.setMode(ServiceList.MODE_NORMAL)
                self.servicelist.setRoot(root, justSet)
                else:
                        self.servicelist.setMode(ServiceList.MODE_NORMAL)
                self.servicelist.setRoot(root, justSet)
+               self.buildTitleString()
+
+       def removeModeStr(self, str):
+               if self.mode == MODE_TV:
+                       pos = str.find(' (TV)')
+               else:
+                       pos = str.find(' (Radio)')
+               if pos != -1:
+                       return str[:pos]
+               return str
+
+       def getServiceName(self, ref):
+               str = self.removeModeStr(ServiceReference(ref).getServiceName())
+               if not len(str):
+                       pathstr = ref.getPath()
+                       if pathstr.find('FROM PROVIDERS') != -1:
+                               return _("Provider")
+                       if pathstr.find('FROM SATELLITES') != -1:
+                               return _("Satellites")
+                       if pathstr.find(') ORDER BY name') != -1:
+                               return _("All")
+               return str
+
+       def buildTitleString(self):
+               titleStr = self.instance.getTitle()
+               pos = titleStr.find(']')
+               if pos == -1:
+                       pos = titleStr.find(')')
+               if pos != -1:
+                       titleStr = titleStr[:pos+1]
+                       Len = len(self.servicePath)
+                       if Len > 0:
+                               base_ref = self.servicePath[0]
+                               if Len > 1:
+                                       end_ref = self.servicePath[Len-1]
+                               else:
+                                       end_ref = None
+                               nameStr = self.getServiceName(base_ref)
+                               titleStr += ' ' + nameStr
+                               if end_ref is not None:
+                                       if Len > 2:
+                                               titleStr += '/../'
+                                       else:
+                                               titleStr += '/'
+                                       nameStr = self.getServiceName(end_ref)
+                                       titleStr += nameStr
+                               self.instance.setTitle(titleStr)
 
        def moveUp(self):
                self.servicelist.moveUp()
 
        def moveUp(self):
                self.servicelist.moveUp()
@@ -479,47 +568,30 @@ class ChannelSelectionBase(Screen):
                self.servicelist.moveDown()
 
        def clearPath(self):
                self.servicelist.moveDown()
 
        def clearPath(self):
-               if self.mode == MODE_RADIO:
-                       self.servicePathRadio = [ ]
-               else:
-                       self.servicePathTV = [ ]
+               del self.servicePath[:]
 
        def enterPath(self, ref, justSet=False):
 
        def enterPath(self, ref, justSet=False):
-               if self.mode == MODE_RADIO:
-                       self.servicePathRadio.append(ref)
-               else:
-                       self.servicePathTV.append(ref)
+               self.servicePath.append(ref)
                self.setRoot(ref, justSet)
 
        def pathUp(self, justSet=False):
                self.setRoot(ref, justSet)
 
        def pathUp(self, justSet=False):
-               if self.mode == MODE_TV:
-                       prev = self.servicePathTV.pop()
-                       length = len(self.servicePathTV)
-                       if length:
-                               current = self.servicePathTV[length-1]
-               else:
-                       prev = self.servicePathRadio.pop()
-                       length = len(self.servicePathRadio)
-                       if length:
-                               current = self.servicePathRadio[length-1]
+               prev = self.servicePath.pop()
+               length = len(self.servicePath)
+               if length:
+                       current = self.servicePath[length-1]
                self.setRoot(current, justSet)
                if not justSet:
                        self.setCurrentSelection(prev)
                return prev
 
        def isBasePathEqual(self, ref):
                self.setRoot(current, justSet)
                if not justSet:
                        self.setCurrentSelection(prev)
                return prev
 
        def isBasePathEqual(self, ref):
-               if self.mode == MODE_RADIO and len(self.servicePathRadio) > 1 and self.servicePathRadio[0] == ref:
-                       return True
-               elif self.mode == MODE_TV and len(self.servicePathTV) > 1 and self.servicePathTV[0] == ref:
+               if len(self.servicePath) > 1 and self.servicePath[0] == ref:
                        return True
                return False
 
        def isPrevPathEqual(self, ref):
                        return True
                return False
 
        def isPrevPathEqual(self, ref):
-               path = self.servicePathRadio
-               if self.mode == MODE_TV:
-                       path = self.servicePathTV
-               length = len(path)
-               if length > 1 and path[length-2] == ref:
+               length = len(self.servicePath)
+               if length > 1 and self.servicePath[length-2] == ref:
                        return True
                return False
 
                        return True
                return False
 
@@ -572,9 +644,12 @@ class ChannelSelectionBase(Screen):
                                                                service.setName(service_name) # why we need this cast?
                                                        except:
                                                                if orbpos > 1800: # west
                                                                service.setName(service_name) # why we need this cast?
                                                        except:
                                                                if orbpos > 1800: # west
-                                                                       service.setName("%s (%3.1f" + _("W") + ")" %(str, (0 - (orbpos - 3600)) / 10.0))
+                                                                       orbpos = 3600 - orbpos
+                                                                       h = _("W")
                                                                else:
                                                                else:
-                                                                       service.setName("%s (%3.1f" + _("E") + ")" % (str, orbpos / 10.0))
+                                                                       h = _("E")
+                                                               n = ("%s (%d.%d" + h + ")") % (service_name, orbpos / 10, orbpos % 10)
+                                                               service.setName(n)
                                                        self.servicelist.addService(service)
                                                        self.servicelist.finishFill()
                                                        if prev is not None:
                                                        self.servicelist.addService(service)
                                                        self.servicelist.finishFill()
                                                        if prev is not None:
@@ -604,6 +679,15 @@ class ChannelSelectionBase(Screen):
                                ref = self.getCurrentSelection()
                                self.enterPath(ref)
 
                                ref = self.getCurrentSelection()
                                self.enterPath(ref)
 
+       def inBouquet(self):
+               return self.isBasePathEqual(self.bouquet_root)
+
+       def atBegin(self):
+               return self.servicelist.atBegin()
+
+       def atEnd(self):
+               return self.servicelist.atEnd()
+
        def nextBouquet(self):
                self.changeBouquet(+1)
 
        def nextBouquet(self):
                self.changeBouquet(+1)
 
@@ -665,6 +749,8 @@ class ChannelSelectionBase(Screen):
                        return bouquets
                return None
 
                        return bouquets
                return None
 
+HISTORYSIZE = 20
+
 class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
        def __init__(self, session):
                ChannelSelectionBase.__init__(self,session)
 class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
        def __init__(self, session):
                ChannelSelectionBase.__init__(self,session)
@@ -683,22 +769,24 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                                "cancel": self.cancel,
                                "ok": self.channelSelected,
                        })
                                "cancel": self.cancel,
                                "ok": self.channelSelected,
                        })
-               self.onShown.append(self.onShow)
+               self.onShown.append(self.__onShown)
 
                self.lastChannelRootTimer = eTimer()
 
                self.lastChannelRootTimer = eTimer()
-               self.lastChannelRootTimer.timeout.get().append(self.onCreate)
+               self.lastChannelRootTimer.timeout.get().append(self.__onCreate)
                self.lastChannelRootTimer.start(100,True)
 
                self.lastChannelRootTimer.start(100,True)
 
-       def onCreate(self):
+               self.history = [ ]
+               self.history_pos = 0
+
+       def __onCreate(self):
                self.setTvMode()
                self.setTvMode()
-               self.servicePathTV = [ ]
                self.restoreRoot()
                lastservice=eServiceReference(config.tv.lastservice.value)
                if lastservice.valid():
                        self.setCurrentSelection(lastservice)
                self.restoreRoot()
                lastservice=eServiceReference(config.tv.lastservice.value)
                if lastservice.valid():
                        self.setCurrentSelection(lastservice)
-                       self.session.nav.playService(lastservice)
+                       self.zap()
 
 
-       def onShow(self):
+       def __onShown(self):
                self.recallBouquetMode()
                ref = self.session.nav.getCurrentlyPlayingServiceReference()
                if ref is not None and ref.valid() and ref.getPath() == "":
                self.recallBouquetMode()
                ref = self.session.nav.getCurrentlyPlayingServiceReference()
                if ref is not None and ref.valid() and ref.getPath() == "":
@@ -721,9 +809,47 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
        #called from infoBar and channelSelected
        def zap(self):
                ref = self.session.nav.getCurrentlyPlayingServiceReference()
        #called from infoBar and channelSelected
        def zap(self):
                ref = self.session.nav.getCurrentlyPlayingServiceReference()
-               if ref is None or ref != self.getCurrentSelection():
-                       self.session.nav.playService(self.getCurrentSelection())
+               nref = self.getCurrentSelection()
+               if ref is None or ref != nref:
+                       self.session.nav.playService(nref)
+               self.saveRoot()
+               self.saveChannel()
+               tmp=self.servicePath[:]
+               tmp.append(nref)
+               try:
+                       del self.history[self.history_pos+1:]
+               except:
+                       pass
+               self.history.append(tmp)
+               hlen = len(self.history)
+               if hlen > HISTORYSIZE:
+                       del self.history[0]
+                       hlen -= 1
+               self.history_pos = hlen-1
+
+       def historyBack(self):
+               hlen = len(self.history)
+               if hlen > 1 and self.history_pos > 0:
+                       self.history_pos -= 1
+                       self.setHistoryPath()
+
+       def historyNext(self):
+               hlen = len(self.history)
+               if hlen > 1 and self.history_pos < (hlen-1):
+                       self.history_pos += 1
+                       self.setHistoryPath()
+
+       def setHistoryPath(self):
+               path = self.history[self.history_pos][:]
+               ref = path.pop()
+               self.servicePath = path
                self.saveRoot()
                self.saveRoot()
+               plen = len(path)
+               root = path[plen-1]
+               if self.getRoot() != root:
+                       self.setRoot(root)
+               self.session.nav.playService(ref)
+               self.setCurrentSelection(ref)
                self.saveChannel()
 
        def saveRoot(self):
                self.saveChannel()
 
        def saveRoot(self):
@@ -739,7 +865,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                        config.tv.lastroot.save()
 
        def restoreRoot(self):
                        config.tv.lastroot.save()
 
        def restoreRoot(self):
-               self.servicePathTV = [ ]
+               self.clearPath()
                re = compile('.+?;')
                tmp = re.findall(config.tv.lastroot.value)
                cnt = 0
                re = compile('.+?;')
                tmp = re.findall(config.tv.lastroot.value)
                cnt = 0
@@ -759,7 +885,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                        if pathstr is not None and pathstr.find(refstr) == 0:
                                self.restoreRoot()
                                lastservice=eServiceReference(config.tv.lastservice.value)
                        if pathstr is not None and pathstr.find(refstr) == 0:
                                self.restoreRoot()
                                lastservice=eServiceReference(config.tv.lastservice.value)
-                               if lastservice is not None:
+                               if lastservice.valid():
                                        self.setCurrentSelection(lastservice)
                                return True
                return False
                                        self.setCurrentSelection(lastservice)
                                return True
                return False
@@ -843,7 +969,7 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                        config.radio.lastroot.save()
 
        def restoreRoot(self):
                        config.radio.lastroot.save()
 
        def restoreRoot(self):
-               self.servicePathRadio = [ ]
+               self.clearPath()
                re = compile('.+?;')
                tmp = re.findall(config.radio.lastroot.value)
                cnt = 0
                re = compile('.+?;')
                tmp = re.findall(config.radio.lastroot.value)
                cnt = 0
@@ -863,7 +989,7 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                        if pathstr is not None and pathstr.find(refstr) == 0:
                                self.restoreRoot()
                                lastservice=eServiceReference(config.radio.lastservice.value)
                        if pathstr is not None and pathstr.find(refstr) == 0:
                                self.restoreRoot()
                                lastservice=eServiceReference(config.radio.lastservice.value)
-                               if lastservice is not None:
+                               if lastservice.valid():
                                        self.setCurrentSelection(lastservice)
                                return True
                return False
                                        self.setCurrentSelection(lastservice)
                                return True
                return False
@@ -876,7 +1002,7 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                        self.servicelist.setCurrent(lastservice)
                        self.session.nav.playService(lastservice)
                        self.servicelist.setPlayableIgnoreService(lastservice)
                        self.servicelist.setCurrent(lastservice)
                        self.session.nav.playService(lastservice)
                        self.servicelist.setPlayableIgnoreService(lastservice)
-               self.info.instance.show()
+               self.info.show()
 
        def channelSelected(self): # just return selected service
                ref = self.getCurrentSelection()
 
        def channelSelected(self): # just return selected service
                ref = self.getCurrentSelection()
@@ -896,7 +1022,7 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                        self.saveRoot()
 
        def closeRadio(self):
                        self.saveRoot()
 
        def closeRadio(self):
-               self.info.instance.hide()
+               self.info.hide()
                #set previous tv service
                lastservice=eServiceReference(config.tv.lastservice.value)
                self.session.nav.playService(lastservice)
                #set previous tv service
                lastservice=eServiceReference(config.tv.lastservice.value)
                self.session.nav.playService(lastservice)
@@ -906,17 +1032,17 @@ class SimpleChannelSelection(ChannelSelectionBase):
        def __init__(self, session, title):
                ChannelSelectionBase.__init__(self, session)
                self.title = title
        def __init__(self, session, title):
                ChannelSelectionBase.__init__(self, session)
                self.title = title
-               self.onShown.append(self.onExecCallback)
+               self.onShown.append(self.__onExecCallback)
 
                self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
                        {
 
                self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
                        {
-                               "cancel": self.cancel,
+                               "cancel": self.close,
                                "ok": self.channelSelected,
                                "keyRadio": self.setModeRadio,
                                "keyTV": self.setModeTv,
                        })
 
                                "ok": self.channelSelected,
                                "keyRadio": self.setModeRadio,
                                "keyTV": self.setModeTv,
                        })
 
-       def onExecCallback(self):
+       def __onExecCallback(self):
                self.session.currentDialog.instance.setTitle(self.title)
                self.setModeTv()
 
                self.session.currentDialog.instance.setTitle(self.title)
                self.setModeTv()