change keys for activating/controlling PiP to color keys instead of number keys
[enigma2.git] / lib / python / Screens / InfoBarGenerics.py
index 4f0e76b16375c246eea03be4e0b9234a1875a6d5..af8f0a91c67bc4ba03b41c474700c251f503da90 100644 (file)
@@ -12,12 +12,12 @@ from Components.ProgressBar import *
 from Components.ServiceEventTracker import ServiceEventTracker
 from Components.Sources.CurrentService import CurrentService
 from Components.Sources.EventInfo import EventInfo
+from Components.Sources.RadioText import RadioText
 from Components.Sources.FrontendStatus import FrontendStatus
 from Components.Sources.Boolean import Boolean
 from Components.Sources.Clock import Clock
 from Components.TimerList import TimerEntryComponent
-from Components.config import config, configElement, ConfigSubsection, configSequence, configElementBoolean, configSelection, configElement_nonSave, getConfigListEntry
-from Components.config import configfile, configsequencearg
+from Components.config import config, ConfigBoolean
 
 from EpgSelection import EPGSelection
 from Plugins.Plugin import PluginDescriptor
@@ -44,8 +44,6 @@ import time
 import os
 import bisect
 
-from Components.config import config, currentConfigSelectionElement
-
 # hack alert!
 from Menu import MainMenu, mdom
 
@@ -240,7 +238,7 @@ class InfoBarNumberZap:
                        self.servicelist.setCurrentSelection(service) #select the service in servicelist
                        self.servicelist.zap()
 
