fix no more working color buttons in channellist after disable movemode
[enigma2.git] / lib / python / Screens / ChannelSelection.py
index d4a1e7cea08d9911cd5eece5d98f3b65efc7c0d2..9cc6be7d54a38f2737d6e991bf6557e86bdfa3df 100644 (file)
@@ -1,16 +1,17 @@
 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 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 Components.ServiceName import ServiceName
 from Components.Clock import Clock
 from Components.EventInfo import EventInfo
+from re import *
 
 import xml.dom.minidom
 
@@ -32,7 +33,7 @@ class ChannelContextMenu(FixedMenu):
 
                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
 
@@ -106,6 +107,21 @@ class ChannelContextMenu(FixedMenu):
                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
@@ -116,12 +132,28 @@ class ChannelSelectionEdit:
                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()
+                               elif action == "ok":
+                                       pass # avoid typo warning...
+                               else:
+                                       ActionMap.action(self, contexts, action)
+               self["ChannelSelectEditActions"] = ChannelSelectionEditActionMap(self, ["ChannelSelectEditActions", "OkCancelActions"],
+                       {
+                               "contextMenu": self.doContext,
+                       })
+
        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()
@@ -131,7 +163,7 @@ class ChannelSelectionEdit:
        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
@@ -191,7 +223,7 @@ class ChannelSelectionEdit:
                                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):
@@ -206,6 +238,7 @@ class ChannelSelectionEdit:
                        if self.entry_marked:
                                self.toggleMoveMarked() # unmark current entry
                        self.movemode = False
+                       self.pathChangedDisabled = False # re-enable path change
                        self.mutableList.flushChanges() # FIXME add check if changes was made
                        self.mutableList = None
                        self.instance.setTitle(self.saved_title)
@@ -213,6 +246,7 @@ class ChannelSelectionEdit:
                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]");
@@ -236,8 +270,6 @@ class ChannelSelectionEdit:
        def doContext(self):
                self.session.open(ChannelContextMenu, self)
 
-USE_MULTIBOUQUETS = False
-
 MODE_TV = 0
 MODE_RADIO = 1
 
@@ -259,6 +291,29 @@ class ChannelSelectionBase(Screen):
 
                self.numericalTextInput = NumericalTextInput()
 
+               self.servicePathTV = [ ]
+               self.servicePathRadio = [ ]
+
+               self.pathChangedDisabled = False
+
+               self["ChannelSelectBaseActions"] = NumberActionMap(["ChannelSelectBaseActions", "NumberActions"],
+                       {
+                               "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')
@@ -291,12 +346,22 @@ class ChannelSelectionBase(Screen):
                                                offsetCount += 1
                return offsetCount
 
-       def setTvMode(self):
-               self.service_types = self.service_types_tv
-               if USE_MULTIBOUQUETS:
-                       self.bouquet_root = eServiceReference('1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.tv" ORDER BY bouquet')
+       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.bouquet_root = eServiceReference('%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types))
+                       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:
@@ -304,13 +369,9 @@ class ChannelSelectionBase(Screen):
                title += " (TV)"
                self.instance.setTitle(title)
                self.mode = MODE_TV
+               self.recallBouquetMode()
 
        def setRadioMode(self):
-               self.service_types = self.service_types_radio
-               if USE_MULTIBOUQUETS:
-                       self.bouquet_root = eServiceReference('1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "bouquets.radio" ORDER BY bouquet')
-               else:
-                       self.bouquet_root = eServiceReference('%s FROM BOUQUET "userbouquet.favourites.radio" ORDER BY bouquet'%(self.service_types))
                title = self.instance.getTitle()
                pos = title.find(" (")
                if pos != -1:
@@ -318,8 +379,9 @@ class ChannelSelectionBase(Screen):
                title += " (Radio)"
                self.instance.setTitle(title)
                self.mode = MODE_RADIO
+               self.recallBouquetMode()
 
-       def setRootBase(self, root, justSet=False):
+       def setRoot(self, root, justSet=False):
                path = root.getPath()
                inBouquetRootList = path.find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK
                pos = path.find(' FROM BOUQUET')
@@ -339,42 +401,138 @@ class ChannelSelectionBase(Screen):
        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:
+                       print "MODE_TV"
+                       prev = self.servicePathTV.pop()
+                       print "prev", prev.toString()
+                       length = len(self.servicePathTV)
+                       print "length", length
+                       if length:
+                               current = self.servicePathTV[length-1]
+                               print "current", current.toString()
+               else:
+                       prev = self.servicePathRadio.pop()
+                       length = len(self.servicePathRadio)
+                       if length:
+                               current = self.servicePathRadio[length-1]
+               self.setRoot(current, justSet)
+               if not justSet:
+                       print "setCurrentSelection prev"
+                       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):
-               ref = eServiceReference('%s ORDER BY name'%(self.service_types))
-               self.setRoot(ref)
+               if not self.pathChangedDisabled:
+                       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):
-               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")
+               if not self.pathChangedDisabled:
+                       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:
-                                       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()
+                                       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))
+                                                       self.servicelist.addService(service)
+                                                       self.servicelist.finishFill()
+                                                       if prev is not None:
+                                                               self.setCurrentSelection(prev)
 
        def showProviders(self):
