fixes bug #556
[enigma2.git] / lib / python / Screens / ChannelSelection.py
index 5047d6dfa83121a4bb15bcf5fb419ad4850a654b..0895c9c201398eac4b98723f21d3f7bb2b08d088 100644 (file)
@@ -1,28 +1,38 @@
+from Tools.Profile import profile
+
 from Screen import Screen
 from Components.Button import Button
 from Components.ServiceList import ServiceList
 from Components.ActionMap import NumberActionMap, ActionMap, HelpableActionMap
 from Components.MenuList import MenuList
 from Screen import Screen
 from Components.Button import Button
 from Components.ServiceList import ServiceList
 from Components.ActionMap import NumberActionMap, ActionMap, HelpableActionMap
 from Components.MenuList import MenuList
-from Components.ServiceEventTracker import ServiceEventTracker
+from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase
+profile("ChannelSelection.py 1")
 from EpgSelection import EPGSelection
 from EpgSelection import EPGSelection
-from enigma import eServiceReference, eEPGCache, eServiceCenter, eTimer, eDVBDB, iPlayableService, iServiceInformation
+from enigma import eServiceReference, eEPGCache, eServiceCenter, eRCInput, eTimer, eDVBDB, iPlayableService, iServiceInformation, getPrevAsciiCode
 from Components.config import config, ConfigSubsection, ConfigText
 from Tools.NumericalTextInput import NumericalTextInput
 from Components.config import config, ConfigSubsection, ConfigText
 from Tools.NumericalTextInput import NumericalTextInput
+profile("ChannelSelection.py 2")
 from Components.NimManager import nimmanager
 from Components.NimManager import nimmanager
-from Components.Sources.Source import ObsoleteSource
+profile("ChannelSelection.py 2.1")
 from Components.Sources.RdsDecoder import RdsDecoder
 from Components.Sources.RdsDecoder import RdsDecoder
+profile("ChannelSelection.py 2.2")
 from Components.Sources.ServiceEvent import ServiceEvent
 from Components.Sources.ServiceEvent import ServiceEvent
+profile("ChannelSelection.py 2.3")
 from Components.Input import Input
 from Components.Input import Input
+profile("ChannelSelection.py 3")
 from Components.ParentalControl import parentalControl
 from Components.ParentalControl import parentalControl
-from Components.Pixmap import Pixmap
+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
+profile("ChannelSelection.py 4")
+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
 from os import remove
+profile("ChannelSelection.py after imports")
 
 FLAG_SERVICE_NEW_FOUND = 64 #define in lib/dvb/idvb.h as dxNewFound = 64
 
 
 FLAG_SERVICE_NEW_FOUND = 64 #define in lib/dvb/idvb.h as dxNewFound = 64
 
@@ -61,24 +71,26 @@ OFF = 0
 EDIT_BOUQUET = 1
 EDIT_ALTERNATIVES = 2
 
 EDIT_BOUQUET = 1
 EDIT_ALTERNATIVES = 2
 
-def append_when_current_valid(current, menu, args, level = 0):
+def append_when_current_valid(current, menu, args, level = 0, key = ""):
        if current and current.valid() and level <= config.usage.setup_level.index:
        if current and current.valid() and level <= config.usage.setup_level.index:
-               menu.append(args)
+               menu.append(ChoiceEntryComponent(key, args))
 
 class ChannelContextMenu(Screen):
        def __init__(self, session, csel):
                Screen.__init__(self, session)
 
 class ChannelContextMenu(Screen):
        def __init__(self, session, csel):
                Screen.__init__(self, session)
-               #raise "we need a better summary screen here"
+               #raise Exception("we need a better summary screen here")
                self.csel = csel
                self.bsel = None
 
                self.csel = csel
                self.bsel = None
 
-               self["actions"] = ActionMap(["OkCancelActions"],
+               self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "NumberActions"],
                        {
                                "ok": self.okbuttonClick,
                        {
                                "ok": self.okbuttonClick,
-                               "cancel": self.cancelClick
+                               "cancel": self.cancelClick,
+                               "blue": self.showServiceInPiP
                        })
                menu = [ ]
 
                        })
                menu = [ ]
 
