typos
[enigma2.git] / lib / python / Screens / Wizard.py
1 from Screen import Screen
2
3 import string
4
5 from Screens.HelpMenu import HelpableScreen
6 from Components.config import config
7 from Components.Label import Label
8 from Components.Slider import Slider
9 from Components.ActionMap import NumberActionMap
10 from Components.MenuList import MenuList
11 from Components.ConfigList import ConfigList
12 from Components.Sources.List import List
13
14 from enigma import eTimer
15
16 from xml.sax import make_parser
17 from xml.sax.handler import ContentHandler
18
19 class WizardSummary(Screen):
20         skin = """
21         <screen position="0,0" size="132,64">
22                 <widget name="text" position="6,4" size="120,42" font="Regular;14" transparent="1" />
23                 <widget source="parent.list" render="Label" position="6,25" size="120,21" font="Regular;16">
24                         <convert type="StringListSelection" />
25                 </widget>
26         </screen>"""
27         
28         def __init__(self, session, parent):
29                 Screen.__init__(self, session, parent)
30                 
31                 #names = parent.skinName
32                 #if not isinstance(names, list):
33                         #names = [names]
34 #                       
35                 #self.skinName = [x + "_summary" for x in names ]
36                 #self.skinName.append("Wizard")
37                 #print "*************+++++++++++++++++****************++++++++++******************* WizardSummary", self.skinName
38                         #
39                 self["text"] = Label("")
40                 self.onShow.append(self.setCallback)
41                 
42         def setCallback(self):
43                 self.parent.setLCDTextCallback(self.setText)
44                 
45         def setText(self, text):
46                 self["text"].setText(text)
47
48 class Wizard(Screen, HelpableScreen):
49         def createSummary(self):
50                         print "WizardCreateSummary"
51                         return WizardSummary
52
53         class parseWizard(ContentHandler):
54                 def __init__(self, wizard):
55                         self.isPointsElement, self.isReboundsElement = 0, 0
56                         self.wizard = wizard
57                         self.currContent = ""
58                         self.lastStep = 0
59                         
60                 
61                 
62                 def startElement(self, name, attrs):
63                         print "startElement", name
64                         self.currContent = name
65                         if (name == "step"):
66                                 self.lastStep += 1
67                                 if attrs.has_key('id'):
68                                         id = str(attrs.get('id'))
69                                 else:
70                                         id = ""
71                                 print "id:", id
72                                 if attrs.has_key('nextstep'):
73                                         nextstep = str(attrs.get('nextstep'))
74                                 else:
75                                         nextstep = None
76                                 if attrs.has_key('timeout'):
77                                         timeout = int(attrs.get('timeout'))
78                                 else:
79                                         timeout = None
80                                 if attrs.has_key('timeoutaction'):
81                                         timeoutaction = str(attrs.get('timeoutaction'))
82                                 else:
83                                         timeoutaction = 'nextpage'
84
85                                 if attrs.has_key('timeoutstep'):
86                                         timeoutstep = str(attrs.get('timeoutstep'))
87                                 else:
88                                         timeoutstep = ''
89                                 self.wizard[self.lastStep] = {"id": id, "condition": "", "text": "", "timeout": timeout, "timeoutaction": timeoutaction, "timeoutstep": timeoutstep, "list": [], "config": {"screen": None, "args": None, "type": "" }, "code": "", "codeafter": "", "nextstep": nextstep}
90                         elif (name == "text"):
91                                 self.wizard[self.lastStep]["text"] = string.replace(str(attrs.get('value')), "\\n", "\n")
92                         elif (name == "displaytext"):
93                                 self.wizard[self.lastStep]["displaytext"] = string.replace(str(attrs.get('value')), "\\n", "\n")
94                         elif (name == "list"):
95                                 if (attrs.has_key('type')):
96                                         if attrs["type"] == "dynamic":
97                                                 self.wizard[self.lastStep]["dynamiclist"] = attrs.get("source")
98                                         #self.wizard[self.lastStep]["list"].append(("Hallo", "test"))
99                                 if (attrs.has_key("evaluation")):
100                                         print "evaluation"
101                                         self.wizard[self.lastStep]["listevaluation"] = attrs.get("evaluation")
102                                 if (attrs.has_key("onselect")):
103                                         self.wizard[self.lastStep]["onselect"] = attrs.get("onselect")                  
104                         elif (name == "listentry"):
105                                 self.wizard[self.lastStep]["list"].append((str(attrs.get('caption')), str(attrs.get('step'))))
106                         elif (name == "config"):
107                                 exec "from Screens." + str(attrs.get('module')) + " import *"
108                                 self.wizard[self.lastStep]["config"]["screen"] = eval(str(attrs.get('screen')))
109                                 if (attrs.has_key('args')):
110                                         print "has args"
111                                         self.wizard[self.lastStep]["config"]["args"] = str(attrs.get('args'))
112                                 self.wizard[self.lastStep]["config"]["type"] = str(attrs.get('type'))
113                         elif (name == "code"):
114                                 if attrs.has_key('pos') and str(attrs.get('pos')) == "after":
115                                         self.codeafter = True
116                                 else:
117                                         self.codeafter = False
118                         elif (name == "condition"):
119                                 pass
120                 def endElement(self, name):
121                         self.currContent = ""
122                         if name == 'code':
123                                 if self.codeafter:
124                                         self.wizard[self.lastStep]["codeafter"] = self.wizard[self.lastStep]["codeafter"].strip()
125                                 else:
126                                         self.wizard[self.lastStep]["code"] = self.wizard[self.lastStep]["code"].strip()
127                         elif name == 'condition':
128                                 self.wizard[self.lastStep]["condition"] = self.wizard[self.lastStep]["condition"].strip()
129                         elif name == 'step':
130                                 print "Step number", self.lastStep, ":", self.wizard[self.lastStep]
131                                                                 
132                 def characters(self, ch):
133                         if self.currContent == "code":
134                                 if self.codeafter:
135                                         self.wizard[self.lastStep]["codeafter"] = self.wizard[self.lastStep]["codeafter"] + ch
136                                 else:
137                                         self.wizard[self.lastStep]["code"] = self.wizard[self.lastStep]["code"] + ch
138                         elif self.currContent == "condition":
139                                  self.wizard[self.lastStep]["condition"] = self.wizard[self.lastStep]["condition"] + ch
140
141         def __init__(self, session, showSteps = True, showStepSlider = True, showList = True, showConfig = True):
142                 Screen.__init__(self, session)
143                 HelpableScreen.__init__(self)
144
145                 self.stepHistory = []
146
147                 self.wizard = {}
148                 parser = make_parser()
149                 print "Reading " + self.xmlfile
150                 wizardHandler = self.parseWizard(self.wizard)
151                 parser.setContentHandler(wizardHandler)
152                 if self.xmlfile[0] != '/':
153                         parser.parse('/usr/share/enigma2/' + self.xmlfile)
154                 else:
155                         parser.parse(self.xmlfile)
156
157                 self.showSteps = showSteps
158                 self.showStepSlider = showStepSlider
159                 self.showList = showList
160                 self.showConfig = showConfig
161
162                 self.numSteps = len(self.wizard)
163                 self.currStep = 1
164                 
165                 self.timeoutTimer = eTimer()
166                 self.timeoutTimer.callback.append(self.timeoutCounterFired)
167
168                 self["text"] = Label()
169
170                 if showConfig:
171                         self["config"] = ConfigList([])
172
173                 if self.showSteps:
174                         self["step"] = Label()
175                 
176                 if self.showStepSlider:
177                         self["stepslider"] = Slider(1, self.numSteps)
178                 
179                 if self.showList:
180                         self.list = []
181                         self["list"] = List(self.list, enableWrapAround = True)
182                         self["list"].onSelectionChanged.append(self.selChanged)
183                         #self["list"] = MenuList(self.list, enableWrapAround = True)
184
185                 self.onShown.append(self.updateValues)
186
187                 self.configInstance = None
188                 
189                 self.lcdCallbacks = []
190                 
191                 self["actions"] = NumberActionMap(["WizardActions", "NumberActions", "ColorActions"],
192                 {
193                         "ok": self.ok,
194                         "back": self.back,
195                         "left": self.left,
196                         "right": self.right,
197                         "up": self.up,
198                         "down": self.down,
199                         "red": self.red,
200                         "green": self.green,
201                         "yellow": self.yellow,
202                         "blue":self.blue,
203                         "1": self.keyNumberGlobal,
204                         "2": self.keyNumberGlobal,
205                         "3": self.keyNumberGlobal,
206                         "4": self.keyNumberGlobal,
207                         "5": self.keyNumberGlobal,
208                         "6": self.keyNumberGlobal,
209                         "7": self.keyNumberGlobal,
210                         "8": self.keyNumberGlobal,
211                         "9": self.keyNumberGlobal,
212                         "0": self.keyNumberGlobal
213                 }, -1)
214                 
215         def red(self):
216                 print "red"
217                 pass
218
219         def green(self):
220                 print "green"
221                 pass
222         
223         def yellow(self):
224                 print "yellow"
225                 pass
226         
227         def blue(self):
228                 print "blue"
229                 pass
230         
231         def setLCDTextCallback(self, callback):
232                 self.lcdCallbacks.append(callback)
233
234         def back(self):
235                 print "getting back..."
236                 print "stepHistory:", self.stepHistory
237                 if len(self.stepHistory) > 1:
238                         self.currStep = self.stepHistory[-2]
239                         self.stepHistory = self.stepHistory[:-2]
240                 if self.currStep < 1:
241                         self.currStep = 1
242                 print "currStep:", self.currStep
243                 print "new stepHistory:", self.stepHistory
244                 self.updateValues()
245                 print "after updateValues stepHistory:", self.stepHistory
246                 
247         def markDone(self):
248                 pass
249         
250         def getStepWithID(self, id):
251                 print "getStepWithID:", id
252                 count = 0
253                 for x in self.wizard:
254                         if self.wizard[x]["id"] == id:
255                                 print "result:", count
256                                 return count
257                         count += 1
258                 print "result: nothing"
259                 return 0
260
261         def finished(self, gotoStep = None, *args, **kwargs):
262                 print "finished"
263                 currStep = self.currStep
264
265                 if self.updateValues not in self.onShown:
266                         self.onShown.append(self.updateValues)
267
268                 if self.showList:
269                         if (len(self.wizard[currStep]["evaluatedlist"]) > 0):
270                                 print "current:", self["list"].current
271                                 nextStep = self["list"].current[1]
272                                 if (self.wizard[currStep].has_key("listevaluation")):
273                                         exec("self." + self.wizard[self.currStep]["listevaluation"] + "('" + nextStep + "')")
274                                 else:
275                                         self.currStep = self.getStepWithID(nextStep)
276
277                 if (currStep == self.numSteps): # wizard finished
278                         self.markDone()
279                         self.close()
280                 else:
281                         self.runCode(self.wizard[currStep]["codeafter"])
282                         if self.wizard[currStep]["nextstep"] is not None:
283                                 self.currStep = self.getStepWithID(self.wizard[currStep]["nextstep"])
284                         if gotoStep is not None:
285                                 self.currStep = self.getStepWithID(gotoStep)
286                         self.currStep += 1
287                         self.updateValues()
288
289                 print "Now: " + str(self.currStep)
290
291
292         def ok(self):
293                 print "OK"
294                 currStep = self.currStep
295                 
296                 if self.showConfig:
297                         if (self.wizard[currStep]["config"]["screen"] != None):
298                                 # TODO: don't die, if no run() is available
299                                 # there was a try/except here, but i can't see a reason
300                                 # for this. If there is one, please do a more specific check
301                                 # and/or a comment in which situation there is no run()
302                                 if callable(getattr(self.configInstance, "runAsync", None)):
303                                         self.onShown.remove(self.updateValues)
304                                         self.configInstance.runAsync(self.finished)
305                                         return
306                                 else:
307                                         self.configInstance.run()
308                 self.finished()
309
310         def keyNumberGlobal(self, number):
311                 if (self.wizard[self.currStep]["config"]["screen"] != None):
312                         self.configInstance.keyNumberGlobal(number)
313                 
314         def left(self):
315                 self.resetCounter()
316                 if (self.wizard[self.currStep]["config"]["screen"] != None):
317                         self.configInstance.keyLeft()
318                 print "left"
319         
320         def right(self):
321                 self.resetCounter()
322                 if (self.wizard[self.currStep]["config"]["screen"] != None):
323                         self.configInstance.keyRight()
324                 print "right"
325
326         def up(self):
327                 self.resetCounter()
328                 if (self.showConfig and self.wizard[self.currStep]["config"]["screen"] != None):
329                                 self["config"].instance.moveSelection(self["config"].instance.moveUp)
330                 elif (self.showList and len(self.wizard[self.currStep]["evaluatedlist"]) > 0):
331                         self["list"].selectPrevious()
332                         if self.wizard[self.currStep].has_key("onselect"):
333                                 print "current:", self["list"].current
334                                 self.selection = self["list"].current[-1]
335                                 #self.selection = self.wizard[self.currStep]["evaluatedlist"][self["list"].l.getCurrentSelectionIndex()][1]
336                                 exec("self." + self.wizard[self.currStep]["onselect"] + "()")
337                 print "up"
338                 
339         def down(self):
340                 self.resetCounter()
341                 if (self.showConfig and self.wizard[self.currStep]["config"]["screen"] != None):
342                         self["config"].instance.moveSelection(self["config"].instance.moveDown)
343                 elif (self.showList and len(self.wizard[self.currStep]["evaluatedlist"]) > 0):
344                         #self["list"].instance.moveSelection(self["list"].instance.moveDown)
345                         self["list"].selectNext()
346                         if self.wizard[self.currStep].has_key("onselect"):
347                                 print "current:", self["list"].current
348                                 #self.selection = self.wizard[self.currStep]["evaluatedlist"][self["list"].l.getCurrentSelectionIndex()][1]
349                                 #exec("self." + self.wizard[self.currStep]["onselect"] + "()")
350                                 self.selection = self["list"].current[-1]
351                                 #self.selection = self.wizard[self.currStep]["evaluatedlist"][self["list"].l.getCurrentSelectionIndex()][1]
352                                 exec("self." + self.wizard[self.currStep]["onselect"] + "()")
353                 print "down"
354                 
355         def selChanged(self):
356                 self.resetCounter()
357                 
358                 if (self.showConfig and self.wizard[self.currStep]["config"]["screen"] != None):
359                                 self["config"].instance.moveSelection(self["config"].instance.moveUp)
360                 elif (self.showList and len(self.wizard[self.currStep]["evaluatedlist"]) > 0):
361                         if self.wizard[self.currStep].has_key("onselect"):
362                                 self.selection = self["list"].current[-1]
363                                 print "self.selection:", self.selection
364                                 exec("self." + self.wizard[self.currStep]["onselect"] + "()")
365                 
366         def resetCounter(self):
367                 self.timeoutCounter = self.wizard[self.currStep]["timeout"]
368                 
369         def runCode(self, code):
370                 if code != "":
371                         print "code", code
372                         exec(code)
373                         
374         def updateText(self, firstset = False):
375                 text = _(self.wizard[self.currStep]["text"])
376                 if text.find("[timeout]") != -1:
377                         text = text.replace("[timeout]", str(self.timeoutCounter))
378                         self["text"].setText(text)
379                 else:
380                         if firstset:
381                                 self["text"].setText(text)
382                 
383         def updateValues(self):
384                 print "Updating values in step " + str(self.currStep)
385                 self.timeoutTimer.stop()
386                 
387                 if self.configInstance is not None:
388                         del self.configInstance["config"]
389                         self.configInstance.doClose()
390                         self.configInstance = None
391                 
392                 self.condition = True
393                 exec (self.wizard[self.currStep]["condition"])
394                 if self.condition:
395                         if len(self.stepHistory) == 0 or self.stepHistory[-1] != self.currStep:
396                                 self.stepHistory.append(self.currStep)
397                         print "wizard step:", self.wizard[self.currStep]
398                         
399                         if self.showSteps:
400                                 self["step"].setText(_("Step ") + str(self.currStep) + "/" + str(self.numSteps))
401                         if self.showStepSlider:
402                                 self["stepslider"].setValue(self.currStep)
403                 
404                         if self.wizard[self.currStep]["timeout"] is not None:
405                                 self.resetCounter() 
406                                 self.timeoutTimer.start(1000)
407                         
408                         print "wizard text", _(self.wizard[self.currStep]["text"])
409                         self.updateText(firstset = True)
410                         if self.wizard[self.currStep].has_key("displaytext"):
411                                 displaytext = self.wizard[self.currStep]["displaytext"]
412                                 print "set LCD text"
413                                 for x in self.lcdCallbacks:
414                                         x(displaytext)
415                                 
416                         self.runCode(self.wizard[self.currStep]["code"])
417                         
418                         if self.showList:
419                                 print "showing list,", self.currStep
420                                 for renderer in self.renderer:
421                                         rootrenderer = renderer
422                                         while renderer.source is not None:
423                                                 print "self.list:", self["list"]
424                                                 if renderer.source is self["list"]:
425                                                         print "setZPosition"
426                                                         rootrenderer.instance.setZPosition(1)
427                                                 renderer = renderer.source
428                                                 
429                                 #self["list"].instance.setZPosition(1)
430                                 self.list = []
431                                 if (self.wizard[self.currStep].has_key("dynamiclist")):
432                                         print "dynamic list, calling",  self.wizard[self.currStep]["dynamiclist"]
433                                         newlist = eval("self." + self.wizard[self.currStep]["dynamiclist"] + "()")
434                                         #self.wizard[self.currStep]["evaluatedlist"] = []
435                                         for entry in newlist:
436                                                 #self.wizard[self.currStep]["evaluatedlist"].append(entry)
437                                                 self.list.append(entry)
438                                         #del self.wizard[self.currStep]["dynamiclist"]
439                                 if (len(self.wizard[self.currStep]["list"]) > 0):
440                                         #self["list"].instance.setZPosition(2)
441                                         for x in self.wizard[self.currStep]["list"]:
442                                                 self.list.append((_(x[0]), x[1]))
443                                 self.wizard[self.currStep]["evaluatedlist"] = self.list
444                                 self["list"].list = self.list
445                                 self["list"].index = 0
446                         else:
447                                 self["list"].hide()
448         
449                         if self.showConfig:
450                                 self["config"].instance.setZPosition(1)
451                                 if (self.wizard[self.currStep]["config"]["screen"] != None):
452                                         if self.wizard[self.currStep]["config"]["type"] == "standalone":
453                                                 print "Type is standalone"
454                                                 self.session.openWithCallback(self.ok, self.wizard[self.currStep]["config"]["screen"])
455                                         else:
456                                                 self["config"].instance.setZPosition(2)
457                                                 print "wizard screen", self.wizard[self.currStep]["config"]["screen"]
458                                                 if self.wizard[self.currStep]["config"]["args"] == None:
459                                                         self.configInstance = self.session.instantiateDialog(self.wizard[self.currStep]["config"]["screen"])
460                                                 else:
461                                                         self.configInstance = self.session.instantiateDialog(self.wizard[self.currStep]["config"]["screen"], eval(self.wizard[self.currStep]["config"]["args"]))
462                                                 self["config"].l.setList(self.configInstance["config"].list)
463                                                 self.configInstance["config"].destroy()
464                                                 self.configInstance["config"] = self["config"]
465                                 else:
466                                         self["config"].l.setList([])
467                         else:
468                                 if self.has_key("config"):
469                                         self["config"].hide()
470                 else: # condition false
471                                 self.currStep += 1
472                                 self.updateValues()
473                                 
474         def timeoutCounterFired(self):
475                 self.timeoutCounter -= 1
476                 print "timeoutCounter:", self.timeoutCounter
477                 if self.timeoutCounter == 0:
478                         if self.wizard[self.currStep]["timeoutaction"] == "selectnext":
479                                 print "selection next item"
480                                 self.down()
481                         else:
482                                 if self.wizard[self.currStep]["timeoutaction"] == "changestep":
483                                         self.finished(gotoStep = self.wizard[self.currStep]["timeoutstep"])
484                 self.updateText()
485
486 class WizardManager:
487         def __init__(self):
488                 self.wizards = []
489         
490         def registerWizard(self, wizard, precondition, priority = 0):
491                 self.wizards.append((wizard, precondition, priority))
492         
493         def getWizards(self):
494                 list = []
495                 for x in self.wizards:
496                         if x[1] == 1: # precondition
497                                 list.append((x[2], x[0]))
498                 return list
499
500 wizardManager = WizardManager()