X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=Cura%2Fgui%2FmainWindow.py;h=99c0b2d85537ed406741adf8d54e49621020d407;hb=b746cb489d71c9989f87b0441e10458de9a61b22;hp=e432b8a81533d06ac892f797ae9c8183e52d1f09;hpb=dae8f5e9813465a1a361ad1af6c4a6e661bf113b;p=cura.git diff --git a/Cura/gui/mainWindow.py b/Cura/gui/mainWindow.py index e432b8a8..99c0b2d8 100644 --- a/Cura/gui/mainWindow.py +++ b/Cura/gui/mainWindow.py @@ -14,33 +14,31 @@ from Cura.gui import configWizard from Cura.gui import firmwareInstall from Cura.gui import simpleMode from Cura.gui import sceneView +from Cura.gui import aboutWindow from Cura.gui.util import dropTarget #from Cura.gui.tools import batchRun from Cura.gui.tools import pidDebugger from Cura.gui.tools import minecraftImport -from Cura.gui.tools import youmagineGui from Cura.util import profile from Cura.util import version from Cura.util import meshLoader -from Cura.util import resources class mainWindow(wx.Frame): def __init__(self): super(mainWindow, self).__init__(None, title='Cura - ' + version.getVersion()) - self.extruderCount = int(profile.getPreference('extruder_amount')) - wx.EVT_CLOSE(self, self.OnClose) - self.SetDropTarget(dropTarget.FileDropTarget(self.OnDropFiles, meshLoader.loadSupportedExtensions())) + # allow dropping any file, restrict later + self.SetDropTarget(dropTarget.FileDropTarget(self.OnDropFiles)) self.normalModeOnlyItems = [] mruFile = os.path.join(profile.getBasePath(), 'mru_filelist.ini') - self.config = wx.FileConfig(appName="Cura", + self.config = wx.FileConfig(appName="Cura", localFilename=mruFile, style=wx.CONFIG_USE_LOCAL_FILE) - + self.ID_MRU_MODEL1, self.ID_MRU_MODEL2, self.ID_MRU_MODEL3, self.ID_MRU_MODEL4, self.ID_MRU_MODEL5, self.ID_MRU_MODEL6, self.ID_MRU_MODEL7, self.ID_MRU_MODEL8, self.ID_MRU_MODEL9, self.ID_MRU_MODEL10 = [wx.NewId() for line in xrange(10)] self.modelFileHistory = wx.FileHistory(10, self.ID_MRU_MODEL1) self.config.SetPath("/ModelMRU") @@ -53,109 +51,120 @@ class mainWindow(wx.Frame): self.menubar = wx.MenuBar() self.fileMenu = wx.Menu() - i = self.fileMenu.Append(-1, 'Load model file...\tCTRL+L') + i = self.fileMenu.Append(-1, _("Load model file...\tCTRL+L")) self.Bind(wx.EVT_MENU, lambda e: self.scene.showLoadModel(), i) - i = self.fileMenu.Append(-1, 'Save model...\tCTRL+S') + i = self.fileMenu.Append(-1, _("Save model...\tCTRL+S")) self.Bind(wx.EVT_MENU, lambda e: self.scene.showSaveModel(), i) - i = self.fileMenu.Append(-1, 'Clear platform') + i = self.fileMenu.Append(-1, _("Clear platform")) self.Bind(wx.EVT_MENU, lambda e: self.scene.OnDeleteAll(e), i) self.fileMenu.AppendSeparator() - i = self.fileMenu.Append(-1, 'Print...\tCTRL+P') + i = self.fileMenu.Append(-1, _("Print...\tCTRL+P")) self.Bind(wx.EVT_MENU, lambda e: self.scene.showPrintWindow(), i) - i = self.fileMenu.Append(-1, 'Save GCode...') + i = self.fileMenu.Append(-1, _("Save GCode...")) self.Bind(wx.EVT_MENU, lambda e: self.scene.showSaveGCode(), i) - i = self.fileMenu.Append(-1, 'Show slice engine log...') + i = self.fileMenu.Append(-1, _("Show slice engine log...")) self.Bind(wx.EVT_MENU, lambda e: self.scene._showSliceLog(), i) self.fileMenu.AppendSeparator() - i = self.fileMenu.Append(-1, 'Open Profile...') + i = self.fileMenu.Append(-1, _("Open Profile...")) self.normalModeOnlyItems.append(i) self.Bind(wx.EVT_MENU, self.OnLoadProfile, i) - i = self.fileMenu.Append(-1, 'Save Profile...') + i = self.fileMenu.Append(-1, _("Save Profile...")) self.normalModeOnlyItems.append(i) self.Bind(wx.EVT_MENU, self.OnSaveProfile, i) - i = self.fileMenu.Append(-1, 'Load Profile from GCode...') + i = self.fileMenu.Append(-1, _("Load Profile from GCode...")) self.normalModeOnlyItems.append(i) self.Bind(wx.EVT_MENU, self.OnLoadProfileFromGcode, i) self.fileMenu.AppendSeparator() - i = self.fileMenu.Append(-1, 'Reset Profile to default') + i = self.fileMenu.Append(-1, _("Reset Profile to default")) self.normalModeOnlyItems.append(i) self.Bind(wx.EVT_MENU, self.OnResetProfile, i) self.fileMenu.AppendSeparator() - i = self.fileMenu.Append(-1, 'Preferences...\tCTRL+,') + i = self.fileMenu.Append(-1, _("Preferences...\tCTRL+,")) self.Bind(wx.EVT_MENU, self.OnPreferences, i) + i = self.fileMenu.Append(-1, _("Machine settings...")) + self.Bind(wx.EVT_MENU, self.OnMachineSettings, i) self.fileMenu.AppendSeparator() # Model MRU list modelHistoryMenu = wx.Menu() - self.fileMenu.AppendMenu(wx.NewId(), "&Recent Model Files", modelHistoryMenu) + self.fileMenu.AppendMenu(wx.NewId(), '&' + _("Recent Model Files"), modelHistoryMenu) self.modelFileHistory.UseMenu(modelHistoryMenu) self.modelFileHistory.AddFilesToMenu() self.Bind(wx.EVT_MENU_RANGE, self.OnModelMRU, id=self.ID_MRU_MODEL1, id2=self.ID_MRU_MODEL10) # Profle MRU list profileHistoryMenu = wx.Menu() - self.fileMenu.AppendMenu(wx.NewId(), "&Recent Profile Files", profileHistoryMenu) + self.fileMenu.AppendMenu(wx.NewId(), _("Recent Profile Files"), profileHistoryMenu) self.profileFileHistory.UseMenu(profileHistoryMenu) self.profileFileHistory.AddFilesToMenu() self.Bind(wx.EVT_MENU_RANGE, self.OnProfileMRU, id=self.ID_MRU_PROFILE1, id2=self.ID_MRU_PROFILE10) - + self.fileMenu.AppendSeparator() - i = self.fileMenu.Append(wx.ID_EXIT, 'Quit') + i = self.fileMenu.Append(wx.ID_EXIT, _("Quit")) self.Bind(wx.EVT_MENU, self.OnQuit, i) - self.menubar.Append(self.fileMenu, '&File') + self.menubar.Append(self.fileMenu, '&' + _("File")) toolsMenu = wx.Menu() - i = toolsMenu.Append(-1, 'Switch to quickprint...') - self.switchToQuickprintMenuItem = i - self.Bind(wx.EVT_MENU, self.OnSimpleSwitch, i) - i = toolsMenu.Append(-1, 'Switch to full settings...') - self.switchToNormalMenuItem = i - self.Bind(wx.EVT_MENU, self.OnNormalSwitch, i) - toolsMenu.AppendSeparator() #i = toolsMenu.Append(-1, 'Batch run...') #self.Bind(wx.EVT_MENU, self.OnBatchRun, i) #self.normalModeOnlyItems.append(i) + if minecraftImport.hasMinecraft(): - i = toolsMenu.Append(-1, 'Minecraft import...') + i = toolsMenu.Append(-1, _("Minecraft map import...")) self.Bind(wx.EVT_MENU, self.OnMinecraftImport, i) + if version.isDevVersion(): - i = toolsMenu.Append(-1, 'PID Debugger...') + i = toolsMenu.Append(-1, _("PID Debugger...")) self.Bind(wx.EVT_MENU, self.OnPIDDebugger, i) - self.menubar.Append(toolsMenu, 'Tools') + + i = toolsMenu.Append(-1, _("Copy profile to clipboard")) + self.Bind(wx.EVT_MENU, self.onCopyProfileClipboard,i) + self.menubar.Append(toolsMenu, _("Tools")) + + #Machine menu for machine configuration/tooling + self.machineMenu = wx.Menu() + self.updateMachineMenu() + + self.menubar.Append(self.machineMenu, _("Machine")) expertMenu = wx.Menu() - i = expertMenu.Append(-1, 'Open expert settings...') + i = expertMenu.Append(-1, _("Switch to quickprint..."), kind=wx.ITEM_RADIO) + self.switchToQuickprintMenuItem = i + self.Bind(wx.EVT_MENU, self.OnSimpleSwitch, i) + + i = expertMenu.Append(-1, _("Switch to full settings..."), kind=wx.ITEM_RADIO) + self.switchToNormalMenuItem = i + self.Bind(wx.EVT_MENU, self.OnNormalSwitch, i) + expertMenu.AppendSeparator() + + i = expertMenu.Append(-1, _("Open expert settings...\tCTRL+E")) self.normalModeOnlyItems.append(i) self.Bind(wx.EVT_MENU, self.OnExpertOpen, i) expertMenu.AppendSeparator() - if firmwareInstall.getDefaultFirmware() is not None: - i = expertMenu.Append(-1, 'Install default Marlin firmware') - self.Bind(wx.EVT_MENU, self.OnDefaultMarlinFirmware, i) - i = expertMenu.Append(-1, 'Install custom firmware') - self.Bind(wx.EVT_MENU, self.OnCustomFirmware, i) - expertMenu.AppendSeparator() - i = expertMenu.Append(-1, 'Run first run wizard...') + i = expertMenu.Append(-1, _("Run first run wizard...")) self.Bind(wx.EVT_MENU, self.OnFirstRunWizard, i) - i = expertMenu.Append(-1, 'Run bed leveling wizard...') - self.Bind(wx.EVT_MENU, self.OnBedLevelWizard, i) - if self.extruderCount > 1: - i = expertMenu.Append(-1, 'Run head offset wizard...') - self.Bind(wx.EVT_MENU, self.OnHeadOffsetWizard, i) - self.menubar.Append(expertMenu, 'Expert') + 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...")) + self.Bind(wx.EVT_MENU, self.OnHeadOffsetWizard, self.headOffsetWizardMenuItem) + + self.menubar.Append(expertMenu, _("Expert")) helpMenu = wx.Menu() - i = helpMenu.Append(-1, 'Online documentation...') + i = helpMenu.Append(-1, _("Online documentation...")) self.Bind(wx.EVT_MENU, lambda e: webbrowser.open('http://daid.github.com/Cura'), i) - i = helpMenu.Append(-1, 'Report a problem...') + 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...') + i = helpMenu.Append(-1, _("Check for update...")) self.Bind(wx.EVT_MENU, self.OnCheckForUpdate, i) - i = helpMenu.Append(-1, 'About Cura...') + 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.menubar.Append(helpMenu, _("Help")) self.SetMenuBar(self.menubar) self.splitter = wx.SplitterWindow(self, style = wx.SP_3D | wx.SP_LIVE_UPDATE) @@ -167,16 +176,11 @@ class mainWindow(wx.Frame): self.simpleSettingsPanel = simpleMode.simpleModePanel(self.leftPane, lambda : self.scene.sceneUpdated()) self.normalSettingsPanel = normalSettingsPanel(self.leftPane, lambda : self.scene.sceneUpdated()) - self.youmagineButton = wx.BitmapButton(self.leftPane, -1, wx.Bitmap(resources.getPathForImage('youmagine-text.png'))) - self.youmagineButton.SetToolTipString("Share your design to YouMagine.com") - self.youmagineButton.Bind(wx.EVT_BUTTON, self.OnYouMagine) - self.leftSizer = wx.BoxSizer(wx.VERTICAL) self.leftSizer.Add(self.simpleSettingsPanel, 1) self.leftSizer.Add(self.normalSettingsPanel, 1, wx.EXPAND) - self.leftSizer.Add(self.youmagineButton, 0, wx.ALIGN_CENTER) self.leftPane.SetSizer(self.leftSizer) - + #Preview window self.scene = sceneView.SceneView(self.rightPane) @@ -192,7 +196,7 @@ class mainWindow(wx.Frame): sizer.Layout() self.sizer = sizer - self.updateProfileToControls() + self.updateProfileToAllControls() self.SetBackgroundColour(self.normalSettingsPanel.GetBackgroundColour()) @@ -203,6 +207,12 @@ class mainWindow(wx.Frame): self.SetSize((wx.Display().GetClientArea().GetWidth()/2,wx.Display().GetClientArea().GetHeight()/2)) self.Centre() + #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.lastTriedClipboard = profile.getProfileString() + # Restore the window position, size & state from the preferences file try: if profile.getPreference('window_maximized') == 'True': @@ -216,7 +226,7 @@ class mainWindow(wx.Frame): self.SetPosition((posx,posy)) if width > 0 and height > 0: self.SetSize((width,height)) - + self.normalSashPos = int(profile.getPreference('window_normal_sash')) except: self.normalSashPos = 0 @@ -235,6 +245,34 @@ class mainWindow(wx.Frame): self.Centre() self.updateSliceMode() + self.scene.SetFocus() + + def onTimer(self, e): + #Check if there is something in the clipboard + profileString = "" + try: + if not wx.TheClipboard.IsOpened(): + if not wx.TheClipboard.Open(): + return + do = wx.TextDataObject() + if wx.TheClipboard.GetData(do): + profileString = do.GetText() + wx.TheClipboard.Close() + + startTag = "CURA_PROFILE_STRING:" + if startTag in profileString: + #print "Found correct syntax on clipboard" + profileString = profileString.replace("\n","").strip() + profileString = profileString[profileString.find(startTag)+len(startTag):] + if profileString != self.lastTriedClipboard: + print profileString + self.lastTriedClipboard = profileString + profile.setProfileFromString(profileString) + self.scene.notification.message("Loaded new profile from clipboard.") + self.updateProfileToAllControls() + except: + print "Unable to read from clipboard" + def updateSliceMode(self): isSimple = profile.getPreference('startMode') == 'Simple' @@ -245,37 +283,52 @@ class mainWindow(wx.Frame): for i in self.normalModeOnlyItems: i.Enable(not isSimple) - self.switchToQuickprintMenuItem.Enable(not isSimple) - self.switchToNormalMenuItem.Enable(isSimple) + if isSimple: + self.switchToQuickprintMenuItem.Check() + else: + self.switchToNormalMenuItem.Check() # Set splitter sash position & size if isSimple: # Save normal mode sash self.normalSashPos = self.splitter.GetSashPosition() - - # Change location of sash to width of quick mode pane - (width, height) = self.simpleSettingsPanel.GetSizer().GetSize() - (width, height) = self.youmagineButton.GetSize() + + # Change location of sash to width of quick mode pane + (width, height) = self.simpleSettingsPanel.GetSizer().GetSize() self.splitter.SetSashPosition(width, True) - + # Disable sash self.splitter.SetSashSize(0) else: 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': + self.bedLevelWizardMenuItem.Enable(False) + self.headOffsetWizardMenuItem.Enable(False) + if int(profile.getMachineSetting('extruder_amount')) < 2: + self.headOffsetWizardMenuItem.Enable(False) self.scene.updateProfileToControls() def OnPreferences(self, e): prefDialog = preferencesDialog.preferencesDialog(self) prefDialog.Centre() prefDialog.Show() + prefDialog.Raise() + wx.CallAfter(prefDialog.Show) + + def OnMachineSettings(self, e): + prefDialog = preferencesDialog.machineSettingsDialog(self) + prefDialog.Centre() + prefDialog.Show() + prefDialog.Raise() def OnDropFiles(self, files): if len(files) > 0: profile.setPluginConfig([]) - self.updateProfileToControls() - self.scene.loadScene(files) + self.updateProfileToAllControls() + self.scene.loadFiles(files) def OnModelMRU(self, e): fileNum = e.GetId() - self.ID_MRU_MODEL1 @@ -288,14 +341,14 @@ class mainWindow(wx.Frame): # Load Model profile.putPreference('lastFile', path) filelist = [ path ] - self.scene.loadScene(filelist) + self.scene.loadFiles(filelist) def addToModelMRU(self, file): self.modelFileHistory.AddFileToHistory(file) self.config.SetPath("/ModelMRU") self.modelFileHistory.Save(self.config) self.config.Flush() - + def OnProfileMRU(self, e): fileNum = e.GetId() - self.ID_MRU_PROFILE1 path = self.profileFileHistory.GetHistoryFile(fileNum) @@ -304,35 +357,73 @@ class mainWindow(wx.Frame): self.config.SetPath("/ProfileMRU") self.profileFileHistory.Save(self.config) self.config.Flush() - # Load Profile + # Load Profile profile.loadProfile(path) - self.updateProfileToControls() + self.updateProfileToAllControls() def addToProfileMRU(self, file): self.profileFileHistory.AddFileToHistory(file) self.config.SetPath("/ProfileMRU") self.profileFileHistory.Save(self.config) - self.config.Flush() + self.config.Flush() - def updateProfileToControls(self): + def updateProfileToAllControls(self): self.scene.updateProfileToControls() self.normalSettingsPanel.updateProfileToControls() self.simpleSettingsPanel.updateProfileToControls() + def reloadSettingPanels(self): + self.leftSizer.Detach(self.simpleSettingsPanel) + self.leftSizer.Detach(self.normalSettingsPanel) + self.simpleSettingsPanel.Destroy() + self.normalSettingsPanel.Destroy() + self.simpleSettingsPanel = simpleMode.simpleModePanel(self.leftPane, lambda : self.scene.sceneUpdated()) + 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.updateProfileToAllControls() + + def updateMachineMenu(self): + #Remove all items so we can rebuild the menu. Inserting items seems to cause crashes, so this is the safest way. + for item in self.machineMenu.GetMenuItems(): + self.machineMenu.RemoveItem(item) + + #Add a menu item for each machine configuration. + for n in xrange(0, profile.getMachineCount()): + i = self.machineMenu.Append(n + 0x1000, profile.getMachineSetting('machine_name', n).title(), kind=wx.ITEM_RADIO) + if n == int(profile.getPreferenceFloat('active_machine')): + i.Check(True) + self.Bind(wx.EVT_MENU, lambda e: self.OnSelectMachine(e.GetId() - 0x1000), i) + + self.machineMenu.AppendSeparator() + + i = self.machineMenu.Append(-1, _("Machine settings...")) + self.Bind(wx.EVT_MENU, self.OnMachineSettings, i) + + #Add tools for machines. + self.machineMenu.AppendSeparator() + + self.defaultFirmwareInstallMenuItem = self.machineMenu.Append(-1, _("Install default firmware...")) + self.Bind(wx.EVT_MENU, self.OnDefaultMarlinFirmware, self.defaultFirmwareInstallMenuItem) + + i = self.machineMenu.Append(-1, _("Install custom firmware...")) + self.Bind(wx.EVT_MENU, self.OnCustomFirmware, i) + def OnLoadProfile(self, e): - dlg=wx.FileDialog(self, "Select profile file to load", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST) + dlg=wx.FileDialog(self, _("Select profile file to load"), os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST) dlg.SetWildcard("ini files (*.ini)|*.ini") if dlg.ShowModal() == wx.ID_OK: profileFile = dlg.GetPath() profile.loadProfile(profileFile) - self.updateProfileToControls() + self.updateProfileToAllControls() # Update the Profile MRU self.addToProfileMRU(profileFile) dlg.Destroy() def OnLoadProfileFromGcode(self, e): - dlg=wx.FileDialog(self, "Select gcode file to load profile from", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST) + dlg=wx.FileDialog(self, _("Select gcode file to load profile from"), os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST) dlg.SetWildcard("gcode files (*.gcode)|*.gcode;*.g") if dlg.ShowModal() == wx.ID_OK: gcodeFile = dlg.GetPath() @@ -340,16 +431,16 @@ class mainWindow(wx.Frame): hasProfile = False for line in f: if line.startswith(';CURA_PROFILE_STRING:'): - profile.loadProfileFromString(line[line.find(':')+1:].strip()) + profile.setProfileFromString(line[line.find(':')+1:].strip()) hasProfile = True if hasProfile: - self.updateProfileToControls() + self.updateProfileToAllControls() else: - wx.MessageBox('No profile found in GCode file.\nThis feature only works with GCode files made by Cura 12.07 or newer.', 'Profile load error', wx.OK | wx.ICON_INFORMATION) + wx.MessageBox(_("No profile found in GCode file.\nThis feature only works with GCode files made by Cura 12.07 or newer."), _("Profile load error"), wx.OK | wx.ICON_INFORMATION) dlg.Destroy() def OnSaveProfile(self, e): - dlg=wx.FileDialog(self, "Select profile file to save", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_SAVE) + 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() @@ -357,12 +448,12 @@ class mainWindow(wx.Frame): dlg.Destroy() def OnResetProfile(self, e): - dlg = wx.MessageDialog(self, 'This will reset all profile settings to defaults.\nUnless you have saved your current profile, all settings will be lost!\nDo you really want to reset?', 'Profile reset', wx.YES_NO | wx.ICON_QUESTION) + dlg = wx.MessageDialog(self, _("This will reset all profile settings to defaults.\nUnless you have saved your current profile, all settings will be lost!\nDo you really want to reset?"), _("Profile reset"), wx.YES_NO | wx.ICON_QUESTION) result = dlg.ShowModal() == wx.ID_YES dlg.Destroy() if result: profile.resetProfile() - self.updateProfileToControls() + self.updateProfileToAllControls() def OnSimpleSwitch(self, e): profile.putPreference('startMode', 'Simple') @@ -376,9 +467,9 @@ class mainWindow(wx.Frame): firmwareInstall.InstallFirmware() def OnCustomFirmware(self, e): - if profile.getPreference('machine_type') == 'ultimaker': - wx.MessageBox('Warning: Installing a custom firmware does not guarantee that you machine will function correctly, and could damage your machine.', 'Firmware update', wx.OK | wx.ICON_EXCLAMATION) - dlg=wx.FileDialog(self, "Open firmware to upload", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST) + if profile.getMachineSetting('machine_type').startswith('ultimaker'): + wx.MessageBox(_("Warning: Installing a custom firmware does not guarantee that you machine will function correctly, and could damage your machine."), _("Firmware update"), wx.OK | wx.ICON_EXCLAMATION) + 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() @@ -388,8 +479,14 @@ class mainWindow(wx.Frame): firmwareInstall.InstallFirmware(filename) def OnFirstRunWizard(self, e): + self.Hide() configWizard.configWizard() - self.updateProfileToControls() + self.Show() + self.reloadSettingPanels() + + def OnSelectMachine(self, index): + profile.setActiveMachine(index) + self.reloadSettingPanels() def OnBedLevelWizard(self, e): configWizard.bedLevelWizard() @@ -412,41 +509,31 @@ class mainWindow(wx.Frame): debugger.Centre() debugger.Show(True) - def OnYouMagine(self, e): - if len(self.scene._scene.objects()) < 1: - wx.MessageBox('You cannot upload to YouMagine without have a file loaded.', 'Cura', wx.OK | wx.ICON_ERROR) - return - youmagineGui.youmagineManager(self, self.scene._scene) + def onCopyProfileClipboard(self, e): + try: + if not wx.TheClipboard.IsOpened(): + wx.TheClipboard.Open() + clipData = wx.TextDataObject() + self.lastTriedClipboard = profile.getProfileString() + profileString = profile.insertNewlines("CURA_PROFILE_STRING:" + self.lastTriedClipboard) + clipData.SetText(profileString) + wx.TheClipboard.SetData(clipData) + wx.TheClipboard.Close() + except: + print "Could not write to clipboard, unable to get ownership. Another program is using the clipboard." def OnCheckForUpdate(self, e): newVersion = version.checkForNewerVersion() if newVersion is not None: - if wx.MessageBox('A new version of Cura is available, would you like to download?', 'New version available', wx.YES_NO | wx.ICON_INFORMATION) == wx.YES: + if wx.MessageBox(_("A new version of Cura is available, would you like to download?"), _("New version available"), wx.YES_NO | wx.ICON_INFORMATION) == wx.YES: webbrowser.open(newVersion) else: - wx.MessageBox('You are running the latest version of Cura!', 'Awesome!', wx.ICON_INFORMATION) + wx.MessageBox(_("You are running the latest version of Cura!"), _("Awesome!"), wx.ICON_INFORMATION) def OnAbout(self, e): - info = wx.AboutDialogInfo() - info.SetName('Cura') - info.SetDescription('End solution for Open Source Fused Filament Fabrication 3D printing.') - info.SetWebSite('http://software.ultimaker.com/') - info.SetCopyright('Copyright (C) David Braam') - info.SetLicence(""" - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . -""") - wx.AboutBox(info) + aboutBox = aboutWindow.aboutWindow() + aboutBox.Centre() + aboutBox.Show() def OnClose(self, e): profile.saveProfile(profile.getDefaultProfilePath()) @@ -459,15 +546,15 @@ class mainWindow(wx.Frame): profile.putPreference('window_pos_y', posy) (width, height) = self.GetSize() profile.putPreference('window_width', width) - profile.putPreference('window_height', height) - + profile.putPreference('window_height', height) + # Save normal sash position. If in normal mode (!simple mode), get last position of sash before saving it... isSimple = profile.getPreference('startMode') == 'Simple' if not isSimple: self.normalSashPos = self.splitter.GetSashPosition() profile.putPreference('window_normal_sash', self.normalSashPos) - #HACK: Set the paint function of the glCanvas to nothing so it won't keep refreshing. Which keeps wxWidgets from quiting. + #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._slicer.cleanup() @@ -489,21 +576,21 @@ class normalSettingsPanel(configBase.configPanelBase): (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') self._addSettingsToPanels('advanced', left, right) self.SizeLabelWidths(left, right) #Plugin page self.pluginPanel = pluginPanel.pluginPanel(self.nb, callback) - if len(self.pluginPanel.pluginList) > 0: - self.nb.AddPage(self.pluginPanel, "Plugins") - else: - self.pluginPanel.Show(False) + self.nb.AddPage(self.pluginPanel, _("Plugins")) #Alteration page - self.alterationPanel = alterationPanel.alterationPanel(self.nb, callback) - self.nb.AddPage(self.alterationPanel, "Start/End-GCode") + if profile.getMachineSetting('gcode_flavor') == 'UltiGCode': + self.alterationPanel = None + else: + self.alterationPanel = alterationPanel.alterationPanel(self.nb, callback) + self.nb.AddPage(self.alterationPanel, "Start/End-GCode") self.Bind(wx.EVT_SIZE, self.OnSize) @@ -520,10 +607,9 @@ class normalSettingsPanel(configBase.configPanelBase): n += 1 + len(profile.getSettingsForCategory(category, title)) if n > count / 2: p = right - configBase.TitleRow(p, title) + configBase.TitleRow(p, _(title)) for s in profile.getSettingsForCategory(category, title): - if s.checkConditions(): - configBase.SettingRow(p, s.getName()) + configBase.SettingRow(p, s.getName()) def SizeLabelWidths(self, left, right): leftWidth = self.getLabelColumnWidth(left) @@ -535,17 +621,17 @@ class normalSettingsPanel(configBase.configPanelBase): def OnSize(self, e): # Make the size of the Notebook control the same size as this control self.nb.SetSize(self.GetSize()) - + # Propegate the OnSize() event (just in case) e.Skip() - + # Perform out resize magic self.UpdateSize(self.printPanel) self.UpdateSize(self.advancedPanel) - + def UpdateSize(self, configPanel): sizer = configPanel.GetSizer() - + # Pseudocde # if horizontal: # if width(col1) < best_width(col1) || width(col2) < best_width(col2): @@ -554,7 +640,7 @@ class normalSettingsPanel(configBase.configPanelBase): # if width(col1) > (best_width(col1) + best_width(col1)): # switch to horizontal # - + col1 = configPanel.leftPanel colSize1 = col1.GetSize() colBestSize1 = col1.GetBestSize() @@ -563,7 +649,7 @@ class normalSettingsPanel(configBase.configPanelBase): colBestSize2 = col2.GetBestSize() orientation = sizer.GetOrientation() - + if orientation == wx.HORIZONTAL: if (colSize1[0] <= colBestSize1[0]) or (colSize2[0] <= colBestSize2[0]): configPanel.Freeze() @@ -589,5 +675,6 @@ class normalSettingsPanel(configBase.configPanelBase): def updateProfileToControls(self): super(normalSettingsPanel, self).updateProfileToControls() - self.alterationPanel.updateProfileToControls() + if self.alterationPanel is not None: + self.alterationPanel.updateProfileToControls() self.pluginPanel.updateProfileToControls()