update for new config, add deleteDialog as inverse of instantiateDialog
[enigma2.git] / mytest.py
1 from Tools import RedirectOutput
2 from enigma import *
3 from tools import *
4
5 from Components.Language import language
6
7 def setEPGLanguage():
8         print "language set to", language.getLanguage()
9         eServiceEvent.setEPGLanguage(language.getLanguage())
10         
11 language.addCallback(setEPGLanguage)
12
13 import traceback
14 import Screens.InfoBar
15 from Screens.SimpleSummary import SimpleSummary
16
17 import sys
18 import time
19
20 import ServiceReference
21
22 from Navigation import Navigation
23
24 from skin import readSkin, applyAllAttributes
25
26 from Tools.Directories import InitFallbackFiles, resolveFilename, SCOPE_PLUGINS, SCOPE_SKIN_IMAGE
27 from Components.config import config, ConfigText, configfile, ConfigSubsection, ConfigInteger
28 InitFallbackFiles()
29 eDVBDB.getInstance().reloadBouquets()
30
31 config.misc.radiopic = ConfigText(default = resolveFilename(SCOPE_SKIN_IMAGE)+"radio.mvi")
32
33 try:
34         import e2reactor
35         e2reactor.install()
36         
37         from twisted.internet import reactor
38         
39         def runReactor():
40                 reactor.run()
41 except ImportError:
42         print "twisted not available"
43         def runReactor():
44                 runMainloop()
45
46 # initialize autorun plugins and plugin menu entries
47 from Components.PluginComponent import plugins
48
49 from Screens.Wizard import wizardManager
50 from Screens.ImageWizard import *
51 from Screens.StartWizard import *
52 from Screens.TutorialWizard import *
53 from Tools.BoundFunction import boundFunction
54 from Plugins.Plugin import PluginDescriptor
55
56 had = dict()
57
58 def dump(dir, p = ""):
59         if isinstance(dir, dict):
60                 for (entry, val) in dir.items():
61                         dump(val, p + "(dict)/" + entry)
62         if hasattr(dir, "__dict__"):
63                 for name, value in dir.__dict__.items():
64                         if not had.has_key(str(value)):
65                                 had[str(value)] = 1
66                                 dump(value, p + "/" + str(name))
67                         else:
68                                 print p + "/" + str(name) + ":" + str(dir.__class__) + "(cycle)"
69         else:
70                 print p + ":" + str(dir)
71
72 # + ":" + str(dir.__class__)
73
74 # display
75
76 class OutputDevice:
77         def create(self, screen): pass
78
79 # display: HTML
80
81 class HTMLOutputDevice(OutputDevice):
82         def create(self, comp):
83                 print comp.produceHTML()
84
85 html = HTMLOutputDevice()
86
87 class GUIOutputDevice(OutputDevice):
88         parent = None
89         def create(self, comp, desktop):
90                 comp.createGUIScreen(self.parent, desktop)
91
92 # Session.open:
93 # * push current active dialog ('current_dialog') onto stack
94 # * call execEnd for this dialog
95 #   * clear in_exec flag
96 #   * hide screen
97 # * instantiate new dialog into 'current_dialog'
98 #   * create screens, components
99 #   * read, apply skin
100 #   * create GUI for screen
101 # * call execBegin for new dialog
102 #   * set in_exec
103 #   * show gui screen
104 #   * call components' / screen's onExecBegin
105 # ... screen is active, until it calls 'close'...
106 # Session.close:
107 # * assert in_exec
108 # * save return value
109 # * start deferred close handler ('onClose')
110 # * execEnd
111 #   * clear in_exec
112 #   * hide screen
113 # .. a moment later:
114 # Session.doClose:
115 # * destroy screen
116
117 class Session:
118         def __init__(self, desktop = None, summary_desktop = None, navigation = None):
119                 self.desktop = desktop
120                 self.summary_desktop = summary_desktop
121                 self.nav = navigation
122                 self.delay_timer = eTimer()
123                 self.delay_timer.timeout.get().append(self.processDelay)
124                 
125                 self.current_dialog = None
126                 
127                 self.dialog_stack = [ ]
128                 self.summary_stack = [ ]
129                 self.summary = None
130                 
131                 self.in_exec = False
132                 
133                 for p in plugins.getPlugins(PluginDescriptor.WHERE_SESSIONSTART):
134                         p(reason=0, session=self)
135         
136         def processDelay(self):
137                 callback = self.current_dialog.callback
138
139                 retval = self.current_dialog.returnValue
140
141                 if self.current_dialog.isTmp:
142                         self.current_dialog.doClose()
143 #                       dump(self.current_dialog)
144                         del self.current_dialog
145                 else:
146                         del self.current_dialog.callback
147                 
148                 self.popCurrent()
149                 if callback is not None:
150                         callback(*retval)
151
152         def execBegin(self, first=True):
153                 assert not self.in_exec 
154                 self.in_exec = True
155                 c = self.current_dialog
156                 
157                 # when this is an execbegin after a execend of a "higher" dialog,
158                 # popSummary already did the right thing.
159                 if first:
160                         self.pushSummary()
161                         summary = c.createSummary() or SimpleSummary
162                         self.summary = self.instantiateSummaryDialog(summary, c)
163                         self.summary.show()
164                         c.addSummary(self.summary)
165
166                 c.execBegin()
167
168                 # when execBegin opened a new dialog, don't bother showing the old one.
169                 if c == self.current_dialog:
170                         c.show()
171                 
172         def execEnd(self, last=True):
173                 assert self.in_exec
174                 self.in_exec = False
175
176                 self.current_dialog.execEnd()
177                 self.current_dialog.hide()
178                 
179                 if last:
180                         self.current_dialog.removeSummary(self.summary)
181                         self.popSummary()
182         
183         def create(self, screen, arguments, **kwargs):
184                 # creates an instance of 'screen' (which is a class)
185                 try:
186                         return screen(self, *arguments, **kwargs)
187                 except:
188                         errstr = "Screen %s(%s, %s): %s" % (str(screen), str(arguments), str(kwargs), sys.exc_info()[0])
189                         print errstr
190                         traceback.print_exc(file=sys.stdout)
191                         quitMainloop(5)
192         
193         def instantiateDialog(self, screen, *arguments, **kwargs):
194                 return self.doInstantiateDialog(screen, arguments, kwargs, self.desktop)
195         
196         def deleteDialog(self, screen):
197                 screen.hide()
198                 screen.doClose()
199         
200         def instantiateSummaryDialog(self, screen, *arguments, **kwargs):
201                 return self.doInstantiateDialog(screen, arguments, kwargs, self.summary_desktop)
202         
203         def doInstantiateDialog(self, screen, arguments, kwargs, desktop):
204                 # create dialog
205                 
206                 try:
207                         dlg = self.create(screen, arguments, **kwargs)
208                 except:
209                         print 'EXCEPTION IN DIALOG INIT CODE, ABORTING:'
210                         print '-'*60
211                         traceback.print_exc(file=sys.stdout)
212                         quitMainloop(5)
213                         print '-'*60
214                 
215                 if dlg is None:
216                         return
217
218                 # read skin data
219                 readSkin(dlg, None, dlg.skinName, desktop)
220
221                 # create GUI view of this dialog
222                 assert desktop is not None
223                 
224                 z = 0
225                 title = ""
226                 for (key, value) in dlg.skinAttributes:
227                         if key == "zPosition":
228                                 z = int(value)
229                         elif key == "title":
230                                 title = value
231                 
232                 dlg.instance = eWindow(desktop, z)
233                 dlg.title = title
234                 applyAllAttributes(dlg.instance, desktop, dlg.skinAttributes)
235                 gui = GUIOutputDevice()
236                 gui.parent = dlg.instance
237                 gui.create(dlg, desktop)
238                 
239                 return dlg
240          
241         def pushCurrent(self):
242                 if self.current_dialog is not None:
243                         self.dialog_stack.append(self.current_dialog)
244                         self.execEnd(last=False)
245         
246         def popCurrent(self):
247                 if len(self.dialog_stack):
248                         self.current_dialog = self.dialog_stack.pop()
249                         self.execBegin(first=False)
250                 else:
251                         self.current_dialog = None
252
253         def execDialog(self, dialog):
254                 self.pushCurrent()
255                 self.current_dialog = dialog
256                 self.current_dialog.isTmp = False
257                 self.current_dialog.callback = None # would cause re-entrancy problems.
258                 self.execBegin()
259
260         def openWithCallback(self, callback, screen, *arguments, **kwargs):
261                 dlg = self.open(screen, *arguments, **kwargs)
262                 dlg.callback = callback
263                 return dlg
264
265         def open(self, screen, *arguments, **kwargs):
266                 if len(self.dialog_stack) and not self.in_exec:
267                         raise "modal open are allowed only from a screen which is modal!"
268                         # ...unless it's the very first screen.
269                 
270                 self.pushCurrent()
271                 dlg = self.current_dialog = self.instantiateDialog(screen, *arguments, **kwargs)
272                 dlg.isTmp = True
273                 dlg.callback = None
274                 self.execBegin()
275                 return dlg
276
277         def close(self, screen, *retval):
278                 if not self.in_exec:
279                         print "close after exec!"
280                         return
281                 
282                 # be sure that the close is for the right dialog!
283                 # if it's not, you probably closed after another dialog
284                 # was opened. this can happen if you open a dialog
285                 # onExecBegin, and forget to do this only once.
286                 # after close of the top dialog, the underlying will
287                 # gain focus again (for a short time), thus triggering
288                 # the onExec, which opens the dialog again, closing the loop.
289                 assert screen == self.current_dialog
290                 
291                 self.current_dialog.returnValue = retval
292                 self.delay_timer.start(0, 1)
293                 self.execEnd()
294
295         def pushSummary(self):
296                 if self.summary is not None:
297                         self.summary.hide()
298                 self.summary_stack.append(self.summary)
299                 self.summary = None
300
301         def popSummary(self):
302                 if self.summary is not None:
303                         self.summary.doClose()
304                 self.summary = self.summary_stack.pop()
305                 if self.summary is not None:
306                         self.summary.show()
307
308 from Screens.Volume import Volume
309 from Screens.Mute import Mute
310 from GlobalActions import globalActionMap
311
312 #TODO .. move this to a own .py file
313 class VolumeControl:
314         """Volume control, handles volUp, volDown, volMute actions and display
315         a corresponding dialog"""
316         def __init__(self, session):
317                 global globalActionMap
318                 globalActionMap.actions["volumeUp"]=self.volUp
319                 globalActionMap.actions["volumeDown"]=self.volDown
320                 globalActionMap.actions["volumeMute"]=self.volMute
321
322                 config.audio = ConfigSubsection()
323                 config.audio.volume = ConfigInteger(default = 100, limits = (0, 100))
324
325                 self.volumeDialog = session.instantiateDialog(Volume)
326                 self.muteDialog = session.instantiateDialog(Mute)
327
328                 self.hideVolTimer = eTimer()
329                 self.hideVolTimer.timeout.get().append(self.volHide)
330
331                 vol = config.audio.volume.value
332                 print "volume is", vol
333                 self.volumeDialog.setValue(vol)
334                 eDVBVolumecontrol.getInstance().setVolume(vol, vol)
335
336         def volSave(self):
337                 config.audio.volume.value = eDVBVolumecontrol.getInstance().getVolume()
338                 config.audio.volume.save()
339
340         def     volUp(self):
341                 if (eDVBVolumecontrol.getInstance().isMuted()):
342                         self.volMute()
343                 eDVBVolumecontrol.getInstance().volumeUp()
344                 self.volumeDialog.show()
345                 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
346                 self.volSave()
347                 self.hideVolTimer.start(3000, True)
348
349         def     volDown(self):
350                 if (eDVBVolumecontrol.getInstance().isMuted()):
351                         self.volMute()
352                 eDVBVolumecontrol.getInstance().volumeDown()
353                 self.volumeDialog.show()
354                 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
355                 self.volSave()
356                 self.hideVolTimer.start(3000, True)
357
358         def volHide(self):
359                 self.volumeDialog.hide()
360
361         def     volMute(self):
362                 eDVBVolumecontrol.getInstance().volumeToggleMute()
363                 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
364
365                 if (eDVBVolumecontrol.getInstance().isMuted()):
366                         self.muteDialog.show()
367                 else:
368                         self.muteDialog.hide()
369
370 from Screens.Standby import Standby
371
372 class PowerKey:
373         """ PowerKey stuff - handles the powerkey press and powerkey release actions"""
374         
375         def __init__(self, session):
376                 self.session = session
377                 self.powerKeyTimer = eTimer()
378                 self.powerKeyTimer.timeout.get().append(self.powertimer)
379                 globalActionMap.actions["powerdown"]=self.powerdown
380                 globalActionMap.actions["powerup"]=self.powerup
381                 self.standbyblocked = 0
382 #               self["PowerKeyActions"] = HelpableActionMap(self, "PowerKeyActions",
383                         #{
384                                 #"powerdown": self.powerdown,
385                                 #"powerup": self.powerup,
386                                 #"discreteStandby": (self.standby, "Go standby"),
387                                 #"discretePowerOff": (self.quit, "Go to deep standby"),
388                         #})
389
390         def powertimer(self):   
391                 print "PowerOff - Now!"
392                 self.quit()
393         
394         def powerdown(self):
395                 self.standbyblocked = 0
396                 self.powerKeyTimer.start(3000, True)
397
398         def powerup(self):
399                 self.powerKeyTimer.stop()
400                 if self.standbyblocked == 0:
401                         self.standbyblocked = 1
402                         self.standby()
403
404         def standby(self):
405                 if self.session.current_dialog and self.session.current_dialog.ALLOW_SUSPEND:
406                         self.session.open(Standby, self)
407
408         def quit(self):
409                 # halt
410                 quitMainloop(1)
411
412 def runScreenTest():
413         plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
414
415         session = Session(desktop = getDesktop(0), summary_desktop = getDesktop(1), navigation = Navigation())
416         
417         screensToRun = [ ]
418         
419         for p in plugins.getPlugins(PluginDescriptor.WHERE_WIZARD):
420                 screensToRun.append(p.__call__)
421         
422         screensToRun += wizardManager.getWizards()
423         
424         screensToRun.append(Screens.InfoBar.InfoBar)
425
426         ePythonConfigQuery.setQueryFunc(configfile.getResolvedKey)
427
428         def runNextScreen(session, screensToRun, *result):
429                 if result:
430                         quitMainloop(*result)
431                         return
432         
433                 screen = screensToRun[0]
434                 
435                 if len(screensToRun):
436                         session.openWithCallback(boundFunction(runNextScreen, session, screensToRun[1:]), screen)
437                 else:
438                         session.open(screen)
439         
440         runNextScreen(session, screensToRun)
441         
442         vol = VolumeControl(session)
443         power = PowerKey(session)
444         
445         runReactor()
446         
447         configfile.save()
448         
449         from Tools.DreamboxHardware import setFPWakeuptime
450         from time import time
451         nextRecordingTime = session.nav.RecordTimer.getNextRecordingTime()
452         if nextRecordingTime != -1:
453                 if (nextRecordingTime - time() < 330): # no time to switch box back on
454                         setFPWakeuptime(time() + 30) # so switch back on in 30 seconds
455                 else:
456                         setFPWakeuptime(nextRecordingTime - (300))
457         
458         session.nav.stopService()
459         session.nav.shutdown()
460         
461         return 0
462
463 import keymapparser
464 keymapparser.readKeymap()
465 import skin
466 skin.loadSkinData(getDesktop(0))
467
468 import Components.InputDevice
469 Components.InputDevice.InitInputDevices()
470
471 import Components.AVSwitch
472 Components.AVSwitch.InitAVSwitch()
473
474 import Components.RecordingConfig
475 Components.RecordingConfig.InitRecordingConfig()
476
477 import Components.UsageConfig
478 Components.UsageConfig.InitUsageConfig()
479
480 import Components.Network
481 Components.Network.InitNetwork()
482
483 import Components.Lcd
484 Components.Lcd.InitLcd()
485
486 import Components.SetupDevices
487 Components.SetupDevices.InitSetupDevices()
488
489 import Components.RFmod
490 Components.RFmod.InitRFmod()
491
492 import Components.NimManager
493
494 import Screens.Ci
495 Screens.Ci.InitCiConfig()
496
497 # first, setup a screen
498 try:
499         runScreenTest()
500
501         plugins.shutdown()
502 except:
503         print 'EXCEPTION IN PYTHON STARTUP CODE:'
504         print '-'*60
505         traceback.print_exc(file=sys.stdout)
506         quitMainloop(5)
507         print '-'*60