small fix
[enigma2.git] / lib / python / Screens / ChannelSelection.py
index 1ccddf75ed49702cf9e1ac7281c32479340e8a45..0432823bfccf4e84c3295018607127e6a204ccd8 100644 (file)
@@ -1,33 +1,39 @@
+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 Components.ServiceEventTracker import ServiceEventTracker
+from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase
+profile("ChannelSelection.py 1")
 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 Screens.FixedMenu import FixedMenu
 from Tools.NumericalTextInput import NumericalTextInput
+profile("ChannelSelection.py 2")
 from Components.NimManager import nimmanager
-from Components.Sources.Clock import Clock
+profile("ChannelSelection.py 2.1")
 from Components.Sources.RdsDecoder import RdsDecoder
+profile("ChannelSelection.py 2.2")
+from Components.Sources.ServiceEvent import ServiceEvent
+profile("ChannelSelection.py 2.3")
 from Components.Input import Input
+profile("ChannelSelection.py 3")
 from Components.ParentalControl import parentalControl
-from Components.Pixmap import BlinkingPixmapConditional
 from Screens.InputBox import InputBox, PinInput
 from Screens.MessageBox import MessageBox
 from Screens.ServiceInfo import ServiceInfo
+profile("ChannelSelection.py 4")
 from Screens.RdsDisplay import RassInteractive
 from ServiceReference import ServiceReference
 from Tools.BoundFunction import boundFunction
-from re import *
+from re import compile
 from os import remove
+profile("ChannelSelection.py after imports")
 
 FLAG_SERVICE_NEW_FOUND = 64 #define in lib/dvb/idvb.h as dxNewFound = 64
 
-import xml.dom.minidom
-
 class BouquetSelector(Screen):
        def __init__(self, session, bouquets, selectedFunc, enableWrapAround=False):
                Screen.__init__(self, session)
@@ -63,13 +69,14 @@ OFF = 0
 EDIT_BOUQUET = 1
 EDIT_ALTERNATIVES = 2
 
-def apend_when_current_valid(current, menu, args):
-       if current and current.valid():
+def append_when_current_valid(current, menu, args, level = 0):
+       if current and current.valid() and level <= config.usage.setup_level.index:
                menu.append(args)
 
 class ChannelContextMenu(Screen):
        def __init__(self, session, csel):
                Screen.__init__(self, session)
+               #raise Exception("we need a better summary screen here")
                self.csel = csel
                self.bsel = None
 
@@ -88,64 +95,66 @@ class ChannelContextMenu(Screen):
                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)):
-                       apend_when_current_valid(current, menu, (_("show transponder info"), self.showServiceInformations))
+               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:
                                isPlayable = not (current_sel_flags & (eServiceReference.isMarker|eServiceReference.isDirectory))
                                if isPlayable:
                                        if config.ParentalControl.configured.value:
                                                if parentalControl.getProtectionLevel(csel.getCurrentSelection().toCompareString()) == -1:
-                                                       apend_when_current_valid(current, menu, (_("add to parental protection"), boundFunction(self.addParentalProtection, csel.getCurrentSelection())))
+                                                       append_when_current_valid(current, menu, (_("add to parental protection"), boundFunction(self.addParentalProtection, csel.getCurrentSelection())), level = 0)
                                                else:
-                                                       apend_when_current_valid(current, menu, (_("remove from parental protection"), boundFunction(self.removeParentalProtection, csel.getCurrentSelection())))
+                                                       append_when_current_valid(current, menu, (_("remove from parental protection"), boundFunction(self.removeParentalProtection, csel.getCurrentSelection())), level = 0)
                                        if haveBouquets:
-                                               apend_when_current_valid(current, menu, (_("add service to bouquet"), self.addServiceToBouquetSelected))
+                                               append_when_current_valid(current, menu, (_("add service to bouquet"), self.addServiceToBouquetSelected), level = 0)
                                        else:
-                                               apend_when_current_valid(current, menu, (_("add service to favourites"), self.addServiceToBouquetSelected))
+                                               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:
-                                                       apend_when_current_valid(current, menu, (_("copy to bouquets"), self.copyCurrentToBouquetList))
+                                                       append_when_current_valid(current, menu, (_("copy to bouquets"), self.copyCurrentToBouquetList), level = 0)
                                        if current_sel_path.find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
