fix radio player
[enigma2.git] / lib / python / Screens / ChannelSelection.py
index 45de7abd4cf0cce751cefecb9c841bfef8bcb3e2..04c3c4480ade20811c3ab8cd138d880e5d276b2c 100644 (file)
@@ -1,19 +1,23 @@
 from Screen import Screen
 from Components.Button import Button
 from Components.ServiceList import ServiceList
 from Screen import Screen
 from Components.Button import Button
 from Components.ServiceList import ServiceList
-from Components.ActionMap import NumberActionMap
+from Components.ActionMap import NumberActionMap, ActionMap
 from EpgSelection import EPGSelection
 from enigma import eServiceReference, eEPGCache, eEPGCachePtr, eServiceCenter, eServiceCenterPtr, iMutableServiceListPtr, iStaticServiceInformationPtr, eTimer
 from EpgSelection import EPGSelection
 from enigma import eServiceReference, eEPGCache, eEPGCachePtr, eServiceCenter, eServiceCenterPtr, iMutableServiceListPtr, iStaticServiceInformationPtr, eTimer
-from Components.config import config, configElement, ConfigSubsection, configText
+from Components.config import config, configElement, ConfigSubsection, configText, currentConfigSelectionElement
 from Screens.FixedMenu import FixedMenu
 from Tools.NumericalTextInput import NumericalTextInput
 from Components.NimManager import nimmanager
 from Screens.FixedMenu import FixedMenu
 from Tools.NumericalTextInput import NumericalTextInput
 from Components.NimManager import nimmanager
+from Components.ServiceName import ServiceName
+from Components.Clock import Clock
+from Components.EventInfo import EventInfo
+from re import *
 
 import xml.dom.minidom
 
 class BouquetSelector(FixedMenu):
 
 import xml.dom.minidom
 
 class BouquetSelector(FixedMenu):
-       def __init__(self, session, bouquets, parent):
-               self.parent=parent
+       def __init__(self, session, bouquets, selectedFunc):
+               self.selectedFunc=selectedFunc
                entrys = [ ]
                for x in bouquets:
                        entrys.append((x[0], self.bouquetSelected, x[1]))
                entrys = [ ]
                for x in bouquets:
                        entrys.append((x[0], self.bouquetSelected, x[1]))
@@ -21,8 +25,7 @@ class BouquetSelector(FixedMenu):
                self.skinName = "Menu"
 
        def bouquetSelected(self):
                self.skinName = "Menu"
 
        def bouquetSelected(self):
-               self.parent.addCurrentServiceToBouquet(self["menu"].getCurrent()[2])
-               self.close()
+               self.selectedFunc(self["menu"].getCurrent()[2])
 
 class ChannelContextMenu(FixedMenu):
        def __init__(self, session, csel):
 
 class ChannelContextMenu(FixedMenu):
        def __init__(self, session, csel):
@@ -30,7 +33,7 @@ class ChannelContextMenu(FixedMenu):
 
                menu = [ ]
 
 
                menu = [ ]
 
-               inBouquetRootList = csel.servicelist.getRoot().getPath().find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
+               inBouquetRootList = csel.getRoot().getPath().find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
                inBouquet = csel.getMutableList() is not None
                haveBouquets = csel.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') != -1
 
                inBouquet = csel.getMutableList() is not None
                haveBouquets = csel.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') != -1
 
@@ -68,23 +71,15 @@ class ChannelContextMenu(FixedMenu):
                self.skinName = "Menu"
 
        def addServiceToBouquetSelected(self):
                self.skinName = "Menu"
 
        def addServiceToBouquetSelected(self):
-               bouquets = [ ]
-               serviceHandler = eServiceCenter.getInstance()
-               list = serviceHandler.list(self.csel.bouquet_root)
-               if not list is None:
-                       while True:
-                               s = list.getNext()
-                               if not s.valid():
-                                       break
-                               if ((s.flags & eServiceReference.flagDirectory) == eServiceReference.flagDirectory):
-                                       info = serviceHandler.info(s)
-                                       if not info is None:
-                                               bouquets.append((info.getName(s), s))
-               cnt = len(bouquets)
+               bouquets = self.csel.getBouquetList()
+               if bouquets is None:
+                       cnt = 0
+               else:
+                       cnt = len(bouquets)
                if cnt > 1: # show bouquet list
                if cnt > 1: # show bouquet list
-                       self.session.open(BouquetSelector, bouquets, self)
+                       self.session.open(BouquetSelector, bouquets, self.addCurrentServiceToBouquet)
                elif cnt == 1: # add to only one existing bouquet
                elif cnt == 1: # add to only one existing bouquet
