add subtitle support, though still disabled in dvb service
[enigma2.git] / lib / python / Screens / InfoBarGenerics.py
index 9a8844495d5eca23e85e4ebb4376b926e927f857..948ecbf6e2c90b27128525151cc5e12e49f82bb8 100644 (file)
@@ -13,7 +13,7 @@ from Components.PluginComponent import plugins
 from Components.ProgressBar import *
 from Components.ServiceEventTracker import ServiceEventTracker
 from Components.ServiceName import ServiceName
-from Components.config import config, configElement, ConfigSubsection, configSequence, configElementBoolean
+from Components.config import config, configElement, ConfigSubsection, configSequence, configElementBoolean, configSelection, configElement_nonSave, getConfigListEntry
 from Components.config import configfile, configsequencearg
 from Components.TimerList import TimerEntryComponent
 from Components.TunerInfo import TunerInfo
@@ -30,6 +30,7 @@ from Screens.MessageBox import MessageBox
 from Screens.MinuteInput import MinuteInput
 from Screens.TimerSelection import TimerSelection
 from Screens.PictureInPicture import PictureInPicture
+from Screens.SubtitleDisplay import SubtitleDisplay
 from ServiceReference import ServiceReference
 
 from Tools import Notifications
@@ -265,7 +266,7 @@ class InfoBarChannelSelection:
                config.misc.initialchannelselection.value = 0
                config.misc.initialchannelselection.save()
                self.switchChannelDown()
-               
+
        def historyBack(self):
                self.servicelist.historyBack()
 
@@ -342,8 +343,15 @@ class InfoBarSimpleEventView:
 class InfoBarEPG:
        """ EPG - Opens an EPG list when the showEPGList action fires """
        def __init__(self):
+               self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
+                       {
+                               iPlayableService.evUpdatedEventInfo: self.__evEventInfoChanged,
+                       })
+
+               self.is_now_next = False
                self.dlg_stack = [ ]
                self.bouquetSel = None