-                                               apend_when_current_valid(current, menu, (_("remove all new found flags"), self.removeAllNewFoundFlags))
+                                               append_when_current_valid(current, menu, (_("remove all new found flags"), self.removeAllNewFoundFlags), level = 0)
                                if inBouquet:
-                                       apend_when_current_valid(current, menu, (_("remove entry"), self.removeCurrentService))
+                                       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:
-                                       apend_when_current_valid(current, menu, (_("remove new found flag"), self.removeNewFoundFlag))
+                                       append_when_current_valid(current, menu, (_("remove new found flag"), self.removeNewFoundFlag), level = 0)
                        else:
                                        menu.append((_("add bouquet"), self.showBouquetInputBox))
-                                       apend_when_current_valid(current, menu, (_("remove entry"), self.removeBouquet))
+                                       append_when_current_valid(current, menu, (_("remove entry"), self.removeBouquet), level = 0)
 
                if inBouquet: # current list is editable?
                        if csel.bouquet_mark_edit == OFF:
                                if not csel.movemode:
-                                       apend_when_current_valid(current, menu, (_("enable move mode"), self.toggleMoveMode))
+                                       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))
                                                if haveBouquets:
-                                                       apend_when_current_valid(current, menu, (_("enable bouquet edit"), self.bouquetMarkStart))
+                                                       append_when_current_valid(current, menu, (_("enable bouquet edit"), self.bouquetMarkStart), level = 0)
                                                else:
-                                                       apend_when_current_valid(current, menu, (_("enable favourite edit"), self.bouquetMarkStart))
+                                                       append_when_current_valid(current, menu, (_("enable favourite edit"), self.bouquetMarkStart), level = 0)
                                                if current_sel_flags & eServiceReference.isGroup:
-                                                       apend_when_current_valid(current, menu, (_("edit alternatives"), self.editAlternativeServices))
-                                                       apend_when_current_valid(current, menu, (_("show alternatives"), self.showAlternativeServices))
-                                                       apend_when_current_valid(current, menu, (_("remove all alternatives"), self.removeAlternativeServices))
+                                                       append_when_current_valid(current, menu, (_("edit alternatives"), self.editAlternativeServices), level = 2)
+                                                       append_when_current_valid(current, menu, (_("show alternatives"), self.showAlternativeServices), level = 2)
+                                                       append_when_current_valid(current, menu, (_("remove all alternatives"), self.removeAlternativeServices), level = 2)
                                                elif not current_sel_flags & eServiceReference.isMarker:
-                                                       apend_when_current_valid(current, menu, (_("add alternatives"), self.addAlternativeServices))
+                                                       append_when_current_valid(current, menu, (_("add alternatives"), self.addAlternativeServices), level = 2)
                                else:
-                                       apend_when_current_valid(current, menu, (_("disable move mode"), self.toggleMoveMode))
+                                       append_when_current_valid(current, menu, (_("disable move mode"), self.toggleMoveMode), level = 0)
                        else:
                                if csel.bouquet_mark_edit == EDIT_BOUQUET:
                                        if haveBouquets:
-                                               apend_when_current_valid(current, menu, (_("end bouquet edit"), self.bouquetMarkEnd))
-                                               apend_when_current_valid(current, menu, (_("abort bouquet edit"), self.bouquetMarkAbort))
+                                               append_when_current_valid(current, menu, (_("end bouquet edit"), self.bouquetMarkEnd), level = 0)
+                                               append_when_current_valid(current, menu, (_("abort bouquet edit"), self.bouquetMarkAbort), level = 0)
                                        else:
-                                               apend_when_current_valid(current, menu, (_("end favourites edit"), self.bouquetMarkEnd))
-                                               apend_when_current_valid(current, menu, (_("abort favourites edit"), self.bouquetMarkAbort))
+                                               append_when_current_valid(current, menu, (_("end favourites edit"), self.bouquetMarkEnd), level = 0)
+                                               append_when_current_valid(current, menu, (_("abort favourites edit"), self.bouquetMarkAbort), level = 0)
                                else:
-                                               apend_when_current_valid(current, menu, (_("end alternatives edit"), self.bouquetMarkEnd))
-                                               apend_when_current_valid(current, menu, (_("abort alternatives edit"), self.bouquetMarkAbort))
+                                               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)
@@ -160,7 +169,7 @@ class ChannelContextMenu(Screen):
                self.session.open( ServiceInfo, self.csel.getCurrentSelection() )
 
        def showBouquetInputBox(self):