-                       self.addCurrentServiceToBouquet(bouquet[0][1])
+                       self.addCurrentServiceToBouquet(bouquets[0][1])
                else: #no bouquets in root.. so assume only one favourite list is used
                        self.addCurrentServiceToBouquet(self.csel.bouquet_root)
 
                else: #no bouquets in root.. so assume only one favourite list is used
                        self.addCurrentServiceToBouquet(self.csel.bouquet_root)
 
@@ -112,6 +107,21 @@ class ChannelContextMenu(FixedMenu):
                self.csel.endMarkedEdit(abort=True)
                self.close()
 
                self.csel.endMarkedEdit(abort=True)
                self.close()
 
+class ChannelSelectionEPG:
+       def __init__(self):
+               self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
+                       {
+                               "showEPGList": self.showEPGList,
+                       })
+
+       def showEPGList(self):
+               ref=self.getCurrentSelection()
+               ptr=eEPGCache.getInstance()
+               if ptr.startTimeQuery(ref) != -1:
+                       self.session.open(EPGSelection, ref)
+               else:
+                       print 'no epg for service', ref.toString()
+
 class ChannelSelectionEdit:
        def __init__(self):
                self.entry_marked = False
 class ChannelSelectionEdit:
        def __init__(self):
                self.entry_marked = False
@@ -122,12 +132,25 @@ class ChannelSelectionEdit:
                self.saved_title = None
                self.saved_root = None
 
                self.saved_title = None
                self.saved_root = None
 
+               class ChannelSelectionEditActionMap(ActionMap):
+                       def __init__(self, csel, contexts = [ ], actions = { }, prio=0):
+                               ActionMap.__init__(self, contexts, actions, prio)
+                               self.csel = csel
+                       def action(self, contexts, action):
+                               if action == "cancel":
+                                       self.csel.handleEditCancel()
+                               ActionMap.action(self, contexts, action)
+               self["ChannelSelectEditActions"] = ChannelSelectionEditActionMap(self, ["ChannelSelectEditActions"],
+                       {
+                               "contextMenu": self.doContext,
+                       })
+
        def getMutableList(self, root=eServiceReference()):
                if not self.mutableList is None:
                        return self.mutableList
                serviceHandler = eServiceCenter.getInstance()
                if not root.valid():
        def getMutableList(self, root=eServiceReference()):
                if not self.mutableList is None:
                        return self.mutableList
                serviceHandler = eServiceCenter.getInstance()
                if not root.valid():
-                       root=self.servicelist.getRoot()
+                       root=self.getRoot()
                list = serviceHandler.list(root)
                if list is not None:
                        return list.startEdit()
                list = serviceHandler.list(root)
                if list is not None:
                        return list.startEdit()
@@ -137,7 +160,7 @@ 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.servicelist.getRoot()
+               self.bouquetRoot = self.getRoot()
                self.clearMarks() # this clears the internal marked set in the listboxservicecontent
                self.saved_title = self.instance.getTitle()
                new_title = self.saved_title
                self.clearMarks() # this clears the internal marked set in the listboxservicecontent
                self.saved_title = self.instance.getTitle()
                new_title = self.saved_title
@@ -197,7 +220,7 @@ class ChannelSelectionEdit:
                                if self.servicelist.getCurrentIndex() == currentIndex:
                                        currentIndex -= 1
                                mutableList.flushChanges() #FIXME dont flush on each single removed service
                                if self.servicelist.getCurrentIndex() == currentIndex:
                                        currentIndex -= 1
                                mutableList.flushChanges() #FIXME dont flush on each single removed service
-                               self.setRoot(self.servicelist.getRoot())
+                               self.setRoot(self.getRoot())
                                self.servicelist.moveToIndex(currentIndex)
 
        def addCurrentServiceToBouquet(self, dest):
                                self.servicelist.moveToIndex(currentIndex)
 
        def addCurrentServiceToBouquet(self, dest):
@@ -242,6 +265,9 @@ class ChannelSelectionEdit:
        def doContext(self):
                self.session.open(ChannelContextMenu, self)
 
        def doContext(self):
                self.session.open(ChannelContextMenu, self)
 
+MODE_TV = 0
+MODE_RADIO = 1
+
 class ChannelSelectionBase(Screen):
        def __init__(self, session):
                Screen.__init__(self, session)
 class ChannelSelectionBase(Screen):
        def __init__(self, session):
                Screen.__init__(self, session)
@@ -250,11 +276,6 @@ class ChannelSelectionBase(Screen):
                self.service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17)'
                self.service_types_radio = '1:7:1:0:0:0:0:0:0:0:(type == 2)'
 
                self.service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17)'
                self.service_types_radio = '1:7:1:0:0:0:0:0:0:0:(type == 2)'
 
