chiark / gitweb /
Merge branch 'master' of github.com:daid/Cura
[cura.git] / Cura / gui / configWizard.py
1 from __future__ import absolute_import\r
2 import __init__\r
3 \r
4 import wx, os, platform, types, webbrowser, threading, time, re\r
5 import wx.wizard\r
6 \r
7 from gui import firmwareInstall\r
8 from util import machineCom\r
9 from util import profile\r
10 \r
11 class InfoPage(wx.wizard.WizardPageSimple):\r
12         def __init__(self, parent, title):\r
13                 wx.wizard.WizardPageSimple.__init__(self, parent)\r
14 \r
15                 sizer = wx.BoxSizer(wx.VERTICAL)\r
16                 self.sizer = sizer\r
17                 self.SetSizer(sizer)\r
18 \r
19                 title = wx.StaticText(self, -1, title)\r
20                 title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD))\r
21                 sizer.Add(title, 0, wx.ALIGN_CENTRE|wx.ALL, 5)\r
22                 sizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, 5)\r
23         \r
24         def AddText(self,info):\r
25                 text = wx.StaticText(self, -1, info)\r
26                 self.GetSizer().Add(text, 0, wx.LEFT|wx.RIGHT, 5)\r
27                 return text\r
28         \r
29         def AddSeperator(self):\r
30                 self.GetSizer().Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, 5)\r
31         \r
32         def AddHiddenSeperator(self):\r
33                 self.AddText('')\r
34         \r
35         def AddRadioButton(self, label, style = 0):\r
36                 radio = wx.RadioButton(self, -1, label, style=style)\r
37                 self.GetSizer().Add(radio, 0, wx.EXPAND|wx.ALL, 5)\r
38                 return radio\r
39         \r
40         def AddButton(self, label):\r
41                 button = wx.Button(self, -1, label)\r
42                 self.GetSizer().Add(button, 0, wx.LEFT, 5)\r
43                 return button\r
44         \r
45         def AddDualButton(self, label1, label2):\r
46                 p = wx.Panel(self)\r
47                 p.SetSizer(wx.BoxSizer(wx.HORIZONTAL))\r
48                 button1 = wx.Button(p, -1, label1)\r
49                 p.GetSizer().Add(button1, 0, wx.RIGHT, 8)\r
50                 button2 = wx.Button(p, -1, label2)\r
51                 p.GetSizer().Add(button2, 0)\r
52                 self.GetSizer().Add(p, 0, wx.LEFT, 5)\r
53                 return button1, button2\r
54         \r
55         def AllowNext(self):\r
56                 return True\r
57         \r
58         def StoreData(self):\r
59                 pass\r
60 \r
61 class FirstInfoPage(InfoPage):\r
62         def __init__(self, parent):\r
63                 super(FirstInfoPage, self).__init__(parent, "First time run wizard")\r
64                 self.AddText('Welcome, and thanks for trying Cura!')\r
65                 self.AddSeperator()\r
66                 self.AddText('This wizard will help you with the following steps:')\r
67                 self.AddText('* Configure Cura for your machine')\r
68                 self.AddText('* Upgrade your firmware')\r
69                 self.AddText('* Calibrate your machine')\r
70                 #self.AddText('* Do your first print')\r
71 \r
72 class RepRapInfoPage(InfoPage):\r
73         def __init__(self, parent):\r
74                 super(RepRapInfoPage, self).__init__(parent, "RepRap information")\r
75                 self.AddText('Sorry, but this wizard will not help you with\nconfiguring and calibrating your RepRap.')\r
76                 self.AddSeperator()\r
77                 self.AddText('You will have to manually install Marlin or Sprinter firmware\nand configure Cura.')\r
78 \r
79 class MachineSelectPage(InfoPage):\r
80         def __init__(self, parent):\r
81                 super(MachineSelectPage, self).__init__(parent, "Select your machine")\r
82                 self.AddText('What kind of machine do you have:')\r
83 \r
84                 self.UltimakerRadio = self.AddRadioButton("Ultimaker", style=wx.RB_GROUP)\r
85                 self.UltimakerRadio.SetValue(True)\r
86                 self.UltimakerRadio.Bind(wx.EVT_RADIOBUTTON, self.OnUltimakerSelect)\r
87                 self.OtherRadio = self.AddRadioButton("Other (Ex: RepRap)")\r
88                 self.OtherRadio.Bind(wx.EVT_RADIOBUTTON, self.OnOtherSelect)\r
89                 \r
90         def OnUltimakerSelect(self, e):\r
91                 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().ultimakerFirmwareUpgradePage)\r
92                 \r
93         def OnOtherSelect(self, e):\r
94                 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().repRapInfoPage)\r
95         \r
96         def StoreData(self):\r
97                 if self.UltimakerRadio.GetValue():\r
98                         profile.putPreference('machine_width', '205')\r
99                         profile.putPreference('machine_depth', '205')\r
100                         profile.putPreference('machine_height', '200')\r
101                         profile.putPreference('machine_type', 'ultimaker')\r
102                         profile.putProfileSetting('nozzle_size', '0.4')\r
103                         profile.putProfileSetting('machine_center_x', '100')\r
104                         profile.putProfileSetting('machine_center_y', '100')\r
105                 else:\r
106                         profile.putPreference('machine_width', '80')\r
107                         profile.putPreference('machine_depth', '80')\r
108                         profile.putPreference('machine_height', '60')\r
109                         profile.putPreference('machine_type', 'reprap')\r
110                         profile.putProfileSetting('nozzle_size', '0.5')\r
111                         profile.putProfileSetting('machine_center_x', '40')\r
112                         profile.putProfileSetting('machine_center_y', '40')\r
113                 profile.putProfileSetting('wall_thickness', float(profile.getProfileSetting('nozzle_size')) * 2)\r
114 \r
115 class FirmwareUpgradePage(InfoPage):\r
116         def __init__(self, parent):\r
117                 super(FirmwareUpgradePage, self).__init__(parent, "Upgrade Ultimaker Firmware")\r
118                 self.AddText('Firmware is the piece of software running directly on your 3D printer.\nThis firmware controls the step motors, regulates the temperature\nand ultimately makes your printer work.')\r
119                 self.AddHiddenSeperator()\r
120                 self.AddText('The firmware shipping with new Ultimakers works, but upgrades\nhave been made to make better prints, and make calibration easier.')\r
121                 self.AddHiddenSeperator()\r
122                 self.AddText('Cura requires these new features and thus\nyour firmware will most likely need to be upgraded.\nYou will get the chance to do so now.')\r
123                 upgradeButton, skipUpgradeButton = self.AddDualButton('Upgrade to Marlin firmware', 'Skip upgrade')\r
124                 upgradeButton.Bind(wx.EVT_BUTTON, self.OnUpgradeClick)\r
125                 skipUpgradeButton.Bind(wx.EVT_BUTTON, self.OnSkipClick)\r
126                 self.AddHiddenSeperator()\r
127                 self.AddText('Do not upgrade to this firmware if:')\r
128                 self.AddText('* You have an older machine based on ATMega1280')\r
129                 self.AddText('* Have other changes in the firmware')\r
130                 button = self.AddButton('Goto this page for a custom firmware')\r
131                 button.Bind(wx.EVT_BUTTON, self.OnUrlClick)\r
132         \r
133         def AllowNext(self):\r
134                 return False\r
135         \r
136         def OnUpgradeClick(self, e):\r
137                 if firmwareInstall.InstallFirmware():\r
138                         self.GetParent().FindWindowById(wx.ID_FORWARD).Enable()\r
139                 \r
140         def OnSkipClick(self, e):\r
141                 self.GetParent().FindWindowById(wx.ID_FORWARD).Enable()\r
142         \r
143         def OnUrlClick(self, e):\r
144                 webbrowser.open('http://daid.mine.nu/~daid/marlin_build/')\r
145 \r
146 class UltimakerCheckupPage(InfoPage):\r
147         def __init__(self, parent):\r
148                 super(UltimakerCheckupPage, self).__init__(parent, "Ultimaker Checkup")\r
149                 self.AddText('It is a good idea to do a few sanity checks now on your Ultimaker.\nYou can skip these if you know your machine is functional.')\r
150                 b1, b2 = self.AddDualButton('Run checks', 'Skip checks')\r
151                 b1.Bind(wx.EVT_BUTTON, self.OnCheckClick)\r
152                 b2.Bind(wx.EVT_BUTTON, self.OnSkipClick)\r
153                 self.AddSeperator();\r
154                 self.checkPanel = None\r
155         \r
156         def AllowNext(self):\r
157                 return False\r
158         \r
159         def OnSkipClick(self, e):\r
160                 self.GetParent().FindWindowById(wx.ID_FORWARD).Enable()\r
161         \r
162         def OnCheckClick(self, e):\r
163                 if self.checkPanel != None:\r
164                         self.checkPanel.Destroy()\r
165                 self.checkPanel = wx.Panel(self)\r
166                 self.checkPanel.SetSizer(wx.BoxSizer(wx.VERTICAL))\r
167                 self.GetSizer().Add(self.checkPanel, 0, wx.LEFT|wx.RIGHT, 5)\r
168                 threading.Thread(target=self.OnRun).start()\r
169 \r
170         def AddProgressText(self, info):\r
171                 text = wx.StaticText(self.checkPanel, -1, info)\r
172                 self.checkPanel.GetSizer().Add(text, 0)\r
173                 self.checkPanel.Layout()\r
174                 self.Layout()\r
175         \r
176         def OnRun(self):\r
177                 wx.CallAfter(self.AddProgressText, "Connecting to machine...")\r
178                 self.comm = machineCom.MachineCom()\r
179                 \r
180                 if not self.comm.isOpen():\r
181                         wx.CallAfter(self.AddProgressText, "Error: Failed to open serial port to machine")\r
182                         wx.CallAfter(self.AddProgressText, "If this keeps happening, try disconnecting and reconnecting the USB cable")\r
183                         return\r
184 \r
185                 wx.CallAfter(self.AddProgressText, "Checking start message...")\r
186                 if self.DoCommCommandWithTimeout(None, 'start') == False:\r
187                         wx.CallAfter(self.AddProgressText, "Error: Missing start message.")\r
188                         self.comm.close()\r
189                         return\r
190                 \r
191                 #Wait 3 seconds for the SD card init to timeout if we have SD in our firmware but there is no SD card found.\r
192                 time.sleep(3)\r
193                 \r
194                 wx.CallAfter(self.AddProgressText, "Disabling step motors...")\r
195                 if self.DoCommCommandWithTimeout('M84') == False:\r
196                         wx.CallAfter(self.AddProgressText, "Error: Missing reply to Deactivate steppers (M84).")\r
197                         self.comm.close()\r
198                         return\r
199 \r
200                 if self.DoCommCommandWithTimeout("M104 S0") == False:\r
201                         wx.CallAfter(self.AddProgressText, "Failed to set temperature")\r
202                         self.comm.close()\r
203                         return\r
204 \r
205                 wx.MessageBox('Please move the printer head to the center of the machine\nalso move the platform so it is not at the highest or lowest position,\nand make sure the machine is powered on.', 'Machine check', wx.OK | wx.ICON_INFORMATION)\r
206                 \r
207                 idleTemp = self.readTemp()\r
208                 if idleTemp > 40:\r
209                         wx.CallAfter(self.AddProgressText, "Waiting for head to cool down before temperature test...")\r
210                         while idleTemp > 40:\r
211                                 idleTemp = self.readTemp()\r
212                                 time.sleep(1)\r
213                 \r
214                 wx.CallAfter(self.AddProgressText, "Checking heater and temperature sensor...")\r
215                 wx.CallAfter(self.AddProgressText, "(This takes about 30 seconds)")\r
216                 if self.DoCommCommandWithTimeout("M104 S100") == False:\r
217                         wx.CallAfter(self.AddProgressText, "Failed to set temperature")\r
218                         self.comm.close()\r
219                         return\r
220                 \r
221                 time.sleep(25)\r
222                 tempInc = self.readTemp() - idleTemp\r
223                 \r
224                 if self.DoCommCommandWithTimeout("M104 S0") == False:\r
225                         wx.CallAfter(self.AddProgressText, "Failed to set temperature")\r
226                         self.comm.close()\r
227                         return\r
228                 \r
229                 if tempInc < 15:\r
230                         wx.CallAfter(self.AddProgressText, "Your temperature sensor or heater is not working!")\r
231                         self.comm.close()\r
232                         return\r
233                 wx.CallAfter(self.AddProgressText, "Heater and temperature sensor working\nWarning: head might still be hot!")\r
234 \r
235                 wx.CallAfter(self.AddProgressText, "Checking endstops")\r
236                 if self.DoCommCommandWithTimeout('M119', 'x_min') != "x_min:L x_max:L y_min:L y_max:L z_min:L z_max:L":\r
237                         wx.CallAfter(self.AddProgressText, "Error: There is a problem in your endstops!\nOne of them seems to be pressed while it shouldn't\ncheck the cable connections and the switches themselfs.")\r
238                         self.comm.close()\r
239                         return\r
240                 wx.CallAfter(self.AddProgressText, "Please press the X end switch in the front left corner.")\r
241                 if not self.DoCommCommandAndWaitForReply('M119', 'x_min', "x_min:H x_max:L y_min:L y_max:L z_min:L z_max:L"):\r
242                         wx.CallAfter(self.AddProgressText, "Failed to check the x_min endstop!")\r
243                         self.comm.close()\r
244                         return\r
245                 wx.CallAfter(self.AddProgressText, "Please press the X end switch in the front right corner.")\r
246                 if not self.DoCommCommandAndWaitForReply('M119', 'x_min', "x_min:L x_max:H y_min:L y_max:L z_min:L z_max:L"):\r
247                         wx.CallAfter(self.AddProgressText, "Failed to check the x_max endstop!")\r
248                         self.comm.close()\r
249                         return\r
250                 wx.CallAfter(self.AddProgressText, "Please press the Y end switch in the front left corner.")\r
251                 if not self.DoCommCommandAndWaitForReply('M119', 'x_min', "x_min:L x_max:L y_min:H y_max:L z_min:L z_max:L"):\r
252                         wx.CallAfter(self.AddProgressText, "Failed to check the x_max endstop!")\r
253                         self.comm.close()\r
254                         return\r
255                 wx.CallAfter(self.AddProgressText, "Please press the Y end switch in the back left corner.")\r
256                 if not self.DoCommCommandAndWaitForReply('M119', 'x_min', "x_min:L x_max:L y_min:L y_max:H z_min:L z_max:L"):\r
257                         wx.CallAfter(self.AddProgressText, "Failed to check the x_max endstop!")\r
258                         self.comm.close()\r
259                         return\r
260                 wx.CallAfter(self.AddProgressText, "Please press the Z end switch in the top.")\r
261                 if not self.DoCommCommandAndWaitForReply('M119', 'x_min', "x_min:L x_max:L y_min:L y_max:L z_min:H z_max:L"):\r
262                         wx.CallAfter(self.AddProgressText, "Failed to check the x_max endstop!")\r
263                         self.comm.close()\r
264                         return\r
265                 wx.CallAfter(self.AddProgressText, "Please press the Z end switch in the bottom.")\r
266                 if not self.DoCommCommandAndWaitForReply('M119', 'x_min', "x_min:L x_max:L y_min:L y_max:L z_min:L z_max:H"):\r
267                         wx.CallAfter(self.AddProgressText, "Failed to check the x_max endstop!")\r
268                         self.comm.close()\r
269                         return\r
270                 wx.CallAfter(self.AddProgressText, "End stops are working.")\r
271 \r
272                 wx.CallAfter(self.AddProgressText, "Done!")\r
273                 wx.CallAfter(self.GetParent().FindWindowById(wx.ID_FORWARD).Enable)\r
274                 self.comm.close()\r
275                 \r
276         def readTemp(self):\r
277                 line = self.DoCommCommandWithTimeout("M105", "ok T:")\r
278                 if line == False:\r
279                         return -1\r
280                 return int(re.search('T:([0-9]*)', line).group(1))\r
281         \r
282         def DoCommCommandAndWaitForReply(self, cmd, replyStart, reply):\r
283                 while True:\r
284                         ret = self.DoCommCommandWithTimeout(cmd, replyStart)\r
285                         if ret == reply:\r
286                                 return True\r
287                         if ret == False:\r
288                                 return False\r
289                         time.sleep(1)\r
290         \r
291         def DoCommCommandWithTimeout(self, cmd = None, replyStart = 'ok'):\r
292                 if cmd != None:\r
293                         self.comm.sendCommand(cmd)\r
294                 t = threading.Timer(5, self.OnSerialTimeout)\r
295                 t.start()\r
296                 while True:\r
297                         line = self.comm.readline()\r
298                         if line == '' or line == None:\r
299                                 self.comm.close()\r
300                                 return False\r
301                         print line.rstrip()\r
302                         if line.startswith(replyStart):\r
303                                 break\r
304                 t.cancel()\r
305                 return line.rstrip()\r
306         \r
307         def OnSerialTimeout(self):\r
308                 self.comm.close()\r
309 \r
310 class UltimakerCalibrationPage(InfoPage):\r
311         def __init__(self, parent):\r
312                 super(UltimakerCalibrationPage, self).__init__(parent, "Ultimaker Calibration")\r
313                 \r
314                 self.AddText("Your Ultimaker requires some calibration.");\r
315                 self.AddText("This calibration is needed for a proper extrusion amount.");\r
316                 self.AddSeperator()\r
317                 self.AddText("The following values are needed:");\r
318                 self.AddText("* Diameter of filament");\r
319                 self.AddText("* Number of steps per mm of filament extrusion");\r
320                 self.AddSeperator()\r
321                 self.AddText("The better you have calibrated these values, the better your prints\nwill become.");\r
322                 self.AddSeperator()\r
323                 self.AddText("First we need the diameter of your filament:");\r
324                 self.filamentDiameter = wx.TextCtrl(self, -1, profile.getProfileSetting('filament_diameter'))\r
325                 self.GetSizer().Add(self.filamentDiameter, 0, wx.LEFT, 5)\r
326                 self.AddText("If you do not own digital Calipers that can measure\nat least 2 digits then use 2.89mm.\nWhich is the average diameter of most filament.");\r
327                 self.AddText("Note: This value can be changed later at any time.");\r
328 \r
329         def StoreData(self):\r
330                 profile.putProfileSetting('filament_diameter', self.filamentDiameter.GetValue())\r
331 \r
332 class UltimakerCalibrateStepsPerEPage(InfoPage):\r
333         def __init__(self, parent):\r
334                 super(UltimakerCalibrateStepsPerEPage, self).__init__(parent, "Ultimaker Calibration")\r
335 \r
336                 if profile.getPreference('steps_per_e') == '0':\r
337                         profile.putPreference('steps_per_e', '865.888')\r
338                 \r
339                 self.AddText("Calibrating the Steps Per E requires some manual actions.")\r
340                 self.AddText("First remove any filament from your machine.")\r
341                 self.AddText("Next put in your filament so the tip is aligned with the\ntop of the extruder drive.")\r
342                 self.AddText("We'll push the filament 100mm")\r
343                 self.extrudeButton = self.AddButton("Extrude 100mm filament")\r
344                 self.AddText("Now measure the amount of extruded filament:\n(this can be more or less then 100mm)")\r
345                 p = wx.Panel(self)\r
346                 p.SetSizer(wx.BoxSizer(wx.HORIZONTAL))\r
347                 self.lengthInput = wx.TextCtrl(p, -1, '100')\r
348                 p.GetSizer().Add(self.lengthInput, 0, wx.RIGHT, 8)\r
349                 self.saveLengthButton = wx.Button(p, -1, 'Save')\r
350                 p.GetSizer().Add(self.saveLengthButton, 0)\r
351                 self.GetSizer().Add(p, 0, wx.LEFT, 5)\r
352                 self.AddText("This results in the following steps per E:")\r
353                 self.stepsPerEInput = wx.TextCtrl(self, -1, profile.getPreference('steps_per_e'))\r
354                 self.GetSizer().Add(self.stepsPerEInput, 0, wx.LEFT, 5)\r
355                 self.AddText("You can repeat these steps to get better calibration.")\r
356                 self.AddSeperator()\r
357                 self.AddText("If you still have filament in your printer which needs\nheat to remove, press the heat up button below:")\r
358                 self.heatButton = self.AddButton("Heatup for filament removal")\r
359                 \r
360                 self.saveLengthButton.Bind(wx.EVT_BUTTON, self.OnSaveLengthClick)\r
361                 self.extrudeButton.Bind(wx.EVT_BUTTON, self.OnExtrudeClick)\r
362                 self.heatButton.Bind(wx.EVT_BUTTON, self.OnHeatClick)\r
363         \r
364         def OnSaveLengthClick(self, e):\r
365                 currentEValue = float(self.stepsPerEInput.GetValue())\r
366                 realExtrudeLength = float(self.lengthInput.GetValue())\r
367                 newEValue = currentEValue * 100 / realExtrudeLength\r
368                 self.stepsPerEInput.SetValue(str(newEValue))\r
369                 self.lengthInput.SetValue("100")\r
370         \r
371         def OnExtrudeClick(self, e):\r
372                 threading.Thread(target=self.OnExtrudeRun).start()\r
373 \r
374         def OnExtrudeRun(self):\r
375                 self.heatButton.Enable(False)\r
376                 self.extrudeButton.Enable(False)\r
377                 currentEValue = float(self.stepsPerEInput.GetValue())\r
378                 self.comm = machineCom.MachineCom()\r
379                 if not self.comm.isOpen():\r
380                         wx.MessageBox("Error: Failed to open serial port to machine\nIf this keeps happening, try disconnecting and reconnecting the USB cable", 'Printer error', wx.OK | wx.ICON_INFORMATION)\r
381                         self.heatButton.Enable(True)\r
382                         self.extrudeButton.Enable(True)\r
383                         return\r
384                 while True:\r
385                         line = self.comm.readline()\r
386                         if line == '':\r
387                                 return\r
388                         if line.startswith('start'):\r
389                                 break\r
390                 #Wait 3 seconds for the SD card init to timeout if we have SD in our firmware but there is no SD card found.\r
391                 time.sleep(3)\r
392                 \r
393                 self.sendGCommand('M302') #Disable cold extrusion protection\r
394                 self.sendGCommand("M92 E%f" % (currentEValue));\r
395                 self.sendGCommand("G92 E0");\r
396                 self.sendGCommand("G1 E100 F600");\r
397                 time.sleep(15)\r
398                 self.comm.close()\r
399                 self.extrudeButton.Enable()\r
400                 self.heatButton.Enable()\r
401 \r
402         def OnHeatClick(self, e):\r
403                 threading.Thread(target=self.OnHeatRun).start()\r
404         \r
405         def OnHeatRun(self):\r
406                 self.heatButton.Enable(False)\r
407                 self.extrudeButton.Enable(False)\r
408                 self.comm = machineCom.MachineCom()\r
409                 if not self.comm.isOpen():\r
410                         wx.MessageBox("Error: Failed to open serial port to machine\nIf this keeps happening, try disconnecting and reconnecting the USB cable", 'Printer error', wx.OK | wx.ICON_INFORMATION)\r
411                         self.heatButton.Enable(True)\r
412                         self.extrudeButton.Enable(True)\r
413                         return\r
414                 while True:\r
415                         line = self.comm.readline()\r
416                         if line == '':\r
417                                 self.heatButton.Enable(True)\r
418                                 self.extrudeButton.Enable(True)\r
419                                 return\r
420                         if line.startswith('start'):\r
421                                 break\r
422                 #Wait 3 seconds for the SD card init to timeout if we have SD in our firmware but there is no SD card found.\r
423                 time.sleep(3)\r
424                 \r
425                 self.sendGCommand('M104 S200') #Set the temperature to 200C, should be enough to get PLA and ABS out.\r
426                 wx.MessageBox('Wait till you can remove the filament from the machine, and press OK.\n(Temperature is set to 200C)', 'Machine heatup', wx.OK | wx.ICON_INFORMATION)\r
427                 self.sendGCommand('M104 S0')\r
428                 time.sleep(1)\r
429                 self.comm.close()\r
430                 self.heatButton.Enable(True)\r
431                 self.extrudeButton.Enable(True)\r
432         \r
433         def sendGCommand(self, cmd):\r
434                 self.comm.sendCommand(cmd) #Disable cold extrusion protection\r
435                 while True:\r
436                         line = self.comm.readline()\r
437                         if line == '':\r
438                                 return\r
439                         if line.startswith('ok'):\r
440                                 break\r
441         \r
442         def StoreData(self):\r
443                 profile.putPreference('steps_per_e', self.stepsPerEInput.GetValue())\r
444 \r
445 class configWizard(wx.wizard.Wizard):\r
446         def __init__(self):\r
447                 super(configWizard, self).__init__(None, -1, "Configuration Wizard")\r
448                 \r
449                 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGED, self.OnPageChanged)\r
450                 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)\r
451 \r
452                 self.firstInfoPage = FirstInfoPage(self)\r
453                 self.machineSelectPage = MachineSelectPage(self)\r
454                 self.ultimakerFirmwareUpgradePage = FirmwareUpgradePage(self)\r
455                 self.ultimakerCheckupPage = UltimakerCheckupPage(self)\r
456                 self.ultimakerCalibrationPage = UltimakerCalibrationPage(self)\r
457                 self.ultimakerCalibrateStepsPerEPage = UltimakerCalibrateStepsPerEPage(self)\r
458                 self.repRapInfoPage = RepRapInfoPage(self)\r
459 \r
460                 wx.wizard.WizardPageSimple.Chain(self.firstInfoPage, self.machineSelectPage)\r
461                 wx.wizard.WizardPageSimple.Chain(self.machineSelectPage, self.ultimakerFirmwareUpgradePage)\r
462                 wx.wizard.WizardPageSimple.Chain(self.ultimakerFirmwareUpgradePage, self.ultimakerCheckupPage)\r
463                 wx.wizard.WizardPageSimple.Chain(self.ultimakerCheckupPage, self.ultimakerCalibrationPage)\r
464                 wx.wizard.WizardPageSimple.Chain(self.ultimakerCalibrationPage, self.ultimakerCalibrateStepsPerEPage)\r
465                 \r
466                 self.FitToPage(self.firstInfoPage)\r
467                 self.GetPageAreaSizer().Add(self.firstInfoPage)\r
468                 \r
469                 self.RunWizard(self.firstInfoPage)\r
470                 self.Destroy()\r
471 \r
472         def OnPageChanging(self, e):\r
473                 e.GetPage().StoreData()\r
474 \r
475         def OnPageChanged(self, e):\r
476                 if e.GetPage().AllowNext():\r
477                         self.FindWindowById(wx.ID_FORWARD).Enable() \r
478                 else:\r
479                         self.FindWindowById(wx.ID_FORWARD).Disable() \r
480                 self.FindWindowById(wx.ID_BACKWARD).Disable() \r