1 from Screen import Screen
2 from Components.ActionMap import ActionMap, HelpableActionMap
3 from Components.ActionMap import NumberActionMap
4 from Components.Label import *
5 from Components.ProgressBar import *
6 from Components.config import configfile, configsequencearg
7 from Components.config import config, configElement, ConfigSubsection, configSequence
8 from ChannelSelection import ChannelSelection, BouquetSelector
10 from Components.Pixmap import Pixmap, PixmapConditional
11 from Components.BlinkingPixmap import BlinkingPixmapConditional
12 from Components.ServiceName import ServiceName
13 from Components.EventInfo import EventInfo
15 from ServiceReference import ServiceReference
16 from EpgSelection import EPGSelection
18 from Screens.MessageBox import MessageBox
19 from Screens.Volume import Volume
20 from Screens.Mute import Mute
21 from Screens.Dish import Dish
22 from Screens.Standby import Standby
23 from Screens.EventView import EventView
24 from Screens.MinuteInput import MinuteInput
25 from Components.Harddisk import harddiskmanager
27 from Tools import Notifications
28 from Tools.Directories import *
30 #from enigma import eTimer, eDVBVolumecontrol, quitMainloop
36 from Components.config import config, currentConfigSelectionElement
39 from Menu import MainMenu, mdom
41 from GlobalActions import globalActionMap
43 class InfoBarVolumeControl:
44 """Volume control, handles volUp, volDown, volMute actions and display
45 a corresponding dialog"""
48 global globalActionMap
49 globalActionMap.actions["volumeUp"]=self.volUp
50 globalActionMap.actions["volumeDown"]=self.volDown
51 globalActionMap.actions["volumeMute"]=self.volMute
53 config.audio = ConfigSubsection()
54 config.audio.volume = configElement("config.audio.volume", configSequence, [100], configsequencearg.get("INTEGER", (0, 100)))
56 self.volumeDialog = self.session.instantiateDialog(Volume)
57 self.muteDialog = self.session.instantiateDialog(Mute)
59 self.hideVolTimer = eTimer()
60 self.hideVolTimer.timeout.get().append(self.volHide)
62 vol = config.audio.volume.value[0]
63 self.volumeDialog.setValue(vol)
64 eDVBVolumecontrol.getInstance().setVolume(vol, vol)
67 config.audio.volume.value = eDVBVolumecontrol.getInstance().getVolume()
68 config.audio.volume.save()
71 if (eDVBVolumecontrol.getInstance().isMuted()):
73 eDVBVolumecontrol.getInstance().volumeUp()
74 self.volumeDialog.instance.show()
75 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
77 self.hideVolTimer.start(3000, True)
80 if (eDVBVolumecontrol.getInstance().isMuted()):
82 eDVBVolumecontrol.getInstance().volumeDown()
83 self.volumeDialog.instance.show()
84 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
86 self.hideVolTimer.start(3000, True)
89 self.volumeDialog.instance.hide()
92 eDVBVolumecontrol.getInstance().volumeToggleMute()
93 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
95 if (eDVBVolumecontrol.getInstance().isMuted()):
96 self.muteDialog.instance.show()
98 self.muteDialog.instance.hide()
102 self.dishDialog = self.session.instantiateDialog(Dish)
103 self.onShown.append(self.dishDialog.instance.hide)
105 class InfoBarShowHide:
106 """ InfoBar show/hide control, accepts toggleShow and hide actions, might start
107 fancy animations. """
114 self["ShowHideActions"] = ActionMap( ["InfobarShowHideActions"] ,
116 "toggleShow": self.toggleShow,
120 self.state = self.STATE_SHOWN
122 self.onExecBegin.append(self.show)
123 self.onClose.append(self.delHideTimer)
125 self.hideTimer = eTimer()
126 self.hideTimer.timeout.get().append(self.doTimerHide)
127 self.hideTimer.start(5000, True)
129 def delHideTimer(self):
136 self.state = self.STATE_SHOWN
137 self.hideTimer.start(5000, True)
139 def doTimerHide(self):
140 self.hideTimer.stop()
141 if self.state == self.STATE_SHOWN:
143 self.state = self.STATE_HIDDEN
145 def toggleShow(self):
146 if self.state == self.STATE_SHOWN:
148 #pls check animation support, sorry
150 self.hideTimer.stop()
151 self.state = self.STATE_HIDDEN
152 elif self.state == self.STATE_HIDDEN:
157 self.instance.m_animation.startMoveAnimation(ePoint(0, 600), ePoint(0, 380), 100)
158 self.state = self.STATE_SHOWN
161 self.instance.m_animation.startMoveAnimation(ePoint(0, 380), ePoint(0, 600), 100)
162 self.state = self.STATE_HIDDEN
164 class NumberZap(Screen):
171 self.close(int(self["number"].getText()))
173 def keyNumberGlobal(self, number):
174 self.Timer.start(3000, True) #reset timer
175 self.field = self.field + str(number)
176 self["number"].setText(self.field)
177 if len(self.field) >= 4:
180 def __init__(self, session, number):
181 Screen.__init__(self, session)
182 self.field = str(number)
184 self["channel"] = Label(_("Channel:"))
186 self["number"] = Label(self.field)
188 self["actions"] = NumberActionMap( [ "SetupActions" ],
192 "1": self.keyNumberGlobal,
193 "2": self.keyNumberGlobal,
194 "3": self.keyNumberGlobal,
195 "4": self.keyNumberGlobal,
196 "5": self.keyNumberGlobal,
197 "6": self.keyNumberGlobal,
198 "7": self.keyNumberGlobal,
199 "8": self.keyNumberGlobal,
200 "9": self.keyNumberGlobal,
201 "0": self.keyNumberGlobal
204 self.Timer = eTimer()
205 self.Timer.timeout.get().append(self.keyOK)
206 self.Timer.start(3000, True)
208 class InfoBarPowerKey:
209 """ PowerKey stuff - handles the powerkey press and powerkey release actions"""
212 self.powerKeyTimer = eTimer()
213 self.powerKeyTimer.timeout.get().append(self.powertimer)
214 self["PowerKeyActions"] = HelpableActionMap(self, "PowerKeyActions",
216 "powerdown": self.powerdown,
217 "powerup": self.powerup,
218 "discreteStandby": (self.standby, "Go standby"),
219 "discretePowerOff": (self.quit, "Go to deep standby"),
222 def powertimer(self):
223 print "PowerOff - Now!"
227 self.standbyblocked = 0
228 self.powerKeyTimer.start(3000, True)
231 self.powerKeyTimer.stop()
232 if self.standbyblocked == 0:
233 self.standbyblocked = 1
237 self.session.open(Standby, self)
243 class InfoBarNumberZap:
244 """ Handles an initial number for NumberZapping """
246 self["NumberZapActions"] = NumberActionMap( [ "NumberZapActions"],
248 "1": self.keyNumberGlobal,
249 "2": self.keyNumberGlobal,
250 "3": self.keyNumberGlobal,
251 "4": self.keyNumberGlobal,
252 "5": self.keyNumberGlobal,
253 "6": self.keyNumberGlobal,
254 "7": self.keyNumberGlobal,
255 "8": self.keyNumberGlobal,
256 "9": self.keyNumberGlobal,
257 "0": self.keyNumberGlobal,
260 def keyNumberGlobal(self, number):
261 # print "You pressed number " + str(number)
263 self.session.nav.zapLast()
267 self.session.openWithCallback(self.numberEntered, NumberZap, number)
269 def numberEntered(self, retval):
270 # print self.servicelist
272 self.zapToNumber(retval)
274 def searchNumberHelper(self, serviceHandler, num, bouquet):
275 servicelist = serviceHandler.list(bouquet)
276 if not servicelist is None:
278 serviceIterator = servicelist.getNext()
279 if not serviceIterator.valid(): #check end of list
281 if serviceIterator.flags: #assume normal dvb service have no flags set
284 if not num: #found service with searched number ?
285 return serviceIterator, 0
288 def zapToNumber(self, number):
289 bouquet = self.servicelist.bouquet_root
291 serviceHandler = eServiceCenter.getInstance()
292 if bouquet.toString().find('FROM BOUQUET "bouquets.') == -1: #FIXME HACK
293 service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
295 bouquetlist = serviceHandler.list(bouquet)
296 if not bouquetlist is None:
298 bouquet = self.servicelist.appendDVBTypes(bouquetlist.getNext())
299 if not bouquet.valid(): #check end of list
301 if ((bouquet.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
303 service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
304 if not service is None:
305 self.session.nav.playService(service) #play service
306 if self.servicelist.getRoot() != bouquet: #already in correct bouquet?
307 self.servicelist.setRoot(bouquet)
308 self.servicelist.setCurrentSelection(service) #select the service in servicelist
310 class InfoBarChannelSelection:
311 """ ChannelSelection - handles the channelSelection dialog and the initial
312 channelChange actions which open the channelSelection dialog """
315 self.servicelist = self.session.instantiateDialog(ChannelSelection)
317 self["ChannelSelectActions"] = HelpableActionMap(self, "InfobarChannelSelection",
319 "switchChannelUp": self.switchChannelUp,
320 "switchChannelDown": self.switchChannelDown,
321 "zapUp": (self.zapUp, _("next channel")),
322 "zapDown": (self.zapDown, _("previous channel")),
325 def switchChannelUp(self):
326 self.servicelist.moveUp()
327 self.session.execDialog(self.servicelist)
329 def switchChannelDown(self):
330 self.servicelist.moveDown()
331 self.session.execDialog(self.servicelist)
334 self.servicelist.moveUp()
335 self.servicelist.zap()
340 self.servicelist.moveDown()
341 self.servicelist.zap()
346 """ Handles a menu action, to open the (main) menu """
348 self["MenuActions"] = HelpableActionMap(self, "InfobarMenuActions",
350 "mainMenu": (self.mainMenu, "Enter main menu..."),
354 print "loading mainmenu XML..."
355 menu = mdom.childNodes[0]
356 assert menu.tagName == "menu", "root element in menu must be 'menu'!"
357 self.session.open(MainMenu, menu, menu.childNodes)
360 """ EPG - Opens an EPG list when the showEPGList action fires """
362 self["EPGActions"] = HelpableActionMap(self, "InfobarEPGActions",
364 "showEPGList": (self.showEPG, _("show EPG...")),
368 if currentConfigSelectionElement(config.usage.epgtoggle) == "yes":
369 self.openSingleServiceEPG()
373 def showEPGList(self):
374 bouquets = self.servicelist.getBouquetList()
379 if cnt > 1: # show bouquet list
380 self.session.open(BouquetSelector, bouquets, self.openBouquetEPG)
381 elif cnt == 1: # add to only one existing bouquet
382 self.openBouquetEPG(bouquets[0][1])
383 else: #no bouquets so we open single epg
384 self.openSingleEPGSelector(self.session.nav.getCurrentlyPlayingServiceReference())
386 def bouquetEPGCallback(self, info):
388 self.openSingleServiceEPG()
390 def singleEPGCallback(self, info):
394 def openEventView(self):
397 service = self.session.nav.getCurrentService()
398 info = service.info()
401 self.epglist.append(ptr)
404 self.epglist.append(ptr)
405 if len(self.epglist) > 0:
406 self.session.open(EventView, self.epglist[0], ServiceReference(ref), self.eventViewCallback)
410 def openSingleServiceEPG(self):
411 ref=self.session.nav.getCurrentlyPlayingServiceReference()
412 ptr=eEPGCache.getInstance()
413 if ptr.startTimeQuery(ref) != -1:
414 self.session.openWithCallback(self.singleEPGCallback, EPGSelection, ref)
415 else: # try to show now/next
416 print 'no epg for service', ref.toString()
419 def openBouquetEPG(self, bouquet):
420 ptr=eEPGCache.getInstance()
422 servicelist = eServiceCenter.getInstance().list(bouquet)
423 if not servicelist is None:
425 service = servicelist.getNext()
426 if not service.valid(): #check if end of list
428 if service.flags: #ignore non playable services
430 services.append(ServiceReference(service))
432 self.session.openWithCallback(self.bouquetEPGCallback, EPGSelection, services)
434 def openSingleEPGSelector(self, ref):
435 ptr=eEPGCache.getInstance()
436 if ptr.startTimeQuery(ref) != -1:
437 self.session.open(EPGSelection, ref)
438 else: # try to show now/next
439 print 'no epg for service', ref.toString()
442 service = self.session.nav.getCurrentService()
443 info = service.info()
446 self.epglist.append(ptr)
449 self.epglist.append(ptr)
450 if len(self.epglist) > 0:
451 self.session.open(EventView, self.epglist[0], ServiceReference(ref), self.eventViewCallback)
455 def eventViewCallback(self, setEvent, setService, val): #used for now/next displaying
456 if len(self.epglist) > 1:
457 tmp = self.epglist[0]
458 self.epglist[0]=self.epglist[1]
460 setEvent(self.epglist[0])
465 """provides a snr/agc/ber display"""
467 self["snr"] = Label()
468 self["agc"] = Label()
469 self["ber"] = Label()
470 self["snr_percent"] = Label()
471 self["agc_percent"] = Label()
472 self["ber_count"] = Label()
473 self["snr_progress"] = ProgressBar()
474 self["agc_progress"] = ProgressBar()
475 self["ber_progress"] = ProgressBar()
476 self.timer = eTimer()
477 self.timer.timeout.get().append(self.updateTunerInfo)
478 self.timer.start(1000)
484 return (long)(log(val)/log(2))
487 def updateTunerInfo(self):
488 if self.instance.isVisible():
489 service = self.session.nav.getCurrentService()
493 if service is not None:
494 feinfo = service.frontendStatusInfo()
495 if feinfo is not None:
496 ber=feinfo.getFrontendInfo(iFrontendStatusInformation.bitErrorRate)
497 snr=feinfo.getFrontendInfo(iFrontendStatusInformation.signalPower)*100/65536
498 agc=feinfo.getFrontendInfo(iFrontendStatusInformation.signalQuality)*100/65536
499 self["snr_percent"].setText("%d%%"%(snr))
500 self["agc_percent"].setText("%d%%"%(agc))
501 self["ber_count"].setText("%d"%(ber))
502 self["snr_progress"].setValue(snr)
503 self["agc_progress"].setValue(agc)
504 self["ber_progress"].setValue(self.calc(ber))
507 """provides a current/next event info display"""
509 self["Event_Now_StartTime"] = EventInfo(self.session.nav, EventInfo.Now_StartTime)
510 self["Event_Next_StartTime"] = EventInfo(self.session.nav, EventInfo.Next_StartTime)
512 self["Event_Now"] = EventInfo(self.session.nav, EventInfo.Now)
513 self["Event_Next"] = EventInfo(self.session.nav, EventInfo.Next)
515 self["Event_Now_Duration"] = EventInfo(self.session.nav, EventInfo.Now_Duration)
516 self["Event_Next_Duration"] = EventInfo(self.session.nav, EventInfo.Next_Duration)
518 class InfoBarServiceName:
520 self["ServiceName"] = ServiceName(self.session.nav)
523 """handles actions like seeking, pause"""
525 # ispause, isff, issm, skip
526 SEEK_STATE_PLAY = (0, 0, 0, 0)
527 SEEK_STATE_PAUSE = (1, 0, 0, 0)
528 SEEK_STATE_FF_2X = (0, 2, 0, 0)
529 SEEK_STATE_FF_4X = (0, 4, 0, 0)
530 SEEK_STATE_FF_8X = (0, 8, 0, 0)
531 SEEK_STATE_FF_32X = (0, 4, 0, 32)
532 SEEK_STATE_FF_64X = (0, 4, 0, 64)
533 SEEK_STATE_FF_128X = (0, 4, 0, 128)
535 SEEK_STATE_BACK_4X = (0, 0, 0, -4)
536 SEEK_STATE_BACK_32X = (0, 0, 0, -32)
537 SEEK_STATE_BACK_64X = (0, 0, 0, -64)
538 SEEK_STATE_BACK_128X = (0, 0, 0, -128)
540 SEEK_STATE_SM_HALF = (0, 0, 2, 0)
541 SEEK_STATE_SM_QUARTER = (0, 0, 4, 0)
542 SEEK_STATE_SM_EIGHTH = (0, 0, 8, 0)
545 self["SeekActions"] = HelpableActionMap(self, "InfobarSeekActions",
547 "pauseService": (self.pauseService, "pause"),
548 "unPauseService": (self.unPauseService, "continue"),
550 "seekFwd": (self.seekFwd, "skip forward"),
551 "seekFwdUp": (self.seekFwdUp, "skip forward"),
552 "seekBack": (self.seekBack, "skip backward"),
553 "seekBackUp": (self.seekBackUp, "skip backward"),
556 self.seekstate = self.SEEK_STATE_PLAY
557 self.seekTimer = eTimer()
558 self.seekTimer.timeout.get().append(self.seekTimerFired)
559 self.skipinterval = 500 # 500ms skip interval
560 self.onClose.append(self.delSeekTimer)
562 self.fwdtimer = False
563 self.fwdKeyTimer = eTimer()
564 self.fwdKeyTimer.timeout.get().append(self.fwdTimerFire)
566 self.rwdtimer = False
567 self.rwdKeyTimer = eTimer()
568 self.rwdKeyTimer.timeout.get().append(self.rwdTimerFire)
576 def delSeekTimer(self):
579 def seekTimerFired(self):
580 self.seekbase += self.skipmode * self.skipinterval
582 # check if we bounced against the beginning of the file
583 if self.seekbase < 0:
585 self.setSeekState(self.SEEK_STATE_PLAY)
587 self.doSeek(self.seekbase)
589 def setSeekState(self, state):
590 oldstate = self.seekstate
592 self.seekstate = state
594 service = self.session.nav.getCurrentService()
598 pauseable = service.pause()
601 if oldstate[i] != self.seekstate[i]:
602 (self.session.nav.pause, pauseable.setFastForward, pauseable.setSlowMotion, self.setSkipMode)[i](self.seekstate[i])
604 def setSkipMode(self, skipmode):
605 self.skipmode = skipmode
607 self.seekTimer.stop()
609 self.seekTimer.start(500)
611 service = self.session.nav.getCurrentService()
615 seekable = service.seek()
620 seekable.setTrickmode(1)
622 seekable.setTrickmode(0)
624 self.seekbase = seekable.getPlayPosition()[1] / 90
626 def pauseService(self):
627 if (self.seekstate == self.SEEK_STATE_PAUSE):
628 self.unPauseService()
630 self.setSeekState(self.SEEK_STATE_PAUSE);
632 def unPauseService(self):
633 self.setSeekState(self.SEEK_STATE_PLAY);
635 def doSeek(self, seektime):
636 service = self.session.nav.getCurrentService()
640 seekable = service.seek()
643 seekable.seekTo(90 * seektime)
646 print "start fwd timer"
648 self.fwdKeyTimer.start(500)
651 print "start rewind timer"
653 self.rwdKeyTimer.start(500)
657 self.fwdKeyTimer.stop()
658 self.fwdtimer = False
660 self.SEEK_STATE_PLAY: self.SEEK_STATE_FF_2X,
661 self.SEEK_STATE_PAUSE: self.SEEK_STATE_SM_EIGHTH,
662 self.SEEK_STATE_FF_2X: self.SEEK_STATE_FF_4X,
663 self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_8X,
664 self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_32X,
665 self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_64X,
666 self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_128X,
667 self.SEEK_STATE_FF_128X: self.SEEK_STATE_FF_128X,
668 self.SEEK_STATE_BACK_4X: self.SEEK_STATE_PLAY,
669 self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_4X,
670 self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_32X,
671 self.SEEK_STATE_BACK_128X: self.SEEK_STATE_BACK_64X,
672 self.SEEK_STATE_SM_HALF: self.SEEK_STATE_SM_HALF,
673 self.SEEK_STATE_SM_QUARTER: self.SEEK_STATE_SM_HALF,
674 self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_SM_QUARTER
676 self.setSeekState(lookup[self.seekstate]);
678 def seekBackUp(self):
680 self.rwdKeyTimer.stop()
681 self.rwdtimer = False
684 self.SEEK_STATE_PLAY: self.SEEK_STATE_BACK_4X,
685 self.SEEK_STATE_PAUSE: self.SEEK_STATE_PAUSE,
686 self.SEEK_STATE_FF_2X: self.SEEK_STATE_PLAY,
687 self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_2X,
688 self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_4X,
689 self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_8X,
690 self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_32X,
691 self.SEEK_STATE_FF_128X: self.SEEK_STATE_FF_64X,
692 self.SEEK_STATE_BACK_4X: self.SEEK_STATE_BACK_32X,
693 self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_64X,
694 self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_128X,
695 self.SEEK_STATE_BACK_128X: self.SEEK_STATE_BACK_128X,
696 self.SEEK_STATE_SM_HALF: self.SEEK_STATE_SM_QUARTER,
697 self.SEEK_STATE_SM_QUARTER: self.SEEK_STATE_SM_EIGHTH,
698 self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_PAUSE
700 self.setSeekState(lookup[self.seekstate]);
702 def fwdTimerFire(self):
703 print "Display seek fwd"
704 self.fwdKeyTimer.stop()
705 self.fwdtimer = False
706 self.session.openWithCallback(self.fwdSeekTo, MinuteInput)
708 def fwdSeekTo(self, minutes):
709 print "Seek", minutes, "minutes forward"
711 service = self.session.nav.getCurrentService()
714 seekable = service.seek()
717 seekable.seekRelative(1, minutes * 60 * 90000)
719 def rwdTimerFire(self):
720 self.rwdKeyTimer.stop()
721 self.rwdtimer = False
722 self.session.openWithCallback(self.rwdSeekTo, MinuteInput)
724 def rwdSeekTo(self, minutes):
725 self.fwdSeekTo(0 - minutes)
727 class InfoBarShowMovies:
729 # i don't really like this class.
730 # it calls a not further specified "movie list" on up/down/movieList,
731 # so this is not moe than an action map
733 self["MovieListActions"] = HelpableActionMap(self, "InfobarMovieListActions",
735 "movieList": (self.showMovies, "movie list"),
736 "up": (self.showMovies, "movie list"),
737 "down": (self.showMovies, "movie list")
740 class InfoBarTimeshift:
742 self["TimeshiftActions"] = HelpableActionMap(self, "InfobarTimeshiftActions",
744 "timeshiftStart": (self.startTimeshift, "start timeshift "),
745 "timeshiftStop": (self.stopTimeshift, "stop timeshift")
749 def getTimeshift(self):
750 service = self.session.nav.getCurrentService()
751 return service.timeshift()
753 def startTimeshift(self):
754 # TODO: check for harddisk! (or do this in the interface? would make
755 # more sense... for example radio could be timeshifted in memory,
756 # and the decision can't be made here)
757 print "enable timeshift"
758 ts = self.getTimeshift()
760 self.session.open(MessageBox, _("Timeshift not possible!"), MessageBox.TYPE_ERROR)
761 print "no ts interface"
763 print "ok, timeshift enabled"
768 pauseable = self.session.nav.getCurrentService().pause()
769 pauseable.pause() # switch to record
771 def stopTimeshift(self):
772 print "disable timeshift"
773 ts = self.getTimeshift()
780 from RecordTimer import parseEvent
782 class InfoBarInstantRecord:
783 """Instant Record - handles the instantRecord action in order to
784 start/stop instant records"""
786 self["InstantRecordActions"] = HelpableActionMap(self, "InfobarInstantRecord",
788 "instantRecord": (self.instantRecord, "Instant Record..."),
790 self.recording = None
792 self["BlinkingPoint"] = BlinkingPixmapConditional()
793 self.onShown.append(self["BlinkingPoint"].hideWidget)
794 self["BlinkingPoint"].setConnect(self.session.nav.RecordTimer.isRecording)
796 def stopCurrentRecording(self):
797 self.session.nav.RecordTimer.removeEntry(self.recording)
798 self.recording = None
800 def startInstantRecording(self):
801 serviceref = self.session.nav.getCurrentlyPlayingServiceReference()
803 # try to get event info
806 service = self.session.nav.getCurrentService()
807 info = service.info()
808 ev = info.getEvent(0)
813 if event is not None:
814 data = parseEvent(event)
816 if begin < time.time():
825 data = (begin, end, data[2], data[3], data[4])
827 data = (time.time(), time.time() + 3600 * 10, "instant record", "", None)
829 # fix me, description.
830 self.recording = self.session.nav.recordWithTimer(serviceref, *data)
831 self.recording.dontSave = True
833 #self["BlinkingPoint"].setConnect(lambda: self.recording.isRunning())
835 def isInstantRecordRunning(self):
836 if self.recording != None:
837 if self.recording.isRunning():
841 def recordQuestionCallback(self, answer):
845 if self.isInstantRecordRunning():
846 self.stopCurrentRecording()
848 self.startInstantRecording()
850 def instantRecord(self):
852 stat = os.stat(resolveFilename(SCOPE_HDD))
854 self.session.open(MessageBox, _("No HDD found or HDD not initialized!"), MessageBox.TYPE_ERROR)
857 if self.isInstantRecordRunning():
858 self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Do you want to stop the current\n(instant) recording?"))
860 self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Start recording?"))
862 from Screens.AudioSelection import AudioSelection
864 class InfoBarAudioSelection:
866 self["AudioSelectionAction"] = HelpableActionMap(self, "InfobarAudioSelectionActions",
868 "audioSelection": (self.audioSelection, "Audio Options..."),
871 def audioSelection(self):
872 service = self.session.nav.getCurrentService()
873 audio = service.audioTracks()
874 n = audio.getNumberOfTracks()
876 self.session.open(AudioSelection, audio)
878 from Screens.SubserviceSelection import SubserviceSelection
880 class InfoBarSubserviceSelection:
882 self["SubserviceSelectionAction"] = HelpableActionMap(self, "InfobarSubserviceSelectionActions",
884 "subserviceSelection": (self.subserviceSelection, "Subservice list..."),
887 def subserviceSelection(self):
888 service = self.session.nav.getCurrentService()
889 subservices = service.subServices()
890 n = subservices.getNumberOfSubservices()
892 self.session.openWithCallback(self.subserviceSelected, SubserviceSelection, subservices)
894 def subserviceSelected(self, service):
895 if not service is None:
896 self.session.nav.playService(service)
898 class InfoBarAdditionalInfo:
900 self["DolbyActive"] = Pixmap()
901 self["CryptActive"] = Pixmap()
902 self["FormatActive"] = Pixmap()
904 self["ButtonRed"] = PixmapConditional(withTimer = False)
905 self["ButtonRed"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
906 self.onShown.append(self["ButtonRed"].update)
907 self["ButtonRedText"] = LabelConditional(text = _("Record"), withTimer = False)
908 self["ButtonRedText"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
909 self.onShown.append(self["ButtonRedText"].update)
911 self["ButtonGreen"] = Pixmap()
912 self["ButtonGreenText"] = Label(_("Subservices"))
914 self["ButtonYellow"] = PixmapConditional(withTimer = False)
915 self["ButtonYellow"].setConnect(lambda: False)
917 self["ButtonBlue"] = PixmapConditional(withTimer = False)
918 self["ButtonBlue"].setConnect(lambda: False)
920 self.session.nav.event.append(self.gotServiceEvent) # we like to get service events
922 def hideSubServiceIndication(self):
923 self["ButtonGreen"].hideWidget()
924 self["ButtonGreenText"].hide()
926 def showSubServiceIndication(self):
927 self["ButtonGreen"].showWidget()
928 self["ButtonGreenText"].show()
930 def checkFormat(self, service):
931 info = service.info()
933 aspect = info.getInfo(iServiceInformation.sAspect)
934 if aspect in [ 3, 4, 7, 8, 0xB, 0xC, 0xF, 0x10 ]:
935 self["FormatActive"].showWidget()
937 self["FormatActive"].hideWidget()
939 def checkSubservices(self, service):
940 if service.subServices().getNumberOfSubservices() > 0:
941 self.showSubServiceIndication()
943 self.hideSubServiceIndication()
945 def checkDolby(self, service):
948 audio = service.audioTracks()
949 if audio is not None:
950 n = audio.getNumberOfTracks()
952 i = audio.getTrackInfo(x)
953 description = i.getDescription();
954 if description.find("AC3") != -1 or description.find("DTS") != -1:
958 self["DolbyActive"].showWidget()
960 self["DolbyActive"].hideWidget()
962 def checkCrypted(self, service):
963 info = service.info()
965 if info.getInfo(iServiceInformation.sIsCrypted) > 0:
966 self["CryptActive"].showWidget()
968 self["CryptActive"].hideWidget()
970 def gotServiceEvent(self, ev):
971 service = self.session.nav.getCurrentService()
972 if ev == pNavigation.evUpdatedEventInfo:
973 self.checkSubservices(service)
974 self.checkFormat(service)
975 elif ev == pNavigation.evUpdatedInfo:
976 self.checkCrypted(service)
977 self.checkDolby(service)
978 elif ev == pNavigation.evStopService:
979 self.hideSubServiceIndication()
980 self["CryptActive"].hideWidget()
981 self["DolbyActive"].hideWidget()
982 self["FormatActive"].hideWidget()
984 class InfoBarNotifications:
986 self.onExecBegin.append(self.checkNotifications)
987 Notifications.notificationAdded.append(self.checkNotificationsIfExecing)
989 def checkNotificationsIfExecing(self):
991 self.checkNotifications()
993 def checkNotifications(self):
994 if len(Notifications.notifications):
995 n = Notifications.notifications[0]
996 Notifications.notifications = Notifications.notifications[1:]
1000 self.session.openWithCallback(cb, *n[1:])
1002 self.session.open(*n[1:])