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.Dish import Dish
20 from Screens.Standby import Standby
21 from Screens.EventView import EventView
22 from Screens.MinuteInput import MinuteInput
23 from Components.Harddisk import harddiskmanager
25 from Tools import Notifications
26 from Tools.Directories import *
28 #from enigma import eTimer, eDVBVolumecontrol, quitMainloop
34 from Components.config import config, currentConfigSelectionElement
37 from Menu import MainMenu, mdom
41 self.dishDialog = self.session.instantiateDialog(Dish)
42 self.onShown.append(self.dishDialog.instance.hide)
44 class InfoBarShowHide:
45 """ InfoBar show/hide control, accepts toggleShow and hide actions, might start
53 self["ShowHideActions"] = ActionMap( ["InfobarShowHideActions"] ,
55 "toggleShow": self.toggleShow,
59 self.state = self.STATE_SHOWN
61 self.onExecBegin.append(self.show)
62 self.onClose.append(self.delHideTimer)
64 self.hideTimer = eTimer()
65 self.hideTimer.timeout.get().append(self.doTimerHide)
66 self.hideTimer.start(5000, True)
68 def delHideTimer(self):
75 self.state = self.STATE_SHOWN
76 self.hideTimer.start(5000, True)
78 def doTimerHide(self):
80 if self.state == self.STATE_SHOWN:
82 self.state = self.STATE_HIDDEN
85 if self.state == self.STATE_SHOWN:
87 #pls check animation support, sorry
90 self.state = self.STATE_HIDDEN
91 elif self.state == self.STATE_HIDDEN:
96 self.instance.m_animation.startMoveAnimation(ePoint(0, 600), ePoint(0, 380), 100)
97 self.state = self.STATE_SHOWN
100 self.instance.m_animation.startMoveAnimation(ePoint(0, 380), ePoint(0, 600), 100)
101 self.state = self.STATE_HIDDEN
103 class NumberZap(Screen):
110 self.close(int(self["number"].getText()))
112 def keyNumberGlobal(self, number):
113 self.Timer.start(3000, True) #reset timer
114 self.field = self.field + str(number)
115 self["number"].setText(self.field)
116 if len(self.field) >= 4:
119 def __init__(self, session, number):
120 Screen.__init__(self, session)
121 self.field = str(number)
123 self["channel"] = Label(_("Channel:"))
125 self["number"] = Label(self.field)
127 self["actions"] = NumberActionMap( [ "SetupActions" ],
131 "1": self.keyNumberGlobal,
132 "2": self.keyNumberGlobal,
133 "3": self.keyNumberGlobal,
134 "4": self.keyNumberGlobal,
135 "5": self.keyNumberGlobal,
136 "6": self.keyNumberGlobal,
137 "7": self.keyNumberGlobal,
138 "8": self.keyNumberGlobal,
139 "9": self.keyNumberGlobal,
140 "0": self.keyNumberGlobal
143 self.Timer = eTimer()
144 self.Timer.timeout.get().append(self.keyOK)
145 self.Timer.start(3000, True)
147 class InfoBarPowerKey:
148 """ PowerKey stuff - handles the powerkey press and powerkey release actions"""
151 self.powerKeyTimer = eTimer()
152 self.powerKeyTimer.timeout.get().append(self.powertimer)
153 self["PowerKeyActions"] = HelpableActionMap(self, "PowerKeyActions",
155 "powerdown": self.powerdown,
156 "powerup": self.powerup,
157 "discreteStandby": (self.standby, "Go standby"),
158 "discretePowerOff": (self.quit, "Go to deep standby"),
161 def powertimer(self):
162 print "PowerOff - Now!"
166 self.standbyblocked = 0
167 self.powerKeyTimer.start(3000, True)
170 self.powerKeyTimer.stop()
171 if self.standbyblocked == 0:
172 self.standbyblocked = 1
176 self.session.open(Standby, self)
182 class InfoBarNumberZap:
183 """ Handles an initial number for NumberZapping """
185 self["NumberZapActions"] = NumberActionMap( [ "NumberZapActions"],
187 "1": self.keyNumberGlobal,
188 "2": self.keyNumberGlobal,
189 "3": self.keyNumberGlobal,
190 "4": self.keyNumberGlobal,
191 "5": self.keyNumberGlobal,
192 "6": self.keyNumberGlobal,
193 "7": self.keyNumberGlobal,
194 "8": self.keyNumberGlobal,
195 "9": self.keyNumberGlobal,
196 "0": self.keyNumberGlobal,
199 def keyNumberGlobal(self, number):
200 # print "You pressed number " + str(number)
202 self.session.nav.zapLast()
206 self.session.openWithCallback(self.numberEntered, NumberZap, number)
208 def numberEntered(self, retval):
209 # print self.servicelist
211 self.zapToNumber(retval)
213 def searchNumberHelper(self, serviceHandler, num, bouquet):
214 servicelist = serviceHandler.list(bouquet)
215 if not servicelist is None:
217 serviceIterator = servicelist.getNext()
218 if not serviceIterator.valid(): #check end of list
220 if serviceIterator.flags: #assume normal dvb service have no flags set
223 if not num: #found service with searched number ?
224 return serviceIterator, 0
227 def zapToNumber(self, number):
228 bouquet = self.servicelist.bouquet_root
230 serviceHandler = eServiceCenter.getInstance()
231 if bouquet.toString().find('FROM BOUQUET "bouquets.') == -1: #FIXME HACK
232 service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
234 bouquetlist = serviceHandler.list(bouquet)
235 if not bouquetlist is None:
237 bouquet = self.servicelist.appendDVBTypes(bouquetlist.getNext())
238 if not bouquet.valid(): #check end of list
240 if ((bouquet.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
242 service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
243 if not service is None:
244 self.session.nav.playService(service) #play service
245 if self.servicelist.getRoot() != bouquet: #already in correct bouquet?
246 self.servicelist.setRoot(bouquet)
247 self.servicelist.setCurrentSelection(service) #select the service in servicelist
249 class InfoBarChannelSelection:
250 """ ChannelSelection - handles the channelSelection dialog and the initial
251 channelChange actions which open the channelSelection dialog """
254 self.servicelist = self.session.instantiateDialog(ChannelSelection)
256 self["ChannelSelectActions"] = HelpableActionMap(self, "InfobarChannelSelection",
258 "switchChannelUp": self.switchChannelUp,
259 "switchChannelDown": self.switchChannelDown,
260 "zapUp": (self.zapUp, _("next channel")),
261 "zapDown": (self.zapDown, _("previous channel")),
264 def switchChannelUp(self):
265 self.servicelist.moveUp()
266 self.session.execDialog(self.servicelist)
268 def switchChannelDown(self):
269 self.servicelist.moveDown()
270 self.session.execDialog(self.servicelist)
273 self.servicelist.moveUp()
274 self.servicelist.zap()
279 self.servicelist.moveDown()
280 self.servicelist.zap()
285 """ Handles a menu action, to open the (main) menu """
287 self["MenuActions"] = HelpableActionMap(self, "InfobarMenuActions",
289 "mainMenu": (self.mainMenu, "Enter main menu..."),
293 print "loading mainmenu XML..."
294 menu = mdom.childNodes[0]
295 assert menu.tagName == "menu", "root element in menu must be 'menu'!"
296 self.session.open(MainMenu, menu, menu.childNodes)
299 """ EPG - Opens an EPG list when the showEPGList action fires """
301 self["EPGActions"] = HelpableActionMap(self, "InfobarEPGActions",
303 "showEPGList": (self.showEPG, _("show EPG...")),
307 if currentConfigSelectionElement(config.usage.epgtoggle) == "yes":
308 self.openSingleServiceEPG()
312 def showEPGList(self):
313 bouquets = self.servicelist.getBouquetList()
318 if cnt > 1: # show bouquet list
319 self.session.open(BouquetSelector, bouquets, self.openBouquetEPG)
320 elif cnt == 1: # add to only one existing bouquet
321 self.openBouquetEPG(bouquets[0][1])
322 else: #no bouquets so we open single epg
323 self.openSingleEPGSelector(self.session.nav.getCurrentlyPlayingServiceReference())
325 def bouquetEPGCallback(self, info):
327 self.openSingleServiceEPG()
329 def singleEPGCallback(self, info):
333 def openEventView(self):
336 service = self.session.nav.getCurrentService()
337 info = service.info()
340 self.epglist.append(ptr)
343 self.epglist.append(ptr)
344 if len(self.epglist) > 0:
345 self.session.open(EventView, self.epglist[0], ServiceReference(ref), self.eventViewCallback)
349 def openSingleServiceEPG(self):
350 ref=self.session.nav.getCurrentlyPlayingServiceReference()
351 ptr=eEPGCache.getInstance()
352 if ptr.startTimeQuery(ref) != -1:
353 self.session.openWithCallback(self.singleEPGCallback, EPGSelection, ref)
354 else: # try to show now/next
355 print 'no epg for service', ref.toString()
358 def openBouquetEPG(self, bouquet):
359 ptr=eEPGCache.getInstance()
361 servicelist = eServiceCenter.getInstance().list(bouquet)
362 if not servicelist is None:
364 service = servicelist.getNext()
365 if not service.valid(): #check if end of list
367 if service.flags: #ignore non playable services
369 services.append(ServiceReference(service))
371 self.session.openWithCallback(self.bouquetEPGCallback, EPGSelection, services)
373 def openSingleEPGSelector(self, ref):
374 ptr=eEPGCache.getInstance()
375 if ptr.startTimeQuery(ref) != -1:
376 self.session.open(EPGSelection, ref)
377 else: # try to show now/next
378 print 'no epg for service', ref.toString()
381 service = self.session.nav.getCurrentService()
382 info = service.info()
385 self.epglist.append(ptr)
388 self.epglist.append(ptr)
389 if len(self.epglist) > 0:
390 self.session.open(EventView, self.epglist[0], ServiceReference(ref), self.eventViewCallback)
394 def eventViewCallback(self, setEvent, setService, val): #used for now/next displaying
395 if len(self.epglist) > 1:
396 tmp = self.epglist[0]
397 self.epglist[0]=self.epglist[1]
399 setEvent(self.epglist[0])
404 """provides a snr/agc/ber display"""
406 self["snr"] = Label()
407 self["agc"] = Label()
408 self["ber"] = Label()
409 self["snr_percent"] = Label()
410 self["agc_percent"] = Label()
411 self["ber_count"] = Label()
412 self["snr_progress"] = ProgressBar()
413 self["agc_progress"] = ProgressBar()
414 self["ber_progress"] = ProgressBar()
415 self.timer = eTimer()
416 self.timer.timeout.get().append(self.updateTunerInfo)
417 self.timer.start(1000)
423 return (long)(log(val)/log(2))
426 def updateTunerInfo(self):
427 if self.instance.isVisible():
428 service = self.session.nav.getCurrentService()
432 if service is not None:
433 feinfo = service.frontendStatusInfo()
434 if feinfo is not None:
435 ber=feinfo.getFrontendInfo(iFrontendStatusInformation.bitErrorRate)
436 snr=feinfo.getFrontendInfo(iFrontendStatusInformation.signalPower)*100/65536
437 agc=feinfo.getFrontendInfo(iFrontendStatusInformation.signalQuality)*100/65536
438 self["snr_percent"].setText("%d%%"%(snr))
439 self["agc_percent"].setText("%d%%"%(agc))
440 self["ber_count"].setText("%d"%(ber))
441 self["snr_progress"].setValue(snr)
442 self["agc_progress"].setValue(agc)
443 self["ber_progress"].setValue(self.calc(ber))
446 """provides a current/next event info display"""
448 self["Event_Now_StartTime"] = EventInfo(self.session.nav, EventInfo.Now_StartTime)
449 self["Event_Next_StartTime"] = EventInfo(self.session.nav, EventInfo.Next_StartTime)
451 self["Event_Now"] = EventInfo(self.session.nav, EventInfo.Now)
452 self["Event_Next"] = EventInfo(self.session.nav, EventInfo.Next)
454 self["Event_Now_Duration"] = EventInfo(self.session.nav, EventInfo.Now_Duration)
455 self["Event_Next_Duration"] = EventInfo(self.session.nav, EventInfo.Next_Duration)
457 class InfoBarServiceName:
459 self["ServiceName"] = ServiceName(self.session.nav)
462 """handles actions like seeking, pause"""
464 # ispause, isff, issm, skip
465 SEEK_STATE_PLAY = (0, 0, 0, 0)
466 SEEK_STATE_PAUSE = (1, 0, 0, 0)
467 SEEK_STATE_FF_2X = (0, 2, 0, 0)
468 SEEK_STATE_FF_4X = (0, 4, 0, 0)
469 SEEK_STATE_FF_8X = (0, 8, 0, 0)
470 SEEK_STATE_FF_32X = (0, 4, 0, 32)
471 SEEK_STATE_FF_64X = (0, 4, 0, 64)
472 SEEK_STATE_FF_128X = (0, 4, 0, 128)
474 SEEK_STATE_BACK_4X = (0, 0, 0, -4)
475 SEEK_STATE_BACK_32X = (0, 0, 0, -32)
476 SEEK_STATE_BACK_64X = (0, 0, 0, -64)
477 SEEK_STATE_BACK_128X = (0, 0, 0, -128)
479 SEEK_STATE_SM_HALF = (0, 0, 2, 0)
480 SEEK_STATE_SM_QUARTER = (0, 0, 4, 0)
481 SEEK_STATE_SM_EIGHTH = (0, 0, 8, 0)
484 self["SeekActions"] = HelpableActionMap(self, "InfobarSeekActions",
486 "pauseService": (self.pauseService, "pause"),
487 "unPauseService": (self.unPauseService, "continue"),
489 "seekFwd": (self.seekFwd, "skip forward"),
490 "seekFwdUp": (self.seekFwdUp, "skip forward"),
491 "seekBack": (self.seekBack, "skip backward"),
492 "seekBackUp": (self.seekBackUp, "skip backward"),
495 self.seekstate = self.SEEK_STATE_PLAY
496 self.seekTimer = eTimer()
497 self.seekTimer.timeout.get().append(self.seekTimerFired)
498 self.skipinterval = 500 # 500ms skip interval
499 self.onClose.append(self.delSeekTimer)
501 self.fwdtimer = False
502 self.fwdKeyTimer = eTimer()
503 self.fwdKeyTimer.timeout.get().append(self.fwdTimerFire)
505 self.rwdtimer = False
506 self.rwdKeyTimer = eTimer()
507 self.rwdKeyTimer.timeout.get().append(self.rwdTimerFire)
515 def delSeekTimer(self):
518 def seekTimerFired(self):
519 self.seekbase += self.skipmode * self.skipinterval
521 # check if we bounced against the beginning of the file
522 if self.seekbase < 0:
524 self.setSeekState(self.SEEK_STATE_PLAY)
526 self.doSeek(self.seekbase)
528 def setSeekState(self, state):
529 oldstate = self.seekstate
531 self.seekstate = state
533 service = self.session.nav.getCurrentService()
537 pauseable = service.pause()
540 if oldstate[i] != self.seekstate[i]:
541 (self.session.nav.pause, pauseable.setFastForward, pauseable.setSlowMotion, self.setSkipMode)[i](self.seekstate[i])
543 def setSkipMode(self, skipmode):
544 self.skipmode = skipmode
546 self.seekTimer.stop()
548 self.seekTimer.start(500)
550 service = self.session.nav.getCurrentService()
554 seekable = service.seek()
559 seekable.setTrickmode(1)
561 seekable.setTrickmode(0)
563 self.seekbase = seekable.getPlayPosition()[1] / 90
565 def pauseService(self):
566 if (self.seekstate == self.SEEK_STATE_PAUSE):
567 self.unPauseService()
569 self.setSeekState(self.SEEK_STATE_PAUSE);
571 def unPauseService(self):
572 self.setSeekState(self.SEEK_STATE_PLAY);
574 def doSeek(self, seektime):
575 service = self.session.nav.getCurrentService()
579 seekable = service.seek()
582 seekable.seekTo(90 * seektime)
585 print "start fwd timer"
587 self.fwdKeyTimer.start(500)
590 print "start rewind timer"
592 self.rwdKeyTimer.start(500)
596 self.fwdKeyTimer.stop()
597 self.fwdtimer = False
599 self.SEEK_STATE_PLAY: self.SEEK_STATE_FF_2X,
600 self.SEEK_STATE_PAUSE: self.SEEK_STATE_SM_EIGHTH,
601 self.SEEK_STATE_FF_2X: self.SEEK_STATE_FF_4X,
602 self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_8X,
603 self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_32X,
604 self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_64X,
605 self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_128X,
606 self.SEEK_STATE_FF_128X: self.SEEK_STATE_FF_128X,
607 self.SEEK_STATE_BACK_4X: self.SEEK_STATE_PLAY,
608 self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_4X,
609 self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_32X,
610 self.SEEK_STATE_BACK_128X: self.SEEK_STATE_BACK_64X,
611 self.SEEK_STATE_SM_HALF: self.SEEK_STATE_SM_HALF,
612 self.SEEK_STATE_SM_QUARTER: self.SEEK_STATE_SM_HALF,
613 self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_SM_QUARTER
615 self.setSeekState(lookup[self.seekstate]);
617 def seekBackUp(self):
619 self.rwdKeyTimer.stop()
620 self.rwdtimer = False
623 self.SEEK_STATE_PLAY: self.SEEK_STATE_BACK_4X,
624 self.SEEK_STATE_PAUSE: self.SEEK_STATE_PAUSE,
625 self.SEEK_STATE_FF_2X: self.SEEK_STATE_PLAY,
626 self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_2X,
627 self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_4X,
628 self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_8X,
629 self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_32X,
630 self.SEEK_STATE_FF_128X: self.SEEK_STATE_FF_64X,
631 self.SEEK_STATE_BACK_4X: self.SEEK_STATE_BACK_32X,
632 self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_64X,
633 self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_128X,
634 self.SEEK_STATE_BACK_128X: self.SEEK_STATE_BACK_128X,
635 self.SEEK_STATE_SM_HALF: self.SEEK_STATE_SM_QUARTER,
636 self.SEEK_STATE_SM_QUARTER: self.SEEK_STATE_SM_EIGHTH,
637 self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_PAUSE
639 self.setSeekState(lookup[self.seekstate]);
641 def fwdTimerFire(self):
642 print "Display seek fwd"
643 self.fwdKeyTimer.stop()
644 self.fwdtimer = False
645 self.session.openWithCallback(self.fwdSeekTo, MinuteInput)
647 def fwdSeekTo(self, minutes):
648 print "Seek", minutes, "minutes forward"
650 service = self.session.nav.getCurrentService()
653 seekable = service.seek()
656 seekable.seekRelative(1, minutes * 60 * 90000)
658 def rwdTimerFire(self):
659 self.rwdKeyTimer.stop()
660 self.rwdtimer = False
661 self.session.openWithCallback(self.rwdSeekTo, MinuteInput)
663 def rwdSeekTo(self, minutes):
664 self.fwdSeekTo(0 - minutes)
666 class InfoBarShowMovies:
668 # i don't really like this class.
669 # it calls a not further specified "movie list" on up/down/movieList,
670 # so this is not moe than an action map
672 self["MovieListActions"] = HelpableActionMap(self, "InfobarMovieListActions",
674 "movieList": (self.showMovies, "movie list"),
675 "up": (self.showMovies, "movie list"),
676 "down": (self.showMovies, "movie list")
679 class InfoBarTimeshift:
681 self["TimeshiftActions"] = HelpableActionMap(self, "InfobarTimeshiftActions",
683 "timeshiftStart": (self.startTimeshift, "start timeshift "),
684 "timeshiftStop": (self.stopTimeshift, "stop timeshift")
688 def getTimeshift(self):
689 service = self.session.nav.getCurrentService()
690 return service.timeshift()
692 def startTimeshift(self):
693 # TODO: check for harddisk! (or do this in the interface? would make
694 # more sense... for example radio could be timeshifted in memory,
695 # and the decision can't be made here)
696 print "enable timeshift"
697 ts = self.getTimeshift()
699 self.session.open(MessageBox, _("Timeshift not possible!"), MessageBox.TYPE_ERROR)
700 print "no ts interface"
702 print "ok, timeshift enabled"
707 pauseable = self.session.nav.getCurrentService().pause()
708 pauseable.pause() # switch to record
710 def stopTimeshift(self):
711 print "disable timeshift"
712 ts = self.getTimeshift()
719 from RecordTimer import parseEvent
721 class InfoBarInstantRecord:
722 """Instant Record - handles the instantRecord action in order to
723 start/stop instant records"""
725 self["InstantRecordActions"] = HelpableActionMap(self, "InfobarInstantRecord",
727 "instantRecord": (self.instantRecord, "Instant Record..."),
729 self.recording = None
731 self["BlinkingPoint"] = BlinkingPixmapConditional()
732 self.onShown.append(self["BlinkingPoint"].hideWidget)
733 self["BlinkingPoint"].setConnect(self.session.nav.RecordTimer.isRecording)
735 def stopCurrentRecording(self):
736 self.session.nav.RecordTimer.removeEntry(self.recording)
737 self.recording = None
739 def startInstantRecording(self):
740 serviceref = self.session.nav.getCurrentlyPlayingServiceReference()
742 # try to get event info
745 service = self.session.nav.getCurrentService()
746 info = service.info()
747 ev = info.getEvent(0)
752 if event is not None:
753 data = parseEvent(event)
755 if begin < time.time():
764 data = (begin, end, data[2], data[3], data[4])
766 data = (time.time(), time.time() + 3600 * 10, "instant record", "", None)
768 # fix me, description.
769 self.recording = self.session.nav.recordWithTimer(serviceref, *data)
770 self.recording.dontSave = True
772 #self["BlinkingPoint"].setConnect(lambda: self.recording.isRunning())
774 def isInstantRecordRunning(self):
775 if self.recording != None:
776 if self.recording.isRunning():
780 def recordQuestionCallback(self, answer):
784 if self.isInstantRecordRunning():
785 self.stopCurrentRecording()
787 self.startInstantRecording()
789 def instantRecord(self):
791 stat = os.stat(resolveFilename(SCOPE_HDD))
793 self.session.open(MessageBox, _("No HDD found or HDD not initialized!"), MessageBox.TYPE_ERROR)
796 if self.isInstantRecordRunning():
797 self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Do you want to stop the current\n(instant) recording?"))
799 self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Start recording?"))
801 from Screens.AudioSelection import AudioSelection
803 class InfoBarAudioSelection:
805 self["AudioSelectionAction"] = HelpableActionMap(self, "InfobarAudioSelectionActions",
807 "audioSelection": (self.audioSelection, "Audio Options..."),
810 def audioSelection(self):
811 service = self.session.nav.getCurrentService()
812 audio = service.audioTracks()
813 n = audio.getNumberOfTracks()
815 self.session.open(AudioSelection, audio)
817 from Screens.SubserviceSelection import SubserviceSelection
819 class InfoBarSubserviceSelection:
821 self["SubserviceSelectionAction"] = HelpableActionMap(self, "InfobarSubserviceSelectionActions",
823 "subserviceSelection": (self.subserviceSelection, "Subservice list..."),
826 def subserviceSelection(self):
827 service = self.session.nav.getCurrentService()
828 subservices = service.subServices()
829 n = subservices.getNumberOfSubservices()
831 self.session.openWithCallback(self.subserviceSelected, SubserviceSelection, subservices)
833 def subserviceSelected(self, service):
834 if not service is None:
835 self.session.nav.playService(service)
837 class InfoBarAdditionalInfo:
839 self["DolbyActive"] = Pixmap()
840 self["CryptActive"] = Pixmap()
841 self["FormatActive"] = Pixmap()
843 self["ButtonRed"] = PixmapConditional(withTimer = False)
844 self["ButtonRed"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
845 self.onShown.append(self["ButtonRed"].update)
846 self["ButtonRedText"] = LabelConditional(text = _("Record"), withTimer = False)
847 self["ButtonRedText"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
848 self.onShown.append(self["ButtonRedText"].update)
850 self["ButtonGreen"] = Pixmap()
851 self["ButtonGreenText"] = Label(_("Subservices"))
853 self["ButtonYellow"] = PixmapConditional(withTimer = False)
854 self["ButtonYellow"].setConnect(lambda: False)
856 self["ButtonBlue"] = PixmapConditional(withTimer = False)
857 self["ButtonBlue"].setConnect(lambda: False)
859 self.session.nav.event.append(self.gotServiceEvent) # we like to get service events
861 def hideSubServiceIndication(self):
862 self["ButtonGreen"].hideWidget()
863 self["ButtonGreenText"].hide()
865 def showSubServiceIndication(self):
866 self["ButtonGreen"].showWidget()
867 self["ButtonGreenText"].show()
869 def checkFormat(self, service):
870 info = service.info()
872 aspect = info.getInfo(iServiceInformation.sAspect)
873 if aspect in [ 3, 4, 7, 8, 0xB, 0xC, 0xF, 0x10 ]:
874 self["FormatActive"].showWidget()
876 self["FormatActive"].hideWidget()
878 def checkSubservices(self, service):
879 if service.subServices().getNumberOfSubservices() > 0:
880 self.showSubServiceIndication()
882 self.hideSubServiceIndication()
884 def checkDolby(self, service):
887 audio = service.audioTracks()
888 if audio is not None:
889 n = audio.getNumberOfTracks()
891 i = audio.getTrackInfo(x)
892 description = i.getDescription();
893 if description.find("AC3") != -1 or description.find("DTS") != -1:
897 self["DolbyActive"].showWidget()
899 self["DolbyActive"].hideWidget()
901 def checkCrypted(self, service):
902 info = service.info()
904 if info.getInfo(iServiceInformation.sIsCrypted) > 0:
905 self["CryptActive"].showWidget()
907 self["CryptActive"].hideWidget()
909 def gotServiceEvent(self, ev):
910 service = self.session.nav.getCurrentService()
911 if ev == pNavigation.evUpdatedEventInfo:
912 self.checkSubservices(service)
913 self.checkFormat(service)
914 elif ev == pNavigation.evUpdatedInfo:
915 self.checkCrypted(service)
916 self.checkDolby(service)
917 elif ev == pNavigation.evStopService:
918 self.hideSubServiceIndication()
919 self["CryptActive"].hideWidget()
920 self["DolbyActive"].hideWidget()
921 self["FormatActive"].hideWidget()
923 class InfoBarNotifications:
925 self.onExecBegin.append(self.checkNotifications)
926 Notifications.notificationAdded.append(self.checkNotificationsIfExecing)
928 def checkNotificationsIfExecing(self):
930 self.checkNotifications()
932 def checkNotifications(self):
933 if len(Notifications.notifications):
934 n = Notifications.notifications[0]
935 Notifications.notifications = Notifications.notifications[1:]
939 self.session.openWithCallback(cb, *n[1:])
941 self.session.open(*n[1:])