zap to last channel with 0
[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, [100], 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, True)
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, True)
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, True)
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.start(5000, True)
133
134         def doTimerHide(self):
135                 self.hideTimer.stop()
136                 if self.state == self.STATE_SHOWN:
137                         self.instance.hide()
138                         self.state = self.STATE_HIDDEN
139
140         def toggleShow(self):
141                 if self.state == self.STATE_SHOWN:
142                         self.instance.hide()
143                         #pls check animation support, sorry
144 #                       self.startHide()
145                         self.hideTimer.stop()
146                         self.state = self.STATE_HIDDEN
147                 elif self.state == self.STATE_HIDDEN:
148                         self.instance.show()
149                         self.show()
150                         
151         def startShow(self):
152                 self.instance.m_animation.startMoveAnimation(ePoint(0, 600), ePoint(0, 380), 100)
153                 self.state = self.STATE_SHOWN
154         
155         def startHide(self):
156                 self.instance.m_animation.startMoveAnimation(ePoint(0, 380), ePoint(0, 600), 100)
157                 self.state = self.STATE_HIDDEN
158
159 class NumberZap(Screen):
160         def quit(self):
161                 self.Timer.stop()
162                 self.close(0)
163
164         def keyOK(self):
165                 self.Timer.stop()
166                 self.close(int(self["number"].getText()))
167
168         def keyNumberGlobal(self, number):
169                 self.Timer.start(3000, True)            #reset timer
170                 self.field = self.field + str(number)
171                 self["number"].setText(self.field)
172                 if len(self.field) >= 4:
173                         self.keyOK()
174
175         def __init__(self, session, number):
176                 Screen.__init__(self, session)
177                 self.field = str(number)
178
179                 self["channel"] = Label(_("Channel:"))
180
181                 self["number"] = Label(self.field)
182
183                 self["actions"] = NumberActionMap( [ "SetupActions" ], 
184                         {
185                                 "cancel": self.quit,
186                                 "ok": self.keyOK,
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
197                         })
198
199                 self.Timer = eTimer()
200                 self.Timer.timeout.get().append(self.keyOK)
201                 self.Timer.start(3000, True)
202
203 class InfoBarPowerKey:
204         """ PowerKey stuff - handles the powerkey press and powerkey release actions"""
205         
206         def __init__(self):
207                 self.powerKeyTimer = eTimer()
208                 self.powerKeyTimer.timeout.get().append(self.powertimer)
209                 self["PowerKeyActions"] = HelpableActionMap(self, "PowerKeyActions",
210                         {
211                                 "powerdown": self.powerdown,
212                                 "powerup": self.powerup,
213                                 "discreteStandby": (self.standby, "Go standby"),
214                                 "discretePowerOff": (self.quit, "Go to deep standby"),
215                         })
216
217         def powertimer(self):   
218                 print "PowerOff - Now!"
219                 self.quit()
220         
221         def powerdown(self):
222                 self.standbyblocked = 0
223                 self.powerKeyTimer.start(3000, True)
224
225         def powerup(self):
226                 self.powerKeyTimer.stop()
227                 if self.standbyblocked == 0:
228                         self.standbyblocked = 1
229                         self.standby()
230
231         def standby(self):
232                 self.session.open(Standby, self)
233
234         def quit(self):
235                 # halt
236                 quitMainloop(1)
237
238 class InfoBarNumberZap:
239         """ Handles an initial number for NumberZapping """
240         def __init__(self):
241                 self["NumberZapActions"] = NumberActionMap( [ "NumberZapActions"],
242                         {
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,
253                         })
254
255         def keyNumberGlobal(self, number):
256 #               print "You pressed number " + str(number)
257                 if number == 0:
258                         self.session.nav.zapLast()
259                         self.instance.show()
260                         self.show()
261                 else:
262                         self.session.openWithCallback(self.numberEntered, NumberZap, number)
263
264         def numberEntered(self, retval):
265 #               print self.servicelist
266                 if retval > 0:
267                         self.zapToNumber(retval)
268
269         def searchNumberHelper(self, serviceHandler, num, bouquet):
270                 servicelist = serviceHandler.list(bouquet)
271                 if not servicelist is None:
272                         while num:
273                                 serviceIterator = servicelist.getNext()
274                                 if not serviceIterator.valid(): #check end of list
275                                         break
276                                 if serviceIterator.flags: #assume normal dvb service have no flags set
277                                         continue
278                                 num -= 1;
279                         if not num: #found service with searched number ?
280                                 return serviceIterator, 0
281                 return None, num
282
283         def zapToNumber(self, number):
284                 bouquet = self.servicelist.bouquet_root
285                 service = None
286                 serviceHandler = eServiceCenter.getInstance()
287                 if bouquet.toString().find('FROM BOUQUET "bouquets.') == -1: #FIXME HACK
288                         service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
289                 else:
290                         bouquetlist = serviceHandler.list(bouquet)
291                         if not bouquetlist is None:
292                                 while number:
293                                         bouquet = bouquetlist.getNext()
294                                         if not bouquet.valid(): #check end of list
295                                                 break
296                                         if ((bouquet.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
297                                                 continue
298                                         service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
299                 if not service is None:
300                         self.session.nav.playService(service) #play service
301                         if self.servicelist.getRoot() != bouquet: #already in correct bouquet?
302                                 self.servicelist.setRoot(bouquet)
303                         self.servicelist.setCurrentSelection(service) #select the service in servicelist
304
305 class InfoBarChannelSelection:
306         """ ChannelSelection - handles the channelSelection dialog and the initial 
307         channelChange actions which open the channelSelection dialog """
308         def __init__(self):
309                 #instantiate forever
310                 self.servicelist = self.session.instantiateDialog(ChannelSelection)
311
312                 self["ChannelSelectActions"] = HelpableActionMap(self, "InfobarChannelSelection",
313                         {
314                                 "switchChannelUp": self.switchChannelUp,
315                                 "switchChannelDown": self.switchChannelDown,
316                                 "zapUp": (self.zapUp, _("next channel")),
317                                 "zapDown": (self.zapDown, _("previous channel")),
318                         })
319                         
320         def switchChannelUp(self):      
321                 self.servicelist.moveUp()
322                 self.session.execDialog(self.servicelist)
323
324         def switchChannelDown(self):    
325                 self.servicelist.moveDown()
326                 self.session.execDialog(self.servicelist)
327
328         def     zapUp(self):
329                 self.servicelist.moveUp()
330                 self.servicelist.zap()
331                 self.instance.show()
332                 self.show()
333
334         def     zapDown(self):
335                 self.servicelist.moveDown()
336                 self.servicelist.zap()
337                 self.instance.show()
338                 self.show()
339                 
340 class InfoBarMenu:
341         """ Handles a menu action, to open the (main) menu """
342         def __init__(self):
343                 self["MenuActions"] = HelpableActionMap(self, "InfobarMenuActions", 
344                         {
345                                 "mainMenu": (self.mainMenu, "Enter main menu..."),
346                         })
347
348         def mainMenu(self):
349                 print "loading mainmenu XML..."
350                 menu = mdom.childNodes[0]
351                 assert menu.tagName == "menu", "root element in menu must be 'menu'!"
352                 self.session.open(MainMenu, menu, menu.childNodes)
353
354 class InfoBarEPG:
355         """ EPG - Opens an EPG list when the showEPGList action fires """
356         def __init__(self):
357                 self["EPGActions"] = HelpableActionMap(self, "InfobarEPGActions", 
358                         {
359                                 "showEPGList": (self.showEPGList, _("show EPG...")),
360                         })
361
362         def showEPGList(self):
363                 ref=self.session.nav.getCurrentlyPlayingServiceReference()
364                 ptr=eEPGCache.getInstance()
365                 if ptr.startTimeQuery(ref) != -1:
366                         self.session.open(EPGSelection, ref)
367                 else: # try to show now/next
368                         print 'no epg for service', ref.toString()
369                         try:
370                                 self.epglist = [ ]
371                                 service = self.session.nav.getCurrentService()
372                                 info = service.info()
373                                 ptr=info.getEvent(0)
374                                 if ptr:
375                                         self.epglist.append(ptr)
376                                 ptr=info.getEvent(1)
377                                 if ptr:
378                                         self.epglist.append(ptr)
379                                 if len(self.epglist) > 0:
380                                         self.session.open(EventView, self.epglist[0], ServiceReference(ref), self.eventViewCallback)
381                         except:
382                                 pass
383
384         def eventViewCallback(self, setEvent, val): #used for now/next displaying
385                 if len(self.epglist) > 1:
386                         tmp = self.epglist[0]
387                         self.epglist[0]=self.epglist[1]
388                         self.epglist[1]=tmp
389                         setEvent(self.epglist[0])
390
391 from math import log
392
393 class InfoBarTuner:
394         """provides a snr/agc/ber display"""
395         def __init__(self):
396                 self["snr"] = Label()
397                 self["agc"] = Label()
398                 self["ber"] = Label()
399                 self["snr_percent"] = Label()
400                 self["agc_percent"] = Label()
401                 self["ber_count"] = Label()
402                 self["snr_progress"] = ProgressBar()
403                 self["agc_progress"] = ProgressBar()
404                 self["ber_progress"] = ProgressBar()
405                 self.timer = eTimer()
406                 self.timer.timeout.get().append(self.updateTunerInfo)
407                 self.timer.start(1000)
408
409         def calc(self,val):
410                 if not val:
411                         return 0
412                 if val < 2500:
413                         return (long)(log(val)/log(2))
414                 return val*100/65535
415
416         def updateTunerInfo(self):
417                 if self.instance.isVisible():
418                         service = self.session.nav.getCurrentService()
419                         snr=0
420                         agc=0
421                         ber=0
422                         if service is not None:
423                                 feinfo = service.frontendStatusInfo()
424                                 if feinfo is not None:
425                                         ber=feinfo.getFrontendInfo(iFrontendStatusInformation.bitErrorRate)
426                                         snr=feinfo.getFrontendInfo(iFrontendStatusInformation.signalPower)*100/65536
427                                         agc=feinfo.getFrontendInfo(iFrontendStatusInformation.signalQuality)*100/65536
428                         self["snr_percent"].setText("%d%%"%(snr))
429                         self["agc_percent"].setText("%d%%"%(agc))
430                         self["ber_count"].setText("%d"%(ber))
431                         self["snr_progress"].setValue(snr)
432                         self["agc_progress"].setValue(agc)
433                         self["ber_progress"].setValue(self.calc(ber))
434
435 class InfoBarEvent:
436         """provides a current/next event info display"""
437         def __init__(self):
438                 self["Event_Now_StartTime"] = EventInfo(self.session.nav, EventInfo.Now_StartTime)
439                 self["Event_Next_StartTime"] = EventInfo(self.session.nav, EventInfo.Next_StartTime)
440                                 
441                 self["Event_Now"] = EventInfo(self.session.nav, EventInfo.Now)
442                 self["Event_Next"] = EventInfo(self.session.nav, EventInfo.Next)
443
444                 self["Event_Now_Duration"] = EventInfo(self.session.nav, EventInfo.Now_Duration)
445                 self["Event_Next_Duration"] = EventInfo(self.session.nav, EventInfo.Next_Duration)
446
447 class InfoBarServiceName:
448         def __init__(self):
449                 self["ServiceName"] = ServiceName(self.session.nav)
450
451 class InfoBarPVR:
452
453         # ispause, isff, issm, skip
454         SEEK_STATE_PLAY = (0, 0, 0, 0)
455         SEEK_STATE_PAUSE = (1, 0, 0, 0)
456         SEEK_STATE_FF_2X = (0, 2, 0, 0)
457         SEEK_STATE_FF_4X = (0, 4, 0, 0)
458         SEEK_STATE_FF_8X = (0, 8, 0, 0)
459         SEEK_STATE_FF_32X = (0, 4, 0, 32)
460         SEEK_STATE_FF_64X = (0, 4, 0, 64)
461         SEEK_STATE_FF_128X = (0, 4, 0, 128)
462         
463         SEEK_STATE_BACK_4X = (0, 0, 0, -4)
464         SEEK_STATE_BACK_32X = (0, 0, 0, -32)
465         SEEK_STATE_BACK_64X = (0, 0, 0, -64)
466         SEEK_STATE_BACK_128X = (0, 0, 0, -128)
467         
468         SEEK_STATE_SM_HALF = (0, 0, 2, 0)
469         SEEK_STATE_SM_QUARTER = (0, 0, 4, 0)
470         SEEK_STATE_SM_EIGHTH = (0, 0, 8, 0)
471         
472         """handles PVR specific actions like seeking, pause"""
473         def __init__(self):
474                 self["PVRActions"] = HelpableActionMap(self, "InfobarPVRActions", 
475                         {
476                                 "pauseService": (self.pauseService, "pause"),
477                                 "unPauseService": (self.unPauseService, "continue"),
478                                 
479                                 "seekFwd": (self.seekFwd, "skip forward"),
480                                 "seekBack": (self.seekBack, "skip backward"),
481                         })
482
483                 self.seekstate = self.SEEK_STATE_PLAY
484                 self.seekTimer = eTimer()
485                 self.seekTimer.timeout.get().append(self.seekTimerFired)
486                 self.skipinterval = 500 # 500ms skip interval
487                 self.onClose.append(self.delSeekTimer)
488         
489         def delSeekTimer(self):
490                 del self.seekTimer
491         
492         def seekTimerFired(self):
493                 self.seekbase += self.skipmode * self.skipinterval
494                 
495                 # check if we bounced against the beginning of the file
496                 if self.seekbase < 0:
497                         self.seekbase = 0;
498                         self.setSeekState(self.SEEK_STATE_PLAY)
499                         
500                 self.doSeek(self.seekbase)
501
502         def setSeekState(self, state):
503                 oldstate = self.seekstate
504                 
505                 self.seekstate = state
506
507                 service = self.session.nav.getCurrentService()
508                 if service is None:
509                         return
510                 
511                 pauseable = service.pause()
512                 
513                 for i in range(4):
514                         if oldstate[i] != self.seekstate[i]:
515                                 (self.session.nav.pause, pauseable.setFastForward, pauseable.setSlowMotion, self.setSkipMode)[i](self.seekstate[i])
516                 
517         def setSkipMode(self, skipmode):
518                 self.skipmode = skipmode
519                 if skipmode == 0:
520                         self.seekTimer.stop()
521                 else:
522                         self.seekTimer.start(500)
523                 
524                 service = self.session.nav.getCurrentService()
525                 if service is None:
526                         return
527                 
528                 seekable = service.seek()
529                 if seekable is None:
530                         return
531
532                 if skipmode:
533                         seekable.setTrickmode(1)
534                 else:
535                         seekable.setTrickmode(0)
536                 
537                 self.seekbase = seekable.getPlayPosition()[1] / 90
538         
539         def pauseService(self):
540                 self.setSeekState(self.SEEK_STATE_PAUSE);
541                 
542         def unPauseService(self):
543                 self.setSeekState(self.SEEK_STATE_PLAY);
544         
545         def doSeek(self, seektime):
546                 service = self.session.nav.getCurrentService()
547                 if service is None:
548                         return
549                 
550                 seekable = service.seek()
551                 if seekable is None:
552                         return
553                 seekable.seekTo(90 * seektime)
554
555         def seekFwd(self):
556                 lookup = {
557                                 self.SEEK_STATE_PLAY: self.SEEK_STATE_FF_2X,
558                                 self.SEEK_STATE_PAUSE: self.SEEK_STATE_SM_EIGHTH,
559                                 self.SEEK_STATE_FF_2X: self.SEEK_STATE_FF_4X,
560                                 self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_8X,
561                                 self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_32X,
562                                 self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_64X,
563                                 self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_128X,
564                                 self.SEEK_STATE_FF_128X: self.SEEK_STATE_FF_128X,
565                                 self.SEEK_STATE_BACK_4X: self.SEEK_STATE_PLAY,
566                                 self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_4X,
567                                 self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_32X,
568                                 self.SEEK_STATE_BACK_128X: self.SEEK_STATE_BACK_64X,
569                                 self.SEEK_STATE_SM_HALF: self.SEEK_STATE_SM_HALF,
570                                 self.SEEK_STATE_SM_QUARTER: self.SEEK_STATE_SM_HALF,
571                                 self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_SM_QUARTER
572                         }
573                 self.setSeekState(lookup[self.seekstate]);
574         
575         def seekBack(self):
576                 lookup = {
577                                 self.SEEK_STATE_PLAY: self.SEEK_STATE_BACK_4X,
578                                 self.SEEK_STATE_PAUSE: self.SEEK_STATE_PAUSE,
579                                 self.SEEK_STATE_FF_2X: self.SEEK_STATE_PLAY,
580                                 self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_2X,
581                                 self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_4X,
582                                 self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_8X,
583                                 self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_32X,
584                                 self.SEEK_STATE_FF_128X: self.SEEK_STATE_FF_64X,
585                                 self.SEEK_STATE_BACK_4X: self.SEEK_STATE_BACK_32X,
586                                 self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_64X,
587                                 self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_128X,
588                                 self.SEEK_STATE_BACK_128X: self.SEEK_STATE_BACK_128X,
589                                 self.SEEK_STATE_SM_HALF: self.SEEK_STATE_SM_QUARTER,
590                                 self.SEEK_STATE_SM_QUARTER: self.SEEK_STATE_SM_EIGHTH,
591                                 self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_PAUSE
592                         }
593                 self.setSeekState(lookup[self.seekstate]);
594
595 from RecordTimer import parseEvent
596
597 class InfoBarInstantRecord:
598         """Instant Record - handles the instantRecord action in order to 
599         start/stop instant records"""
600         def __init__(self):
601                 self["InstantRecordActions"] = HelpableActionMap(self, "InfobarInstantRecord",
602                         {
603                                 "instantRecord": (self.instantRecord, "Instant Record..."),
604                         })
605                 self.recording = None
606                 
607                 self["BlinkingPoint"] = BlinkingPixmapConditional()
608                 self.onShown.append(self["BlinkingPoint"].hideWidget)
609                 self["BlinkingPoint"].setConnect(self.session.nav.RecordTimer.isRecording)
610                 
611         def stopCurrentRecording(self): 
612                 self.session.nav.RecordTimer.removeEntry(self.recording)
613                 self.recording = None
614                         
615         def startInstantRecording(self):
616                 serviceref = self.session.nav.getCurrentlyPlayingServiceReference()
617                 
618                 # try to get event info
619                 event = None
620                 try:
621                         service = self.session.nav.getCurrentService()
622                         info = service.info()
623                         ev = info.getEvent(0)
624                         event = ev
625                 except:
626                         pass
627                 
628                 if event is not None:
629                         data = parseEvent(event)
630                         data = (data[0], data[1] + 3600 * 10, data[2], data[3], data[4])
631                 else:
632                         data = (time.time(), time.time() + 3600 * 10, "instant record", "", None)
633                 
634                 # fix me, description. 
635                 self.recording = self.session.nav.recordWithTimer(serviceref, *data)
636                 self.recording.dontSave = True
637                 
638                 #self["BlinkingPoint"].setConnect(lambda: self.recording.isRunning())
639                 
640         def isInstantRecordRunning(self):
641                 if self.recording != None:
642                         if self.recording.isRunning():
643                                 return True
644                 return False
645
646         def recordQuestionCallback(self, answer):
647                 if answer == False:
648                         return
649                 
650                 if self.isInstantRecordRunning():
651                         self.stopCurrentRecording()
652                 else:
653                         self.startInstantRecording()
654
655         def instantRecord(self):
656                 try:
657                         stat = os.stat("/hdd/movies")
658                 except:
659                         self.session.open(MessageBox, "No HDD found!")
660                         return
661         
662                 if self.isInstantRecordRunning():
663                         self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Do you want to stop the current\n(instant) recording?"))
664                 else:
665                         self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Start recording?"))
666
667 from Screens.AudioSelection import AudioSelection
668
669 class InfoBarAudioSelection:
670         def __init__(self):
671                 self["AudioSelectionAction"] = HelpableActionMap(self, "InfobarAudioSelectionActions", 
672                         {
673                                 "audioSelection": (self.audioSelection, "Audio Options..."),
674                         })
675
676         def audioSelection(self):
677                 service = self.session.nav.getCurrentService()
678                 audio = service.audioTracks()
679                 n = audio.getNumberOfTracks()
680                 if n > 0:
681                         self.session.open(AudioSelection, audio)
682
683 from Screens.SubserviceSelection import SubserviceSelection
684
685 class InfoBarSubserviceSelection:
686         def __init__(self):
687                 self["SubserviceSelectionAction"] = HelpableActionMap(self, "InfobarSubserviceSelectionActions",
688                         {
689                                 "subserviceSelection": (self.subserviceSelection, "Subservice list..."),
690                         })
691
692         def subserviceSelection(self):
693                 service = self.session.nav.getCurrentService()
694                 subservices = service.subServices()
695                 n = subservices.getNumberOfSubservices()
696                 if n > 0:
697                         self.session.openWithCallback(self.subserviceSelected, SubserviceSelection, subservices)
698
699         def subserviceSelected(self, service):
700                 if not service is None:
701                         self.session.nav.playService(service)
702
703 class InfoBarAdditionalInfo:
704         def __init__(self):
705                 self["DolbyActive"] = PixmapConditional()
706                 # TODO: get the info from c++ somehow
707                 self["DolbyActive"].setConnect(lambda: False)
708                 
709                 self["CryptActive"] = PixmapConditional()
710                 # TODO: get the info from c++ somehow
711                 self["CryptActive"].setConnect(lambda: False)
712                 
713                 self["FormatActive"] = PixmapConditional()
714                 # TODO: get the info from c++ somehow
715                 self["FormatActive"].setConnect(lambda: False)
716                 
717                 self["ButtonRed"] = PixmapConditional(withTimer = False)
718                 self["ButtonRed"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
719                 self.onShown.append(self["ButtonRed"].update)
720                 self["ButtonRedText"] = LabelConditional(text = _("Record"), withTimer = False)
721                 self["ButtonRedText"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
722                 self.onShown.append(self["ButtonRedText"].update)
723                                 
724                 self["ButtonGreen"] = PixmapConditional()
725                 self["ButtonGreen"].setConnect(lambda: self.session.nav.getCurrentService().subServices().getNumberOfSubservices() > 0)
726                 self["ButtonGreenText"] = LabelConditional(text = _("Subservices"))
727                 self["ButtonGreenText"].setConnect(lambda: self.session.nav.getCurrentService().subServices().getNumberOfSubservices() > 0)
728
729                 self["ButtonYellow"] = PixmapConditional()
730                 self["ButtonYellow"].setConnect(lambda: False)
731
732                 self["ButtonBlue"] = PixmapConditional()
733                 self["ButtonBlue"].setConnect(lambda: False)
734
735 class InfoBarNotifications:
736         def __init__(self):
737                 self.onExecBegin.append(self.checkNotifications)
738                 Notifications.notificationAdded.append(self.checkNotificationsIfExecing)
739         
740         def checkNotificationsIfExecing(self):
741                 if self.execing:
742                         self.checkNotifications()
743
744         def checkNotifications(self):
745                 if len(Notifications.notifications):
746                         n = Notifications.notifications[0]
747                         Notifications.notifications = Notifications.notifications[1:]
748                         print "open",n
749                         cb = n[0]
750                         if cb is not None:
751                                 self.session.openWithCallback(cb, *n[1:])
752                         else:
753                                 self.session.open(*n[1:])