X-Git-Url: http://code.vuplus.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=lib%2Fpython%2FScreens%2FInfoBarGenerics.py;h=4f6eafca0c752f17ca8d68f8dff53512dd96a42b;hb=439941c4d23e8384ea334d599b42b338beb7ebd5;hp=4bcadef9cdf423996932d719c64545bc31dcd575;hpb=a648830a100839cb95548cffe2a6cd291f8da19c;p=vuplus_dvbapp diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py old mode 100644 new mode 100755 index 4bcadef..d1c6c84 --- a/lib/python/Screens/InfoBarGenerics.py +++ b/lib/python/Screens/InfoBarGenerics.py @@ -1,4 +1,4 @@ -from ChannelSelection import ChannelSelection, BouquetSelector +from ChannelSelection import ChannelSelection, BouquetSelector, SilentBouquetSelector from Components.ActionMap import ActionMap, HelpableActionMap from Components.ActionMap import NumberActionMap @@ -36,10 +36,10 @@ from enigma import eTimer, eServiceCenter, eDVBServicePMTHandler, iServiceInform iPlayableService, eServiceReference, eEPGCache, eActionMap from time import time, localtime, strftime -from os import stat as os_stat +from os import stat as os_stat, system as os_system from bisect import insort -from RecordTimer import RecordTimerEntry, RecordTimer +from RecordTimer import RecordTimerEntry, RecordTimer, findSafeRecordPath # hack alert! from Menu import MainMenu, mdom @@ -47,10 +47,12 @@ from Menu import MainMenu, mdom class InfoBarDish: def __init__(self): self.dishDialog = self.session.instantiateDialog(Dish) + self.dishDialog.setAnimationMode(0) class InfoBarUnhandledKey: def __init__(self): self.unhandledKeyDialog = self.session.instantiateDialog(UnhandledKey) + self.unhandledKeyDialog.setAnimationMode(0) self.hideUnhandledKeySymbolTimer = eTimer() self.hideUnhandledKeySymbolTimer.callback.append(self.unhandledKeyDialog.hide) self.checkUnusedTimer = eTimer() @@ -233,7 +235,7 @@ class InfoBarNumberZap: else: self.servicelist.recallPrevService() else: - if self.has_key("TimeshiftActions") and not self.timeshift_enabled: + if not (self.has_key("TimeshiftActions") and self.timeshift_enabled): self.session.openWithCallback(self.numberEntered, NumberZap, number) def numberEntered(self, retval): @@ -559,6 +561,12 @@ class InfoBarEPG: cnt = 0 else: cnt = len(bouquets) + if config.usage.multiepg_ask_bouquet.value: + self.openMultiServiceEPGAskBouquet(bouquets, cnt, withCallback) + else: + self.openMultiServiceEPGSilent(bouquets, cnt, withCallback) + + def openMultiServiceEPGAskBouquet(self, bouquets, cnt, withCallback): if cnt > 1: # show bouquet list if withCallback: self.bouquetSel = self.session.openWithCallback(self.closed, BouquetSelector, bouquets, self.openBouquetEPG, enableWrapAround=True) @@ -568,6 +576,21 @@ class InfoBarEPG: elif cnt == 1: self.openBouquetEPG(bouquets[0][1], withCallback) + def openMultiServiceEPGSilent(self, bouquets, cnt, withCallback): + root = self.servicelist.getRoot() + rootstr = root.toCompareString() + current = 0 + for bouquet in bouquets: + if bouquet[1].toCompareString() == rootstr: + break + current += 1 + if current >= cnt: + current = 0 + if cnt > 1: # create bouquet list for bouq+/- + self.bouquetSel = SilentBouquetSelector(bouquets, True, self.servicelist.getBouquetNumOffset(root)) + if cnt >= 1: + self.openBouquetEPG(root, withCallback) + def changeServiceCB(self, direction, epg): if self.serviceSel: if direction > 0: @@ -598,6 +621,7 @@ class InfoBarEPG: if list: list.append((_("show single service EPG..."), self.openSingleServiceEPG)) + list.append((_("Multi EPG"), self.openMultiServiceEPG)) self.session.openWithCallback(self.EventInfoPluginChosen, ChoiceBox, title=_("Please choose an extension..."), list = list, skin_name = "EPGExtensionsList") else: self.openSingleServiceEPG() @@ -665,6 +689,7 @@ class InfoBarRdsDecoder: """provides RDS and Rass support/display""" def __init__(self): self.rds_display = self.session.instantiateDialog(RdsInfoDisplay) + self.rds_display.setAnimationMode(0) self.rass_interactive = None self.__event_tracker = ServiceEventTracker(screen=self, eventmap= @@ -750,7 +775,7 @@ class InfoBarSeek: self["SeekActions"] = InfoBarSeekActionMap(self, actionmap, { - "playpauseService": self.playpauseService, + "playpauseService": (self.playpauseService, _("Pause/Continue")), "pauseService": (self.pauseService, _("pause")), "unPauseService": (self.unPauseService, _("continue")), @@ -1083,6 +1108,7 @@ class InfoBarPVRState: def __init__(self, screen=PVRState, force_show = False): self.onPlayStateChanged.append(self.__playStateChanged) self.pvrStateDialog = self.session.instantiateDialog(screen) + self.pvrStateDialog.setAnimationMode(0) self.onShow.append(self._mayShow) self.onHide.append(self.pvrStateDialog.hide) self.force_show = force_show @@ -1159,11 +1185,12 @@ class InfoBarShowMovies: 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) + if SystemInfo["PVRSupport"]: + 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 "rewind key" @@ -1178,7 +1205,8 @@ class InfoBarTimeshift: self.__event_tracker = ServiceEventTracker(screen=self, eventmap= { iPlayableService.evStart: self.__serviceStarted, - iPlayableService.evSeekableStatusChanged: self.__seekableStatusChanged + iPlayableService.evSeekableStatusChanged: self.__seekableStatusChanged, + iPlayableService.evUser+3: self.__lowDiskspaceMessage }) def getTimeshift(self): @@ -1196,6 +1224,13 @@ class InfoBarTimeshift: if self.timeshift_enabled: print "hu, timeshift already enabled?" else: + from Components import Harddisk + if Harddisk.getMountPath(config.usage.timeshift_path.value) != '/' and \ + SystemInfo.get("DisableUsbRecord", True) and \ + Harddisk.isUsbStorage(config.usage.timeshift_path.value): + self.session.open(MessageBox, _("Timeshift not possible on a USB storage."), MessageBox.TYPE_ERROR) + return 0 + if not ts.startTimeshift(): self.timeshift_enabled = 1 @@ -1282,6 +1317,9 @@ class InfoBarTimeshift: self.timeshift_enabled = False self.__seekableStatusChanged() + def __lowDiskspaceMessage(self): + Notifications.AddPopup(text = _("Write error. Not enough space for writing.\n"), type = MessageBox.TYPE_ERROR, timeout = 0, id = "DiskFullMessage") + from Screens.PiPSetup import PiPSetup class InfoBarExtensions: @@ -1296,6 +1334,9 @@ class InfoBarExtensions: "extensions": (self.showExtensionSelection, _("view extensions...")), }, 1) # lower priority + for p in plugins.getPlugins(PluginDescriptor.WHERE_EXTENSIONSINGLE): + p(self) + def addExtension(self, extension, key = None, type = EXTENSION_SINGLE): self.list.append((type, extension, key)) @@ -1352,6 +1393,7 @@ class InfoBarExtensions: answer[1][1]() from Tools.BoundFunction import boundFunction +import inspect # depends on InfoBarExtensions @@ -1363,9 +1405,13 @@ class InfoBarPlugins: return name def getPluginList(self): - list = [((boundFunction(self.getPluginName, p.name), boundFunction(self.runPlugin, p), lambda: True), None, p.name) for p in plugins.getPlugins(where = PluginDescriptor.WHERE_EXTENSIONSMENU)] - list.sort(key = lambda e: e[2]) # sort by name - return list + l = [] + for p in plugins.getPlugins(where = PluginDescriptor.WHERE_EXTENSIONSMENU): + args = inspect.getargspec(p.__call__)[0] + if len(args) == 1 or len(args) == 2 and isinstance(self, InfoBarChannelSelection): + l.append(((boundFunction(self.getPluginName, p.name), boundFunction(self.runPlugin, p), lambda: True), None, p.name)) + l.sort(key = lambda e: e[2]) # sort by name + return l def runPlugin(self, plugin): if isinstance(self, InfoBarChannelSelection): @@ -1432,6 +1478,7 @@ class InfoBarPiP: self.session.pipshown = False else: self.session.pip = self.session.instantiateDialog(PictureInPicture) + self.session.pip.setAnimationMode(0) self.session.pip.show() newservice = self.session.nav.getCurrentlyPlayingServiceReference() if self.session.pip.playService(newservice): @@ -1474,10 +1521,11 @@ class InfoBarInstantRecord: """Instant Record - handles the instantRecord action in order to start/stop instant records""" def __init__(self): - self["InstantRecordActions"] = HelpableActionMap(self, "InfobarInstantRecord", - { - "instantRecord": (self.instantRecord, _("Instant Record...")), - }) + if SystemInfo["PVRSupport"]: + self["InstantRecordActions"] = HelpableActionMap(self, "InfobarInstantRecord", + { + "instantRecord": (self.instantRecord, _("Instant Record...")), + }) self.recording = [] def stopCurrentRecording(self, entry = -1): @@ -1523,28 +1571,30 @@ class InfoBarInstantRecord: recording = RecordTimerEntry(serviceref, begin, end, name, description, eventid, dirname = preferredInstantRecordPath()) recording.dontSave = True - + if event is None or limitEvent == False: recording.autoincrease = True - if recording.setAutoincreaseEnd(): - self.session.nav.RecordTimer.record(recording) - self.recording.append(recording) + recording.setAutoincreaseEnd() + + simulTimerList = self.session.nav.RecordTimer.record(recording) + + if simulTimerList is None: # no conflict + self.recording.append(recording) else: - simulTimerList = self.session.nav.RecordTimer.record(recording) - if simulTimerList is not None: # conflict with other recording - name = simulTimerList[1].name - name_date = ' '.join((name, strftime('%c', localtime(simulTimerList[1].begin)))) - print "[TIMER] conflicts with", name_date - recording.autoincrease = True # start with max available length, then increment - if recording.setAutoincreaseEnd(): - self.session.nav.RecordTimer.record(recording) - self.recording.append(recording) - self.session.open(MessageBox, _("Record time limited due to conflicting timer %s") % name_date, MessageBox.TYPE_INFO) - else: - self.session.open(MessageBox, _("Couldn't record due to conflicting timer %s") % name, MessageBox.TYPE_INFO) - recording.autoincrease = False - else: + if len(simulTimerList) > 1: # with other recording + name = simulTimerList[1].name + name_date = ' '.join((name, strftime('%c', localtime(simulTimerList[1].begin)))) + print "[TIMER] conflicts with", name_date + recording.autoincrease = True # start with max available length, then increment + if recording.setAutoincreaseEnd(): + self.session.nav.RecordTimer.record(recording) self.recording.append(recording) + self.session.open(MessageBox, _("Record time limited due to conflicting timer %s") % name_date, MessageBox.TYPE_INFO) + else: + self.session.open(MessageBox, _("Couldn't record due to conflicting timer %s") % name, MessageBox.TYPE_INFO) + else: + self.session.open(MessageBox, _("Couldn't record due to invalid service %s") % serviceref, MessageBox.TYPE_INFO) + recording.autoincrease = False def isInstantRecordRunning(self): print "self.recording:", self.recording @@ -1622,13 +1672,14 @@ class InfoBarInstantRecord: self.session.nav.RecordTimer.timeChanged(entry) def instantRecord(self): - dir = preferredInstantRecordPath() - if not dir or not fileExists(dir, 'w'): - dir = defaultMoviePath() - try: - stat = os_stat(dir) - except: - # XXX: this message is a little odd as we might be recording to a remote device + if not fileExists("/hdd", 0): + print "not found /hdd" + os_system("ln -s /media/hdd /hdd") + + recPath = preferredInstantRecordPath() + if not findSafeRecordPath(recPath) and not findSafeRecordPath(defaultMoviePath()): + if not recPath: + recPath = "" self.session.open(MessageBox, _("No HDD found or HDD not initialized!"), MessageBox.TYPE_ERROR) return @@ -1662,126 +1713,11 @@ class InfoBarAudioSelection: }) def audioSelection(self): - service = self.session.nav.getCurrentService() - self.audioTracks = audio = service and service.audioTracks() - n = audio and audio.getNumberOfTracks() or 0 - tlist = [] - if n > 0: - self.audioChannel = service.audioChannel() - - idx = 0 - while idx < n: - cnt = 0 - i = audio.getTrackInfo(idx) - languages = i.getLanguage().split('/') - description = i.getDescription() - language = "" - - for lang in languages: - if cnt: - language += ' / ' - if LanguageCodes.has_key(lang): - language += LanguageCodes[lang][0] - else: - language += lang - cnt += 1 - - if len(description): - description += " (" + language + ")" - else: - description = language - - tlist.append((description, idx)) - idx += 1 - - tlist.sort(key=lambda x: x[0]) - - selectedAudio = self.audioTracks.getCurrentTrack() - - selection = 0 - - for x in tlist: - if x[1] != selectedAudio: - selection += 1 - else: - break - - availableKeys = [] - usedKeys = [] - - if SystemInfo["CanDownmixAC3"]: - 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 - 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 - - def changeAC3Downmix(self, arg): - choicelist = self.session.current_dialog["list"] - list = choicelist.list - t = list[0][1] - list[0][1]=(t[0], t[1], t[2], t[3], t[4], t[5], t[6], - _("AC3 downmix") + " - " + (_("On"), _("Off"))[config.av.downmix_ac3.value and 1 or 0]) - choicelist.setList(list) - if config.av.downmix_ac3.value: - config.av.downmix_ac3.value = False - else: - config.av.downmix_ac3.value = True - config.av.downmix_ac3.save() - - def audioSelected(self, audio): - if audio is not None: - if isinstance(audio[1], str): - if audio[1] == "mode": - keys = ["red", "green", "yellow"] - selection = self.audioChannel.getCurrentChannel() - tlist = ((_("left"), 0), (_("stereo"), 1), (_("right"), 2)) - self.session.openWithCallback(self.modeSelected, ChoiceBox, title=_("Select audio mode"), list = tlist, selection = selection, keys = keys, skin_name ="AudioModeSelection") - else: - del self.audioChannel - if self.session.nav.getCurrentService().audioTracks().getNumberOfTracks() > audio[1]: - self.audioTracks.selectTrack(audio[1]) - else: - del self.audioChannel - del self.audioTracks - - def modeSelected(self, mode): - if mode is not None: - self.audioChannel.selectChannel(mode[1]) - del self.audioChannel + from Screens.AudioSelection import AudioSelection + self.session.openWithCallback(self.audioSelected, AudioSelection, infobar=self) + + def audioSelected(self, ret=None): + print "[infobar::audioSelected]", ret class InfoBarSubserviceSelection: def __init__(self): @@ -1909,13 +1845,74 @@ class InfoBarSubserviceSelection: else: del self.selectedSubservice +from Components.Sources.HbbtvApplication import HbbtvApplication +gHbbtvApplication = HbbtvApplication() +class InfoBarRedButton: + def __init__(self): + if not (config.misc.rcused.value == 1): + self["RedButtonActions"] = HelpableActionMap(self, "InfobarRedButtonActions", + { + "activateRedButton": (self.activateRedButton, _("Red button...")), + }) + self["HbbtvApplication"] = gHbbtvApplication + else: + self["HbbtvApplication"] = Boolean(fixed=0) + self["HbbtvApplication"].name = "" #is this a hack? + + self.onHBBTVActivation = [ ] + self.onRedButtonActivation = [ ] + self.onReadyForAIT = [ ] + self.__et = ServiceEventTracker(screen=self, eventmap= + { + iPlayableService.evHBBTVInfo: self.detectedHbbtvApplication, + iPlayableService.evUpdatedInfo: self.updateInfomation + }) + + def updateAIT(self, orgId=0): + for x in self.onReadyForAIT: + try: + x(orgId) + except Exception, ErrMsg: + print ErrMsg + #self.onReadyForAIT.remove(x) + + def updateInfomation(self): + try: + self["HbbtvApplication"].setApplicationName("") + self.updateAIT() + except Exception, ErrMsg: + pass + + def detectedHbbtvApplication(self): + service = self.session.nav.getCurrentService() + info = service and service.info() + try: + for x in info.getInfoObject(iServiceInformation.sHBBTVUrl): + print x + if x[0] in (-1, 1): + self.updateAIT(x[3]) + self["HbbtvApplication"].setApplicationName(x[1]) + break + except Exception, ErrMsg: + pass + + def activateRedButton(self): + service = self.session.nav.getCurrentService() + info = service and service.info() + if info and info.getInfoString(iServiceInformation.sHBBTVUrl) != "": + for x in self.onHBBTVActivation: + x() + elif False: # TODO: other red button services + for x in self.onRedButtonActivation: + x() + class InfoBarAdditionalInfo: def __init__(self): self["RecordingPossible"] = Boolean(fixed=harddiskmanager.HDDCount() > 0 and config.misc.rcused.value == 1) self["TimeshiftPossible"] = self["RecordingPossible"] - self["ShowTimeshiftOnYellow"] = Boolean(fixed=(not config.misc.rcused.value == 0)) - self["ShowAudioOnYellow"] = Boolean(fixed=config.misc.rcused.value == 0) + self["ShowTimeshiftOnYellow"] = Boolean(fixed=(config.misc.rcused.value == 1)) + self["ShowAudioOnYellow"] = Boolean(fixed=config.misc.rcused.value != 1) self["ShowRecordOnRed"] = Boolean(fixed=config.misc.rcused.value == 1) self["ExtensionsAvailable"] = Boolean(fixed=1) @@ -2247,6 +2244,7 @@ class InfoBarSubtitleSupport(object): def __init__(self): object.__init__(self) self.subtitle_window = self.session.instantiateDialog(SubtitleDisplay) + self.subtitle_window.setAnimationMode(0) self.__subtitles_enabled = False self.__event_tracker = ServiceEventTracker(screen=self, eventmap= @@ -2265,8 +2263,7 @@ class InfoBarSubtitleSupport(object): self.__selected_subtitle = None def __updatedInfo(self): - if not self.cached_subtitle_checked: - self.cached_subtitle_checked = True + if not self.__selected_subtitle: subtitle = self.getCurrentServiceSubtitle() self.setSelectedSubtitle(subtitle and subtitle.getCachedSubtitle()) if self.__selected_subtitle: @@ -2287,7 +2284,7 @@ class InfoBarSubtitleSupport(object): else: if subtitle: subtitle.disableSubtitles(self.subtitle_window.instance) - self.__selected_subtitle = False + self.__selected_subtitle = None self.__subtitles_enabled = False self.subtitle_window.hide() @@ -2337,3 +2334,67 @@ class InfoBarServiceErrorPopupSupport: Notifications.AddPopup(text = error, type = MessageBox.TYPE_ERROR, timeout = 5, id = "ZapError") else: Notifications.RemovePopup(id = "ZapError") + +class InfoBarHDMI: + def __init__(self): + self.hdmiInServiceRef = eServiceReference('8192:0:1:0:0:0:0:0:0:0:') + + if SystemInfo.get("HdmiInSupport", False): + self.addExtension((self.getShowHdmiInName, self.HDMIIn, lambda: True), None) + self.addExtension((self.getShowHdmiInPIPName, self.HDMIInPIP, self.showHDMIPIPMenu), None) + + def getShowHdmiInName(self): + curref = self.session.nav.getCurrentlyPlayingServiceReference() + if curref and curref.type == 8192: + name = _("Disable HDMI-IN on Main Screen") + else: + name = _("Enable HDMI-IN on Main Screen") + + return name + + def getShowHdmiInPIPName(self): + return _("Enable HDMI-IN on PIP") + + def showHDMIPIPMenu(self): + _pipAvailable = SystemInfo.get("NumVideoDecoders", 1) > 1 + + hdmiin_enabled = False + curref = self.session.nav.getCurrentlyPlayingServiceReference() + if curref and curref.type == 8192: + hdmiin_enabled = True + + hdmiin_pip_shown = False + if self.session.pipshown: + pipref=self.session.pip.getCurrentService() + if pipref and pipref.type == 8192: + hdmiin_pip_shown = True + + return _pipAvailable and not hdmiin_enabled and not hdmiin_pip_shown + + def getCurrentServiceRef(self): + slist = self.servicelist + currentServiceSref = slist.servicelist.getCurrent() + return currentServiceSref + + def HDMIIn(self): + curref = self.session.nav.getCurrentlyPlayingServiceReference() + if curref and curref.type == 8192: + self.session.nav.playService(self.getCurrentServiceRef()) + else: + self.session.nav.playService(self.hdmiInServiceRef) + + def HDMIInPIP(self): + if self.session.pipshown: + del self.session.pip + + self.session.pip = self.session.instantiateDialog(PictureInPicture) + self.session.pip.setAnimationMode(0) + self.session.pip.show() + newservice = self.hdmiInServiceRef + if self.session.pip.playService(newservice): + self.session.pipshown = True + self.session.pip.servicePath = self.servicelist.getCurrentServicePath() + else: + self.session.pipshown = False + del self.session.pip + self.session.openWithCallback(self.close, MessageBox, _("Could not open Picture in Picture"), MessageBox.TYPE_ERROR)