fix timerHide in infobar
[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                 print "INFOBARSHOWHIDE init"
94                 self["ShowHideActions"] = ActionMap( ["InfobarShowHideActions"] ,
95                         {
96                                 "toggleShow": self.toggleShow,
97                                 "hide": self.hide,
98                         })
99
100                 self.state = self.STATE_SHOWN
101                 
102                 self.onExecBegin.append(self.show)
103                 self.onClose.append(self.delHideTimer)
104                 
105                 self.hideTimer = eTimer()
106                 self.hideTimer.timeout.get().append(self.doTimerHide)
107                 self.hideTimer.start(5000)
108
109         def delHideTimer(self):
110                 del self.hideTimer
111
112         def hide(self): 
113                 self.instance.hide()
114                 
115         def show(self):
116                 self.state = self.STATE_SHOWN
117                 self.hideTimer.start(5000)
118
119         def doTimerHide(self):
120                 self.hideTimer.stop()
121                 if self.state == self.STATE_SHOWN:
122                         self.instance.hide()
123                         self.state = self.STATE_HIDDEN
124
125         def toggleShow(self):
126                 if self.state == self.STATE_SHOWN:
127                         self.instance.hide()
128                         #pls check animation support, sorry
129 #                       self.startHide()
130                         self.hideTimer.stop()
131                         self.state = self.STATE_HIDDEN
132                 elif self.state == self.STATE_HIDDEN:
133                         self.instance.show()
134                         self.show()
135                         
136         def startShow(self):
137                 self.instance.m_animation.startMoveAnimation(ePoint(0, 600), ePoint(0, 380), 100)
138                 self.state = self.STATE_SHOWN
139         
140         def startHide(self):
141                 self.instance.m_animation.startMoveAnimation(ePoint(0, 380), ePoint(0, 600), 100)
142                 self.state = self.STATE_HIDDEN
143
144 class NumberZap(Screen):
145         def quit(self):
146                 self.Timer.stop()
147                 self.close(0)
148
149         def keyOK(self):
150                 self.Timer.stop()
151                 self.close(int(self["number"].getText()))
152
153         def keyNumberGlobal(self, number):
154                 self.Timer.start(3000)          #reset timer
155                 self.field = self.field + str(number)
156                 self["number"].setText(self.field)
157                 if len(self.field) >= 4:
158                         self.keyOK()
159
160         def __init__(self, session, number):
161                 Screen.__init__(self, session)
162                 self.field = str(number)
163
164                 self["channel"] = Label(_("Channel:"))
165
166                 self["number"] = Label(self.field)
167
168                 self["actions"] = NumberActionMap( [ "SetupActions" ], 
169                         {
170                                 "cancel": self.quit,
171                                 "ok": self.keyOK,
172                                 "1": self.keyNumberGlobal,
173                                 "2": self.keyNumberGlobal,
174                                 "3": self.keyNumberGlobal,
175                                 "4": self.keyNumberGlobal,
176                                 "5": self.keyNumberGlobal,
177                                 "6": self.keyNumberGlobal,
178                                 "7": self.keyNumberGlobal,
179                                 "8": self.keyNumberGlobal,
180                                 "9": self.keyNumberGlobal,
181                                 "0": self.keyNumberGlobal
182                         })
183
184                 self.Timer = eTimer()
185                 self.Timer.timeout.get().append(self.keyOK)
186                 self.Timer.start(3000)
187
188 class InfoBarPowerKey:
189         """ PowerKey stuff - handles the powerkey press and powerkey release actions"""
190         
191         def __init__(self):
192                 self.powerKeyTimer = eTimer()
193                 self.powerKeyTimer.timeout.get().append(self.powertimer)
194                 self["PowerKeyActions"] = HelpableActionMap(self, "PowerKeyActions",
195                         {
196                                 "powerdown": self.powerdown,
197                                 "powerup": self.powerup,
198                                 "discreteStandby": (self.standby, "Go standby"),
199                                 "discretePowerOff": (self.quit, "Go to deep standby"),
200                         })
201
202         def powertimer(self):   
203                 print "PowerOff - Now!"
204                 self.quit()
205         
206         def powerdown(self):
207                 self.standbyblocked = 0
208                 self.powerKeyTimer.start(3000)
209
210         def powerup(self):
211                 self.powerKeyTimer.stop()
212                 if self.standbyblocked == 0:
213                         self.standbyblocked = 1
214                         self.standby()
215
216         def standby(self):
217                 self.session.open(Standby, self)
218
219         def quit(self):
220                 # halt
221                 quitMainloop(1)
222
223 class InfoBarNumberZap:
224         """ Handles an initial number for NumberZapping """
225         def __init__(self):
226                 self["NumberZapActions"] = NumberActionMap( [ "NumberZapActions"],
227                         {
228                                 "1": self.keyNumberGlobal,
229                                 "2": self.keyNumberGlobal,
230                                 "3": self.keyNumberGlobal,
231                                 "4": self.keyNumberGlobal,
232                                 "5": self.keyNumberGlobal,
233                                 "6": self.keyNumberGlobal,
234                                 "7": self.keyNumberGlobal,
235                                 "8": self.keyNumberGlobal,
236                                 "9": self.keyNumberGlobal,
237                                 "0": self.keyNumberGlobal,
238                         })
239
240         def keyNumberGlobal(self, number):
241 #               print "You pressed number " + str(number)
242                 self.session.openWithCallback(self.numberEntered, NumberZap, number)
243
244         def numberEntered(self, retval):
245 #               print self.servicelist
246                 if retval > 0:
247                         self.servicelist.zapToNumber(retval)
248
249 class InfoBarChannelSelection:
250         """ ChannelSelection - handles the channelSelection dialog and the initial 
251         channelChange actions which open the channelSelection dialog """
252         def __init__(self):
253                 #instantiate forever
254                 self.servicelist = self.session.instantiateDialog(ChannelSelection)
255
256                 self["ChannelSelectActions"] = HelpableActionMap(self, "InfobarChannelSelection",
257                         {
258                                 "switchChannelUp": self.switchChannelUp,
259                                 "switchChannelDown": self.switchChannelDown,
260                                 "zapUp": (self.zapUp, _("next channel")),
261                                 "zapDown": (self.zapDown, _("previous channel")),
262                         })
263                         
264         def switchChannelUp(self):      
265                 self.servicelist.moveUp()
266                 self.session.execDialog(self.servicelist)
267
268         def switchChannelDown(self):    
269                 self.servicelist.moveDown()
270                 self.session.execDialog(self.servicelist)
271
272         def     zapUp(self):
273                 self.servicelist.moveUp()
274                 self.servicelist.zap()
275
276         def     zapDown(self):
277                 self.servicelist.moveDown()
278                 self.servicelist.zap()
279
280 class InfoBarMenu:
281         """ Handles a menu action, to open the (main) menu """
282         def __init__(self):
283                 self["MenuActions"] = HelpableActionMap(self, "InfobarMenuActions", 
284                         {
285                                 "mainMenu": (self.mainMenu, "Enter main menu..."),
286                         })
287
288         def mainMenu(self):
289                 print "loading mainmenu XML..."
290                 menu = mdom.childNodes[0]
291                 assert menu.tagName == "menu", "root element in menu must be 'menu'!"
292                 self.session.open(MainMenu, menu, menu.childNodes)
293
294 class InfoBarEPG:
295         """ EPG - Opens an EPG list when the showEPGList action fires """
296         def __init__(self):
297                 self["EPGActions"] = HelpableActionMap(self, "InfobarEPGActions", 
298                         {
299                                 "showEPGList": (self.showEPGList, _("show EPG...")),
300                         })
301
302         def showEPGList(self):
303                 ref=self.session.nav.getCurrentlyPlayingServiceReference()
304                 ptr=eEPGCache.getInstance()
305                 if ptr.startTimeQuery(ref) != -1:
306                         self.session.open(EPGSelection, ref)
307                 else: # try to show now/next
308                         print 'no epg for service', ref.toString()
309                         try:
310                                 self.epglist = [ ]
311                                 service = self.session.nav.getCurrentService()
312                                 info = service.info()
313                                 ptr=info.getEvent(0)
314                                 if ptr:
315                                         self.epglist.append(ptr)
316                                 ptr=info.getEvent(1)
317                                 if ptr:
318                                         self.epglist.append(ptr)
319                                 if len(self.epglist) > 0:
320                                         self.session.open(EventView, self.epglist[0], ServiceReference(ref), self.eventViewCallback)
321                         except:
322                                 pass
323
324         def eventViewCallback(self, setEvent, val): #used for now/next displaying
325                 if len(self.epglist) > 1:
326                         tmp = self.epglist[0]
327                         self.epglist[0]=self.epglist[1]
328                         self.epglist[1]=tmp
329                         setEvent(self.epglist[0])
330
331 class InfoBarEvent:
332         """provides a current/next event info display"""
333         def __init__(self):
334                 self["Event_Now_StartTime"] = EventInfo(self.session.nav, EventInfo.Now_StartTime)
335                 self["Event_Next_StartTime"] = EventInfo(self.session.nav, EventInfo.Next_StartTime)
336                                 
337                 self["Event_Now"] = EventInfo(self.session.nav, EventInfo.Now)
338                 self["Event_Next"] = EventInfo(self.session.nav, EventInfo.Next)
339
340                 self["Event_Now_Duration"] = EventInfo(self.session.nav, EventInfo.Now_Duration)
341                 self["Event_Next_Duration"] = EventInfo(self.session.nav, EventInfo.Next_Duration)
342
343 class InfoBarServiceName:
344         def __init__(self):
345                 self["ServiceName"] = ServiceName(self.session.nav)
346
347 class InfoBarPVR:
348         """handles PVR specific actions like seeking, pause"""
349         def __init__(self):
350                 self["PVRActions"] = HelpableActionMap(self, "InfobarPVRActions", 
351                         {
352                                 "pauseService": (self.pauseService, "pause"),
353                                 "unPauseService": (self.unPauseService, "continue"),
354                                 
355                                 "seekFwd": (self.seekFwd, "skip forward"),
356                                 "seekBack": (self.seekBack, "skip backward"),
357                         })
358                 
359         def pauseService(self):
360                 self.session.nav.pause(1)
361                 
362         def unPauseService(self):
363                 self.session.nav.pause(0)
364         
365         def doSeek(self, dir, seektime):
366                 service = self.session.nav.getCurrentService()
367                 if service is None:
368                         return
369                 
370                 seekable = service.seek()
371                 if seekable is None:
372                         return
373                 seekable.seekRelative(dir, 90 * seektime)
374
375         def seekFwd(self):
376                 self.doSeek(+1, 60000)
377         
378         def seekBack(self):
379                 self.doSeek(-1, 60000)
380
381 class InfoBarInstantRecord:
382         """Instant Record - handles the instantRecord action in order to 
383         start/stop instant records"""
384         def __init__(self):
385                 self["InstnantRecordActions"] = HelpableActionMap(self, "InfobarInstantRecord",
386                         {
387                                 "instantRecord": (self.instantRecord, "Instant Record..."),
388                         })
389                 self.recording = None
390
391         def stopCurrentRecording(self): 
392                 self.session.nav.RecordTimer.removeEntry(self.recording)
393                 self.recording = None
394         
395         def startInstantRecording(self):
396                 serviceref = self.session.nav.getCurrentlyPlayingServiceReference()
397                         
398                 # try to get event info
399                 epg = None
400                 try:
401                         service = self.session.nav.getCurrentService()
402                         info = service.info()
403                         ev = info.getEvent(0)
404                         epg = ev
405                 except:
406                         pass
407                 
408                 # fix me, description. 
409                 self.recording = self.session.nav.recordWithTimer(time.time(), time.time() + 3600, serviceref, epg, "instant record")
410                 self.recording.dontSave = True
411
412         def recordQuestionCallback(self, answer):
413                 if answer == False:
414                         return
415                 
416                 if self.recording != None:
417                         self.stopCurrentRecording()
418                 else:
419                         self.startInstantRecording()
420
421         def instantRecord(self):
422                 try:
423                         stat = os.stat("/hdd/movies")
424                 except:
425                         self.session.open(MessageBox, "No HDD found!")
426                         return
427         
428                 if self.recording != None:
429                         self.session.openWithCallback(self.recordQuestionCallback, MessageBox, "Do you want to stop the current\n(instant) recording?")
430                 else:
431                         self.session.openWithCallback(self.recordQuestionCallback, MessageBox, "Start recording?")
432
433 from Screens.AudioSelection import AudioSelection
434
435 class InfoBarAudioSelection:
436         def __init__(self):
437                 self["AudioSelectionAction"] = HelpableActionMap(self, "InfobarAudioSelectionActions", 
438                         {
439                                 "audioSelection": (self.audioSelection, "Audio Options..."),
440                         })
441
442         def audioSelection(self):
443                 service = self.session.nav.getCurrentService()
444                 audio = service.audioTracks()
445                 n = audio.getNumberOfTracks()
446                 if n > 0:
447                         self.session.open(AudioSelection, audio)