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
37 from Menu import MainMenu, mdom
39 class InfoBarVolumeControl:
40 """Volume control, handles volUp, volDown, volMute actions and display
41 a corresponding dialog"""
43 config.audio = ConfigSubsection()
44 config.audio.volume = configElement("config.audio.volume", configSequence, [100], configsequencearg.get("INTEGER", (0, 100)))
46 self["VolumeActions"] = ActionMap( ["InfobarVolumeActions"] ,
48 "volumeUp": self.volUp,
49 "volumeDown": self.volDown,
50 "volumeMute": self.volMute,
53 self.volumeDialog = self.session.instantiateDialog(Volume)
54 self.muteDialog = self.session.instantiateDialog(Mute)
56 self.hideVolTimer = eTimer()
57 self.hideVolTimer.timeout.get().append(self.volHide)
59 vol = config.audio.volume.value[0]
60 self.volumeDialog.setValue(vol)
61 eDVBVolumecontrol.getInstance().setVolume(vol, vol)
64 config.audio.volume.value = eDVBVolumecontrol.getInstance().getVolume()
65 config.audio.volume.save()
68 if (eDVBVolumecontrol.getInstance().isMuted()):
70 eDVBVolumecontrol.getInstance().volumeUp()
71 self.volumeDialog.instance.show()
72 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
74 self.hideVolTimer.start(3000, True)
77 if (eDVBVolumecontrol.getInstance().isMuted()):
79 eDVBVolumecontrol.getInstance().volumeDown()
80 self.volumeDialog.instance.show()
81 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
83 self.hideVolTimer.start(3000, True)
86 self.volumeDialog.instance.hide()
89 eDVBVolumecontrol.getInstance().volumeToggleMute()
90 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
92 if (eDVBVolumecontrol.getInstance().isMuted()):
93 self.muteDialog.instance.show()
95 self.muteDialog.instance.hide()
99 self.dishDialog = self.session.instantiateDialog(Dish)
100 self.onShown.append(self.dishDialog.instance.hide)
102 class InfoBarShowHide:
103 """ InfoBar show/hide control, accepts toggleShow and hide actions, might start
104 fancy animations. """
111 self["ShowHideActions"] = ActionMap( ["InfobarShowHideActions"] ,
113 "toggleShow": self.toggleShow,
117 self.state = self.STATE_SHOWN
119 self.onExecBegin.append(self.show)
120 self.onClose.append(self.delHideTimer)
122 self.hideTimer = eTimer()
123 self.hideTimer.timeout.get().append(self.doTimerHide)
124 self.hideTimer.start(5000, True)
126 def delHideTimer(self):
133 self.state = self.STATE_SHOWN
134 self.hideTimer.start(5000, True)
136 def doTimerHide(self):
137 self.hideTimer.stop()
138 if self.state == self.STATE_SHOWN:
140 self.state = self.STATE_HIDDEN
142 def toggleShow(self):
143 if self.state == self.STATE_SHOWN:
145 #pls check animation support, sorry
147 self.hideTimer.stop()
148 self.state = self.STATE_HIDDEN
149 elif self.state == self.STATE_HIDDEN:
154 self.instance.m_animation.startMoveAnimation(ePoint(0, 600), ePoint(0, 380), 100)
155 self.state = self.STATE_SHOWN
158 self.instance.m_animation.startMoveAnimation(ePoint(0, 380), ePoint(0, 600), 100)
159 self.state = self.STATE_HIDDEN
161 class NumberZap(Screen):
168 self.close(int(self["number"].getText()))
170 def keyNumberGlobal(self, number):
171 self.Timer.start(3000, True) #reset timer
172 self.field = self.field + str(number)
173 self["number"].setText(self.field)
174 if len(self.field) >= 4:
177 def __init__(self, session, number):
178 Screen.__init__(self, session)
179 self.field = str(number)
181 self["channel"] = Label(_("Channel:"))
183 self["number"] = Label(self.field)
185 self["actions"] = NumberActionMap( [ "SetupActions" ],
189 "1": self.keyNumberGlobal,
190 "2": self.keyNumberGlobal,
191 "3": self.keyNumberGlobal,
192 "4": self.keyNumberGlobal,
193 "5": self.keyNumberGlobal,
194 "6": self.keyNumberGlobal,
195 "7": self.keyNumberGlobal,
196 "8": self.keyNumberGlobal,
197 "9": self.keyNumberGlobal,
198 "0": self.keyNumberGlobal
201 self.Timer = eTimer()
202 self.Timer.timeout.get().append(self.keyOK)
203 self.Timer.start(3000, True)
205 class InfoBarPowerKey:
206 """ PowerKey stuff - handles the powerkey press and powerkey release actions"""
209 self.powerKeyTimer = eTimer()
210 self.powerKeyTimer.timeout.get().append(self.powertimer)
211 self["PowerKeyActions"] = HelpableActionMap(self, "PowerKeyActions",
213 "powerdown": self.powerdown,
214 "powerup": self.powerup,
215 "discreteStandby": (self.standby, "Go standby"),
216 "discretePowerOff": (self.quit, "Go to deep standby"),
219 def powertimer(self):
220 print "PowerOff - Now!"
224 self.standbyblocked = 0
225 self.powerKeyTimer.start(3000, True)
228 self.powerKeyTimer.stop()
229 if self.standbyblocked == 0:
230 self.standbyblocked = 1
234 self.session.open(Standby, self)
240 class InfoBarNumberZap:
241 """ Handles an initial number for NumberZapping """
243 self["NumberZapActions"] = NumberActionMap( [ "NumberZapActions"],
245 "1": self.keyNumberGlobal,
246 "2": self.keyNumberGlobal,
247 "3": self.keyNumberGlobal,
248 "4": self.keyNumberGlobal,
249 "5": self.keyNumberGlobal,
250 "6": self.keyNumberGlobal,
251 "7": self.keyNumberGlobal,
252 "8": self.keyNumberGlobal,
253 "9": self.keyNumberGlobal,
254 "0": self.keyNumberGlobal,
257 def keyNumberGlobal(self, number):
258 # print "You pressed number " + str(number)
260 self.session.nav.zapLast()
264 self.session.openWithCallback(self.numberEntered, NumberZap, number)
266 def numberEntered(self, retval):
267 # print self.servicelist
269 self.zapToNumber(retval)
271 def searchNumberHelper(self, serviceHandler, num, bouquet):
272 servicelist = serviceHandler.list(bouquet)
273 if not servicelist is None:
275 serviceIterator = servicelist.getNext()
276 if not serviceIterator.valid(): #check end of list
278 if serviceIterator.flags: #assume normal dvb service have no flags set
281 if not num: #found service with searched number ?
282 return serviceIterator, 0
285 def zapToNumber(self, number):
286 bouquet = self.servicelist.bouquet_root
288 serviceHandler = eServiceCenter.getInstance()
289 if bouquet.toString().find('FROM BOUQUET "bouquets.') == -1: #FIXME HACK
290 service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
292 bouquetlist = serviceHandler.list(bouquet)
293 if not bouquetlist is None:
295 bouquet = self.servicelist.appendDVBTypes(bouquetlist.getNext())
296 if not bouquet.valid(): #check end of list
298 if ((bouquet.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
300 service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
301 if not service is None:
302 self.session.nav.playService(service) #play service
303 if self.servicelist.getRoot() != bouquet: #already in correct bouquet?
304 self.servicelist.setRoot(bouquet)
305 self.servicelist.setCurrentSelection(service) #select the service in servicelist
307 class InfoBarChannelSelection:
308 """ ChannelSelection - handles the channelSelection dialog and the initial
309 channelChange actions which open the channelSelection dialog """
312 self.servicelist = self.session.instantiateDialog(ChannelSelection)
314 self["ChannelSelectActions"] = HelpableActionMap(self, "InfobarChannelSelection",
316 "switchChannelUp": self.switchChannelUp,
317 "switchChannelDown": self.switchChannelDown,
318 "zapUp": (self.zapUp, _("next channel")),
319 "zapDown": (self.zapDown, _("previous channel")),
322 def switchChannelUp(self):
323 self.servicelist.moveUp()
324 self.session.execDialog(self.servicelist)
326 def switchChannelDown(self):
327 self.servicelist.moveDown()
328 self.session.execDialog(self.servicelist)
331 self.servicelist.moveUp()
332 self.servicelist.zap()
337 self.servicelist.moveDown()
338 self.servicelist.zap()
343 """ Handles a menu action, to open the (main) menu """
345 self["MenuActions"] = HelpableActionMap(self, "InfobarMenuActions",
347 "mainMenu": (self.mainMenu, "Enter main menu..."),
351 print "loading mainmenu XML..."
352 menu = mdom.childNodes[0]
353 assert menu.tagName == "menu", "root element in menu must be 'menu'!"
354 self.session.open(MainMenu, menu, menu.childNodes)
357 """ EPG - Opens an EPG list when the showEPGList action fires """
359 self["EPGActions"] = HelpableActionMap(self, "InfobarEPGActions",
361 "showEPGList": (self.showEPGList, _("show EPG...")),
364 def showEPGList(self):
365 bouquets = self.servicelist.getBouquetList()
370 if cnt > 1: # show bouquet list
371 self.session.open(BouquetSelector, bouquets, self.openBouquetEPG)
372 elif cnt == 1: # add to only one existing bouquet
373 self.openBouquetEPG(bouquets[0][1])
374 else: #no bouquets so we open single epg
375 self.openSingleEPGSelector(self.session.nav.getCurrentlyPlayingServiceReference())
377 def bouquetEPGCallback(self, info):
379 self.openSingleServiceEPG()
381 def singleEPGCallback(self, info):
385 def openEventView(self):
388 service = self.session.nav.getCurrentService()
389 info = service.info()
392 self.epglist.append(ptr)
395 self.epglist.append(ptr)
396 if len(self.epglist) > 0:
397 self.session.open(EventView, self.epglist[0], ServiceReference(ref), self.eventViewCallback)
401 def openSingleServiceEPG(self):
402 ref=self.session.nav.getCurrentlyPlayingServiceReference()
403 ptr=eEPGCache.getInstance()
404 if ptr.startTimeQuery(ref) != -1:
405 self.session.openWithCallback(self.singleEPGCallback, EPGSelection, ref)
406 else: # try to show now/next
407 print 'no epg for service', ref.toString()
410 def openBouquetEPG(self, bouquet):
411 ptr=eEPGCache.getInstance()
413 servicelist = eServiceCenter.getInstance().list(bouquet)
414 if not servicelist is None:
416 service = servicelist.getNext()
417 if not service.valid(): #check if end of list
419 if service.flags: #ignore non playable services
421 services.append(ServiceReference(service))
423 self.session.openWithCallback(self.bouquetEPGCallback, EPGSelection, services)
425 def openSingleEPGSelector(self, ref):
426 ptr=eEPGCache.getInstance()
427 if ptr.startTimeQuery(ref) != -1:
428 self.session.open(EPGSelection, ref)
429 else: # try to show now/next
430 print 'no epg for service', ref.toString()
433 service = self.session.nav.getCurrentService()
434 info = service.info()
437 self.epglist.append(ptr)
440 self.epglist.append(ptr)
441 if len(self.epglist) > 0:
442 self.session.open(EventView, self.epglist[0], ServiceReference(ref), self.eventViewCallback)
446 def eventViewCallback(self, setEvent, setService, val): #used for now/next displaying
447 if len(self.epglist) > 1:
448 tmp = self.epglist[0]
449 self.epglist[0]=self.epglist[1]
451 setEvent(self.epglist[0])
456 """provides a snr/agc/ber display"""
458 self["snr"] = Label()
459 self["agc"] = Label()
460 self["ber"] = Label()
461 self["snr_percent"] = Label()
462 self["agc_percent"] = Label()
463 self["ber_count"] = Label()
464 self["snr_progress"] = ProgressBar()
465 self["agc_progress"] = ProgressBar()
466 self["ber_progress"] = ProgressBar()
467 self.timer = eTimer()
468 self.timer.timeout.get().append(self.updateTunerInfo)
469 self.timer.start(1000)
475 return (long)(log(val)/log(2))
478 def updateTunerInfo(self):
479 if self.instance.isVisible():
480 service = self.session.nav.getCurrentService()
484 if service is not None:
485 feinfo = service.frontendStatusInfo()
486 if feinfo is not None:
487 ber=feinfo.getFrontendInfo(iFrontendStatusInformation.bitErrorRate)
488 snr=feinfo.getFrontendInfo(iFrontendStatusInformation.signalPower)*100/65536
489 agc=feinfo.getFrontendInfo(iFrontendStatusInformation.signalQuality)*100/65536
490 self["snr_percent"].setText("%d%%"%(snr))
491 self["agc_percent"].setText("%d%%"%(agc))
492 self["ber_count"].setText("%d"%(ber))
493 self["snr_progress"].setValue(snr)
494 self["agc_progress"].setValue(agc)
495 self["ber_progress"].setValue(self.calc(ber))
498 """provides a current/next event info display"""
500 self["Event_Now_StartTime"] = EventInfo(self.session.nav, EventInfo.Now_StartTime)
501 self["Event_Next_StartTime"] = EventInfo(self.session.nav, EventInfo.Next_StartTime)
503 self["Event_Now"] = EventInfo(self.session.nav, EventInfo.Now)
504 self["Event_Next"] = EventInfo(self.session.nav, EventInfo.Next)
506 self["Event_Now_Duration"] = EventInfo(self.session.nav, EventInfo.Now_Duration)
507 self["Event_Next_Duration"] = EventInfo(self.session.nav, EventInfo.Next_Duration)
509 class InfoBarServiceName:
511 self["ServiceName"] = ServiceName(self.session.nav)
515 # ispause, isff, issm, skip
516 SEEK_STATE_PLAY = (0, 0, 0, 0)
517 SEEK_STATE_PAUSE = (1, 0, 0, 0)
518 SEEK_STATE_FF_2X = (0, 2, 0, 0)
519 SEEK_STATE_FF_4X = (0, 4, 0, 0)
520 SEEK_STATE_FF_8X = (0, 8, 0, 0)
521 SEEK_STATE_FF_32X = (0, 4, 0, 32)
522 SEEK_STATE_FF_64X = (0, 4, 0, 64)
523 SEEK_STATE_FF_128X = (0, 4, 0, 128)
525 SEEK_STATE_BACK_4X = (0, 0, 0, -4)
526 SEEK_STATE_BACK_32X = (0, 0, 0, -32)
527 SEEK_STATE_BACK_64X = (0, 0, 0, -64)
528 SEEK_STATE_BACK_128X = (0, 0, 0, -128)
530 SEEK_STATE_SM_HALF = (0, 0, 2, 0)
531 SEEK_STATE_SM_QUARTER = (0, 0, 4, 0)
532 SEEK_STATE_SM_EIGHTH = (0, 0, 8, 0)
534 """handles PVR specific actions like seeking, pause"""
536 self["PVRActions"] = HelpableActionMap(self, "InfobarPVRActions",
538 "pauseService": (self.pauseService, "pause"),
539 "unPauseService": (self.unPauseService, "continue"),
541 "seekFwd": (self.seekFwd, "skip forward"),
542 "seekFwdUp": (self.seekFwdUp, "skip forward"),
543 "seekBack": (self.seekBack, "skip backward"),
544 "seekBackUp": (self.seekBackUp, "skip backward"),
546 "up": (self.showMovies, "movie list"),
547 "down": (self.showMovies, "movie list")
550 self.seekstate = self.SEEK_STATE_PLAY
551 self.seekTimer = eTimer()
552 self.seekTimer.timeout.get().append(self.seekTimerFired)
553 self.skipinterval = 500 # 500ms skip interval
554 self.onClose.append(self.delSeekTimer)
556 self.fwdtimer = False
557 self.fwdKeyTimer = eTimer()
558 self.fwdKeyTimer.timeout.get().append(self.fwdTimerFire)
560 self.rwdtimer = False
561 self.rwdKeyTimer = eTimer()
562 self.rwdKeyTimer.timeout.get().append(self.rwdTimerFire)
570 def delSeekTimer(self):
573 def seekTimerFired(self):
574 self.seekbase += self.skipmode * self.skipinterval
576 # check if we bounced against the beginning of the file
577 if self.seekbase < 0:
579 self.setSeekState(self.SEEK_STATE_PLAY)
581 self.doSeek(self.seekbase)
583 def setSeekState(self, state):
584 oldstate = self.seekstate
586 self.seekstate = state
588 service = self.session.nav.getCurrentService()
592 pauseable = service.pause()
595 if oldstate[i] != self.seekstate[i]:
596 (self.session.nav.pause, pauseable.setFastForward, pauseable.setSlowMotion, self.setSkipMode)[i](self.seekstate[i])
598 def setSkipMode(self, skipmode):
599 self.skipmode = skipmode
601 self.seekTimer.stop()
603 self.seekTimer.start(500)
605 service = self.session.nav.getCurrentService()
609 seekable = service.seek()
614 seekable.setTrickmode(1)
616 seekable.setTrickmode(0)
618 self.seekbase = seekable.getPlayPosition()[1] / 90
620 def pauseService(self):
621 if (self.seekstate == self.SEEK_STATE_PAUSE):
622 self.unPauseService()
624 self.setSeekState(self.SEEK_STATE_PAUSE);
626 def unPauseService(self):
627 self.setSeekState(self.SEEK_STATE_PLAY);
629 def doSeek(self, seektime):
630 service = self.session.nav.getCurrentService()
634 seekable = service.seek()
637 seekable.seekTo(90 * seektime)
640 print "start fwd timer"
642 self.fwdKeyTimer.start(500)
645 print "start rewind timer"
647 self.rwdKeyTimer.start(500)
651 self.fwdKeyTimer.stop()
652 self.fwdtimer = False
654 self.SEEK_STATE_PLAY: self.SEEK_STATE_FF_2X,
655 self.SEEK_STATE_PAUSE: self.SEEK_STATE_SM_EIGHTH,
656 self.SEEK_STATE_FF_2X: self.SEEK_STATE_FF_4X,
657 self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_8X,
658 self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_32X,
659 self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_64X,
660 self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_128X,
661 self.SEEK_STATE_FF_128X: self.SEEK_STATE_FF_128X,
662 self.SEEK_STATE_BACK_4X: self.SEEK_STATE_PLAY,
663 self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_4X,
664 self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_32X,
665 self.SEEK_STATE_BACK_128X: self.SEEK_STATE_BACK_64X,
666 self.SEEK_STATE_SM_HALF: self.SEEK_STATE_SM_HALF,
667 self.SEEK_STATE_SM_QUARTER: self.SEEK_STATE_SM_HALF,
668 self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_SM_QUARTER
670 self.setSeekState(lookup[self.seekstate]);
672 def seekBackUp(self):
674 self.rwdKeyTimer.stop()
675 self.rwdtimer = False
678 self.SEEK_STATE_PLAY: self.SEEK_STATE_BACK_4X,
679 self.SEEK_STATE_PAUSE: self.SEEK_STATE_PAUSE,
680 self.SEEK_STATE_FF_2X: self.SEEK_STATE_PLAY,
681 self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_2X,
682 self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_4X,
683 self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_8X,
684 self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_32X,
685 self.SEEK_STATE_FF_128X: self.SEEK_STATE_FF_64X,
686 self.SEEK_STATE_BACK_4X: self.SEEK_STATE_BACK_32X,
687 self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_64X,
688 self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_128X,
689 self.SEEK_STATE_BACK_128X: self.SEEK_STATE_BACK_128X,
690 self.SEEK_STATE_SM_HALF: self.SEEK_STATE_SM_QUARTER,
691 self.SEEK_STATE_SM_QUARTER: self.SEEK_STATE_SM_EIGHTH,
692 self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_PAUSE
694 self.setSeekState(lookup[self.seekstate]);
696 def fwdTimerFire(self):
697 print "Display seek fwd"
698 self.fwdKeyTimer.stop()
699 self.fwdtimer = False
700 self.session.openWithCallback(self.fwdSeekTo, MinuteInput)
702 def fwdSeekTo(self, minutes):
703 print "Seek", minutes, "minutes forward"
705 service = self.session.nav.getCurrentService()
708 seekable = service.seek()
711 seekable.seekRelative(1, minutes * 60 * 90000)
713 def rwdTimerFire(self):
714 self.rwdKeyTimer.stop()
715 self.rwdtimer = False
716 self.session.openWithCallback(self.rwdSeekTo, MinuteInput)
718 def rwdSeekTo(self, minutes):
719 self.fwdSeekTo(0 - minutes)
721 from RecordTimer import parseEvent
723 class InfoBarInstantRecord:
724 """Instant Record - handles the instantRecord action in order to
725 start/stop instant records"""
727 self["InstantRecordActions"] = HelpableActionMap(self, "InfobarInstantRecord",
729 "instantRecord": (self.instantRecord, "Instant Record..."),
731 self.recording = None
733 self["BlinkingPoint"] = BlinkingPixmapConditional()
734 self.onShown.append(self["BlinkingPoint"].hideWidget)
735 self["BlinkingPoint"].setConnect(self.session.nav.RecordTimer.isRecording)
737 def stopCurrentRecording(self):
738 self.session.nav.RecordTimer.removeEntry(self.recording)
739 self.recording = None
741 def startInstantRecording(self):
742 serviceref = self.session.nav.getCurrentlyPlayingServiceReference()
744 # try to get event info
747 service = self.session.nav.getCurrentService()
748 info = service.info()
749 ev = info.getEvent(0)
754 if event is not None:
755 data = parseEvent(event)
756 data = (data[0], data[1] + 3600 * 10, data[2], data[3], data[4])
758 data = (time.time(), time.time() + 3600 * 10, "instant record", "", None)
760 # fix me, description.
761 self.recording = self.session.nav.recordWithTimer(serviceref, *data)
762 self.recording.dontSave = True
764 #self["BlinkingPoint"].setConnect(lambda: self.recording.isRunning())
766 def isInstantRecordRunning(self):
767 if self.recording != None:
768 if self.recording.isRunning():
772 def recordQuestionCallback(self, answer):
776 if self.isInstantRecordRunning():
777 self.stopCurrentRecording()
779 self.startInstantRecording()
781 def instantRecord(self):
783 stat = os.stat(resolveFilename(SCOPE_HDD))
785 self.session.open(MessageBox, _("No HDD found or HDD not initialized!"), MessageBox.TYPE_ERROR)
788 if self.isInstantRecordRunning():
789 self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Do you want to stop the current\n(instant) recording?"))
791 self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Start recording?"))
793 from Screens.AudioSelection import AudioSelection
795 class InfoBarAudioSelection:
797 self["AudioSelectionAction"] = HelpableActionMap(self, "InfobarAudioSelectionActions",
799 "audioSelection": (self.audioSelection, "Audio Options..."),
802 def audioSelection(self):
803 service = self.session.nav.getCurrentService()
804 audio = service.audioTracks()
805 n = audio.getNumberOfTracks()
807 self.session.open(AudioSelection, audio)
809 from Screens.SubserviceSelection import SubserviceSelection
811 class InfoBarSubserviceSelection:
813 self["SubserviceSelectionAction"] = HelpableActionMap(self, "InfobarSubserviceSelectionActions",
815 "subserviceSelection": (self.subserviceSelection, "Subservice list..."),
818 def subserviceSelection(self):
819 service = self.session.nav.getCurrentService()
820 subservices = service.subServices()
821 n = subservices.getNumberOfSubservices()
823 self.session.openWithCallback(self.subserviceSelected, SubserviceSelection, subservices)
825 def subserviceSelected(self, service):
826 if not service is None:
827 self.session.nav.playService(service)
829 class InfoBarAdditionalInfo:
831 self["DolbyActive"] = Pixmap()
832 self["CryptActive"] = Pixmap()
833 self["FormatActive"] = Pixmap()
835 self["ButtonRed"] = PixmapConditional(withTimer = False)
836 self["ButtonRed"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
837 self.onShown.append(self["ButtonRed"].update)
838 self["ButtonRedText"] = LabelConditional(text = _("Record"), withTimer = False)
839 self["ButtonRedText"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
840 self.onShown.append(self["ButtonRedText"].update)
842 self["ButtonGreen"] = Pixmap()
843 self["ButtonGreenText"] = Label(_("Subservices"))
845 self["ButtonYellow"] = PixmapConditional(withTimer = False)
846 self["ButtonYellow"].setConnect(lambda: False)
848 self["ButtonBlue"] = PixmapConditional(withTimer = False)
849 self["ButtonBlue"].setConnect(lambda: False)
851 self.session.nav.event.append(self.gotServiceEvent) # we like to get service events
853 def hideSubServiceIndication(self):
854 self["ButtonGreen"].hideWidget()
855 self["ButtonGreenText"].hide()
857 def showSubServiceIndication(self):
858 self["ButtonGreen"].showWidget()
859 self["ButtonGreenText"].show()
861 def checkFormat(self, service):
862 info = service.info()
864 aspect = info.getInfo(iServiceInformation.sAspect)
865 if aspect in [ 3, 4, 7, 8, 0xB, 0xC, 0xF, 0x10 ]:
866 self["FormatActive"].showWidget()
868 self["FormatActive"].hideWidget()
870 def checkSubservices(self, service):
871 if service.subServices().getNumberOfSubservices() > 0:
872 self.showSubServiceIndication()
874 self.hideSubServiceIndication()
876 def checkDolby(self, service):
878 audio = service.audioTracks()
879 if audio is not None:
880 n = audio.getNumberOfTracks()
882 i = audio.getTrackInfo(x)
883 description = i.getDescription();
884 if description.find("AC3") != -1 or description.find("DTS") != -1:
888 self["DolbyActive"].showWidget()
890 self["DolbyActive"].hideWidget()
892 def checkCrypted(self, service):
893 info = service.info()
895 if info.getInfo(iServiceInformation.sIsCrypted) > 0:
896 self["CryptActive"].showWidget()
898 self["CryptActive"].hideWidget()
900 def gotServiceEvent(self, ev):
901 service = self.session.nav.getCurrentService()
902 if ev == pNavigation.evUpdatedEventInfo:
903 self.checkSubservices(service)
904 self.checkFormat(service)
905 elif ev == pNavigation.evUpdatedInfo:
906 self.checkCrypted(service)
907 self.checkDolby(service)
908 elif ev == pNavigation.evStopService:
909 self.hideSubServiceIndication()
910 self["CryptActive"].hideWidget()
911 self["DolbyActive"].hideWidget()
912 self["FormatActive"].hideWidget()
914 class InfoBarNotifications:
916 self.onExecBegin.append(self.checkNotifications)
917 Notifications.notificationAdded.append(self.checkNotificationsIfExecing)
919 def checkNotificationsIfExecing(self):
921 self.checkNotifications()
923 def checkNotifications(self):
924 if len(Notifications.notifications):
925 n = Notifications.notifications[0]
926 Notifications.notifications = Notifications.notifications[1:]
930 self.session.openWithCallback(cb, *n[1:])
932 self.session.open(*n[1:])