bouquets and lamedb now stored in /etc/enigma2 (CONFIGDIR/enigma2)
[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                                 "up": (self.showMovies, "movie list"),
483                                 "down": (self.showMovies, "movie list")
484                         })
485
486                 self.seekstate = self.SEEK_STATE_PLAY
487                 self.seekTimer = eTimer()
488                 self.seekTimer.timeout.get().append(self.seekTimerFired)
489                 self.skipinterval = 500 # 500ms skip interval
490                 self.onClose.append(self.delSeekTimer)
491         
492         def up(self):
493                 pass
494         
495         def down(self):
496                 pass
497         
498         def delSeekTimer(self):
499                 del self.seekTimer
500         
501         def seekTimerFired(self):
502                 self.seekbase += self.skipmode * self.skipinterval
503                 
504                 # check if we bounced against the beginning of the file
505                 if self.seekbase < 0:
506                         self.seekbase = 0;
507                         self.setSeekState(self.SEEK_STATE_PLAY)
508                         
509                 self.doSeek(self.seekbase)
510
511         def setSeekState(self, state):
512                 oldstate = self.seekstate
513                 
514                 self.seekstate = state
515
516                 service = self.session.nav.getCurrentService()
517                 if service is None:
518                         return
519                 
520                 pauseable = service.pause()
521                 
522                 for i in range(4):
523                         if oldstate[i] != self.seekstate[i]:
524                                 (self.session.nav.pause, pauseable.setFastForward, pauseable.setSlowMotion, self.setSkipMode)[i](self.seekstate[i])
525                 
526         def setSkipMode(self, skipmode):
527                 self.skipmode = skipmode
528                 if skipmode == 0:
529                         self.seekTimer.stop()
530                 else:
531                         self.seekTimer.start(500)
532                 
533                 service = self.session.nav.getCurrentService()
534                 if service is None:
535                         return
536                 
537                 seekable = service.seek()
538                 if seekable is None:
539                         return
540
541                 if skipmode:
542                         seekable.setTrickmode(1)
543                 else:
544                         seekable.setTrickmode(0)
545                 
546                 self.seekbase = seekable.getPlayPosition()[1] / 90
547         
548         def pauseService(self):
549                 if (self.seekstate == self.SEEK_STATE_PAUSE):
550                         self.unPauseService()
551                 else:
552                         self.setSeekState(self.SEEK_STATE_PAUSE);
553                 
554         def unPauseService(self):
555                 self.setSeekState(self.SEEK_STATE_PLAY);
556         
557         def doSeek(self, seektime):
558                 service = self.session.nav.getCurrentService()
559                 if service is None:
560                         return
561                 
562                 seekable = service.seek()
563                 if seekable is None:
564                         return
565                 seekable.seekTo(90 * seektime)
566
567         def seekFwd(self):
568                 lookup = {
569                                 self.SEEK_STATE_PLAY: self.SEEK_STATE_FF_2X,
570                                 self.SEEK_STATE_PAUSE: self.SEEK_STATE_SM_EIGHTH,
571                                 self.SEEK_STATE_FF_2X: self.SEEK_STATE_FF_4X,
572                                 self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_8X,
573                                 self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_32X,
574                                 self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_64X,
575                                 self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_128X,
576                                 self.SEEK_STATE_FF_128X: self.SEEK_STATE_FF_128X,
577                                 self.SEEK_STATE_BACK_4X: self.SEEK_STATE_PLAY,
578                                 self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_4X,
579                                 self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_32X,
580                                 self.SEEK_STATE_BACK_128X: self.SEEK_STATE_BACK_64X,
581                                 self.SEEK_STATE_SM_HALF: self.SEEK_STATE_SM_HALF,
582                                 self.SEEK_STATE_SM_QUARTER: self.SEEK_STATE_SM_HALF,
583                                 self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_SM_QUARTER
584                         }
585                 self.setSeekState(lookup[self.seekstate]);
586         
587         def seekBack(self):
588                 lookup = {
589                                 self.SEEK_STATE_PLAY: self.SEEK_STATE_BACK_4X,
590                                 self.SEEK_STATE_PAUSE: self.SEEK_STATE_PAUSE,
591                                 self.SEEK_STATE_FF_2X: self.SEEK_STATE_PLAY,
592                                 self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_2X,
593                                 self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_4X,
594                                 self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_8X,
595                                 self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_32X,
596                                 self.SEEK_STATE_FF_128X: self.SEEK_STATE_FF_64X,
597                                 self.SEEK_STATE_BACK_4X: self.SEEK_STATE_BACK_32X,
598                                 self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_64X,
599                                 self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_128X,
600                                 self.SEEK_STATE_BACK_128X: self.SEEK_STATE_BACK_128X,
601                                 self.SEEK_STATE_SM_HALF: self.SEEK_STATE_SM_QUARTER,
602                                 self.SEEK_STATE_SM_QUARTER: self.SEEK_STATE_SM_EIGHTH,
603                                 self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_PAUSE
604                         }
605                 self.setSeekState(lookup[self.seekstate]);
606
607 from RecordTimer import parseEvent
608
609 class InfoBarInstantRecord:
610         """Instant Record - handles the instantRecord action in order to 
611         start/stop instant records"""
612         def __init__(self):
613                 self["InstantRecordActions"] = HelpableActionMap(self, "InfobarInstantRecord",
614                         {
615                                 "instantRecord": (self.instantRecord, "Instant Record..."),
616                         })
617                 self.recording = None
618                 
619                 self["BlinkingPoint"] = BlinkingPixmapConditional()
620                 self.onShown.append(self["BlinkingPoint"].hideWidget)
621                 self["BlinkingPoint"].setConnect(self.session.nav.RecordTimer.isRecording)
622                 
623         def stopCurrentRecording(self): 
624                 self.session.nav.RecordTimer.removeEntry(self.recording)
625                 self.recording = None
626                         
627         def startInstantRecording(self):
628                 serviceref = self.session.nav.getCurrentlyPlayingServiceReference()
629                 
630                 # try to get event info
631                 event = None
632                 try:
633                         service = self.session.nav.getCurrentService()
634                         info = service.info()
635                         ev = info.getEvent(0)
636                         event = ev
637                 except:
638                         pass
639                 
640                 if event is not None:
641                         data = parseEvent(event)
642                         data = (data[0], data[1] + 3600 * 10, data[2], data[3], data[4])
643                 else:
644                         data = (time.time(), time.time() + 3600 * 10, "instant record", "", None)
645                 
646                 # fix me, description. 
647                 self.recording = self.session.nav.recordWithTimer(serviceref, *data)
648                 self.recording.dontSave = True
649                 
650                 #self["BlinkingPoint"].setConnect(lambda: self.recording.isRunning())
651                 
652         def isInstantRecordRunning(self):
653                 if self.recording != None:
654                         if self.recording.isRunning():
655                                 return True
656                 return False
657
658         def recordQuestionCallback(self, answer):
659                 if answer == False:
660                         return
661                 
662                 if self.isInstantRecordRunning():
663                         self.stopCurrentRecording()
664                 else:
665                         self.startInstantRecording()
666
667         def instantRecord(self):
668                 try:
669                         stat = os.stat("/hdd/movies")
670                 except:
671                         self.session.open(MessageBox, "No HDD found!")
672                         return
673         
674                 if self.isInstantRecordRunning():
675                         self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Do you want to stop the current\n(instant) recording?"))
676                 else:
677                         self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Start recording?"))
678
679 from Screens.AudioSelection import AudioSelection
680
681 class InfoBarAudioSelection:
682         def __init__(self):
683                 self["AudioSelectionAction"] = HelpableActionMap(self, "InfobarAudioSelectionActions", 
684                         {
685                                 "audioSelection": (self.audioSelection, "Audio Options..."),
686                         })
687
688         def audioSelection(self):
689                 service = self.session.nav.getCurrentService()
690                 audio = service.audioTracks()
691                 n = audio.getNumberOfTracks()
692                 if n > 0:
693                         self.session.open(AudioSelection, audio)
694
695 from Screens.SubserviceSelection import SubserviceSelection
696
697 class InfoBarSubserviceSelection:
698         def __init__(self):
699                 self["SubserviceSelectionAction"] = HelpableActionMap(self, "InfobarSubserviceSelectionActions",
700                         {
701                                 "subserviceSelection": (self.subserviceSelection, "Subservice list..."),
702                         })
703
704         def subserviceSelection(self):
705                 service = self.session.nav.getCurrentService()
706                 subservices = service.subServices()
707                 n = subservices.getNumberOfSubservices()
708                 if n > 0:
709                         self.session.openWithCallback(self.subserviceSelected, SubserviceSelection, subservices)
710
711         def subserviceSelected(self, service):
712                 if not service is None:
713                         self.session.nav.playService(service)
714
715 class InfoBarAdditionalInfo:
716         def __init__(self):
717                 self["DolbyActive"] = Pixmap()
718                 self["CryptActive"] = Pixmap()
719                 self["FormatActive"] = Pixmap()
720                 
721                 self["ButtonRed"] = PixmapConditional(withTimer = False)
722                 self["ButtonRed"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
723                 self.onShown.append(self["ButtonRed"].update)
724                 self["ButtonRedText"] = LabelConditional(text = _("Record"), withTimer = False)
725                 self["ButtonRedText"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
726                 self.onShown.append(self["ButtonRedText"].update)
727
728                 self["ButtonGreen"] = Pixmap()
729                 self["ButtonGreenText"] = Label(_("Subservices"))
730
731                 self["ButtonYellow"] = PixmapConditional(withTimer = False)
732                 self["ButtonYellow"].setConnect(lambda: False)
733
734                 self["ButtonBlue"] = PixmapConditional(withTimer = False)
735                 self["ButtonBlue"].setConnect(lambda: False)
736
737                 self.session.nav.event.append(self.gotServiceEvent) # we like to get service events
738
739         def hideSubServiceIndication(self):
740                 self["ButtonGreen"].hideWidget()
741                 self["ButtonGreenText"].hide()
742
743         def showSubServiceIndication(self):
744                 self["ButtonGreen"].showWidget()
745                 self["ButtonGreenText"].show()
746
747         def checkFormat(self, service):
748                 info = service.info()
749                 if info is not None:
750                         aspect = info.getInfo(iServiceInformation.sAspect)
751                         if aspect in [ 3, 4, 7, 8, 0xB, 0xC, 0xF, 0x10 ]:
752                                 self["FormatActive"].showWidget()
753                         else:
754                                 self["FormatActive"].hideWidget()
755
756         def checkSubservices(self, service):
757                 if service.subServices().getNumberOfSubservices() > 0:
758                         self.showSubServiceIndication()
759                 else:
760                         self.hideSubServiceIndication()
761
762         def checkDolby(self, service):
763                 dolby = False
764                 audio = service.audioTracks()
765                 if audio is not None:
766                         n = audio.getNumberOfTracks()
767                         for x in range(n):
768                                 i = audio.getTrackInfo(x)
769                                 description = i.getDescription();
770                                 if description.find("AC3") != -1 or description.find("DTS") != -1:
771                                         dolby = True
772                                         break
773                 if dolby:
774                         self["DolbyActive"].showWidget()
775                 else:
776                         self["DolbyActive"].hideWidget()
777
778         def checkCrypted(self, service):
779                 info = service.info()
780                 if info is not None:
781                         if info.getInfo(iServiceInformation.sIsCrypted) > 0:
782                                 self["CryptActive"].showWidget()
783                         else:
784                                 self["CryptActive"].hideWidget()
785
786         def gotServiceEvent(self, ev):
787                 service = self.session.nav.getCurrentService()
788                 if ev == pNavigation.evUpdatedEventInfo:
789                         self.checkSubservices(service)
790                         self.checkFormat(service)
791                 elif ev == pNavigation.evUpdatedInfo:
792                         self.checkCrypted(service)
793                         self.checkDolby(service)
794                 elif ev == pNavigation.evStopService:
795                         self.hideSubServiceIndication()
796                         self["CryptActive"].hideWidget()
797                         self["DolbyActive"].hideWidget()
798                         self["FormatActive"].hideWidget()
799
800 class InfoBarNotifications:
801         def __init__(self):
802                 self.onExecBegin.append(self.checkNotifications)
803                 Notifications.notificationAdded.append(self.checkNotificationsIfExecing)
804         
805         def checkNotificationsIfExecing(self):
806                 if self.execing:
807                         self.checkNotifications()
808
809         def checkNotifications(self):
810                 if len(Notifications.notifications):
811                         n = Notifications.notifications[0]
812                         Notifications.notifications = Notifications.notifications[1:]
813                         print "open",n
814                         cb = n[0]
815                         if cb is not None:
816                                 self.session.openWithCallback(cb, *n[1:])
817                         else:
818                                 self.session.open(*n[1:])