-               self.session.openWithCallback(self.bouquetInputCallback, InputBox, title=_("Please enter a name for the new bouquet"), text="bouquetname", maxSize=False, type=Input.TEXT)
+               self.session.openWithCallback(self.bouquetInputCallback, InputBox, title=_("Please enter a name for the new bouquet"), text="bouquetname", maxSize=False, visible_width = 56, type=Input.TEXT)
 
        def bouquetInputCallback(self, bouquet):
                if bouquet is not None:
@@ -197,6 +206,17 @@ class ChannelContextMenu(Screen):
                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()
@@ -206,7 +226,7 @@ class ChannelContextMenu(Screen):
                self.close()
 
        def showMarkerInputBox(self):
-               self.session.openWithCallback(self.markerInputCallback, InputBox, title=_("Please enter a name for the new marker"), text="markername", maxSize=False, type=Input.TEXT)
+               self.session.openWithCallback(self.markerInputCallback, InputBox, title=_("Please enter a name for the new marker"), text="markername", maxSize=False, visible_width = 56, type=Input.TEXT)
 
        def markerInputCallback(self, marker):
                if marker is not None:
@@ -272,6 +292,22 @@ class ChannelContextMenu(Screen):
                self.csel.startMarkedEdit(EDIT_ALTERNATIVES)
                self.close()
 
+class SelectionEventInfo:
+       def __init__(self):
+               self["ServiceEvent"] = ServiceEvent()
+               self.servicelist.connectSelChanged(self.__selectionChanged)
+               self.timer = eTimer()
+               self.timer.callback.append(self.updateEventInfo)
+               self.onShown.append(self.__selectionChanged)
+
+       def __selectionChanged(self):
+               if self.execing:
+                       self.timer.start(100, True)
+
+       def updateEventInfo(self):
+               cur = self.getCurrentSelection()
+               self["ServiceEvent"].newService(cur)
+
 class ChannelSelectionEPG:
        def __init__(self):
                self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
@@ -281,11 +317,24 @@ class ChannelSelectionEPG:
 
        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):
@@ -394,10 +443,10 @@ class ChannelSelectionEdit:
                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)"
-                               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()
@@ -477,7 +526,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.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:
@@ -522,7 +571,7 @@ class ChannelSelectionEdit:
                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()
@@ -577,7 +626,7 @@ class ChannelSelectionEdit:
                        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:]
@@ -604,9 +653,18 @@ class ChannelSelectionEdit:
 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):
@@ -633,7 +691,7 @@ class ChannelSelectionBase(Screen):
 
                self.bouquetNumOffsetCache = { }
 
-               self["ChannelSelectBaseActions"] = NumberActionMap(["ChannelSelectBaseActions", "NumberActions"],
+               self["ChannelSelectBaseActions"] = NumberActionMap(["ChannelSelectBaseActions", "NumberActions", "InputAsciiActions"],
                        {
                                "showFavourites": self.showFavourites,
                                "showAllServices": self.showAllServices,
@@ -643,6 +701,7 @@ class ChannelSelectionBase(Screen):
                                "prevBouquet": self.prevBouquet,
                                "nextMarker": self.nextMarker,
                                "prevMarker": self.prevMarker,
+                               "gotAsciiCode": self.keyAsciiCode,
                                "1": self.keyNumberGlobal,
                                "2": self.keyNumberGlobal,
                                "3": self.keyNumberGlobal,
@@ -702,7 +761,7 @@ class ChannelSelectionBase(Screen):
                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]
@@ -713,7 +772,7 @@ class ChannelSelectionBase(Screen):
                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]
@@ -744,18 +803,18 @@ class ChannelSelectionBase(Screen):
 
        def getServiceName(self, ref):
                str = self.removeModeStr(ServiceReference(ref).getServiceName())
-               if not len(str):
+               if not str:
                        pathstr = ref.getPath()
-                       if pathstr.find('FROM PROVIDERS') != -1:
+                       if 'FROM PROVIDERS' in pathstr:
                                return _("Provider")
-                       if pathstr.find('FROM SATELLITES') != -1:
+                       if 'FROM SATELLITES' in pathstr:
                                return _("Satellites")
-                       if pathstr.find(') ORDER BY name') != -1:
+                       if ') ORDER BY name' in pathstr:
                                return _("All")
                return str
 
        def buildTitleString(self):
-               titleStr = self.instance.getTitle()
+               titleStr = self.getTitle()
                pos = titleStr.find(']')
                if pos == -1:
                        pos = titleStr.find(')')
@@ -794,9 +853,8 @@ class ChannelSelectionBase(Screen):
 
        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)
