add kwargs support for notifications
[enigma2.git] / lib / python / Screens / InfoBarGenerics.py
index 0ae0dc420b9c6d43941a93a0bc4c1fa2330d5712..2bae4296161dddc43f557636d9ad815957e32303 100644 (file)
@@ -342,6 +342,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...")),
@@ -357,8 +366,7 @@ class InfoBarEPG:
                        self.servicelist.setCurrentSelection(service) #select the service in servicelist
                        self.servicelist.zap()
 
-       def openBouquetEPG(self, bouquet, withCallback=True):
-               ptr=eEPGCache.getInstance()
+       def getBouquetServices(self, bouquet):
                services = [ ]
                servicelist = eServiceCenter.getInstance().list(bouquet)
                if not servicelist is None:
@@ -369,16 +377,39 @@ class InfoBarEPG:
                                if service.flags: #ignore non playable services
                                        continue
                                services.append(ServiceReference(service))
+               return services
+
+       def openBouquetEPG(self, bouquet, withCallback=True):
+               services = self.getBouquetServices(bouquet)
                if len(services):
                        self.epg_bouquet = bouquet
                        if withCallback:
-                               self.session.openWithCallback(self.closed, EPGSelection, services, self.zapToService)
+                               self.dlg_stack.append(self.session.openWithCallback(self.closed, EPGSelection, services, self.zapToService, None, self.changeBouquetCB))
                        else:
-                               self.session.open(EPGSelection, services, self.zapToService)
+                               self.session.open(EPGSelection, services, self.zapToService, None, self.changeBouquetCB)
 
-       def closed(self, ret):
+       def changeBouquetCB(self, direction, epg):
+               if self.bouquetSel:
+                       if direction > 0:
+                               self.bouquetSel.down()
+                       else:
+                               self.bouquetSel.up()
+                       bouquet = self.bouquetSel.getCurrent()
+                       services = self.getBouquetServices(bouquet)
+                       if len(services):
+                               self.epg_bouquet = bouquet
+                               epg.setServices(services)
+
+       def closed(self, ret=False):
+               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:
-                       self.close(ret)
+                       dlgs=len(self.dlg_stack)
+                       if dlgs > 0:
+                               self.dlg_stack[dlgs-1].close(dlgs > 1)
 
        def openMultiServiceEPG(self, withCallback=True):
                bouquets = self.servicelist.getBouquetList()
@@ -388,38 +419,54 @@ class InfoBarEPG:
                        cnt = len(bouquets)
                if cnt > 1: # show bouquet list
                        if withCallback:
-                               self.session.openWithCallback(self.closed, BouquetSelector, bouquets, self.openBouquetEPG)
+                               self.bouquetSel = self.session.openWithCallback(self.closed, BouquetSelector, bouquets, self.openBouquetEPG, enableWrapAround=True)
+                               self.dlg_stack.append(self.bouquetSel)
                        else:
-                               self.session.open(BouquetSelector, bouquets, self.openBouquetEPG)
+                               self.bouquetSel = self.session.open(BouquetSelector, bouquets, self.openBouquetEPG, enableWrapAround=True)
                elif cnt == 1: 
                        self.openBouquetEPG(bouquets[0][1], withCallback)
 
        def openSingleServiceEPG(self):
                ref=self.session.nav.getCurrentlyPlayingServiceReference()
-               ptr=eEPGCache.getInstance()
-               self.session.openWithCallback(self.closed, EPGSelection, ref)
+               self.session.open(EPGSelection, ref)
 
-       def openEventView(self):
+       def openSimilarList(self, eventid, refstr):
+               self.session.open(EPGSelection, refstr, None, eventid)
+
+       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
+                       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.session.open(EventViewEPGSelect, self.epglist[0], ServiceReference(ref), self.eventViewCallback, self.openSingleServiceEPG, self.openMultiServiceEPG)
+                       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)
@@ -561,7 +608,7 @@ class InfoBarSeek:
        def getSeek(self):
                service = self.session.nav.getCurrentService()
                if service is None:
-                       return False
+                       return None
 
                seek = service.seek()
 
