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)
408 return (long)(log(val)/log(2))
410 def updateTunerInfo(self):
411 if self.instance.isVisible():
412 service = self.session.nav.getCurrentService()
416 if service is not None:
417 feinfo = service.frontendStatusInfo()
418 if feinfo is not None:
419 ber=feinfo.getFrontendInfo(iFrontendStatusInformation.bitErrorRate)
420 snr=feinfo.getFrontendInfo(iFrontendStatusInformation.signalPower)*100/65536
421 agc=feinfo.getFrontendInfo(iFrontendStatusInformation.signalQuality)*100/65536
422 self["snr_percent"].setText("%d%%"%(snr))
423 self["agc_percent"].setText("%d%%"%(agc))
424 self["ber_count"].setText("%d"%(ber))
425 self["snr_progress"].setValue(snr)
426 self["agc_progress"].setValue(agc)
427 self["ber_progress"].setValue(self.log2(ber))
430 """provides a current/next event info display"""
432 self["Event_Now_StartTime"] = EventInfo(self.session.nav, EventInfo.Now_StartTime)
433 self["Event_Next_StartTime"] = EventInfo(self.session.nav, EventInfo.Next_StartTime)
435 self["Event_Now"] = EventInfo(self.session.nav, EventInfo.Now)
436 self["Event_Next"] = EventInfo(self.session.nav, EventInfo.Next)
438 self["Event_Now_Duration"] = EventInfo(self.session.nav, EventInfo.Now_Duration)
439 self["Event_Next_Duration"] = EventInfo(self.session.nav, EventInfo.Next_Duration)
441 class InfoBarServiceName:
443 self["ServiceName"] = ServiceName(self.session.nav)
446 """handles PVR specific actions like seeking, pause"""
448 self["PVRActions"] = HelpableActionMap(self, "InfobarPVRActions",
450 "pauseService": (self.pauseService, "pause"),
451 "unPauseService": (self.unPauseService, "continue"),
453 "seekFwd": (self.seekFwd, "skip forward"),
454 "seekBack": (self.seekBack, "skip backward"),
457 def pauseService(self):
458 self.session.nav.pause(1)
460 def unPauseService(self):
461 self.session.nav.pause(0)
463 def doSeek(self, dir, seektime):
464 service = self.session.nav.getCurrentService()
468 seekable = service.seek()
471 seekable.seekRelative(dir, 90 * seektime)
474 self.doSeek(+1, 60000)
477 self.doSeek(-1, 60000)
479 class InfoBarInstantRecord:
480 """Instant Record - handles the instantRecord action in order to
481 start/stop instant records"""
483 self["InstantRecordActions"] = HelpableActionMap(self, "InfobarInstantRecord",
485 "instantRecord": (self.instantRecord, "Instant Record..."),
487 self.recording = None
489 self["BlinkingPoint"] = BlinkingPixmapConditional()
490 self.onShown.append(self["BlinkingPoint"].hideWidget)
491 self["BlinkingPoint"].setConnect(self.session.nav.RecordTimer.isRecording)
493 def stopCurrentRecording(self):
494 self.session.nav.RecordTimer.removeEntry(self.recording)
495 self.recording = None
497 def startInstantRecording(self):
498 serviceref = self.session.nav.getCurrentlyPlayingServiceReference()
500 # try to get event info
503 service = self.session.nav.getCurrentService()
504 info = service.info()
505 ev = info.getEvent(0)
510 # fix me, description.
511 self.recording = self.session.nav.recordWithTimer(time.time(), time.time() + 3600, serviceref, epg, "instant record")
512 self.recording.dontSave = True
514 #self["BlinkingPoint"].setConnect(lambda: self.recording.isRunning())
516 def isInstantRecordRunning(self):
517 if self.recording != None:
518 if self.recording.isRunning():
522 def recordQuestionCallback(self, answer):
526 if self.isInstantRecordRunning():
527 self.stopCurrentRecording()
529 self.startInstantRecording()
531 def instantRecord(self):
533 stat = os.stat("/hdd/movies")
535 self.session.open(MessageBox, "No HDD found!")
538 if self.isInstantRecordRunning():
539 self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Do you want to stop the current\n(instant) recording?"))
541 self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Start recording?"))
543 from Screens.AudioSelection import AudioSelection
545 class InfoBarAudioSelection:
547 self["AudioSelectionAction"] = HelpableActionMap(self, "InfobarAudioSelectionActions",
549 "audioSelection": (self.audioSelection, "Audio Options..."),
552 def audioSelection(self):
553 service = self.session.nav.getCurrentService()
554 audio = service.audioTracks()
555 n = audio.getNumberOfTracks()
557 self.session.open(AudioSelection, audio)
559 from Screens.SubserviceSelection import SubserviceSelection
561 class InfoBarSubserviceSelection:
563 self["SubserviceSelectionAction"] = HelpableActionMap(self, "InfobarSubserviceSelectionActions",
565 "subserviceSelection": (self.subserviceSelection, "Subservice list..."),
568 def subserviceSelection(self):
569 service = self.session.nav.getCurrentService()
570 subservices = service.subServices()
571 n = subservices.getNumberOfSubservices()
573 self.session.openWithCallback(self.subserviceSelected, SubserviceSelection, subservices)
575 def subserviceSelected(self, service):
576 if not service is None:
577 self.session.nav.playService(service)
579 class InfoBarAdditionalInfo:
581 self["DolbyActive"] = PixmapConditional()
582 # TODO: get the info from c++ somehow
583 self["DolbyActive"].setConnect(lambda: False)
585 self["CryptActive"] = PixmapConditional()
586 # TODO: get the info from c++ somehow
587 self["CryptActive"].setConnect(lambda: False)
589 self["FormatActive"] = PixmapConditional()
590 # TODO: get the info from c++ somehow
591 self["FormatActive"].setConnect(lambda: False)
593 self["ButtonRed"] = PixmapConditional(withTimer = False)
594 self["ButtonRed"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
595 self.onShown.append(self["ButtonRed"].update)
596 self["ButtonRedText"] = LabelConditional(text = _("Record"), withTimer = False)
597 self["ButtonRedText"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
598 self.onShown.append(self["ButtonRedText"].update)
600 self["ButtonGreen"] = PixmapConditional()
601 self["ButtonGreen"].setConnect(lambda: self.session.nav.getCurrentService().subServices().getNumberOfSubservices() > 0)
602 self["ButtonGreenText"] = LabelConditional(text = _("Subservices"))
603 self["ButtonGreenText"].setConnect(lambda: self.session.nav.getCurrentService().subServices().getNumberOfSubservices() > 0)
605 self["ButtonYellow"] = PixmapConditional()
606 self["ButtonYellow"].setConnect(lambda: False)
608 self["ButtonBlue"] = PixmapConditional()
609 self["ButtonBlue"].setConnect(lambda: False)
611 class InfoBarNotifications:
613 self.onExecBegin.append(self.checkNotifications)
614 Notifications.notificationAdded.append(self.checkNotificationsIfExecing)
616 def checkNotificationsIfExecing(self):
618 self.checkNotifications()
620 def checkNotifications(self):
621 if len(Notifications.notifications):
622 n = Notifications.notifications[0]
623 Notifications.notifications = Notifications.notifications[1:]
627 self.session.openWithCallback(cb, *n[1:])
629 self.session.open(*n[1:])