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.Standby import Standby
21 from Screens.EventView import EventView
23 from Tools import Notifications
25 #from enigma import eTimer, eDVBVolumecontrol, quitMainloop
32 from Menu import MainMenu, mdom
34 class InfoBarVolumeControl:
35 """Volume control, handles volUp, volDown, volMute actions and display
36 a corresponding dialog"""
38 config.audio = ConfigSubsection()
39 config.audio.volume = configElement("config.audio.volume", configSequence, [5], configsequencearg.get("INTEGER", (0, 100)))
41 self["VolumeActions"] = ActionMap( ["InfobarVolumeActions"] ,
43 "volumeUp": self.volUp,
44 "volumeDown": self.volDown,
45 "volumeMute": self.volMute,
48 self.volumeDialog = self.session.instantiateDialog(Volume)
49 self.muteDialog = self.session.instantiateDialog(Mute)
51 self.hideVolTimer = eTimer()
52 self.hideVolTimer.timeout.get().append(self.volHide)
54 vol = config.audio.volume.value[0]
55 self.volumeDialog.setValue(vol)
56 eDVBVolumecontrol.getInstance().setVolume(vol, vol)
59 config.audio.volume.value = eDVBVolumecontrol.getInstance().getVolume()
60 config.audio.volume.save()
63 if (eDVBVolumecontrol.getInstance().isMuted()):
65 eDVBVolumecontrol.getInstance().volumeUp()
66 self.volumeDialog.instance.show()
67 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
69 self.hideVolTimer.start(3000)
72 if (eDVBVolumecontrol.getInstance().isMuted()):
74 eDVBVolumecontrol.getInstance().volumeDown()
75 self.volumeDialog.instance.show()
76 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
78 self.hideVolTimer.start(3000)
81 self.volumeDialog.instance.hide()
84 eDVBVolumecontrol.getInstance().volumeToggleMute()
85 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
87 if (eDVBVolumecontrol.getInstance().isMuted()):
88 self.muteDialog.instance.show()
90 self.muteDialog.instance.hide()
92 class InfoBarShowHide:
93 """ InfoBar show/hide control, accepts toggleShow and hide actions, might start
101 self["ShowHideActions"] = ActionMap( ["InfobarShowHideActions"] ,
103 "toggleShow": self.toggleShow,
107 self.state = self.STATE_SHOWN
109 self.onExecBegin.append(self.show)
110 self.onClose.append(self.delHideTimer)
112 self.hideTimer = eTimer()
113 self.hideTimer.timeout.get().append(self.doTimerHide)
114 self.hideTimer.start(5000)
116 def delHideTimer(self):
123 self.state = self.STATE_SHOWN
124 self.hideTimer.stop()
125 self.hideTimer.start(5000)
127 def doTimerHide(self):
128 self.hideTimer.stop()
129 if self.state == self.STATE_SHOWN:
131 self.state = self.STATE_HIDDEN
133 def toggleShow(self):
134 if self.state == self.STATE_SHOWN:
136 #pls check animation support, sorry
138 self.hideTimer.stop()
139 self.state = self.STATE_HIDDEN
140 elif self.state == self.STATE_HIDDEN:
145 self.instance.m_animation.startMoveAnimation(ePoint(0, 600), ePoint(0, 380), 100)
146 self.state = self.STATE_SHOWN
149 self.instance.m_animation.startMoveAnimation(ePoint(0, 380), ePoint(0, 600), 100)
150 self.state = self.STATE_HIDDEN
152 class NumberZap(Screen):
159 self.close(int(self["number"].getText()))
161 def keyNumberGlobal(self, number):
162 self.Timer.start(3000) #reset timer
163 self.field = self.field + str(number)
164 self["number"].setText(self.field)
165 if len(self.field) >= 4:
168 def __init__(self, session, number):
169 Screen.__init__(self, session)
170 self.field = str(number)
172 self["channel"] = Label(_("Channel:"))
174 self["number"] = Label(self.field)
176 self["actions"] = NumberActionMap( [ "SetupActions" ],
180 "1": self.keyNumberGlobal,
181 "2": self.keyNumberGlobal,
182 "3": self.keyNumberGlobal,
183 "4": self.keyNumberGlobal,
184 "5": self.keyNumberGlobal,
185 "6": self.keyNumberGlobal,
186 "7": self.keyNumberGlobal,
187 "8": self.keyNumberGlobal,
188 "9": self.keyNumberGlobal,
189 "0": self.keyNumberGlobal
192 self.Timer = eTimer()
193 self.Timer.timeout.get().append(self.keyOK)
194 self.Timer.start(3000)
196 class InfoBarPowerKey:
197 """ PowerKey stuff - handles the powerkey press and powerkey release actions"""
200 self.powerKeyTimer = eTimer()
201 self.powerKeyTimer.timeout.get().append(self.powertimer)
202 self["PowerKeyActions"] = HelpableActionMap(self, "PowerKeyActions",
204 "powerdown": self.powerdown,
205 "powerup": self.powerup,
206 "discreteStandby": (self.standby, "Go standby"),
207 "discretePowerOff": (self.quit, "Go to deep standby"),
210 def powertimer(self):
211 print "PowerOff - Now!"
215 self.standbyblocked = 0
216 self.powerKeyTimer.start(3000)
219 self.powerKeyTimer.stop()
220 if self.standbyblocked == 0:
221 self.standbyblocked = 1
225 self.session.open(Standby, self)
231 class InfoBarNumberZap:
232 """ Handles an initial number for NumberZapping """
234 self["NumberZapActions"] = NumberActionMap( [ "NumberZapActions"],
236 "1": self.keyNumberGlobal,
237 "2": self.keyNumberGlobal,
238 "3": self.keyNumberGlobal,
239 "4": self.keyNumberGlobal,
240 "5": self.keyNumberGlobal,
241 "6": self.keyNumberGlobal,
242 "7": self.keyNumberGlobal,
243 "8": self.keyNumberGlobal,
244 "9": self.keyNumberGlobal,
245 "0": self.keyNumberGlobal,
248 def keyNumberGlobal(self, number):
249 # print "You pressed number " + str(number)
250 self.session.openWithCallback(self.numberEntered, NumberZap, number)
252 def numberEntered(self, retval):
253 # print self.servicelist
255 self.zapToNumber(retval)
257 def searchNumberHelper(self, serviceHandler, num, bouquet):
258 servicelist = serviceHandler.list(bouquet)
259 if not servicelist is None:
261 serviceIterator = servicelist.getNext()
262 if not serviceIterator.valid(): #check end of list
264 if serviceIterator.flags: #assume normal dvb service have no flags set
267 if not num: #found service with searched number ?
268 return serviceIterator, 0
271 def zapToNumber(self, number):
272 bouquet = self.servicelist.bouquet_root
274 serviceHandler = eServiceCenter.getInstance()
275 if bouquet.toString().find('FROM BOUQUET "bouquets.') == -1: #FIXME HACK
276 service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
278 bouquetlist = serviceHandler.list(bouquet)
279 if not bouquetlist is None:
281 bouquet = bouquetlist.getNext()
282 if not bouquet.valid(): #check end of list
284 if ((bouquet.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
286 service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
287 if not service is None:
288 self.session.nav.playService(service) #play service
289 if self.servicelist.getRoot() != bouquet: #already in correct bouquet?
290 self.servicelist.setRoot(bouquet)
291 self.servicelist.setCurrentSelection(service) #select the service in servicelist
293 class InfoBarChannelSelection:
294 """ ChannelSelection - handles the channelSelection dialog and the initial
295 channelChange actions which open the channelSelection dialog """
298 self.servicelist = self.session.instantiateDialog(ChannelSelection)
300 self["ChannelSelectActions"] = HelpableActionMap(self, "InfobarChannelSelection",
302 "switchChannelUp": self.switchChannelUp,
303 "switchChannelDown": self.switchChannelDown,
304 "zapUp": (self.zapUp, _("next channel")),
305 "zapDown": (self.zapDown, _("previous channel")),
308 def switchChannelUp(self):
309 self.servicelist.moveUp()
310 self.session.execDialog(self.servicelist)
312 def switchChannelDown(self):
313 self.servicelist.moveDown()
314 self.session.execDialog(self.servicelist)
317 self.servicelist.moveUp()
318 self.servicelist.zap()
323 self.servicelist.moveDown()
324 self.servicelist.zap()
329 """ Handles a menu action, to open the (main) menu """
331 self["MenuActions"] = HelpableActionMap(self, "InfobarMenuActions",
333 "mainMenu": (self.mainMenu, "Enter main menu..."),
337 print "loading mainmenu XML..."
338 menu = mdom.childNodes[0]
339 assert menu.tagName == "menu", "root element in menu must be 'menu'!"
340 self.session.open(MainMenu, menu, menu.childNodes)
343 """ EPG - Opens an EPG list when the showEPGList action fires """
345 self["EPGActions"] = HelpableActionMap(self, "InfobarEPGActions",
347 "showEPGList": (self.showEPGList, _("show EPG...")),
350 def showEPGList(self):
351 ref=self.session.nav.getCurrentlyPlayingServiceReference()
352 ptr=eEPGCache.getInstance()
353 if ptr.startTimeQuery(ref) != -1:
354 self.session.open(EPGSelection, ref)
355 else: # try to show now/next
356 print 'no epg for service', ref.toString()
359 service = self.session.nav.getCurrentService()
360 info = service.info()
363 self.epglist.append(ptr)
366 self.epglist.append(ptr)
367 if len(self.epglist) > 0:
368 self.session.open(EventView, self.epglist[0], ServiceReference(ref), self.eventViewCallback)
372 def eventViewCallback(self, setEvent, val): #used for now/next displaying
373 if len(self.epglist) > 1:
374 tmp = self.epglist[0]
375 self.epglist[0]=self.epglist[1]
377 setEvent(self.epglist[0])
380 """provides a current/next event info display"""
382 self["Event_Now_StartTime"] = EventInfo(self.session.nav, EventInfo.Now_StartTime)
383 self["Event_Next_StartTime"] = EventInfo(self.session.nav, EventInfo.Next_StartTime)
385 self["Event_Now"] = EventInfo(self.session.nav, EventInfo.Now)
386 self["Event_Next"] = EventInfo(self.session.nav, EventInfo.Next)
388 self["Event_Now_Duration"] = EventInfo(self.session.nav, EventInfo.Now_Duration)
389 self["Event_Next_Duration"] = EventInfo(self.session.nav, EventInfo.Next_Duration)
391 class InfoBarServiceName:
393 self["ServiceName"] = ServiceName(self.session.nav)
396 """handles PVR specific actions like seeking, pause"""
398 self["PVRActions"] = HelpableActionMap(self, "InfobarPVRActions",
400 "pauseService": (self.pauseService, "pause"),
401 "unPauseService": (self.unPauseService, "continue"),
403 "seekFwd": (self.seekFwd, "skip forward"),
404 "seekBack": (self.seekBack, "skip backward"),
407 def pauseService(self):
408 self.session.nav.pause(1)
410 def unPauseService(self):
411 self.session.nav.pause(0)
413 def doSeek(self, dir, seektime):
414 service = self.session.nav.getCurrentService()
418 seekable = service.seek()
421 seekable.seekRelative(dir, 90 * seektime)
424 self.doSeek(+1, 60000)
427 self.doSeek(-1, 60000)
429 class InfoBarInstantRecord:
430 """Instant Record - handles the instantRecord action in order to
431 start/stop instant records"""
433 self["InstantRecordActions"] = HelpableActionMap(self, "InfobarInstantRecord",
435 "instantRecord": (self.instantRecord, "Instant Record..."),
437 self.recording = None
439 self["BlinkingPoint"] = BlinkingPixmapConditional()
440 self.onShown.append(self["BlinkingPoint"].hidePixmap)
441 self["BlinkingPoint"].setConnect(self.session.nav.RecordTimer.isRecording)
443 def stopCurrentRecording(self):
444 self.session.nav.RecordTimer.removeEntry(self.recording)
445 self.recording = None
447 def startInstantRecording(self):
448 serviceref = self.session.nav.getCurrentlyPlayingServiceReference()
450 # try to get event info
453 service = self.session.nav.getCurrentService()
454 info = service.info()
455 ev = info.getEvent(0)
460 # fix me, description.
461 self.recording = self.session.nav.recordWithTimer(time.time(), time.time() + 3600, serviceref, epg, "instant record")
462 self.recording.dontSave = True
464 #self["BlinkingPoint"].setConnect(lambda: self.recording.isRunning())
466 def isInstantRecordRunning(self):
467 if self.recording != None:
468 if self.recording.isRunning():
472 def recordQuestionCallback(self, answer):
476 if self.isInstantRecordRunning():
477 self.stopCurrentRecording()
479 self.startInstantRecording()
481 def instantRecord(self):
483 stat = os.stat("/hdd/movies")
485 self.session.open(MessageBox, "No HDD found!")
488 if self.isInstantRecordRunning():
489 self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Do you want to stop the current\n(instant) recording?"))
491 self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Start recording?"))
493 from Screens.AudioSelection import AudioSelection
495 class InfoBarAudioSelection:
497 self["AudioSelectionAction"] = HelpableActionMap(self, "InfobarAudioSelectionActions",
499 "audioSelection": (self.audioSelection, "Audio Options..."),
502 def audioSelection(self):
503 service = self.session.nav.getCurrentService()
504 audio = service.audioTracks()
505 n = audio.getNumberOfTracks()
507 self.session.open(AudioSelection, audio)
509 class InfoBarAdditionalInfo:
511 self["DolbyActive"] = PixmapConditional()
512 # TODO: get the info from c++ somehow
513 self["DolbyActive"].setConnect(lambda: False)
515 self["CryptActive"] = PixmapConditional()
516 # TODO: get the info from c++ somehow
517 self["CryptActive"].setConnect(lambda: False)
519 self["FormatActive"] = PixmapConditional()
520 # TODO: get the info from c++ somehow
521 self["FormatActive"].setConnect(lambda: False)
523 self["ButtonRed"] = Pixmap()
524 self["ButtonRedText"] = Label(_("Record"))
525 self["ButtonGreen"] = Pixmap()
526 self["ButtonYellow"] = Pixmap()
527 self["ButtonBlue"] = Pixmap()
529 class InfoBarNotifications:
531 self.onExecBegin.append(self.checkNotifications)
532 Notifications.notificationAdded.append(self.checkNotificationsIfExecing)
534 def checkNotificationsIfExecing(self):
536 self.checkNotifications()
538 def checkNotifications(self):
539 if len(Notifications.notifications):
540 n = Notifications.notifications[0]
541 Notifications.notifications = Notifications.notifications[1:]
545 self.session.openWithCallback(cb, *n[1:])
547 self.session.open(*n[1:])