changing service in timer edit is now possible
[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.onExecBegin.append(self.show)
102                 self.onClose.append(self.delHideTimer)
103                 
104                 self.hideTimer = eTimer()
105                 self.hideTimer.timeout.get().append(self.doTimerHide)
106                 self.hideTimer.start(5000)
107
108         def delHideTimer(self):
109                 del self.hideTimer
110
111         def hide(self): 
112                 self.instance.hide()
113                 
114         def show(self):
115                 self.state = self.STATE_SHOWN
116                 self.hideTimer.stop()
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                 self.instance.show()
276                 self.show()
277
278         def     zapDown(self):
279                 self.servicelist.moveDown()
280                 self.servicelist.zap()
281                 self.instance.show()
282                 self.show()
283                 
284 class InfoBarMenu:
285         """ Handles a menu action, to open the (main) menu """
286         def __init__(self):
287                 self["MenuActions"] = HelpableActionMap(self, "InfobarMenuActions", 
288                         {
289                                 "mainMenu": (self.mainMenu, "Enter main menu..."),
290                         })
291
292         def mainMenu(self):
293                 print "loading mainmenu XML..."
294                 menu = mdom.childNodes[0]
295                 assert menu.tagName == "menu", "root element in menu must be 'menu'!"
296                 self.session.open(MainMenu, menu, menu.childNodes)
297
298 class InfoBarEPG:
299         """ EPG - Opens an EPG list when the showEPGList action fires """
300         def __init__(self):
301                 self["EPGActions"] = HelpableActionMap(self, "InfobarEPGActions", 
302                         {
303                                 "showEPGList": (self.showEPGList, _("show EPG...")),
304                         })
305
306         def showEPGList(self):
307                 ref=self.session.nav.getCurrentlyPlayingServiceReference()
308                 ptr=eEPGCache.getInstance()
309                 if ptr.startTimeQuery(ref) != -1:
310                         self.session.open(EPGSelection, ref)
311                 else: # try to show now/next
312                         print 'no epg for service', ref.toString()
313                         try:
314                                 self.epglist = [ ]
315                                 service = self.session.nav.getCurrentService()
316                                 info = service.info()
317                                 ptr=info.getEvent(0)
318                                 if ptr:
319                                         self.epglist.append(ptr)
320                                 ptr=info.getEvent(1)
321                                 if ptr:
322                                         self.epglist.append(ptr)
323                                 if len(self.epglist) > 0:
324                                         self.session.open(EventView, self.epglist[0], ServiceReference(ref), self.eventViewCallback)
325                         except:
326                                 pass
327
328         def eventViewCallback(self, setEvent, val): #used for now/next displaying
329                 if len(self.epglist) > 1:
330                         tmp = self.epglist[0]
331                         self.epglist[0]=self.epglist[1]
332                         self.epglist[1]=tmp
333                         setEvent(self.epglist[0])
334
335 class InfoBarEvent:
336         """provides a current/next event info display"""
337         def __init__(self):
338                 self["Event_Now_StartTime"] = EventInfo(self.session.nav, EventInfo.Now_StartTime)
339                 self["Event_Next_StartTime"] = EventInfo(self.session.nav, EventInfo.Next_StartTime)
340                                 
341                 self["Event_Now"] = EventInfo(self.session.nav, EventInfo.Now)
342                 self["Event_Next"] = EventInfo(self.session.nav, EventInfo.Next)
343
344                 self["Event_Now_Duration"] = EventInfo(self.session.nav, EventInfo.Now_Duration)
345                 self["Event_Next_Duration"] = EventInfo(self.session.nav, EventInfo.Next_Duration)
346
347 class InfoBarServiceName:
348         def __init__(self):
349                 self["ServiceName"] = ServiceName(self.session.nav)
350
351 class InfoBarPVR:
352         """handles PVR specific actions like seeking, pause"""
353         def __init__(self):
354                 self["PVRActions"] = HelpableActionMap(self, "InfobarPVRActions", 
355                         {
356                                 "pauseService": (self.pauseService, "pause"),
357                                 "unPauseService": (self.unPauseService, "continue"),
358                                 
359                                 "seekFwd": (self.seekFwd, "skip forward"),
360                                 "seekBack": (self.seekBack, "skip backward"),
361                         })
362                 
363         def pauseService(self):
364                 self.session.nav.pause(1)
365                 
366         def unPauseService(self):
367                 self.session.nav.pause(0)
368         
369         def doSeek(self, dir, seektime):
370                 service = self.session.nav.getCurrentService()
371                 if service is None:
372                         return
373                 
374                 seekable = service.seek()
375                 if seekable is None:
376                         return
377                 seekable.seekRelative(dir, 90 * seektime)
378
379         def seekFwd(self):
380                 self.doSeek(+1, 60000)
381         
382         def seekBack(self):
383                 self.doSeek(-1, 60000)
384
385 class InfoBarInstantRecord:
386         """Instant Record - handles the instantRecord action in order to 
387         start/stop instant records"""
388         def __init__(self):
389                 self["InstnantRecordActions"] = HelpableActionMap(self, "InfobarInstantRecord",
390                         {
391                                 "instantRecord": (self.instantRecord, "Instant Record..."),
392                         })
393                 self.recording = None
394
395         def stopCurrentRecording(self): 
396                 self.session.nav.RecordTimer.removeEntry(self.recording)
397                 self.recording = None
398         
399         def startInstantRecording(self):
400                 serviceref = self.session.nav.getCurrentlyPlayingServiceReference()
401                         
402                 # try to get event info
403                 epg = None
404                 try:
405                         service = self.session.nav.getCurrentService()
406                         info = service.info()
407                         ev = info.getEvent(0)
408                         epg = ev
409                 except:
410                         pass
411                 
412                 # fix me, description. 
413                 self.recording = self.session.nav.recordWithTimer(time.time(), time.time() + 3600, serviceref, epg, "instant record")
414                 self.recording.dontSave = True
415
416         def recordQuestionCallback(self, answer):
417                 if answer == False:
418                         return
419                 
420                 if self.recording != None:
421                         self.stopCurrentRecording()
422                 else:
423                         self.startInstantRecording()
424
425         def instantRecord(self):
426                 try:
427                         stat = os.stat("/hdd/movies")
428                 except:
429                         self.session.open(MessageBox, "No HDD found!")
430                         return
431         
432                 if self.recording != None:
433                         self.session.openWithCallback(self.recordQuestionCallback, MessageBox, "Do you want to stop the current\n(instant) recording?")
434                 else:
435                         self.session.openWithCallback(self.recordQuestionCallback, MessageBox, "Start recording?")
436
437 from Screens.AudioSelection import AudioSelection
438
439 class InfoBarAudioSelection:
440         def __init__(self):
441                 self["AudioSelectionAction"] = HelpableActionMap(self, "InfobarAudioSelectionActions", 
442                         {
443                                 "audioSelection": (self.audioSelection, "Audio Options..."),
444                         })
445
446         def audioSelection(self):
447                 service = self.session.nav.getCurrentService()
448                 audio = service.audioTracks()
449                 n = audio.getNumberOfTracks()
450                 if n > 0:
451                         self.session.open(AudioSelection, audio)