@@ -852,30 +910,44 @@ class ChannelSelectionBase(Screen):
                                                        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_name = _("Providers")
+                                                               service_type = _("Providers")
                                                        elif service.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
-                                                               service_name = _("New")
+                                                               service_type = _("New")
                                                        else:
-                                                               service_name = _("Services")
+                                                               service_type = _("Services")
                                                        try:
-                                                               service_name += str(' - %s'%(nimmanager.getSatDescription(orbpos)))
-                                                               service.setName(service_name) # why we need this cast?
+                                                               # why we need this cast?
+                                                               service_name = str(nimmanager.getSatDescription(orbpos))
                                                        except:
-                                                               if orbpos == 0xFFFF: #Cable
-                                                                       n = ("%s (%s)") % (service_name, _("Cable"))
-                                                               elif orbpos == 0xEEEE: #Terrestrial
-                                                                       n = ("%s (%s)") % (service_name, _("Terrestrial"))
+                                                               if unsigned_orbpos == 0xFFFF: #Cable
+                                                                       service_name = _("Cable")
+                                                               elif unsigned_orbpos == 0xEEEE: #Terrestrial
+                                                                       service_name = _("Terrestrial")
                                                                else:
                                                                        if orbpos > 1800: # west
                                                                                orbpos = 3600 - orbpos
                                                                                h = _("W")
                                                                        else:
                                                                                h = _("E")
-                                                                       n = ("%s (%d.%d" + h + ")") % (service_name, orbpos / 10, orbpos % 10)
-                                                               service.setName(n)
+                                                                       service_name = ("%d.%d" + h) % (orbpos / 10, orbpos % 10)
+                                                       service.setName("%s - %s" % (service_name, service_type))
                                                        self.servicelist.addService(service)
+                                               cur_ref = self.session.nav.getCurrentlyPlayingServiceReference()
+                                               if cur_ref:
+                                                       pos = self.service_types.rfind(':')
+                                                       refstr = '%s (channelID == %08x%04x%04x) && %s ORDER BY name' %(self.service_types[:pos+1],
+                                                               cur_ref.getUnsignedData(4), # NAMESPACE
+                                                               cur_ref.getUnsignedData(2), # TSID
+                                                               cur_ref.getUnsignedData(3), # ONID
+                                                               self.service_types[pos+1:])
+                                                       ref = eServiceReference(refstr)
+                                                       ref.setName(_("Current Transponder"))
+                                                       self.servicelist.addService(ref)
                                                self.servicelist.finishFill()
                                                if prev is not None:
                                                        self.setCurrentSelection(prev)
@@ -910,7 +982,9 @@ class ChannelSelectionBase(Screen):
                                self.enterPath(ref)
 
        def inBouquet(self):
-               return self.isBasePathEqual(self.bouquet_root)
+               if self.servicePath and self.servicePath[0] == self.bouquet_root:
+                       return True
+               return False
 
        def atBegin(self):
                return self.servicelist.atBegin()
@@ -941,6 +1015,12 @@ class ChannelSelectionBase(Screen):
                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()
 
@@ -948,14 +1028,6 @@ class ChannelSelectionBase(Screen):
                return self.servicelist.getCurrent()
 
        def setCurrentSelection(self, service):
-               servicepath = service.getPath()
-               pos = servicepath.find(" FROM BOUQUET")
-               if pos != -1:
-                       if self.mode == MODE_TV:
-                               servicepath = '(type == 1)' + servicepath[pos:]
-                       else:
-                               servicepath = '(type == 2)' + servicepath[pos:]
-                       service.setPath(servicepath)
                self.servicelist.setCurrent(service)
 
        def getBouquetList(self):
@@ -1019,11 +1091,12 @@ config.radio.lastroot = ConfigText()
 config.servicelist = ConfigSubsection()
 config.servicelist.lastmode = ConfigText(default = "tv")
 
