import platform
from Cura.util import meshLoader
+try:
+ #MacOS release currently lacks some wx components, like the Publisher.
+ from wx.lib.pubsub import Publisher
+except:
+ Publisher = None
+
class mainWindow(wx.Frame):
def __init__(self):
- super(mainWindow, self).__init__(None, title='Cura - ' + version.getVersion())
+ super(mainWindow, self).__init__(None, title=_('Cura - ') + version.getVersion())
wx.EVT_CLOSE(self, self.OnClose)
i = self.fileMenu.Append(-1, _("Save Profile..."))
self.normalModeOnlyItems.append(i)
self.Bind(wx.EVT_MENU, self.OnSaveProfile, i)
+ if version.isDevVersion():
+ i = self.fileMenu.Append(-1, "Save difference from default...")
+ self.normalModeOnlyItems.append(i)
+ self.Bind(wx.EVT_MENU, self.OnSaveDifferences, i)
i = self.fileMenu.Append(-1, _("Load Profile from GCode..."))
self.normalModeOnlyItems.append(i)
self.Bind(wx.EVT_MENU, self.OnLoadProfileFromGcode, i)
if version.isDevVersion():
i = toolsMenu.Append(-1, _("PID Debugger..."))
self.Bind(wx.EVT_MENU, self.OnPIDDebugger, i)
+ i = toolsMenu.Append(-1, _("Auto Firmware Update..."))
+ self.Bind(wx.EVT_MENU, self.OnAutoFirmwareUpdate, i)
- i = toolsMenu.Append(-1, _("Copy profile to clipboard"))
- self.Bind(wx.EVT_MENU, self.onCopyProfileClipboard,i)
+ #i = toolsMenu.Append(-1, _("Copy profile to clipboard"))
+ #self.Bind(wx.EVT_MENU, self.onCopyProfileClipboard,i)
toolsMenu.AppendSeparator()
self.allAtOnceItem = toolsMenu.Append(-1, _("Print all at once"), kind=wx.ITEM_RADIO)
self.normalModeOnlyItems.append(i)
self.Bind(wx.EVT_MENU, self.OnExpertOpen, i)
expertMenu.AppendSeparator()
- i = expertMenu.Append(-1, _("Run first run wizard..."))
- self.Bind(wx.EVT_MENU, self.OnFirstRunWizard, i)
self.bedLevelWizardMenuItem = expertMenu.Append(-1, _("Run bed leveling wizard..."))
self.Bind(wx.EVT_MENU, self.OnBedLevelWizard, self.bedLevelWizardMenuItem)
self.headOffsetWizardMenuItem = expertMenu.Append(-1, _("Run head offset wizard..."))
helpMenu = wx.Menu()
i = helpMenu.Append(-1, _("Online documentation..."))
- self.Bind(wx.EVT_MENU, lambda e: webbrowser.open('http://daid.github.com/Cura'), i)
+ self.Bind(wx.EVT_MENU, lambda e: webbrowser.open('http://lulzbot.com/cura'), i)
i = helpMenu.Append(-1, _("Report a problem..."))
- self.Bind(wx.EVT_MENU, lambda e: webbrowser.open('https://github.com/daid/Cura/issues'), i)
- i = helpMenu.Append(-1, _("Check for update..."))
- self.Bind(wx.EVT_MENU, self.OnCheckForUpdate, i)
- i = helpMenu.Append(-1, _("Open YouMagine website..."))
- self.Bind(wx.EVT_MENU, lambda e: webbrowser.open('https://www.youmagine.com/'), i)
+ self.Bind(wx.EVT_MENU, lambda e: webbrowser.open('https://github.com/alephobjects/Cura/issues'), i)
+ #i = helpMenu.Append(-1, _("Check for update..."))
+ #self.Bind(wx.EVT_MENU, self.OnCheckForUpdate, i)
+ #i = helpMenu.Append(-1, _("Open YouMagine website..."))
+ #self.Bind(wx.EVT_MENU, lambda e: webbrowser.open('https://www.youmagine.com/'), i)
i = helpMenu.Append(-1, _("About Cura..."))
self.Bind(wx.EVT_MENU, self.OnAbout, i)
self.menubar.Append(helpMenu, _("Help"))
self.rightPane = wx.Panel(self.splitter, style=wx.BORDER_NONE)
self.splitter.Bind(wx.EVT_SPLITTER_DCLICK, lambda evt: evt.Veto())
+ #Preview window
+ self.scene = sceneView.SceneView(self.rightPane)
+
##Gui components##
- self.simpleSettingsPanel = simpleMode.simpleModePanel(self.leftPane, lambda : self.scene.sceneUpdated())
- self.normalSettingsPanel = normalSettingsPanel(self.leftPane, lambda : self.scene.sceneUpdated())
+ self.simpleSettingsPanel = simpleMode.simpleModePanel(self.leftPane, self.scene.sceneUpdated)
+ self.normalSettingsPanel = normalSettingsPanel(self.leftPane, self.scene.sceneUpdated)
self.leftSizer = wx.BoxSizer(wx.VERTICAL)
self.leftSizer.Add(self.simpleSettingsPanel, 1)
self.leftSizer.Add(self.normalSettingsPanel, 1, wx.EXPAND)
self.leftPane.SetSizer(self.leftSizer)
- #Preview window
- self.scene = sceneView.SceneView(self.rightPane)
-
#Main sizer, to position the preview window, buttons and tab control
sizer = wx.BoxSizer()
self.rightPane.SetSizer(sizer)
#Timer set; used to check if profile is on the clipboard
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.onTimer)
- self.timer.Start(1000)
+ #self.timer.Start(1000)
self.lastTriedClipboard = profile.getProfileString()
# Restore the window position, size & state from the preferences file
self.updateSliceMode()
self.scene.SetFocus()
+ self.dialogframe = None
+ if Publisher is not None:
+ Publisher().subscribe(self.onPluginUpdate, "pluginupdate")
+
+ pluginCount = self.normalSettingsPanel.pluginPanel.GetActivePluginCount()
+ if pluginCount == 1:
+ self.scene.notification.message("Warning: 1 plugin from the previous session is still active.")
+
+ if pluginCount > 1:
+ self.scene.notification.message("Warning: %i plugins from the previous session are still active." % pluginCount)
+
+ def onPluginUpdate(self,msg): #receives commands from the plugin thread
+ cmd = str(msg.data).split(";")
+ if cmd[0] == "OpenPluginProgressWindow":
+ if len(cmd)==1: #no titel received
+ cmd.append("Plugin")
+ if len(cmd)<3: #no message text received
+ cmd.append("Plugin is executed...")
+ dialogwidth = 300
+ dialogheight = 80
+ self.dialogframe = wx.Frame(self, -1, cmd[1],pos = ((wx.SystemSettings.GetMetric(wx.SYS_SCREEN_X)-dialogwidth)/2,(wx.SystemSettings.GetMetric(wx.SYS_SCREEN_Y)-dialogheight)/2), size=(dialogwidth,dialogheight), style = wx.STAY_ON_TOP)
+ self.dialogpanel = wx.Panel(self.dialogframe, -1, pos = (0,0), size = (dialogwidth,dialogheight))
+ self.dlgtext = wx.StaticText(self.dialogpanel, label = cmd[2], pos = (10,10), size = (280,40))
+ self.dlgbar = wx.Gauge(self.dialogpanel,-1, 100, pos = (10,50), size = (280,20), style = wx.GA_HORIZONTAL)
+ self.dialogframe.Show()
+
+ elif cmd[0] == "Progress":
+ number = int(cmd[1])
+ if number <= 100 and self.dialogframe is not None:
+ self.dlgbar.SetValue(number)
+ else:
+ self.dlgbar.SetValue(100)
+ elif cmd[0] == "ClosePluginProgressWindow":
+ self.dialogframe.Destroy()
+ self.dialogframe=None
+ else:
+ print "Unknown Plugin update received: " + cmd[0]
def onTimer(self, e):
#Check if there is something in the clipboard
print profileString
self.lastTriedClipboard = profileString
profile.setProfileFromString(profileString)
- self.scene.notification.message("Loaded new profile from clipboard.")
+ self.scene.notification.message(_("Loaded new profile from clipboard."))
self.updateProfileToAllControls()
except:
print "Unable to read from clipboard"
- def updateSliceMode(self):
+ def updateSliceMode(self, changedMode = True):
isSimple = profile.getPreference('startMode') == 'Simple'
self.normalSettingsPanel.Show(not isSimple)
# Set splitter sash position & size
if isSimple:
- # Save normal mode sash
- self.normalSashPos = self.splitter.GetSashPosition()
+ # Save normal mode sash (only if we changed mode from normal
+ # to simple)
+ if changedMode:
+ self.normalSashPos = self.splitter.GetSashPosition()
# Change location of sash to width of quick mode pane
(width, height) = self.simpleSettingsPanel.GetSizer().GetSize()
# Disable sash
self.splitter.SetSashSize(0)
else:
- self.splitter.SetSashPosition(self.normalSashPos, True)
+ # Only change the sash position if we changed mode from simple
+ if changedMode:
+ self.splitter.SetSashPosition(self.normalSashPos, True)
# Enabled sash
self.splitter.SetSashSize(4)
self.defaultFirmwareInstallMenuItem.Enable(firmwareInstall.getDefaultFirmware() is not None)
- if profile.getMachineSetting('machine_type') == 'ultimaker2':
+ if profile.getMachineSetting('machine_type').startswith('ultimaker2') or \
+ profile.getMachineSetting('machine_type').startswith('lulzbot_'):
self.bedLevelWizardMenuItem.Enable(False)
self.headOffsetWizardMenuItem.Enable(False)
+ else:
+ self.bedLevelWizardMenuItem.Enable(True)
+ self.headOffsetWizardMenuItem.Enable(False)
if int(profile.getMachineSetting('extruder_amount')) < 2:
self.headOffsetWizardMenuItem.Enable(False)
self.scene.updateProfileToControls()
prefDialog.Centre()
prefDialog.Show()
prefDialog.Raise()
- wx.CallAfter(prefDialog.Show)
def OnMachineSettings(self, e):
prefDialog = preferencesDialog.machineSettingsDialog(self)
prefDialog.Raise()
def OnDropFiles(self, files):
- if len(files) > 0:
- self.updateProfileToAllControls()
self.scene.loadFiles(files)
def OnModelMRU(self, e):
self.normalSettingsPanel.updateProfileToControls()
self.simpleSettingsPanel.updateProfileToControls()
- def reloadSettingPanels(self):
+ def reloadSettingPanels(self, changedSliceMode = False):
self.leftSizer.Detach(self.simpleSettingsPanel)
self.leftSizer.Detach(self.normalSettingsPanel)
self.simpleSettingsPanel.Destroy()
self.normalSettingsPanel = normalSettingsPanel(self.leftPane, lambda : self.scene.sceneUpdated())
self.leftSizer.Add(self.simpleSettingsPanel, 1)
self.leftSizer.Add(self.normalSettingsPanel, 1, wx.EXPAND)
- self.updateSliceMode()
+ self.updateSliceMode(changedSliceMode)
self.updateProfileToAllControls()
def updateMachineMenu(self):
self.Bind(wx.EVT_MENU, lambda e: self.OnSelectMachine(e.GetId() - 0x1000), i)
self.machineMenu.AppendSeparator()
-
+ i = self.machineMenu.Append(-1, _("Add new machine..."))
+ self.Bind(wx.EVT_MENU, self.OnAddNewMachine, i)
i = self.machineMenu.Append(-1, _("Machine settings..."))
self.Bind(wx.EVT_MENU, self.OnMachineSettings, i)
dlg=wx.FileDialog(self, _("Select profile file to save"), os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_SAVE)
dlg.SetWildcard("ini files (*.ini)|*.ini")
if dlg.ShowModal() == wx.ID_OK:
- profileFile = dlg.GetPath()
- if not profileFile.lower().endswith('.ini'): #hack for linux, as for some reason the .ini is not appended.
- profileFile += '.ini'
- profile.saveProfile(profileFile)
+ profile_filename = dlg.GetPath()
+ if not profile_filename.lower().endswith('.ini'): #hack for linux, as for some reason the .ini is not appended.
+ profile_filename += '.ini'
+ profile.saveProfile(profile_filename)
+ dlg.Destroy()
+
+ def OnSaveDifferences(self, e):
+ dlg=wx.FileDialog(self, _("Select profile file to save"), os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_SAVE)
+ dlg.SetWildcard("ini files (*.ini)|*.ini")
+ if dlg.ShowModal() == wx.ID_OK:
+ profile_filename = dlg.GetPath()
+ if not profile_filename.lower().endswith('.ini'): #hack for linux, as for some reason the .ini is not appended.
+ profile_filename += '.ini'
+ profile.saveProfileDifferenceFromDefault(profile_filename)
dlg.Destroy()
def OnResetProfile(self, e):
def OnNormalSwitch(self, e):
profile.putPreference('startMode', 'Normal')
+ dlg = wx.MessageDialog(self, _("Copy the settings from quickprint to your full settings?\n(This will overwrite any full setting modifications you have)"), _("Profile copy"), wx.YES_NO | wx.ICON_QUESTION)
+ result = dlg.ShowModal() == wx.ID_YES
+ dlg.Destroy()
+ if result:
+ profile.resetProfile()
+ for k, v in self.simpleSettingsPanel.getSettingOverrides().items():
+ profile.putProfileSetting(k, v)
+ self.updateProfileToAllControls()
self.updateSliceMode()
def OnDefaultMarlinFirmware(self, e):
- firmwareInstall.InstallFirmware()
+ firmwareInstall.InstallFirmware(self)
def OnCustomFirmware(self, e):
if profile.getMachineSetting('machine_type').startswith('ultimaker'):
if not(os.path.exists(filename)):
return
#For some reason my Ubuntu 10.10 crashes here.
- firmwareInstall.InstallFirmware(filename)
+ firmwareInstall.InstallFirmware(self, filename)
- def OnFirstRunWizard(self, e):
+ def OnAddNewMachine(self, e):
self.Hide()
- configWizard.configWizard()
+ wasSimple = profile.getPreference('startMode') == 'Simple'
+ configWizard.ConfigWizard(True)
+ isSimple = profile.getPreference('startMode') == 'Simple'
self.Show()
- self.reloadSettingPanels()
+ self.reloadSettingPanels(isSimple != wasSimple)
+ self.updateMachineMenu()
def OnSelectMachine(self, index):
profile.setActiveMachine(index)
- self.reloadSettingPanels()
+ self.reloadSettingPanels(False)
def OnBedLevelWizard(self, e):
configWizard.bedLevelWizard()
debugger.Centre()
debugger.Show(True)
+ def OnAutoFirmwareUpdate(self, e):
+ dlg=wx.FileDialog(self, _("Open firmware to upload"), os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
+ dlg.SetWildcard("HEX file (*.hex)|*.hex;*.HEX")
+ if dlg.ShowModal() == wx.ID_OK:
+ filename = dlg.GetPath()
+ dlg.Destroy()
+ if not(os.path.exists(filename)):
+ return
+ #For some reason my Ubuntu 10.10 crashes here.
+ installer = firmwareInstall.AutoUpdateFirmware(self, filename)
+
def onCopyProfileClipboard(self, e):
try:
if not wx.TheClipboard.IsOpened():
wx.MessageBox(_("You are running the latest version of Cura!"), _("Awesome!"), wx.ICON_INFORMATION)
def OnAbout(self, e):
- aboutBox = aboutWindow.aboutWindow()
+ aboutBox = aboutWindow.aboutWindow(self)
aboutBox.Centre()
aboutBox.Show()
+ aboutBox.Raise()
def OnClose(self, e):
profile.saveProfile(profile.getDefaultProfilePath(), True)
#HACK: Set the paint function of the glCanvas to nothing so it won't keep refreshing. Which can keep wxWidgets from quiting.
print "Closing down"
self.scene.OnPaint = lambda e : e
- self.scene._engine.cleanup()
+ self.scene.cleanup()
self.Destroy()
def OnQuit(self, e):
self.SetSizer(wx.BoxSizer(wx.HORIZONTAL))
self.GetSizer().Add(self.nb, 1, wx.EXPAND)
- (left, right, self.printPanel) = self.CreateDynamicConfigTab(self.nb, 'Basic')
+ (left, right, self.printPanel) = self.CreateDynamicConfigTab(self.nb, _('Basic'))
self._addSettingsToPanels('basic', left, right)
self.SizeLabelWidths(left, right)
- (left, right, self.advancedPanel) = self.CreateDynamicConfigTab(self.nb, 'Advanced')
+ (left, right, self.advancedPanel) = self.CreateDynamicConfigTab(self.nb, _('Advanced'))
self._addSettingsToPanels('advanced', left, right)
self.SizeLabelWidths(left, right)
self.alterationPanel = None
else:
self.alterationPanel = alterationPanel.alterationPanel(self.nb, callback)
- self.nb.AddPage(self.alterationPanel, "Start/End-GCode")
+ self.nb.AddPage(self.alterationPanel, _("Start/End-GCode"))
self.Bind(wx.EVT_SIZE, self.OnSize)