Support turbo2.
[vuplus_dvbapp] / lib / python / Screens / ChannelSelection.py
old mode 100644 (file)
new mode 100755 (executable)
index e8bbce1..6882a93
@@ -8,7 +8,7 @@ from Components.MenuList import MenuList
 from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase
 profile("ChannelSelection.py 1")
 from EpgSelection import EPGSelection
 from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase
 profile("ChannelSelection.py 1")
 from EpgSelection import EPGSelection
-from enigma import eServiceReference, eEPGCache, eServiceCenter, eRCInput, eTimer, eDVBDB, iPlayableService, iServiceInformation, getPrevAsciiCode
+from enigma import eServiceReference, eEPGCache, eServiceCenter, eRCInput, eTimer, eDVBDB, iPlayableService, iServiceInformation, getPrevAsciiCode, eEnv
 from Components.config import config, ConfigSubsection, ConfigText
 from Tools.NumericalTextInput import NumericalTextInput
 profile("ChannelSelection.py 2")
 from Components.config import config, ConfigSubsection, ConfigText
 from Tools.NumericalTextInput import NumericalTextInput
 profile("ChannelSelection.py 2")
@@ -20,8 +20,8 @@ from Components.Sources.ServiceEvent import ServiceEvent
 profile("ChannelSelection.py 2.3")
 from Components.Input import Input
 profile("ChannelSelection.py 3")
 profile("ChannelSelection.py 2.3")
 from Components.Input import Input
 profile("ChannelSelection.py 3")
-from Components.ParentalControl import parentalControl
 from Components.ChoiceList import ChoiceList, ChoiceEntryComponent
 from Components.ChoiceList import ChoiceList, ChoiceEntryComponent
+from Components.SystemInfo import SystemInfo
 from Screens.InputBox import InputBox, PinInput
 from Screens.MessageBox import MessageBox
 from Screens.ServiceInfo import ServiceInfo
 from Screens.InputBox import InputBox, PinInput
 from Screens.MessageBox import MessageBox
 from Screens.ServiceInfo import ServiceInfo
@@ -30,7 +30,6 @@ from Screens.PictureInPicture import PictureInPicture
 from Screens.RdsDisplay import RassInteractive
 from ServiceReference import ServiceReference
 from Tools.BoundFunction import boundFunction
 from Screens.RdsDisplay import RassInteractive
 from ServiceReference import ServiceReference
 from Tools.BoundFunction import boundFunction
-from re import compile
 from os import remove
 profile("ChannelSelection.py after imports")
 
 from os import remove
 profile("ChannelSelection.py after imports")
 
@@ -66,6 +65,24 @@ class BouquetSelector(Screen):
        def cancelClick(self):
                self.close(False)
 
        def cancelClick(self):
                self.close(False)
 
+class SilentBouquetSelector:
+       def __init__(self, bouquets, enableWrapAround=False, current=0):
+               self.bouquets = [b[1] for b in bouquets]
+               self.pos = current
+               self.count = len(bouquets)
+               self.enableWrapAround = enableWrapAround
+
+       def up(self):
+               if self.pos > 0 or self.enableWrapAround:
+                       self.pos = (self.pos - 1) % self.count
+
+       def down(self):
+               if self.pos < (self.count - 1) or self.enableWrapAround:
+                       self.pos = (self.pos + 1) % self.count
+
+       def getCurrent(self):
+               return self.bouquets[self.pos]
+
 # csel.bouquet_mark_edit values
 OFF = 0
 EDIT_BOUQUET = 1
 # csel.bouquet_mark_edit values
 OFF = 0
 EDIT_BOUQUET = 1
@@ -77,6 +94,7 @@ def append_when_current_valid(current, menu, args, level = 0, key = ""):
 
 class ChannelContextMenu(Screen):
        def __init__(self, session, csel):
 
 class ChannelContextMenu(Screen):
        def __init__(self, session, csel):
+
                Screen.__init__(self, session)
                #raise Exception("we need a better summary screen here")
                self.csel = csel
                Screen.__init__(self, session)
                #raise Exception("we need a better summary screen here")
                self.csel = csel