-               self.service_types = self.service_types_tv
-
-               #self.bouquet_root = eServiceReference('1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.tv" ORDER BY bouquet')
-               self.bouquet_root = eServiceReference('%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types))
-
                self["key_red"] = Button(_("All"))
                self["key_green"] = Button(_("Satellites"))
                self["key_yellow"] = Button(_("Provider"))
                self["key_red"] = Button(_("All"))
                self["key_green"] = Button(_("Satellites"))
                self["key_yellow"] = Button(_("Provider"))
@@ -263,11 +284,45 @@ class ChannelSelectionBase(Screen):
                self["list"] = ServiceList()
                self.servicelist = self["list"]
 
                self["list"] = ServiceList()
                self.servicelist = self["list"]
 
-               #self["okbutton"] = Button("ok", [self.channelSelected])
-
                self.numericalTextInput = NumericalTextInput()
 
                self.numericalTextInput = NumericalTextInput()
 
+               self.servicePathTV = [ ]
+               self.servicePathRadio = [ ]
+
+               class ChannelBaseActionMap(NumberActionMap):
+                       def __init__(self, csel, contexts = [ ], actions = { }, prio=0):
+                               NumberActionMap.__init__(self, contexts, actions, prio)
+                               self.csel = csel
+                       def action(self, contexts, action):
+                               if not self.csel.enterBouquet(action):
+                                       NumberActionMap.action(self, contexts, action)
+               self["ChannelSelectBaseActions"] = ChannelBaseActionMap(self, ["ChannelSelectBaseActions"],
+                       {
+                               "showFavourites": self.showFavourites,
+                               "showAllServices": self.showAllServices,
+                               "showProviders": self.showProviders,
+                               "showSatellites": self.showSatellites,
+                               "1": self.keyNumberGlobal,
+                               "2": self.keyNumberGlobal,
+                               "3": self.keyNumberGlobal,
+                               "4": self.keyNumberGlobal,
+                               "5": self.keyNumberGlobal,
+                               "6": self.keyNumberGlobal,
+                               "7": self.keyNumberGlobal,
+                               "8": self.keyNumberGlobal,
+                               "9": self.keyNumberGlobal,
+                               "0": self.keyNumberGlobal
+                       })
+
+       def appendDVBTypes(self, ref):
+               path = ref.getPath()
+               pos = path.find(' FROM BOUQUET')
+               if pos != -1:
+                       return eServiceReference(self.service_types + path[pos:])
+               return ref
+
        def getBouquetNumOffset(self, bouquet):
        def getBouquetNumOffset(self, bouquet):
+               bouquet = self.appendDVBTypes(bouquet)
                if self.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') == -1: #FIXME HACK
                        return 0
                offsetCount = 0
                if self.bouquet_root.getPath().find('FROM BOUQUET "bouquets.') == -1: #FIXME HACK
                        return 0
                offsetCount = 0
@@ -275,7 +330,7 @@ class ChannelSelectionBase(Screen):
                bouquetlist = serviceHandler.list(self.bouquet_root)
                if not bouquetlist is None:
                        while True:
                bouquetlist = serviceHandler.list(self.bouquet_root)
                if not bouquetlist is None:
                        while True:
-                               bouquetIterator = bouquetlist.getNext()
+                               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):
                                if not bouquetIterator.valid() or bouquetIterator == bouquet: #end of list or bouquet found
                                        break
                                if ((bouquetIterator.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
@@ -291,11 +346,51 @@ class ChannelSelectionBase(Screen):
                                                offsetCount += 1
                return offsetCount
 
                                                offsetCount += 1
                return offsetCount
 
+       def recallBouquetMode(self):
+               if self.mode == MODE_TV:
+                       self.service_types = self.service_types_tv
+                       if currentConfigSelectionElement(config.usage.multibouquet) == "yes":
+                               self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
+                       else:
+                               self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types)
+               else:
+                       self.service_types = self.service_types_radio
+                       if currentConfigSelectionElement(config.usage.multibouquet) == "yes":
+                               self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.radio" ORDER BY bouquet'
+                       else:
+                               self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.radio" ORDER BY bouquet'%(self.service_types)
+               self.bouquet_root = eServiceReference(self.bouquet_rootstr)
+
+       def setTvMode(self):
+               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):
+               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 setRootBase(self, root, justSet=False):
        def setRootBase(self, root, justSet=False):
-               inBouquetRootList = root.getPath().find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
-               if not inBouquetRootList and (root.getPath().find('FROM BOUQUET') != -1):
+               path = root.getPath()
+               inBouquetRootList = path.find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
+               pos = path.find(' FROM BOUQUET')
+               isBouquet = pos != -1
+               if not inBouquetRootList and isBouquet:
                        self.servicelist.setMode(ServiceList.MODE_FAVOURITES)
                        self.servicelist.setNumberOffset(self.getBouquetNumOffset(root))
                        self.servicelist.setMode(ServiceList.MODE_FAVOURITES)
                        self.servicelist.setNumberOffset(self.getBouquetNumOffset(root))
