17a8150e0e9c2693095e11137a98237b96652e42
[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, KEY_LEFT, KEY_RIGHT, KEY_DELETE, KEY_BACKSPACE
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):
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                 def startElement(self, name, attrs):
61                         #print "startElement", name
62                         self.currContent = name
63                         if (name == "step"):
64                                 self.lastStep += 1
65                                 if attrs.has_key('id'):
66                                         id = str(attrs.get('id'))
67                                 else:
68                                         id = ""
69                                 #print "id:", id
70                                 if attrs.has_key('nextstep'):
71                                         nextstep = str(attrs.get('nextstep'))
72                                 else:
73                                         nextstep = None
74                                 if attrs.has_key('timeout'):
75                                         timeout = int(attrs.get('timeout'))
76                                 else:
77                                         timeout = None
78                                 if attrs.has_key('timeoutaction'):
79                                         timeoutaction = str(attrs.get('timeoutaction'))
80                                 else:
81                                         timeoutaction = 'nextpage'
82
83                                 if attrs.has_key('timeoutstep'):
84                                         timeoutstep = str(attrs.get('timeoutstep'))
85                                 else:
86                                         timeoutstep = ''
87                                 self.wizard[self.lastStep] = {"id": id, "condition": "", "text": "", "timeout": timeout, "timeoutaction": timeoutaction, "timeoutstep": timeoutstep, "list": [], "config": {"screen": None, "args": None, "type": "" }, "code": "", "codeafter": "", "code_async": "", "codeafter_async": "", "nextstep": nextstep}
88                         elif (name == "text"):
89                                 self.wizard[self.lastStep]["text"] = string.replace(str(attrs.get('value')), "\\n", "\n")
90                         elif (name == "displaytext"):
91                                 self.wizard[self.lastStep]["displaytext"] = string.replace(str(attrs.get('value')), "\\n", "\n")
92                         elif (name == "list"):
93                                 if (attrs.has_key('type')):
94                                         if attrs["type"] == "dynamic":
95                                                 self.wizard[self.lastStep]["dynamiclist"] = attrs.get("source")
96                                         #self.wizard[self.lastStep]["list"].append(("Hallo", "test"))
97                                 if (attrs.has_key("evaluation")):
98                                         #print "evaluation"
99                                         self.wizard[self.lastStep]["listevaluation"] = attrs.get("evaluation")
100                                 if (attrs.has_key("onselect")):
101                                         self.wizard[self.lastStep]["onselect"] = attrs.get("onselect")                  
102                         elif (name == "listentry"):
103                                 self.wizard[self.lastStep]["list"].append((str(attrs.get('caption')), str(attrs.get('step'))))
104                         elif (name == "config"):
105                                 type = str(attrs.get('type'))
106                                 self.wizard[self.lastStep]["config"]["type"] = type
107                                 if type == "ConfigList" or type == "standalone":
108                                         try:
109                                                 exec "from Screens." + str(attrs.get('module')) + " import *"
110                                         except:
111                                                 exec "from " + str(attrs.get('module')) + " import *"
112                                 
113                                         self.wizard[self.lastStep]["config"]["screen"] = eval(str(attrs.get('screen')))
114                                         if (attrs.has_key('args')):
115                                                 #print "has args"
116                                                 self.wizard[self.lastStep]["config"]["args"] = str(attrs.get('args'))
117                                 elif type == "dynamic":
118                                         self.wizard[self.lastStep]["config"]["source"] = str(attrs.get('source'))
119                                         if (attrs.has_key('evaluation')):
120                                                 self.wizard[self.lastStep]["config"]["evaluation"] = str(attrs.get('evaluation'))
121                         elif (name == "code"):
122                                 self.async_code = attrs.has_key('async') and str(attrs.get('async')) == "yes"
123                                 if attrs.has_key('pos') and str(attrs.get('pos')) == "after":
124                                         self.codeafter = True
125                                 else:
126                                         self.codeafter = False
127                         elif (name == "condition"):
128                                 pass
129                         
130                 def endElement(self, name):
131                         self.currContent = ""
132                         if name == 'code':
133                                 if self.async_code:
134                                         if self.codeafter:
135                                                 self.wizard[self.lastStep]["codeafter_async"] = self.wizard[self.lastStep]["codeafter_async"].strip()
136                                         else:
137                                                 self.wizard[self.lastStep]["code_async"] = self.wizard[self.lastStep]["code_async"].strip()
138                                 else:
139                                         if self.codeafter:
140                                                 self.wizard[self.lastStep]["codeafter"] = self.wizard[self.lastStep]["codeafter"].strip()
141                                         else:
142                                                 self.wizard[self.lastStep]["code"] = self.wizard[self.lastStep]["code"].strip()
143                         elif name == 'condition':
144                                 self.wizard[self.lastStep]["condition"] = self.wizard[self.lastStep]["condition"].strip()
145                         elif name == 'step':
146                                 #print "Step number", self.lastStep, ":", self.wizard[self.lastStep]
147                                 pass
148                                                                 
149                 def characters(self, ch):
150                         if self.currContent == "code":
151                                 if self.async_code:
152                                         if self.codeafter:
153                                                 self.wizard[self.lastStep]["codeafter_async"] = self.wizard[self.lastStep]["codeafter_async"] + ch
154                                         else:
155                                                 self.wizard[self.lastStep]["code_async"] = self.wizard[self.lastStep]["code_async"] + ch
156                                 else:
157                                         if self.codeafter:
158                                                 self.wizard[self.lastStep]["codeafter"] = self.wizard[self.lastStep]["codeafter"] + ch
159                                         else:
160                                                 self.wizard[self.lastStep]["code"] = self.wizard[self.lastStep]["code"] + ch
161                         elif self.currContent == "condition":
162                                  self.wizard[self.lastStep]["condition"] = self.wizard[self.lastStep]["condition"] + ch
163         
164         def __init__(self, session, showSteps = True, showStepSlider = True, showList = True, showConfig = True):
165                 Screen.__init__(self, session)
166
167                 self.stepHistory = []
168
169                 self.wizard = {}
170                 parser = make_parser()
171                 if not isinstance(self.xmlfile, list):
172                         self.xmlfile = [self.xmlfile]
173                 print "Reading ", self.xmlfile
174                 wizardHandler = self.parseWizard(self.wizard)
175                 parser.setContentHandler(wizardHandler)
176                 for xmlfile in self.xmlfile:
177                         if xmlfile[0] != '/':
178                                 parser.parse('/usr/share/enigma2/' + xmlfile)
179                         else:
180                                 parser.parse(xmlfile)
181
182                 self.showSteps = showSteps
183                 self.showStepSlider = showStepSlider
184                 self.showList = showList
185                 self.showConfig = showConfig
186
187                 self.numSteps = len(self.wizard)
188                 self.currStep = self.getStepWithID("start") + 1
189                 
190                 self.timeoutTimer = eTimer()
191                 self.timeoutTimer.callback.append(self.timeoutCounterFired)
192
193                 self["text"] = Label()
194
195                 if showConfig:
196                         self["config"] = ConfigList([], session = session)
197
198                 if self.showSteps:
199                         self["step"] = Label()
200                 
201                 if self.showStepSlider:
202                         self["stepslider"] = Slider(1, self.numSteps)
203                 
204                 if self.showList:
205                         self.list = []
206                         self["list"] = List(self.list, enableWrapAround = True)
207                         self["list"].onSelectionChanged.append(self.selChanged)
208                         #self["list"] = MenuList(self.list, enableWrapAround = True)
209
210                 self.onShown.append(self.updateValues)
211
212                 self.configInstance = None
213                 
214                 self.lcdCallbacks = []
215                 
216                 self.disableKeys = False
217                 
218                 self["actions"] = NumberActionMap(["WizardActions", "NumberActions", "ColorActions", "SetupActions"],
219                 {
220                         "ok": self.ok,
221                         "back": self.back,
222                         "left": self.left,
223                         "right": self.right,
224                         "up": self.up,
225                         "down": self.down,
226                         "red": self.red,
227                         "green": self.green,
228                         "yellow": self.yellow,
229                         "blue":self.blue,
230                         "deleteBackward": self.deleteBackward,
231                         "deleteForward": self.deleteForward,
232                         "1": self.keyNumberGlobal,
233                         "2": self.keyNumberGlobal,
234                         "3": self.keyNumberGlobal,
235                         "4": self.keyNumberGlobal,
236                         "5": self.keyNumberGlobal,
237                         "6": self.keyNumberGlobal,
238                         "7": self.keyNumberGlobal,
239                         "8": self.keyNumberGlobal,
240                         "9": self.keyNumberGlobal,
241                         "0": self.keyNumberGlobal
242                 }, -1)
243                 
244         def red(self):
245                 print "red"
246                 pass
247
248         def green(self):
249                 print "green"
250                 pass
251         
252         def yellow(self):
253                 print "yellow"
254                 pass
255         
256         def blue(self):
257                 print "blue"
258                 pass
259         
260         def deleteForward(self):
261                 self.resetCounter()
262                 if (self.wizard[self.currStep]["config"]["screen"] != None):
263                         self.configInstance.keyDelete()
264                 elif (self.wizard[self.currStep]["config"]["type"] == "dynamic"):
265                         self["config"].handleKey(KEY_DELETE)
266                 print "deleteForward"
267
268         def deleteBackward(self):
269                 self.resetCounter()
270                 if (self.wizard[self.currStep]["config"]["screen"] != None):
271                         self.configInstance.keyBackspace()
272                 elif (self.wizard[self.currStep]["config"]["type"] == "dynamic"):
273                         self["config"].handleKey(KEY_BACKSPACE)
274                 print "deleteBackward"
275         
276         def setLCDTextCallback(self, callback):
277                 self.lcdCallbacks.append(callback)
278
279         def back(self):
280                 if self.disableKeys:
281                         return
282                 print "getting back..."
283                 print "stepHistory:", self.stepHistory
284                 if len(self.stepHistory) > 1:
285                         self.currStep = self.stepHistory[-2]
286                         self.stepHistory = self.stepHistory[:-2]
287                 if self.currStep < 1:
288                         self.currStep = 1
289                 print "currStep:", self.currStep
290                 print "new stepHistory:", self.stepHistory
291                 self.updateValues()
292                 print "after updateValues stepHistory:", self.stepHistory
293                 
294         def markDone(self):
295                 pass
296         
297         def getStepWithID(self, id):
298                 print "getStepWithID:", id
299                 count = 0
300                 for x in self.wizard.keys():
301                         if self.wizard[x]["id"] == id:
302                                 print "result:", count
303                                 return count
304                         count += 1
305                 print "result: nothing"
306                 return 0
307
308         def finished(self, gotoStep = None, *args, **kwargs):
309                 print "finished"
310                 self.prevStep = self.currStep
311                 self.gotoStep = gotoStep
312
313                 if self.updateValues not in self.onShown:
314                         self.onShown.append(self.updateValues)
315
316                 if self.showConfig:
317                         if self.wizard[self.prevStep]["config"]["type"] == "dynamic":
318                                 eval("self." + self.wizard[self.prevStep]["config"]["evaluation"])()
319
320                 if self.showList:
321                         if (len(self.wizard[self.prevStep]["evaluatedlist"]) > 0):
322                                 print "current:", self["list"].current
323                                 nextStep = self["list"].current[1]
324                                 if (self.wizard[self.prevStep].has_key("listevaluation")):
325                                         exec("self." + self.wizard[self.currStep]["listevaluation"] + "('" + nextStep + "')")
326                                 else:
327                                         self.currStep = self.getStepWithID(nextStep)
328
329                 if ((self.prevStep == self.numSteps and self.wizard[self.prevStep]["nextstep"] is None) or self.wizard[self.prevStep]["id"] == "end"): # wizard finished
330                         print "wizard finished"
331                         self.markDone()
332                         self.close()
333                 else:
334                         self.codeafterA=True
335                         self.runCode(self.wizard[self.prevStep]["codeafter"])
336                         if self.runCode(self.wizard[self.prevStep]["codeafter_async"]):
337                                 if self.updateValues in self.onShown:
338                                         self.onShown.remove(self.updateValues)
339                         else:
340                                 self.afterAsyncCode()
341
342         def ok(self):
343                 print "OK"
344                 if self.disableKeys:
345                         return
346                 currStep = self.currStep
347                 
348                 if self.showConfig:
349                         if (self.wizard[currStep]["config"]["screen"] != None):
350                                 # TODO: don't die, if no run() is available
351                                 # there was a try/except here, but i can't see a reason
352                                 # for this. If there is one, please do a more specific check
353                                 # and/or a comment in which situation there is no run()
354                                 if callable(getattr(self.configInstance, "runAsync", None)):
355                                         if self.updateValues in self.onShown:
356                                                 self.onShown.remove(self.updateValues)
357                                         self.configInstance.runAsync(self.finished)
358                                         return
359                                 else:
360                                         self.configInstance.run()
361                 self.finished()
362
363         def keyNumberGlobal(self, number):
364                 if (self.wizard[self.currStep]["config"]["screen"] != None):
365                         self.configInstance.keyNumberGlobal(number)
366                 
367         def left(self):
368                 self.resetCounter()
369                 if (self.wizard[self.currStep]["config"]["screen"] != None):
370                         self.configInstance.keyLeft()
371                 elif (self.wizard[self.currStep]["config"]["type"] == "dynamic"):
372                         self["config"].handleKey(KEY_LEFT)
373                 print "left"
374         
375         def right(self):
376                 self.resetCounter()
377                 if (self.wizard[self.currStep]["config"]["screen"] != None):
378                         self.configInstance.keyRight()
379                 elif (self.wizard[self.currStep]["config"]["type"] == "dynamic"):
380                         self["config"].handleKey(KEY_RIGHT)     
381                 print "right"
382
383         def up(self):
384                 self.resetCounter()
385                 if (self.showConfig and self.wizard[self.currStep]["config"]["screen"] != None  or self.wizard[self.currStep]["config"]["type"] == "dynamic"):
386                         self["config"].instance.moveSelection(self["config"].instance.moveUp)
387                 elif (self.showList and len(self.wizard[self.currStep]["evaluatedlist"]) > 0):
388                         self["list"].selectPrevious()
389                         if self.wizard[self.currStep].has_key("onselect"):
390                                 print "current:", self["list"].current
391                                 self.selection = self["list"].current[-1]
392                                 #self.selection = self.wizard[self.currStep]["evaluatedlist"][self["list"].l.getCurrentSelectionIndex()][1]
393                                 exec("self." + self.wizard[self.currStep]["onselect"] + "()")
394                 print "up"
395                 
396         def down(self):
397                 self.resetCounter()
398                 if (self.showConfig and self.wizard[self.currStep]["config"]["screen"] != None  or self.wizard[self.currStep]["config"]["type"] == "dynamic"):
399                         self["config"].instance.moveSelection(self["config"].instance.moveDown)
400                 elif (self.showList and len(self.wizard[self.currStep]["evaluatedlist"]) > 0):
401                         #self["list"].instance.moveSelection(self["list"].instance.moveDown)
402                         self["list"].selectNext()
403                         if self.wizard[self.currStep].has_key("onselect"):
404                                 print "current:", self["list"].current
405                                 #self.selection = self.wizard[self.currStep]["evaluatedlist"][self["list"].l.getCurrentSelectionIndex()][1]
406                                 #exec("self." + self.wizard[self.currStep]["onselect"] + "()")
407                                 self.selection = self["list"].current[-1]
408                                 #self.selection = self.wizard[self.currStep]["evaluatedlist"][self["list"].l.getCurrentSelectionIndex()][1]
409                                 exec("self." + self.wizard[self.currStep]["onselect"] + "()")
410                 print "down"
411                 
412         def selChanged(self):
413                 self.resetCounter()
414                 
415                 if (self.showConfig and self.wizard[self.currStep]["config"]["screen"] != None):
416                         self["config"].instance.moveSelection(self["config"].instance.moveUp)
417                 elif (self.showList and len(self.wizard[self.currStep]["evaluatedlist"]) > 0):
418                         if self.wizard[self.currStep].has_key("onselect"):
419                                 self.selection = self["list"].current[-1]
420                                 print "self.selection:", self.selection
421                                 exec("self." + self.wizard[self.currStep]["onselect"] + "()")
422                 
423         def resetCounter(self):
424                 self.timeoutCounter = self.wizard[self.currStep]["timeout"]
425                 
426         def runCode(self, code):
427                 if code != "":
428                         print "code", code
429                         exec(code)
430                         return True
431                 return False
432
433         def getTranslation(self, text):
434                 return _(text)
435                         
436         def updateText(self, firstset = False):
437                 text = self.getTranslation(self.wizard[self.currStep]["text"])
438                 if text.find("[timeout]") != -1:
439                         text = text.replace("[timeout]", str(self.timeoutCounter))
440                         self["text"].setText(text)
441                 else:
442                         if firstset:
443                                 self["text"].setText(text)
444                 
445         def updateValues(self):
446                 print "Updating values in step " + str(self.currStep)
447                 # calling a step which doesn't exist can only happen if the condition in the last step is not fulfilled
448                 # if a non-existing step is called, end the wizard 
449                 if self.currStep > len(self.wizard):
450                         self.markDone()
451                         self.close()
452                         return
453
454                 self.timeoutTimer.stop()
455                 
456                 if self.configInstance is not None:
457                         # remove callbacks
458                         self.configInstance["config"].onSelectionChanged = []
459                         del self.configInstance["config"]
460                         self.configInstance.doClose()
461                         self.configInstance = None
462
463                 exec (self.wizard[self.currStep]["condition"])
464
465                 if len(self.stepHistory) == 0 or self.stepHistory[-1] != self.currStep:
466                         self.stepHistory.append(self.currStep)
467                 print "wizard step:", self.wizard[self.currStep]
468                         
469                 if self.showSteps:
470                         self["step"].setText(self.getTranslation("Step ") + str(self.currStep) + "/" + str(self.numSteps))
471                 if self.showStepSlider:
472                         self["stepslider"].setValue(self.currStep)
473                 
474                 if self.wizard[self.currStep]["timeout"] is not None:
475                         self.resetCounter() 
476                         self.timeoutTimer.start(1000)
477                         
478                 print "wizard text", self.getTranslation(self.wizard[self.currStep]["text"])
479                 self.updateText(firstset = True)
480                 if self.wizard[self.currStep].has_key("displaytext"):
481                         displaytext = self.wizard[self.currStep]["displaytext"]
482                         print "set LCD text"
483                         for x in self.lcdCallbacks:
484                                 x(displaytext)
485                                 
486                 self.codeafterA=False
487                 self.runCode(self.wizard[self.currStep]["code"])
488                 if self.runCode(self.wizard[self.currStep]["code_async"]):
489                         if self.updateValues in self.onShown:
490                                 self.onShown.remove(self.updateValues)
491                 else:
492                         self.afterAsyncCode()
493
494         def afterAsyncCode(self):
495                 if self.codeafterA:
496                         if self.wizard[self.prevStep]["nextstep"] is not None:
497                                 self.currStep = self.getStepWithID(self.wizard[self.currStep]["nextstep"])
498                         if self.gotoStep is not None:
499                                 self.currStep = self.getStepWithID(self.gotoStep)
500                         self.currStep += 1
501                         self.updateValues()
502                         print "Now: " + str(self.currStep)
503                 else:
504                         if self.showList:
505                                 print "showing list,", self.currStep
506                                 for renderer in self.renderer:
507                                         rootrenderer = renderer
508                                         while renderer.source is not None:
509                                                 print "self.list:", self["list"]
510                                                 if renderer.source is self["list"]:
511                                                         print "setZPosition"
512                                                         rootrenderer.instance.setZPosition(1)
513                                                 renderer = renderer.source
514
515                                 #self["list"].instance.setZPosition(1)
516                                 self.list = []
517                                 if (self.wizard[self.currStep].has_key("dynamiclist")):
518                                         print "dynamic list, calling",  self.wizard[self.currStep]["dynamiclist"]
519                                         newlist = eval("self." + self.wizard[self.currStep]["dynamiclist"] + "()")
520                                         #self.wizard[self.currStep]["evaluatedlist"] = []
521                                         for entry in newlist:
522                                                 #self.wizard[self.currStep]["evaluatedlist"].append(entry)
523                                                 self.list.append(entry)
524                                         #del self.wizard[self.currStep]["dynamiclist"]
525                                 if (len(self.wizard[self.currStep]["list"]) > 0):
526                                         #self["list"].instance.setZPosition(2)
527                                         for x in self.wizard[self.currStep]["list"]:
528                                                 self.list.append((self.getTranslation(x[0]), x[1]))
529                                 self.wizard[self.currStep]["evaluatedlist"] = self.list
530                                 self["list"].list = self.list
531                                 self["list"].index = 0
532                         else:
533                                 self["list"].hide()
534         
535                         if self.showConfig:
536                                 print "showing config"
537                                 self["config"].instance.setZPosition(1)
538                                 if self.wizard[self.currStep]["config"]["type"] == "dynamic":
539                                                 print "config type is dynamic"
540                                                 self["config"].instance.setZPosition(2)
541                                                 self["config"].l.setList(eval("self." + self.wizard[self.currStep]["config"]["source"])())
542                                 elif (self.wizard[self.currStep]["config"]["screen"] != None):
543                                         if self.wizard[self.currStep]["config"]["type"] == "standalone":
544                                                 print "Type is standalone"
545                                                 self.session.openWithCallback(self.ok, self.wizard[self.currStep]["config"]["screen"])
546                                         else:
547                                                 self["config"].instance.setZPosition(2)
548                                                 print "wizard screen", self.wizard[self.currStep]["config"]["screen"]
549                                                 if self.wizard[self.currStep]["config"]["args"] == None:
550                                                         self.configInstance = self.session.instantiateDialog(self.wizard[self.currStep]["config"]["screen"])
551                                                 else:
552                                                         self.configInstance = self.session.instantiateDialog(self.wizard[self.currStep]["config"]["screen"], eval(self.wizard[self.currStep]["config"]["args"]))
553                                                 self["config"].l.setList(self.configInstance["config"].list)
554                                                 callbacks = self.configInstance["config"].onSelectionChanged
555                                                 self.configInstance["config"].destroy()
556                                                 print "clearConfigList", self.configInstance["config"], self["config"]
557                                                 self.configInstance["config"] = self["config"]
558                                                 self.configInstance["config"].onSelectionChanged = callbacks
559                                                 print "clearConfigList", self.configInstance["config"], self["config"]
560                                 else:
561                                         self["config"].l.setList([])
562                         else:
563                                 if self.has_key("config"):
564                                         self["config"].hide()
565
566         def timeoutCounterFired(self):
567                 self.timeoutCounter -= 1
568                 print "timeoutCounter:", self.timeoutCounter
569                 if self.timeoutCounter == 0:
570                         if self.wizard[self.currStep]["timeoutaction"] == "selectnext":
571                                 print "selection next item"
572                                 self.down()
573                         else:
574                                 if self.wizard[self.currStep]["timeoutaction"] == "changestep":
575                                         self.finished(gotoStep = self.wizard[self.currStep]["timeoutstep"])
576                 self.updateText()
577
578 class WizardManager:
579         def __init__(self):
580                 self.wizards = []
581         
582         def registerWizard(self, wizard, precondition, priority = 0):
583                 self.wizards.append((wizard, precondition, priority))
584         
585         def getWizards(self):
586                 list = []
587                 for x in self.wizards:
588                         if x[1] == 1: # precondition
589                                 list.append((x[2], x[0]))
590                 return list
591
592 wizardManager = WizardManager()