@@ -106,17 +124,31 @@ class ChannelContextMenu(Screen):
                                isPlayable = not (current_sel_flags & (eServiceReference.isMarker|eServiceReference.isDirectory))
                                if isPlayable:
                                        if config.ParentalControl.configured.value:
                                isPlayable = not (current_sel_flags & (eServiceReference.isMarker|eServiceReference.isDirectory))
                                if isPlayable:
                                        if config.ParentalControl.configured.value:
+                                               from Components.ParentalControl import parentalControl
                                                if parentalControl.getProtectionLevel(csel.getCurrentSelection().toCompareString()) == -1:
                                                        append_when_current_valid(current, menu, (_("add to parental protection"), boundFunction(self.addParentalProtection, csel.getCurrentSelection())), level = 0)
                                                else:
                                                        append_when_current_valid(current, menu, (_("remove from parental protection"), boundFunction(self.removeParentalProtection, csel.getCurrentSelection())), level = 0)
                                        if haveBouquets:
                                                if parentalControl.getProtectionLevel(csel.getCurrentSelection().toCompareString()) == -1:
                                                        append_when_current_valid(current, menu, (_("add to parental protection"), boundFunction(self.addParentalProtection, csel.getCurrentSelection())), level = 0)
                                                else:
                                                        append_when_current_valid(current, menu, (_("remove from parental protection"), boundFunction(self.removeParentalProtection, csel.getCurrentSelection())), level = 0)
                                        if haveBouquets:
-                                               append_when_current_valid(current, menu, (_("add service to bouquet"), self.addServiceToBouquetSelected), level = 0)
+                                               bouquets = self.csel.getBouquetList()
+                                               if bouquets is None:
+                                                       bouquetCnt = 0
+                                               else:
+                                                       bouquetCnt = len(bouquets)
+                                               if not inBouquet or bouquetCnt > 1:
+                                                       append_when_current_valid(current, menu, (_("add service to bouquet"), self.addServiceToBouquetSelected), level = 0)
                                        else:
                                        else:
-                                               append_when_current_valid(current, menu, (_("add service to favourites"), self.addServiceToBouquetSelected), level = 0)
+                                               if not inBouquet:
+                                                       append_when_current_valid(current, menu, (_("add service to favourites"), self.addServiceToBouquetSelected), level = 0)
                                else:
                                else:
-                                       if current_root.getPath().find('FROM SATELLITES') != -1:
-                                               append_when_current_valid(current, menu, (_("remove selected satellite"), self.removeSatelliteServices), level = 0)
+                                       if 'FROM SATELLITES' in current_root.getPath() and _("Services") in eServiceCenter.getInstance().info(current).getName(current):
+                                               unsigned_orbpos = current.getUnsignedData(4) >> 16
+                                               if unsigned_orbpos == 0xFFFF: #Cable
+                                                       append_when_current_valid(current, menu, (_("remove cable services"), self.removeSatelliteServices), level = 0)
+                                               elif unsigned_orbpos == 0xEEEE: #Terrestrial
+                                                       append_when_current_valid(current, menu, (_("remove terrestrial services"), self.removeSatelliteServices), level = 0)
+                                               else:
+                                                       append_when_current_valid(current, menu, (_("remove selected satellite"), self.removeSatelliteServices), level = 0)
                                        if haveBouquets:
                                                if not inBouquet and current_sel_path.find("PROVIDERS") == -1:
                                                        append_when_current_valid(current, menu, (_("copy to bouquets"), self.copyCurrentToBouquetList), level = 0)
                                        if haveBouquets:
                                                if not inBouquet and current_sel_path.find("PROVIDERS") == -1:
                                                        append_when_current_valid(current, menu, (_("copy to bouquets"), self.copyCurrentToBouquetList), level = 0)
@@ -126,7 +158,7 @@ class ChannelContextMenu(Screen):
                                        append_when_current_valid(current, menu, (_("remove entry"), self.removeCurrentService), level = 0)
                                if current_root and current_root.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
                                        append_when_current_valid(current, menu, (_("remove new found flag"), self.removeNewFoundFlag), level = 0)
                                        append_when_current_valid(current, menu, (_("remove entry"), self.removeCurrentService), level = 0)
                                if current_root and current_root.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
                                        append_when_current_valid(current, menu, (_("remove new found flag"), self.removeNewFoundFlag), level = 0)