-config.misc.initialchannelselection = configElementBoolean("config.misc.initialchannelselection", 1);
+config.misc.initialchannelselection = ConfigBoolean(default = True)
 
 class InfoBarChannelSelection:
        """ ChannelSelection - handles the channelSelection dialog and the initial 
@@ -249,7 +247,7 @@ class InfoBarChannelSelection:
                #instantiate forever
                self.servicelist = self.session.instantiateDialog(ChannelSelection)
                
-               if config.misc.initialchannelselection.value == 1:
+               if config.misc.initialchannelselection.value:
                        self.onShown.append(self.firstRun)
 
                self["ChannelSelectActions"] = HelpableActionMap(self, "InfobarChannelSelection",
@@ -277,7 +275,7 @@ class InfoBarChannelSelection:
 
        def firstRun(self):
                self.onShown.remove(self.firstRun)
-               config.misc.initialchannelselection.value = 0
+               config.misc.initialchannelselection.value = False
                config.misc.initialchannelselection.save()
                self.switchChannelDown()
 
@@ -299,16 +297,36 @@ class InfoBarChannelSelection:
                self.session.execDialog(self.servicelist)
 
        def zapUp(self):
-               if currentConfigSelectionElement(config.usage.quickzap_bouquet_change) == "yes":
-                       if self.servicelist.inBouquet() and self.servicelist.atBegin():
-                               self.servicelist.prevBouquet()
-               self.servicelist.moveUp()
+               if self.servicelist.inBouquet():
+                       prev = self.servicelist.getCurrentSelection()
+                       if prev:
+                               prev = prev.toString()
+                               while True:
+                                       if config.usage.quickzap_bouquet_change.value:
+                                               if self.servicelist.atBegin():
+                                                       self.servicelist.prevBouquet()
+                                       self.servicelist.moveUp()
+                                       cur = self.servicelist.getCurrentSelection()
+                                       if not cur or (not (cur.flags & 64)) or cur.toString() == prev:
+                                               break
+               else:
+                       self.servicelist.moveUp()
                self.servicelist.zap()
                self.doShow()
 
        def zapDown(self):
-               if currentConfigSelectionElement(config.usage.quickzap_bouquet_change) == "yes" and self.servicelist.inBouquet() and self.servicelist.atEnd():
-                       self.servicelist.nextBouquet()
+               if self.servicelist.inBouquet():
+                       prev = self.servicelist.getCurrentSelection()
+                       if prev:
+                               prev = prev.toString()
+                               while True:
+                                       if config.usage.quickzap_bouquet_change.value and self.servicelist.atEnd():
+                                               self.servicelist.nextBouquet()
+                                       else:
+                                               self.servicelist.moveDown()
+                                       cur = self.servicelist.getCurrentSelection()
+                                       if not cur or (not (cur.flags & 64)) or cur.toString() == prev:
+                                               break
                else:
                        self.servicelist.moveDown()
                self.servicelist.zap()
@@ -508,6 +526,11 @@ class InfoBarEvent:
                self["Event_Now"] = EventInfo(self.session.nav, EventInfo.NOW)
                self["Event_Next"] = EventInfo(self.session.nav, EventInfo.NEXT)
 
+class InfoBarRadioText:
+       """provides radio (RDS) text info display"""
+       def __init__(self):
+               self["RadioText"] = RadioText(self.session.nav)
+
 class InfoBarServiceName:
        def __init__(self):
                self["CurrentService"] = CurrentService(self.session.nav)
@@ -672,7 +695,7 @@ class InfoBarSeek:
                print "unpause"
                if self.seekstate == self.SEEK_STATE_PLAY:
                        return 0
-               self.setSeekState(self.SEEK_STATE_PLAY);
+               self.setSeekState(self.SEEK_STATE_PLAY)
        
        def doSeek(self, seektime):
                print "doseek", seektime
@@ -807,6 +830,11 @@ class InfoBarSeek:
                if seekable is not None:
                        seekable.seekRelative(1, diff)
 
+       def seekAbsolute(self, abs):
+               seekable = self.getSeek()
+               if seekable is not None:
+                       seekable.seekTo(abs)
+
 from Screens.PVRState import PVRState, TimeshiftState
 
 class InfoBarPVRState:
@@ -1002,69 +1030,183 @@ class InfoBarTimeshift:
 from Screens.PiPSetup import PiPSetup
 
 class InfoBarExtensions:
+       EXTENSION_SINGLE = 0
+       EXTENSION_LIST = 1
+       
        def __init__(self):
-               self.session.pipshown = False
+               self.list = []
                
                self["InstantExtensionsActions"] = HelpableActionMap(self, "InfobarExtensions",
                        {
-                               "extensions": (self.extensions, _("view extensions...")),
+                               "extensions": (self.showExtensionSelection, _("view extensions...")),
                        })
 
-       PIPON = 0
-       PIPOFF = 1
-       MOVEPIP = 2
-       PIPSWAP = 3
-       ENABLE_SUBTITLE = 4
+       def addExtension(self, extension, key = None, type = EXTENSION_SINGLE):
+               self.list.append((type, extension, key))
+               
+       def updateExtension(self, extension, key = None):
+               self.extensionsList.append(extension)
+               if key is not None:
+                       if self.extensionKeys.has_key(key):
+                               key = None
+               
+               if key is None:
+                       for x in self.availableKeys:
+                               if not self.extensionKeys.has_key(x):
+                                       key = x
+                                       break
+
+               if key is not None:
+                       self.extensionKeys[key] = len(self.extensionsList) - 1
+                       
+       def updateExtensions(self):
+               self.extensionsList = []
+               self.availableKeys = [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "red", "green", "yellow", "blue" ]
+               self.extensionKeys = {}
+               for x in self.list:
+                       if x[0] == self.EXTENSION_SINGLE:
+                               self.updateExtension(x[1], x[2])
+                       else:
+                               for y in x[1]():
+                                       self.updateExtension(y[0], y[1])
 
-       def extensions(self):
+
+       def showExtensionSelection(self):
+               self.updateExtensions()
+               extensionsList = self.extensionsList[:]
+               keys = []
+               list = []
+               for x in self.availableKeys:
+                       if self.extensionKeys.has_key(x):
+                               entry = self.extensionKeys[x]
+                               extension = self.extensionsList[entry]
+                               if extension[2]():
+                                       name = str(extension[0]())
+                                       list.append((extension[0](), extension))
+                                       keys.append(x)
+                                       extensionsList.remove(extension)
+                               else:
+                                       extensionsList.remove(extension)
+               for x in extensionsList:
+                       list.append((x[0](), x))
+               keys += [""] * len(extensionsList)
+               self.session.openWithCallback(self.extensionCallback, ChoiceBox, title=_("Please choose an extension..."), list = list, keys = keys)
+
+       def extensionCallback(self, answer):
+               if answer is not None:
+                       answer[1][1]()
+
+from Tools.BoundFunction import boundFunction
+
+# depends on InfoBarExtensions
+from Components.PluginComponent import plugins
+
+class InfoBarPlugins:
+       def __init__(self):
+               self.addExtension(extension = self.getPluginList, type = InfoBarExtensions.EXTENSION_LIST)
+               
+               
+       def getPluginName(self, name):
+               return name
+               
+       def getPluginList(self):
                list = []
-               if self.session.pipshown == False:
-                       list.append((_("Activate Picture in Picture"), self.PIPON))
-               elif self.session.pipshown == True:
-                       list.append((_("Disable Picture in Picture"), self.PIPOFF))
-                       list.append((_("Move Picture in Picture"), self.MOVEPIP))
-                       list.append((_("Swap services"), self.PIPSWAP))
+               for p in plugins.getPlugins(where = PluginDescriptor.WHERE_EXTENSIONSMENU):
+                       list.append(((boundFunction(self.getPluginName, p.name), boundFunction(self.runPlugin, p), lambda: True), None))
+               return list
+
+       def runPlugin(self, plugin):
+               plugin(session = self.session)
+
+# depends on InfoBarExtensions and InfoBarSubtitleSupport
+class InfoBarSubtitles:
+       def __init__(self):
+               self.addExtension((self.getDisableSubtitleName, self.disableSubtitles, self.subtitlesEnabled), "4")
+               self.addExtension(extension = self.getSubtitleList, type = InfoBarExtensions.EXTENSION_LIST)
                
+       def getDisableSubtitleName(self):
+               return _("Disable subtitles")
+
+       def getSubtitleList(self):
+               list = []
                s = self.getCurrentServiceSubtitle()
                l = s and s.getSubtitleList() or [ ]
-               
+
                for x in l:
-                       list.append(("Enable Subtitles: " + x[0], self.ENABLE_SUBTITLE, x[1]))
+                       list.append(((boundFunction(self.getSubtitleEntryName, x[0]), boundFunction(self.enableSubtitle, x[1]), lambda: True), None))
+               return list
+       
+       def getSubtitleEntryName(self, name):
+               return "Enable Subtitles: " + name
+
+       def enableSubtitle(self, subtitles):
+               print "enable subitles", subtitles
+               self.selected_subtitle = subtitles
+               self.subtitles_enabled = True
                
-               self.session.openWithCallback(self.extensionCallback, ChoiceBox, title=_("Please choose an extension..."), list = list)
+       def subtitlesEnabled(self):
+               return self.subtitles_enabled
+               
+       def disableSubtitles(self):
+               self.subtitles_enabled = False
 
-       def extensionCallback(self, answer):
-               if answer is not None:
-                       if answer[1] == self.PIPON:
-                               self.session.pip = self.session.instantiateDialog(PictureInPicture)
-                               newservice = self.session.nav.getCurrentlyPlayingServiceReference()
-                               if self.session.pip.playService(newservice):
-                                       self.session.pipshown = True
-                                       self.session.pip.servicePath = self.servicelist.getCurrentServicePath()
-                               else:
-                                       self.session.pipshown = False
-                                       del self.session.pip
-                               self.session.nav.playService(newservice)
-                       elif answer[1] == self.PIPOFF:
-                               del self.session.pip
+# depends on InfoBarExtensions
+class InfoBarPiP:
+       def __init__(self):
+               self.session.pipshown = False
+
+               self.addExtension((self.getShowHideName, self.showPiP, self.available), "red")
+               self.addExtension((self.getMoveName, self.movePiP, self.pipShown), "green")
+               self.addExtension((self.getSwapName, self.swapPiP, self.pipShown), "yellow")
+       
+       def available(self):
+               return True
+       
+       def pipShown(self):
+               return self.session.pipshown
+       
+       def getShowHideName(self):
+               if self.session.pipshown:
+                       return _("Disable Picture in Picture")
+               else:
+                       return _("Activate Picture in Picture")
+               
+       def getSwapName(self):
+               return _("Swap Services")
+               
+       def getMoveName(self):
+               return _("Move Picture in Picture")
+       
+       def showPiP(self):
+               if self.session.pipshown:
+                       del self.session.pip
+                       self.session.pipshown = False
+               else:
+                       self.session.pip = self.session.instantiateDialog(PictureInPicture)
+                       newservice = self.session.nav.getCurrentlyPlayingServiceReference()
+                       if self.session.pip.playService(newservice):
+                               self.session.pipshown = True
+                               self.session.pip.servicePath = self.servicelist.getCurrentServicePath()
+                       else:
                                self.session.pipshown = False
-                       elif answer[1] == self.PIPSWAP:
-                               swapservice = self.session.nav.getCurrentlyPlayingServiceReference()
-                               if self.session.pip.servicePath:
-                                       servicepath = self.servicelist.getCurrentServicePath()
-                                       ref=servicepath[len(servicepath)-1]
-                                       pipref=self.session.pip.getCurrentService()
-                                       self.session.pip.playService(swapservice)
-                                       self.servicelist.setCurrentServicePath(self.session.pip.servicePath)
-                                       if pipref.toString() != ref.toString(): # is a subservice ?
-                                               self.session.nav.stopService() # stop portal
-                                               self.session.nav.playService(pipref) # start subservice
-                                       self.session.pip.servicePath=servicepath
-                       elif answer[1] == self.MOVEPIP:
-                               self.session.open(PiPSetup, pip = self.session.pip)
-                       elif answer[1] == self.ENABLE_SUBTITLE:
-                               self.selected_subtitle = answer[2]
-                               self.subtitles_enabled = True
+                               del self.session.pip
+                       self.session.nav.playService(newservice)
+       
+       def swapPiP(self):
+               swapservice = self.session.nav.getCurrentlyPlayingServiceReference()
+               if self.session.pip.servicePath:
+                       servicepath = self.servicelist.getCurrentServicePath()
+                       ref=servicepath[len(servicepath)-1]
+                       pipref=self.session.pip.getCurrentService()
+                       self.session.pip.playService(swapservice)
+                       self.servicelist.setCurrentServicePath(self.session.pip.servicePath)
+                       if pipref.toString() != ref.toString(): # is a subservice ?
+                               self.session.nav.stopService() # stop portal
+                               self.session.nav.playService(pipref) # start subservice
+                       self.session.pip.servicePath=servicepath
+       
+       def movePiP(self):
+               self.session.open(PiPSetup, pip = self.session.pip)
 
 from RecordTimer import parseEvent
 
@@ -1205,11 +1347,11 @@ class InfoBarAudioSelection:
                service = self.session.nav.getCurrentService()
                audio = service and service.audioTracks()
                self.audioTracks = audio
-               n = audio and audio.getNumberOfTracks()
+               n = audio and audio.getNumberOfTracks() or 0
                keys = [ "red", "", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] + [""]*n
                tlist = []
                print "tlist:", tlist
-               if n and n > 0:
+               if n > 0:
                        self.audioChannel = service.audioChannel()
 
                        for x in range(n):
@@ -1313,6 +1455,7 @@ class InfoBarSubserviceSelection:
                                if newservice.valid():
                                        del subservices
                                        del service
+                                       self.doShow()
                                        self.session.nav.playService(newservice)
 
        def subserviceSelection(self):
@@ -1330,12 +1473,22 @@ class InfoBarSubserviceSelection:
                                        selection = x
                                tlist.append((i.getName(), i))
 
-                       self.session.openWithCallback(self.subserviceSelected, ChoiceBox, title=_("Please select a subservice..."), list = tlist, selection = selection)
+                       tlist = [(_("Quickzap"), "quickzap", service.subServices()), ("--", "")] + tlist
+
+                       keys = ["red", "",  "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" ] + [""] * n
+
+                       self.session.openWithCallback(self.subserviceSelected, ChoiceBox, title=_("Please select a subservice..."), list = tlist, selection = selection + 2, keys = keys)
 
        def subserviceSelected(self, service):
                if not service is None:
-                       self["SubserviceQuickzapAction"].setEnabled(True)
-                       self.session.nav.playService(service[1])
+                       if isinstance(service[1], str):
+                               if service[1] == "quickzap":
+                                       from Screens.SubservicesQuickzap import SubservicesQuickzap
+                                       self.session.open(SubservicesQuickzap, service[2])
+                       else:
+                               self["SubserviceQuickzapAction"].setEnabled(True)
+                               self.doShow()
+                               self.session.nav.playService(service[1])
 
 class InfoBarAdditionalInfo:
        def __init__(self):
@@ -1423,6 +1576,9 @@ class InfoBarCueSheetSupport:
        CUT_TYPE_IN = 0
        CUT_TYPE_OUT = 1
        CUT_TYPE_MARK = 2
+       CUT_TYPE_LAST = 3
+       
+       ENABLE_RESUME_SUPPORT = False
        
        def __init__(self):
                self["CueSheetActions"] = HelpableActionMap(self, "InfobarCueSheetActions", 
@@ -1433,14 +1589,34 @@ class InfoBarCueSheetSupport:
                        }, prio=1) 
                
                self.cut_list = [ ]
+               self.is_closing = False
                self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
                        {
                                iPlayableService.evStart: self.__serviceStarted,
                        })
 
        def __serviceStarted(self):
+               if self.is_closing:
+                       return
                print "new service started! trying to download cuts!"
                self.downloadCuesheet()
+               
+               if self.ENABLE_RESUME_SUPPORT:
+                       last = None
+                       
+                       for (pts, what) in self.cut_list:
+                               if what == self.CUT_TYPE_LAST:
+                                       last = pts
+                       
+                       if last is not None:
+                               self.resume_point = last
+                               Notifications.AddNotificationWithCallback(self.playLastCB, MessageBox, _("Do you want to resume this playback?"), timeout=10)
+
+       def playLastCB(self, answer):
+               if answer == True:
+                       seekable = self.__getSeekable()
+                       if seekable is not None:
+                               seekable.seekTo(self.resume_point)
 
        def __getSeekable(self):
                service = self.session.nav.getCurrentService()
@@ -1542,10 +1718,10 @@ class InfoBarCueSheetSupport:
 class InfoBarSummary(Screen):
        skin = """
        <screen position="0,0" size="132,64">
-               <widget source="CurrentTime" render="Label" position="50,46" size="82,18" font="Regular;16" >
+               <widget source="CurrentTime" render="Label" position="56,46" size="82,18" font="Regular;16" >
                        <convert type="ClockToText">WithSeconds</convert>
                </widget>
-               <widget source="CurrentService" render="Label" position="0,4" size="132,42" font="Regular;18" >
+               <widget source="CurrentService" render="Label" position="6,4" size="120,42" font="Regular;18" >
                        <convert type="ServiceName">Name</convert>
                </widget>
        </screen>"""