+               self.pipAvailable = False
                current = csel.getCurrentSelection()
                current_root = csel.getRoot()
                current_sel_path = current.getPath()
                current = csel.getCurrentSelection()
                current_root = csel.getRoot()
                current_sel_path = current.getPath()
@@ -87,7 +99,7 @@ class ChannelContextMenu(Screen):
                inBouquet = csel.getMutableList() is not None
                haveBouquets = config.usage.multibouquet.value
 
                inBouquet = csel.getMutableList() is not None
                haveBouquets = config.usage.multibouquet.value
 
-               if not (len(current_sel_path) or current_sel_flags & (eServiceReference.isDirectory|eServiceReference.isMarker)):
+               if not (current_sel_path or current_sel_flags & (eServiceReference.isDirectory|eServiceReference.isMarker)):
                        append_when_current_valid(current, menu, (_("show transponder info"), self.showServiceInformations), level = 2)
                if csel.bouquet_mark_edit == OFF and not csel.movemode:
                        if not inBouquetRootList:
                        append_when_current_valid(current, menu, (_("show transponder info"), self.showServiceInformations), level = 2)
                if csel.bouquet_mark_edit == OFF and not csel.movemode:
                        if not inBouquetRootList:
@@ -103,6 +115,8 @@ class ChannelContextMenu(Screen):
                                        else:
                                                append_when_current_valid(current, menu, (_("add service to favourites"), self.addServiceToBouquetSelected), level = 0)
                                else:
                                        else:
                                                append_when_current_valid(current, menu, (_("add service to favourites"), self.addServiceToBouquetSelected), level = 0)
                                else:
+                                       if current_root.getPath().find('FROM SATELLITES') != -1:
+                                               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)
@@ -112,8 +126,11 @@ 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 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:
                        else:
-                                       menu.append((_("add bouquet"), self.showBouquetInputBox))
+                                       menu.append(ChoiceEntryComponent(text = (_("add bouquet"), self.showBouquetInputBox)))
                                        append_when_current_valid(current, menu, (_("remove entry"), self.removeBouquet), level = 0)
 
                if inBouquet: # current list is editable?
                                        append_when_current_valid(current, menu, (_("remove entry"), self.removeBouquet), level = 0)
 
                if inBouquet: # current list is editable?
@@ -121,7 +138,7 @@ class ChannelContextMenu(Screen):
                                if not csel.movemode:
                                        append_when_current_valid(current, menu, (_("enable move mode"), self.toggleMoveMode), level = 1)
                                        if not inBouquetRootList and current_root and not (current_root.flags & eServiceReference.isGroup):
                                if not csel.movemode:
                                        append_when_current_valid(current, menu, (_("enable move mode"), self.toggleMoveMode), level = 1)
                                        if not inBouquetRootList and current_root and not (current_root.flags & eServiceReference.isGroup):
-                                               menu.append((_("add marker"), self.showMarkerInputBox))
+                                               menu.append(ChoiceEntryComponent(text = (_("add marker"), self.showMarkerInputBox)))
                                                if haveBouquets:
                                                        append_when_current_valid(current, menu, (_("enable bouquet edit"), self.bouquetMarkStart), level = 0)
                                                else:
                                                if haveBouquets:
                                                        append_when_current_valid(current, menu, (_("enable bouquet edit"), self.bouquetMarkStart), level = 0)
                                                else:
@@ -146,11 +163,11 @@ class ChannelContextMenu(Screen):
                                                append_when_current_valid(current, menu, (_("end alternatives edit"), self.bouquetMarkEnd), level = 0)
                                                append_when_current_valid(current, menu, (_("abort alternatives edit"), self.bouquetMarkAbort), level = 0)
 
                                                append_when_current_valid(current, menu, (_("end alternatives edit"), self.bouquetMarkEnd), level = 0)
                                                append_when_current_valid(current, menu, (_("abort alternatives edit"), self.bouquetMarkAbort), level = 0)
 