-                               if isPlayable:
+                               if isPlayable and SystemInfo.get("NumVideoDecoders", 1) > 1:
                                        append_when_current_valid(current, menu, (_("Activate Picture in Picture"), self.showServiceInPiP), level = 0, key = "blue")
                                        self.pipAvailable = True
                        else:
                                        append_when_current_valid(current, menu, (_("Activate Picture in Picture"), self.showServiceInPiP), level = 0, key = "blue")
                                        self.pipAvailable = True
                        else:
@@ -184,6 +216,7 @@ class ChannelContextMenu(Screen):
                self.close()
 
        def addParentalProtection(self, service):
                self.close()
 
        def addParentalProtection(self, service):
+               from Components.ParentalControl import parentalControl
                parentalControl.protectService(service.toCompareString())
                self.close()
 
                parentalControl.protectService(service.toCompareString())
                self.close()
 
@@ -192,6 +225,7 @@ class ChannelContextMenu(Screen):
 
        def pinEntered(self, service, result):
                if result:
 
        def pinEntered(self, service, result):
                if result:
+                       from Components.ParentalControl import parentalControl
                        parentalControl.unProtectService(service)
                        self.close()
                else:
                        parentalControl.unProtectService(service)
                        self.close()
                else:
@@ -203,12 +237,13 @@ class ChannelContextMenu(Screen):
                if self.session.pipshown:
                        del self.session.pip
                self.session.pip = self.session.instantiateDialog(PictureInPicture)
                if self.session.pipshown:
                        del self.session.pip
                self.session.pip = self.session.instantiateDialog(PictureInPicture)
+               self.session.pip.setAnimationMode(0)
                self.session.pip.show()
                newservice = self.csel.servicelist.getCurrent()
                if self.session.pip.playService(newservice):
                        self.session.pipshown = True
                        self.session.pip.servicePath = self.csel.getCurrentServicePath()
                self.session.pip.show()
                newservice = self.csel.servicelist.getCurrent()
                if self.session.pip.playService(newservice):
                        self.session.pipshown = True
                        self.session.pip.servicePath = self.csel.getCurrentServicePath()
-                       self.close()
+                       self.close(True)
                else:
                        self.session.pipshown = False
                        del self.session.pip
                else:
                        self.session.pipshown = False
                        del self.session.pip
@@ -223,7 +258,7 @@ class ChannelContextMenu(Screen):
                if cnt > 1: # show bouquet list
                        self.bsel = self.session.openWithCallback(self.bouquetSelClosed, BouquetSelector, bouquets, self.addCurrentServiceToBouquet)
                elif cnt == 1: # add to only one existing bouquet
                if cnt > 1: # show bouquet list
                        self.bsel = self.session.openWithCallback(self.bouquetSelClosed, BouquetSelector, bouquets, self.addCurrentServiceToBouquet)
                elif cnt == 1: # add to only one existing bouquet
-                       self.addCurrentServiceToBouquet(bouquets[0][1])
+                       self.addCurrentServiceToBouquet(bouquets[0][1], closeBouquetSelection = False)
 
        def bouquetSelClosed(self, recursive):
                self.bsel = None
 
        def bouquetSelClosed(self, recursive):
                self.bsel = None
@@ -231,14 +266,7 @@ class ChannelContextMenu(Screen):
                        self.close(False)
 
        def removeSatelliteServices(self):
                        self.close(False)
 
        def removeSatelliteServices(self):
-               curpath = self.csel.getCurrentSelection().getPath()
-               idx = curpath.find("satellitePosition == ")
-               if idx != -1:
-                       tmp = curpath[idx+21:]
-                       idx = tmp.find(')')
-                       if idx != -1:
-                               satpos = int(tmp[:idx])
-                               eDVBDB.getInstance().removeServices(-1, -1, -1, satpos)
+               self.csel.removeSatelliteServices()
                self.close()
 
        def copyCurrentToBouquetList(self):
                self.close()
 
        def copyCurrentToBouquetList(self):
@@ -257,12 +285,12 @@ class ChannelContextMenu(Screen):
                        self.csel.addMarker(marker)
                self.close()
 
                        self.csel.addMarker(marker)
                self.close()
 
