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 = 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.openSingleServiceEPG, _("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 openSingleServiceEPG(self):
386 ref=self.session.nav.getCurrentlyPlayingServiceReference()
387 ptr=eEPGCache.getInstance()
388 if ptr.startTimeQuery(ref) != -1:
389 self.session.openWithCallback(self.singleEPGCallback, EPGSelection, ref)
390 else: # try to show now/next
391 print 'no epg for service', ref.toString()
394 service = self.session.nav.getCurrentService()
395 info = service.info()
398 self.epglist.append(ptr)
401 self.epglist.append(ptr)
402 if len(self.epglist) > 0:
403 self.session.open(EventView, self.epglist[0], ServiceReference(ref), self.eventViewCallback)
407 def openBouquetEPG(self, bouquet):
408 ptr=eEPGCache.getInstance()
410 servicelist = eServiceCenter.getInstance().list(bouquet)
411 if not servicelist is None:
413 service = servicelist.getNext()
414 if not service.valid(): #check if end of list
416 if service.flags: #ignore non playable services
418 services.append(ServiceReference(service))
420 self.session.openWithCallback(self.bouquetEPGCallback, EPGSelection, services)
422 def openSingleEPGSelector(self, ref):
423 ptr=eEPGCache.getInstance()
424 if ptr.startTimeQuery(ref) != -1:
425 self.session.open(EPGSelection, ref)
426 else: # try to show now/next
427 print 'no epg for service', ref.toString()
430 service = self.session.nav.getCurrentService()
431 info = service.info()
434 self.epglist.append(ptr)
437 self.epglist.append(ptr)
438 if len(self.epglist) > 0:
439 self.session.open(EventView, self.epglist[0], ServiceReference(ref), self.eventViewCallback)
443 def eventViewCallback(self, setEvent, setService, val): #used for now/next displaying
444 if len(self.epglist) > 1:
445 tmp = self.epglist[0]
446 self.epglist[0]=self.epglist[1]
448 setEvent(self.epglist[0])
453 """provides a snr/agc/ber display"""
455 self["snr"] = Label()
456 self["agc"] = Label()
457 self["ber"] = Label()
458 self["snr_percent"] = Label()
459 self["agc_percent"] = Label()
460 self["ber_count"] = Label()
461 self["snr_progress"] = ProgressBar()
462 self["agc_progress"] = ProgressBar()
463 self["ber_progress"] = ProgressBar()
464 self.timer = eTimer()
465 self.timer.timeout.get().append(self.updateTunerInfo)
466 self.timer.start(1000)
472 return (long)(log(val)/log(2))
475 def updateTunerInfo(self):
476 if self.instance.isVisible():
477 service = self.session.nav.getCurrentService()
481 if service is not None:
482 feinfo = service.frontendStatusInfo()
483 if feinfo is not None:
484 ber=feinfo.getFrontendInfo(iFrontendStatusInformation.bitErrorRate)
485 snr=feinfo.getFrontendInfo(iFrontendStatusInformation.signalPower)*100/65536
486 agc=feinfo.getFrontendInfo(iFrontendStatusInformation.signalQuality)*100/65536
487 self["snr_percent"].setText("%d%%"%(snr))
488 self["agc_percent"].setText("%d%%"%(agc))
489 self["ber_count"].setText("%d"%(ber))
490 self["snr_progress"].setValue(snr)
491 self["agc_progress"].setValue(agc)
492 self["ber_progress"].setValue(self.calc(ber))
495 """provides a current/next event info display"""
497 self["Event_Now_StartTime"] = EventInfo(self.session.nav, EventInfo.Now_StartTime)
498 self["Event_Next_StartTime"] = EventInfo(self.session.nav, EventInfo.Next_StartTime)
500 self["Event_Now"] = EventInfo(self.session.nav, EventInfo.Now)
501 self["Event_Next"] = EventInfo(self.session.nav, EventInfo.Next)
503 self["Event_Now_Duration"] = EventInfo(self.session.nav, EventInfo.Now_Duration)
504 self["Event_Next_Duration"] = EventInfo(self.session.nav, EventInfo.Next_Duration)
506 class InfoBarServiceName:
508 self["ServiceName"] = ServiceName(self.session.nav)
512 # ispause, isff, issm, skip
513 SEEK_STATE_PLAY = (0, 0, 0, 0)
514 SEEK_STATE_PAUSE = (1, 0, 0, 0)
515 SEEK_STATE_FF_2X = (0, 2, 0, 0)
516 SEEK_STATE_FF_4X = (0, 4, 0, 0)
517 SEEK_STATE_FF_8X = (0, 8, 0, 0)
518 SEEK_STATE_FF_32X = (0, 4, 0, 32)
519 SEEK_STATE_FF_64X = (0, 4, 0, 64)
520 SEEK_STATE_FF_128X = (0, 4, 0, 128)
522 SEEK_STATE_BACK_4X = (0, 0, 0, -4)
523 SEEK_STATE_BACK_32X = (0, 0, 0, -32)
524 SEEK_STATE_BACK_64X = (0, 0, 0, -64)
525 SEEK_STATE_BACK_128X = (0, 0, 0, -128)
527 SEEK_STATE_SM_HALF = (0, 0, 2, 0)
528 SEEK_STATE_SM_QUARTER = (0, 0, 4, 0)
529 SEEK_STATE_SM_EIGHTH = (0, 0, 8, 0)
531 """handles PVR specific actions like seeking, pause"""
533 self["PVRActions"] = HelpableActionMap(self, "InfobarPVRActions",
535 "pauseService": (self.pauseService, "pause"),
536 "unPauseService": (self.unPauseService, "continue"),
538 "seekFwd": (self.seekFwd, "skip forward"),
539 "seekFwdUp": (self.seekFwdUp, "skip forward"),
540 "seekBack": (self.seekBack, "skip backward"),
541 "seekBackUp": (self.seekBackUp, "skip backward"),
543 "up": (self.showMovies, "movie list"),
544 "down": (self.showMovies, "movie list")
547 self.seekstate = self.SEEK_STATE_PLAY
548 self.seekTimer = eTimer()
549 self.seekTimer.timeout.get().append(self.seekTimerFired)
550 self.skipinterval = 500 # 500ms skip interval
551 self.onClose.append(self.delSeekTimer)
553 self.fwdtimer = False
554 self.fwdKeyTimer = eTimer()
555 self.fwdKeyTimer.timeout.get().append(self.fwdTimerFire)
557 self.rwdtimer = False
558 self.rwdKeyTimer = eTimer()
559 self.rwdKeyTimer.timeout.get().append(self.rwdTimerFire)
567 def delSeekTimer(self):
570 def seekTimerFired(self):
571 self.seekbase += self.skipmode * self.skipinterval
573 # check if we bounced against the beginning of the file
574 if self.seekbase < 0:
576 self.setSeekState(self.SEEK_STATE_PLAY)
578 self.doSeek(self.seekbase)
580 def setSeekState(self, state):
581 oldstate = self.seekstate
583 self.seekstate = state
585 service = self.session.nav.getCurrentService()
589 pauseable = service.pause()
592 if oldstate[i] != self.seekstate[i]:
593 (self.session.nav.pause, pauseable.setFastForward, pauseable.setSlowMotion, self.setSkipMode)[i](self.seekstate[i])
595 def setSkipMode(self, skipmode):
596 self.skipmode = skipmode
598 self.seekTimer.stop()
600 self.seekTimer.start(500)
602 service = self.session.nav.getCurrentService()
606 seekable = service.seek()
611 seekable.setTrickmode(1)
613 seekable.setTrickmode(0)
615 self.seekbase = seekable.getPlayPosition()[1] / 90
617 def pauseService(self):
618 if (self.seekstate == self.SEEK_STATE_PAUSE):
619 self.unPauseService()
621 self.setSeekState(self.SEEK_STATE_PAUSE);
623 def unPauseService(self):
624 self.setSeekState(self.SEEK_STATE_PLAY);
626 def doSeek(self, seektime):
627 service = self.session.nav.getCurrentService()
631 seekable = service.seek()
634 seekable.seekTo(90 * seektime)
637 print "start fwd timer"
639 self.fwdKeyTimer.start(500)
642 print "start rewind timer"
644 self.rwdKeyTimer.start(500)
648 self.fwdKeyTimer.stop()
649 self.fwdtimer = False
651 self.SEEK_STATE_PLAY: self.SEEK_STATE_FF_2X,
652 self.SEEK_STATE_PAUSE: self.SEEK_STATE_SM_EIGHTH,
653 self.SEEK_STATE_FF_2X: self.SEEK_STATE_FF_4X,
654 self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_8X,
655 self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_32X,
656 self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_64X,
657 self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_128X,
658 self.SEEK_STATE_FF_128X: self.SEEK_STATE_FF_128X,
659 self.SEEK_STATE_BACK_4X: self.SEEK_STATE_PLAY,
660 self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_4X,
661 self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_32X,
662 self.SEEK_STATE_BACK_128X: self.SEEK_STATE_BACK_64X,
663 self.SEEK_STATE_SM_HALF: self.SEEK_STATE_SM_HALF,
664 self.SEEK_STATE_SM_QUARTER: self.SEEK_STATE_SM_HALF,
665 self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_SM_QUARTER
667 self.setSeekState(lookup[self.seekstate]);
669 def seekBackUp(self):
671 self.rwdKeyTimer.stop()
672 self.rwdtimer = False
675 self.SEEK_STATE_PLAY: self.SEEK_STATE_BACK_4X,
676 self.SEEK_STATE_PAUSE: self.SEEK_STATE_PAUSE,
677 self.SEEK_STATE_FF_2X: self.SEEK_STATE_PLAY,
678 self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_2X,
679 self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_4X,
680 self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_8X,
681 self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_32X,
682 self.SEEK_STATE_FF_128X: self.SEEK_STATE_FF_64X,
683 self.SEEK_STATE_BACK_4X: self.SEEK_STATE_BACK_32X,
684 self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_64X,
685 self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_128X,
686 self.SEEK_STATE_BACK_128X: self.SEEK_STATE_BACK_128X,
687 self.SEEK_STATE_SM_HALF: self.SEEK_STATE_SM_QUARTER,
688 self.SEEK_STATE_SM_QUARTER: self.SEEK_STATE_SM_EIGHTH,
689 self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_PAUSE
691 self.setSeekState(lookup[self.seekstate]);
693 def fwdTimerFire(self):
694 print "Display seek fwd"
695 self.fwdKeyTimer.stop()
696 self.fwdtimer = False
697 self.session.openWithCallback(self.fwdSeekTo, MinuteInput)
699 def fwdSeekTo(self, minutes):
700 print "Seek", minutes, "minutes forward"
702 service = self.session.nav.getCurrentService()
705 seekable = service.seek()
708 seekable.seekRelative(1, minutes * 60 * 90000)
710 def rwdTimerFire(self):
711 self.rwdKeyTimer.stop()
712 self.rwdtimer = False
713 self.session.openWithCallback(self.rwdSeekTo, MinuteInput)
715 def rwdSeekTo(self, minutes):
716 self.fwdSeekTo(0 - minutes)
718 from RecordTimer import parseEvent
720 class InfoBarInstantRecord:
721 """Instant Record - handles the instantRecord action in order to
722 start/stop instant records"""
724 self["InstantRecordActions"] = HelpableActionMap(self, "InfobarInstantRecord",
726 "instantRecord": (self.instantRecord, "Instant Record..."),
728 self.recording = None
730 self["BlinkingPoint"] = BlinkingPixmapConditional()
731 self.onShown.append(self["BlinkingPoint"].hideWidget)
732 self["BlinkingPoint"].setConnect(self.session.nav.RecordTimer.isRecording)
734 def stopCurrentRecording(self):
735 self.session.nav.RecordTimer.removeEntry(self.recording)
736 self.recording = None
738 def startInstantRecording(self):
739 serviceref = self.session.nav.getCurrentlyPlayingServiceReference()
741 # try to get event info
744 service = self.session.nav.getCurrentService()
745 info = service.info()
746 ev = info.getEvent(0)
751 if event is not None:
752 data = parseEvent(event)
753 data = (data[0], data[1] + 3600 * 10, data[2], data[3], data[4])
755 data = (time.time(), time.time() + 3600 * 10, "instant record", "", None)
757 # fix me, description.
758 self.recording = self.session.nav.recordWithTimer(serviceref, *data)
759 self.recording.dontSave = True
761 #self["BlinkingPoint"].setConnect(lambda: self.recording.isRunning())
763 def isInstantRecordRunning(self):
764 if self.recording != None:
765 if self.recording.isRunning():
769 def recordQuestionCallback(self, answer):
773 if self.isInstantRecordRunning():
774 self.stopCurrentRecording()
776 self.startInstantRecording()
778 def instantRecord(self):
780 stat = os.stat(resolveFilename(SCOPE_HDD))
782 self.session.open(MessageBox, _("No HDD found or HDD not initialized!"), MessageBox.TYPE_ERROR)
785 if self.isInstantRecordRunning():
786 self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Do you want to stop the current\n(instant) recording?"))
788 self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Start recording?"))
790 from Screens.AudioSelection import AudioSelection
792 class InfoBarAudioSelection:
794 self["AudioSelectionAction"] = HelpableActionMap(self, "InfobarAudioSelectionActions",
796 "audioSelection": (self.audioSelection, "Audio Options..."),
799 def audioSelection(self):
800 service = self.session.nav.getCurrentService()
801 audio = service.audioTracks()
802 n = audio.getNumberOfTracks()
804 self.session.open(AudioSelection, audio)
806 from Screens.SubserviceSelection import SubserviceSelection
808 class InfoBarSubserviceSelection:
810 self["SubserviceSelectionAction"] = HelpableActionMap(self, "InfobarSubserviceSelectionActions",
812 "subserviceSelection": (self.subserviceSelection, "Subservice list..."),
815 def subserviceSelection(self):
816 service = self.session.nav.getCurrentService()
817 subservices = service.subServices()
818 n = subservices.getNumberOfSubservices()
820 self.session.openWithCallback(self.subserviceSelected, SubserviceSelection, subservices)
822 def subserviceSelected(self, service):
823 if not service is None:
824 self.session.nav.playService(service)
826 class InfoBarAdditionalInfo:
828 self["DolbyActive"] = Pixmap()
829 self["CryptActive"] = Pixmap()
830 self["FormatActive"] = Pixmap()
832 self["ButtonRed"] = PixmapConditional(withTimer = False)
833 self["ButtonRed"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
834 self.onShown.append(self["ButtonRed"].update)
835 self["ButtonRedText"] = LabelConditional(text = _("Record"), withTimer = False)
836 self["ButtonRedText"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
837 self.onShown.append(self["ButtonRedText"].update)
839 self["ButtonGreen"] = Pixmap()
840 self["ButtonGreenText"] = Label(_("Subservices"))
842 self["ButtonYellow"] = PixmapConditional(withTimer = False)
843 self["ButtonYellow"].setConnect(lambda: False)
845 self["ButtonBlue"] = PixmapConditional(withTimer = False)
846 self["ButtonBlue"].setConnect(lambda: False)
848 self.session.nav.event.append(self.gotServiceEvent) # we like to get service events
850 def hideSubServiceIndication(self):
851 self["ButtonGreen"].hideWidget()
852 self["ButtonGreenText"].hide()
854 def showSubServiceIndication(self):
855 self["ButtonGreen"].showWidget()
856 self["ButtonGreenText"].show()
858 def checkFormat(self, service):
859 info = service.info()
861 aspect = info.getInfo(iServiceInformation.sAspect)
862 if aspect in [ 3, 4, 7, 8, 0xB, 0xC, 0xF, 0x10 ]:
863 self["FormatActive"].showWidget()
865 self["FormatActive"].hideWidget()
867 def checkSubservices(self, service):
868 if service.subServices().getNumberOfSubservices() > 0:
869 self.showSubServiceIndication()
871 self.hideSubServiceIndication()
873 def checkDolby(self, service):
875 audio = service.audioTracks()
876 if audio is not None:
877 n = audio.getNumberOfTracks()
879 i = audio.getTrackInfo(x)
880 description = i.getDescription();
881 if description.find("AC3") != -1 or description.find("DTS") != -1:
885 self["DolbyActive"].showWidget()
887 self["DolbyActive"].hideWidget()
889 def checkCrypted(self, service):
890 info = service.info()
892 if info.getInfo(iServiceInformation.sIsCrypted) > 0:
893 self["CryptActive"].showWidget()
895 self["CryptActive"].hideWidget()
897 def gotServiceEvent(self, ev):
898 service = self.session.nav.getCurrentService()
899 if ev == pNavigation.evUpdatedEventInfo:
900 self.checkSubservices(service)
901 self.checkFormat(service)
902 elif ev == pNavigation.evUpdatedInfo:
903 self.checkCrypted(service)
904 self.checkDolby(service)
905 elif ev == pNavigation.evStopService:
906 self.hideSubServiceIndication()
907 self["CryptActive"].hideWidget()
908 self["DolbyActive"].hideWidget()
909 self["FormatActive"].hideWidget()
911 class InfoBarNotifications:
913 self.onExecBegin.append(self.checkNotifications)
914 Notifications.notificationAdded.append(self.checkNotificationsIfExecing)
916 def checkNotificationsIfExecing(self):
918 self.checkNotifications()
920 def checkNotifications(self):
921 if len(Notifications.notifications):
922 n = Notifications.notifications[0]
923 Notifications.notifications = Notifications.notifications[1:]
927 self.session.openWithCallback(cb, *n[1:])
929 self.session.open(*n[1:])