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 class InfoBarVolumeControl:
42 """Volume control, handles volUp, volDown, volMute actions and display
43 a corresponding dialog"""
45 config.audio = ConfigSubsection()
46 config.audio.volume = configElement("config.audio.volume", configSequence, [100], configsequencearg.get("INTEGER", (0, 100)))
48 self["VolumeActions"] = ActionMap( ["InfobarVolumeActions"] ,
50 "volumeUp": self.volUp,
51 "volumeDown": self.volDown,
52 "volumeMute": self.volMute,
55 self.volumeDialog = self.session.instantiateDialog(Volume)
56 self.muteDialog = self.session.instantiateDialog(Mute)
58 self.hideVolTimer = eTimer()
59 self.hideVolTimer.timeout.get().append(self.volHide)
61 vol = config.audio.volume.value[0]
62 self.volumeDialog.setValue(vol)
63 eDVBVolumecontrol.getInstance().setVolume(vol, vol)
66 config.audio.volume.value = eDVBVolumecontrol.getInstance().getVolume()
67 config.audio.volume.save()
70 if (eDVBVolumecontrol.getInstance().isMuted()):
72 eDVBVolumecontrol.getInstance().volumeUp()
73 self.volumeDialog.instance.show()
74 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
76 self.hideVolTimer.start(3000, True)
79 if (eDVBVolumecontrol.getInstance().isMuted()):
81 eDVBVolumecontrol.getInstance().volumeDown()
82 self.volumeDialog.instance.show()
83 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
85 self.hideVolTimer.start(3000, True)
88 self.volumeDialog.instance.hide()
91 eDVBVolumecontrol.getInstance().volumeToggleMute()
92 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
94 if (eDVBVolumecontrol.getInstance().isMuted()):
95 self.muteDialog.instance.show()
97 self.muteDialog.instance.hide()
101 self.dishDialog = self.session.instantiateDialog(Dish)
102 self.onShown.append(self.dishDialog.instance.hide)
104 class InfoBarShowHide:
105 """ InfoBar show/hide control, accepts toggleShow and hide actions, might start
106 fancy animations. """
113 self["ShowHideActions"] = ActionMap( ["InfobarShowHideActions"] ,
115 "toggleShow": self.toggleShow,
119 self.state = self.STATE_SHOWN
121 self.onExecBegin.append(self.show)
122 self.onClose.append(self.delHideTimer)
124 self.hideTimer = eTimer()
125 self.hideTimer.timeout.get().append(self.doTimerHide)
126 self.hideTimer.start(5000, True)
128 def delHideTimer(self):
135 self.state = self.STATE_SHOWN
136 self.hideTimer.start(5000, True)
138 def doTimerHide(self):
139 self.hideTimer.stop()
140 if self.state == self.STATE_SHOWN:
142 self.state = self.STATE_HIDDEN
144 def toggleShow(self):
145 if self.state == self.STATE_SHOWN:
147 #pls check animation support, sorry
149 self.hideTimer.stop()
150 self.state = self.STATE_HIDDEN
151 elif self.state == self.STATE_HIDDEN:
156 self.instance.m_animation.startMoveAnimation(ePoint(0, 600), ePoint(0, 380), 100)
157 self.state = self.STATE_SHOWN
160 self.instance.m_animation.startMoveAnimation(ePoint(0, 380), ePoint(0, 600), 100)
161 self.state = self.STATE_HIDDEN
163 class NumberZap(Screen):
170 self.close(int(self["number"].getText()))
172 def keyNumberGlobal(self, number):
173 self.Timer.start(3000, True) #reset timer
174 self.field = self.field + str(number)
175 self["number"].setText(self.field)
176 if len(self.field) >= 4:
179 def __init__(self, session, number):
180 Screen.__init__(self, session)
181 self.field = str(number)
183 self["channel"] = Label(_("Channel:"))
185 self["number"] = Label(self.field)
187 self["actions"] = NumberActionMap( [ "SetupActions" ],
191 "1": self.keyNumberGlobal,
192 "2": self.keyNumberGlobal,
193 "3": self.keyNumberGlobal,
194 "4": self.keyNumberGlobal,
195 "5": self.keyNumberGlobal,
196 "6": self.keyNumberGlobal,
197 "7": self.keyNumberGlobal,
198 "8": self.keyNumberGlobal,
199 "9": self.keyNumberGlobal,
200 "0": self.keyNumberGlobal
203 self.Timer = eTimer()
204 self.Timer.timeout.get().append(self.keyOK)
205 self.Timer.start(3000, True)
207 class InfoBarPowerKey:
208 """ PowerKey stuff - handles the powerkey press and powerkey release actions"""
211 self.powerKeyTimer = eTimer()
212 self.powerKeyTimer.timeout.get().append(self.powertimer)
213 self["PowerKeyActions"] = HelpableActionMap(self, "PowerKeyActions",
215 "powerdown": self.powerdown,
216 "powerup": self.powerup,
217 "discreteStandby": (self.standby, "Go standby"),
218 "discretePowerOff": (self.quit, "Go to deep standby"),
221 def powertimer(self):
222 print "PowerOff - Now!"
226 self.standbyblocked = 0
227 self.powerKeyTimer.start(3000, True)
230 self.powerKeyTimer.stop()
231 if self.standbyblocked == 0:
232 self.standbyblocked = 1
236 self.session.open(Standby, self)
242 class InfoBarNumberZap:
243 """ Handles an initial number for NumberZapping """
245 self["NumberZapActions"] = NumberActionMap( [ "NumberZapActions"],
247 "1": self.keyNumberGlobal,
248 "2": self.keyNumberGlobal,
249 "3": self.keyNumberGlobal,
250 "4": self.keyNumberGlobal,
251 "5": self.keyNumberGlobal,
252 "6": self.keyNumberGlobal,
253 "7": self.keyNumberGlobal,
254 "8": self.keyNumberGlobal,
255 "9": self.keyNumberGlobal,
256 "0": self.keyNumberGlobal,
259 def keyNumberGlobal(self, number):
260 # print "You pressed number " + str(number)
262 self.session.nav.zapLast()
266 self.session.openWithCallback(self.numberEntered, NumberZap, number)
268 def numberEntered(self, retval):
269 # print self.servicelist
271 self.zapToNumber(retval)
273 def searchNumberHelper(self, serviceHandler, num, bouquet):
274 servicelist = serviceHandler.list(bouquet)
275 if not servicelist is None:
277 serviceIterator = servicelist.getNext()
278 if not serviceIterator.valid(): #check end of list
280 if serviceIterator.flags: #assume normal dvb service have no flags set
283 if not num: #found service with searched number ?
284 return serviceIterator, 0
287 def zapToNumber(self, number):
288 bouquet = self.servicelist.bouquet_root
290 serviceHandler = eServiceCenter.getInstance()
291 if bouquet.toString().find('FROM BOUQUET "bouquets.') == -1: #FIXME HACK
292 service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
294 bouquetlist = serviceHandler.list(bouquet)
295 if not bouquetlist is None:
297 bouquet = self.servicelist.appendDVBTypes(bouquetlist.getNext())
298 if not bouquet.valid(): #check end of list
300 if ((bouquet.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
302 service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
303 if not service is None:
304 self.session.nav.playService(service) #play service
305 if self.servicelist.getRoot() != bouquet: #already in correct bouquet?
306 self.servicelist.setRoot(bouquet)
307 self.servicelist.setCurrentSelection(service) #select the service in servicelist
309 class InfoBarChannelSelection:
310 """ ChannelSelection - handles the channelSelection dialog and the initial
311 channelChange actions which open the channelSelection dialog """
314 self.servicelist = self.session.instantiateDialog(ChannelSelection)
316 self["ChannelSelectActions"] = HelpableActionMap(self, "InfobarChannelSelection",
318 "switchChannelUp": self.switchChannelUp,
319 "switchChannelDown": self.switchChannelDown,
320 "zapUp": (self.zapUp, _("next channel")),
321 "zapDown": (self.zapDown, _("previous channel")),
324 def switchChannelUp(self):
325 self.servicelist.moveUp()
326 self.session.execDialog(self.servicelist)
328 def switchChannelDown(self):
329 self.servicelist.moveDown()
330 self.session.execDialog(self.servicelist)
333 self.servicelist.moveUp()
334 self.servicelist.zap()
339 self.servicelist.moveDown()
340 self.servicelist.zap()
345 """ Handles a menu action, to open the (main) menu """
347 self["MenuActions"] = HelpableActionMap(self, "InfobarMenuActions",
349 "mainMenu": (self.mainMenu, "Enter main menu..."),
353 print "loading mainmenu XML..."
354 menu = mdom.childNodes[0]
355 assert menu.tagName == "menu", "root element in menu must be 'menu'!"
356 self.session.open(MainMenu, menu, menu.childNodes)
359 """ EPG - Opens an EPG list when the showEPGList action fires """
361 self["EPGActions"] = HelpableActionMap(self, "InfobarEPGActions",
363 "showEPGList": (self.showEPG, _("show EPG...")),
367 if currentConfigSelectionElement(config.usage.epgtoggle) == "yes":
368 self.openSingleServiceEPG()
372 def showEPGList(self):
373 bouquets = self.servicelist.getBouquetList()
378 if cnt > 1: # show bouquet list
379 self.session.open(BouquetSelector, bouquets, self.openBouquetEPG)
380 elif cnt == 1: # add to only one existing bouquet
381 self.openBouquetEPG(bouquets[0][1])
382 else: #no bouquets so we open single epg
383 self.openSingleEPGSelector(self.session.nav.getCurrentlyPlayingServiceReference())
385 def bouquetEPGCallback(self, info):
387 self.openSingleServiceEPG()
389 def singleEPGCallback(self, info):
393 def openEventView(self):
396 service = self.session.nav.getCurrentService()
397 info = service.info()
400 self.epglist.append(ptr)
403 self.epglist.append(ptr)
404 if len(self.epglist) > 0:
405 self.session.open(EventView, self.epglist[0], ServiceReference(ref), self.eventViewCallback)
409 def openSingleServiceEPG(self):
410 ref=self.session.nav.getCurrentlyPlayingServiceReference()
411 ptr=eEPGCache.getInstance()
412 if ptr.startTimeQuery(ref) != -1:
413 self.session.openWithCallback(self.singleEPGCallback, EPGSelection, ref)
414 else: # try to show now/next
415 print 'no epg for service', ref.toString()
418 def openBouquetEPG(self, bouquet):
419 ptr=eEPGCache.getInstance()
421 servicelist = eServiceCenter.getInstance().list(bouquet)
422 if not servicelist is None:
424 service = servicelist.getNext()
425 if not service.valid(): #check if end of list
427 if service.flags: #ignore non playable services
429 services.append(ServiceReference(service))
431 self.session.openWithCallback(self.bouquetEPGCallback, EPGSelection, services)
433 def openSingleEPGSelector(self, ref):
434 ptr=eEPGCache.getInstance()
435 if ptr.startTimeQuery(ref) != -1:
436 self.session.open(EPGSelection, ref)
437 else: # try to show now/next
438 print 'no epg for service', ref.toString()
441 service = self.session.nav.getCurrentService()
442 info = service.info()
445 self.epglist.append(ptr)
448 self.epglist.append(ptr)
449 if len(self.epglist) > 0:
450 self.session.open(EventView, self.epglist[0], ServiceReference(ref), self.eventViewCallback)
454 def eventViewCallback(self, setEvent, setService, val): #used for now/next displaying
455 if len(self.epglist) > 1:
456 tmp = self.epglist[0]
457 self.epglist[0]=self.epglist[1]
459 setEvent(self.epglist[0])
464 """provides a snr/agc/ber display"""
466 self["snr"] = Label()
467 self["agc"] = Label()
468 self["ber"] = Label()
469 self["snr_percent"] = Label()
470 self["agc_percent"] = Label()
471 self["ber_count"] = Label()
472 self["snr_progress"] = ProgressBar()
473 self["agc_progress"] = ProgressBar()
474 self["ber_progress"] = ProgressBar()
475 self.timer = eTimer()
476 self.timer.timeout.get().append(self.updateTunerInfo)
477 self.timer.start(1000)
483 return (long)(log(val)/log(2))
486 def updateTunerInfo(self):
487 if self.instance.isVisible():
488 service = self.session.nav.getCurrentService()
492 if service is not None:
493 feinfo = service.frontendStatusInfo()
494 if feinfo is not None:
495 ber=feinfo.getFrontendInfo(iFrontendStatusInformation.bitErrorRate)
496 snr=feinfo.getFrontendInfo(iFrontendStatusInformation.signalPower)*100/65536
497 agc=feinfo.getFrontendInfo(iFrontendStatusInformation.signalQuality)*100/65536
498 self["snr_percent"].setText("%d%%"%(snr))
499 self["agc_percent"].setText("%d%%"%(agc))
500 self["ber_count"].setText("%d"%(ber))
501 self["snr_progress"].setValue(snr)
502 self["agc_progress"].setValue(agc)
503 self["ber_progress"].setValue(self.calc(ber))
506 """provides a current/next event info display"""
508 self["Event_Now_StartTime"] = EventInfo(self.session.nav, EventInfo.Now_StartTime)
509 self["Event_Next_StartTime"] = EventInfo(self.session.nav, EventInfo.Next_StartTime)
511 self["Event_Now"] = EventInfo(self.session.nav, EventInfo.Now)
512 self["Event_Next"] = EventInfo(self.session.nav, EventInfo.Next)
514 self["Event_Now_Duration"] = EventInfo(self.session.nav, EventInfo.Now_Duration)
515 self["Event_Next_Duration"] = EventInfo(self.session.nav, EventInfo.Next_Duration)
517 class InfoBarServiceName:
519 self["ServiceName"] = ServiceName(self.session.nav)
522 """handles actions like seeking, pause"""
524 # ispause, isff, issm, skip
525 SEEK_STATE_PLAY = (0, 0, 0, 0)
526 SEEK_STATE_PAUSE = (1, 0, 0, 0)
527 SEEK_STATE_FF_2X = (0, 2, 0, 0)
528 SEEK_STATE_FF_4X = (0, 4, 0, 0)
529 SEEK_STATE_FF_8X = (0, 8, 0, 0)
530 SEEK_STATE_FF_32X = (0, 4, 0, 32)
531 SEEK_STATE_FF_64X = (0, 4, 0, 64)
532 SEEK_STATE_FF_128X = (0, 4, 0, 128)
534 SEEK_STATE_BACK_4X = (0, 0, 0, -4)
535 SEEK_STATE_BACK_32X = (0, 0, 0, -32)
536 SEEK_STATE_BACK_64X = (0, 0, 0, -64)
537 SEEK_STATE_BACK_128X = (0, 0, 0, -128)
539 SEEK_STATE_SM_HALF = (0, 0, 2, 0)
540 SEEK_STATE_SM_QUARTER = (0, 0, 4, 0)
541 SEEK_STATE_SM_EIGHTH = (0, 0, 8, 0)
544 self["SeekActions"] = HelpableActionMap(self, "InfobarSeekActions",
546 "pauseService": (self.pauseService, "pause"),
547 "unPauseService": (self.unPauseService, "continue"),
549 "seekFwd": (self.seekFwd, "skip forward"),
550 "seekFwdUp": (self.seekFwdUp, "skip forward"),
551 "seekBack": (self.seekBack, "skip backward"),
552 "seekBackUp": (self.seekBackUp, "skip backward"),
555 self.seekstate = self.SEEK_STATE_PLAY
556 self.seekTimer = eTimer()
557 self.seekTimer.timeout.get().append(self.seekTimerFired)
558 self.skipinterval = 500 # 500ms skip interval
559 self.onClose.append(self.delSeekTimer)
561 self.fwdtimer = False
562 self.fwdKeyTimer = eTimer()
563 self.fwdKeyTimer.timeout.get().append(self.fwdTimerFire)
565 self.rwdtimer = False
566 self.rwdKeyTimer = eTimer()
567 self.rwdKeyTimer.timeout.get().append(self.rwdTimerFire)
575 def delSeekTimer(self):
578 def seekTimerFired(self):
579 self.seekbase += self.skipmode * self.skipinterval
581 # check if we bounced against the beginning of the file
582 if self.seekbase < 0:
584 self.setSeekState(self.SEEK_STATE_PLAY)
586 self.doSeek(self.seekbase)
588 def setSeekState(self, state):
589 oldstate = self.seekstate
591 self.seekstate = state
593 service = self.session.nav.getCurrentService()
597 pauseable = service.pause()
600 if oldstate[i] != self.seekstate[i]:
601 (self.session.nav.pause, pauseable.setFastForward, pauseable.setSlowMotion, self.setSkipMode)[i](self.seekstate[i])
603 def setSkipMode(self, skipmode):
604 self.skipmode = skipmode
606 self.seekTimer.stop()
608 self.seekTimer.start(500)
610 service = self.session.nav.getCurrentService()
614 seekable = service.seek()
619 seekable.setTrickmode(1)
621 seekable.setTrickmode(0)
623 self.seekbase = seekable.getPlayPosition()[1] / 90
625 def pauseService(self):
626 if (self.seekstate == self.SEEK_STATE_PAUSE):
627 self.unPauseService()
629 self.setSeekState(self.SEEK_STATE_PAUSE);
631 def unPauseService(self):
632 self.setSeekState(self.SEEK_STATE_PLAY);
634 def doSeek(self, seektime):
635 service = self.session.nav.getCurrentService()
639 seekable = service.seek()
642 seekable.seekTo(90 * seektime)
645 print "start fwd timer"
647 self.fwdKeyTimer.start(500)
650 print "start rewind timer"
652 self.rwdKeyTimer.start(500)
656 self.fwdKeyTimer.stop()
657 self.fwdtimer = False
659 self.SEEK_STATE_PLAY: self.SEEK_STATE_FF_2X,
660 self.SEEK_STATE_PAUSE: self.SEEK_STATE_SM_EIGHTH,
661 self.SEEK_STATE_FF_2X: self.SEEK_STATE_FF_4X,
662 self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_8X,
663 self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_32X,
664 self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_64X,
665 self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_128X,
666 self.SEEK_STATE_FF_128X: self.SEEK_STATE_FF_128X,
667 self.SEEK_STATE_BACK_4X: self.SEEK_STATE_PLAY,
668 self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_4X,
669 self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_32X,
670 self.SEEK_STATE_BACK_128X: self.SEEK_STATE_BACK_64X,
671 self.SEEK_STATE_SM_HALF: self.SEEK_STATE_SM_HALF,
672 self.SEEK_STATE_SM_QUARTER: self.SEEK_STATE_SM_HALF,
673 self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_SM_QUARTER
675 self.setSeekState(lookup[self.seekstate]);
677 def seekBackUp(self):
679 self.rwdKeyTimer.stop()
680 self.rwdtimer = False
683 self.SEEK_STATE_PLAY: self.SEEK_STATE_BACK_4X,
684 self.SEEK_STATE_PAUSE: self.SEEK_STATE_PAUSE,
685 self.SEEK_STATE_FF_2X: self.SEEK_STATE_PLAY,
686 self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_2X,
687 self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_4X,
688 self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_8X,
689 self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_32X,
690 self.SEEK_STATE_FF_128X: self.SEEK_STATE_FF_64X,
691 self.SEEK_STATE_BACK_4X: self.SEEK_STATE_BACK_32X,
692 self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_64X,
693 self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_128X,
694 self.SEEK_STATE_BACK_128X: self.SEEK_STATE_BACK_128X,
695 self.SEEK_STATE_SM_HALF: self.SEEK_STATE_SM_QUARTER,
696 self.SEEK_STATE_SM_QUARTER: self.SEEK_STATE_SM_EIGHTH,
697 self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_PAUSE
699 self.setSeekState(lookup[self.seekstate]);
701 def fwdTimerFire(self):
702 print "Display seek fwd"
703 self.fwdKeyTimer.stop()
704 self.fwdtimer = False
705 self.session.openWithCallback(self.fwdSeekTo, MinuteInput)
707 def fwdSeekTo(self, minutes):
708 print "Seek", minutes, "minutes forward"
710 service = self.session.nav.getCurrentService()
713 seekable = service.seek()
716 seekable.seekRelative(1, minutes * 60 * 90000)
718 def rwdTimerFire(self):
719 self.rwdKeyTimer.stop()
720 self.rwdtimer = False
721 self.session.openWithCallback(self.rwdSeekTo, MinuteInput)
723 def rwdSeekTo(self, minutes):
724 self.fwdSeekTo(0 - minutes)
726 class InfoBarShowMovies:
728 # i don't really like this class.
729 # it calls a not further specified "movie list" on up/down/movieList,
730 # so this is not moe than an action map
732 self["MovieListActions"] = HelpableActionMap(self, "InfobarMovieListActions",
734 "movieList": (self.showMovies, "movie list"),
735 "up": (self.showMovies, "movie list"),
736 "down": (self.showMovies, "movie list")
739 class InfoBarTimeshift:
741 self["TimeshiftActions"] = HelpableActionMap(self, "InfobarTimeshiftActions",
743 "timeshiftStart": (self.startTimeshift, "start timeshift "),
744 "timeshiftStop": (self.stopTimeshift, "stop timeshift")
748 def getTimeshift(self):
749 service = self.session.nav.getCurrentService()
750 return service.timeshift()
752 def startTimeshift(self):
753 # TODO: check for harddisk! (or do this in the interface? would make
754 # more sense... for example radio could be timeshifted in memory,
755 # and the decision can't be made here)
756 print "enable timeshift"
757 ts = self.getTimeshift()
759 self.session.open(MessageBox, _("Timeshift not possible!"), MessageBox.TYPE_ERROR)
760 print "no ts interface"
762 print "ok, timeshift enabled"
767 pauseable = self.session.nav.getCurrentService().pause()
768 pauseable.pause() # switch to record
770 def stopTimeshift(self):
771 print "disable timeshift"
772 ts = self.getTimeshift()
779 from RecordTimer import parseEvent
781 class InfoBarInstantRecord:
782 """Instant Record - handles the instantRecord action in order to
783 start/stop instant records"""
785 self["InstantRecordActions"] = HelpableActionMap(self, "InfobarInstantRecord",
787 "instantRecord": (self.instantRecord, "Instant Record..."),
789 self.recording = None
791 self["BlinkingPoint"] = BlinkingPixmapConditional()
792 self.onShown.append(self["BlinkingPoint"].hideWidget)
793 self["BlinkingPoint"].setConnect(self.session.nav.RecordTimer.isRecording)
795 def stopCurrentRecording(self):
796 self.session.nav.RecordTimer.removeEntry(self.recording)
797 self.recording = None
799 def startInstantRecording(self):
800 serviceref = self.session.nav.getCurrentlyPlayingServiceReference()
802 # try to get event info
805 service = self.session.nav.getCurrentService()
806 info = service.info()
807 ev = info.getEvent(0)
812 if event is not None:
813 data = parseEvent(event)
815 if begin < time.time():
824 data = (begin, end, data[2], data[3], data[4])
826 data = (time.time(), time.time() + 3600 * 10, "instant record", "", None)
828 # fix me, description.
829 self.recording = self.session.nav.recordWithTimer(serviceref, *data)
830 self.recording.dontSave = True
832 #self["BlinkingPoint"].setConnect(lambda: self.recording.isRunning())
834 def isInstantRecordRunning(self):
835 if self.recording != None:
836 if self.recording.isRunning():
840 def recordQuestionCallback(self, answer):
844 if self.isInstantRecordRunning():
845 self.stopCurrentRecording()
847 self.startInstantRecording()
849 def instantRecord(self):
851 stat = os.stat(resolveFilename(SCOPE_HDD))
853 self.session.open(MessageBox, _("No HDD found or HDD not initialized!"), MessageBox.TYPE_ERROR)
856 if self.isInstantRecordRunning():
857 self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Do you want to stop the current\n(instant) recording?"))
859 self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Start recording?"))
861 from Screens.AudioSelection import AudioSelection
863 class InfoBarAudioSelection:
865 self["AudioSelectionAction"] = HelpableActionMap(self, "InfobarAudioSelectionActions",
867 "audioSelection": (self.audioSelection, "Audio Options..."),
870 def audioSelection(self):
871 service = self.session.nav.getCurrentService()
872 audio = service.audioTracks()
873 n = audio.getNumberOfTracks()
875 self.session.open(AudioSelection, audio)
877 from Screens.SubserviceSelection import SubserviceSelection
879 class InfoBarSubserviceSelection:
881 self["SubserviceSelectionAction"] = HelpableActionMap(self, "InfobarSubserviceSelectionActions",
883 "subserviceSelection": (self.subserviceSelection, "Subservice list..."),
886 def subserviceSelection(self):
887 service = self.session.nav.getCurrentService()
888 subservices = service.subServices()
889 n = subservices.getNumberOfSubservices()
891 self.session.openWithCallback(self.subserviceSelected, SubserviceSelection, subservices)
893 def subserviceSelected(self, service):
894 if not service is None:
895 self.session.nav.playService(service)
897 class InfoBarAdditionalInfo:
899 self["DolbyActive"] = Pixmap()
900 self["CryptActive"] = Pixmap()
901 self["FormatActive"] = Pixmap()
903 self["ButtonRed"] = PixmapConditional(withTimer = False)
904 self["ButtonRed"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
905 self.onShown.append(self["ButtonRed"].update)
906 self["ButtonRedText"] = LabelConditional(text = _("Record"), withTimer = False)
907 self["ButtonRedText"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
908 self.onShown.append(self["ButtonRedText"].update)
910 self["ButtonGreen"] = Pixmap()
911 self["ButtonGreenText"] = Label(_("Subservices"))
913 self["ButtonYellow"] = PixmapConditional(withTimer = False)
914 self["ButtonYellow"].setConnect(lambda: False)
916 self["ButtonBlue"] = PixmapConditional(withTimer = False)
917 self["ButtonBlue"].setConnect(lambda: False)
919 self.session.nav.event.append(self.gotServiceEvent) # we like to get service events
921 def hideSubServiceIndication(self):
922 self["ButtonGreen"].hideWidget()
923 self["ButtonGreenText"].hide()
925 def showSubServiceIndication(self):
926 self["ButtonGreen"].showWidget()
927 self["ButtonGreenText"].show()
929 def checkFormat(self, service):
930 info = service.info()
932 aspect = info.getInfo(iServiceInformation.sAspect)
933 if aspect in [ 3, 4, 7, 8, 0xB, 0xC, 0xF, 0x10 ]:
934 self["FormatActive"].showWidget()
936 self["FormatActive"].hideWidget()
938 def checkSubservices(self, service):
939 if service.subServices().getNumberOfSubservices() > 0:
940 self.showSubServiceIndication()
942 self.hideSubServiceIndication()
944 def checkDolby(self, service):
947 audio = service.audioTracks()
948 if audio is not None:
949 n = audio.getNumberOfTracks()
951 i = audio.getTrackInfo(x)
952 description = i.getDescription();
953 if description.find("AC3") != -1 or description.find("DTS") != -1:
957 self["DolbyActive"].showWidget()
959 self["DolbyActive"].hideWidget()
961 def checkCrypted(self, service):
962 info = service.info()
964 if info.getInfo(iServiceInformation.sIsCrypted) > 0:
965 self["CryptActive"].showWidget()
967 self["CryptActive"].hideWidget()
969 def gotServiceEvent(self, ev):
970 service = self.session.nav.getCurrentService()
971 if ev == pNavigation.evUpdatedEventInfo:
972 self.checkSubservices(service)
973 self.checkFormat(service)
974 elif ev == pNavigation.evUpdatedInfo:
975 self.checkCrypted(service)
976 self.checkDolby(service)
977 elif ev == pNavigation.evStopService:
978 self.hideSubServiceIndication()
979 self["CryptActive"].hideWidget()
980 self["DolbyActive"].hideWidget()
981 self["FormatActive"].hideWidget()
983 class InfoBarNotifications:
985 self.onExecBegin.append(self.checkNotifications)
986 Notifications.notificationAdded.append(self.checkNotificationsIfExecing)
988 def checkNotificationsIfExecing(self):
990 self.checkNotifications()
992 def checkNotifications(self):
993 if len(Notifications.notifications):
994 n = Notifications.notifications[0]
995 Notifications.notifications = Notifications.notifications[1:]
999 self.session.openWithCallback(cb, *n[1:])
1001 self.session.open(*n[1:])