always show timeshift state when infobar is visible (not only when state is
[enigma2.git] / lib / python / Screens / InfoBarGenerics.py
index 3ec37c6474b13a6e069d592ac54b058f76d0f462..571947915f0ec37d3b97d78e4168fbde82272491 100644 (file)
@@ -36,14 +36,14 @@ from Screens.SleepTimerEdit import SleepTimerEdit
 from ServiceReference import ServiceReference
 
 from Tools import Notifications
-from Tools.Directories import *
+from Tools.Directories import SCOPE_HDD, resolveFilename
 
-#from enigma import eTimer, eDVBVolumecontrol, quitMainloop
-from enigma import *
+from enigma import eTimer, eServiceCenter, eDVBServicePMTHandler, iServiceInformation, \
+       iPlayableService, eServiceReference, eDVBResourceManager, iFrontendInformation, eEPGCache
 
-import time
-import os
-import bisect
+from time import time
+from os import stat as os_stat
+from bisect import insort
 
 # hack alert!
 from Menu import MainMenu, mdom
@@ -210,9 +210,9 @@ class InfoBarNumberZap:
                                serviceIterator = servicelist.getNext()
                                if not serviceIterator.valid(): #check end of list
                                        break
-                               if serviceIterator.flags: #assume normal dvb service have no flags set
-                                       continue
-                               num -= 1;
+                               playable = not (serviceIterator.flags & (eServiceReference.isMarker|eServiceReference.isDirectory))
+                               if playable:
+                                       num -= 1;
                        if not num: #found service with searched number ?
                                return serviceIterator, 0
                return None, num
@@ -230,9 +230,8 @@ class InfoBarNumberZap:
                                        bouquet = self.servicelist.appendDVBTypes(bouquetlist.getNext())
                                        if not bouquet.valid(): #check end of list
                                                break
-                                       if not (bouquet.flags & eServiceReference.isDirectory):
-                                               continue
-                                       service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
+                                       if bouquet.flags & eServiceReference.isDirectory:
+                                               service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
                if not service is None:
                        if self.servicelist.getRoot() != bouquet: #already in correct bouquet?
                                self.servicelist.clearPath()
@@ -425,7 +424,7 @@ class InfoBarEPG:
                                service = servicelist.getNext()
                                if not service.valid(): #check if end of list
                                        break
-                               if service.flags: #ignore non playable services
+                               if service.flags & (eServiceReference.isDirectory | eServiceReference.isMarker): #ignore non playable services
                                        continue
                                services.append(ServiceReference(service))
                return services
@@ -597,6 +596,7 @@ class InfoBarSeek:
 
                self["SeekActions"] = InfoBarSeekActionMap(self, "InfobarSeekActions", 
                        {
+                               "playpauseService": (self.playpauseService, _("pause")),
                                "pauseService": (self.pauseService, _("pause")),
                                "unPauseService": (self.unPauseService, _("continue")),
                                
@@ -693,6 +693,12 @@ class InfoBarSeek:
                self.checkSkipShowHideLock()
 
                return True
+       
+       def playpauseService(self):
+               if self.seekstate != self.SEEK_STATE_PLAY:
+                       self.unPauseService()
+               else:
+                       self.pauseService()
 
        def pauseService(self):
                if self.seekstate == self.SEEK_STATE_PAUSE:
@@ -854,14 +860,15 @@ class InfoBarSeek:
 from Screens.PVRState import PVRState, TimeshiftState
 
 class InfoBarPVRState:
-       def __init__(self, screen=PVRState):
+       def __init__(self, screen=PVRState, show_always=False):
+               self.show_always = show_always
                self.onPlayStateChanged.append(self.__playStateChanged)
                self.pvrStateDialog = self.session.instantiateDialog(screen)
                self.onShow.append(self.__mayShow)
                self.onHide.append(self.pvrStateDialog.hide)
        
        def __mayShow(self):
-               if self.seekstate != self.SEEK_STATE_PLAY and self.execing:
+               if self.execing and (self.show_always or self.seekstate != self.SEEK_STATE_PLAY):
                        self.pvrStateDialog.show()
 
        def __playStateChanged(self, state):
@@ -871,7 +878,7 @@ class InfoBarPVRState:
 
 class InfoBarTimeshiftState(InfoBarPVRState):
        def __init__(self):
-               InfoBarPVRState.__init__(self, screen=TimeshiftState)
+               InfoBarPVRState.__init__(self, screen=TimeshiftState, show_always=True)
 
 class InfoBarShowMovies:
 
@@ -954,7 +961,6 @@ class InfoBarTimeshift:
                        print "hu, timeshift already enabled?"
                else:
                        if not ts.startTimeshift():
-                               import time
                                self.timeshift_enabled = 1
 
                                # we remove the "relative time" for now.
@@ -1241,8 +1247,8 @@ class InfoBarInstantRecord:
                except:
                        pass
 
-               begin = time.time()
-               end = time.time() + 3600 * 10
+               begin = time()
+               end = time() + 3600 * 10
                name = "instant record"
                description = ""
                eventid = None
@@ -1316,12 +1322,12 @@ class InfoBarInstantRecord:
        def inputCallback(self, value):
                if value is not None:
                        print "stopping recording after", int(value), "minutes."
-                       self.recording[self.selectedEntry].end = time.time() + 60 * int(value)
+                       self.recording[self.selectedEntry].end = time() + 60 * int(value)
                        self.session.nav.RecordTimer.timeChanged(self.recording[self.selectedEntry])
 
        def instantRecord(self):
                try:
-                       stat = os.stat(resolveFilename(SCOPE_HDD))
+                       stat = os_stat(resolveFilename(SCOPE_HDD))
                except:
                        self.session.open(MessageBox, _("No HDD found or HDD not initialized!"), MessageBox.TYPE_ERROR)
                        return
@@ -1537,8 +1543,8 @@ class InfoBarAdditionalInfo:
                self["ExtensionsAvailable"] = Boolean(fixed=1)
 
                self.session.nav.event.append(self.gotServiceEvent) # we like to get service events
-               res_mgr = eDVBResourceManagerPtr()
-               if eDVBResourceManager.getInstance(res_mgr) == 0:
+               res_mgr = eDVBResourceManager.getInstance()
+               if res_mgr:
                        res_mgr.frontendUseMaskChanged.get().append(self.tunerUseMaskChanged)
 
        def tunerUseMaskChanged(self, mask):
@@ -1585,12 +1591,21 @@ class InfoBarNotifications:
        def checkNotifications(self):
                if len(Notifications.notifications):
                        n = Notifications.notifications[0]
+                       
                        Notifications.notifications = Notifications.notifications[1:]
                        cb = n[0]
                        if cb is not None:
-                               self.session.openWithCallback(cb, n[1], *n[2], **n[3])
+                               dlg = self.session.openWithCallback(cb, n[1], *n[2], **n[3])
                        else:
-                               self.session.open(n[1], *n[2], **n[3])
+                               dlg = self.session.open(n[1], *n[2], **n[3])
+                       
+                       # remember that this notification is currently active
+                       d = (n[4], dlg)
+                       Notifications.current_notifications.append(d)
+                       dlg.onClose.append(boundFunction(self.__notificationClosed, d))
+
+       def __notificationClosed(self, d):
+               Notifications.current_notifications.remove(d)
 
 class InfoBarServiceNotifications:
        def __init__(self):
@@ -1721,7 +1736,7 @@ class InfoBarCueSheetSupport:
                        return None
 
        def addMark(self, point):
-               bisect.insort(self.cut_list, point)
+               insort(self.cut_list, point)
                self.uploadCuesheet()
 
        def removeMark(self, point):
@@ -1842,3 +1857,48 @@ class InfoBarSubtitleSupport(object):
 
        subtitles_enabled = property(lambda self: self.__subtitles_enabled, setSubtitlesEnable)
        selected_subtitle = property(lambda self: self.__selected_subtitle, setSelectedSubtitle)
+
+class InfoBarServiceErrorPopupSupport:
+       def __init__(self):
+               self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
+                       {
+                               iPlayableService.evTuneFailed: self.__tuneFailed,
+                               iPlayableService.evStart: self.__serviceStarted
+                       })
+               self.__serviceStarted()
+
+       def __serviceStarted(self):
+               self.last_error = None
+               Notifications.RemovePopup(id = "ZapError")
+
+       def __tuneFailed(self):
+               service = self.session.nav.getCurrentService()
+               info = service and service.info()
+               error = info and info.getInfo(iServiceInformation.sDVBState)
+               
+               if error == self.last_error:
+                       error = None
+               else:
+                       self.last_error = error
+
+               errors = {
+                       eDVBServicePMTHandler.eventNoResources: _("No free tuner!"),
+                       eDVBServicePMTHandler.eventTuneFailed: _("Tune failed!"),
+                       eDVBServicePMTHandler.eventNoPAT: _("No data on transponder!\n(Timeout reading PAT)"),
+                       eDVBServicePMTHandler.eventNoPATEntry: _("Service not found!\n(SID not found in PAT)"),
+                       eDVBServicePMTHandler.eventNoPMT: _("Service invalid!\n(Timeout reading PMT)"),
+                       eDVBServicePMTHandler.eventNewProgramInfo: None,
+                       eDVBServicePMTHandler.eventTuned: None,
+                       eDVBServicePMTHandler.eventSOF: None,
+                       eDVBServicePMTHandler.eventEOF: None
+               }
+
+               if error not in errors:
+                       error = None
+
+               error = error is not None and errors[error]
+
+               if error is not None:
+                       Notifications.AddPopup(text = error, type = MessageBox.TYPE_ERROR, timeout = 5, id = "ZapError")
+               else:
+                       Notifications.RemovePopup(id = "ZapError")