movieplayer_select.patch by Moritz Venn
[enigma2.git] / lib / python / Screens / ChannelSelection.py
index 1ccddf75ed49702cf9e1ac7281c32479340e8a45..7bd50472719a8c17fa44ae6477833b093f38e7f1 100644 (file)
@@ -1,33 +1,42 @@
+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
+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.Source import ObsoleteSource
+profile("ChannelSelection.py 2.2")
 from Components.Sources.RdsDecoder import RdsDecoder
+profile("ChannelSelection.py 2.3")
+from Components.Sources.ServiceEvent import ServiceEvent
+profile("ChannelSelection.py 2.4")
 from Components.Input import Input
+profile("ChannelSelection.py 3")
 from Components.ParentalControl import parentalControl
-from Components.Pixmap import BlinkingPixmapConditional
+from Components.Pixmap import Pixmap
 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 +72,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 "we need a better summary screen here"
                self.csel = csel
                self.bsel = None
 
@@ -89,63 +99,63 @@ class ChannelContextMenu(Screen):
                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))
+                       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 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 +170,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:
@@ -206,7 +216,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 +282,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"],
@@ -605,7 +631,7 @@ 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_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25) || (type == 134)'
 service_types_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2)'
 
 class ChannelSelectionBase(Screen):
@@ -633,7 +659,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 +669,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,
@@ -852,30 +879,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 +951,9 @@ class ChannelSelectionBase(Screen):
                                self.enterPath(ref)
 
        def inBouquet(self):
-               return self.isBasePathEqual(self.bouquet_root)
+               if len(self.servicePath) > 0 and self.servicePath[0] == self.bouquet_root:
+                       return True
+               return False
 
        def atBegin(self):
                return self.servicelist.atBegin()
@@ -941,6 +984,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()
 
@@ -1019,11 +1068,14 @@ 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["CurrentTime"] = ObsoleteSource(new_source = "global.CurrentTime", removal_date = "2008-01")
 
                self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
                        {
@@ -1040,7 +1092,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 +1104,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 +1181,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 +1190,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[:]
@@ -1257,6 +1326,7 @@ 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
@@ -1266,9 +1336,9 @@ class RadioInfoBar(Screen, InfoBarEvent, InfoBarServiceName):
                Screen.__init__(self, session)
                InfoBarEvent.__init__(self)
                InfoBarServiceName.__init__(self)
-               self["CurrentTime"] = Clock()
+               self["CurrentTime"] = ObsoleteSource(new_source = "global.CurrentTime", removal_date = "2008-01")
                self["RdsDecoder"] = RdsDecoder(self.session.nav)
-               self["BlinkingPoint"] = BlinkingPixmapConditional()
+               self["BlinkingPoint"] = Pixmap()
                self["BlinkingPoint"].hide()
 
 class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
@@ -1279,9 +1349,6 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                ChannelSelectionEdit.__init__(self)
                ChannelSelectionEPG.__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
@@ -1384,6 +1451,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