+                       refstr = self.service_types + path[pos:]
+                       root = eServiceReference(refstr)
                else:
                        self.servicelist.setMode(ServiceList.MODE_NORMAL)
                self.servicelist.setRoot(root, justSet)
                else:
                        self.servicelist.setMode(ServiceList.MODE_NORMAL)
                self.servicelist.setRoot(root, justSet)
@@ -306,42 +401,129 @@ class ChannelSelectionBase(Screen):
        def moveDown(self):
                self.servicelist.moveDown()
 
        def moveDown(self):
                self.servicelist.moveDown()
 
+       def clearPath(self):
+               if self.mode == MODE_RADIO:
+                       self.servicePathRadio = [ ]
+               else:
+                       self.servicePathTV = [ ]
+
+       def enterPath(self, ref, justSet=False):
+               if self.mode == MODE_RADIO:
+                       self.servicePathRadio.append(ref)
+               else:
+                       self.servicePathTV.append(ref)
+               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]
+               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:
+                       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:
+                       return True
+               return False
+
+       def preEnterPath(self, refstr):
+               return False
+
        def showAllServices(self):
        def showAllServices(self):
-               ref = eServiceReference('%s ORDER BY name'%(self.service_types))
-               self.setRoot(ref)
+               refstr = '%s ORDER BY name'%(self.service_types)
+               if not self.preEnterPath(refstr):
+                       ref = eServiceReference(refstr)
+                       currentRoot = self.getRoot()
+                       if currentRoot is None or currentRoot != ref:
+                               self.clearPath()
+                               self.enterPath(ref)
 
        def showSatellites(self):
 
        def showSatellites(self):
-               ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
-               self.setRoot(ref, True)
-               serviceHandler = eServiceCenter.getInstance()
-               servicelist = serviceHandler.list(ref)
-               if not servicelist is None:
-                       while True:
-                               service = servicelist.getNext()
-                               if not service.valid(): #check if end of list
-                                       break
-                               orbpos = service.getData(4) >> 16
-                               if service.getPath().find("FROM PROVIDER") != -1:
-                                       service_name = _("Providers")
-                               else:
-                                       service_name = _("Services")
-                               try:
-                                       service_name += str(' - %s'%(nimmanager.getSatDescription(orbpos)))
-                                       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))
-                                       else:
-                                               service.setName("%s (%3.1f" + _("E") + ")" % (str, orbpos / 10.0))
-                               self.servicelist.addService(service)
-               self.servicelist.finishFill()
+               refstr = '%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types)
+               if not self.preEnterPath(refstr):
+                       ref = eServiceReference(refstr)
+                       justSet=False
+                       prev = None
+
+                       if self.isBasePathEqual(ref):
+                               if self.isPrevPathEqual(ref):
+                                       justSet=True
+                               prev = self.pathUp(justSet)
+                       else:
+                               currentRoot = self.getRoot()
+                               if currentRoot is None or currentRoot != ref:
+                                       justSet=True
+                                       self.clearPath()
+                                       self.enterPath(ref, True)
+                       if justSet:
+                               serviceHandler = eServiceCenter.getInstance()
+                               servicelist = serviceHandler.list(ref)
+                               if not servicelist is None:
+                                       while True:
+                                               service = servicelist.getNext()
+                                               if not service.valid(): #check if end of list
+                                                       break
+                                               orbpos = service.getData(4) >> 16
+                                               if service.getPath().find("FROM PROVIDER") != -1:
+                                                       service_name = _("Providers")
+                                               else:
+                                                       service_name = _("Services")
+                                               try:
+                                                       service_name += str(' - %s'%(nimmanager.getSatDescription(orbpos)))
+                                                       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))
+                                                       else:
+                                                               service.setName("%s (%3.1f" + _("E") + ")" % (str, orbpos / 10.0))
+       #                                       print service.toString()
+                                               self.servicelist.addService(service)
+                                               self.servicelist.finishFill()
+                                               if prev is not None:
+       #                                       print "-->", prev.toString()
+                                                       self.setCurrentSelection(prev)
 
        def showProviders(self):
 
        def showProviders(self):
