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