-               menu.append((_("back"), self.cancelClick))
-               self["menu"] = MenuList(menu)
+               menu.append(ChoiceEntryComponent(text = (_("back"), self.cancelClick)))
+               self["menu"] = ChoiceList(menu)
 
        def okbuttonClick(self):
 
        def okbuttonClick(self):
-               self["menu"].getCurrent()[1]()
+               self["menu"].getCurrent()[0][1]()
 
        def cancelClick(self):
                self.close(False)
 
        def cancelClick(self):
                self.close(False)
@@ -179,6 +196,23 @@ class ChannelContextMenu(Screen):
                        self.close()
                else:
                        self.session.openWithCallback(self.close, MessageBox, _("The pin code you entered is wrong."), MessageBox.TYPE_ERROR)
                        self.close()
                else:
                        self.session.openWithCallback(self.close, MessageBox, _("The pin code you entered is wrong."), MessageBox.TYPE_ERROR)
+                       
+       def showServiceInPiP(self):
+               if not self.pipAvailable:
+                       return
+               if self.session.pipshown:
+                       del self.session.pip
+               self.session.pip = self.session.instantiateDialog(PictureInPicture)
+               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(True)
+               else:
+                       self.session.pipshown = False
+                       del self.session.pip
+                       self.session.openWithCallback(self.close, MessageBox, _("Could not open Picture in Picture"), MessageBox.TYPE_ERROR)
 
        def addServiceToBouquetSelected(self):
                bouquets = self.csel.getBouquetList()
 
        def addServiceToBouquetSelected(self):
                bouquets = self.csel.getBouquetList()
@@ -196,6 +230,17 @@ class ChannelContextMenu(Screen):
                if recursive:
                        self.close(False)
 
                if recursive:
                        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.close()
+
        def copyCurrentToBouquetList(self):
                self.csel.copyCurrentToBouquetList()
                self.close()
        def copyCurrentToBouquetList(self):
                self.csel.copyCurrentToBouquetList()
                self.close()
@@ -276,7 +321,7 @@ class SelectionEventInfo:
                self["ServiceEvent"] = ServiceEvent()
                self.servicelist.connectSelChanged(self.__selectionChanged)
                self.timer = eTimer()
                self["ServiceEvent"] = ServiceEvent()
                self.servicelist.connectSelChanged(self.__selectionChanged)
                self.timer = eTimer()
-               self.timer.timeout.get().append(self.updateEventInfo)
+               self.timer.callback.append(self.updateEventInfo)
                self.onShown.append(self.__selectionChanged)
 
        def __selectionChanged(self):
                self.onShown.append(self.__selectionChanged)
 
        def __selectionChanged(self):
@@ -296,11 +341,24 @@ class ChannelSelectionEPG:
 
        def showEPGList(self):
                ref=self.getCurrentSelection()
 
        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()
+               if ref:
+                       self.savedService = ref
+                       self.session.openWithCallback(self.SingleServiceEPGClosed, EPGSelection, ref, serviceChangeCB=self.changeServiceCB)
+
+       def SingleServiceEPGClosed(self, ret=False):
+               self.setCurrentSelection(self.savedService)
+
+       def changeServiceCB(self, direction, epg):
+               beg = self.getCurrentSelection()
+               while True:
+                       if direction > 0:
+                               self.moveDown()
+                       else:
+                               self.moveUp()
+                       cur = self.getCurrentSelection()
+                       if cur == beg or not (cur.flags & eServiceReference.isMarker):
+                               break
+               epg.setService(ServiceReference(self.getCurrentSelection()))
 
 class ChannelSelectionEdit:
        def __init__(self):
 
 class ChannelSelectionEdit:
        def __init__(self):
@@ -391,7 +449,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()
@@ -409,10 +467,10 @@ class ChannelSelectionEdit:
                if mutableBouquetList:
                        if self.mode == MODE_TV:
                                bName += " (TV)"
                if mutableBouquetList:
                        if self.mode == MODE_TV:
                                bName += " (TV)"
-                               str = '1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET \"userbouquet.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(bName))
+                               str = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET \"userbouquet.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(bName))
                        else:
                                bName += " (Radio)"
                        else:
                                bName += " (Radio)"