-               ref = eServiceReference('%s FROM PROVIDERS ORDER BY name'%(self.service_types))
-               self.setRoot(ref)
+               refstr = '%s FROM PROVIDERS ORDER BY name'%(self.service_types)
+               if not self.preEnterPath(refstr):
+                       ref = eServiceReference(refstr)
+                       if self.isBasePathEqual(ref):
+                               self.pathUp()
+                       else:
+                               currentRoot = self.getRoot()
+                               if currentRoot is None or currentRoot != ref:
+                                       self.clearPath()
+                                       self.enterPath(ref)
 
        def showFavourites(self):
 
        def showFavourites(self):
-               self.setRoot(self.bouquet_root)
+               if not self.preEnterPath(self.bouquet_rootstr):
+                       if self.isBasePathEqual(self.bouquet_root):
+                               self.pathUp()
+                       else:
+                               currentRoot = self.getRoot()
+                               if currentRoot is None or currentRoot != self.bouquet_root:
+                                       self.clearPath()
+                                       self.enterPath(self.bouquet_root)
 
        def keyNumberGlobal(self, number):
                char = self.numericalTextInput.getKey(number)
 
        def keyNumberGlobal(self, number):
                char = self.numericalTextInput.getKey(number)
@@ -365,90 +547,86 @@ class ChannelSelectionBase(Screen):
                return self.servicelist.getCurrent()
 
        def setCurrentSelection(self, service):
                return self.servicelist.getCurrent()
 
        def setCurrentSelection(self, service):
+               servicepath = service.getPath()
+               pos = servicepath.find(" FROM BOUQUET")
+               if pos != -1:
+                       servicepath = '(type == 1)' + servicepath[pos:]
+                       service.setPath(servicepath)
                self.servicelist.setCurrent(service)
 
        def cancel(self):
                self.close(None)
 
                self.servicelist.setCurrent(service)
 
        def cancel(self):
                self.close(None)
 
-class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit):
+       def getBouquetList(self):
+               serviceCount=0
+               bouquets = [ ]
+               serviceHandler = eServiceCenter.getInstance()
+               list = serviceHandler.list(self.bouquet_root)
+               if not list is None:
+                       while True:
+                               s = list.getNext()
+                               if not s.valid():
+                                       break
+                               if ((s.flags & eServiceReference.flagDirectory) == eServiceReference.flagDirectory):
+                                       info = serviceHandler.info(s)
+                                       if not info is None:
+                                               bouquets.append((info.getName(s), s))
+                               else:
+                                       serviceCount += 1
+                       if len(bouquets) == 0 and serviceCount > 0:
+                               info = serviceHandler.info(self.bouquet_root)
+                               if not info is None:
+                                       bouquets.append((info.getName(self.bouquet_root), self.bouquet_root))
+                       return bouquets
+               return None
+
+class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
        def __init__(self, session):
                ChannelSelectionBase.__init__(self,session)
                ChannelSelectionEdit.__init__(self)
        def __init__(self, session):
                ChannelSelectionBase.__init__(self,session)
                ChannelSelectionEdit.__init__(self)
+               ChannelSelectionEPG.__init__(self)
 
                #config for lastservice
                config.tv = ConfigSubsection();
                config.tv.lastservice = configElement("config.tv.lastservice", configText, "", 0);
                config.tv.lastroot = configElement("config.tv.lastroot", configText, "", 0);
 
                #config for lastservice
                config.tv = ConfigSubsection();
                config.tv.lastservice = configElement("config.tv.lastservice", configText, "", 0);
                config.tv.lastroot = configElement("config.tv.lastroot", configText, "", 0);
+               config.tv.prevservice = configElement("config.tv.prevservice", configText, "", 0);
+               config.tv.prevroot = configElement("config.tv.prevroot", configText, "", 0);
 
 
-               class ChannelActionMap(NumberActionMap):
-                       def action(self, contexts, action):
-                               if not self.csel.enterBouquet(action):
-                                       if action == "cancel":
-                                               self.csel.handleEditCancel()
-                                       NumberActionMap.action(self, contexts, action)
-               self["actions"] = ChannelActionMap(["ChannelSelectActions", "OkCancelActions", "ContextMenuActions"],
+               self["actions"] = ActionMap(["OkCancelActions"],
                        {
                                "cancel": self.cancel,
                                "ok": self.channelSelected,
                        {
                                "cancel": self.cancel,
                                "ok": self.channelSelected,
-                               "mark": self.doMark,
-                               "contextMenu": self.doContext,
-                               "showFavourites": self.showFavourites,
-                               "showAllServices": self.showAllServices,
-                               "showProviders": self.showProviders,
-                               "showSatellites": self.showSatellites,
-                               "showEPGList": self.showEPGList,
-                               "1": self.keyNumberGlobal,
-                               "2": self.keyNumberGlobal,
-                               "3": self.keyNumberGlobal,
-                               "4": self.keyNumberGlobal,
-                               "5": self.keyNumberGlobal,
-                               "6": self.keyNumberGlobal,
-                               "7": self.keyNumberGlobal,
-                               "8": self.keyNumberGlobal,
-                               "9": self.keyNumberGlobal,
-                               "0": self.keyNumberGlobal
                        })
                        })
