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