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 Screens.UnhandledKey import UnhandledKey
from ServiceReference import ServiceReference
from Tools import Notifications
from Tools.Directories import fileExists
from enigma import eTimer, eServiceCenter, eDVBServicePMTHandler, iServiceInformation, \
- iPlayableService, eServiceReference, eEPGCache
+ iPlayableService, eServiceReference, eEPGCache, eActionMap
from time import time, localtime, strftime
from os import stat as os_stat
def __init__(self):
self.dishDialog = self.session.instantiateDialog(Dish)
+class InfoBarUnhandledKey:
+ def __init__(self):
+ self.unhandledKeyDialog = self.session.instantiateDialog(UnhandledKey)
+ self.hideUnhandledKeySymbolTimer = eTimer()
+ self.hideUnhandledKeySymbolTimer.callback.append(self.unhandledKeyDialog.hide)
+ self.checkUnusedTimer = eTimer()
+ self.checkUnusedTimer.callback.append(self.checkUnused)
+ self.onLayoutFinish.append(self.unhandledKeyDialog.hide)
+ eActionMap.getInstance().bindAction('', -0x7FFFFFFF, self.actionA) #highest prio
+ eActionMap.getInstance().bindAction('', 0x7FFFFFFF, self.actionB) #lowest prio
+ self.flags = (1<<1);
+ self.uflags = 0;
+
+ #this function is called on every keypress!
+ def actionA(self, key, flag):
+ if flag != 4:
+ if self.flags & (1<<1):
+ self.flags = self.uflags = 0
+ self.flags |= (1<<flag)
+ if flag == 1: # break
+ self.checkUnusedTimer.start(0, True)
+ return 0
+
+ #this function is only called when no other action has handled this key
+ def actionB(self, key, flag):
+ if flag != 4:
+ self.uflags |= (1<<flag)
+
+ def checkUnused(self):
+ if self.flags == self.uflags:
+ self.unhandledKeyDialog.show()
+ self.hideUnhandledKeySymbolTimer.start(2000, True)
+
class InfoBarShowHide:
""" InfoBar show/hide control, accepts toggleShow and hide actions, might start
fancy animations. """
self["EPGActions"] = HelpableActionMap(self, "InfobarEPGActions",
{
"showEventInfo": (self.openEventView, _("show EPG...")),
- "showEventInfoPlugin": (self.showEventInfoPlugins, _("show single service EPG...")),
+ "showEventInfoPlugin": (self.showEventInfoPlugins, _("list of EPG views...")),
"showInfobarOrEpgWhenInfobarAlreadyVisible": self.showEventInfoWhenNotVisible,
})
iPlayableService.evEOF: self.__evEOF,
iPlayableService.evSOF: self.__evSOF,
})
-
- self.minSpeedBackward = useSeekBackHack and 16 or 0
+ self.fast_winding_hint_message_showed = False
class InfoBarSeekActionMap(HelpableActionMap):
def __init__(self, screen, *args, **kwargs):
self.__seekableStatusChanged()
def makeStateForward(self, n):
- minspeed = config.seek.stepwise_minspeed.value
- repeat = int(config.seek.stepwise_repeat.value)
- if minspeed != "Never" and n >= int(minspeed) and repeat > 1:
- return (0, n * repeat, repeat, ">> %dx" % n)
- else:
+# minspeed = config.seek.stepwise_minspeed.value
+# repeat = int(config.seek.stepwise_repeat.value)
+# if minspeed != "Never" and n >= int(minspeed) and repeat > 1:
+# return (0, n * repeat, repeat, ">> %dx" % n)
+# else:
return (0, n, 0, ">> %dx" % n)
def makeStateBackward(self, n):
- minspeed = config.seek.stepwise_minspeed.value
- repeat = int(config.seek.stepwise_repeat.value)
- if self.minSpeedBackward and n < self.minSpeedBackward:
- r = (self.minSpeedBackward - 1)/ n + 1
- if minspeed != "Never" and n >= int(minspeed) and repeat > 1:
- r = max(r, repeat)
- return (0, -n * r, r, "<< %dx" % n)
- elif minspeed != "Never" and n >= int(minspeed) and repeat > 1:
- return (0, -n * repeat, repeat, "<< %dx" % n)
- else:
+# minspeed = config.seek.stepwise_minspeed.value
+# repeat = int(config.seek.stepwise_repeat.value)
+# if minspeed != "Never" and n >= int(minspeed) and repeat > 1:
+# return (0, -n * repeat, repeat, "<< %dx" % n)
+# else:
return (0, -n, 0, "<< %dx" % n)
def makeStateSlowMotion(self, n):
# print "seekable"
def __serviceStarted(self):
+ self.fast_winding_hint_message_showed = False
self.seekstate = self.SEEK_STATE_PLAY
self.__seekableStatusChanged()
if config.seek.on_pause.value == "play":
self.unPauseService()
elif config.seek.on_pause.value == "step":
- self.doSeekRelative(0)
+ self.doSeekRelative(1)
elif config.seek.on_pause.value == "last":
self.setSeekState(self.lastseekstate)
self.lastseekstate = self.SEEK_STATE_PLAY
self.showAfterSeek()
def seekFwd(self):
+ seek = self.getSeek()
+ if seek and not (seek.isCurrentlySeekable() & 2):
+ if not self.fast_winding_hint_message_showed and (seek.isCurrentlySeekable() & 1):
+ self.session.open(MessageBox, _("No fast winding possible yet.. but you can use the number buttons to skip forward/backward!"), MessageBox.TYPE_INFO, timeout=10)
+ self.fast_winding_hint_message_showed = True
+ return
+ return 0 # trade as unhandled action
if self.seekstate == self.SEEK_STATE_PLAY:
self.setSeekState(self.makeStateForward(int(config.seek.enter_forward.value)))
elif self.seekstate == self.SEEK_STATE_PAUSE:
self.setSeekState(self.makeStateSlowMotion(speed))
def seekBack(self):
+ seek = self.getSeek()
+ if seek and not (seek.isCurrentlySeekable() & 2):
+ if not self.fast_winding_hint_message_showed and (seek.isCurrentlySeekable() & 1):
+ self.session.open(MessageBox, _("No fast winding possible yet.. but you can use the number buttons to skip forward/backward!"), MessageBox.TYPE_INFO, timeout=10)
+ self.fast_winding_hint_message_showed = True
+ return
+ return 0 # trade as unhandled action
seekstate = self.seekstate
if seekstate == self.SEEK_STATE_PLAY:
self.setSeekState(self.makeStateBackward(int(config.seek.enter_backward.value)))
self.setSeekState(self.makeStateBackward(int(config.seek.enter_backward.value)))
self.doSeekRelative(-6)
elif seekstate == self.SEEK_STATE_PAUSE:
- self.doSeekRelative(-3)
+ self.doSeekRelative(-1)
elif self.isStateForward(seekstate):
speed = seekstate[1]
if seekstate[2]:
self.pvrStateDialog.hide()
else:
self._mayShow()
-
class InfoBarTimeshiftState(InfoBarPVRState):
def __init__(self):
InfoBarPVRState.__init__(self, screen=TimeshiftState, force_show = True)
+ self.__hideTimer = eTimer()
+ self.__hideTimer.callback.append(self.__hideTimeshiftState)
def _mayShow(self):
- if self.execing and self.timeshift_enabled and self.seekstate != self.SEEK_STATE_PLAY:
+ if self.execing and self.timeshift_enabled:
self.pvrStateDialog.show()
+ if self.seekstate == self.SEEK_STATE_PLAY and not self.shown:
+ self.__hideTimer.start(5*1000, True)
+
+ def __hideTimeshiftState(self):
+ self.pvrStateDialog.hide()
class InfoBarShowMovies:
self.setSeekState(self.SEEK_STATE_PAUSE)
if back:
- self.doSeek(-5) # seek some gops before end
self.ts_rewind_timer.start(200, 1)
- else:
- self.doSeek(-1) # seek 1 gop before end
def rewindService(self):
self.setSeekState(self.makeStateBackward(int(config.seek.enter_backward.value)))
def JobViewCB(self, in_background):
job_manager.in_background = in_background
-# depends on InfoBarExtensions
-class InfoBarSleepTimer:
- def __init__(self):
- self.addExtension((self.getSleepTimerName, self.showSleepTimerSetup, lambda: True), "1")
-
- def getSleepTimerName(self):
- return _("Sleep Timer")
-
- def showSleepTimerSetup(self):
- self.session.open(SleepTimerEdit)
-
# depends on InfoBarExtensions
class InfoBarPiP:
def __init__(self):
else:
break
+ availableKeys = []
+ usedKeys = []
+
if SystemInfo["CanDownmixAC3"]:
- tlist = [(_("AC3 downmix") + " - " +(_("Off"), _("On"))[config.av.downmix_ac3.value and 1 or 0], "CALLFUNC", self.changeAC3Downmix),
- ((_("Left"), _("Stereo"), _("Right"))[self.audioChannel.getCurrentChannel()], "mode"),
- ("--", "")] + tlist
- keys = [ "red", "green", "", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] + [""]*n
- selection += 3
- else:
- tlist = [((_("Left"), _("Stereo"), _("Right"))[self.audioChannel.getCurrentChannel()], "mode"), ("--", "")] + tlist
- keys = [ "red", "", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] + [""]*n
+ flist = [(_("AC3 downmix") + " - " +(_("Off"), _("On"))[config.av.downmix_ac3.value and 1 or 0], "CALLFUNC", self.changeAC3Downmix),
+ ((_("Left"), _("Stereo"), _("Right"))[self.audioChannel.getCurrentChannel()], "mode")]
+ usedKeys.extend(["red", "green"])
+ availableKeys.extend(["yellow", "blue"])
selection += 2
- self.session.openWithCallback(self.audioSelected, ChoiceBox, title=_("Select audio track"), list = tlist, selection = selection, keys = keys, skin_name = "AudioTrackSelection")
+ else:
+ flist = [((_("Left"), _("Stereo"), _("Right"))[self.audioChannel.getCurrentChannel()], "mode")]
+ usedKeys.extend(["red"])
+ availableKeys.extend(["green", "yellow", "blue"])
+ selection += 1
+
+ if hasattr(self, "runPlugin"):
+ class PluginCaller:
+ def __init__(self, fnc, *args):
+ self.fnc = fnc
+ self.args = args
+ def __call__(self, *args, **kwargs):
+ self.fnc(*self.args)
+
+ Plugins = [ (p.name, PluginCaller(self.runPlugin, p)) for p in plugins.getPlugins(where = PluginDescriptor.WHERE_AUDIOMENU) ]
+
+ for p in Plugins:
+ selection += 1
+ flist.append((p[0], "CALLFUNC", p[1]))
+ if availableKeys:
+ usedKeys.append(availableKeys[0])
+ del availableKeys[0]
+ else:
+ usedKeys.append("")
+
+ flist.append(("--", ""))
+ usedKeys.append("")
+ selection += 1
+
+ keys = usedKeys + [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" ] + [""] * n
+ self.session.openWithCallback(self.audioSelected, ChoiceBox, title=_("Select audio track"), list = flist + tlist, selection = selection, keys = keys, skin_name = "AudioTrackSelection")
else:
del self.audioTracks
if last is not None:
self.resume_point = last
+
+ l = last / 90000
if config.usage.on_movie_start.value == "ask":
- Notifications.AddNotificationWithCallback(self.playLastCB, MessageBox, _("Do you want to resume this playback?"), timeout=10)
+ Notifications.AddNotificationWithCallback(self.playLastCB, MessageBox, _("Do you want to resume this playback?") + "\n" + (_("Resume position at %s") % ("%d:%02d:%02d" % (l/3600, l%3600/60, l%60))), timeout=10)
elif config.usage.on_movie_start.value == "resume":
# TRANSLATORS: The string "Resuming playback" flashes for a moment
# TRANSLATORS: at the start of a movie, when the user has selected