-               self["actions"].csel = self
                self.onShown.append(self.onShow)
 
                self.onShown.append(self.onShow)
 
-#              self.onLayoutFinish.append(self.onCreate)
                self.lastChannelRootTimer = eTimer()
                self.lastChannelRootTimer.timeout.get().append(self.onCreate)
                self.lastChannelRootTimer.start(100,True)
 
        def onCreate(self):
                self.lastChannelRootTimer = eTimer()
                self.lastChannelRootTimer.timeout.get().append(self.onCreate)
                self.lastChannelRootTimer.start(100,True)
 
        def onCreate(self):
-               lastroot=eServiceReference(config.tv.lastroot.value)
-               if lastroot.valid():
-                       self.setRoot(lastroot)
-               else:
-                       self.showFavourites()
-                       self.saveRoot(self.getRoot())
+               self.setTvMode()
+               self.servicePathTV = [ ]
+               self.restoreRoot()
                lastservice=eServiceReference(config.tv.lastservice.value)
                if lastservice.valid():
                lastservice=eServiceReference(config.tv.lastservice.value)
                if lastservice.valid():
+                       self.setCurrentSelection(lastservice)
                        self.session.nav.playService(lastservice)
                        self.session.nav.playService(lastservice)
-                       self.servicelist.setCurrent(lastservice)
 
        def onShow(self):
 
        def onShow(self):
+               self.recallBouquetMode()
                ref = self.session.nav.getCurrentlyPlayingServiceReference()
                if ref is not None and ref.valid() and ref.getPath() == "":
                        self.servicelist.setPlayableIgnoreService(ref)
                else:
                        self.servicelist.setPlayableIgnoreService(eServiceReference())
 
                ref = self.session.nav.getCurrentlyPlayingServiceReference()
                if ref is not None and ref.valid() and ref.getPath() == "":
                        self.servicelist.setPlayableIgnoreService(ref)
                else:
                        self.servicelist.setPlayableIgnoreService(eServiceReference())
 
-       def showEPGList(self):
-               ref=self.getCurrentSelection()
-               ptr=eEPGCache.getInstance()
-               if ptr.startTimeQuery(ref) != -1:
-                       self.session.open(EPGSelection, ref)
-               else:
-                       print 'no epg for service', ref.toString()
-
        def channelSelected(self):
                ref = self.getCurrentSelection()
                if self.movemode:
                        self.toggleMoveMarked()
                elif (ref.flags & 7) == 7:
        def channelSelected(self):
                ref = self.getCurrentSelection()
                if self.movemode:
                        self.toggleMoveMarked()
                elif (ref.flags & 7) == 7:
-                       self.setRoot(ref)
+                       self.enterPath(ref)
                elif self.bouquet_mark_edit:
                        self.doMark()
                else:
                elif self.bouquet_mark_edit:
                        self.doMark()
                else:
@@ -461,32 +639,190 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit):
 
        #called from infoBar and channelSelected
        def zap(self):
 
        #called from infoBar and channelSelected
        def zap(self):
-               self.session.nav.playService(self.getCurrentSelection())
-               self.saveRoot(self.getRoot())
+               ref = self.session.nav.getCurrentlyPlayingServiceReference()
+               if ref is None or ref != self.getCurrentSelection():
+                       self.session.nav.playService(self.getCurrentSelection())
+               self.saveRoot()
                self.saveChannel()
 
                self.saveChannel()
 
-       def saveRoot(self, root):
-               if root is not None:
-                       config.tv.lastroot.value = root.toString()
+       def saveRoot(self):
+               path = ''
+               for i in self.servicePathTV:
+                       path += i.toString()
+                       path += ';'
+               if config.tv.prevroot.value != config.tv.lastroot.value:
+                       config.tv.prevroot.value = config.tv.lastroot.value
+                       config.tv.prevroot.save()
+               if len(path) and path != config.tv.lastroot.value:
+                       config.tv.lastroot.value = path
                        config.tv.lastroot.save()
 
                        config.tv.lastroot.save()
 