-class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
+class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, SelectionEventInfo):
        def __init__(self, session):
                ChannelSelectionBase.__init__(self,session)
                ChannelSelectionEdit.__init__(self)
                ChannelSelectionEPG.__init__(self)
+               SelectionEventInfo.__init__(self)
 
                self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
                        {
@@ -1040,7 +1113,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                        })
 
                self.lastChannelRootTimer = eTimer()
-               self.lastChannelRootTimer.timeout.get().append(self.__onCreate)
+               self.lastChannelRootTimer.callback.append(self.__onCreate)
                self.lastChannelRootTimer.start(100,True)
 
                self.history_tv = [ ]
@@ -1052,6 +1125,16 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                self.lastroot = config.tv.lastroot
                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()
@@ -1119,6 +1202,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                        root = self.getRoot()
                        if not root or not (root.flags & eServiceReference.isGroup):
                                self.zap()
+                               self.asciiOff()
                                self.close(ref)
 
        #called from infoBar and channelSelected
@@ -1127,12 +1211,18 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                ref = self.session.nav.getCurrentlyPlayingServiceReference()
                nref = self.getCurrentSelection()
                if ref is None or ref != nref:
+                       self.new_service_played = True
                        self.session.nav.playService(nref)
                        self.saveRoot()
                        self.saveChannel(nref)
                        config.servicelist.lastmode.save()
                        self.addToHistory(nref)
 
+       def newServicePlayed(self):
+               ret = self.new_service_played
+               self.new_service_played = False
+               return ret
+
        def addToHistory(self, ref):
                if self.servicePath is not None:
                        tmp=self.servicePath[:]
@@ -1166,8 +1256,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                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)
@@ -1180,7 +1269,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                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()
 
@@ -1190,7 +1279,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                tmp = re.findall(self.lastroot.value)
                cnt = 0
                for i in tmp:
-                       self.servicePath.append(eServiceReference(i[:len(i)-1]))
+                       self.servicePath.append(eServiceReference(i[:-1]))
                        cnt += 1
                if cnt:
                        path = self.servicePath.pop()
@@ -1200,7 +1289,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                        self.saveRoot()
 
        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()
@@ -1220,16 +1309,14 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                        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):
-               hlen = len(self.history)
-               if hlen > 0:
+               if self.history:
                        return self.history[self.history_pos]
                return None
 
@@ -1257,31 +1344,23 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                elif self.revertMode == MODE_RADIO:
                        self.setModeRadio()
                self.revertMode = None
+               self.asciiOff()
                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)
-               InfoBarEvent.__init__(self)
-               InfoBarServiceName.__init__(self)
-               self["CurrentTime"] = Clock()
                self["RdsDecoder"] = RdsDecoder(self.session.nav)
-               self["BlinkingPoint"] = BlinkingPixmapConditional()
-               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)
+               InfoBarBase.__init__(self)
                self.infobar = infobar
-               config.radio = ConfigSubsection();
-               config.radio.lastservice = ConfigText()
-               config.radio.lastroot = ConfigText()
                self.onLayoutFinish.append(self.onCreate)
 
                self.info = session.instantiateDialog(RadioInfoBar) # our simple infobar
@@ -1309,6 +1388,11 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                },-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();
@@ -1327,8 +1411,6 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                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):
@@ -1347,7 +1429,7 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                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()
 
@@ -1357,7 +1439,7 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                tmp = re.findall(config.radio.lastroot.value)
                cnt = 0
                for i in tmp:
-                       self.servicePathRadio.append(eServiceReference(i[:len(i)-1]))
+                       self.servicePathRadio.append(eServiceReference(i[:-1]))
                        cnt += 1
                if cnt:
                        path = self.servicePathRadio.pop()
@@ -1367,7 +1449,7 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                        self.saveRoot()
 
        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()
@@ -1384,6 +1466,8 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                if lastservice.valid():
                        self.servicelist.setCurrent(lastservice)
                        self.session.nav.playService(lastservice)
+               else:
+                       self.session.nav.stopService()
                self.info.show()
 
        def channelSelected(self): # just return selected service
@@ -1408,9 +1492,6 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
 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,
@@ -1418,9 +1499,10 @@ class SimpleChannelSelection(ChannelSelectionBase):
                                "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