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