+       def restoreRoot(self):
+               self.servicePathTV = [ ]
+               re = compile('.+?;')
+               tmp = re.findall(config.tv.lastroot.value)
+               cnt = 0
+               for i in tmp:
+                       self.servicePathTV.append(eServiceReference(i[:len(i)-1]))
+                       cnt += 1
+               if cnt:
+                       path = self.servicePathTV.pop()
+                       self.enterPath(path)
+               else:
+                       self.showFavourites()
+                       self.saveRoot()
+
+       def preEnterPath(self, refstr):
+               if len(self.servicePathTV) and self.servicePathTV[0] != eServiceReference(refstr):
+                       pathstr = config.tv.lastroot.value
+                       if pathstr is not None and pathstr.find(refstr) == 0:
+                               self.restoreRoot()
+                               lastservice=eServiceReference(config.tv.lastservice.value)
+                               if lastservice is not None:
+                                       self.setCurrentSelection(lastservice)
+                               return True
+               return False
+
        def saveChannel(self):
                ref = self.session.nav.getCurrentlyPlayingServiceReference()
                if ref is not None:
                        refstr = ref.toString()
                else:
                        refstr = ""
        def saveChannel(self):
                ref = self.session.nav.getCurrentlyPlayingServiceReference()
                if ref is not None:
                        refstr = ref.toString()
                else:
                        refstr = ""
-               config.tv.lastservice.value = refstr
-               config.tv.lastservice.save()
+               if refstr != config.tv.lastservice.value:
+                       config.tv.prevservice.value = config.tv.lastservice.value
+                       config.tv.prevservice.save()
+                       config.tv.lastservice.value = refstr
+                       config.tv.lastservice.save()
+
+       def recallPrevService(self):
+               if len(config.tv.prevservice.value) and len(config.tv.prevroot.value):
+                       if config.tv.lastroot.value != config.tv.prevroot.value:
+                               tmp = config.tv.lastroot.value
+                               config.tv.lastroot.value = config.tv.prevroot.value
+                               config.tv.lastroot.save()
+                               config.tv.prevroot.value = tmp
+                               config.tv.prevroot.save()
+                               self.restoreRoot()
+                       if config.tv.lastservice.value != config.tv.prevservice.value:
+                               tmp = config.tv.lastservice.value
+                               config.tv.lastservice.value = config.tv.prevservice.value
+                               config.tv.lastservice.save()
+                               config.tv.prevservice.value = tmp
+                               config.tv.prevservice.save()
+                               lastservice=eServiceReference(config.tv.lastservice.value)
+                               self.session.nav.playService(lastservice)
+                               self.setCurrentSelection(lastservice)
 
        def cancel(self):
                self.close(None)
 
        def cancel(self):
                self.close(None)
-               lastroot=eServiceReference(config.tv.lastroot.value)
+               self.restoreRoot()
                lastservice=eServiceReference(config.tv.lastservice.value)
                lastservice=eServiceReference(config.tv.lastservice.value)
-               if lastroot.valid() and self.getRoot() != lastroot:
-                       self.setRoot(lastroot)
                if lastservice.valid() and self.getCurrentSelection() != lastservice:
                if lastservice.valid() and self.getCurrentSelection() != lastservice:
+                       self.setCurrentSelection(lastservice)
+
+from Screens.InfoBarGenerics import InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord
+
+class RadioInfoBar(Screen, InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord):
+       def __init__(self, session):
+               Screen.__init__(self, session)
+               InfoBarEvent.__init__(self)
+               InfoBarServiceName.__init__(self)
+               InfoBarInstantRecord.__init__(self)
+               self["Clock"] = Clock()
+
+class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
+       def __init__(self, session):
+               ChannelSelectionBase.__init__(self, session)
+               ChannelSelectionEdit.__init__(self)
+               ChannelSelectionEPG.__init__(self)
+
+               config.radio = ConfigSubsection();
+               config.radio.lastservice = configElement("config.radio.lastservice", configText, "", 0);
+               config.radio.lastroot = configElement("config.radio.lastroot", configText, "", 0);
+               self.onLayoutFinish.append(self.onCreate)
+
+               self.info = session.instantiateDialog(RadioInfoBar)
+
+               self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
+                       {
+                               "keyTV": self.closeRadio,
+                               "keyRadio": self.closeRadio,
+                               "cancel": self.closeRadio,
+                               "ok": self.channelSelected,
+                       })
+
+       def saveRoot(self):
+               path = ''
+               for i in self.servicePathRadio:
+                       path += i.toString()
+                       path += ';'
+               if len(path) and path != config.radio.lastroot.value:
+                       config.radio.lastroot.value = path
+                       config.radio.lastroot.save()
+
+       def restoreRoot(self):
+               self.servicePathRadio = [ ]
+               re = compile('.+?;')
+               tmp = re.findall(config.radio.lastroot.value)
+               cnt = 0
+               for i in tmp:
+                       self.servicePathRadio.append(eServiceReference(i[:len(i)-1]))
+                       cnt += 1
+               if cnt:
+                       path = self.servicePathRadio.pop()
+                       self.enterPath(path)
+               else:
+                       self.showFavourites()
+                       self.saveRoot()
+
+       def preEnterPath(self, refstr):
+               if len(self.servicePathRadio) and self.servicePathRadio[0] != eServiceReference(refstr):
+                       pathstr = config.radio.lastroot.value
+                       if pathstr is not None and pathstr.find(refstr) == 0:
+                               self.restoreRoot()
+                               lastservice=eServiceReference(config.radio.lastservice.value)
+                               if lastservice is not None:
+                                       self.setCurrentSelection(lastservice)
+                               return True
+               return False
+
+       def onCreate(self):
+               self.setRadioMode()
+               self.restoreRoot()
+               lastservice=eServiceReference(config.radio.lastservice.value)
+               if lastservice.valid():
                        self.servicelist.setCurrent(lastservice)
                        self.servicelist.setCurrent(lastservice)
