1 from __future__ import absolute_import
\r
4 import wx, os, platform, types, webbrowser, threading, time, re
\r
7 from gui import firmwareInstall
\r
8 from util import machineCom
\r
9 from util import profile
\r
11 class InfoPage(wx.wizard.WizardPageSimple):
\r
12 def __init__(self, parent, title):
\r
13 wx.wizard.WizardPageSimple.__init__(self, parent)
\r
15 sizer = wx.GridBagSizer(5, 5)
\r
17 self.SetSizer(sizer)
\r
18 sizer.AddGrowableCol(1)
\r
20 title = wx.StaticText(self, -1, title)
\r
21 title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD))
\r
22 sizer.Add(title, pos=(0, 0), span=(1,2), flag=wx.ALIGN_CENTRE|wx.ALL)
\r
23 sizer.Add(wx.StaticLine(self, -1), pos=(1,0), span=(1,2), flag=wx.EXPAND|wx.ALL)
\r
27 def AddText(self,info):
\r
28 text = wx.StaticText(self, -1, info)
\r
29 self.GetSizer().Add(text, pos=(self.rowNr, 0), span=(1,2), flag=wx.LEFT|wx.RIGHT)
\r
33 def AddSeperator(self):
\r
34 self.GetSizer().Add(wx.StaticLine(self, -1), pos=(self.rowNr, 0), span=(1,2), flag=wx.EXPAND|wx.ALL)
\r
37 def AddHiddenSeperator(self):
\r
40 def AddRadioButton(self, label, style = 0):
\r
41 radio = wx.RadioButton(self, -1, label, style=style)
\r
42 self.GetSizer().Add(radio, pos=(self.rowNr, 0), span=(1,2), flag=wx.EXPAND|wx.ALL)
\r
46 def AddCheckbox(self, label, checked = False):
\r
47 check = wx.CheckBox(self, -1)
\r
48 text = wx.StaticText(self, -1, label)
\r
49 check.SetValue(checked)
\r
50 self.GetSizer().Add(text, pos=(self.rowNr, 0), span=(1,1), flag=wx.LEFT|wx.RIGHT)
\r
51 self.GetSizer().Add(check, pos=(self.rowNr, 1), span=(1,2), flag=wx.ALL)
\r
55 def AddButton(self, label):
\r
56 button = wx.Button(self, -1, label)
\r
57 self.GetSizer().Add(button, pos=(self.rowNr, 0), span=(1,2), flag=wx.LEFT)
\r
61 def AddDualButton(self, label1, label2):
\r
62 button1 = wx.Button(self, -1, label1)
\r
63 self.GetSizer().Add(button1, pos=(self.rowNr, 0), flag=wx.RIGHT)
\r
64 button2 = wx.Button(self, -1, label2)
\r
65 self.GetSizer().Add(button2, pos=(self.rowNr, 1))
\r
67 return button1, button2
\r
69 def AddTextCtrl(self, value):
\r
70 ret = wx.TextCtrl(self, -1, value)
\r
71 self.GetSizer().Add(ret, pos=(self.rowNr, 0), span=(1,2), flag=wx.LEFT)
\r
75 def AddLabelTextCtrl(self, info, value):
\r
76 text = wx.StaticText(self, -1, info)
\r
77 ret = wx.TextCtrl(self, -1, value)
\r
78 self.GetSizer().Add(text, pos=(self.rowNr, 0), span=(1,1), flag=wx.LEFT)
\r
79 self.GetSizer().Add(ret, pos=(self.rowNr, 1), span=(1,1), flag=wx.LEFT)
\r
83 def AddTextCtrlButton(self, value, buttonText):
\r
84 text = wx.TextCtrl(self, -1, value)
\r
85 button = wx.Button(self, -1, buttonText)
\r
86 self.GetSizer().Add(text, pos=(self.rowNr, 0), span=(1,1), flag=wx.LEFT)
\r
87 self.GetSizer().Add(button, pos=(self.rowNr, 1), span=(1,1), flag=wx.LEFT)
\r
90 def AllowNext(self):
\r
93 def StoreData(self):
\r
96 class FirstInfoPage(InfoPage):
\r
97 def __init__(self, parent):
\r
98 super(FirstInfoPage, self).__init__(parent, "First time run wizard")
\r
99 self.AddText('Welcome, and thanks for trying Cura!')
\r
100 self.AddSeperator()
\r
101 self.AddText('This wizard will help you with the following steps:')
\r
102 self.AddText('* Configure Cura for your machine')
\r
103 self.AddText('* Upgrade your firmware')
\r
104 self.AddText('* Calibrate your machine')
\r
105 #self.AddText('* Do your first print')
\r
107 class RepRapInfoPage(InfoPage):
\r
108 def __init__(self, parent):
\r
109 super(RepRapInfoPage, self).__init__(parent, "RepRap information")
\r
110 self.AddText('RepRap machines are vastly different, and there is no\ndefault configuration in Cura for any of them.')
\r
111 self.AddText('If you like a default profile for your machine added,\nthen make an issue on github.')
\r
112 self.AddSeperator()
\r
113 self.AddText('You will have to manually install Marlin or Sprinter firmware.')
\r
114 self.AddSeperator()
\r
115 self.machineWidth = self.AddLabelTextCtrl('Machine width (mm)', '80')
\r
116 self.machineDepth = self.AddLabelTextCtrl('Machine depth (mm)', '80')
\r
117 self.machineHeight = self.AddLabelTextCtrl('Machine height (mm)', '60')
\r
118 self.nozzleSize = self.AddLabelTextCtrl('Nozzle size (mm)', '0.5')
\r
119 self.heatedBed = self.AddCheckbox('Heated bed')
\r
121 def StoreData(self):
\r
122 profile.putPreference('machine_width', self.machineWidth.GetValue())
\r
123 profile.putPreference('machine_depth', self.machineDepth.GetValue())
\r
124 profile.putPreference('machine_height', self.machineHeight.GetValue())
\r
125 profile.putProfileSetting('nozzle_size', self.nozzleSize.GetValue())
\r
126 profile.putProfileSetting('machine_center_x', profile.getPreferenceFloat('machine_width') / 2)
\r
127 profile.putProfileSetting('machine_center_y', profile.getPreferenceFloat('machine_depth') / 2)
\r
128 profile.putProfileSetting('wall_thickness', float(profile.getProfileSettingFloat('nozzle_size')) * 2)
\r
129 profile.putPreference('has_heated_bed', str(self.heatedBed.GetValue()))
\r
131 class MachineSelectPage(InfoPage):
\r
132 def __init__(self, parent):
\r
133 super(MachineSelectPage, self).__init__(parent, "Select your machine")
\r
134 self.AddText('What kind of machine do you have:')
\r
136 self.UltimakerRadio = self.AddRadioButton("Ultimaker", style=wx.RB_GROUP)
\r
137 self.UltimakerRadio.SetValue(True)
\r
138 self.UltimakerRadio.Bind(wx.EVT_RADIOBUTTON, self.OnUltimakerSelect)
\r
139 self.OtherRadio = self.AddRadioButton("Other (Ex: RepRap)")
\r
140 self.OtherRadio.Bind(wx.EVT_RADIOBUTTON, self.OnOtherSelect)
\r
142 def OnUltimakerSelect(self, e):
\r
143 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().ultimakerFirmwareUpgradePage)
\r
145 def OnOtherSelect(self, e):
\r
146 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().repRapInfoPage)
\r
148 def StoreData(self):
\r
149 if self.UltimakerRadio.GetValue():
\r
150 profile.putPreference('machine_width', '205')
\r
151 profile.putPreference('machine_depth', '205')
\r
152 profile.putPreference('machine_height', '200')
\r
153 profile.putPreference('machine_type', 'ultimaker')
\r
154 profile.putProfileSetting('nozzle_size', '0.4')
\r
155 profile.putProfileSetting('machine_center_x', '100')
\r
156 profile.putProfileSetting('machine_center_y', '100')
\r
158 profile.putPreference('machine_width', '80')
\r
159 profile.putPreference('machine_depth', '80')
\r
160 profile.putPreference('machine_height', '60')
\r
161 profile.putPreference('machine_type', 'reprap')
\r
162 profile.putProfileSetting('nozzle_size', '0.5')
\r
163 profile.putProfileSetting('machine_center_x', '40')
\r
164 profile.putProfileSetting('machine_center_y', '40')
\r
165 profile.putProfileSetting('wall_thickness', float(profile.getProfileSetting('nozzle_size')) * 2)
\r
167 class FirmwareUpgradePage(InfoPage):
\r
168 def __init__(self, parent):
\r
169 super(FirmwareUpgradePage, self).__init__(parent, "Upgrade Ultimaker Firmware")
\r
170 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
171 self.AddHiddenSeperator()
\r
172 self.AddText('The firmware shipping with new Ultimakers works, but upgrades\nhave been made to make better prints, and make calibration easier.')
\r
173 self.AddHiddenSeperator()
\r
174 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
175 upgradeButton, skipUpgradeButton = self.AddDualButton('Upgrade to Marlin firmware', 'Skip upgrade')
\r
176 upgradeButton.Bind(wx.EVT_BUTTON, self.OnUpgradeClick)
\r
177 skipUpgradeButton.Bind(wx.EVT_BUTTON, self.OnSkipClick)
\r
178 self.AddHiddenSeperator()
\r
179 self.AddText('Do not upgrade to this firmware if:')
\r
180 self.AddText('* You have an older machine based on ATMega1280')
\r
181 self.AddText('* Have other changes in the firmware')
\r
182 button = self.AddButton('Goto this page for a custom firmware')
\r
183 button.Bind(wx.EVT_BUTTON, self.OnUrlClick)
\r
185 def AllowNext(self):
\r
188 def OnUpgradeClick(self, e):
\r
189 if firmwareInstall.InstallFirmware():
\r
190 self.GetParent().FindWindowById(wx.ID_FORWARD).Enable()
\r
192 def OnSkipClick(self, e):
\r
193 self.GetParent().FindWindowById(wx.ID_FORWARD).Enable()
\r
195 def OnUrlClick(self, e):
\r
196 webbrowser.open('http://daid.mine.nu/~daid/marlin_build/')
\r
198 class UltimakerCheckupPage(InfoPage):
\r
199 def __init__(self, parent):
\r
200 super(UltimakerCheckupPage, self).__init__(parent, "Ultimaker Checkup")
\r
201 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
202 b1, b2 = self.AddDualButton('Run checks', 'Skip checks')
\r
203 b1.Bind(wx.EVT_BUTTON, self.OnCheckClick)
\r
204 b2.Bind(wx.EVT_BUTTON, self.OnSkipClick)
\r
205 self.AddSeperator()
\r
206 self.checkPanel = None
\r
208 def AllowNext(self):
\r
211 def OnSkipClick(self, e):
\r
212 self.GetParent().FindWindowById(wx.ID_FORWARD).Enable()
\r
214 def OnCheckClick(self, e):
\r
215 if self.checkPanel != None:
\r
216 self.checkPanel.Destroy()
\r
217 self.checkPanel = wx.Panel(self)
\r
218 self.checkPanel.SetSizer(wx.BoxSizer(wx.VERTICAL))
\r
219 self.GetSizer().Add(self.checkPanel, 0, wx.LEFT|wx.RIGHT, 5)
\r
220 threading.Thread(target=self.OnRun).start()
\r
222 def AddProgressText(self, info):
\r
223 text = wx.StaticText(self.checkPanel, -1, info)
\r
224 self.checkPanel.GetSizer().Add(text, 0)
\r
225 self.checkPanel.Layout()
\r
229 wx.CallAfter(self.AddProgressText, "Connecting to machine...")
\r
230 self.comm = machineCom.MachineCom()
\r
232 if not self.comm.isOpen():
\r
233 wx.CallAfter(self.AddProgressText, "Error: Failed to open serial port to machine")
\r
234 wx.CallAfter(self.AddProgressText, "If this keeps happening, try disconnecting and reconnecting the USB cable")
\r
237 wx.CallAfter(self.AddProgressText, "Checking start message...")
\r
238 if self.DoCommCommandWithTimeout(None, 'start') == False:
\r
239 wx.CallAfter(self.AddProgressText, "Error: Missing start message.")
\r
243 #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
246 wx.CallAfter(self.AddProgressText, "Disabling step motors...")
\r
247 if self.DoCommCommandWithTimeout('M84') == False:
\r
248 wx.CallAfter(self.AddProgressText, "Error: Missing reply to Deactivate steppers (M84).")
\r
252 if self.DoCommCommandWithTimeout("M104 S0") == False:
\r
253 wx.CallAfter(self.AddProgressText, "Failed to set temperature")
\r
257 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
259 idleTemp = self.readTemp()
\r
261 wx.CallAfter(self.AddProgressText, "Waiting for head to cool down before temperature test...")
\r
262 while idleTemp > 40:
\r
263 idleTemp = self.readTemp()
\r
266 wx.CallAfter(self.AddProgressText, "Checking heater and temperature sensor...")
\r
267 wx.CallAfter(self.AddProgressText, "(This takes about 30 seconds)")
\r
268 if self.DoCommCommandWithTimeout("M104 S100") == False:
\r
269 wx.CallAfter(self.AddProgressText, "Failed to set temperature")
\r
274 tempInc = self.readTemp() - idleTemp
\r
276 if self.DoCommCommandWithTimeout("M104 S0") == False:
\r
277 wx.CallAfter(self.AddProgressText, "Failed to set temperature")
\r
282 wx.CallAfter(self.AddProgressText, "Your temperature sensor or heater is not working!")
\r
285 wx.CallAfter(self.AddProgressText, "Heater and temperature sensor working\nWarning: head might still be hot!")
\r
287 wx.CallAfter(self.AddProgressText, "Checking endstops")
\r
288 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
289 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
292 wx.CallAfter(self.AddProgressText, "Please press the X end switch in the front left corner.")
\r
293 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
294 wx.CallAfter(self.AddProgressText, "Failed to check the x_min endstop!")
\r
297 wx.CallAfter(self.AddProgressText, "Please press the X end switch in the front right corner.")
\r
298 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
299 wx.CallAfter(self.AddProgressText, "Failed to check the x_max endstop!")
\r
302 wx.CallAfter(self.AddProgressText, "Please press the Y end switch in the front left corner.")
\r
303 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
304 wx.CallAfter(self.AddProgressText, "Failed to check the x_max endstop!")
\r
307 wx.CallAfter(self.AddProgressText, "Please press the Y end switch in the back left corner.")
\r
308 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
309 wx.CallAfter(self.AddProgressText, "Failed to check the x_max endstop!")
\r
312 wx.CallAfter(self.AddProgressText, "Please press the Z end switch in the top.")
\r
313 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
314 wx.CallAfter(self.AddProgressText, "Failed to check the x_max endstop!")
\r
317 wx.CallAfter(self.AddProgressText, "Please press the Z end switch in the bottom.")
\r
318 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
319 wx.CallAfter(self.AddProgressText, "Failed to check the x_max endstop!")
\r
322 wx.CallAfter(self.AddProgressText, "End stops are working.")
\r
324 wx.CallAfter(self.AddProgressText, "Done!")
\r
325 wx.CallAfter(self.GetParent().FindWindowById(wx.ID_FORWARD).Enable)
\r
328 def readTemp(self):
\r
329 line = self.DoCommCommandWithTimeout("M105", "ok T:")
\r
332 return int(re.search('T:([0-9]*)', line).group(1))
\r
334 def DoCommCommandAndWaitForReply(self, cmd, replyStart, reply):
\r
336 ret = self.DoCommCommandWithTimeout(cmd, replyStart)
\r
343 def DoCommCommandWithTimeout(self, cmd = None, replyStart = 'ok'):
\r
345 self.comm.sendCommand(cmd)
\r
346 t = threading.Timer(5, self.OnSerialTimeout)
\r
349 line = self.comm.readline()
\r
350 if line == '' or line == None:
\r
353 print line.rstrip()
\r
354 if replyStart in line:
\r
357 return line.rstrip()
\r
359 def OnSerialTimeout(self):
\r
362 class UltimakerCalibrationPage(InfoPage):
\r
363 def __init__(self, parent):
\r
364 super(UltimakerCalibrationPage, self).__init__(parent, "Ultimaker Calibration")
\r
366 self.AddText("Your Ultimaker requires some calibration.")
\r
367 self.AddText("This calibration is needed for a proper extrusion amount.")
\r
368 self.AddSeperator()
\r
369 self.AddText("The following values are needed:")
\r
370 self.AddText("* Diameter of filament")
\r
371 self.AddText("* Number of steps per mm of filament extrusion")
\r
372 self.AddSeperator()
\r
373 self.AddText("The better you have calibrated these values, the better your prints\nwill become.")
\r
374 self.AddSeperator()
\r
375 self.AddText("First we need the diameter of your filament:")
\r
376 self.filamentDiameter = self.AddTextCtrl(profile.getProfileSetting('filament_diameter'))
\r
377 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
378 self.AddText("Note: This value can be changed later at any time.")
\r
380 def StoreData(self):
\r
381 profile.putProfileSetting('filament_diameter', self.filamentDiameter.GetValue())
\r
383 class UltimakerCalibrateStepsPerEPage(InfoPage):
\r
384 def __init__(self, parent):
\r
385 super(UltimakerCalibrateStepsPerEPage, self).__init__(parent, "Ultimaker Calibration")
\r
387 if profile.getPreference('steps_per_e') == '0':
\r
388 profile.putPreference('steps_per_e', '865.888')
\r
390 self.AddText("Calibrating the Steps Per E requires some manual actions.")
\r
391 self.AddText("First remove any filament from your machine.")
\r
392 self.AddText("Next put in your filament so the tip is aligned with the\ntop of the extruder drive.")
\r
393 self.AddText("We'll push the filament 100mm")
\r
394 self.extrudeButton = self.AddButton("Extrude 100mm filament")
\r
395 self.AddText("Now measure the amount of extruded filament:\n(this can be more or less then 100mm)")
\r
396 self.lengthInput, self.saveLengthButton = self.AddTextCtrlButton('100', 'Save')
\r
397 self.AddText("This results in the following steps per E:")
\r
398 self.stepsPerEInput = self.AddTextCtrl(profile.getPreference('steps_per_e'))
\r
399 self.AddText("You can repeat these steps to get better calibration.")
\r
400 self.AddSeperator()
\r
401 self.AddText("If you still have filament in your printer which needs\nheat to remove, press the heat up button below:")
\r
402 self.heatButton = self.AddButton("Heatup for filament removal")
\r
404 self.saveLengthButton.Bind(wx.EVT_BUTTON, self.OnSaveLengthClick)
\r
405 self.extrudeButton.Bind(wx.EVT_BUTTON, self.OnExtrudeClick)
\r
406 self.heatButton.Bind(wx.EVT_BUTTON, self.OnHeatClick)
\r
408 def OnSaveLengthClick(self, e):
\r
409 currentEValue = float(self.stepsPerEInput.GetValue())
\r
410 realExtrudeLength = float(self.lengthInput.GetValue())
\r
411 newEValue = currentEValue * 100 / realExtrudeLength
\r
412 self.stepsPerEInput.SetValue(str(newEValue))
\r
413 self.lengthInput.SetValue("100")
\r
415 def OnExtrudeClick(self, e):
\r
416 threading.Thread(target=self.OnExtrudeRun).start()
\r
418 def OnExtrudeRun(self):
\r
419 self.heatButton.Enable(False)
\r
420 self.extrudeButton.Enable(False)
\r
421 currentEValue = float(self.stepsPerEInput.GetValue())
\r
422 self.comm = machineCom.MachineCom()
\r
423 if not self.comm.isOpen():
\r
424 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
425 self.heatButton.Enable(True)
\r
426 self.extrudeButton.Enable(True)
\r
429 line = self.comm.readline()
\r
432 if 'start' in line:
\r
434 #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
437 self.sendGCommand('M302') #Disable cold extrusion protection
\r
438 self.sendGCommand("M92 E%f" % (currentEValue))
\r
439 self.sendGCommand("G92 E0")
\r
440 self.sendGCommand("G1 E100 F600")
\r
443 self.extrudeButton.Enable()
\r
444 self.heatButton.Enable()
\r
446 def OnHeatClick(self, e):
\r
447 threading.Thread(target=self.OnHeatRun).start()
\r
449 def OnHeatRun(self):
\r
450 self.heatButton.Enable(False)
\r
451 self.extrudeButton.Enable(False)
\r
452 self.comm = machineCom.MachineCom()
\r
453 if not self.comm.isOpen():
\r
454 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
455 self.heatButton.Enable(True)
\r
456 self.extrudeButton.Enable(True)
\r
459 line = self.comm.readline()
\r
461 self.heatButton.Enable(True)
\r
462 self.extrudeButton.Enable(True)
\r
464 if 'start' in line:
\r
466 #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
469 self.sendGCommand('M104 S200') #Set the temperature to 200C, should be enough to get PLA and ABS out.
\r
470 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
471 self.sendGCommand('M104 S0')
\r
474 self.heatButton.Enable(True)
\r
475 self.extrudeButton.Enable(True)
\r
477 def sendGCommand(self, cmd):
\r
478 self.comm.sendCommand(cmd) #Disable cold extrusion protection
\r
480 line = self.comm.readline()
\r
483 if line.startswith('ok'):
\r
486 def StoreData(self):
\r
487 profile.putPreference('steps_per_e', self.stepsPerEInput.GetValue())
\r
489 class configWizard(wx.wizard.Wizard):
\r
490 def __init__(self):
\r
491 super(configWizard, self).__init__(None, -1, "Configuration Wizard")
\r
493 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGED, self.OnPageChanged)
\r
494 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)
\r
496 self.firstInfoPage = FirstInfoPage(self)
\r
497 self.machineSelectPage = MachineSelectPage(self)
\r
498 self.ultimakerFirmwareUpgradePage = FirmwareUpgradePage(self)
\r
499 self.ultimakerCheckupPage = UltimakerCheckupPage(self)
\r
500 self.ultimakerCalibrationPage = UltimakerCalibrationPage(self)
\r
501 self.ultimakerCalibrateStepsPerEPage = UltimakerCalibrateStepsPerEPage(self)
\r
502 self.repRapInfoPage = RepRapInfoPage(self)
\r
504 wx.wizard.WizardPageSimple.Chain(self.firstInfoPage, self.machineSelectPage)
\r
505 wx.wizard.WizardPageSimple.Chain(self.machineSelectPage, self.ultimakerFirmwareUpgradePage)
\r
506 wx.wizard.WizardPageSimple.Chain(self.ultimakerFirmwareUpgradePage, self.ultimakerCheckupPage)
\r
507 wx.wizard.WizardPageSimple.Chain(self.ultimakerCheckupPage, self.ultimakerCalibrationPage)
\r
508 wx.wizard.WizardPageSimple.Chain(self.ultimakerCalibrationPage, self.ultimakerCalibrateStepsPerEPage)
\r
510 self.FitToPage(self.firstInfoPage)
\r
511 self.GetPageAreaSizer().Add(self.firstInfoPage)
\r
513 self.RunWizard(self.firstInfoPage)
\r
516 def OnPageChanging(self, e):
\r
517 e.GetPage().StoreData()
\r
519 def OnPageChanged(self, e):
\r
520 if e.GetPage().AllowNext():
\r
521 self.FindWindowById(wx.ID_FORWARD).Enable()
\r
523 self.FindWindowById(wx.ID_FORWARD).Disable()
\r
524 self.FindWindowById(wx.ID_BACKWARD).Disable()
\r