add non working multi bouquet switch
[enigma2.git] / lib / python / Screens / ChannelSelection.py
index a7752274b530f6d7cca71bf19379f869312663c9..a5b6e0340c3d7abe0ed1194f1e4860523d38dc48 100644 (file)
@@ -8,12 +8,16 @@ from Components.config import config, configElement, ConfigSubsection, configTex
 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)
 
@@ -127,7 +122,7 @@ class ChannelSelectionEdit:
                        return self.mutableList
                serviceHandler = eServiceCenter.getInstance()
                if not root.valid():
                        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 +132,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 +192,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 +237,11 @@ class ChannelSelectionEdit:
        def doContext(self):
                self.session.open(ChannelContextMenu, self)
 
        def doContext(self):
                self.session.open(ChannelContextMenu, self)
 
+USE_MULTIBOUQUETS = False
+
+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 +250,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 +258,20 @@ 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 = [ ]
+
+       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 +279,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 +295,44 @@ class ChannelSelectionBase(Screen):
                                                offsetCount += 1
                return offsetCount
 
                                                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')
+               else:
+                       self.bouquet_root = eServiceReference('%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types))
+               title = self.instance.getTitle()
+               pos = title.find(" (")
+               if pos != -1:
+                       title = title[:pos]
+               title += " (TV)"
+               self.instance.setTitle(title)
+               self.mode = MODE_TV
+
+       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:
+                       title = title[:pos]
+               title += " (Radio)"
+               self.instance.setTitle(title)
+               self.mode = MODE_RADIO
+
        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 +343,110 @@ 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 showAllServices(self):
                ref = eServiceReference('%s ORDER BY name'%(self.service_types))
        def showAllServices(self):
                ref = eServiceReference('%s ORDER BY name'%(self.service_types))
-               self.setRoot(ref)
+               self.clearPath()
+               self.enterPath(ref)
 
        def showSatellites(self):
 
        def showSatellites(self):
+               justSet=False
+               prev = None
                ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types))
                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 += ' - %s'%(nimmanager.getSatDescription(orbpos))
-                                       service.setName(str(service_name)) # why we need this cast?
-                               except:
-                                       if orbpos > 1800: # west
-                                               service.setName("%s (%3.1fW)"%(str, (0 - (orbpos - 3600)) / 10.0))
+               if self.isBasePathEqual(ref):
+                       if self.isPrevPathEqual(ref):
+                               justSet=True
+                       prev = self.pathUp(justSet)
+               else:
+                       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:
                                        else:
-                                               service.setName("%s (%3.1fE)"%(str, orbpos / 10.0))
-                               self.servicelist.addService(service)
-               self.servicelist.finishFill()
+                                               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):
                ref = eServiceReference('%s FROM PROVIDERS ORDER BY name'%(self.service_types))
 
        def showProviders(self):
                ref = eServiceReference('%s FROM PROVIDERS ORDER BY name'%(self.service_types))
-               self.setRoot(ref)
+               if self.isBasePathEqual(ref):
+                       self.pathUp()
+               else:
+                       self.clearPath()
+                       self.enterPath(ref)
 
        def showFavourites(self):
 
        def showFavourites(self):
-               self.setRoot(self.bouquet_root)
+               if self.isBasePathEqual(self.bouquet_root):
+                       self.pathUp()
+               else:
+                       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,11 +470,39 @@ 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)
 
+       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):
        def __init__(self, session):
                ChannelSelectionBase.__init__(self,session)
 class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit):
        def __init__(self, session):
                ChannelSelectionBase.__init__(self,session)
@@ -379,6 +512,8 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit):
                config.tv = ConfigSubsection();
                config.tv.lastservice = configElement("config.tv.lastservice", configText, "", 0);
                config.tv.lastroot = configElement("config.tv.lastroot", configText, "", 0);
                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):
 
                class ChannelActionMap(NumberActionMap):
                        def action(self, contexts, action):
@@ -411,24 +546,21 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit):
                self["actions"].csel = self
                self.onShown.append(self.onShow)
 
                self["actions"].csel = self
                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.setTvMode()
                ref = self.session.nav.getCurrentlyPlayingServiceReference()
                if ref is not None and ref.valid() and ref.getPath() == "":
                        self.servicelist.setPlayableIgnoreService(ref)
                ref = self.session.nav.getCurrentlyPlayingServiceReference()
                if ref is not None and ref.valid() and ref.getPath() == "":
                        self.servicelist.setPlayableIgnoreService(ref)
@@ -448,7 +580,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit):
                if self.movemode:
                        self.toggleMoveMarked()
                elif (ref.flags & 7) == 7:
                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 +593,187 @@ 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())
+               if self.session.nav.getCurrentlyPlayingServiceReference() != 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 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)
+
+class ServiceInfoWindow(Screen):
+       def __init__(self, session):
+               Screen.__init__(self, session)
+               self["Service_Name"] = ServiceName(self.session.nav)
+               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):
+       def __init__(self, session):
+               ChannelSelectionBase.__init__(self, session)
+               ChannelSelectionEdit.__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)
+
+               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"],
+                       {
+                               "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 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 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:
+                       if self.session.nav.getCurrentlyPlayingServiceReference() != 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):
@@ -498,7 +785,7 @@ class SimpleChannelSelection(ChannelSelectionBase):
                        def action(self, contexts, action):
                                if not self.csel.enterBouquet(action):
                                        NumberActionMap.action(self, contexts, action)
                        def action(self, contexts, action):
                                if not self.csel.enterBouquet(action):
                                        NumberActionMap.action(self, contexts, action)
-               self["actions"] = ChannelActionMap(["ChannelSelectActions", "OkCancelActions", "ContextMenuActions"],
+               self["actions"] = ChannelActionMap(["ChannelSelectActions", "OkCancelActions", "ContextMenuActions", "TvRadioActions"],
                        {
                                "cancel": self.cancel,
                                "ok": self.channelSelected,
                        {
                                "cancel": self.cancel,
                                "ok": self.channelSelected,
@@ -506,6 +793,8 @@ class SimpleChannelSelection(ChannelSelectionBase):
                                "showAllServices": self.showAllServices,
                                "showProviders": self.showProviders,
                                "showSatellites": self.showSatellites,
                                "showAllServices": self.showAllServices,
                                "showProviders": self.showProviders,
                                "showSatellites": self.showSatellites,
+                               "keyRadio": self.setModeRadio,
+                               "keyTV": self.setModeTv,
                                "1": self.keyNumberGlobal,
                                "2": self.keyNumberGlobal,
                                "3": self.keyNumberGlobal,
                                "1": self.keyNumberGlobal,
                                "2": self.keyNumberGlobal,
                                "3": self.keyNumberGlobal,
@@ -520,14 +809,24 @@ class SimpleChannelSelection(ChannelSelectionBase):
                self["actions"].csel = self
 
        def onExecCallback(self):
                self["actions"].csel = 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):
-               self.setRootBase(root)
+       def setRoot(self, root, justSet=False):
+               self.setRootBase(root, justSet)
 
 
+       def setModeTv(self):
+               self.setTvMode()
+               self.showFavourites()
+
+       def setModeRadio(self):
+               self.setRadioMode()
+               self.showFavourites()