-               ref = eServiceReference('%s FROM PROVIDERS ORDER BY name'%(self.service_types))
-               self.setRoot(ref)
+               if not self.pathChangedDisabled:
+                       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):
-               self.setRoot(self.bouquet_root)
+               if not self.pathChangedDisabled:
+                       if not self.preEnterPath(self.bouquet_rootstr):
+                               if self.isBasePathEqual(self.bouquet_root):
+                                       print "basepath equal"
+                                       self.pathUp()
+                               else:
+                                       print "basepath not equal"
+                                       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)
@@ -382,15 +540,6 @@ class ChannelSelectionBase(Screen):
                print "You would go to character " + str(char)
                self.servicelist.moveToChar(char)
 
-       def enterBouquet(self, action):
-               if action[:7] == "bouquet":
-                       if action.find("FROM BOUQUET") != -1:
-                               self.setRoot(eServiceReference("1:7:1:0:0:0:0:0:0:0:" + action[8:]))
-                       else:
-                               self.setRoot(eServiceReference("1:0:1:0:0:0:0:0:0:0:" + action[8:]))
-                       return True
-               return False
-
        def getRoot(self):
                return self.servicelist.getRoot()
 
@@ -398,11 +547,16 @@ class ChannelSelectionBase(Screen):
                return self.servicelist.getCurrent()
 
        def setCurrentSelection(self, service):
+               servicepath = service.getPath()
+               pos = servicepath.find(" FROM BOUQUET")
+               if pos != -1:
+                       if self.mode == MODE_TV:
+                               servicepath = '(type == 1)' + servicepath[pos:]
+                       else:
+                               servicepath = '(type == 2)' + servicepath[pos:]
+                       service.setPath(servicepath)
                self.servicelist.setCurrent(service)
 
-       def cancel(self):
-               self.close(None)
-
        def getBouquetList(self):
                serviceCount=0
                bouquets = [ ]
@@ -426,45 +580,24 @@ class ChannelSelectionBase(Screen):
                        return bouquets
                return None
 
-class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit):
+class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
        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.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,
-                               "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.lastChannelRootTimer = eTimer()
@@ -473,138 +606,186 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit):
 
        def onCreate(self):
                self.setTvMode()
-               lastroot=eServiceReference(config.tv.lastroot.value)
-               if lastroot.valid():
-                       self.setRoot(lastroot)
-               else:
-                       self.showFavourites()
-                       self.saveRoot(self.getRoot())
-
+               self.servicePathTV = [ ]
+               self.restoreRoot()
                lastservice=eServiceReference(config.tv.lastservice.value)
                if lastservice.valid():
-                       self.servicelist.setCurrent(lastservice)
+                       self.setCurrentSelection(lastservice)
                        self.session.nav.playService(lastservice)
 
        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())
 
-       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:
-                       self.setRoot(ref)
+                       self.enterPath(ref)
                elif self.bouquet_mark_edit:
                        self.doMark()
                else:
                        self.zap()
                        self.close(ref)
 
-       def setRoot(self, root, justSet=False):
-               if not self.movemode:
-                       self.setRootBase(root, justSet)
-
        #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()
 
