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