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.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
23 from Components.Harddisk import harddiskmanager
25 from Tools import Notifications
27 #from enigma import eTimer, eDVBVolumecontrol, quitMainloop
34 from Menu import MainMenu, mdom
36 class InfoBarVolumeControl:
37 """Volume control, handles volUp, volDown, volMute actions and display
38 a corresponding dialog"""
40 config.audio = ConfigSubsection()
41 config.audio.volume = configElement("config.audio.volume", configSequence, [5], configsequencearg.get("INTEGER", (0, 100)))
43 self["VolumeActions"] = ActionMap( ["InfobarVolumeActions"] ,
45 "volumeUp": self.volUp,
46 "volumeDown": self.volDown,
47 "volumeMute": self.volMute,
50 self.volumeDialog = self.session.instantiateDialog(Volume)
51 self.muteDialog = self.session.instantiateDialog(Mute)
53 self.hideVolTimer = eTimer()
54 self.hideVolTimer.timeout.get().append(self.volHide)
56 vol = config.audio.volume.value[0]
57 self.volumeDialog.setValue(vol)
58 eDVBVolumecontrol.getInstance().setVolume(vol, vol)
61 config.audio.volume.value = eDVBVolumecontrol.getInstance().getVolume()
62 config.audio.volume.save()
65 if (eDVBVolumecontrol.getInstance().isMuted()):
67 eDVBVolumecontrol.getInstance().volumeUp()
68 self.volumeDialog.instance.show()
69 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
71 self.hideVolTimer.start(3000)
74 if (eDVBVolumecontrol.getInstance().isMuted()):
76 eDVBVolumecontrol.getInstance().volumeDown()
77 self.volumeDialog.instance.show()
78 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
80 self.hideVolTimer.start(3000)
83 self.volumeDialog.instance.hide()
86 eDVBVolumecontrol.getInstance().volumeToggleMute()
87 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
89 if (eDVBVolumecontrol.getInstance().isMuted()):
90 self.muteDialog.instance.show()
92 self.muteDialog.instance.hide()
96 self.dishDialog = self.session.instantiateDialog(Dish)
97 self.onShown.append(self.dishDialog.instance.hide)
99 class InfoBarShowHide:
100 """ InfoBar show/hide control, accepts toggleShow and hide actions, might start
101 fancy animations. """
108 self["ShowHideActions"] = ActionMap( ["InfobarShowHideActions"] ,
110 "toggleShow": self.toggleShow,
114 self.state = self.STATE_SHOWN
116 self.onExecBegin.append(self.show)
117 self.onClose.append(self.delHideTimer)
119 self.hideTimer = eTimer()
120 self.hideTimer.timeout.get().append(self.doTimerHide)
121 self.hideTimer.start(5000)
123 def delHideTimer(self):
130 self.state = self.STATE_SHOWN
131 self.hideTimer.stop()
132 self.hideTimer.start(5000)
134 def doTimerHide(self):
135 self.hideTimer.stop()
136 if self.state == self.STATE_SHOWN:
138 self.state = self.STATE_HIDDEN
140 def toggleShow(self):
141 if self.state == self.STATE_SHOWN:
143 #pls check animation support, sorry
145 self.hideTimer.stop()
146 self.state = self.STATE_HIDDEN
147 elif self.state == self.STATE_HIDDEN:
152 self.instance.m_animation.startMoveAnimation(ePoint(0, 600), ePoint(0, 380), 100)
153 self.state = self.STATE_SHOWN
156 self.instance.m_animation.startMoveAnimation(ePoint(0, 380), ePoint(0, 600), 100)
157 self.state = self.STATE_HIDDEN
159 class NumberZap(Screen):
166 self.close(int(self["number"].getText()))
168 def keyNumberGlobal(self, number):
169 self.Timer.start(3000) #reset timer
170 self.field = self.field + str(number)
171 self["number"].setText(self.field)
172 if len(self.field) >= 4:
175 def __init__(self, session, number):
176 Screen.__init__(self, session)
177 self.field = str(number)
179 self["channel"] = Label(_("Channel:"))
181 self["number"] = Label(self.field)
183 self["actions"] = NumberActionMap( [ "SetupActions" ],
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 self.Timer = eTimer()
200 self.Timer.timeout.get().append(self.keyOK)
201 self.Timer.start(3000)
203 class InfoBarPowerKey:
204 """ PowerKey stuff - handles the powerkey press and powerkey release actions"""
207 self.powerKeyTimer = eTimer()
208 self.powerKeyTimer.timeout.get().append(self.powertimer)
209 self["PowerKeyActions"] = HelpableActionMap(self, "PowerKeyActions",
211 "powerdown": self.powerdown,
212 "powerup": self.powerup,
213 "discreteStandby": (self.standby, "Go standby"),
214 "discretePowerOff": (self.quit, "Go to deep standby"),
217 def powertimer(self):
218 print "PowerOff - Now!"
222 self.standbyblocked = 0
223 self.powerKeyTimer.start(3000)
226 self.powerKeyTimer.stop()
227 if self.standbyblocked == 0:
228 self.standbyblocked = 1
232 self.session.open(Standby, self)
238 class InfoBarNumberZap:
239 """ Handles an initial number for NumberZapping """
241 self["NumberZapActions"] = NumberActionMap( [ "NumberZapActions"],
243 "1": self.keyNumberGlobal,
244 "2": self.keyNumberGlobal,
245 "3": self.keyNumberGlobal,
246 "4": self.keyNumberGlobal,
247 "5": self.keyNumberGlobal,
248 "6": self.keyNumberGlobal,
249 "7": self.keyNumberGlobal,
250 "8": self.keyNumberGlobal,
251 "9": self.keyNumberGlobal,
252 "0": self.keyNumberGlobal,
255 def keyNumberGlobal(self, number):
256 # print "You pressed number " + str(number)
257 self.session.openWithCallback(self.numberEntered, NumberZap, number)
259 def numberEntered(self, retval):
260 # print self.servicelist
262 self.zapToNumber(retval)
264 def searchNumberHelper(self, serviceHandler, num, bouquet):
265 servicelist = serviceHandler.list(bouquet)
266 if not servicelist is None:
268 serviceIterator = servicelist.getNext()
269 if not serviceIterator.valid(): #check end of list
271 if serviceIterator.flags: #assume normal dvb service have no flags set
274 if not num: #found service with searched number ?
275 return serviceIterator, 0
278 def zapToNumber(self, number):
279 bouquet = self.servicelist.bouquet_root
281 serviceHandler = eServiceCenter.getInstance()
282 if bouquet.toString().find('FROM BOUQUET "bouquets.') == -1: #FIXME HACK
283 service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
285 bouquetlist = serviceHandler.list(bouquet)
286 if not bouquetlist is None:
288 bouquet = bouquetlist.getNext()
289 if not bouquet.valid(): #check end of list
291 if ((bouquet.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
293 service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
294 if not service is None:
295 self.session.nav.playService(service) #play service
296 if self.servicelist.getRoot() != bouquet: #already in correct bouquet?
297 self.servicelist.setRoot(bouquet)
298 self.servicelist.setCurrentSelection(service) #select the service in servicelist
300 class InfoBarChannelSelection:
301 """ ChannelSelection - handles the channelSelection dialog and the initial
302 channelChange actions which open the channelSelection dialog """
305 self.servicelist = self.session.instantiateDialog(ChannelSelection)
307 self["ChannelSelectActions"] = HelpableActionMap(self, "InfobarChannelSelection",
309 "switchChannelUp": self.switchChannelUp,
310 "switchChannelDown": self.switchChannelDown,
311 "zapUp": (self.zapUp, _("next channel")),
312 "zapDown": (self.zapDown, _("previous channel")),
315 def switchChannelUp(self):
316 self.servicelist.moveUp()
317 self.session.execDialog(self.servicelist)
319 def switchChannelDown(self):
320 self.servicelist.moveDown()
321 self.session.execDialog(self.servicelist)
324 self.servicelist.moveUp()
325 self.servicelist.zap()
330 self.servicelist.moveDown()
331 self.servicelist.zap()
336 """ Handles a menu action, to open the (main) menu """
338 self["MenuActions"] = HelpableActionMap(self, "InfobarMenuActions",
340 "mainMenu": (self.mainMenu, "Enter main menu..."),
344 print "loading mainmenu XML..."
345 menu = mdom.childNodes[0]
346 assert menu.tagName == "menu", "root element in menu must be 'menu'!"
347 self.session.open(MainMenu, menu, menu.childNodes)
350 """ EPG - Opens an EPG list when the showEPGList action fires """
352 self["EPGActions"] = HelpableActionMap(self, "InfobarEPGActions",
354 "showEPGList": (self.showEPGList, _("show EPG...")),
357 def showEPGList(self):
358 ref=self.session.nav.getCurrentlyPlayingServiceReference()
359 ptr=eEPGCache.getInstance()
360 if ptr.startTimeQuery(ref) != -1:
361 self.session.open(EPGSelection, ref)
362 else: # try to show now/next
363 print 'no epg for service', ref.toString()
366 service = self.session.nav.getCurrentService()
367 info = service.info()
370 self.epglist.append(ptr)
373 self.epglist.append(ptr)
374 if len(self.epglist) > 0:
375 self.session.open(EventView, self.epglist[0], ServiceReference(ref), self.eventViewCallback)
379 def eventViewCallback(self, setEvent, val): #used for now/next displaying
380 if len(self.epglist) > 1:
381 tmp = self.epglist[0]
382 self.epglist[0]=self.epglist[1]
384 setEvent(self.epglist[0])
387 """provides a current/next event info display"""
389 self["Event_Now_StartTime"] = EventInfo(self.session.nav, EventInfo.Now_StartTime)
390 self["Event_Next_StartTime"] = EventInfo(self.session.nav, EventInfo.Next_StartTime)
392 self["Event_Now"] = EventInfo(self.session.nav, EventInfo.Now)
393 self["Event_Next"] = EventInfo(self.session.nav, EventInfo.Next)
395 self["Event_Now_Duration"] = EventInfo(self.session.nav, EventInfo.Now_Duration)
396 self["Event_Next_Duration"] = EventInfo(self.session.nav, EventInfo.Next_Duration)
398 class InfoBarServiceName:
400 self["ServiceName"] = ServiceName(self.session.nav)
403 """handles PVR specific actions like seeking, pause"""
405 self["PVRActions"] = HelpableActionMap(self, "InfobarPVRActions",
407 "pauseService": (self.pauseService, "pause"),
408 "unPauseService": (self.unPauseService, "continue"),
410 "seekFwd": (self.seekFwd, "skip forward"),
411 "seekBack": (self.seekBack, "skip backward"),
414 def pauseService(self):
415 self.session.nav.pause(1)
417 def unPauseService(self):
418 self.session.nav.pause(0)
420 def doSeek(self, dir, seektime):
421 service = self.session.nav.getCurrentService()
425 seekable = service.seek()
428 seekable.seekRelative(dir, 90 * seektime)
431 self.doSeek(+1, 60000)
434 self.doSeek(-1, 60000)
436 class InfoBarInstantRecord:
437 """Instant Record - handles the instantRecord action in order to
438 start/stop instant records"""
440 self["InstantRecordActions"] = HelpableActionMap(self, "InfobarInstantRecord",
442 "instantRecord": (self.instantRecord, "Instant Record..."),
444 self.recording = None
446 self["BlinkingPoint"] = BlinkingPixmapConditional()
447 self.onShown.append(self["BlinkingPoint"].hideWidget)
448 self["BlinkingPoint"].setConnect(self.session.nav.RecordTimer.isRecording)
450 def stopCurrentRecording(self):
451 self.session.nav.RecordTimer.removeEntry(self.recording)
452 self.recording = None
454 def startInstantRecording(self):
455 serviceref = self.session.nav.getCurrentlyPlayingServiceReference()
457 # try to get event info
460 service = self.session.nav.getCurrentService()
461 info = service.info()
462 ev = info.getEvent(0)
467 # fix me, description.
468 self.recording = self.session.nav.recordWithTimer(time.time(), time.time() + 3600, serviceref, epg, "instant record")
469 self.recording.dontSave = True
471 #self["BlinkingPoint"].setConnect(lambda: self.recording.isRunning())
473 def isInstantRecordRunning(self):
474 if self.recording != None:
475 if self.recording.isRunning():
479 def recordQuestionCallback(self, answer):
483 if self.isInstantRecordRunning():
484 self.stopCurrentRecording()
486 self.startInstantRecording()
488 def instantRecord(self):
490 stat = os.stat("/hdd/movies")
492 self.session.open(MessageBox, "No HDD found!")
495 if self.isInstantRecordRunning():
496 self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Do you want to stop the current\n(instant) recording?"))
498 self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Start recording?"))
500 from Screens.AudioSelection import AudioSelection
502 class InfoBarAudioSelection:
504 self["AudioSelectionAction"] = HelpableActionMap(self, "InfobarAudioSelectionActions",
506 "audioSelection": (self.audioSelection, "Audio Options..."),
509 def audioSelection(self):
510 service = self.session.nav.getCurrentService()
511 audio = service.audioTracks()
512 n = audio.getNumberOfTracks()
514 self.session.open(AudioSelection, audio)
516 from Screens.SubserviceSelection import SubserviceSelection
518 class InfoBarSubserviceSelection:
520 self["SubserviceSelectionAction"] = HelpableActionMap(self, "InfobarSubserviceSelectionActions",
522 "subserviceSelection": (self.subserviceSelection, "Subservice list..."),
525 def subserviceSelection(self):
526 service = self.session.nav.getCurrentService()
527 subservices = service.subServices()
528 n = subservices.getNumberOfSubservices()
530 self.session.openWithCallback(self.subserviceSelected, SubserviceSelection, subservices)
532 def subserviceSelected(self, service):
533 if not service is None:
534 self.session.nav.playService(service)
536 class InfoBarAdditionalInfo:
538 self["DolbyActive"] = PixmapConditional()
539 # TODO: get the info from c++ somehow
540 self["DolbyActive"].setConnect(lambda: False)
542 self["CryptActive"] = PixmapConditional()
543 # TODO: get the info from c++ somehow
544 self["CryptActive"].setConnect(lambda: False)
546 self["FormatActive"] = PixmapConditional()
547 # TODO: get the info from c++ somehow
548 self["FormatActive"].setConnect(lambda: False)
550 self["ButtonRed"] = PixmapConditional(withTimer = False)
551 self["ButtonRed"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
552 self.onShown.append(self["ButtonRed"].update)
553 self["ButtonRedText"] = LabelConditional(text = _("Record"), withTimer = False)
554 self["ButtonRedText"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
555 self.onShown.append(self["ButtonRedText"].update)
557 self["ButtonGreen"] = PixmapConditional()
558 self["ButtonGreen"].setConnect(lambda: self.session.nav.getCurrentService().subServices().getNumberOfSubservices() > 0)
559 self["ButtonGreenText"] = LabelConditional(text = _("Subservices"))
560 self["ButtonGreenText"].setConnect(lambda: self.session.nav.getCurrentService().subServices().getNumberOfSubservices() > 0)
562 self["ButtonYellow"] = PixmapConditional()
563 self["ButtonYellow"].setConnect(lambda: False)
565 self["ButtonBlue"] = PixmapConditional()
566 self["ButtonBlue"].setConnect(lambda: False)
568 class InfoBarNotifications:
570 self.onExecBegin.append(self.checkNotifications)
571 Notifications.notificationAdded.append(self.checkNotificationsIfExecing)
573 def checkNotificationsIfExecing(self):
575 self.checkNotifications()
577 def checkNotifications(self):
578 if len(Notifications.notifications):
579 n = Notifications.notifications[0]
580 Notifications.notifications = Notifications.notifications[1:]
584 self.session.openWithCallback(cb, *n[1:])
586 self.session.open(*n[1:])