-                               str = '1:7:2:0:0:0:0:0:0:0:(type == 2) FROM BOUQUET \"userbouquet.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(bName))
+                               str = '1:7:2:0:0:0:0:0:0:0:FROM BOUQUET \"userbouquet.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(bName))
                        new_bouquet_ref = eServiceReference(str)
                        if not mutableBouquetList.addService(new_bouquet_ref):
                                mutableBouquetList.flushChanges()
                        new_bouquet_ref = eServiceReference(str)
                        if not mutableBouquetList.addService(new_bouquet_ref):
                                mutableBouquetList.flushChanges()
@@ -492,7 +550,7 @@ class ChannelSelectionEdit:
                self.mutableList = self.getMutableList()
                # add all services from the current list to internal marked set in listboxservicecontent
                self.clearMarks() # this clears the internal marked set in the listboxservicecontent
                self.mutableList = self.getMutableList()
                # add all services from the current list to internal marked set in listboxservicecontent
                self.clearMarks() # this clears the internal marked set in the listboxservicecontent
-               self.saved_title = self.instance.getTitle()
+               self.saved_title = self.getTitle()
                pos = self.saved_title.find(')')
                new_title = self.saved_title[:pos+1]
                if type == EDIT_ALTERNATIVES:
                pos = self.saved_title.find(')')
                new_title = self.saved_title[:pos+1]
                if type == EDIT_ALTERNATIVES:
@@ -537,7 +595,7 @@ class ChannelSelectionEdit:
                del self.servicePath[:] # remove all elements
                self.servicePath += self.savedPath # add saved elements
                del self.savedPath
                del self.servicePath[:] # remove all elements
                self.servicePath += self.savedPath # add saved elements
                del self.savedPath
-               self.setRoot(self.servicePath[len(self.servicePath)-1])
+               self.setRoot(self.servicePath[-1])
 
        def clearMarks(self):
                self.servicelist.clearMarks()
 
        def clearMarks(self):
                self.servicelist.clearMarks()
@@ -592,7 +650,7 @@ class ChannelSelectionEdit:
                        self.mutableList = self.getMutableList()
                        self.movemode = True
                        self.pathChangeDisabled = True # no path change allowed in movemode
                        self.mutableList = self.getMutableList()
                        self.movemode = True
                        self.pathChangeDisabled = True # no path change allowed in movemode
-                       self.saved_title = self.instance.getTitle()
+                       self.saved_title = self.getTitle()
                        new_title = self.saved_title
                        pos = self.saved_title.find(')')
                        new_title = self.saved_title[:pos+1] + ' ' + _("[move mode]") + self.saved_title[pos+1:]
                        new_title = self.saved_title
                        pos = self.saved_title.find(')')
                        new_title = self.saved_title[:pos+1] + ' ' + _("[move mode]") + self.saved_title[pos+1:]
@@ -614,14 +672,27 @@ 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
 
-# this makes it much simple to implement a selectable radio or tv mode :)
-service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25)'
-service_types_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2)'
+# type 1 = digital television service
+# type 4 = nvod reference service (NYI)
+# type 17 = MPEG-2 HD digital television service
+# type 22 = advanced codec SD digital television
+# type 24 = advanced codec SD NVOD reference service (NYI)
+# type 25 = advanced codec HD digital television
+# type 27 = advanced codec HD NVOD reference service (NYI)
+# type 2 = digital radio sound service
+# type 10 = advanced codec digital radio sound service
+
+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_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2) || (type == 10)'
 
 class ChannelSelectionBase(Screen):
        def __init__(self, session):
 
 class ChannelSelectionBase(Screen):
        def __init__(self, session):
@@ -641,6 +712,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
 
@@ -648,7 +720,7 @@ class ChannelSelectionBase(Screen):
 
                self.bouquetNumOffsetCache = { }
 
 
                self.bouquetNumOffsetCache = { }
 
