X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/364dcf5cdfa9f39414074a48501f25d714117729..562f08b0d0d53a3b79516dff47a7eea7ba971d17:/lib/python/Screens/InfoBarGenerics.py diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py index 5e28cdee..7a2f985e 100644 --- a/lib/python/Screens/InfoBarGenerics.py +++ b/lib/python/Screens/InfoBarGenerics.py @@ -1,67 +1,45 @@ from Screen import Screen -from Components.ActionMap import ActionMap +from Components.ActionMap import ActionMap, HelpableActionMap from Components.ActionMap import NumberActionMap -from Components.Label import Label -from Components.config import configfile -from ChannelSelection import ChannelSelection - +from Components.Label import * +from Components.ProgressBar import * +from Components.config import configfile, configsequencearg +from Components.config import config, configElement, ConfigSubsection, configSequence +from ChannelSelection import ChannelSelection, BouquetSelector + +from Components.Pixmap import Pixmap, PixmapConditional +from Components.BlinkingPixmap import BlinkingPixmapConditional from Components.ServiceName import ServiceName -from Components.EventInfo import EventInfo +from Components.EventInfo import EventInfo, EventInfoProgress +from ServiceReference import ServiceReference from EpgSelection import EPGSelection from Screens.MessageBox import MessageBox -from Screens.Volume import Volume -from Screens.Mute import Mute +from Screens.Dish import Dish from Screens.Standby import Standby +from Screens.EventView import EventView +from Screens.MinuteInput import MinuteInput +from Components.Harddisk import harddiskmanager + +from Tools import Notifications +from Tools.Directories import * #from enigma import eTimer, eDVBVolumecontrol, quitMainloop from enigma import * +import time +import os + +from Components.config import config, currentConfigSelectionElement + # hack alert! from Menu import MainMenu, mdom -class InfoBarVolumeControl: - """Volume control, handles volUp, volDown, volMute actions and display - a corresponding dialog""" - +class InfoBarDish: def __init__(self): - self["VolumeActions"] = ActionMap( ["InfobarVolumeActions"] , - { - "volumeUp": self.volUp, - "volumeDown": self.volDown, - "volumeMute": self.volMute, - }) - - self.volumeDialog = self.session.instantiateDialog(Volume) - self.muteDialog = self.session.instantiateDialog(Mute) - - self.hideVolTimer = eTimer() - self.hideVolTimer.timeout.get().append(self.volHide) - - def volUp(self): - eDVBVolumecontrol.getInstance().volumeUp() - self.volumeDialog.instance.show() - self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume()) - self.hideVolTimer.start(3000) - - def volDown(self): - eDVBVolumecontrol.getInstance().volumeDown() - self.volumeDialog.instance.show() - self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume()) - self.hideVolTimer.start(3000) - - def volHide(self): - self.volumeDialog.instance.hide() - - def volMute(self): - eDVBVolumecontrol.getInstance().volumeToggleMute() - self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume()) - - if (eDVBVolumecontrol.getInstance().isMuted()): - self.muteDialog.instance.show() - else: - self.muteDialog.instance.hide() + self.dishDialog = self.session.instantiateDialog(Dish) + self.onShown.append(self.dishDialog.instance.show) class InfoBarShowHide: """ InfoBar show/hide control, accepts toggleShow and hide actions, might start @@ -78,16 +56,27 @@ class InfoBarShowHide: "hide": self.hide, }) - self.state = self.STATE_HIDDEN + self.state = self.STATE_SHOWN + + self.onExecBegin.append(self.show) + self.onClose.append(self.delHideTimer) self.hideTimer = eTimer() self.hideTimer.timeout.get().append(self.doTimerHide) - #self.hideTimer.start(1000) + self.hideTimer.start(5000, True) + + def delHideTimer(self): + del self.hideTimer def hide(self): self.instance.hide() + + def show(self): + self.state = self.STATE_SHOWN + self.hideTimer.start(5000, True) def doTimerHide(self): + self.hideTimer.stop() if self.state == self.STATE_SHOWN: self.instance.hide() self.state = self.STATE_HIDDEN @@ -97,14 +86,12 @@ class InfoBarShowHide: self.instance.hide() #pls check animation support, sorry # self.startHide() + self.hideTimer.stop() self.state = self.STATE_HIDDEN - else: + elif self.state == self.STATE_HIDDEN: self.instance.show() -# self.startShow() - self.state = self.STATE_SHOWN - #TODO: make it customizable - self.hideTimer.start(5000) - + self.show() + def startShow(self): self.instance.m_animation.startMoveAnimation(ePoint(0, 600), ePoint(0, 380), 100) self.state = self.STATE_SHOWN @@ -116,15 +103,14 @@ class InfoBarShowHide: class NumberZap(Screen): def quit(self): self.Timer.stop() - self.close() + self.close(0) def keyOK(self): self.Timer.stop() - print "do the action here" - self.close() + self.close(int(self["number"].getText())) def keyNumberGlobal(self, number): - self.Timer.start(3000) #reset timer + self.Timer.start(3000, True) #reset timer self.field = self.field + str(number) self["number"].setText(self.field) if len(self.field) >= 4: @@ -133,7 +119,9 @@ class NumberZap(Screen): def __init__(self, session, number): Screen.__init__(self, session) self.field = str(number) - + + self["channel"] = Label(_("Channel:")) + self["number"] = Label(self.field) self["actions"] = NumberActionMap( [ "SetupActions" ], @@ -154,7 +142,7 @@ class NumberZap(Screen): self.Timer = eTimer() self.Timer.timeout.get().append(self.keyOK) - self.Timer.start(3000) + self.Timer.start(3000, True) class InfoBarPowerKey: """ PowerKey stuff - handles the powerkey press and powerkey release actions""" @@ -162,10 +150,12 @@ class InfoBarPowerKey: def __init__(self): self.powerKeyTimer = eTimer() self.powerKeyTimer.timeout.get().append(self.powertimer) - self["PowerKeyActions"] = ActionMap( ["PowerKeyActions"], + self["PowerKeyActions"] = HelpableActionMap(self, "PowerKeyActions", { "powerdown": self.powerdown, "powerup": self.powerup, + "discreteStandby": (self.standby, "Go standby"), + "discretePowerOff": (self.quit, "Go to deep standby"), }) def powertimer(self): @@ -174,19 +164,20 @@ class InfoBarPowerKey: def powerdown(self): self.standbyblocked = 0 - self.powerKeyTimer.start(3000) + self.powerKeyTimer.start(3000, True) def powerup(self): self.powerKeyTimer.stop() if self.standbyblocked == 0: self.standbyblocked = 1 - self.session.open(Standby, self) + self.standby() - def quit(self): - # self.session.open(Standby, self) - configfile.save() - quitMainloop(0) + def standby(self): + self.session.open(Standby, self) + def quit(self): + # halt + quitMainloop(1) class InfoBarNumberZap: """ Handles an initial number for NumberZapping """ @@ -206,8 +197,57 @@ class InfoBarNumberZap: }) def keyNumberGlobal(self, number): - print "You pressed number " + str(number) - self.session.open(NumberZap, number) +# print "You pressed number " + str(number) + if number == 0: + self.servicelist.recallPrevService() + self.instance.show() + self.show() + else: + self.session.openWithCallback(self.numberEntered, NumberZap, number) + + def numberEntered(self, retval): +# print self.servicelist + if retval > 0: + self.zapToNumber(retval) + + def searchNumberHelper(self, serviceHandler, num, bouquet): + servicelist = serviceHandler.list(bouquet) + if not servicelist is None: + while num: + 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; + if not num: #found service with searched number ? + return serviceIterator, 0 + return None, num + + def zapToNumber(self, number): + bouquet = self.servicelist.bouquet_root + service = None + serviceHandler = eServiceCenter.getInstance() + if bouquet.toString().find('FROM BOUQUET "bouquets.') == -1: #FIXME HACK + service, number = self.searchNumberHelper(serviceHandler, number, bouquet) + else: + bouquetlist = serviceHandler.list(bouquet) + if not bouquetlist is None: + while number: + bouquet = self.servicelist.appendDVBTypes(bouquetlist.getNext()) + if not bouquet.valid(): #check end of list + break + if ((bouquet.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory): + continue + service, number = self.searchNumberHelper(serviceHandler, number, bouquet) + if not service is None: + if self.servicelist.getRoot() != bouquet: #already in correct bouquet? + self.servicelist.clearPath() + if self.servicelist.bouquet_root != bouquet: + self.servicelist.enterPath(self.servicelist.bouquet_root) + self.servicelist.enterPath(bouquet) + self.servicelist.setCurrentSelection(service) #select the service in servicelist + self.servicelist.zap() class InfoBarChannelSelection: """ ChannelSelection - handles the channelSelection dialog and the initial @@ -216,12 +256,12 @@ class InfoBarChannelSelection: #instantiate forever self.servicelist = self.session.instantiateDialog(ChannelSelection) - self["ChannelSelectActions"] = ActionMap( ["InfobarChannelSelection"], + self["ChannelSelectActions"] = HelpableActionMap(self, "InfobarChannelSelection", { "switchChannelUp": self.switchChannelUp, "switchChannelDown": self.switchChannelDown, - "zapUp": self.zapUp, - "zapDown": self.zapDown, + "zapUp": (self.zapUp, _("next channel")), + "zapDown": (self.zapDown, _("previous channel")), }) def switchChannelUp(self): @@ -235,17 +275,21 @@ class InfoBarChannelSelection: def zapUp(self): self.servicelist.moveUp() self.servicelist.zap() + self.instance.show() + self.show() def zapDown(self): self.servicelist.moveDown() self.servicelist.zap() - + self.instance.show() + self.show() + class InfoBarMenu: """ Handles a menu action, to open the (main) menu """ def __init__(self): - self["MenuActions"] = ActionMap( [ "InfobarMenuActions" ], + self["MenuActions"] = HelpableActionMap(self, "InfobarMenuActions", { - "mainMenu": self.mainMenu, + "mainMenu": (self.mainMenu, "Enter main menu..."), }) def mainMenu(self): @@ -257,20 +301,151 @@ class InfoBarMenu: class InfoBarEPG: """ EPG - Opens an EPG list when the showEPGList action fires """ def __init__(self): - self["EPGActions"] = ActionMap( [ "InfobarEPGActions" ], + self["EPGActions"] = HelpableActionMap(self, "InfobarEPGActions", { - "showEPGList": self.showEPGList, + "showEPGList": (self.showEPG, _("show EPG...")), }) + def showEPG(self): + if currentConfigSelectionElement(config.usage.epgtoggle) == "yes": + self.openSingleServiceEPG() + else: + self.showEPGList() + def showEPGList(self): + bouquets = self.servicelist.getBouquetList() + if bouquets is None: + cnt = 0 + else: + cnt = len(bouquets) + if cnt > 1: # show bouquet list + self.session.open(BouquetSelector, bouquets, self.openBouquetEPG) + elif cnt == 1: # add to only one existing bouquet + self.openBouquetEPG(bouquets[0][1]) + else: #no bouquets so we open single epg + self.openSingleEPGSelector(self.session.nav.getCurrentlyPlayingServiceReference()) + + def bouquetEPGCallback(self, info): + if info: + self.openSingleServiceEPG() + + def singleEPGCallback(self, info): + if info: + self.showEPGList() + + def openEventView(self): + try: + self.epglist = [ ] + service = self.session.nav.getCurrentService() + info = service.info() + ptr=info.getEvent(0) + if ptr: + self.epglist.append(ptr) + ptr=info.getEvent(1) + if ptr: + self.epglist.append(ptr) + if len(self.epglist) > 0: + self.session.open(EventView, self.epglist[0], ServiceReference(ref), self.eventViewCallback) + except: + pass + + def openSingleServiceEPG(self): ref=self.session.nav.getCurrentlyPlayingServiceReference() ptr=eEPGCache.getInstance() if ptr.startTimeQuery(ref) != -1: - self.session.open(EPGSelection, ref) - else: + self.session.openWithCallback(self.singleEPGCallback, EPGSelection, ref) + else: # try to show now/next print 'no epg for service', ref.toString() -class InfoBarEvent: + + def openBouquetEPG(self, bouquet): + ptr=eEPGCache.getInstance() + services = [ ] + servicelist = eServiceCenter.getInstance().list(bouquet) + if not servicelist is None: + while True: + service = servicelist.getNext() + if not service.valid(): #check if end of list + break + if service.flags: #ignore non playable services + continue + services.append(ServiceReference(service)) + if len(services): + self.session.openWithCallback(self.bouquetEPGCallback, EPGSelection, services) + + def openSingleEPGSelector(self, ref): + ptr=eEPGCache.getInstance() + if ptr.startTimeQuery(ref) != -1: + self.session.open(EPGSelection, ref) + else: # try to show now/next + print 'no epg for service', ref.toString() + try: + self.epglist = [ ] + service = self.session.nav.getCurrentService() + info = service.info() + ptr=info.getEvent(0) + if ptr: + self.epglist.append(ptr) + ptr=info.getEvent(1) + if ptr: + self.epglist.append(ptr) + if len(self.epglist) > 0: + self.session.open(EventView, self.epglist[0], ServiceReference(ref), self.eventViewCallback) + except: + pass + + def eventViewCallback(self, setEvent, setService, val): #used for now/next displaying + if len(self.epglist) > 1: + tmp = self.epglist[0] + self.epglist[0]=self.epglist[1] + self.epglist[1]=tmp + setEvent(self.epglist[0]) + +from math import log + +class InfoBarTuner: + """provides a snr/agc/ber display""" + def __init__(self): + self["snr"] = Label() + self["agc"] = Label() + self["ber"] = Label() + self["snr_percent"] = Label() + self["agc_percent"] = Label() + self["ber_count"] = Label() + self["snr_progress"] = ProgressBar() + self["agc_progress"] = ProgressBar() + self["ber_progress"] = ProgressBar() + self.timer = eTimer() + self.timer.timeout.get().append(self.updateTunerInfo) + self.timer.start(1000) + + def calc(self,val): + if not val: + return 0 + if val < 2500: + return (long)(log(val)/log(2)) + return val*100/65535 + + def updateTunerInfo(self): + if self.instance.isVisible(): + service = self.session.nav.getCurrentService() + snr=0 + agc=0 + ber=0 + if service is not None: + feinfo = service.frontendStatusInfo() + if feinfo is not None: + ber=feinfo.getFrontendInfo(iFrontendStatusInformation.bitErrorRate) + snr=feinfo.getFrontendInfo(iFrontendStatusInformation.signalPower)*100/65536 + agc=feinfo.getFrontendInfo(iFrontendStatusInformation.signalQuality)*100/65536 + self["snr_percent"].setText("%d%%"%(snr)) + self["agc_percent"].setText("%d%%"%(agc)) + self["ber_count"].setText("%d"%(ber)) + self["snr_progress"].setValue(snr) + self["agc_progress"].setValue(agc) + self["ber_progress"].setValue(self.calc(ber)) + +class InfoBarEvent: """provides a current/next event info display""" def __init__(self): self["Event_Now_StartTime"] = EventInfo(self.session.nav, EventInfo.Now_StartTime) @@ -282,29 +457,126 @@ class InfoBarEvent: self["Event_Now_Duration"] = EventInfo(self.session.nav, EventInfo.Now_Duration) self["Event_Next_Duration"] = EventInfo(self.session.nav, EventInfo.Next_Duration) + self["Now_ProgressBar"] = EventInfoProgress(self.session.nav, EventInfo.Now) + class InfoBarServiceName: def __init__(self): self["ServiceName"] = ServiceName(self.session.nav) -class InfoBarPVR: - """handles PVR specific actions like seeking, pause""" +class InfoBarSeek: + """handles actions like seeking, pause""" + + # ispause, isff, issm, skip + SEEK_STATE_PLAY = (0, 0, 0, 0) + SEEK_STATE_PAUSE = (1, 0, 0, 0) + SEEK_STATE_FF_2X = (0, 2, 0, 0) + SEEK_STATE_FF_4X = (0, 4, 0, 0) + SEEK_STATE_FF_8X = (0, 8, 0, 0) + SEEK_STATE_FF_32X = (0, 4, 0, 32) + SEEK_STATE_FF_64X = (0, 4, 0, 64) + SEEK_STATE_FF_128X = (0, 4, 0, 128) + + SEEK_STATE_BACK_4X = (0, 0, 0, -4) + SEEK_STATE_BACK_32X = (0, 0, 0, -32) + SEEK_STATE_BACK_64X = (0, 0, 0, -64) + SEEK_STATE_BACK_128X = (0, 0, 0, -128) + + SEEK_STATE_SM_HALF = (0, 0, 2, 0) + SEEK_STATE_SM_QUARTER = (0, 0, 4, 0) + SEEK_STATE_SM_EIGHTH = (0, 0, 8, 0) + def __init__(self): - self["PVRActions"] = ActionMap( [ "InfobarPVRActions" ], + self["SeekActions"] = HelpableActionMap(self, "InfobarSeekActions", { - "pauseService": self.pauseService, - "unPauseService": self.unPauseService, + "pauseService": (self.pauseService, "pause"), + "unPauseService": (self.unPauseService, "continue"), - "seekFwd": self.seekFwd, - "seekBack": self.seekBack, + "seekFwd": (self.seekFwd, "skip forward"), + "seekFwdUp": (self.seekFwdUp, "skip forward"), + "seekBack": (self.seekBack, "skip backward"), + "seekBackUp": (self.seekBackUp, "skip backward"), }) + + self.seekstate = self.SEEK_STATE_PLAY + self.seekTimer = eTimer() + self.seekTimer.timeout.get().append(self.seekTimerFired) + self.skipinterval = 500 # 500ms skip interval + self.onClose.append(self.delSeekTimer) + + self.fwdtimer = False + self.fwdKeyTimer = eTimer() + self.fwdKeyTimer.timeout.get().append(self.fwdTimerFire) + + self.rwdtimer = False + self.rwdKeyTimer = eTimer() + self.rwdKeyTimer.timeout.get().append(self.rwdTimerFire) + + def up(self): + pass + + def down(self): + pass + + def delSeekTimer(self): + del self.seekTimer + + def seekTimerFired(self): + self.seekbase += self.skipmode * self.skipinterval + + # check if we bounced against the beginning of the file + if self.seekbase < 0: + self.seekbase = 0; + self.setSeekState(self.SEEK_STATE_PLAY) + + self.doSeek(self.seekbase) + + def setSeekState(self, state): + oldstate = self.seekstate + + self.seekstate = state + + service = self.session.nav.getCurrentService() + if service is None: + return + + pauseable = service.pause() + + for i in range(4): + if oldstate[i] != self.seekstate[i]: + (self.session.nav.pause, pauseable.setFastForward, pauseable.setSlowMotion, self.setSkipMode)[i](self.seekstate[i]) + + def setSkipMode(self, skipmode): + self.skipmode = skipmode + if skipmode == 0: + self.seekTimer.stop() + else: + self.seekTimer.start(500) + + service = self.session.nav.getCurrentService() + if service is None: + return + + seekable = service.seek() + if seekable is None: + return + + if skipmode: + seekable.setTrickmode(1) + else: + seekable.setTrickmode(0) + self.seekbase = seekable.getPlayPosition()[1] / 90 + def pauseService(self): - self.session.nav.pause(1) + if (self.seekstate == self.SEEK_STATE_PAUSE): + self.unPauseService() + else: + self.setSeekState(self.SEEK_STATE_PAUSE); def unPauseService(self): - self.session.nav.pause(0) + self.setSeekState(self.SEEK_STATE_PLAY); - def doSeek(self, dir, seektime): + def doSeek(self, seektime): service = self.session.nav.getCurrentService() if service is None: return @@ -312,66 +584,232 @@ class InfoBarPVR: seekable = service.seek() if seekable is None: return - seekable.seekRelative(dir, 90 * seektime) + seekable.seekTo(90 * seektime) def seekFwd(self): - self.doSeek(+1, 10000) - + print "start fwd timer" + self.fwdtimer = True + self.fwdKeyTimer.start(500) + def seekBack(self): - self.doSeek(-1, 10000) + print "start rewind timer" + self.rwdtimer = True + self.rwdKeyTimer.start(500) + + def seekFwdUp(self): + if self.fwdtimer: + self.fwdKeyTimer.stop() + self.fwdtimer = False + lookup = { + self.SEEK_STATE_PLAY: self.SEEK_STATE_FF_2X, + self.SEEK_STATE_PAUSE: self.SEEK_STATE_SM_EIGHTH, + self.SEEK_STATE_FF_2X: self.SEEK_STATE_FF_4X, + self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_8X, + self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_32X, + self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_64X, + self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_128X, + self.SEEK_STATE_FF_128X: self.SEEK_STATE_FF_128X, + self.SEEK_STATE_BACK_4X: self.SEEK_STATE_PLAY, + self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_4X, + self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_32X, + 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.setSeekState(lookup[self.seekstate]); + + def seekBackUp(self): + if self.rwdtimer: + self.rwdKeyTimer.stop() + self.rwdtimer = False + + lookup = { + self.SEEK_STATE_PLAY: self.SEEK_STATE_BACK_4X, + 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_4X: 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: + service = self.session.nav.getCurrentService() + if service is None: + return + seekable = service.seek() + if seekable is None: + return + seekable.seekRelative(1, minutes * 60 * 90000) + + def rwdTimerFire(self): + self.rwdKeyTimer.stop() + self.rwdtimer = False + self.session.openWithCallback(self.rwdSeekTo, MinuteInput) + + def rwdSeekTo(self, minutes): + self.fwdSeekTo(0 - minutes) + +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 moe 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") + }) + +class InfoBarTimeshift: + def __init__(self): + self["TimeshiftActions"] = HelpableActionMap(self, "InfobarTimeshiftActions", + { + "timeshiftStart": (self.startTimeshift, "start timeshift "), + "timeshiftStop": (self.stopTimeshift, "stop timeshift") + }) + self.tshack = 0 + + def getTimeshift(self): + service = self.session.nav.getCurrentService() + return service.timeshift() + + def startTimeshift(self): + # TODO: check for harddisk! (or do this in the interface? would make + # more sense... for example radio could be timeshifted in memory, + # and the decision can't be made here) + 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 + print "ok, timeshift enabled" + if self.tshack == 0: + ts.startTimeshift() + self.tshack = 1 + else: + pauseable = self.session.nav.getCurrentService().pause() + pauseable.pause() # switch to record + + def stopTimeshift(self): + print "disable timeshift" + ts = self.getTimeshift() + if ts is None: + return + ts.stopTimeshift() + self.tshack = 0 + + +from RecordTimer import parseEvent class InfoBarInstantRecord: """Instant Record - handles the instantRecord action in order to start/stop instant records""" def __init__(self): - self["InstnantRecordActions"] = ActionMap( [ "InfobarInstantRecord" ], + self["InstantRecordActions"] = HelpableActionMap(self, "InfobarInstantRecord", { - "instantRecord": self.instantRecord, + "instantRecord": (self.instantRecord, "Instant Record..."), }) self.recording = None - + + self["BlinkingPoint"] = BlinkingPixmapConditional() + self.onShown.append(self["BlinkingPoint"].hideWidget) + self["BlinkingPoint"].setConnect(self.session.nav.RecordTimer.isRecording) + def stopCurrentRecording(self): self.session.nav.RecordTimer.removeEntry(self.recording) self.recording = None - + def startInstantRecording(self): serviceref = self.session.nav.getCurrentlyPlayingServiceReference() - + # try to get event info - epg = None + event = None try: service = self.session.nav.getCurrentService() info = service.info() ev = info.getEvent(0) - epg = ev + event = ev except: pass + if event is not None: + data = parseEvent(event) + begin = data[0] + if begin < time.time(): + begin = time.time() + + end = data[1] + if end < begin: + end = begin + + end += 3600 * 10 + + data = (begin, end, data[2], data[3], data[4]) + else: + data = (time.time(), time.time() + 3600 * 10, "instant record", "", None) + # fix me, description. - self.recording = self.session.nav.recordWithTimer(time.time(), time.time() + 3600, serviceref, epg, "instant record") + self.recording = self.session.nav.recordWithTimer(serviceref, *data) + self.recording.dontSave = True + + #self["BlinkingPoint"].setConnect(lambda: self.recording.isRunning()) + + def isInstantRecordRunning(self): + if self.recording != None: + if self.recording.isRunning(): + return True + return False def recordQuestionCallback(self, answer): if answer == False: return - if self.recording != None: + if self.isInstantRecordRunning(): self.stopCurrentRecording() else: self.startInstantRecording() def instantRecord(self): - if self.recording != None: - self.session.openWithCallback(self.recordQuestionCallback, MessageBox, "Do you want to stop the current\n(instant) recording?") + try: + stat = os.stat(resolveFilename(SCOPE_HDD)) + except: + self.session.open(MessageBox, _("No HDD found or HDD not initialized!"), MessageBox.TYPE_ERROR) + return + + if self.isInstantRecordRunning(): + self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Do you want to stop the current\n(instant) recording?")) else: - self.session.openWithCallback(self.recordQuestionCallback, MessageBox, "Start recording?") + self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Start recording?")) from Screens.AudioSelection import AudioSelection class InfoBarAudioSelection: def __init__(self): - self["AudioSelectionAction"] = ActionMap( [ "InfobarAudioSelectionActions" ], + self["AudioSelectionAction"] = HelpableActionMap(self, "InfobarAudioSelectionActions", { - "audioSelection": self.audioSelection, + "audioSelection": (self.audioSelection, "Audio Options..."), }) def audioSelection(self): @@ -380,3 +818,129 @@ class InfoBarAudioSelection: n = audio.getNumberOfTracks() if n > 0: self.session.open(AudioSelection, audio) + +from Screens.SubserviceSelection import SubserviceSelection + +class InfoBarSubserviceSelection: + def __init__(self): + self["SubserviceSelectionAction"] = HelpableActionMap(self, "InfobarSubserviceSelectionActions", + { + "subserviceSelection": (self.subserviceSelection, "Subservice list..."), + }) + + def subserviceSelection(self): + service = self.session.nav.getCurrentService() + subservices = service.subServices() + n = subservices.getNumberOfSubservices() + if n > 0: + self.session.openWithCallback(self.subserviceSelected, SubserviceSelection, subservices) + + def subserviceSelected(self, service): + if not service is None: + self.session.nav.playService(service) + +class InfoBarAdditionalInfo: + def __init__(self): + self["DolbyActive"] = Pixmap() + self["CryptActive"] = Pixmap() + self["FormatActive"] = Pixmap() + + self["ButtonRed"] = PixmapConditional(withTimer = False) + self["ButtonRed"].setConnect(lambda: harddiskmanager.HDDCount() > 0) + self.onShown.append(self["ButtonRed"].update) + self["ButtonRedText"] = LabelConditional(text = _("Record"), withTimer = False) + self["ButtonRedText"].setConnect(lambda: harddiskmanager.HDDCount() > 0) + self.onShown.append(self["ButtonRedText"].update) + + self["ButtonGreen"] = Pixmap() + self["ButtonGreenText"] = Label(_("Subservices")) + + self["ButtonYellow"] = PixmapConditional(withTimer = False) + self["ButtonYellow"].setConnect(lambda: False) + + self["ButtonBlue"] = PixmapConditional(withTimer = False) + self["ButtonBlue"].setConnect(lambda: False) + + self.session.nav.event.append(self.gotServiceEvent) # we like to get service events + + def hideSubServiceIndication(self): + self["ButtonGreen"].hideWidget() + self["ButtonGreenText"].hide() + + def showSubServiceIndication(self): + self["ButtonGreen"].showWidget() + self["ButtonGreenText"].show() + + def checkFormat(self, service): + info = service.info() + if info is not None: + aspect = info.getInfo(iServiceInformation.sAspect) + if aspect in [ 3, 4, 7, 8, 0xB, 0xC, 0xF, 0x10 ]: + self["FormatActive"].showWidget() + else: + self["FormatActive"].hideWidget() + + def checkSubservices(self, service): + if service.subServices().getNumberOfSubservices() > 0: + self.showSubServiceIndication() + else: + self.hideSubServiceIndication() + + def checkDolby(self, service): + # FIXME + dolby = False + audio = service.audioTracks() + if audio is not None: + n = audio.getNumberOfTracks() + for x in range(n): + i = audio.getTrackInfo(x) + description = i.getDescription(); + if description.find("AC3") != -1 or description.find("DTS") != -1: + dolby = True + break + if dolby: + self["DolbyActive"].showWidget() + else: + self["DolbyActive"].hideWidget() + + def checkCrypted(self, service): + info = service.info() + if info is not None: + if info.getInfo(iServiceInformation.sIsCrypted) > 0: + self["CryptActive"].showWidget() + else: + self["CryptActive"].hideWidget() + + def gotServiceEvent(self, ev): + service = self.session.nav.getCurrentService() + if ev == pNavigation.evUpdatedEventInfo: + self.checkSubservices(service) + self.checkFormat(service) + elif ev == pNavigation.evUpdatedInfo: + self.checkCrypted(service) + self.checkDolby(service) + elif ev == pNavigation.evStopService: + self.hideSubServiceIndication() + self["CryptActive"].hideWidget() + self["DolbyActive"].hideWidget() + self["FormatActive"].hideWidget() + +class InfoBarNotifications: + def __init__(self): + self.onExecBegin.append(self.checkNotifications) + Notifications.notificationAdded.append(self.checkNotificationsIfExecing) + + def checkNotificationsIfExecing(self): + if self.execing: + self.checkNotifications() + + def checkNotifications(self): + if len(Notifications.notifications): + n = Notifications.notifications[0] + Notifications.notifications = Notifications.notifications[1:] + print "open",n + cb = n[0] + if cb is not None: + self.session.openWithCallback(cb, *n[1:]) + else: + self.session.open(*n[1:])