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