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
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 Components.Harddisk import harddiskmanager
26 from Tools import Notifications
28 #from enigma import eTimer, eDVBVolumecontrol, quitMainloop
35 from Menu import MainMenu, mdom
37 class InfoBarVolumeControl:
38 """Volume control, handles volUp, volDown, volMute actions and display
39 a corresponding dialog"""
41 config.audio = ConfigSubsection()
42 config.audio.volume = configElement("config.audio.volume", configSequence, [5], configsequencearg.get("INTEGER", (0, 100)))
44 self["VolumeActions"] = ActionMap( ["InfobarVolumeActions"] ,
46 "volumeUp": self.volUp,
47 "volumeDown": self.volDown,
48 "volumeMute": self.volMute,
51 self.volumeDialog = self.session.instantiateDialog(Volume)
52 self.muteDialog = self.session.instantiateDialog(Mute)
54 self.hideVolTimer = eTimer()
55 self.hideVolTimer.timeout.get().append(self.volHide)
57 vol = config.audio.volume.value[0]
58 self.volumeDialog.setValue(vol)
59 eDVBVolumecontrol.getInstance().setVolume(vol, vol)
62 config.audio.volume.value = eDVBVolumecontrol.getInstance().getVolume()
63 config.audio.volume.save()
66 if (eDVBVolumecontrol.getInstance().isMuted()):
68 eDVBVolumecontrol.getInstance().volumeUp()
69 self.volumeDialog.instance.show()
70 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
72 self.hideVolTimer.start(3000)
75 if (eDVBVolumecontrol.getInstance().isMuted()):
77 eDVBVolumecontrol.getInstance().volumeDown()
78 self.volumeDialog.instance.show()
79 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
81 self.hideVolTimer.start(3000)
84 self.volumeDialog.instance.hide()
87 eDVBVolumecontrol.getInstance().volumeToggleMute()
88 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
90 if (eDVBVolumecontrol.getInstance().isMuted()):
91 self.muteDialog.instance.show()
93 self.muteDialog.instance.hide()
97 self.dishDialog = self.session.instantiateDialog(Dish)
98 self.onShown.append(self.dishDialog.instance.hide)
100 class InfoBarShowHide:
101 """ InfoBar show/hide control, accepts toggleShow and hide actions, might start
102 fancy animations. """
109 self["ShowHideActions"] = ActionMap( ["InfobarShowHideActions"] ,
111 "toggleShow": self.toggleShow,
115 self.state = self.STATE_SHOWN
117 self.onExecBegin.append(self.show)
118 self.onClose.append(self.delHideTimer)
120 self.hideTimer = eTimer()
121 self.hideTimer.timeout.get().append(self.doTimerHide)
122 self.hideTimer.start(5000)
124 def delHideTimer(self):
131 self.state = self.STATE_SHOWN
132 self.hideTimer.stop()
133 self.hideTimer.start(5000)
135 def doTimerHide(self):
136 self.hideTimer.stop()
137 if self.state == self.STATE_SHOWN:
139 self.state = self.STATE_HIDDEN
141 def toggleShow(self):
142 if self.state == self.STATE_SHOWN:
144 #pls check animation support, sorry
146 self.hideTimer.stop()
147 self.state = self.STATE_HIDDEN
148 elif self.state == self.STATE_HIDDEN:
153 self.instance.m_animation.startMoveAnimation(ePoint(0, 600), ePoint(0, 380), 100)
154 self.state = self.STATE_SHOWN
157 self.instance.m_animation.startMoveAnimation(ePoint(0, 380), ePoint(0, 600), 100)
158 self.state = self.STATE_HIDDEN
160 class NumberZap(Screen):
167 self.close(int(self["number"].getText()))
169 def keyNumberGlobal(self, number):
170 self.Timer.start(3000) #reset timer
171 self.field = self.field + str(number)
172 self["number"].setText(self.field)
173 if len(self.field) >= 4:
176 def __init__(self, session, number):
177 Screen.__init__(self, session)
178 self.field = str(number)
180 self["channel"] = Label(_("Channel:"))
182 self["number"] = Label(self.field)
184 self["actions"] = NumberActionMap( [ "SetupActions" ],
188 "1": self.keyNumberGlobal,
189 "2": self.keyNumberGlobal,
190 "3": self.keyNumberGlobal,
191 "4": self.keyNumberGlobal,
192 "5": self.keyNumberGlobal,
193 "6": self.keyNumberGlobal,
194 "7": self.keyNumberGlobal,
195 "8": self.keyNumberGlobal,
196 "9": self.keyNumberGlobal,
197 "0": self.keyNumberGlobal
200 self.Timer = eTimer()
201 self.Timer.timeout.get().append(self.keyOK)
202 self.Timer.start(3000)
204 class InfoBarPowerKey:
205 """ PowerKey stuff - handles the powerkey press and powerkey release actions"""
208 self.powerKeyTimer = eTimer()
209 self.powerKeyTimer.timeout.get().append(self.powertimer)
210 self["PowerKeyActions"] = HelpableActionMap(self, "PowerKeyActions",
212 "powerdown": self.powerdown,
213 "powerup": self.powerup,
214 "discreteStandby": (self.standby, "Go standby"),
215 "discretePowerOff": (self.quit, "Go to deep standby"),
218 def powertimer(self):
219 print "PowerOff - Now!"
223 self.standbyblocked = 0
224 self.powerKeyTimer.start(3000)
227 self.powerKeyTimer.stop()
228 if self.standbyblocked == 0:
229 self.standbyblocked = 1
233 self.session.open(Standby, self)
239 class InfoBarNumberZap:
240 """ Handles an initial number for NumberZapping """
242 self["NumberZapActions"] = NumberActionMap( [ "NumberZapActions"],
244 "1": self.keyNumberGlobal,
245 "2": self.keyNumberGlobal,
246 "3": self.keyNumberGlobal,
247 "4": self.keyNumberGlobal,
248 "5": self.keyNumberGlobal,
249 "6": self.keyNumberGlobal,
250 "7": self.keyNumberGlobal,
251 "8": self.keyNumberGlobal,
252 "9": self.keyNumberGlobal,
253 "0": self.keyNumberGlobal,
256 def keyNumberGlobal(self, number):
257 # print "You pressed number " + str(number)
258 self.session.openWithCallback(self.numberEntered, NumberZap, number)
260 def numberEntered(self, retval):
261 # print self.servicelist
263 self.zapToNumber(retval)
265 def searchNumberHelper(self, serviceHandler, num, bouquet):
266 servicelist = serviceHandler.list(bouquet)
267 if not servicelist is None:
269 serviceIterator = servicelist.getNext()
270 if not serviceIterator.valid(): #check end of list
272 if serviceIterator.flags: #assume normal dvb service have no flags set
275 if not num: #found service with searched number ?
276 return serviceIterator, 0
279 def zapToNumber(self, number):
280 bouquet = self.servicelist.bouquet_root
282 serviceHandler = eServiceCenter.getInstance()
283 if bouquet.toString().find('FROM BOUQUET "bouquets.') == -1: #FIXME HACK
284 service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
286 bouquetlist = serviceHandler.list(bouquet)
287 if not bouquetlist is None:
289 bouquet = bouquetlist.getNext()
290 if not bouquet.valid(): #check end of list
292 if ((bouquet.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
294 service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
295 if not service is None:
296 self.session.nav.playService(service) #play service
297 if self.servicelist.getRoot() != bouquet: #already in correct bouquet?
298 self.servicelist.setRoot(bouquet)
299 self.servicelist.setCurrentSelection(service) #select the service in servicelist
301 class InfoBarChannelSelection:
302 """ ChannelSelection - handles the channelSelection dialog and the initial
303 channelChange actions which open the channelSelection dialog """
306 self.servicelist = self.session.instantiateDialog(ChannelSelection)
308 self["ChannelSelectActions"] = HelpableActionMap(self, "InfobarChannelSelection",
310 "switchChannelUp": self.switchChannelUp,
311 "switchChannelDown": self.switchChannelDown,
312 "zapUp": (self.zapUp, _("next channel")),
313 "zapDown": (self.zapDown, _("previous channel")),
316 def switchChannelUp(self):
317 self.servicelist.moveUp()
318 self.session.execDialog(self.servicelist)
320 def switchChannelDown(self):
321 self.servicelist.moveDown()
322 self.session.execDialog(self.servicelist)
325 self.servicelist.moveUp()
326 self.servicelist.zap()
331 self.servicelist.moveDown()
332 self.servicelist.zap()
337 """ Handles a menu action, to open the (main) menu """
339 self["MenuActions"] = HelpableActionMap(self, "InfobarMenuActions",
341 "mainMenu": (self.mainMenu, "Enter main menu..."),
345 print "loading mainmenu XML..."
346 menu = mdom.childNodes[0]
347 assert menu.tagName == "menu", "root element in menu must be 'menu'!"
348 self.session.open(MainMenu, menu, menu.childNodes)
351 """ EPG - Opens an EPG list when the showEPGList action fires """
353 self["EPGActions"] = HelpableActionMap(self, "InfobarEPGActions",
355 "showEPGList": (self.showEPGList, _("show EPG...")),
358 def showEPGList(self):
359 ref=self.session.nav.getCurrentlyPlayingServiceReference()
360 ptr=eEPGCache.getInstance()
361 if ptr.startTimeQuery(ref) != -1:
362 self.session.open(EPGSelection, ref)
363 else: # try to show now/next
364 print 'no epg for service', ref.toString()
367 service = self.session.nav.getCurrentService()
368 info = service.info()
371 self.epglist.append(ptr)
374 self.epglist.append(ptr)
375 if len(self.epglist) > 0:
376 self.session.open(EventView, self.epglist[0], ServiceReference(ref), self.eventViewCallback)
380 def eventViewCallback(self, setEvent, val): #used for now/next displaying
381 if len(self.epglist) > 1:
382 tmp = self.epglist[0]
383 self.epglist[0]=self.epglist[1]
385 setEvent(self.epglist[0])
390 """provides a snr/agc/ber display"""
392 self["snr"] = Label()
393 self["agc"] = Label()
394 self["ber"] = Label()
395 self["snr_percent"] = Label()
396 self["agc_percent"] = Label()
397 self["ber_count"] = Label()
398 self["snr_progress"] = ProgressBar()
399 self["agc_progress"] = ProgressBar()
400 self["ber_progress"] = ProgressBar()
401 self.timer = eTimer()
402 self.timer.timeout.get().append(self.updateTunerInfo)
403 self.timer.start(500)
409 return (long)(log(val)/log(2))
412 def updateTunerInfo(self):
413 if self.instance.isVisible():
414 service = self.session.nav.getCurrentService()
418 if service is not None:
419 feinfo = service.frontendStatusInfo()
420 if feinfo is not None:
421 ber=feinfo.getFrontendInfo(iFrontendStatusInformation.bitErrorRate)
422 snr=feinfo.getFrontendInfo(iFrontendStatusInformation.signalPower)*100/65536
423 agc=feinfo.getFrontendInfo(iFrontendStatusInformation.signalQuality)*100/65536
424 self["snr_percent"].setText("%d%%"%(snr))
425 self["agc_percent"].setText("%d%%"%(agc))
426 self["ber_count"].setText("%d"%(ber))
427 self["snr_progress"].setValue(snr)
428 self["agc_progress"].setValue(agc)
429 self["ber_progress"].setValue(self.calc(ber))
432 """provides a current/next event info display"""
434 self["Event_Now_StartTime"] = EventInfo(self.session.nav, EventInfo.Now_StartTime)
435 self["Event_Next_StartTime"] = EventInfo(self.session.nav, EventInfo.Next_StartTime)
437 self["Event_Now"] = EventInfo(self.session.nav, EventInfo.Now)
438 self["Event_Next"] = EventInfo(self.session.nav, EventInfo.Next)
440 self["Event_Now_Duration"] = EventInfo(self.session.nav, EventInfo.Now_Duration)
441 self["Event_Next_Duration"] = EventInfo(self.session.nav, EventInfo.Next_Duration)
443 class InfoBarServiceName:
445 self["ServiceName"] = ServiceName(self.session.nav)
448 """handles PVR specific actions like seeking, pause"""
450 self["PVRActions"] = HelpableActionMap(self, "InfobarPVRActions",
452 "pauseService": (self.pauseService, "pause"),
453 "unPauseService": (self.unPauseService, "continue"),
455 "seekFwd": (self.seekFwd, "skip forward"),
456 "seekBack": (self.seekBack, "skip backward"),
459 def pauseService(self):
460 self.session.nav.pause(1)
462 def unPauseService(self):
463 self.session.nav.pause(0)
465 def doSeek(self, dir, seektime):
466 service = self.session.nav.getCurrentService()
470 seekable = service.seek()
473 seekable.seekRelative(dir, 90 * seektime)
476 self.doSeek(+1, 60000)
479 self.doSeek(-1, 60000)
481 class InfoBarInstantRecord:
482 """Instant Record - handles the instantRecord action in order to
483 start/stop instant records"""
485 self["InstantRecordActions"] = HelpableActionMap(self, "InfobarInstantRecord",
487 "instantRecord": (self.instantRecord, "Instant Record..."),
489 self.recording = None
491 self["BlinkingPoint"] = BlinkingPixmapConditional()
492 self.onShown.append(self["BlinkingPoint"].hideWidget)
493 self["BlinkingPoint"].setConnect(self.session.nav.RecordTimer.isRecording)
495 def stopCurrentRecording(self):
496 self.session.nav.RecordTimer.removeEntry(self.recording)
497 self.recording = None
499 def startInstantRecording(self):
500 serviceref = self.session.nav.getCurrentlyPlayingServiceReference()
502 # try to get event info
505 service = self.session.nav.getCurrentService()
506 info = service.info()
507 ev = info.getEvent(0)
512 # fix me, description.
513 self.recording = self.session.nav.recordWithTimer(time.time(), time.time() + 3600, serviceref, epg, "instant record")
514 self.recording.dontSave = True
516 #self["BlinkingPoint"].setConnect(lambda: self.recording.isRunning())
518 def isInstantRecordRunning(self):
519 if self.recording != None:
520 if self.recording.isRunning():
524 def recordQuestionCallback(self, answer):
528 if self.isInstantRecordRunning():
529 self.stopCurrentRecording()
531 self.startInstantRecording()
533 def instantRecord(self):
535 stat = os.stat("/hdd/movies")
537 self.session.open(MessageBox, "No HDD found!")
540 if self.isInstantRecordRunning():
541 self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Do you want to stop the current\n(instant) recording?"))
543 self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Start recording?"))
545 from Screens.AudioSelection import AudioSelection
547 class InfoBarAudioSelection:
549 self["AudioSelectionAction"] = HelpableActionMap(self, "InfobarAudioSelectionActions",
551 "audioSelection": (self.audioSelection, "Audio Options..."),
554 def audioSelection(self):
555 service = self.session.nav.getCurrentService()
556 audio = service.audioTracks()
557 n = audio.getNumberOfTracks()
559 self.session.open(AudioSelection, audio)
561 from Screens.SubserviceSelection import SubserviceSelection
563 class InfoBarSubserviceSelection:
565 self["SubserviceSelectionAction"] = HelpableActionMap(self, "InfobarSubserviceSelectionActions",
567 "subserviceSelection": (self.subserviceSelection, "Subservice list..."),
570 def subserviceSelection(self):
571 service = self.session.nav.getCurrentService()
572 subservices = service.subServices()
573 n = subservices.getNumberOfSubservices()
575 self.session.openWithCallback(self.subserviceSelected, SubserviceSelection, subservices)
577 def subserviceSelected(self, service):
578 if not service is None:
579 self.session.nav.playService(service)
581 class InfoBarAdditionalInfo:
583 self["DolbyActive"] = PixmapConditional()
584 # TODO: get the info from c++ somehow
585 self["DolbyActive"].setConnect(lambda: False)
587 self["CryptActive"] = PixmapConditional()
588 # TODO: get the info from c++ somehow
589 self["CryptActive"].setConnect(lambda: False)
591 self["FormatActive"] = PixmapConditional()
592 # TODO: get the info from c++ somehow
593 self["FormatActive"].setConnect(lambda: False)
595 self["ButtonRed"] = PixmapConditional(withTimer = False)
596 self["ButtonRed"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
597 self.onShown.append(self["ButtonRed"].update)
598 self["ButtonRedText"] = LabelConditional(text = _("Record"), withTimer = False)
599 self["ButtonRedText"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
600 self.onShown.append(self["ButtonRedText"].update)
602 self["ButtonGreen"] = PixmapConditional()
603 self["ButtonGreen"].setConnect(lambda: self.session.nav.getCurrentService().subServices().getNumberOfSubservices() > 0)
604 self["ButtonGreenText"] = LabelConditional(text = _("Subservices"))
605 self["ButtonGreenText"].setConnect(lambda: self.session.nav.getCurrentService().subServices().getNumberOfSubservices() > 0)
607 self["ButtonYellow"] = PixmapConditional()
608 self["ButtonYellow"].setConnect(lambda: False)
610 self["ButtonBlue"] = PixmapConditional()
611 self["ButtonBlue"].setConnect(lambda: False)
613 class InfoBarNotifications:
615 self.onExecBegin.append(self.checkNotifications)
616 Notifications.notificationAdded.append(self.checkNotificationsIfExecing)
618 def checkNotificationsIfExecing(self):
620 self.checkNotifications()
622 def checkNotifications(self):
623 if len(Notifications.notifications):
624 n = Notifications.notifications[0]
625 Notifications.notifications = Notifications.notifications[1:]
629 self.session.openWithCallback(cb, *n[1:])
631 self.session.open(*n[1:])