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