-       def addCurrentServiceToBouquet(self, dest):
+       def addCurrentServiceToBouquet(self, dest, closeBouquetSelection = True):
                self.csel.addServiceToBouquet(dest)
                if self.bsel is not None:
                        self.bsel.close(True)
                else:
                self.csel.addServiceToBouquet(dest)
                if self.bsel is not None:
                        self.bsel.close(True)
                else:
-                       self.close(True) # close bouquet selection
+                       self.close(closeBouquetSelection) # close bouquet selection
 
        def removeCurrentService(self):
                self.csel.removeCurrentService()
 
        def removeCurrentService(self):
                self.csel.removeCurrentService()
@@ -449,7 +477,7 @@ class ChannelSelectionEdit:
                                if mutableAlternatives:
                                        mutableAlternatives.setListName(name)
                                        if mutableAlternatives.addService(cur_service.ref):
                                if mutableAlternatives:
                                        mutableAlternatives.setListName(name)
                                        if mutableAlternatives.addService(cur_service.ref):
-                                               print "add", cur_service.toString(), "to new alternatives failed"
+                                               print "add", cur_service.ref.toString(), "to new alternatives failed"
                                        mutableAlternatives.flushChanges()
                                        self.servicelist.addService(new_ref.ref, True)
                                        self.servicelist.removeCurrent()
                                        mutableAlternatives.flushChanges()
                                        self.servicelist.addService(new_ref.ref, True)
                                        self.servicelist.removeCurrent()
@@ -534,7 +562,7 @@ class ChannelSelectionEdit:
                        refstr = refstr[pos+14:]
                        pos = refstr.find('"')
                        if pos != -1:
                        refstr = refstr[pos+14:]
                        pos = refstr.find('"')
                        if pos != -1:
-                               filename = '/etc/enigma2/' + refstr[:pos] # FIXMEEE !!! HARDCODED /etc/enigma2
+                               filename = eEnv.resolve('${sysconfdir}/enigma2/') + refstr[:pos]
                self.removeCurrentService()
                try:
                        if filename is not None:
                self.removeCurrentService()
                try:
                        if filename is not None:
@@ -542,6 +570,55 @@ class ChannelSelectionEdit:
                except OSError:
                        print "error during remove of", filename
 
                except OSError:
                        print "error during remove of", filename
 
+       def removeSatelliteServices(self):
+               current = self.getCurrentSelection()
+               unsigned_orbpos = current.getUnsignedData(4) >> 16
+               if unsigned_orbpos == 0XFFFF:
+                       msg = _("Are you sure to remove all cable services?")
+               elif unsigned_orbpos == 0XEEEE:
+                       msg = _("Are you sure to remove all terrestrial services?")
+               else:
+                       orbpos = current.getData(4) >> 16
+                       try:
+                               service_name = str(nimmanager.getSatDescription(orbpos))
+                       except:
+                               if orbpos > 1800: # west
+                                       orbpos = 3600 - orbpos
+                                       h = _("W")
+                               else:
+                                       h = _("E")
+                               service_name = ("%d.%d" + h) % (orbpos / 10, orbpos % 10)
+                       msg = _("Are you sure to remove all %s services?" % service_name)
+               self.session.openWithCallback(self.removeSatelliteServicesCallback, MessageBox, msg)
+
+       def removeSatelliteServicesCallback(self, res):
+               if not res:
+                       return
+
+               currentIndex = self.servicelist.getCurrentIndex()
+               current = self.getCurrentSelection()
+               unsigned_orbpos = current.getUnsignedData(4) >> 16
+               if unsigned_orbpos == 0XFFFF:
+                       eDVBDB.getInstance().removeServices(0xFFFF0000 - 0x100000000)
+               elif unsigned_orbpos == 0XEEEE:
+                       eDVBDB.getInstance().removeServices(0xEEEE0000 - 0x100000000)
+               else:
+                       curpath = self.getCurrentSelection().getPath()
+                       idx = curpath.find("satellitePosition == ")
+                       if idx != -1:
+                               tmp = curpath[idx+21:]
+                               idx = tmp.find(')')
+                               if idx != -1:
+                                       satpos = int(tmp[:idx])
+                                       eDVBDB.getInstance().removeServices(-1, -1, -1, satpos)
+
+               if hasattr(self, 'setMode') and hasattr(self, 'showSatellites'):
+                       self.setMode()
+                       self.showSatellites()
+                       self.servicelist.moveToIndex(currentIndex)
+                       if currentIndex != self.servicelist.getCurrentIndex():
+                               self.servicelist.instance.moveSelection(self.servicelist.instance.moveEnd)
+
 #  multiple marked entry stuff ( edit mode, later multiepg selection )
        def startMarkedEdit(self, type):
                self.savedPath = self.servicePath[:]
 #  multiple marked entry stuff ( edit mode, later multiepg selection )
        def startMarkedEdit(self, type):
                self.savedPath = self.servicePath[:]
