1 from Screen import Screen
2 from Components.ActionMap import ActionMap, HelpableActionMap
3 from Components.ActionMap import NumberActionMap
4 from Components.Label import Label
5 from Components.config import configfile, configsequencearg
6 from Components.config import config, configElement, ConfigSubsection, configSequence
7 from ChannelSelection import ChannelSelection
9 from Components.Pixmap import Pixmap, PixmapConditional
10 from Components.BlinkingPixmap import BlinkingPixmapConditional
11 from Components.ServiceName import ServiceName
12 from Components.EventInfo import EventInfo
14 from ServiceReference import ServiceReference
15 from EpgSelection import EPGSelection
17 from Screens.MessageBox import MessageBox
18 from Screens.Volume import Volume
19 from Screens.Mute import Mute
20 from Screens.Dish import Dish
21 from Screens.Standby import Standby
22 from Screens.EventView import EventView
24 from Tools import Notifications
26 #from enigma import eTimer, eDVBVolumecontrol, quitMainloop
33 from Menu import MainMenu, mdom
35 class InfoBarVolumeControl:
36 """Volume control, handles volUp, volDown, volMute actions and display
37 a corresponding dialog"""
39 config.audio = ConfigSubsection()
40 config.audio.volume = configElement("config.audio.volume", configSequence, [5], configsequencearg.get("INTEGER", (0, 100)))
42 self["VolumeActions"] = ActionMap( ["InfobarVolumeActions"] ,
44 "volumeUp": self.volUp,
45 "volumeDown": self.volDown,
46 "volumeMute": self.volMute,
49 self.volumeDialog = self.session.instantiateDialog(Volume)
50 self.muteDialog = self.session.instantiateDialog(Mute)
52 self.hideVolTimer = eTimer()
53 self.hideVolTimer.timeout.get().append(self.volHide)
55 vol = config.audio.volume.value[0]
56 self.volumeDialog.setValue(vol)
57 eDVBVolumecontrol.getInstance().setVolume(vol, vol)
60 config.audio.volume.value = eDVBVolumecontrol.getInstance().getVolume()
61 config.audio.volume.save()
64 if (eDVBVolumecontrol.getInstance().isMuted()):
66 eDVBVolumecontrol.getInstance().volumeUp()
67 self.volumeDialog.instance.show()
68 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
70 self.hideVolTimer.start(3000)
73 if (eDVBVolumecontrol.getInstance().isMuted()):
75 eDVBVolumecontrol.getInstance().volumeDown()
76 self.volumeDialog.instance.show()
77 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
79 self.hideVolTimer.start(3000)
82 self.volumeDialog.instance.hide()
85 eDVBVolumecontrol.getInstance().volumeToggleMute()
86 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
88 if (eDVBVolumecontrol.getInstance().isMuted()):
89 self.muteDialog.instance.show()
91 self.muteDialog.instance.hide()
95 self.dishDialog = self.session.instantiateDialog(Dish)
96 self.onShown.append(self.dishDialog.instance.show)
98 class InfoBarShowHide:
99 """ InfoBar show/hide control, accepts toggleShow and hide actions, might start
100 fancy animations. """
107 self["ShowHideActions"] = ActionMap( ["InfobarShowHideActions"] ,
109 "toggleShow": self.toggleShow,
113 self.state = self.STATE_SHOWN
115 self.onExecBegin.append(self.show)
116 self.onClose.append(self.delHideTimer)
118 self.hideTimer = eTimer()
119 self.hideTimer.timeout.get().append(self.doTimerHide)
120 self.hideTimer.start(5000)
122 def delHideTimer(self):
129 self.state = self.STATE_SHOWN
130 self.hideTimer.stop()
131 self.hideTimer.start(5000)
133 def doTimerHide(self):
134 self.hideTimer.stop()
135 if self.state == self.STATE_SHOWN:
137 self.state = self.STATE_HIDDEN
139 def toggleShow(self):
140 if self.state == self.STATE_SHOWN:
142 #pls check animation support, sorry
144 self.hideTimer.stop()
145 self.state = self.STATE_HIDDEN
146 elif self.state == self.STATE_HIDDEN:
151 self.instance.m_animation.startMoveAnimation(ePoint(0, 600), ePoint(0, 380), 100)
152 self.state = self.STATE_SHOWN
155 self.instance.m_animation.startMoveAnimation(ePoint(0, 380), ePoint(0, 600), 100)
156 self.state = self.STATE_HIDDEN
158 class NumberZap(Screen):
165 self.close(int(self["number"].getText()))
167 def keyNumberGlobal(self, number):
168 self.Timer.start(3000) #reset timer
169 self.field = self.field + str(number)
170 self["number"].setText(self.field)
171 if len(self.field) >= 4:
174 def __init__(self, session, number):
175 Screen.__init__(self, session)
176 self.field = str(number)
178 self["channel"] = Label(_("Channel:"))
180 self["number"] = Label(self.field)
182 self["actions"] = NumberActionMap( [ "SetupActions" ],
186 "1": self.keyNumberGlobal,
187 "2": self.keyNumberGlobal,
188 "3": self.keyNumberGlobal,
189 "4": self.keyNumberGlobal,
190 "5": self.keyNumberGlobal,
191 "6": self.keyNumberGlobal,
192 "7": self.keyNumberGlobal,
193 "8": self.keyNumberGlobal,
194 "9": self.keyNumberGlobal,
195 "0": self.keyNumberGlobal
198 self.Timer = eTimer()
199 self.Timer.timeout.get().append(self.keyOK)
200 self.Timer.start(3000)
202 class InfoBarPowerKey:
203 """ PowerKey stuff - handles the powerkey press and powerkey release actions"""
206 self.powerKeyTimer = eTimer()
207 self.powerKeyTimer.timeout.get().append(self.powertimer)
208 self["PowerKeyActions"] = HelpableActionMap(self, "PowerKeyActions",
210 "powerdown": self.powerdown,
211 "powerup": self.powerup,
212 "discreteStandby": (self.standby, "Go standby"),
213 "discretePowerOff": (self.quit, "Go to deep standby"),
216 def powertimer(self):
217 print "PowerOff - Now!"
221 self.standbyblocked = 0
222 self.powerKeyTimer.start(3000)
225 self.powerKeyTimer.stop()
226 if self.standbyblocked == 0:
227 self.standbyblocked = 1
231 self.session.open(Standby, self)
237 class InfoBarNumberZap:
238 """ Handles an initial number for NumberZapping """
240 self["NumberZapActions"] = NumberActionMap( [ "NumberZapActions"],
242 "1": self.keyNumberGlobal,
243 "2": self.keyNumberGlobal,
244 "3": self.keyNumberGlobal,
245 "4": self.keyNumberGlobal,
246 "5": self.keyNumberGlobal,
247 "6": self.keyNumberGlobal,
248 "7": self.keyNumberGlobal,
249 "8": self.keyNumberGlobal,
250 "9": self.keyNumberGlobal,
251 "0": self.keyNumberGlobal,
254 def keyNumberGlobal(self, number):
255 # print "You pressed number " + str(number)
256 self.session.openWithCallback(self.numberEntered, NumberZap, number)
258 def numberEntered(self, retval):
259 # print self.servicelist
261 self.zapToNumber(retval)
263 def searchNumberHelper(self, serviceHandler, num, bouquet):
264 servicelist = serviceHandler.list(bouquet)
265 if not servicelist is None:
267 serviceIterator = servicelist.getNext()
268 if not serviceIterator.valid(): #check end of list
270 if serviceIterator.flags: #assume normal dvb service have no flags set
273 if not num: #found service with searched number ?
274 return serviceIterator, 0
277 def zapToNumber(self, number):
278 bouquet = self.servicelist.bouquet_root
280 serviceHandler = eServiceCenter.getInstance()
281 if bouquet.toString().find('FROM BOUQUET "bouquets.') == -1: #FIXME HACK
282 service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
284 bouquetlist = serviceHandler.list(bouquet)
285 if not bouquetlist is None:
287 bouquet = bouquetlist.getNext()
288 if not bouquet.valid(): #check end of list
290 if ((bouquet.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
292 service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
293 if not service is None:
294 self.session.nav.playService(service) #play service
295 if self.servicelist.getRoot() != bouquet: #already in correct bouquet?
296 self.servicelist.setRoot(bouquet)
297 self.servicelist.setCurrentSelection(service) #select the service in servicelist
299 class InfoBarChannelSelection:
300 """ ChannelSelection - handles the channelSelection dialog and the initial
301 channelChange actions which open the channelSelection dialog """
304 self.servicelist = self.session.instantiateDialog(ChannelSelection)
306 self["ChannelSelectActions"] = HelpableActionMap(self, "InfobarChannelSelection",
308 "switchChannelUp": self.switchChannelUp,
309 "switchChannelDown": self.switchChannelDown,
310 "zapUp": (self.zapUp, _("next channel")),
311 "zapDown": (self.zapDown, _("previous channel")),
314 def switchChannelUp(self):
315 self.servicelist.moveUp()
316 self.session.execDialog(self.servicelist)
318 def switchChannelDown(self):
319 self.servicelist.moveDown()
320 self.session.execDialog(self.servicelist)
323 self.servicelist.moveUp()
324 self.servicelist.zap()
329 self.servicelist.moveDown()
330 self.servicelist.zap()
335 """ Handles a menu action, to open the (main) menu """
337 self["MenuActions"] = HelpableActionMap(self, "InfobarMenuActions",
339 "mainMenu": (self.mainMenu, "Enter main menu..."),
343 print "loading mainmenu XML..."
344 menu = mdom.childNodes[0]
345 assert menu.tagName == "menu", "root element in menu must be 'menu'!"
346 self.session.open(MainMenu, menu, menu.childNodes)
349 """ EPG - Opens an EPG list when the showEPGList action fires """
351 self["EPGActions"] = HelpableActionMap(self, "InfobarEPGActions",
353 "showEPGList": (self.showEPGList, _("show EPG...")),
356 def showEPGList(self):
357 ref=self.session.nav.getCurrentlyPlayingServiceReference()
358 ptr=eEPGCache.getInstance()
359 if ptr.startTimeQuery(ref) != -1:
360 self.session.open(EPGSelection, ref)
361 else: # try to show now/next
362 print 'no epg for service', ref.toString()
365 service = self.session.nav.getCurrentService()
366 info = service.info()
369 self.epglist.append(ptr)
372 self.epglist.append(ptr)
373 if len(self.epglist) > 0:
374 self.session.open(EventView, self.epglist[0], ServiceReference(ref), self.eventViewCallback)
378 def eventViewCallback(self, setEvent, val): #used for now/next displaying
379 if len(self.epglist) > 1:
380 tmp = self.epglist[0]
381 self.epglist[0]=self.epglist[1]
383 setEvent(self.epglist[0])
386 """provides a current/next event info display"""
388 self["Event_Now_StartTime"] = EventInfo(self.session.nav, EventInfo.Now_StartTime)
389 self["Event_Next_StartTime"] = EventInfo(self.session.nav, EventInfo.Next_StartTime)
391 self["Event_Now"] = EventInfo(self.session.nav, EventInfo.Now)
392 self["Event_Next"] = EventInfo(self.session.nav, EventInfo.Next)
394 self["Event_Now_Duration"] = EventInfo(self.session.nav, EventInfo.Now_Duration)
395 self["Event_Next_Duration"] = EventInfo(self.session.nav, EventInfo.Next_Duration)
397 class InfoBarServiceName:
399 self["ServiceName"] = ServiceName(self.session.nav)
402 """handles PVR specific actions like seeking, pause"""
404 self["PVRActions"] = HelpableActionMap(self, "InfobarPVRActions",
406 "pauseService": (self.pauseService, "pause"),
407 "unPauseService": (self.unPauseService, "continue"),
409 "seekFwd": (self.seekFwd, "skip forward"),
410 "seekBack": (self.seekBack, "skip backward"),
413 def pauseService(self):
414 self.session.nav.pause(1)
416 def unPauseService(self):
417 self.session.nav.pause(0)
419 def doSeek(self, dir, seektime):
420 service = self.session.nav.getCurrentService()
424 seekable = service.seek()
427 seekable.seekRelative(dir, 90 * seektime)
430 self.doSeek(+1, 60000)
433 self.doSeek(-1, 60000)
435 class InfoBarInstantRecord:
436 """Instant Record - handles the instantRecord action in order to
437 start/stop instant records"""
439 self["InstantRecordActions"] = HelpableActionMap(self, "InfobarInstantRecord",
441 "instantRecord": (self.instantRecord, "Instant Record..."),
443 self.recording = None
445 self["BlinkingPoint"] = BlinkingPixmapConditional()
446 self.onShown.append(self["BlinkingPoint"].hidePixmap)
447 self["BlinkingPoint"].setConnect(self.session.nav.RecordTimer.isRecording)
449 def stopCurrentRecording(self):
450 self.session.nav.RecordTimer.removeEntry(self.recording)
451 self.recording = None
453 def startInstantRecording(self):
454 serviceref = self.session.nav.getCurrentlyPlayingServiceReference()
456 # try to get event info
459 service = self.session.nav.getCurrentService()
460 info = service.info()
461 ev = info.getEvent(0)
466 # fix me, description.
467 self.recording = self.session.nav.recordWithTimer(time.time(), time.time() + 3600, serviceref, epg, "instant record")
468 self.recording.dontSave = True
470 #self["BlinkingPoint"].setConnect(lambda: self.recording.isRunning())
472 def isInstantRecordRunning(self):
473 if self.recording != None:
474 if self.recording.isRunning():
478 def recordQuestionCallback(self, answer):
482 if self.isInstantRecordRunning():
483 self.stopCurrentRecording()
485 self.startInstantRecording()
487 def instantRecord(self):
489 stat = os.stat("/hdd/movies")
491 self.session.open(MessageBox, "No HDD found!")
494 if self.isInstantRecordRunning():
495 self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Do you want to stop the current\n(instant) recording?"))
497 self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Start recording?"))
499 from Screens.AudioSelection import AudioSelection
501 class InfoBarAudioSelection:
503 self["AudioSelectionAction"] = HelpableActionMap(self, "InfobarAudioSelectionActions",
505 "audioSelection": (self.audioSelection, "Audio Options..."),
508 def audioSelection(self):
509 service = self.session.nav.getCurrentService()
510 audio = service.audioTracks()
511 n = audio.getNumberOfTracks()
513 self.session.open(AudioSelection, audio)
515 from Screens.SubserviceSelection import SubserviceSelection
517 class InfoBarSubserviceSelection:
519 self["SubserviceSelectionAction"] = HelpableActionMap(self, "InfobarSubserviceSelectionActions",
521 "subserviceSelection": (self.subserviceSelection, "Subservice list..."),
524 def subserviceSelection(self):
525 service = self.session.nav.getCurrentService()
526 subservices = service.subServices()
527 n = subservices.getNumberOfSubservices()
529 self.session.openWithCallback(self.subserviceSelected, SubserviceSelection, subservices)
531 def subserviceSelected(self, service):
532 if not service is None:
533 self.session.nav.playService(service)
535 class InfoBarAdditionalInfo:
537 self["DolbyActive"] = PixmapConditional()
538 # TODO: get the info from c++ somehow
539 self["DolbyActive"].setConnect(lambda: False)
541 self["CryptActive"] = PixmapConditional()
542 # TODO: get the info from c++ somehow
543 self["CryptActive"].setConnect(lambda: False)
545 self["FormatActive"] = PixmapConditional()
546 # TODO: get the info from c++ somehow
547 self["FormatActive"].setConnect(lambda: False)
549 self["ButtonRed"] = Pixmap()
550 self["ButtonRedText"] = Label(_("Record"))
551 self["ButtonGreen"] = Pixmap()
552 self["ButtonGreenText"] = Label(_("Subservices"))
553 # self["ButtonGreenText"].hide()
554 # self["ButtonGreen"].hidePixmap()
555 # self["ButtonYellow"] = Pixmap()
556 # self["ButtonBlue"] = Pixmap()
558 class InfoBarNotifications:
560 self.onExecBegin.append(self.checkNotifications)
561 Notifications.notificationAdded.append(self.checkNotificationsIfExecing)
563 def checkNotificationsIfExecing(self):
565 self.checkNotifications()
567 def checkNotifications(self):
568 if len(Notifications.notifications):
569 n = Notifications.notifications[0]
570 Notifications.notifications = Notifications.notifications[1:]
574 self.session.openWithCallback(cb, *n[1:])
576 self.session.open(*n[1:])