add language selection
[enigma2.git] / 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         SEEK_STATE_SM_HALF = (0, 0, 2, 0)
463         SEEK_STATE_SM_QUARTER = (0, 0, 4, 0)
464         SEEK_STATE_SM_EIGHTH = (0, 0, 8, 0)
465         
466         """handles PVR specific actions like seeking, pause"""
467         def __init__(self):
468                 self["PVRActions"] = HelpableActionMap(self, "InfobarPVRActions", 
469                         {
470                                 "pauseService": (self.pauseService, "pause"),
471                                 "unPauseService": (self.unPauseService, "continue"),
472                                 
473                                 "seekFwd": (self.seekFwd, "skip forward"),
474                                 "seekBack": (self.seekBack, "skip backward"),
475                         })
476
477                 self.seekstate = self.SEEK_STATE_PLAY
478                 self.seekTimer = eTimer()
479                 self.seekTimer.timeout.get().append(self.seekTimerFired)
480                 self.skipinterval = 500 # 500ms skip interval
481         
482         def seekTimerFired(self):
483                 if self.skipmode > 0:
484                         self.doSeek(+1, self.skipmode * self.skipinterval)
485                 else:
486                         self.doSeek(-1, -self.skipmode * self.skipinterval)
487
488         def setSeekState(self, state):
489                 oldstate = self.seekstate
490                 
491                 self.seekstate = state
492
493                 service = self.session.nav.getCurrentService()
494                 if service is None:
495                         return
496                 
497                 pauseable = service.pause()
498                 
499                 for i in range(4):
500                         if oldstate[i] != self.seekstate[i]:
501                                 (self.session.nav.pause, pauseable.setFastForward, pauseable.setSlowMotion, self.setSkipMode)[i](self.seekstate[i])
502                 
503         def setSkipMode(self, skipmode):
504                 self.skipmode = skipmode
505                 if skipmode == 0:
506                         self.seekTimer.stop()
507                 else:
508                         self.seekTimer.start(500)
509         
510         def pauseService(self):
511                 self.setSeekState(self.SEEK_STATE_PAUSE);
512                 
513         def unPauseService(self):
514                 self.setSeekState(self.SEEK_STATE_PLAY);
515         
516         def doSeek(self, dir, seektime):
517                 service = self.session.nav.getCurrentService()
518                 if service is None:
519                         return
520                 
521                 seekable = service.seek()
522                 if seekable is None:
523                         return
524                 seekable.seekRelative(dir, 90 * seektime)
525
526         def seekFwd(self):
527                 lookup = {
528                                 self.SEEK_STATE_PLAY: self.SEEK_STATE_FF_2X,
529                                 self.SEEK_STATE_PAUSE: self.SEEK_STATE_SM_EIGHTH,
530                                 self.SEEK_STATE_FF_2X: self.SEEK_STATE_FF_4X,
531                                 self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_8X,
532                                 self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_32X,
533                                 self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_64X,
534                                 self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_64X,
535                                 self.SEEK_STATE_BACK_4X: self.SEEK_STATE_PLAY,
536                                 self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_4X,
537                                 self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_32X,
538                                 self.SEEK_STATE_SM_HALF: self.SEEK_STATE_SM_HALF,
539                                 self.SEEK_STATE_SM_QUARTER: self.SEEK_STATE_SM_HALF,
540                                 self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_SM_QUARTER
541                         }
542                 self.setSeekState(lookup[self.seekstate]);
543         
544         def seekBack(self):
545                 lookup = {
546                                 self.SEEK_STATE_PLAY: self.SEEK_STATE_BACK_4X,
547                                 self.SEEK_STATE_PAUSE: self.SEEK_STATE_PAUSE,
548                                 self.SEEK_STATE_FF_2X: self.SEEK_STATE_PLAY,
549                                 self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_2X,
550                                 self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_4X,
551                                 self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_8X,
552                                 self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_32X,
553                                 self.SEEK_STATE_BACK_4X: self.SEEK_STATE_BACK_32X,
554                                 self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_64X,
555                                 self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_64X,
556                                 self.SEEK_STATE_SM_HALF: self.SEEK_STATE_SM_QUARTER,
557                                 self.SEEK_STATE_SM_QUARTER: self.SEEK_STATE_SM_EIGHTH,
558                                 self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_PAUSE
559                         }
560                 self.setSeekState(lookup[self.seekstate]);
561
562 class InfoBarInstantRecord:
563         """Instant Record - handles the instantRecord action in order to 
564         start/stop instant records"""
565         def __init__(self):
566                 self["InstantRecordActions"] = HelpableActionMap(self, "InfobarInstantRecord",
567                         {
568                                 "instantRecord": (self.instantRecord, "Instant Record..."),
569                         })
570                 self.recording = None
571                 
572                 self["BlinkingPoint"] = BlinkingPixmapConditional()
573                 self.onShown.append(self["BlinkingPoint"].hideWidget)
574                 self["BlinkingPoint"].setConnect(self.session.nav.RecordTimer.isRecording)
575                 
576         def stopCurrentRecording(self): 
577                 self.session.nav.RecordTimer.removeEntry(self.recording)
578                 self.recording = None
579                         
580         def startInstantRecording(self):
581                 serviceref = self.session.nav.getCurrentlyPlayingServiceReference()
582                         
583                 # try to get event info
584                 epg = None
585                 try:
586                         service = self.session.nav.getCurrentService()
587                         info = service.info()
588                         ev = info.getEvent(0)
589                         epg = ev
590                 except:
591                         pass
592                 
593                 # fix me, description. 
594                 self.recording = self.session.nav.recordWithTimer(time.time(), time.time() + 3600, serviceref, epg, "instant record")
595                 self.recording.dontSave = True
596                 
597                 #self["BlinkingPoint"].setConnect(lambda: self.recording.isRunning())
598                 
599         def isInstantRecordRunning(self):
600                 if self.recording != None:
601                         if self.recording.isRunning():
602                                 return True
603                 return False
604
605         def recordQuestionCallback(self, answer):
606                 if answer == False:
607                         return
608                 
609                 if self.isInstantRecordRunning():
610                         self.stopCurrentRecording()
611                 else:
612                         self.startInstantRecording()
613
614         def instantRecord(self):
615                 try:
616                         stat = os.stat("/hdd/movies")
617                 except:
618                         self.session.open(MessageBox, "No HDD found!")
619                         return
620         
621                 if self.isInstantRecordRunning():
622                         self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Do you want to stop the current\n(instant) recording?"))
623                 else:
624                         self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Start recording?"))
625
626 from Screens.AudioSelection import AudioSelection
627
628 class InfoBarAudioSelection:
629         def __init__(self):
630                 self["AudioSelectionAction"] = HelpableActionMap(self, "InfobarAudioSelectionActions", 
631                         {
632                                 "audioSelection": (self.audioSelection, "Audio Options..."),
633                         })
634
635         def audioSelection(self):
636                 service = self.session.nav.getCurrentService()
637                 audio = service.audioTracks()
638                 n = audio.getNumberOfTracks()
639                 if n > 0:
640                         self.session.open(AudioSelection, audio)
641
642 from Screens.SubserviceSelection import SubserviceSelection
643
644 class InfoBarSubserviceSelection:
645         def __init__(self):
646                 self["SubserviceSelectionAction"] = HelpableActionMap(self, "InfobarSubserviceSelectionActions",
647                         {
648                                 "subserviceSelection": (self.subserviceSelection, "Subservice list..."),
649                         })
650
651         def subserviceSelection(self):
652                 service = self.session.nav.getCurrentService()
653                 subservices = service.subServices()
654                 n = subservices.getNumberOfSubservices()
655                 if n > 0:
656                         self.session.openWithCallback(self.subserviceSelected, SubserviceSelection, subservices)
657
658         def subserviceSelected(self, service):
659                 if not service is None:
660                         self.session.nav.playService(service)
661
662 class InfoBarAdditionalInfo:
663         def __init__(self):
664                 self["DolbyActive"] = PixmapConditional()
665                 # TODO: get the info from c++ somehow
666                 self["DolbyActive"].setConnect(lambda: False)
667                 
668                 self["CryptActive"] = PixmapConditional()
669                 # TODO: get the info from c++ somehow
670                 self["CryptActive"].setConnect(lambda: False)
671                 
672                 self["FormatActive"] = PixmapConditional()
673                 # TODO: get the info from c++ somehow
674                 self["FormatActive"].setConnect(lambda: False)
675                 
676                 self["ButtonRed"] = PixmapConditional(withTimer = False)
677                 self["ButtonRed"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
678                 self.onShown.append(self["ButtonRed"].update)
679                 self["ButtonRedText"] = LabelConditional(text = _("Record"), withTimer = False)
680                 self["ButtonRedText"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
681                 self.onShown.append(self["ButtonRedText"].update)
682                                 
683                 self["ButtonGreen"] = PixmapConditional()
684                 self["ButtonGreen"].setConnect(lambda: self.session.nav.getCurrentService().subServices().getNumberOfSubservices() > 0)
685                 self["ButtonGreenText"] = LabelConditional(text = _("Subservices"))
686                 self["ButtonGreenText"].setConnect(lambda: self.session.nav.getCurrentService().subServices().getNumberOfSubservices() > 0)
687
688                 self["ButtonYellow"] = PixmapConditional()
689                 self["ButtonYellow"].setConnect(lambda: False)
690
691                 self["ButtonBlue"] = PixmapConditional()
692                 self["ButtonBlue"].setConnect(lambda: False)
693
694 class InfoBarNotifications:
695         def __init__(self):
696                 self.onExecBegin.append(self.checkNotifications)
697                 Notifications.notificationAdded.append(self.checkNotificationsIfExecing)
698         
699         def checkNotificationsIfExecing(self):
700                 if self.execing:
701                         self.checkNotifications()
702
703         def checkNotifications(self):
704                 if len(Notifications.notifications):
705                         n = Notifications.notifications[0]
706                         Notifications.notifications = Notifications.notifications[1:]
707                         print "open",n
708                         cb = n[0]
709                         if cb is not None:
710                                 self.session.openWithCallback(cb, *n[1:])
711                         else:
712                                 self.session.open(*n[1:])