pvr: add inductors
[vuplus_dvbapp] / lib / python / Screens / InfoBarGenerics.py
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
9
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
14
15 from ServiceReference import ServiceReference
16 from EpgSelection import EPGSelection
17
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
25
26 from Tools import Notifications
27
28 #from enigma import eTimer, eDVBVolumecontrol, quitMainloop
29 from enigma import *
30
31 import time
32 import os
33
34 # hack alert!
35 from Menu import MainMenu, mdom
36
37 class InfoBarVolumeControl:
38         """Volume control, handles volUp, volDown, volMute actions and display 
39         a corresponding dialog"""
40         def __init__(self):
41                 config.audio = ConfigSubsection()
42                 config.audio.volume = configElement("config.audio.volume", configSequence, [5], configsequencearg.get("INTEGER", (0, 100)))
43
44                 self["VolumeActions"] = ActionMap( ["InfobarVolumeActions"] ,
45                         {
46                                 "volumeUp": self.volUp,
47                                 "volumeDown": self.volDown,
48                                 "volumeMute": self.volMute,
49                         })
50
51                 self.volumeDialog = self.session.instantiateDialog(Volume)
52                 self.muteDialog = self.session.instantiateDialog(Mute)
53
54                 self.hideVolTimer = eTimer()
55                 self.hideVolTimer.timeout.get().append(self.volHide)
56
57                 vol = config.audio.volume.value[0]
58                 self.volumeDialog.setValue(vol)
59                 eDVBVolumecontrol.getInstance().setVolume(vol, vol)
60         
61         def volSave(self):
62                 config.audio.volume.value = eDVBVolumecontrol.getInstance().getVolume()
63                 config.audio.volume.save()
64                 
65         def     volUp(self):
66                 if (eDVBVolumecontrol.getInstance().isMuted()):
67                         self.volMute()
68                 eDVBVolumecontrol.getInstance().volumeUp()
69                 self.volumeDialog.instance.show()
70                 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
71                 self.volSave()
72                 self.hideVolTimer.start(3000)
73
74         def     volDown(self):
75                 if (eDVBVolumecontrol.getInstance().isMuted()):
76                         self.volMute()
77                 eDVBVolumecontrol.getInstance().volumeDown()
78                 self.volumeDialog.instance.show()
79                 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
80                 self.volSave()
81                 self.hideVolTimer.start(3000)
82                 
83         def volHide(self):
84                 self.volumeDialog.instance.hide()
85
86         def     volMute(self):
87                 eDVBVolumecontrol.getInstance().volumeToggleMute()
88                 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
89                 
90                 if (eDVBVolumecontrol.getInstance().isMuted()):
91                         self.muteDialog.instance.show()
92                 else:
93                         self.muteDialog.instance.hide()
94
95 class InfoBarDish:
96         def __init__(self):
97                 self.dishDialog = self.session.instantiateDialog(Dish)
98                 self.onShown.append(self.dishDialog.instance.hide)
99
100 class InfoBarShowHide:
101         """ InfoBar show/hide control, accepts toggleShow and hide actions, might start
102         fancy animations. """
103         STATE_HIDDEN = 0
104         STATE_HIDING = 1
105         STATE_SHOWING = 2
106         STATE_SHOWN = 3
107         
108         def __init__(self):
109                 self["ShowHideActions"] = ActionMap( ["InfobarShowHideActions"] ,
110                         {
111                                 "toggleShow": self.toggleShow,
112                                 "hide": self.hide,
113                         })
114
115                 self.state = self.STATE_SHOWN
116                 
117                 self.onExecBegin.append(self.show)
118                 self.onClose.append(self.delHideTimer)
119                 
120                 self.hideTimer = eTimer()
121                 self.hideTimer.timeout.get().append(self.doTimerHide)
122                 self.hideTimer.start(5000)
123
124         def delHideTimer(self):
125                 del self.hideTimer
126
127         def hide(self): 
128                 self.instance.hide()
129                 
130         def show(self):
131                 self.state = self.STATE_SHOWN
132                 self.hideTimer.stop()
133                 self.hideTimer.start(5000)
134
135         def doTimerHide(self):
136                 self.hideTimer.stop()
137                 if self.state == self.STATE_SHOWN:
138                         self.instance.hide()
139                         self.state = self.STATE_HIDDEN
140
141         def toggleShow(self):
142                 if self.state == self.STATE_SHOWN:
143                         self.instance.hide()
144                         #pls check animation support, sorry
145 #                       self.startHide()
146                         self.hideTimer.stop()
147                         self.state = self.STATE_HIDDEN
148                 elif self.state == self.STATE_HIDDEN:
149                         self.instance.show()
150                         self.show()
151                         
152         def startShow(self):
153                 self.instance.m_animation.startMoveAnimation(ePoint(0, 600), ePoint(0, 380), 100)
154                 self.state = self.STATE_SHOWN
155         
156         def startHide(self):
157                 self.instance.m_animation.startMoveAnimation(ePoint(0, 380), ePoint(0, 600), 100)
158                 self.state = self.STATE_HIDDEN
159
160 class NumberZap(Screen):
161         def quit(self):
162                 self.Timer.stop()
163                 self.close(0)
164
165         def keyOK(self):
166                 self.Timer.stop()
167                 self.close(int(self["number"].getText()))
168
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:
174                         self.keyOK()
175
176         def __init__(self, session, number):
177                 Screen.__init__(self, session)
178                 self.field = str(number)
179
180                 self["channel"] = Label(_("Channel:"))
181
182                 self["number"] = Label(self.field)
183
184                 self["actions"] = NumberActionMap( [ "SetupActions" ], 
185                         {
186                                 "cancel": self.quit,
187                                 "ok": self.keyOK,
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
198                         })
199
200                 self.Timer = eTimer()
201                 self.Timer.timeout.get().append(self.keyOK)
202                 self.Timer.start(3000)
203
204 class InfoBarPowerKey:
205         """ PowerKey stuff - handles the powerkey press and powerkey release actions"""
206         
207         def __init__(self):
208                 self.powerKeyTimer = eTimer()
209                 self.powerKeyTimer.timeout.get().append(self.powertimer)
210                 self["PowerKeyActions"] = HelpableActionMap(self, "PowerKeyActions",
211                         {
212                                 "powerdown": self.powerdown,
213                                 "powerup": self.powerup,
214                                 "discreteStandby": (self.standby, "Go standby"),
215                                 "discretePowerOff": (self.quit, "Go to deep standby"),
216                         })
217
218         def powertimer(self):   
219                 print "PowerOff - Now!"
220                 self.quit()
221         
222         def powerdown(self):
223                 self.standbyblocked = 0
224                 self.powerKeyTimer.start(3000)
225
226         def powerup(self):
227                 self.powerKeyTimer.stop()
228                 if self.standbyblocked == 0:
229                         self.standbyblocked = 1
230                         self.standby()
231
232         def standby(self):
233                 self.session.open(Standby, self)
234
235         def quit(self):
236                 # halt
237                 quitMainloop(1)
238
239 class InfoBarNumberZap:
240         """ Handles an initial number for NumberZapping """
241         def __init__(self):
242                 self["NumberZapActions"] = NumberActionMap( [ "NumberZapActions"],
243                         {
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,
254                         })
255
256         def keyNumberGlobal(self, number):
257 #               print "You pressed number " + str(number)
258                 self.session.openWithCallback(self.numberEntered, NumberZap, number)
259
260         def numberEntered(self, retval):
261 #               print self.servicelist
262                 if retval > 0:
263                         self.zapToNumber(retval)
264
265         def searchNumberHelper(self, serviceHandler, num, bouquet):
266                 servicelist = serviceHandler.list(bouquet)
267                 if not servicelist is None:
268                         while num:
269                                 serviceIterator = servicelist.getNext()
270                                 if not serviceIterator.valid(): #check end of list
271                                         break
272                                 if serviceIterator.flags: #assume normal dvb service have no flags set
273                                         continue
274                                 num -= 1;
275                         if not num: #found service with searched number ?
276                                 return serviceIterator, 0
277                 return None, num
278
279         def zapToNumber(self, number):
280                 bouquet = self.servicelist.bouquet_root
281                 service = None
282                 serviceHandler = eServiceCenter.getInstance()
283                 if bouquet.toString().find('FROM BOUQUET "bouquets.') == -1: #FIXME HACK
284                         service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
285                 else:
286                         bouquetlist = serviceHandler.list(bouquet)
287                         if not bouquetlist is None:
288                                 while number:
289                                         bouquet = bouquetlist.getNext()
290                                         if not bouquet.valid(): #check end of list
291                                                 break
292                                         if ((bouquet.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
293                                                 continue
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
300
301 class InfoBarChannelSelection:
302         """ ChannelSelection - handles the channelSelection dialog and the initial 
303         channelChange actions which open the channelSelection dialog """
304         def __init__(self):
305                 #instantiate forever
306                 self.servicelist = self.session.instantiateDialog(ChannelSelection)
307
308                 self["ChannelSelectActions"] = HelpableActionMap(self, "InfobarChannelSelection",
309                         {
310                                 "switchChannelUp": self.switchChannelUp,
311                                 "switchChannelDown": self.switchChannelDown,
312                                 "zapUp": (self.zapUp, _("next channel")),
313                                 "zapDown": (self.zapDown, _("previous channel")),
314                         })
315                         
316         def switchChannelUp(self):      
317                 self.servicelist.moveUp()
318                 self.session.execDialog(self.servicelist)
319
320         def switchChannelDown(self):    
321                 self.servicelist.moveDown()
322                 self.session.execDialog(self.servicelist)
323
324         def     zapUp(self):
325                 self.servicelist.moveUp()
326                 self.servicelist.zap()
327                 self.instance.show()
328                 self.show()
329
330         def     zapDown(self):
331                 self.servicelist.moveDown()
332                 self.servicelist.zap()
333                 self.instance.show()
334                 self.show()
335                 
336 class InfoBarMenu:
337         """ Handles a menu action, to open the (main) menu """
338         def __init__(self):
339                 self["MenuActions"] = HelpableActionMap(self, "InfobarMenuActions", 
340                         {
341                                 "mainMenu": (self.mainMenu, "Enter main menu..."),
342                         })
343
344         def mainMenu(self):
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)
349
350 class InfoBarEPG:
351         """ EPG - Opens an EPG list when the showEPGList action fires """
352         def __init__(self):
353                 self["EPGActions"] = HelpableActionMap(self, "InfobarEPGActions", 
354                         {
355                                 "showEPGList": (self.showEPGList, _("show EPG...")),
356                         })
357
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()
365                         try:
366                                 self.epglist = [ ]
367                                 service = self.session.nav.getCurrentService()
368                                 info = service.info()
369                                 ptr=info.getEvent(0)
370                                 if ptr:
371                                         self.epglist.append(ptr)
372                                 ptr=info.getEvent(1)
373                                 if ptr:
374                                         self.epglist.append(ptr)
375                                 if len(self.epglist) > 0:
376                                         self.session.open(EventView, self.epglist[0], ServiceReference(ref), self.eventViewCallback)
377                         except:
378                                 pass
379
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]
384                         self.epglist[1]=tmp
385                         setEvent(self.epglist[0])
386
387 from math import log
388
389 class InfoBarTuner:
390         """provides a snr/agc/ber display"""
391         def __init__(self):
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)
404
405         def calc(self,val):
406                 if not val:
407                         return 0
408                 if val < 2500:
409                         return (long)(log(val)/log(2))
410                 return val*100/65535
411
412         def updateTunerInfo(self):
413                 if self.instance.isVisible():
414                         service = self.session.nav.getCurrentService()
415                         snr=0
416                         agc=0
417                         ber=0
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))
430
431 class InfoBarEvent:
432         """provides a current/next event info display"""
433         def __init__(self):
434                 self["Event_Now_StartTime"] = EventInfo(self.session.nav, EventInfo.Now_StartTime)
435                 self["Event_Next_StartTime"] = EventInfo(self.session.nav, EventInfo.Next_StartTime)
436                                 
437                 self["Event_Now"] = EventInfo(self.session.nav, EventInfo.Now)
438                 self["Event_Next"] = EventInfo(self.session.nav, EventInfo.Next)
439
440                 self["Event_Now_Duration"] = EventInfo(self.session.nav, EventInfo.Now_Duration)
441                 self["Event_Next_Duration"] = EventInfo(self.session.nav, EventInfo.Next_Duration)
442
443 class InfoBarServiceName:
444         def __init__(self):
445                 self["ServiceName"] = ServiceName(self.session.nav)
446
447 class InfoBarPVR:
448
449         # ispause, isff, issm, skip
450         SEEK_STATE_PLAY = (0, 0, 0, 0)
451         SEEK_STATE_PAUSE = (1, 0, 0, 0)
452         SEEK_STATE_FF_2X = (0, 2, 0, 0)
453         SEEK_STATE_FF_4X = (0, 4, 0, 0)
454         SEEK_STATE_FF_8X = (0, 8, 0, 0)
455         SEEK_STATE_FF_32X = (0, 0, 0, 32)
456         SEEK_STATE_FF_64X = (0, 0, 0, 64)
457         
458         SEEK_STATE_BACK_4X = (0, 0, 0, -4)
459         SEEK_STATE_BACK_32X = (0, 0, 0, -32)
460         SEEK_STATE_BACK_64X = (0, 0, 0, -64)
461         
462         """handles PVR specific actions like seeking, pause"""
463         def __init__(self):
464                 self["PVRActions"] = HelpableActionMap(self, "InfobarPVRActions", 
465                         {
466                                 "pauseService": (self.pauseService, "pause"),
467                                 "unPauseService": (self.unPauseService, "continue"),
468                                 
469                                 "seekFwd": (self.seekFwd, "skip forward"),
470                                 "seekBack": (self.seekBack, "skip backward"),
471                         })
472
473                 self.seekstate = self.SEEK_STATE_PLAY
474                 self.seekTimer = eTimer()
475                 self.seekTimer.timeout.get().append(self.seekTimerFired)
476                 self.skipinterval = 500 # 500ms skip interval
477         
478         def seekTimerFired(self):
479                 print "skip", self.skipmode
480                 if self.skipmode > 0:
481                         self.doSeek(+1, self.skipmode * self.skipinterval)
482                 else:
483                         self.doSeek(-1, -self.skipmode * self.skipinterval)
484
485         def setSeekState(self, state):
486                 oldstate = self.seekstate
487                 
488                 self.seekstate = state
489
490                 service = self.session.nav.getCurrentService()
491                 if service is None:
492                         return
493                 
494                 pauseable = service.pause()
495                 print "newstate: ", self.seekstate
496                 
497                 for i in range(4):
498                         if oldstate[i] != self.seekstate[i]:
499                                 (self.session.nav.pause, pauseable.setFastForward, pauseable.setSlowMotion, self.setSkipMode)[i](self.seekstate[i])
500                 
501         def setSkipMode(self, skipmode):
502                 self.skipmode = skipmode
503                 if skipmode == 0:
504                         self.seekTimer.stop()
505                 else:
506                         self.seekTimer.start(500)
507         
508         def pauseService(self):
509                 self.setSeekState(self.SEEK_STATE_PAUSE);
510                 
511         def unPauseService(self):
512                 self.setSeekState(self.SEEK_STATE_PLAY);
513         
514         def doSeek(self, dir, seektime):
515                 service = self.session.nav.getCurrentService()
516                 if service is None:
517                         return
518                 
519                 seekable = service.seek()
520                 if seekable is None:
521                         return
522                 seekable.seekRelative(dir, 90 * seektime)
523
524         def seekFwd(self):
525                 lookup = {
526                                 self.SEEK_STATE_PLAY: self.SEEK_STATE_FF_2X,
527                                 self.SEEK_STATE_PAUSE: self.SEEK_STATE_PLAY,
528                                 self.SEEK_STATE_FF_2X: self.SEEK_STATE_FF_4X,
529                                 self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_8X,
530                                 self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_32X,
531                                 self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_64X,
532                                 self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_64X,
533                                 self.SEEK_STATE_BACK_4X: self.SEEK_STATE_PLAY,
534                                 self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_4X,
535                                 self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_32X
536                         }
537                 self.setSeekState(lookup[self.seekstate]);
538         
539         def seekBack(self):
540                 lookup = {
541                                 self.SEEK_STATE_PLAY: self.SEEK_STATE_BACK_4X,
542                                 self.SEEK_STATE_PAUSE: self.SEEK_STATE_BACK_4X,
543                                 self.SEEK_STATE_FF_2X: self.SEEK_STATE_PLAY,
544                                 self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_2X,
545                                 self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_4X,
546                                 self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_8X,
547                                 self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_32X,
548                                 self.SEEK_STATE_BACK_4X: self.SEEK_STATE_BACK_32X,
549                                 self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_64X,
550                                 self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_64X
551                         }
552                 self.setSeekState(lookup[self.seekstate]);
553
554 class InfoBarInstantRecord:
555         """Instant Record - handles the instantRecord action in order to 
556         start/stop instant records"""
557         def __init__(self):
558                 self["InstantRecordActions"] = HelpableActionMap(self, "InfobarInstantRecord",
559                         {
560                                 "instantRecord": (self.instantRecord, "Instant Record..."),
561                         })
562                 self.recording = None
563                 
564                 self["BlinkingPoint"] = BlinkingPixmapConditional()
565                 self.onShown.append(self["BlinkingPoint"].hideWidget)
566                 self["BlinkingPoint"].setConnect(self.session.nav.RecordTimer.isRecording)
567                 
568         def stopCurrentRecording(self): 
569                 self.session.nav.RecordTimer.removeEntry(self.recording)
570                 self.recording = None
571                         
572         def startInstantRecording(self):
573                 serviceref = self.session.nav.getCurrentlyPlayingServiceReference()
574                         
575                 # try to get event info
576                 epg = None
577                 try:
578                         service = self.session.nav.getCurrentService()
579                         info = service.info()
580                         ev = info.getEvent(0)
581                         epg = ev
582                 except:
583                         pass
584                 
585                 # fix me, description. 
586                 self.recording = self.session.nav.recordWithTimer(time.time(), time.time() + 3600, serviceref, epg, "instant record")
587                 self.recording.dontSave = True
588                 
589                 #self["BlinkingPoint"].setConnect(lambda: self.recording.isRunning())
590                 
591         def isInstantRecordRunning(self):
592                 if self.recording != None:
593                         if self.recording.isRunning():
594                                 return True
595                 return False
596
597         def recordQuestionCallback(self, answer):
598                 if answer == False:
599                         return
600                 
601                 if self.isInstantRecordRunning():
602                         self.stopCurrentRecording()
603                 else:
604                         self.startInstantRecording()
605
606         def instantRecord(self):
607                 try:
608                         stat = os.stat("/hdd/movies")
609                 except:
610                         self.session.open(MessageBox, "No HDD found!")
611                         return
612         
613                 if self.isInstantRecordRunning():
614                         self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Do you want to stop the current\n(instant) recording?"))
615                 else:
616                         self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Start recording?"))
617
618 from Screens.AudioSelection import AudioSelection
619
620 class InfoBarAudioSelection:
621         def __init__(self):
622                 self["AudioSelectionAction"] = HelpableActionMap(self, "InfobarAudioSelectionActions", 
623                         {
624                                 "audioSelection": (self.audioSelection, "Audio Options..."),
625                         })
626
627         def audioSelection(self):
628                 service = self.session.nav.getCurrentService()
629                 audio = service.audioTracks()
630                 n = audio.getNumberOfTracks()
631                 if n > 0:
632                         self.session.open(AudioSelection, audio)
633
634 from Screens.SubserviceSelection import SubserviceSelection
635
636 class InfoBarSubserviceSelection:
637         def __init__(self):
638                 self["SubserviceSelectionAction"] = HelpableActionMap(self, "InfobarSubserviceSelectionActions",
639                         {
640                                 "subserviceSelection": (self.subserviceSelection, "Subservice list..."),
641                         })
642
643         def subserviceSelection(self):
644                 service = self.session.nav.getCurrentService()
645                 subservices = service.subServices()
646                 n = subservices.getNumberOfSubservices()
647                 if n > 0:
648                         self.session.openWithCallback(self.subserviceSelected, SubserviceSelection, subservices)
649
650         def subserviceSelected(self, service):
651                 if not service is None:
652                         self.session.nav.playService(service)
653
654 class InfoBarAdditionalInfo:
655         def __init__(self):
656                 self["DolbyActive"] = PixmapConditional()
657                 # TODO: get the info from c++ somehow
658                 self["DolbyActive"].setConnect(lambda: False)
659                 
660                 self["CryptActive"] = PixmapConditional()
661                 # TODO: get the info from c++ somehow
662                 self["CryptActive"].setConnect(lambda: False)
663                 
664                 self["FormatActive"] = PixmapConditional()
665                 # TODO: get the info from c++ somehow
666                 self["FormatActive"].setConnect(lambda: False)
667                 
668                 self["ButtonRed"] = PixmapConditional(withTimer = False)
669                 self["ButtonRed"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
670                 self.onShown.append(self["ButtonRed"].update)
671                 self["ButtonRedText"] = LabelConditional(text = _("Record"), withTimer = False)
672                 self["ButtonRedText"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
673                 self.onShown.append(self["ButtonRedText"].update)
674                                 
675                 self["ButtonGreen"] = PixmapConditional()
676                 self["ButtonGreen"].setConnect(lambda: self.session.nav.getCurrentService().subServices().getNumberOfSubservices() > 0)
677                 self["ButtonGreenText"] = LabelConditional(text = _("Subservices"))
678                 self["ButtonGreenText"].setConnect(lambda: self.session.nav.getCurrentService().subServices().getNumberOfSubservices() > 0)
679
680                 self["ButtonYellow"] = PixmapConditional()
681                 self["ButtonYellow"].setConnect(lambda: False)
682
683                 self["ButtonBlue"] = PixmapConditional()
684                 self["ButtonBlue"].setConnect(lambda: False)
685
686 class InfoBarNotifications:
687         def __init__(self):
688                 self.onExecBegin.append(self.checkNotifications)
689                 Notifications.notificationAdded.append(self.checkNotificationsIfExecing)
690         
691         def checkNotificationsIfExecing(self):
692                 if self.execing:
693                         self.checkNotifications()
694
695         def checkNotifications(self):
696                 if len(Notifications.notifications):
697                         n = Notifications.notifications[0]
698                         Notifications.notifications = Notifications.notifications[1:]
699                         print "open",n
700                         cb = n[0]
701                         if cb is not None:
702                                 self.session.openWithCallback(cb, *n[1:])
703                         else:
704                                 self.session.open(*n[1:])