+ lookup = {
+ self.SEEK_STATE_PLAY: self.SEEK_STATE_BACK_16X,
+ self.SEEK_STATE_PAUSE: self.SEEK_STATE_PAUSE,
+ self.SEEK_STATE_FF_2X: self.SEEK_STATE_PLAY,
+ self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_2X,
+ self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_4X,
+ self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_8X,
+ self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_32X,
+ self.SEEK_STATE_FF_128X: self.SEEK_STATE_FF_64X,
+ self.SEEK_STATE_BACK_16X: self.SEEK_STATE_BACK_32X,
+ self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_64X,
+ self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_128X,
+ 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.setSeekState(lookup[self.seekstate])
+
+ def fwdTimerFire(self):
+ print "Display seek fwd"
+ self.fwdKeyTimer.stop()
+ self.fwdtimer = False
+ self.session.openWithCallback(self.fwdSeekTo, MinuteInput)
+
+ def fwdSeekTo(self, minutes):
+ print "Seek", minutes, "minutes forward"
+ if minutes != 0:
+ seekable = self.getSeek()
+ if seekable is not None:
+ seekable.seekRelative(1, minutes * 60 * 90000)
+
+ def rwdTimerFire(self):
+ print "rwdTimerFire"
+ self.rwdKeyTimer.stop()
+ self.rwdtimer = False
+ self.session.openWithCallback(self.rwdSeekTo, MinuteInput)
+
+ def rwdSeekTo(self, minutes):
+ print "rwdSeekTo"
+ self.fwdSeekTo(0 - minutes)
+
+ def checkSkipShowHideLock(self):
+ wantlock = self.seekstate != self.SEEK_STATE_PLAY
+
+ if self.lockedBecauseOfSkipping and not wantlock:
+ self.unlockShow()
+ self.lockedBecauseOfSkipping = False
+
+ if wantlock and not self.lockedBecauseOfSkipping:
+ self.lockShow()
+ 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)
+ else:
+ self.setSeekState(self.SEEK_STATE_PAUSE)
+
+ def __evSOF(self):
+ self.setSeekState(self.SEEK_STATE_PLAY)
+ self.doSeek(0)
+
+ def seekRelative(self, diff):
+ seekable = self.getSeek()
+ if seekable is not None:
+ seekable.seekRelative(0, diff)
+
+from Screens.PVRState import PVRState
+
+class InfoBarPVRState:
+ def __init__(self):
+ self.onPlayStateChanged.append(self.__playStateChanged)
+ self.pvrStateDialog = self.session.instantiateDialog(PVRState)
+ self.onShow.append(self.__mayShow)
+ self.onHide.append(self.pvrStateDialog.hide)
+
+ def __mayShow(self):
+ if self.seekstate != self.SEEK_STATE_PLAY:
+ self.pvrStateDialog.show()
+
+ def __playStateChanged(self, state):
+ playstateString = state[3]
+ self.pvrStateDialog["state"].setText(playstateString)
+ self.__mayShow()
+
+class InfoBarShowMovies:
+
+ # i don't really like this class.
+ # it calls a not further specified "movie list" on up/down/movieList,
+ # so this is not more than an action map
+ def __init__(self):
+ self["MovieListActions"] = HelpableActionMap(self, "InfobarMovieListActions",
+ {
+ "movieList": (self.showMovies, "movie list"),
+ "up": (self.showMovies, "movie list"),
+ "down": (self.showMovies, "movie list")
+ })
+
+# InfoBarTimeshift requires InfoBarSeek, instantiated BEFORE!
+
+# Hrmf.
+#
+# 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 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
+# - user backwards FILE record BACK # !! enable disable enable
+#
+
+# in other words:
+# - when a service is playing, pressing the "timeshiftStart" button ("yellow") enables recording ("enables timeshift"),
+# freezes the picture (to indicate timeshift), sets timeshiftMode ("activates timeshift")
+# now, the service becomes seekable, so "SeekActions" are enabled, "TimeshiftEnableActions" are disabled.
+# - the user can now PVR around
+# - if it hits the end, the service goes into live mode ("deactivates timeshift", it's of course still "enabled")
+# the service looses it's "seekable" state. It can still be paused, but just to activate timeshift right
+# after!
+# the seek actions will be disabled, but the timeshiftActivateActions will be enabled
+# - if the user rewinds, or press pause, timeshift will be activated again
+
+# note that a timeshift can be enabled ("recording") and
+# activated (currently time-shifting).
+
+class InfoBarTimeshift:
+ def __init__(self):
+ self["TimeshiftActions"] = HelpableActionMap(self, "InfobarTimeshiftActions",
+ {
+ "timeshiftStart": (self.startTimeshift, "start timeshift"), # the "yellow key"
+ "timeshiftStop": (self.stopTimeshift, "stop timeshift") # currently undefined :), probably 'TV'
+ }, prio=1)
+ self["TimeshiftActivateActions"] = ActionMap(["InfobarTimeshiftActivateActions"],
+ {
+ "timeshiftActivateEnd": self.activateTimeshiftEnd, # something like "pause key"
+ "timeshiftActivateEndAndPause": self.activateTimeshiftEndAndPause # something like "backward 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.__event_tracker = ServiceEventTracker(screen=self, eventmap=
+ {
+ iPlayableService.evSeekableStatusChanged: self.__seekableStatusChanged
+ })
+
+ def getTimeshift(self):
+ service = self.session.nav.getCurrentService()
+ return service.timeshift()
+
+ def startTimeshift(self):
+ print "enable timeshift"
+ ts = self.getTimeshift()
+ if ts is None:
+ self.session.open(MessageBox, _("Timeshift not possible!"), MessageBox.TYPE_ERROR)
+ print "no ts interface"
+ return
+
+ if self.timeshift_enabled:
+ print "hu, timeshift already enabled?"
+ else:
+ if not ts.startTimeshift():
+ self.timeshift_enabled = 1
+
+ # PAUSE.
+ self.setSeekState(self.SEEK_STATE_PAUSE)
+
+ # enable the "TimeshiftEnableActions", which will override
+ # the startTimeshift actions
+ self.__seekableStatusChanged()
+ else:
+ print "timeshift failed"
+
+ def stopTimeshift(self):
+ if not self.timeshift_enabled:
+ return
+ print "disable timeshift"
+ ts = self.getTimeshift()
+ if ts is None:
+ return
+ self.session.openWithCallback(self.stopTimeshiftConfirmed, MessageBox, _("Stop Timeshift?"), MessageBox.TYPE_YESNO)
+
+ def stopTimeshiftConfirmed(self, confirmed):
+ if not confirmed:
+ return
+
+ ts = self.getTimeshift()
+ if ts is None:
+ return
+
+ ts.stopTimeshift()
+ self.timeshift_enabled = 0
+
+ # disable actions
+ self.__seekableStatusChanged()
+
+ # activates timeshift, and seeks to (almost) the end
+ def activateTimeshiftEnd(self):
+ ts = self.getTimeshift()
+
+ 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)
+
+ # 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()
+
+ def __seekableStatusChanged(self):
+ enabled = False
+
+ print "self.isSeekable", self.isSeekable()
+ print "self.timeshift_enabled", self.timeshift_enabled
+
+ # when this service is not seekable, but timeshift
+ # is enabled, this means we can activate
+ # the timeshift
+ if not self.isSeekable() and self.timeshift_enabled:
+ enabled = True
+
+ print "timeshift activate:", enabled
+ self["TimeshiftActivateActions"].setEnabled(enabled)
+
+from RecordTimer import parseEvent