@@ -672,7 +749,11 @@ class ChannelSelectionEdit:
                        self.entry_marked = True
 
        def doContext(self):
                        self.entry_marked = True
 
        def doContext(self):
-               self.session.open(ChannelContextMenu, self)
+               self.session.openWithCallback(self.exitContext, ChannelContextMenu, self)
+               
+       def exitContext(self, close = False):
+               if close:
+                       self.cancel()
 
 MODE_TV = 0
 MODE_RADIO = 1
 
 MODE_TV = 0
 MODE_RADIO = 1
@@ -686,8 +767,9 @@ MODE_RADIO = 1
 # type 27 = advanced codec HD NVOD reference service (NYI)
 # type 2 = digital radio sound service
 # type 10 = advanced codec digital radio sound service
 # type 27 = advanced codec HD NVOD reference service (NYI)
 # type 2 = digital radio sound service
 # type 10 = advanced codec digital radio sound service
+# type 31 = High Efficiency Video Coing digital television
 
 
-service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 22) || (type == 25) || (type == 134) || (type == 195)'
+service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 22) || (type == 25) || (type == 31) || (type == 134) || (type == 195)'
 service_types_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2) || (type == 10)'
 
 class ChannelSelectionBase(Screen):
 service_types_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2) || (type == 10)'
 
 class ChannelSelectionBase(Screen):
@@ -708,6 +790,7 @@ class ChannelSelectionBase(Screen):
                self.servicePathTV = [ ]
                self.servicePathRadio = [ ]
                self.servicePath = [ ]
                self.servicePathTV = [ ]
                self.servicePathRadio = [ ]
                self.servicePath = [ ]
+               self.rootChanged = False
 
                self.mode = MODE_TV
 
 
                self.mode = MODE_TV
 
@@ -814,6 +897,7 @@ class ChannelSelectionBase(Screen):
                else:
                        self.servicelist.setMode(ServiceList.MODE_NORMAL)
                self.servicelist.setRoot(root, justSet)
                else:
                        self.servicelist.setMode(ServiceList.MODE_NORMAL)
                self.servicelist.setRoot(root, justSet)
+               self.rootChanged = True
                self.buildTitleString()
 
        def removeModeStr(self, str):
                self.buildTitleString()
 
        def removeModeStr(self, str):
@@ -1040,7 +1124,13 @@ class ChannelSelectionBase(Screen):
                        self.servicelist.moveToChar(charstr[0])
 
        def keyAsciiCode(self):
                        self.servicelist.moveToChar(charstr[0])
 
        def keyAsciiCode(self):
-               unichar = unichr(getPrevAsciiCode())
+               #unichar = unichr(getPrevAsciiCode())
+               from Components.config import getCharValue
+               unichar = getCharValue(getPrevAsciiCode())
+               if unichar is None:
+                       return
+               if len(str(unichar)) > 1:
+                       return
                charstr = unichar.encode("utf-8")
                if len(charstr) == 1:
                        self.servicelist.moveToChar(charstr[0])
                charstr = unichar.encode("utf-8")
                if len(charstr) == 1:
                        self.servicelist.moveToChar(charstr[0])
@@ -1175,6 +1265,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                self.servicelist.setPlayableIgnoreService(eServiceReference())
 
        def setMode(self):
                self.servicelist.setPlayableIgnoreService(eServiceReference())
 
        def setMode(self):
+               self.rootChanged = True
                self.restoreRoot()
                lastservice=eServiceReference(self.lastservice.value)
                if lastservice.valid():
                self.restoreRoot()
                lastservice=eServiceReference(self.lastservice.value)
                if lastservice.valid():
