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