+               self.eventView = None
                self["EPGActions"] = HelpableActionMap(self, "InfobarEPGActions", 
                        {
                                "showEventInfo": (self.openEventView, _("show EPG...")),
@@ -397,10 +405,12 @@ class InfoBarEPG:
                closedScreen = self.dlg_stack.pop()
                if self.bouquetSel and closedScreen == self.bouquetSel:
                        self.bouquetSel = None
+               elif self.eventView and closedScreen == self.eventView:
+                       self.eventView = None
                if ret:
                        dlgs=len(self.dlg_stack)
-                       assert dlgs>0
-                       self.dlg_stack[dlgs-1].close(dlgs > 1)
+                       if dlgs > 0:
+                               self.dlg_stack[dlgs-1].close(dlgs > 1)
 
        def openMultiServiceEPG(self, withCallback=True):
                bouquets = self.servicelist.getBouquetList()
@@ -424,27 +434,41 @@ class InfoBarEPG:
        def openSimilarList(self, eventid, refstr):
                self.session.open(EPGSelection, refstr, None, eventid)
 
-       def openEventView(self):
+       def getNowNext(self):
                self.epglist = [ ]
                service = self.session.nav.getCurrentService()
-               ref = self.session.nav.getCurrentlyPlayingServiceReference()
-               info = service.info()
-               ptr=info.getEvent(0)
+               info = service and service.info()
+               ptr = info and info.getEvent(0)
                if ptr:
                        self.epglist.append(ptr)
-               ptr=info.getEvent(1)
+               ptr = info and info.getEvent(1)
                if ptr:
                        self.epglist.append(ptr)
+
+       def __evEventInfoChanged(self):
+               if self.is_now_next and len(self.dlg_stack) == 1:
+                       self.getNowNext()
+                       assert self.eventView
+                       if len(self.epglist):
+                               self.eventView.setEvent(self.epglist[0])
+
+       def openEventView(self):
+               ref = self.session.nav.getCurrentlyPlayingServiceReference()
+               self.getNowNext()
                if len(self.epglist) == 0:
+                       self.is_now_next = False
                        epg = eEPGCache.getInstance()
-                       ptr = epg.lookupEventTime(ref, -1)
+                       ptr = ref and ref.valid() and epg.lookupEventTime(ref, -1)
                        if ptr:
                                self.epglist.append(ptr)
                                ptr = epg.lookupEventTime(ref, ptr.getBeginTime(), +1)
                                if ptr:
                                        self.epglist.append(ptr)
+               else:
+                       self.is_now_next = True
                if len(self.epglist) > 0:
-                       self.dlg_stack.append(self.session.openWithCallback(self.closed, EventViewEPGSelect, self.epglist[0], ServiceReference(ref), self.eventViewCallback, self.openSingleServiceEPG, self.openMultiServiceEPG, self.openSimilarList))
+                       self.eventView = self.session.openWithCallback(self.closed, EventViewEPGSelect, self.epglist[0], ServiceReference(ref), self.eventViewCallback, self.openSingleServiceEPG, self.openMultiServiceEPG, self.openSimilarList)
+                       self.dlg_stack.append(self.eventView)
                else:
                        print "no epg for the service avail.. so we show multiepg instead of eventinfo"
                        self.openMultiServiceEPG(False)
@@ -983,6 +1007,8 @@ class InfoBarTimeshift:
                self.timeshift_enabled = False
                self.__seekableStatusChanged()
 
+from Screens.PiPSetup import PiPSetup
+
 class InfoBarExtensions:
        def __init__(self):
                self.pipshown = False
@@ -991,36 +1017,55 @@ class InfoBarExtensions:
                        {
                                "extensions": (self.extensions, "Extensions..."),
                        })
-                       
+
+       PIPON = 0
+       PIPOFF = 1
+       MOVEPIP = 2
+       PIPSWAP = 3
+       ENABLE_SUBTITLE = 4
+
        def extensions(self):
                list = []
                if self.pipshown == False:
-                       list.append((_("Activate Picture in Picture"), "pipon"))
+                       list.append((_("Activate Picture in Picture"), self.PIPON))
                elif self.pipshown == True:
-                       list.append((_("Disable Picture in Picture"), "pipoff"))
+                       list.append((_("Disable Picture in Picture"), self.PIPOFF))
+                       list.append((_("Move Picture in Picture"), self.MOVEPIP))
+                       list.append((_("Swap services"), self.PIPSWAP))
+               
+               s = self.getCurrentServiceSubtitle()
+               
+               for x in s.getSubtitleList():
+                       list.append(("DEBUG: Enable Subtitles: " + x[0], self.ENABLE_SUBTITLE, x))
+               
                self.session.openWithCallback(self.extensionCallback, ChoiceBox, title=_("Please choose an extension..."), list = list)
 
        def extensionCallback(self, answer):
                if answer is not None:
-                       if answer[1] == "pipon":
-                               self.session.nav.stopService()
+                       if answer[1] == self.PIPON:
                                self.pip = self.session.instantiateDialog(PictureInPicture)
-                               #self.pip.show()
                                
                                newservice = self.session.nav.getCurrentlyPlayingServiceReference()
-                               self.pipservice = eServiceCenter.getInstance().play(newservice)
-                               if self.pipservice and not self.pipservice.setTarget(1):
-                                       self.pipservice.start()
+                               
+                               if self.pip.playService(newservice):
                                        self.pipshown = True
                                else:
-                                       self.pipservice = None
+                                       self.pipshown = False
                                        del self.pip
-       
-                       elif answer[1] == "pipoff":
-                               #self.pip.hide()
-                               self.pipservice = None
+                               self.session.nav.playService(newservice)
+                       elif answer[1] == self.PIPOFF:
                                del self.pip
                                self.pipshown = False
+                       elif answer[1] == self.PIPSWAP:
+                               swapservice = self.pip.getCurrentService()
+                               self.pip.playService(self.session.nav.getCurrentlyPlayingServiceReference())
+                               self.session.nav.playService(swapservice)
+                               
+                       elif answer[1] == self.MOVEPIP:
+                               self.session.open(PiPSetup, pip = self.pip)
+                       elif answer[1] == self.ENABLE_SUBTITLE:
+                               self.selected_subtitle = answer[2]
+                               self.subtitles_enabled = True
 
 from RecordTimer import parseEvent
 
@@ -1148,7 +1193,7 @@ class InfoBarInstantRecord:
                else:
                        self.session.openWithCallback(self.recordQuestionCallback, ChoiceBox, title=_("Start recording?"), list=[(_("add recording (indefinitely)"), "indefinitely"), (_("add recording (stop after current event)"), "event"), (_("add recording (enter recording duration)"), "manualduration"),(_("don't record"), "no")])
 
-from Screens.AudioSelection import AudioSelection
+from Tools.ISO639 import LanguageCodes
 
 class InfoBarAudioSelection:
        def __init__(self):
@@ -1160,29 +1205,123 @@ class InfoBarAudioSelection:
        def audioSelection(self):
                service = self.session.nav.getCurrentService()
                audio = service.audioTracks()
+               self.audioTracks = audio
                n = audio.getNumberOfTracks()
                if n > 0:
-                       self.session.open(AudioSelection, audio)
+#                      self.audioChannel = service.audioChannel()
+#                      config.audio.audiochannel = configElement_nonSave("config.audio.audiochannel", configSelection, self.audioChannel.getCurrentChannel(), (("left", _("Left  >")), ("stereo", _("<  Stereo  >")), ("right", _("<  Right"))))
+                       tlist = []
+                       for x in range(n):
+                               i = audio.getTrackInfo(x)
+                               language = i.getLanguage()
+                               description = i.getDescription();
+       
+                               if len(language) == 3:
+                                       if language in LanguageCodes:
+                                               language = LanguageCodes[language][0]
+       
+                               if len(description):
+                                       description += " (" + language + ")"
+                               else:
+                                       description = language
+       
+                               tlist.append((description, x))
+                       
+                       selectedAudio = tlist[0][1]
+                       tlist.sort(lambda x,y : cmp(x[0], y[0]))
+
+#                      tlist.insert(0, getConfigListEntry(_("Audio Channel"), config.audio.audiochannel))
+
+                       selection = 0
+                       for x in tlist:
+                               if x[1] != selectedAudio:
+                                       selection += 1
+                               else:
+                                       break
+                       
+                       self.session.openWithCallback(self.audioSelected, ChoiceBox, title=_("Select audio track"), list = tlist, selection = selection)
+               else:
+                       del self.audioTracks
 
-from Screens.SubserviceSelection import SubserviceSelection
+       def audioSelected(self, audio):
+               if audio is not None:
+                       self.audioTracks.selectTrack(audio[1])
+               del self.audioTracks
+#              del self.audioChannel
+#              del config.audio.audiochannel
 
 class InfoBarSubserviceSelection:
        def __init__(self):
                self["SubserviceSelectionAction"] = HelpableActionMap(self, "InfobarSubserviceSelectionActions",
                        {
-                               "subserviceSelection": (self.subserviceSelection, "Subservice list..."),
+                               "subserviceSelection": (self.subserviceSelection, _("Subservice list...")),
                        })
 
+               self["SubserviceQuickzapAction"] = HelpableActionMap(self, "InfobarSubserviceQuickzapActions",
+                       {
+                               "nextSubservice": (self.nextSubservice, _("Switch to next subservice")),
+                               "prevSubservice": (self.prevSubservice, _("Switch to previous subservice"))
+                       }, -1)
+               self["SubserviceQuickzapAction"].setEnabled(False)
+
+               self.session.nav.event.append(self.checkSubservicesAvail) # we like to get service events
+
+       def checkSubservicesAvail(self, ev):
+               if ev == iPlayableService.evUpdatedEventInfo:
+                       service = self.session.nav.getCurrentService()
+                       subservices = service.subServices()
+                       if subservices.getNumberOfSubservices() == 0:
+                               self["SubserviceQuickzapAction"].setEnabled(False)
+
+       def nextSubservice(self):
+               self.changeSubservice(+1)
+
+       def prevSubservice(self):
+               self.changeSubservice(-1)
+
+       def changeSubservice(self, direction):
+               service = self.session.nav.getCurrentService()
+               subservices = service.subServices()
+               n = subservices.getNumberOfSubservices()
+               if n > 0:
+                       selection = -1
+                       ref = self.session.nav.getCurrentlyPlayingServiceReference()
+                       for x in range(n):
+                               if subservices.getSubservice(x).toString() == ref.toString():
+                                       selection = x
+                       if selection != -1:
+                               selection += direction
+                               if selection >= n:
+                                       selection=0
+                               elif selection < 0:
+                                       selection=n-1
+                               newservice = subservices.getSubservice(selection)
+                               if newservice.valid():
+                                       del subservices
+                                       del service
+                                       self.session.nav.playService(newservice)
+
        def subserviceSelection(self):
                service = self.session.nav.getCurrentService()
                subservices = service.subServices()
+               
                n = subservices.getNumberOfSubservices()
+               selection = 0
                if n > 0:
-                       self.session.openWithCallback(self.subserviceSelected, SubserviceSelection, subservices)
+                       ref = self.session.nav.getCurrentlyPlayingServiceReference()
+                       tlist = []
+                       for x in range(n):
+                               i = subservices.getSubservice(x)
+                               if i.toString() == ref.toString():
+                                       selection = x
+                               tlist.append((i.getName(), i))
+
+                       self.session.openWithCallback(self.subserviceSelected, ChoiceBox, title=_("Please select a subservice..."), list = tlist, selection = selection)
 
        def subserviceSelected(self, service):
                if not service is None:
-                       self.session.nav.playService(service)
+                       self["SubserviceQuickzapAction"].setEnabled(True)
+                       self.session.nav.playService(service[1])
 
 class InfoBarAdditionalInfo:
        def __init__(self):
@@ -1282,6 +1421,10 @@ class InfoBarNotifications:
        def __init__(self):
                self.onExecBegin.append(self.checkNotifications)
                Notifications.notificationAdded.append(self.checkNotificationsIfExecing)
+               self.onClose.append(self.__removeNotification)
+       
+       def __removeNotification(self):
+               Notifications.notificationAdded.remove(self.checkNotificationsIfExecing)
        
        def checkNotificationsIfExecing(self):
                if self.execing:
@@ -1291,12 +1434,11 @@ class InfoBarNotifications:
                if len(Notifications.notifications):
                        n = Notifications.notifications[0]
                        Notifications.notifications = Notifications.notifications[1:]
-                       print "open",n
                        cb = n[0]
                        if cb is not None:
-                               self.session.openWithCallback(cb, *n[1:])
+                               self.session.openWithCallback(cb, n[1], *n[2], **n[3])
                        else:
-                               self.session.open(*n[1:])
+                               self.session.open(n[1], *n[2], **n[3])
 
 class InfoBarServiceNotifications:
        def __init__(self):
@@ -1469,3 +1611,50 @@ class InfoBarTeletextPlugin:
 
        def startTeletext(self):
                self.teletext_plugin(session=self.session, service=self.session.nav.getCurrentService())
+
+class InfoBarSubtitleSupport(object):
+       def __init__(self):
+               object.__init__(self)
+               self.subtitle_window = self.session.instantiateDialog(SubtitleDisplay)
+               self.__subtitles_enabled = False
+
+               self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
+                       {
+                               iPlayableService.evStart: self.__serviceStarted,
+                       })
+
+       def __serviceStarted(self):
+               # reenable if it was enabled
+               r = self.__subtitles_enabled
+               self.__subtitles_enabled = False
+               self.__selected_subtitle = None
+               self.setSubtitlesEnable(r)
+
+       def getCurrentServiceSubtitle(self):
+               service = self.session.nav.getCurrentService()
+               return service and service.subtitle()
+       
+       def setSubtitlesEnable(self, enable=True):
+               subtitle = self.getCurrentServiceSubtitle()
+               if enable and self.__selected_subtitle:
+                       if subtitle and not self.__subtitles_enabled:
+                               subtitle.enableSubtitles(self.subtitle_window.instance, self.selected_subtitle)
+                               self.subtitle_window.show()
+                               self.__subtitles_enabled = True
+               else:
+                       if subtitle:
+                               subtitle.disableSubtitles(self.subtitle_window.instance)
+
+                       self.subtitle_window.hide()
+                       self.__subtitles_enabled = False
+
+       def setSelectedSubtitle(self, subtitle):
+               if self.__selected_subtitle != subtitle and self.subtitles_enabled:
+                       subtitle = self.getCurrentServiceSubtitle()
+                       
+                       # kick
+                       self.__serviceStarted()
+               self.__selected_subtitle = subtitle
+
+       subtitles_enabled = property(lambda self: self.__subtitles_enabled, setSubtitlesEnable)
+       selected_subtitle = property(lambda self: self.__selected_subtitle, setSelectedSubtitle)