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