-               self["ChannelSelectBaseActions"] = NumberActionMap(["ChannelSelectBaseActions", "NumberActions"],
+               self["ChannelSelectBaseActions"] = NumberActionMap(["ChannelSelectBaseActions", "NumberActions", "InputAsciiActions"],
                        {
                                "showFavourites": self.showFavourites,
                                "showAllServices": self.showAllServices,
                        {
                                "showFavourites": self.showFavourites,
                                "showAllServices": self.showAllServices,
@@ -658,6 +730,7 @@ class ChannelSelectionBase(Screen):
                                "prevBouquet": self.prevBouquet,
                                "nextMarker": self.nextMarker,
                                "prevMarker": self.prevMarker,
                                "prevBouquet": self.prevBouquet,
                                "nextMarker": self.nextMarker,
                                "prevMarker": self.prevMarker,
+                               "gotAsciiCode": self.keyAsciiCode,
                                "1": self.keyNumberGlobal,
                                "2": self.keyNumberGlobal,
                                "3": self.keyNumberGlobal,
                                "1": self.keyNumberGlobal,
                                "2": self.keyNumberGlobal,
                                "3": self.keyNumberGlobal,
@@ -717,7 +790,7 @@ class ChannelSelectionBase(Screen):
                self.mode = MODE_TV
                self.servicePath = self.servicePathTV
                self.recallBouquetMode()
                self.mode = MODE_TV
                self.servicePath = self.servicePathTV
                self.recallBouquetMode()
-               title = self.instance.getTitle()
+               title = self.getTitle()
                pos = title.find(" (")
                if pos != -1:
                        title = title[:pos]
                pos = title.find(" (")
                if pos != -1:
                        title = title[:pos]
@@ -728,7 +801,7 @@ class ChannelSelectionBase(Screen):
                self.mode = MODE_RADIO
                self.servicePath = self.servicePathRadio
                self.recallBouquetMode()
                self.mode = MODE_RADIO
                self.servicePath = self.servicePathRadio
                self.recallBouquetMode()
-               title = self.instance.getTitle()
+               title = self.getTitle()
                pos = title.find(" (")
                if pos != -1:
                        title = title[:pos]
                pos = title.find(" (")
                if pos != -1:
                        title = title[:pos]
@@ -746,6 +819,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):
@@ -759,18 +833,18 @@ class ChannelSelectionBase(Screen):
 
        def getServiceName(self, ref):
                str = self.removeModeStr(ServiceReference(ref).getServiceName())
 
        def getServiceName(self, ref):
                str = self.removeModeStr(ServiceReference(ref).getServiceName())
-               if not len(str):
+               if not str:
                        pathstr = ref.getPath()
                        pathstr = ref.getPath()
-                       if pathstr.find('FROM PROVIDERS') != -1:
+                       if 'FROM PROVIDERS' in pathstr:
                                return _("Provider")
                                return _("Provider")
-                       if pathstr.find('FROM SATELLITES') != -1:
+                       if 'FROM SATELLITES' in pathstr:
                                return _("Satellites")
                                return _("Satellites")
-                       if pathstr.find(') ORDER BY name') != -1:
+                       if ') ORDER BY name' in pathstr:
                                return _("All")
                return str
 
        def buildTitleString(self):
                                return _("All")
                return str
 
        def buildTitleString(self):
-               titleStr = self.instance.getTitle()
+               titleStr = self.getTitle()
                pos = titleStr.find(']')
                if pos == -1:
                        pos = titleStr.find(')')
                pos = titleStr.find(']')
                if pos == -1:
                        pos = titleStr.find(')')
@@ -809,9 +883,8 @@ class ChannelSelectionBase(Screen):
 
        def pathUp(self, justSet=False):
                prev = self.servicePath.pop()
 
        def pathUp(self, justSet=False):
                prev = self.servicePath.pop()
-               length = len(self.servicePath)
-               if length:
-                       current = self.servicePath[length-1]
+               if self.servicePath:
+                       current = self.servicePath[-1]
                        self.setRoot(current, justSet)
                        if not justSet:
                                self.setCurrentSelection(prev)
                        self.setRoot(current, justSet)
                        if not justSet:
                                self.setCurrentSelection(prev)
@@ -867,7 +940,10 @@ class ChannelSelectionBase(Screen):
                                                        service = servicelist.getNext()
                                                        if not service.valid(): #check if end of list
                                                                break
                                                        service = servicelist.getNext()
                                                        if not service.valid(): #check if end of list
                                                                break
-                                                       orbpos = service.getUnsignedData(4) >> 16
+                                                       unsigned_orbpos = service.getUnsignedData(4) >> 16
+                                                       orbpos = service.getData(4) >> 16
+                                                       if orbpos < 0:
+                                                               orbpos += 3600
                                                        if service.getPath().find("FROM PROVIDER") != -1:
                                                                service_type = _("Providers")
                                                        elif service.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
                                                        if service.getPath().find("FROM PROVIDER") != -1:
                                                                service_type = _("Providers")
                                                        elif service.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
@@ -878,9 +954,9 @@ class ChannelSelectionBase(Screen):
                                                                # why we need this cast?
                                                                service_name = str(nimmanager.getSatDescription(orbpos))
                                                        except:
                                                                # why we need this cast?
                                                                service_name = str(nimmanager.getSatDescription(orbpos))
                                                        except:
-                                                               if orbpos == 0xFFFF: #Cable
+                                                               if unsigned_orbpos == 0xFFFF: #Cable
                                                                        service_name = _("Cable")
                                                                        service_name = _("Cable")
-                                                               elif orbpos == 0xEEEE: #Terrestrial
+                                                               elif unsigned_orbpos == 0xEEEE: #Terrestrial
                                                                        service_name = _("Terrestrial")
                                                                else:
                                                                        if orbpos > 1800: # west
                                                                        service_name = _("Terrestrial")
                                                                else:
                                                                        if orbpos > 1800: # west
@@ -936,7 +1012,7 @@ class ChannelSelectionBase(Screen):
                                self.enterPath(ref)
 
        def inBouquet(self):
                                self.enterPath(ref)
 
        def inBouquet(self):
-               if len(self.servicePath) > 0 and self.servicePath[0] == self.bouquet_root:
+               if self.servicePath and self.servicePath[0] == self.bouquet_root:
                        return True
                return False
 
                        return True
                return False
 
@@ -969,6 +1045,12 @@ class ChannelSelectionBase(Screen):
                if len(charstr) == 1:
                        self.servicelist.moveToChar(charstr[0])
 
                if len(charstr) == 1:
                        self.servicelist.moveToChar(charstr[0])
 
+       def keyAsciiCode(self):
+               unichar = unichr(getPrevAsciiCode())
+               charstr = unichar.encode("utf-8")
+               if len(charstr) == 1:
+                       self.servicelist.moveToChar(charstr[0])
+
        def getRoot(self):
                return self.servicelist.getRoot()
 
        def getRoot(self):
                return self.servicelist.getRoot()
 
@@ -976,14 +1058,6 @@ 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:
-                       if self.mode == MODE_TV:
-                               servicepath = '(type == 1)' + servicepath[pos:]
-                       else:
-                               servicepath = '(type == 2)' + servicepath[pos:]
-                       service.setPath(servicepath)
                self.servicelist.setCurrent(service)
 
        def getBouquetList(self):
                self.servicelist.setCurrent(service)
 
        def getBouquetList(self):
@@ -1054,8 +1128,6 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                ChannelSelectionEPG.__init__(self)
                SelectionEventInfo.__init__(self)
 
                ChannelSelectionEPG.__init__(self)
                SelectionEventInfo.__init__(self)
 
-               self["CurrentTime"] = ObsoleteSource(new_source = "global.CurrentTime", removal_date = "2008-01")
-
                self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
                        {
                                "cancel": self.cancel,
                self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
                        {
                                "cancel": self.cancel,
@@ -1071,7 +1143,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                        })
 
                self.lastChannelRootTimer = eTimer()
                        })
 
                self.lastChannelRootTimer = eTimer()
-               self.lastChannelRootTimer.timeout.get().append(self.__onCreate)
+               self.lastChannelRootTimer.callback.append(self.__onCreate)
                self.lastChannelRootTimer.start(100,True)
 
                self.history_tv = [ ]
                self.lastChannelRootTimer.start(100,True)
 
                self.history_tv = [ ]
@@ -1084,6 +1156,15 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                self.revertMode = None
                config.usage.multibouquet.addNotifier(self.multibouquet_config_changed)
                self.new_service_played = False
                self.revertMode = None
                config.usage.multibouquet.addNotifier(self.multibouquet_config_changed)
                self.new_service_played = False
+               self.onExecBegin.append(self.asciiOn)
+
+       def asciiOn(self):
+               rcinput = eRCInput.getInstance()
+               rcinput.setKeyboardMode(rcinput.kmAscii)
+
+       def asciiOff(self):
+               rcinput = eRCInput.getInstance()
+               rcinput.setKeyboardMode(rcinput.kmNone)
 
        def multibouquet_config_changed(self, val):
                self.recallBouquetMode()
 
        def multibouquet_config_changed(self, val):
                self.recallBouquetMode()
@@ -1100,6 +1181,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():
@@ -1151,6 +1233,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                        root = self.getRoot()
                        if not root or not (root.flags & eServiceReference.isGroup):
                                self.zap()
                        root = self.getRoot()
                        if not root or not (root.flags & eServiceReference.isGroup):
                                self.zap()
+                               self.asciiOff()
                                self.close(ref)
 
        #called from infoBar and channelSelected
                                self.close(ref)
 
        #called from infoBar and channelSelected
@@ -1204,8 +1287,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                del self.servicePath[:]
                self.servicePath += path
                self.saveRoot()
                del self.servicePath[:]
                self.servicePath += path
                self.saveRoot()
-               plen = len(path)
-               root = path[plen-1]
+               root = path[-1]
                cur_root = self.getRoot()
                if cur_root and cur_root != root:
                        self.setRoot(root)
                cur_root = self.getRoot()
                if cur_root and cur_root != root:
                        self.setRoot(root)
@@ -1218,27 +1300,29 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                for i in self.servicePath:
                        path += i.toString()
                        path += ';'
                for i in self.servicePath:
                        path += i.toString()
                        path += ';'
-               if len(path) and path != self.lastroot.value:
+               if path and path != self.lastroot.value:
                        self.lastroot.value = path
                        self.lastroot.save()
 
        def restoreRoot(self):
                        self.lastroot.value = path
                        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[:len(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):
 
        def preEnterPath(self, refstr):
-               if len(self.servicePath) and self.servicePath[0] != eServiceReference(refstr):
+               if self.servicePath and self.servicePath[0] != eServiceReference(refstr):
                        pathstr = self.lastroot.value
                        if pathstr is not None and pathstr.find(refstr) == 0:
                                self.restoreRoot()
                        pathstr = self.lastroot.value
                        if pathstr is not None and pathstr.find(refstr) == 0:
                                self.restoreRoot()
@@ -1258,16 +1342,14 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                        self.lastservice.save()
 
        def setCurrentServicePath(self, path):
                        self.lastservice.save()
 
        def setCurrentServicePath(self, path):
-               hlen = len(self.history)
-               if hlen > 0:
+               if self.history:
                        self.history[self.history_pos] = path
                else:
                        self.history.append(path)
                self.setHistoryPath()
 
        def getCurrentServicePath(self):
                        self.history[self.history_pos] = path
                else:
                        self.history.append(path)
                self.setHistoryPath()
 
        def getCurrentServicePath(self):
-               hlen = len(self.history)
-               if hlen > 0:
+               if self.history:
                        return self.history[self.history_pos]
                return None
 
                        return self.history[self.history_pos]
                return None
 
@@ -1295,27 +1377,22 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                elif self.revertMode == MODE_RADIO:
                        self.setModeRadio()
                self.revertMode = None
                elif self.revertMode == MODE_RADIO:
                        self.setModeRadio()
                self.revertMode = None
+               self.asciiOff()
                self.close(None)
 
                self.close(None)
 
-from Screens.InfoBarGenerics import InfoBarEvent, InfoBarServiceName
-
-class RadioInfoBar(Screen, InfoBarEvent, InfoBarServiceName):
+class RadioInfoBar(Screen):
        def __init__(self, session):
                Screen.__init__(self, session)
        def __init__(self, session):
                Screen.__init__(self, session)
-               InfoBarEvent.__init__(self)
-               InfoBarServiceName.__init__(self)
-               self["CurrentTime"] = ObsoleteSource(new_source = "global.CurrentTime", removal_date = "2008-01")
                self["RdsDecoder"] = RdsDecoder(self.session.nav)
                self["RdsDecoder"] = RdsDecoder(self.session.nav)
-               self["BlinkingPoint"] = Pixmap()
-               self["BlinkingPoint"].hide()
 
 
-class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
+class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, InfoBarBase):
        ALLOW_SUSPEND = True
 
        def __init__(self, session, infobar):
                ChannelSelectionBase.__init__(self, session)
                ChannelSelectionEdit.__init__(self)
                ChannelSelectionEPG.__init__(self)
        ALLOW_SUSPEND = True
 
        def __init__(self, session, infobar):
                ChannelSelectionBase.__init__(self, session)
                ChannelSelectionEdit.__init__(self)
                ChannelSelectionEPG.__init__(self)
+               InfoBarBase.__init__(self)
                self.infobar = infobar
                self.onLayoutFinish.append(self.onCreate)
 
                self.infobar = infobar
                self.onLayoutFinish.append(self.onCreate)
 
@@ -1344,6 +1421,11 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                },-1)
                self["RdsActions"].setEnabled(False)
                infobar.rds_display.onRassInteractivePossibilityChanged.append(self.RassInteractivePossibilityChanged)
                },-1)
                self["RdsActions"].setEnabled(False)
                infobar.rds_display.onRassInteractivePossibilityChanged.append(self.RassInteractivePossibilityChanged)