+                       self.session.nav.playService(lastservice)
+                       self.servicelist.setPlayableIgnoreService(lastservice)
+               self.info.instance.show()
+
+       def channelSelected(self): # just return selected service
+               ref = self.getCurrentSelection()
+               if self.movemode:
+                       self.toggleMoveMarked()
+               elif (ref.flags & 7) == 7:
+                       self.enterPath(ref)
+               elif self.bouquet_mark_edit:
+                       self.doMark()
+               else:
+                       playingref = self.session.nav.getCurrentlyPlayingServiceReference()
+                       if playingref is None or playingref != ref:
+                               self.session.nav.playService(ref)
+                               self.servicelist.setPlayableIgnoreService(ref)
+                               config.radio.lastservice.value = ref.toString()
+                               config.radio.lastservice.save()
+                       self.saveRoot()
+
+       def setRoot(self, root, justSet=False):
+               self.setRootBase(root, justSet)
+
+       def closeRadio(self):
+               self.info.instance.hide()
+               #set previous tv service
+               lastservice=eServiceReference(config.tv.lastservice.value)
+               self.session.nav.playService(lastservice)
+               self.close(None)
 
 class SimpleChannelSelection(ChannelSelectionBase):
        def __init__(self, session, title):
 
 class SimpleChannelSelection(ChannelSelectionBase):
        def __init__(self, session, title):
@@ -494,40 +830,33 @@ class SimpleChannelSelection(ChannelSelectionBase):
                self.title = title
                self.onShown.append(self.onExecCallback)
 
                self.title = title
                self.onShown.append(self.onExecCallback)
 
-               class ChannelActionMap(NumberActionMap):
-                       def action(self, contexts, action):
-                               if not self.csel.enterBouquet(action):
-                                       NumberActionMap.action(self, contexts, action)
-               self["actions"] = ChannelActionMap(["ChannelSelectActions", "OkCancelActions", "ContextMenuActions"],
+               self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
                        {
                                "cancel": self.cancel,
                                "ok": self.channelSelected,
                        {
                                "cancel": self.cancel,
                                "ok": self.channelSelected,
-                               "showFavourites": self.showFavourites,
-                               "showAllServices": self.showAllServices,
-                               "showProviders": self.showProviders,
-                               "showSatellites": self.showSatellites,
-                               "1": self.keyNumberGlobal,
-                               "2": self.keyNumberGlobal,
-                               "3": self.keyNumberGlobal,
-                               "4": self.keyNumberGlobal,
-                               "5": self.keyNumberGlobal,
-                               "6": self.keyNumberGlobal,
-                               "7": self.keyNumberGlobal,
-                               "8": self.keyNumberGlobal,
-                               "9": self.keyNumberGlobal,
-                               "0": self.keyNumberGlobal
+                               "keyRadio": self.setModeRadio,
+                               "keyTV": self.setModeTv,
                        })
                        })
-               self["actions"].csel = self
 
        def onExecCallback(self):
 
        def onExecCallback(self):
-               print "onExecCallback"
-               self.showFavourites()
                self.session.currentDialog.instance.setTitle(self.title)
                self.session.currentDialog.instance.setTitle(self.title)
+               self.setModeTv()
 
        def channelSelected(self): # just return selected service
                ref = self.getCurrentSelection()
 
        def channelSelected(self): # just return selected service
                ref = self.getCurrentSelection()
-               self.close(ref)
+               if (ref.flags & 7) == 7:
+                       self.enterPath(ref)
+               else:
+                       ref = self.getCurrentSelection()
+                       self.close(ref)
+
+       def setRoot(self, root, justSet=False):
+               self.setRootBase(root, justSet)
 
 
-       def setRoot(self, root):
-               self.setRootBase(root)
+       def setModeTv(self):
+               self.setTvMode()
+               self.showFavourites()
 
 
+       def setModeRadio(self):
+               self.setRadioMode()
+               self.showFavourites()