X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/4c0f1d02c675df77c46d9fe3d1f8d8c810806401..f412f2579647e5b4b9857acaa4a1b29ff191533e:/lib/python/Screens/InfoBarGenerics.py diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py index 85994203..da0e6d6f 100644 --- a/lib/python/Screens/InfoBarGenerics.py +++ b/lib/python/Screens/InfoBarGenerics.py @@ -16,8 +16,7 @@ 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, ConfigBoolean - +from Components.config import config, ConfigBoolean, ConfigClock from EpgSelection import EPGSelection from Plugins.Plugin import PluginDescriptor @@ -33,6 +32,7 @@ from Screens.PictureInPicture import PictureInPicture from Screens.SubtitleDisplay import SubtitleDisplay from Screens.RdsDisplay import RdsInfoDisplay, RassInteractive from Screens.SleepTimerEdit import SleepTimerEdit +from Screens.TimeDateInput import TimeDateInput from ServiceReference import ServiceReference from Tools import Notifications @@ -41,7 +41,7 @@ from Tools.Directories import SCOPE_HDD, resolveFilename from enigma import eTimer, eServiceCenter, eDVBServicePMTHandler, iServiceInformation, \ iPlayableService, eServiceReference, eDVBResourceManager, iFrontendInformation, eEPGCache -from time import time +from time import time, localtime, strftime from os import stat as os_stat from bisect import insort @@ -83,24 +83,31 @@ class InfoBarShowHide: self.onShow.append(self.__onShow) self.onHide.append(self.__onHide) + self.current_begin_time=0 def __eventInfoChanged(self): - old_begin_time = self.current_begin_time - service = self.session.nav.getCurrentService() - info = service and service.info() - ptr = info and info.getEvent(0) - self.current_begin_time = ptr and ptr.getBeginTime() or 0 - if config.usage.show_infobar_on_event_change.value: - if old_begin_time and old_begin_time != self.current_begin_time: + if self.execing: + service = self.session.nav.getCurrentService() + old_begin_time = self.current_begin_time + info = service and service.info() + ptr = info and info.getEvent(0) + self.current_begin_time = ptr and ptr.getBeginTime() or 0 + if config.usage.show_infobar_on_event_change.value: + if old_begin_time and old_begin_time != self.current_begin_time: + self.doShow() + + def __serviceStarted(self, force=False): + new = self.servicelist.newServicePlayed() + if self.execing or force: + self.current_begin_time=0 + if config.usage.show_infobar_on_zap.value: self.doShow() + elif not self.__checkServiceStarted in self.onExecBegin and new: + self.onExecBegin.append(self.__checkServiceStarted) - def __serviceStarted(self): - self.current_begin_time=0 - if config.usage.show_infobar_on_zap.value: - service = self.session.nav.getCurrentlyPlayingServiceReference() - service_type = service and service.type: - if service_type and service_type == eServiceReference.idDVB and not len(service.getPath()): - self.doShow() + def __checkServiceStarted(self): + self.__serviceStarted(True) + self.onExecBegin.remove(self.__checkServiceStarted) def __onShow(self): self.__state = self.STATE_SHOWN @@ -568,9 +575,9 @@ class InfoBarRdsDecoder: iPlayableService.evUpdatedRassSlidePic: self.RassSlidePicChanged }) - self["RdsActions"] = HelpableActionMap(self, "InfobarRdsActions", + self["RdsActions"] = ActionMap(["InfobarRdsActions"], { - "startRassInteractive": (self.startRassInteractive, _("View Rass interactive...")) + "startRassInteractive": self.startRassInteractive },-1) self["RdsActions"].setEnabled(False) @@ -629,7 +636,9 @@ class InfoBarSeek: SEEK_STATE_SM_HALF = (0, 0, 2, "/2") SEEK_STATE_SM_QUARTER = (0, 0, 4, "/4") SEEK_STATE_SM_EIGHTH = (0, 0, 8, "/8") - + + SEEK_STATE_EOF = (1, 0, 0, "END") + def __init__(self): self.__event_tracker = ServiceEventTracker(screen=self, eventmap= { @@ -646,9 +655,11 @@ class InfoBarSeek: self.screen = screen def action(self, contexts, action): + print "action:", action if action[:5] == "seek:": time = int(action[5:]) self.screen.seekRelative(time * 90000) + self.screen.doShow() return 1 else: return HelpableActionMap.action(self, contexts, action) @@ -684,7 +695,7 @@ class InfoBarSeek: self.onPlayStateChanged = [ ] self.lockedBecauseOfSkipping = False - + def up(self): pass @@ -724,6 +735,7 @@ class InfoBarSeek: def __serviceStarted(self): self.seekstate = self.SEEK_STATE_PLAY + self.__seekableStatusChanged() def setSeekState(self, state): service = self.session.nav.getCurrentService() @@ -734,23 +746,23 @@ class InfoBarSeek: if not self.isSeekable(): if state not in [self.SEEK_STATE_PLAY, self.SEEK_STATE_PAUSE]: state = self.SEEK_STATE_PLAY - + pauseable = service.pause() if pauseable is None: print "not pauseable." state = self.SEEK_STATE_PLAY - + oldstate = self.seekstate self.seekstate = state - + for i in range(3): if oldstate[i] != self.seekstate[i]: (self.session.nav.pause, pauseable.setFastForward, pauseable.setSlowMotion)[i](self.seekstate[i]) for c in self.onPlayStateChanged: c(self.seekstate) - + self.checkSkipShowHideLock() return True @@ -824,7 +836,8 @@ class InfoBarSeek: self.SEEK_STATE_BACK_128X: self.SEEK_STATE_BACK_64X, self.SEEK_STATE_SM_HALF: self.SEEK_STATE_SM_HALF, self.SEEK_STATE_SM_QUARTER: self.SEEK_STATE_SM_HALF, - self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_SM_QUARTER + self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_SM_QUARTER, + self.SEEK_STATE_EOF: self.SEEK_STATE_EOF, } self.setSeekState(lookup[self.seekstate]) @@ -851,7 +864,8 @@ class InfoBarSeek: self.SEEK_STATE_BACK_128X: self.SEEK_STATE_BACK_128X, self.SEEK_STATE_SM_HALF: self.SEEK_STATE_SM_QUARTER, self.SEEK_STATE_SM_QUARTER: self.SEEK_STATE_SM_EIGHTH, - self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_PAUSE + self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_PAUSE, + self.SEEK_STATE_EOF: self.SEEK_STATE_BACK_16X, } self.setSeekState(lookup[self.seekstate]) @@ -896,13 +910,18 @@ class InfoBarSeek: self.lockedBecauseOfSkipping = True def __evEOF(self): - if self.seekstate != self.SEEK_STATE_PLAY: - self.setSeekState(self.SEEK_STATE_PAUSE) - # HACK - #self.getSeek().seekRelative(1, -90000) - self.setSeekState(self.SEEK_STATE_PLAY) + if self.seekstate == self.SEEK_STATE_EOF: + return + if self.seekstate[1] < 0: # SEEK_STATE_BACK_*X + print "end of stream while seeking back, ignoring." + return + + # if we are seeking, we try to end up ~1s before the end, and pause there. + if not self.seekstate in [self.SEEK_STATE_PLAY, self.SEEK_STATE_PAUSE]: + self.setSeekState(self.SEEK_STATE_EOF) + self.seekRelativeToEnd(-90000) else: - self.setSeekState(self.SEEK_STATE_PAUSE) + self.setSeekState(self.SEEK_STATE_EOF) def __evSOF(self): self.setSeekState(self.SEEK_STATE_PLAY) @@ -911,7 +930,21 @@ class InfoBarSeek: def seekRelative(self, diff): seekable = self.getSeek() if seekable is not None: - seekable.seekRelative(1, diff) + print "seekRelative: res:", seekable.seekRelative(1, diff) + else: + print "seek failed!" + + def seekRelativeToEnd(self, diff): + assert diff <= 0, "diff is expected to be negative!" + + # might sound like an evil hack, but: + # if we seekRelativeToEnd(0), we expect to be at the end, which is what we want, + # and we don't get that by passing 0 here (it would seek to begin). + if diff == 0: + diff = -1 + + # relative-to-end seeking is implemented as absolutes seeks with negative time + self.seekAbsolute(diff) def seekAbsolute(self, abs): seekable = self.getSeek() @@ -964,7 +997,7 @@ class InfoBarShowMovies: # Timeshift works the following way: # demux0 demux1 "TimeshiftActions" "TimeshiftActivateActions" "SeekActions" # - normal playback TUNER unused PLAY enable disable disable -# - user presses "yellow" button. TUNER record PAUSE enable disable enable +# - user presses "yellow" button. FILE record PAUSE enable disable enable # - user presess pause again FILE record PLAY enable disable enable # - user fast forwards FILE record FF enable disable enable # - end of timeshift buffer reached TUNER record PLAY enable enable disable @@ -994,21 +1027,21 @@ class InfoBarTimeshift: }, prio=1) self["TimeshiftActivateActions"] = ActionMap(["InfobarTimeshiftActivateActions"], { - "timeshiftActivateEnd": self.activateTimeshiftEnd, # something like "pause key" - "timeshiftActivateEndAndPause": self.activateTimeshiftEndAndPause # something like "backward key" + "timeshiftActivateEnd": self.activateTimeshiftEnd, # something like "rewind key" + "timeshiftActivateEndAndPause": self.activateTimeshiftEndAndPause # something like "pause key" }, prio=-1) # priority over record self.timeshift_enabled = 0 self.timeshift_state = 0 - self.ts_pause_timer = eTimer() - self.ts_pause_timer.timeout.get().append(self.pauseService) + self.ts_rewind_timer = eTimer() + self.ts_rewind_timer.timeout.get().append(self.rewindService) self.__event_tracker = ServiceEventTracker(screen=self, eventmap= { iPlayableService.evStart: self.__serviceStarted, iPlayableService.evSeekableStatusChanged: self.__seekableStatusChanged }) - + def getTimeshift(self): service = self.session.nav.getCurrentService() return service and service.timeshift() @@ -1019,8 +1052,8 @@ class InfoBarTimeshift: if ts is None: self.session.open(MessageBox, _("Timeshift not possible!"), MessageBox.TYPE_ERROR) print "no ts interface" - return 0; - + return 0 + if self.timeshift_enabled: print "hu, timeshift already enabled?" else: @@ -1029,10 +1062,11 @@ class InfoBarTimeshift: # we remove the "relative time" for now. #self.pvrStateDialog["timeshift"].setRelative(time.time()) - + # PAUSE. - self.setSeekState(self.SEEK_STATE_PAUSE) - + #self.setSeekState(self.SEEK_STATE_PAUSE) + self.activateTimeshiftEnd(False) + # enable the "TimeshiftEnableActions", which will override # the startTimeshift actions self.__seekableStatusChanged() @@ -1061,38 +1095,35 @@ class InfoBarTimeshift: # disable actions self.__seekableStatusChanged() - + # activates timeshift, and seeks to (almost) the end - def activateTimeshiftEnd(self): + def activateTimeshiftEnd(self, back = True): ts = self.getTimeshift() - + print "activateTimeshiftEnd" + if ts is None: return - + if ts.isTimeshiftActive(): print "!! activate timeshift called - but shouldn't this be a normal pause?" self.pauseService() else: - self.setSeekState(self.SEEK_STATE_PLAY) - ts.activateTimeshift() - self.seekRelative(0) - + print "play, ..." + ts.activateTimeshift() # activate timeshift will automatically pause + self.setSeekState(self.SEEK_STATE_PAUSE) + self.seekRelativeToEnd(-90000) # seek approx. 1 sec before end + + if back: + self.ts_rewind_timer.start(200, 1) + + def rewindService(self): + self.setSeekState(self.SEEK_STATE_BACK_16X) + # same as activateTimeshiftEnd, but pauses afterwards. def activateTimeshiftEndAndPause(self): - state = self.seekstate - self.activateTimeshiftEnd() - - # well, this is "andPause", but it could be pressed from pause, - # when pausing on the (fake-)"live" picture, so an un-pause - # is perfectly ok. - - print "now, pauseService" - if state == self.SEEK_STATE_PLAY: - print "is PLAYING, start pause timer" - self.ts_pause_timer.start(200, 1) - else: - print "unpause" - self.unPauseService() + print "activateTimeshiftEndAndPause" + #state = self.seekstate + self.activateTimeshiftEnd(False) def __seekableStatusChanged(self): enabled = False @@ -1362,22 +1393,39 @@ class InfoBarInstantRecord: self.changeDuration(0) else: self.session.openWithCallback(self.changeDuration, TimerSelection, list) + elif answer[1] == "changeendtime": + if len(self.recording) == 1: + self.setEndtime(0) + else: + self.session.openWithCallback(self.setEndTime, TimerSelection, list) elif answer[1] == "stop": if len(self.recording) == 1: self.stopCurrentRecording(0) else: self.session.openWithCallback(self.stopCurrentRecording, TimerSelection, list) - if answer[1] == "indefinitely" or answer[1] == "manualduration" or answer[1] == "event": - limitEvent = False - if answer[1] == "event": - limitEvent = True + elif answer[1] in ( "indefinitely" , "manualduration", "manualendtime", "event"): + self.startInstantRecording(limitEvent = answer[1] in ("event", "manualendtime") or False) if answer[1] == "manualduration": - 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) - + self.changeDuration(len(self.recording)-1) + elif answer[1] == "manualendtime": + self.setEndtime(len(self.recording)-1) print "after:\n", self.recording + def setEndtime(self, entry): + if entry is not None: + self.selectedEntry = entry + self.endtime=ConfigClock(default = self.recording[self.selectedEntry].end) + dlg = self.session.openWithCallback(self.TimeDateInputClosed, TimeDateInput, self.endtime) + dlg.setTitle(_("Please change recording endtime")) + + def TimeDateInputClosed(self, ret): + if len(ret) > 1: + if ret[0]: + localendtime = localtime(ret[1]) + print "stopping recording at", strftime("%c", localendtime) + self.recording[self.selectedEntry].end = ret[1] + self.session.nav.RecordTimer.timeChanged(self.recording[self.selectedEntry]) + def changeDuration(self, entry): if entry is not None: self.selectedEntry = entry @@ -1401,9 +1449,11 @@ class InfoBarInstantRecord: title=_("A recording is currently running.\nWhat do you want to do?"), \ list=[(_("stop recording"), "stop"), \ (_("change recording (duration)"), "changeduration"), \ + (_("change recording (endtime)"), "changeendtime"), \ (_("add recording (indefinitely)"), "indefinitely"), \ (_("add recording (stop after current event)"), "event"), \ (_("add recording (enter recording duration)"), "manualduration"), \ + (_("add recording (enter recording endtime)"), "manualendtime"), \ (_("do nothing"), "no")]) else: self.session.openWithCallback(self.recordQuestionCallback, ChoiceBox, \ @@ -1411,6 +1461,7 @@ class InfoBarInstantRecord: list=[(_("add recording (indefinitely)"), "indefinitely"), \ (_("add recording (stop after current event)"), "event"), \ (_("add recording (enter recording duration)"), "manualduration"), \ + (_("add recording (enter recording endtime)"), "manualendtime"), \ (_("don't record"), "no")]) from Tools.ISO639 import LanguageCodes @@ -1895,6 +1946,7 @@ class InfoBarSubtitleSupport(object): iPlayableService.evUpdatedInfo: self.__updatedInfo }) self.cached_subtitle_checked = False + self.__selected_subtitle = None def __serviceStopped(self): self.subtitle_window.hide() @@ -1905,8 +1957,7 @@ class InfoBarSubtitleSupport(object): if not self.cached_subtitle_checked: subtitle = self.getCurrentServiceSubtitle() self.cached_subtitle_checked = True - if subtitle: - self.__selected_subtitle = subtitle.getCachedSubtitle() + self.__selected_subtitle = subtitle and subtitle.getCachedSubtitle() if self.__selected_subtitle: subtitle.enableSubtitles(self.subtitle_window.instance, self.selected_subtitle) self.subtitle_window.show()