wizard: cleanup circular reference on close
[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.Label import Label
7 from Components.Slider import Slider
8 from Components.ActionMap import HelpableActionMap, NumberActionMap
9 from Components.config import config, configElementBoolean
10 from Components.Pixmap import *
11 from Components.MenuList import MenuList
12 from Components.ConfigList import ConfigList
13
14 from xml.sax import make_parser
15 from xml.sax.handler import ContentHandler
16
17 config.misc.firstrun = configElementBoolean("config.misc.firstrun", 1);
18
19 class Wizard(Screen, HelpableScreen):
20
21         class parseWizard(ContentHandler):
22                 def __init__(self, wizard):
23                         self.isPointsElement, self.isReboundsElement = 0, 0
24                         self.wizard = wizard
25                         self.currContent = ""
26                 
27                 def startElement(self, name, attrs):
28                         print name
29                         self.currContent = name
30                         if (name == "step"):
31                                 self.lastStep = int(attrs.get('number'))
32                                 self.wizard[self.lastStep] = {"text": "", "list": [], "config": {"screen": None, "args": None, "type": "" }, "code": ""}
33                         elif (name == "text"):
34                                 self.wizard[self.lastStep]["text"] = string.replace(str(attrs.get('value')), "\\n", "\n")
35                         elif (name == "listentry"):
36                                 self.wizard[self.lastStep]["list"].append((str(attrs.get('caption')), str(attrs.get('step'))))
37                         elif (name == "config"):
38                                 exec "from Screens." + str(attrs.get('module')) + " import *"
39                                 self.wizard[self.lastStep]["config"]["screen"] = eval(str(attrs.get('screen')))
40                                 if (attrs.has_key('args')):
41                                         print "has args"
42                                         self.wizard[self.lastStep]["config"]["args"] = str(attrs.get('args'))
43                                 self.wizard[self.lastStep]["config"]["type"] = str(attrs.get('type'))
44                 def endElement(self, name):
45                         self.currContent = ""
46                         if name == 'code':
47                                 self.wizard[self.lastStep]["code"] = self.wizard[self.lastStep]["code"].strip()
48                                 
49                 def characters(self, ch):
50                         if self.currContent == "code":
51                                  self.wizard[self.lastStep]["code"] = self.wizard[self.lastStep]["code"] + ch
52                                 
53         def __init__(self, session):
54                 Screen.__init__(self, session)
55                 HelpableScreen.__init__(self)
56
57                 self.wizard = {}
58                 parser = make_parser()
59                 print "Reading " + self.xmlfile
60                 wizardHandler = self.parseWizard(self.wizard)
61                 parser.setContentHandler(wizardHandler)
62                 parser.parse('/usr/share/enigma2/' + self.xmlfile)
63                 
64                 self.numSteps = len(self.wizard)
65                 self.currStep = 1
66
67                 self["text"] = Label()
68
69                 self["config"] = ConfigList([])
70
71                 self["step"] = Label()
72                                 
73                 self["stepslider"] = Slider(1, self.numSteps)
74                 
75                 self.list = []
76                 self["list"] = MenuList(self.list)
77
78                 self.onShown.append(self.updateValues)
79                 self.onClose.append(self.delReferences)
80                 
81                 self["actions"] = NumberActionMap(["WizardActions", "NumberActions"],
82                 {
83                         "ok": self.ok,
84                         "back": self.back,
85                         "left": self.left,
86                         "right": self.right,
87                         "up": self.up,
88                         "down": self.down,
89                         "1": self.keyNumberGlobal,
90                         "2": self.keyNumberGlobal,
91                         "3": self.keyNumberGlobal,
92                         "4": self.keyNumberGlobal,
93                         "5": self.keyNumberGlobal,
94                         "6": self.keyNumberGlobal,
95                         "7": self.keyNumberGlobal,
96                         "8": self.keyNumberGlobal,
97                         "9": self.keyNumberGlobal,
98                         "0": self.keyNumberGlobal
99                 }, -1)
100                 
101                 #self["actions"] = HelpableActionMap(self, "OkCancelActions",
102                         #{
103                                 #"ok": (self.ok, _("Close this Screen...")),
104                         #})
105
106         def back(self):
107                 self.currStep -= 1
108                 if self.currStep < 1:
109                         self.currStep = 1
110                 self.updateValues()
111                 
112         def ok(self):
113                 print "OK"
114                 if (self.wizard[self.currStep]["config"]["screen"] != None):
115                         try: # don't die, if no run() is available
116                                 self.configInstance.run()
117                         except:
118                                 print "Failed to run configInstance"
119                 
120                 if (len(self.wizard[self.currStep]["list"]) > 0):
121                         nextStep = self.wizard[self.currStep]["list"][self["list"].l.getCurrentSelectionIndex()][1]
122                         if nextStep == "end":
123                                 self.currStep = self.numSteps
124                         elif nextStep == "next":
125                                 pass
126                         else:
127                                 self.currStep = int(nextStep) - 1
128
129                 if (self.currStep == self.numSteps): # wizard finished
130                         config.misc.firstrun.value = 0;
131                         config.misc.firstrun.save()
132                         self.session.close()
133                 else:
134                         self.currStep += 1
135                         self.updateValues()
136                         
137                 print "Now: " + str(self.currStep)
138
139         def keyNumberGlobal(self, number):
140                 if (self.wizard[self.currStep]["config"]["screen"] != None):
141                         self.configInstance.keyNumberGlobal(number)
142                 
143         def left(self):
144                 if (self.wizard[self.currStep]["config"]["screen"] != None):
145                         self.configInstance.keyLeft()
146                 print "left"
147         
148         def right(self):
149                 if (self.wizard[self.currStep]["config"]["screen"] != None):
150                         self.configInstance.keyRight()
151                 print "right"
152
153         def up(self):
154                 if (self.wizard[self.currStep]["config"]["screen"] != None):
155                         self["config"].instance.moveSelection(self["config"].instance.moveUp)
156                 elif (len(self.wizard[self.currStep]["list"]) > 0):
157                         self["list"].instance.moveSelection(self["list"].instance.moveUp)
158                 print "up"
159                 
160         def down(self):
161                 if (self.wizard[self.currStep]["config"]["screen"] != None):
162                         self["config"].instance.moveSelection(self["config"].instance.moveDown)
163                 elif (len(self.wizard[self.currStep]["list"]) > 0):
164                         self["list"].instance.moveSelection(self["list"].instance.moveDown)
165                 print "down"
166                 
167         def updateValues(self):
168                 print "Updating values in step " + str(self.currStep)
169                 self["step"].setText(_("Step ") + str(self.currStep) + "/" + str(self.numSteps))
170                 self["stepslider"].setValue(self.currStep)
171
172                 print _(self.wizard[self.currStep]["text"])
173                 self["text"].setText(_(self.wizard[self.currStep]["text"]))
174
175                 if self.wizard[self.currStep]["code"] != "":
176                         print self.wizard[self.currStep]["code"]
177                         exec(self.wizard[self.currStep]["code"])
178                 
179                 self["list"].instance.setZPosition(1)
180                 self.list = []
181                 if (len(self.wizard[self.currStep]["list"]) > 0):
182                         self["list"].instance.setZPosition(2)
183                         for x in self.wizard[self.currStep]["list"]:
184                                 self.list.append((_(x[0]), None))
185                 self["list"].l.setList(self.list)
186
187                 self["config"].instance.setZPosition(1)
188                 if (self.wizard[self.currStep]["config"]["screen"] != None):
189                         if self.wizard[self.currStep]["config"]["type"] == "standalone":
190                                 print "Type is standalone"
191                                 self.session.openWithCallback(self.ok, self.wizard[self.currStep]["config"]["screen"])
192                         else:
193                                 self["config"].instance.setZPosition(2)
194                                 print self.wizard[self.currStep]["config"]["screen"]
195                                 if self.wizard[self.currStep]["config"]["args"] == None:
196                                         self.configInstance = self.session.instantiateDialog(self.wizard[self.currStep]["config"]["screen"])
197                                 else:
198                                         self.configInstance = self.session.instantiateDialog(self.wizard[self.currStep]["config"]["screen"], eval(self.wizard[self.currStep]["config"]["args"]))
199                                 self["config"].l.setList(self.configInstance["config"].list)
200                                 self.configInstance["config"] = self["config"]
201                 else:
202                         self["config"].l.setList([])
203
204         def delReferences(self):
205                 del self.configInstance
206
207 class WizardManager:
208         def __init__(self):
209                 self.wizards = []
210         
211         def registerWizard(self, wizard):
212                 self.wizards.append(wizard)
213         
214         def getWizards(self):
215                 if config.misc.firstrun.value:
216                         return self.wizards
217                 else:
218                         return []
219
220 wizardManager = WizardManager()