@@ -857,7 +904,7 @@ class InfoBarTimeshift:
        
        def getTimeshift(self):
                service = self.session.nav.getCurrentService()
-               return service.timeshift()
+               return service and service.timeshift()
 
        def startTimeshift(self):
                print "enable timeshift"
@@ -958,6 +1005,8 @@ class InfoBarTimeshift:
                self.timeshift_enabled = False
                self.__seekableStatusChanged()
 
+from Screens.PiPSetup import PiPSetup
+
 class InfoBarExtensions:
        def __init__(self):
                self.pipshown = False
@@ -966,29 +1015,43 @@ class InfoBarExtensions:
                        {
                                "extensions": (self.extensions, "Extensions..."),
                        })
-                       
+
+       PIPON = 0
+       PIPOFF = 1
+       MOVEPIP = 2
+
        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))
                self.session.openWithCallback(self.extensionCallback, ChoiceBox, title=_("Please choose an extension..."), list = list)
 
        def extensionCallback(self, answer):
-               if answer[1] == "pipon":
-                       self.session.nav.stopService()
-                       self.pip = self.session.instantiateDialog(PictureInPicture)
-                       #self.pip.show()
-                       
-                       newservice = str(ServiceReference(self.session.nav.getCurrentlyPlayingServiceReference())) + "s"
-                       self.pipservice = eServiceCenter.getInstance().play(eServiceReference(newservice))
-                       self.pipservice.start()
-                       self.pipshown = True
-               elif answer[1] == "pipoff":
-                       #self.pip.hide()
-                       del self.pip
-                       self.pipshown = False
+               if answer is not None:
+                       if answer[1] == self.PIPON:
+#                              self.session.nav.stopService()
+                               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()
+                                       self.pipshown = True
+                               else:
+                                       self.pipservice = None
+                                       del self.pip
+                               self.session.nav.playService(newservice)
+                       elif answer[1] == self.PIPOFF:
+                               #self.pip.hide()
+                               self.pipservice = None
+                               del self.pip
+                               self.pipshown = False
+                       elif answer[1] == self.MOVEPIP:
+                               self.session.open(PiPSetup, pip = self.pip)
 
 from RecordTimer import parseEvent
 
@@ -1060,11 +1123,16 @@ class InfoBarInstantRecord:
                return False
 
        def recordQuestionCallback(self, answer):
+               print "pre:\n", self.recording
+               
                if answer is None or answer[1] == "no":
                        return
                list = []
-               for x in self.recording:
-                       if x.dontSave:
+               recording = self.recording[:]
+               for x in recording:
+                       if not x in self.session.nav.RecordTimer.timer_list:
+                               self.recording.remove(x)
+                       elif x.dontSave and x.isRunning():
                                list.append(TimerEntryComponent(x, False))              
 
                if answer[1] == "changeduration":
@@ -1085,6 +1153,8 @@ class InfoBarInstantRecord:
                                self.selectedEntry = len(self.recording)
                                self.session.openWithCallback(self.inputCallback, InputBox, title=_("How many minutes do you want to record?"), text="5", maxSize=False, type=Input.NUMBER)
                        self.startInstantRecording(limitEvent = limitEvent)
+                       
+               print "after:\n", self.recording
 
        def changeDuration(self, entry):
                if entry is not None:
@@ -1109,7 +1179,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):
@@ -1121,11 +1191,41 @@ class InfoBarAudioSelection:
        def audioSelection(self):
                service = self.session.nav.getCurrentService()
                audio = service.audioTracks()
+               self.audio = audio
                n = audio.getNumberOfTracks()
                if n > 0:
-                       self.session.open(AudioSelection, audio)
+                       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]))
+                       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)
 
-from Screens.SubserviceSelection import SubserviceSelection
+       def audioSelected(self, audio):
+               if audio is not None:
+                       self.audio.selectTrack(audio[1])
+               del self.audio
 
 class InfoBarSubserviceSelection:
        def __init__(self):
@@ -1137,13 +1237,23 @@ class InfoBarSubserviceSelection:
        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.session.nav.playService(service[1])
 
 class InfoBarAdditionalInfo:
        def __init__(self):
@@ -1255,9 +1365,9 @@ class InfoBarNotifications:
                        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):