@@ -1298,19 +1389,21 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                        self.lastroot.save()
 
        def restoreRoot(self):
                        self.lastroot.save()
 
        def restoreRoot(self):
-               self.clearPath()
-               re = compile('.+?;')
-               tmp = re.findall(self.lastroot.value)
-               cnt = 0
-               for i in tmp:
-                       self.servicePath.append(eServiceReference(i[:-1]))
-                       cnt += 1
-               if cnt:
-                       path = self.servicePath.pop()
-                       self.enterPath(path)
-               else:
-                       self.showFavourites()
-                       self.saveRoot()
+               tmp = [x for x in self.lastroot.value.split(';') if x != '']
+               current = [x.toString() for x in self.servicePath]
+               if tmp != current or self.rootChanged:
+                       self.clearPath()
+                       cnt = 0
+                       for i in tmp:
+                               self.servicePath.append(eServiceReference(i))
+                               cnt += 1
+                       if cnt:
+                               path = self.servicePath.pop()
+                               self.enterPath(path)
+                       else:
+                               self.showFavourites()
+                               self.saveRoot()
+                       self.rootChanged = False
 
        def preEnterPath(self, refstr):
                if self.servicePath and self.servicePath[0] != eServiceReference(refstr):
 
        def preEnterPath(self, refstr):
                if self.servicePath and self.servicePath[0] != eServiceReference(refstr):
@@ -1388,12 +1481,13 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                self.onLayoutFinish.append(self.onCreate)
 
                self.info = session.instantiateDialog(RadioInfoBar) # our simple infobar
                self.onLayoutFinish.append(self.onCreate)
 
                self.info = session.instantiateDialog(RadioInfoBar) # our simple infobar
+               self.info.setAnimationMode(0)
 
                self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
                        {
 
                self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
                        {
-                               "keyTV": self.closeRadio,
-                               "keyRadio": self.closeRadio,
-                               "cancel": self.closeRadio,
+                               "keyTV": self.cancel,
+                               "keyRadio": self.cancel,
+                               "cancel": self.cancel,
                                "ok": self.channelSelected,
                        })
 
                                "ok": self.channelSelected,
                        })
 
@@ -1431,7 +1525,7 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                self["RdsActions"].setEnabled(state)
 ########## RDS Radiotext / Rass Support END
 
                self["RdsActions"].setEnabled(state)
 ########## RDS Radiotext / Rass Support END
 
-       def closeRadio(self):
+       def cancel(self):
                self.infobar.rds_display.onRassInteractivePossibilityChanged.remove(self.RassInteractivePossibilityChanged)
                self.info.hide()
                #set previous tv service
                self.infobar.rds_display.onRassInteractivePossibilityChanged.remove(self.RassInteractivePossibilityChanged)
                self.info.hide()
                #set previous tv service
@@ -1458,19 +1552,20 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                        config.radio.lastroot.save()
 
        def restoreRoot(self):
                        config.radio.lastroot.save()
 
        def restoreRoot(self):
-               self.clearPath()
-               re = compile('.+?;')
-               tmp = re.findall(config.radio.lastroot.value)
-               cnt = 0
-               for i in tmp:
-                       self.servicePathRadio.append(eServiceReference(i[:-1]))
-                       cnt += 1
-               if cnt:
-                       path = self.servicePathRadio.pop()
-                       self.enterPath(path)
-               else:
-                       self.showFavourites()
-                       self.saveRoot()
+               tmp = [x for x in config.radio.lastroot.value.split(';') if x != '']
+               current = [x.toString() for x in self.servicePath]
+               if tmp != current or self.rootChanged:
+                       cnt = 0
+                       for i in tmp:
+                               self.servicePathRadio.append(eServiceReference(i))
+                               cnt += 1
+                       if cnt:
+                               path = self.servicePathRadio.pop()
+                               self.enterPath(path)
+                       else:
+                               self.showFavourites()
+                               self.saveRoot()
+                       self.rootChanged = False
 
        def preEnterPath(self, refstr):
                if self.servicePathRadio and self.servicePathRadio[0] != eServiceReference(refstr):
 
        def preEnterPath(self, refstr):
                if self.servicePathRadio and self.servicePathRadio[0] != eServiceReference(refstr):