-       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()
 
+       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 = ""
-               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)
-               lastroot=eServiceReference(config.tv.lastroot.value)
+               self.restoreRoot()
                lastservice=eServiceReference(config.tv.lastservice.value)
-               if lastroot.valid() and self.getRoot() != lastroot:
-                       self.setRoot(lastroot)
                if lastservice.valid() and self.getCurrentSelection() != lastservice:
-                       self.servicelist.setCurrent(lastservice)
+                       self.setCurrentSelection(lastservice)
+
+from Screens.InfoBarGenerics import InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord
 
-class ServiceInfoWindow(Screen):
+class RadioInfoBar(Screen, InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord):
        def __init__(self, session):
                Screen.__init__(self, session)
-               self["Service_Name"] = ServiceName(self.session.nav)
+               InfoBarEvent.__init__(self)
+               InfoBarServiceName.__init__(self)
+               InfoBarInstantRecord.__init__(self)
                self["Clock"] = Clock()
-               self["Event_Now_StartTime"] = EventInfo(self.session.nav, EventInfo.Now_StartTime)
-               self["Event_Next_StartTime"] = EventInfo(self.session.nav, EventInfo.Next_StartTime)
-               self["Event_Now"] = EventInfo(self.session.nav, EventInfo.Now)
-               self["Event_Next"] = EventInfo(self.session.nav, EventInfo.Next)
-               self["Event_Now_Duration"] = EventInfo(self.session.nav, EventInfo.Now_Duration)
-               self["Event_Next_Duration"] = EventInfo(self.session.nav, EventInfo.Next_Duration)
-
-class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit):
+
+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(ServiceInfoWindow)
+               self.info = session.instantiateDialog(RadioInfoBar)
 
-               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", "TvRadioActions"],
+               self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
                        {
                                "keyTV": self.closeRadio,
                                "keyRadio": self.closeRadio,
-                               "contextMenu": self.doContext,
                                "cancel": self.closeRadio,
                                "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
                        })
-               self["actions"].csel = self
 
-       def onCreate(self):
-               self.setRadioMode()
-               lastroot=eServiceReference(config.radio.lastroot.value)
-               if lastroot.valid():
-                       self.setRoot(lastroot)
+       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(self.getRoot())
+                       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)
@@ -617,19 +798,17 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit):
                if self.movemode:
                        self.toggleMoveMarked()
                elif (ref.flags & 7) == 7:
-                       self.setRoot(ref)
+                       self.enterPath(ref)
                elif self.bouquet_mark_edit:
                        self.doMark()
                else:
-                       self.session.nav.playService(ref)
-                       self.servicelist.setPlayableIgnoreService(ref)
-                       config.radio.lastservice.value = ref.toString()
-                       config.radio.lastservice.save()
-                       config.radio.lastroot.value = self.getRoot().toString()
-                       config.radio.lastroot.save()
-               
-       def setRoot(self, root, justSet=False):
-               self.setRootBase(root, justSet)
+                       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 closeRadio(self):
                self.info.instance.hide()
@@ -644,32 +823,13 @@ class SimpleChannelSelection(ChannelSelectionBase):
                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", "TvRadioActions"],
+               self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
                        {
                                "cancel": self.cancel,
                                "ok": self.channelSelected,
-                               "showFavourites": self.showFavourites,
-                               "showAllServices": self.showAllServices,
-                               "showProviders": self.showProviders,
-                               "showSatellites": self.showSatellites,
                                "keyRadio": self.setModeRadio,
                                "keyTV": self.setModeTv,
-                               "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
 
        def onExecCallback(self):
                self.session.currentDialog.instance.setTitle(self.title)
@@ -678,14 +838,11 @@ class SimpleChannelSelection(ChannelSelectionBase):
        def channelSelected(self): # just return selected service
                ref = self.getCurrentSelection()
                if (ref.flags & 7) == 7:
-                       self.setRoot(ref)
+                       self.enterPath(ref)
                else:
                        ref = self.getCurrentSelection()
                        self.close(ref)
 
-       def setRoot(self, root, justSet=False):
-               self.setRootBase(root, justSet)
-
        def setModeTv(self):
                self.setTvMode()
                self.showFavourites()