+               self.onClose.append(self.__onClose)
+
+       def __onClose(self):
+               lastservice=eServiceReference(config.tv.lastservice.value)
+               self.session.nav.playService(lastservice)
 
        def startRassInteractive(self):
                self.info.hide();
 
        def startRassInteractive(self):
                self.info.hide();
@@ -1362,8 +1444,6 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                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
-               lastservice=eServiceReference(config.tv.lastservice.value)
-               self.session.nav.playService(lastservice)
                self.close(None)
 
        def __evServiceStart(self):
                self.close(None)
 
        def __evServiceStart(self):
@@ -1382,27 +1462,28 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                for i in self.servicePathRadio:
                        path += i.toString()
                        path += ';'
                for i in self.servicePathRadio:
                        path += i.toString()
                        path += ';'
-               if len(path) and path != config.radio.lastroot.value:
+               if path and path != config.radio.lastroot.value:
                        config.radio.lastroot.value = path
                        config.radio.lastroot.save()
 
        def restoreRoot(self):
                        config.radio.lastroot.value = path
                        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[:len(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):
 
        def preEnterPath(self, refstr):
-               if len(self.servicePathRadio) and self.servicePathRadio[0] != eServiceReference(refstr):
+               if 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()
                        pathstr = config.radio.lastroot.value
                        if pathstr is not None and pathstr.find(refstr) == 0:
                                self.restoreRoot()
@@ -1445,9 +1526,6 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
 class SimpleChannelSelection(ChannelSelectionBase):
        def __init__(self, session, title):
                ChannelSelectionBase.__init__(self, session)
 class SimpleChannelSelection(ChannelSelectionBase):
        def __init__(self, session, title):
                ChannelSelectionBase.__init__(self, session)
-               self.title = title
-               self.onShown.append(self.__onExecCallback)
-
                self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
                        {
                                "cancel": self.close,
                self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
                        {
                                "cancel": self.close,
@@ -1455,9 +1533,10 @@ class SimpleChannelSelection(ChannelSelectionBase):
                                "keyRadio": self.setModeRadio,
                                "keyTV": self.setModeTv,
                        })
                                "keyRadio": self.setModeRadio,
                                "keyTV": self.setModeTv,
                        })
+               self.title = title
+               self.onLayoutFinish.append(self.layoutFinished)
 
 
-       def __onExecCallback(self):
-               self.setTitle(self.title)
+       def layoutFinished(self):
                self.setModeTv()
 
        def channelSelected(self): # just return selected service
                self.setModeTv()
 
        def channelSelected(self): # just return selected service