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