Wizard.py: async fixes
[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                 currStep = self.currStep
311
312                 if self.updateValues not in self.onShown:
313                         self.onShown.append(self.updateValues)
314                         
315                 if self.showConfig:
316                         if self.wizard[currStep]["config"]["type"] == "dynamic":
317                                 eval("self." + self.wizard[currStep]["config"]["evaluation"])()
318
319                 if self.showList:
320                         if (len(self.wizard[currStep]["evaluatedlist"]) > 0):
321                                 print "current:", self["list"].current
322                                 nextStep = self["list"].current[1]
323                                 if (self.wizard[currStep].has_key("listevaluation")):
324                                         exec("self." + self.wizard[self.currStep]["listevaluation"] + "('" + nextStep + "')")
325                                 else:
326                                         self.currStep = self.getStepWithID(nextStep)
327
328                 print_now = True
329                 if ((currStep == self.numSteps and self.wizard[currStep]["nextstep"] is None) or self.wizard[currStep]["id"] == "end"): # wizard finished
330                         print "wizard finished"
331                         self.markDone()
332                         self.close()
333                 else:
334                         self.codeafter = True
335                         self.runCode(self.wizard[currStep]["codeafter"])
336                         self.prevStep = currStep
337                         self.gotoStep = gotoStep
338                         if not self.runCode(self.wizard[currStep]["codeafter_async"]):
339                                 self.afterAsyncCode()
340                         else:
341                                 if self.updateValues in self.onShown:
342                                         self.onShown.remove(self.updateValues)
343
344                 if print_now:
345                         print "Now: " + str(self.currStep)
346
347         def ok(self):
348                 print "OK"
349                 if self.disableKeys:
350                         return
351                 currStep = self.currStep
352                 
353                 if self.showConfig:
354                         if (self.wizard[currStep]["config"]["screen"] != None):
355                                 # TODO: don't die, if no run() is available
356                                 # there was a try/except here, but i can't see a reason
357                                 # for this. If there is one, please do a more specific check
358                                 # and/or a comment in which situation there is no run()
359                                 if callable(getattr(self.configInstance, "runAsync", None)):
360                                         if self.updateValues in self.onShown:
361                                                 self.onShown.remove(self.updateValues)
362                                         self.configInstance.runAsync(self.finished)
363                                         return
364                                 else:
365                                         self.configInstance.run()
366                 self.finished()
367
368         def keyNumberGlobal(self, number):
369                 if (self.wizard[self.currStep]["config"]["screen"] != None):
370                         self.configInstance.keyNumberGlobal(number)
371                 
372         def left(self):
373                 self.resetCounter()
374                 if (self.wizard[self.currStep]["config"]["screen"] != None):
375                         self.configInstance.keyLeft()
376                 elif (self.wizard[self.currStep]["config"]["type"] == "dynamic"):
377                         self["config"].handleKey(KEY_LEFT)
378                 print "left"
379         
380         def right(self):
381                 self.resetCounter()
382                 if (self.wizard[self.currStep]["config"]["screen"] != None):
383                         self.configInstance.keyRight()
384                 elif (self.wizard[self.currStep]["config"]["type"] == "dynamic"):
385                         self["config"].handleKey(KEY_RIGHT)     
386                 print "right"
387
388         def up(self):
389                 self.resetCounter()
390                 if (self.showConfig and self.wizard[self.currStep]["config"]["screen"] != None  or self.wizard[self.currStep]["config"]["type"] == "dynamic"):
391                         self["config"].instance.moveSelection(self["config"].instance.moveUp)
392                 elif (self.showList and len(self.wizard[self.currStep]["evaluatedlist"]) > 0):
393                         self["list"].selectPrevious()
394                         if self.wizard[self.currStep].has_key("onselect"):
395                                 print "current:", self["list"].current
396                                 self.selection = self["list"].current[-1]
397                                 #self.selection = self.wizard[self.currStep]["evaluatedlist"][self["list"].l.getCurrentSelectionIndex()][1]
398                                 exec("self." + self.wizard[self.currStep]["onselect"] + "()")
399                 print "up"
400                 
401         def down(self):
402                 self.resetCounter()
403                 if (self.showConfig and self.wizard[self.currStep]["config"]["screen"] != None  or self.wizard[self.currStep]["config"]["type"] == "dynamic"):
404                         self["config"].instance.moveSelection(self["config"].instance.moveDown)
405                 elif (self.showList and len(self.wizard[self.currStep]["evaluatedlist"]) > 0):
406                         #self["list"].instance.moveSelection(self["list"].instance.moveDown)
407                         self["list"].selectNext()
408                         if self.wizard[self.currStep].has_key("onselect"):
409                                 print "current:", self["list"].current
410                                 #self.selection = self.wizard[self.currStep]["evaluatedlist"][self["list"].l.getCurrentSelectionIndex()][1]
411                                 #exec("self." + self.wizard[self.currStep]["onselect"] + "()")
412                                 self.selection = self["list"].current[-1]
413                                 #self.selection = self.wizard[self.currStep]["evaluatedlist"][self["list"].l.getCurrentSelectionIndex()][1]
414                                 exec("self." + self.wizard[self.currStep]["onselect"] + "()")
415                 print "down"
416                 
417         def selChanged(self):
418                 self.resetCounter()
419                 
420                 if (self.showConfig and self.wizard[self.currStep]["config"]["screen"] != None):
421                         self["config"].instance.moveSelection(self["config"].instance.moveUp)
422                 elif (self.showList and len(self.wizard[self.currStep]["evaluatedlist"]) > 0):
423                         if self.wizard[self.currStep].has_key("onselect"):
424                                 self.selection = self["list"].current[-1]
425                                 print "self.selection:", self.selection
426                                 exec("self." + self.wizard[self.currStep]["onselect"] + "()")
427                 
428         def resetCounter(self):
429                 self.timeoutCounter = self.wizard[self.currStep]["timeout"]
430                 
431         def runCode(self, code):
432                 if code != "":
433                         print "code", code
434                         exec(code)
435                         return True
436                 return False
437
438         def getTranslation(self, text):
439                 return _(text)
440                         
441         def updateText(self, firstset = False):
442                 text = self.getTranslation(self.wizard[self.currStep]["text"])
443                 if text.find("[timeout]") != -1:
444                         text = text.replace("[timeout]", str(self.timeoutCounter))
445                         self["text"].setText(text)
446                 else:
447                         if firstset:
448                                 self["text"].setText(text)
449                 
450         def updateValues(self):
451                 print "Updating values in step " + str(self.currStep)
452                 # calling a step which doesn't exist can only happen if the condition in the last step is not fulfilled
453                 # if a non-existing step is called, end the wizard 
454                 if self.currStep > len(self.wizard):
455                         self.markDone()
456                         self.close()
457                         return
458
459                 self.timeoutTimer.stop()
460                 
461                 if self.configInstance is not None:
462                         # remove callbacks
463                         self.configInstance["config"].onSelectionChanged = []
464                         del self.configInstance["config"]
465                         self.configInstance.doClose()
466                         self.configInstance = None
467
468                 self.condition = True
469                 exec (self.wizard[self.currStep]["condition"])
470                 if not self.condition:
471                         self.currStep += 1
472                         self.updateValues()
473                 else:
474                         if len(self.stepHistory) == 0 or self.stepHistory[-1] != self.currStep:
475                                 self.stepHistory.append(self.currStep)
476                         print "wizard step:", self.wizard[self.currStep]
477                         
478                         if self.showSteps:
479                                 self["step"].setText(self.getTranslation("Step ") + str(self.currStep) + "/" + str(self.numSteps))
480                         if self.showStepSlider:
481                                 self["stepslider"].setValue(self.currStep)
482                 
483                         if self.wizard[self.currStep]["timeout"] is not None:
484                                 self.resetCounter() 
485                                 self.timeoutTimer.start(1000)
486                         
487                         print "wizard text", self.getTranslation(self.wizard[self.currStep]["text"])
488                         self.updateText(firstset = True)
489                         if self.wizard[self.currStep].has_key("displaytext"):
490                                 displaytext = self.wizard[self.currStep]["displaytext"]
491                                 print "set LCD text"
492                                 for x in self.lcdCallbacks:
493                                         x(displaytext)
494                                 
495                         self.codeafter=False
496                         self.runCode(self.wizard[self.currStep]["code"])
497                         if self.runCode(self.wizard[self.currStep]["code_async"]):
498                                 if self.updateValues in self.onShown:
499                                         self.onShown.remove(self.updateValues)
500                         else:
501                                 self.afterAsyncCode()
502
503         def afterAsyncCode(self):
504                 if not self.updateValues in self.onShown:
505                         self.onShown.append(self.updateValues)
506
507                 if self.codeafter:
508                         if self.wizard[self.prevStep]["nextstep"] is not None:
509                                 self.currStep = self.getStepWithID(self.wizard[self.prevStep]["nextstep"])
510                         if self.gotoStep is not None:
511                                 self.currStep = self.getStepWithID(self.gotoStep)
512                         self.currStep += 1
513                         self.updateValues()
514                         print "Now: " + str(self.currStep)
515                 else:
516                         if self.showList:
517                                 print "showing list,", self.currStep
518                                 for renderer in self.renderer:
519                                         rootrenderer = renderer
520                                         while renderer.source is not None:
521                                                 print "self.list:", self["list"]
522                                                 if renderer.source is self["list"]:
523                                                         print "setZPosition"
524                                                         rootrenderer.instance.setZPosition(1)
525                                                 renderer = renderer.source
526
527                                 #self["list"].instance.setZPosition(1)
528                                 self.list = []
529                                 if (self.wizard[self.currStep].has_key("dynamiclist")):
530                                         print "dynamic list, calling",  self.wizard[self.currStep]["dynamiclist"]
531                                         newlist = eval("self." + self.wizard[self.currStep]["dynamiclist"] + "()")
532                                         #self.wizard[self.currStep]["evaluatedlist"] = []
533                                         for entry in newlist:
534                                                 #self.wizard[self.currStep]["evaluatedlist"].append(entry)
535                                                 self.list.append(entry)
536                                         #del self.wizard[self.currStep]["dynamiclist"]
537                                 if (len(self.wizard[self.currStep]["list"]) > 0):
538                                         #self["list"].instance.setZPosition(2)
539                                         for x in self.wizard[self.currStep]["list"]:
540                                                 self.list.append((self.getTranslation(x[0]), x[1]))
541                                 self.wizard[self.currStep]["evaluatedlist"] = self.list
542                                 self["list"].list = self.list
543                                 self["list"].index = 0
544                         else:
545                                 self["list"].hide()
546         
547                         if self.showConfig:
548                                 print "showing config"
549                                 self["config"].instance.setZPosition(1)
550                                 if self.wizard[self.currStep]["config"]["type"] == "dynamic":
551                                                 print "config type is dynamic"
552                                                 self["config"].instance.setZPosition(2)
553                                                 self["config"].l.setList(eval("self." + self.wizard[self.currStep]["config"]["source"])())
554                                 elif (self.wizard[self.currStep]["config"]["screen"] != None):
555                                         if self.wizard[self.currStep]["config"]["type"] == "standalone":
556                                                 print "Type is standalone"
557                                                 self.session.openWithCallback(self.ok, self.wizard[self.currStep]["config"]["screen"])
558                                         else:
559                                                 self["config"].instance.setZPosition(2)
560                                                 print "wizard screen", self.wizard[self.currStep]["config"]["screen"]
561                                                 if self.wizard[self.currStep]["config"]["args"] == None:
562                                                         self.configInstance = self.session.instantiateDialog(self.wizard[self.currStep]["config"]["screen"])
563                                                 else:
564                                                         self.configInstance = self.session.instantiateDialog(self.wizard[self.currStep]["config"]["screen"], eval(self.wizard[self.currStep]["config"]["args"]))
565                                                 self["config"].l.setList(self.configInstance["config"].list)
566                                                 callbacks = self.configInstance["config"].onSelectionChanged
567                                                 self.configInstance["config"].destroy()
568                                                 print "clearConfigList", self.configInstance["config"], self["config"]
569                                                 self.configInstance["config"] = self["config"]
570                                                 self.configInstance["config"].onSelectionChanged = callbacks
571                                                 print "clearConfigList", self.configInstance["config"], self["config"]
572                                 else:
573                                         self["config"].l.setList([])
574                         else:
575                                 if self.has_key("config"):
576                                         self["config"].hide()
577
578         def timeoutCounterFired(self):
579                 self.timeoutCounter -= 1
580                 print "timeoutCounter:", self.timeoutCounter
581                 if self.timeoutCounter == 0:
582                         if self.wizard[self.currStep]["timeoutaction"] == "selectnext":
583                                 print "selection next item"
584                                 self.down()
585                         else:
586                                 if self.wizard[self.currStep]["timeoutaction"] == "changestep":
587                                         self.finished(gotoStep = self.wizard[self.currStep]["timeoutstep"])
588                 self.updateText()
589
590 class WizardManager:
591         def __init__(self):
592                 self.wizards = []
593         
594         def registerWizard(self, wizard, precondition, priority = 0):
595                 self.wizards.append((wizard, precondition, priority))
596         
597         def getWizards(self):
598                 list = []
599                 for x in self.wizards:
600                         if x[1] == 1: # precondition
601                                 list.append((x[2], x[0]))
602                 return list
603
604 wizardManager = WizardManager()