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