unmute on volUp and volDown if volume is muted
[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 Label
5 from Components.config import configfile, configsequencearg
6 from Components.config import config, configElement, ConfigSubsection, configSequence
7 from ChannelSelection import ChannelSelection
8
9 from Components.Pixmap import Pixmap, PixmapConditional
10 from Components.BlinkingPixmap import BlinkingPixmapConditional
11 from Components.ServiceName import ServiceName
12 from Components.EventInfo import EventInfo
13
14 from ServiceReference import ServiceReference
15 from EpgSelection import EPGSelection
16
17 from Screens.MessageBox import MessageBox
18 from Screens.Volume import Volume
19 from Screens.Mute import Mute
20 from Screens.Standby import Standby
21 from Screens.EventView import EventView
22
23 #from enigma import eTimer, eDVBVolumecontrol, quitMainloop
24 from enigma import *
25
26 import time
27 import os
28
29 # hack alert!
30 from Menu import MainMenu, mdom
31
32 class InfoBarVolumeControl:
33         """Volume control, handles volUp, volDown, volMute actions and display 
34         a corresponding dialog"""
35         def __init__(self):
36                 config.audio = ConfigSubsection()
37                 config.audio.volume = configElement("config.audio.volume", configSequence, [5], configsequencearg.get("INTEGER", (0, 100)))
38
39                 self["VolumeActions"] = ActionMap( ["InfobarVolumeActions"] ,
40                         {
41                                 "volumeUp": self.volUp,
42                                 "volumeDown": self.volDown,
43                                 "volumeMute": self.volMute,
44                         })
45
46                 self.volumeDialog = self.session.instantiateDialog(Volume)
47                 self.muteDialog = self.session.instantiateDialog(Mute)
48
49                 self.hideVolTimer = eTimer()
50                 self.hideVolTimer.timeout.get().append(self.volHide)
51
52                 vol = config.audio.volume.value[0]
53                 self.volumeDialog.setValue(vol)
54                 eDVBVolumecontrol.getInstance().setVolume(vol, vol)
55         
56         def volSave(self):
57                 config.audio.volume.value = eDVBVolumecontrol.getInstance().getVolume()
58                 config.audio.volume.save()
59                 
60         def     volUp(self):
61                 if (eDVBVolumecontrol.getInstance().isMuted()):
62                         self.volMute()
63                 eDVBVolumecontrol.getInstance().volumeUp()
64                 self.volumeDialog.instance.show()
65                 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
66                 self.volSave()
67                 self.hideVolTimer.start(3000)
68
69         def     volDown(self):
70                 if (eDVBVolumecontrol.getInstance().isMuted()):
71                         self.volMute()
72                 eDVBVolumecontrol.getInstance().volumeDown()
73                 self.volumeDialog.instance.show()
74                 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
75                 self.volSave()
76                 self.hideVolTimer.start(3000)
77                 
78         def volHide(self):
79                 self.volumeDialog.instance.hide()
80
81         def     volMute(self):
82                 eDVBVolumecontrol.getInstance().volumeToggleMute()
83                 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
84                 
85                 if (eDVBVolumecontrol.getInstance().isMuted()):
86                         self.muteDialog.instance.show()
87                 else:
88                         self.muteDialog.instance.hide()
89
90 class InfoBarShowHide:
91         """ InfoBar show/hide control, accepts toggleShow and hide actions, might start
92         fancy animations. """
93         STATE_HIDDEN = 0
94         STATE_HIDING = 1
95         STATE_SHOWING = 2
96         STATE_SHOWN = 3
97         
98         def __init__(self):
99                 self["ShowHideActions"] = ActionMap( ["InfobarShowHideActions"] ,
100                         {
101                                 "toggleShow": self.toggleShow,
102                                 "hide": self.hide,
103                         })
104
105                 self.state = self.STATE_SHOWN
106                 
107                 self.onExecBegin.append(self.show)
108                 self.onClose.append(self.delHideTimer)
109                 
110                 self.hideTimer = eTimer()
111                 self.hideTimer.timeout.get().append(self.doTimerHide)
112                 self.hideTimer.start(5000)
113
114         def delHideTimer(self):
115                 del self.hideTimer
116
117         def hide(self): 
118                 self.instance.hide()
119                 
120         def show(self):
121                 self.state = self.STATE_SHOWN
122                 self.hideTimer.stop()
123                 self.hideTimer.start(5000)
124
125         def doTimerHide(self):
126                 self.hideTimer.stop()
127                 if self.state == self.STATE_SHOWN:
128                         self.instance.hide()
129                         self.state = self.STATE_HIDDEN
130
131         def toggleShow(self):
132                 if self.state == self.STATE_SHOWN:
133                         self.instance.hide()
134                         #pls check animation support, sorry
135 #                       self.startHide()
136                         self.hideTimer.stop()
137                         self.state = self.STATE_HIDDEN
138                 elif self.state == self.STATE_HIDDEN:
139                         self.instance.show()
140                         self.show()
141                         
142         def startShow(self):
143                 self.instance.m_animation.startMoveAnimation(ePoint(0, 600), ePoint(0, 380), 100)
144                 self.state = self.STATE_SHOWN
145         
146         def startHide(self):
147                 self.instance.m_animation.startMoveAnimation(ePoint(0, 380), ePoint(0, 600), 100)
148                 self.state = self.STATE_HIDDEN
149
150 class NumberZap(Screen):
151         def quit(self):
152                 self.Timer.stop()
153                 self.close(0)
154
155         def keyOK(self):
156                 self.Timer.stop()
157                 self.close(int(self["number"].getText()))
158
159         def keyNumberGlobal(self, number):
160                 self.Timer.start(3000)          #reset timer
161                 self.field = self.field + str(number)
162                 self["number"].setText(self.field)
163                 if len(self.field) >= 4:
164                         self.keyOK()
165
166         def __init__(self, session, number):
167                 Screen.__init__(self, session)
168                 self.field = str(number)
169
170                 self["channel"] = Label(_("Channel:"))
171
172                 self["number"] = Label(self.field)
173
174                 self["actions"] = NumberActionMap( [ "SetupActions" ], 
175                         {
176                                 "cancel": self.quit,
177                                 "ok": self.keyOK,
178                                 "1": self.keyNumberGlobal,
179                                 "2": self.keyNumberGlobal,
180                                 "3": self.keyNumberGlobal,
181                                 "4": self.keyNumberGlobal,
182                                 "5": self.keyNumberGlobal,
183                                 "6": self.keyNumberGlobal,
184                                 "7": self.keyNumberGlobal,
185                                 "8": self.keyNumberGlobal,
186                                 "9": self.keyNumberGlobal,
187                                 "0": self.keyNumberGlobal
188                         })
189
190                 self.Timer = eTimer()
191                 self.Timer.timeout.get().append(self.keyOK)
192                 self.Timer.start(3000)
193
194 class InfoBarPowerKey:
195         """ PowerKey stuff - handles the powerkey press and powerkey release actions"""
196         
197         def __init__(self):
198                 self.powerKeyTimer = eTimer()
199                 self.powerKeyTimer.timeout.get().append(self.powertimer)
200                 self["PowerKeyActions"] = HelpableActionMap(self, "PowerKeyActions",
201                         {
202                                 "powerdown": self.powerdown,
203                                 "powerup": self.powerup,
204                                 "discreteStandby": (self.standby, "Go standby"),
205                                 "discretePowerOff": (self.quit, "Go to deep standby"),
206                         })
207
208         def powertimer(self):   
209                 print "PowerOff - Now!"
210                 self.quit()
211         
212         def powerdown(self):
213                 self.standbyblocked = 0
214                 self.powerKeyTimer.start(3000)
215
216         def powerup(self):
217                 self.powerKeyTimer.stop()
218                 if self.standbyblocked == 0:
219                         self.standbyblocked = 1
220                         self.standby()
221
222         def standby(self):
223                 self.session.open(Standby, self)
224
225         def quit(self):
226                 # halt
227                 quitMainloop(1)
228
229 class InfoBarNumberZap:
230         """ Handles an initial number for NumberZapping """
231         def __init__(self):
232                 self["NumberZapActions"] = NumberActionMap( [ "NumberZapActions"],
233                         {
234                                 "1": self.keyNumberGlobal,
235                                 "2": self.keyNumberGlobal,
236                                 "3": self.keyNumberGlobal,
237                                 "4": self.keyNumberGlobal,
238                                 "5": self.keyNumberGlobal,
239                                 "6": self.keyNumberGlobal,
240                                 "7": self.keyNumberGlobal,
241                                 "8": self.keyNumberGlobal,
242                                 "9": self.keyNumberGlobal,
243                                 "0": self.keyNumberGlobal,
244                         })
245
246         def keyNumberGlobal(self, number):
247 #               print "You pressed number " + str(number)
248                 self.session.openWithCallback(self.numberEntered, NumberZap, number)
249
250         def numberEntered(self, retval):
251 #               print self.servicelist
252                 if retval > 0:
253                         self.zapToNumber(retval)
254
255         def searchNumberHelper(self, serviceHandler, num, bouquet):
256                 servicelist = serviceHandler.list(bouquet)
257                 if not servicelist is None:
258                         while num:
259                                 serviceIterator = servicelist.getNext()
260                                 if not serviceIterator.valid(): #check end of list
261                                         break
262                                 if serviceIterator.flags: #assume normal dvb service have no flags set
263                                         continue
264                                 num -= 1;
265                         if not num: #found service with searched number ?
266                                 return serviceIterator, 0
267                 return None, num
268
269         def zapToNumber(self, number):
270                 bouquet = self.servicelist.bouquet_root
271                 service = None
272                 serviceHandler = eServiceCenter.getInstance()
273                 if bouquet.toString().find('FROM BOUQUET "bouquets.') == -1: #FIXME HACK
274                         service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
275                 else:
276                         bouquetlist = serviceHandler.list(bouquet)
277                         if not bouquetlist is None:
278                                 while number:
279                                         bouquet = bouquetlist.getNext()
280                                         if not bouquet.valid(): #check end of list
281                                                 break
282                                         if ((bouquet.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
283                                                 continue
284                                         service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
285                 if not service is None:
286                         self.session.nav.playService(service) #play service
287                         if self.servicelist.getRoot() != bouquet: #already in correct bouquet?
288                                 self.servicelist.setRoot(bouquet)
289                         self.servicelist.setCurrentSelection(service) #select the service in servicelist
290
291 class InfoBarChannelSelection:
292         """ ChannelSelection - handles the channelSelection dialog and the initial 
293         channelChange actions which open the channelSelection dialog """
294         def __init__(self):
295                 #instantiate forever
296                 self.servicelist = self.session.instantiateDialog(ChannelSelection)
297
298                 self["ChannelSelectActions"] = HelpableActionMap(self, "InfobarChannelSelection",
299                         {
300                                 "switchChannelUp": self.switchChannelUp,
301                                 "switchChannelDown": self.switchChannelDown,
302                                 "zapUp": (self.zapUp, _("next channel")),
303                                 "zapDown": (self.zapDown, _("previous channel")),
304                         })
305                         
306         def switchChannelUp(self):      
307                 self.servicelist.moveUp()
308                 self.session.execDialog(self.servicelist)
309
310         def switchChannelDown(self):    
311                 self.servicelist.moveDown()
312                 self.session.execDialog(self.servicelist)
313
314         def     zapUp(self):
315                 self.servicelist.moveUp()
316                 self.servicelist.zap()
317                 self.instance.show()
318                 self.show()
319
320         def     zapDown(self):
321                 self.servicelist.moveDown()
322                 self.servicelist.zap()
323                 self.instance.show()
324                 self.show()
325                 
326 class InfoBarMenu:
327         """ Handles a menu action, to open the (main) menu """
328         def __init__(self):
329                 self["MenuActions"] = HelpableActionMap(self, "InfobarMenuActions", 
330                         {
331                                 "mainMenu": (self.mainMenu, "Enter main menu..."),
332                         })
333
334         def mainMenu(self):
335                 print "loading mainmenu XML..."
336                 menu = mdom.childNodes[0]
337                 assert menu.tagName == "menu", "root element in menu must be 'menu'!"
338                 self.session.open(MainMenu, menu, menu.childNodes)
339
340 class InfoBarEPG:
341         """ EPG - Opens an EPG list when the showEPGList action fires """
342         def __init__(self):
343                 self["EPGActions"] = HelpableActionMap(self, "InfobarEPGActions", 
344                         {
345                                 "showEPGList": (self.showEPGList, _("show EPG...")),
346                         })
347
348         def showEPGList(self):
349                 ref=self.session.nav.getCurrentlyPlayingServiceReference()
350                 ptr=eEPGCache.getInstance()
351                 if ptr.startTimeQuery(ref) != -1:
352                         self.session.open(EPGSelection, ref)
353                 else: # try to show now/next
354                         print 'no epg for service', ref.toString()
355                         try:
356                                 self.epglist = [ ]
357                                 service = self.session.nav.getCurrentService()
358                                 info = service.info()
359                                 ptr=info.getEvent(0)
360                                 if ptr:
361                                         self.epglist.append(ptr)
362                                 ptr=info.getEvent(1)
363                                 if ptr:
364                                         self.epglist.append(ptr)
365                                 if len(self.epglist) > 0:
366                                         self.session.open(EventView, self.epglist[0], ServiceReference(ref), self.eventViewCallback)
367                         except:
368                                 pass
369
370         def eventViewCallback(self, setEvent, val): #used for now/next displaying
371                 if len(self.epglist) > 1:
372                         tmp = self.epglist[0]
373                         self.epglist[0]=self.epglist[1]
374                         self.epglist[1]=tmp
375                         setEvent(self.epglist[0])
376
377 class InfoBarEvent:
378         """provides a current/next event info display"""
379         def __init__(self):
380                 self["Event_Now_StartTime"] = EventInfo(self.session.nav, EventInfo.Now_StartTime)
381                 self["Event_Next_StartTime"] = EventInfo(self.session.nav, EventInfo.Next_StartTime)
382                                 
383                 self["Event_Now"] = EventInfo(self.session.nav, EventInfo.Now)
384                 self["Event_Next"] = EventInfo(self.session.nav, EventInfo.Next)
385
386                 self["Event_Now_Duration"] = EventInfo(self.session.nav, EventInfo.Now_Duration)
387                 self["Event_Next_Duration"] = EventInfo(self.session.nav, EventInfo.Next_Duration)
388
389 class InfoBarServiceName:
390         def __init__(self):
391                 self["ServiceName"] = ServiceName(self.session.nav)
392
393 class InfoBarPVR:
394         """handles PVR specific actions like seeking, pause"""
395         def __init__(self):
396                 self["PVRActions"] = HelpableActionMap(self, "InfobarPVRActions", 
397                         {
398                                 "pauseService": (self.pauseService, "pause"),
399                                 "unPauseService": (self.unPauseService, "continue"),
400                                 
401                                 "seekFwd": (self.seekFwd, "skip forward"),
402                                 "seekBack": (self.seekBack, "skip backward"),
403                         })
404                 
405         def pauseService(self):
406                 self.session.nav.pause(1)
407                 
408         def unPauseService(self):
409                 self.session.nav.pause(0)
410         
411         def doSeek(self, dir, seektime):
412                 service = self.session.nav.getCurrentService()
413                 if service is None:
414                         return
415                 
416                 seekable = service.seek()
417                 if seekable is None:
418                         return
419                 seekable.seekRelative(dir, 90 * seektime)
420
421         def seekFwd(self):
422                 self.doSeek(+1, 60000)
423         
424         def seekBack(self):
425                 self.doSeek(-1, 60000)
426
427 class InfoBarInstantRecord:
428         """Instant Record - handles the instantRecord action in order to 
429         start/stop instant records"""
430         def __init__(self):
431                 self["InstantRecordActions"] = HelpableActionMap(self, "InfobarInstantRecord",
432                         {
433                                 "instantRecord": (self.instantRecord, "Instant Record..."),
434                         })
435                 self.recording = None
436                 
437                 self["BlinkingPoint"] = BlinkingPixmapConditional()
438                 self.onShown.append(self["BlinkingPoint"].hidePixmap)
439                 self["BlinkingPoint"].setConnect(self.session.nav.RecordTimer.isRecording)
440                 
441         def stopCurrentRecording(self): 
442                 self.session.nav.RecordTimer.removeEntry(self.recording)
443                 self.recording = None
444                         
445         def startInstantRecording(self):
446                 serviceref = self.session.nav.getCurrentlyPlayingServiceReference()
447                         
448                 # try to get event info
449                 epg = None
450                 try:
451                         service = self.session.nav.getCurrentService()
452                         info = service.info()
453                         ev = info.getEvent(0)
454                         epg = ev
455                 except:
456                         pass
457                 
458                 # fix me, description. 
459                 self.recording = self.session.nav.recordWithTimer(time.time(), time.time() + 3600, serviceref, epg, "instant record")
460                 self.recording.dontSave = True
461                 
462                 #self["BlinkingPoint"].setConnect(lambda: self.recording.isRunning())
463                 
464         def isInstantRecordRunning(self):
465                 if self.recording != None:
466                         if self.recording.isRunning():
467                                 return True
468                 return False
469
470         def recordQuestionCallback(self, answer):
471                 if answer == False:
472                         return
473                 
474                 if self.isInstantRecordRunning():
475                         self.stopCurrentRecording()
476                 else:
477                         self.startInstantRecording()
478
479         def instantRecord(self):
480                 try:
481                         stat = os.stat("/hdd/movies")
482                 except:
483                         self.session.open(MessageBox, "No HDD found!")
484                         return
485         
486                 if self.isInstantRecordRunning():
487                         self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Do you want to stop the current\n(instant) recording?"))
488                 else:
489                         self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Start recording?"))
490
491 from Screens.AudioSelection import AudioSelection
492
493 class InfoBarAudioSelection:
494         def __init__(self):
495                 self["AudioSelectionAction"] = HelpableActionMap(self, "InfobarAudioSelectionActions", 
496                         {
497                                 "audioSelection": (self.audioSelection, "Audio Options..."),
498                         })
499
500         def audioSelection(self):
501                 service = self.session.nav.getCurrentService()
502                 audio = service.audioTracks()
503                 n = audio.getNumberOfTracks()
504                 if n > 0:
505                         self.session.open(AudioSelection, audio)
506
507 class InfoBarAdditionalInfo:
508         def __init__(self):
509                 self["DolbyActive"] = PixmapConditional()
510                 # TODO: get the info from c++ somehow
511                 self["DolbyActive"].setConnect(lambda: False)
512                 
513                 self["CryptActive"] = PixmapConditional()
514                 # TODO: get the info from c++ somehow
515                 self["CryptActive"].setConnect(lambda: False)
516                 
517                 self["FormatActive"] = PixmapConditional()
518                 # TODO: get the info from c++ somehow
519                 self["FormatActive"].setConnect(lambda: False)
520                 
521                 self["ButtonRed"] = Pixmap()
522                 self["ButtonRedText"] = Label(_("Record"))
523                 self["ButtonGreen"] = Pixmap()
524                 self["ButtonYellow"] = Pixmap()
525                 self["ButtonBlue"] = Pixmap()