diff -r c82943fb205f -r cce0af6351f0 printrun-src/printrun/spoolmanager/spoolmanager_gui.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/printrun-src/printrun/spoolmanager/spoolmanager_gui.py Wed Jan 20 10:15:13 2021 +0100
@@ -0,0 +1,639 @@
+# This file is part of the Printrun suite.
+#
+# Printrun is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Printrun 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Printrun. If not, see .
+#
+# Copyright 2017 Rock Storm
+
+import wx
+from . import spoolmanager
+
+class SpoolManagerMainWindow(wx.Frame):
+ """
+ Front-end for the Spool Manager.
+
+ Main window which displays the currently loaded spools and the list of
+ recorded ones with buttons to add, load, edit or delete them.
+ """
+
+ def __init__(self, parent, spool_manager):
+ wx.Frame.__init__(self, parent,
+ title = "Spool Manager",
+ style = wx.DEFAULT_FRAME_STYLE | wx.FRAME_FLOAT_ON_PARENT)
+
+ self.statusbar = self.CreateStatusBar()
+
+ self.SetIcon(parent.GetIcon())
+
+ # Initiate the back-end
+ self.spool_manager = spool_manager
+ self.spool_manager.refresh()
+
+ # Generate the dialogs showing the current spools
+ self.current_spools_dialog = CurrentSpoolDialog(self,
+ self.spool_manager)
+
+ # Generate the list of recorded spools
+ self.spool_list = SpoolListView(self, self.spool_manager)
+
+ # Generate the buttons
+ self.new_button = wx.Button(self, wx.ID_ADD)
+ self.new_button.SetToolTip("Add a new spool")
+ self.edit_button = wx.Button(self, wx.ID_EDIT)
+ self.edit_button.SetToolTip("Edit the selected spool")
+ self.delete_button = wx.Button(self, wx.ID_DELETE)
+ self.delete_button.SetToolTip("Delete the selected spool")
+
+ # "Program" the buttons
+ self.new_button.Bind(wx.EVT_BUTTON, self.onClickAdd)
+ self.edit_button.Bind(wx.EVT_BUTTON, self.onClickEdit)
+ self.delete_button.Bind(wx.EVT_BUTTON, self.onClickDelete)
+
+ # Layout
+ ## Group the buttons
+ self.button_sizer = wx.BoxSizer(wx.VERTICAL)
+ self.button_sizer.Add(self.new_button, 1,
+ wx.FIXED_MINSIZE | wx.ALIGN_CENTER)
+ self.button_sizer.Add(self.edit_button, 1,
+ wx.FIXED_MINSIZE | wx.ALIGN_CENTER)
+ self.button_sizer.Add(self.delete_button, 1,
+ wx.FIXED_MINSIZE | wx.ALIGN_CENTER)
+
+ ## Group the buttons with the spool list
+ self.list_sizer = wx.BoxSizer(wx.HORIZONTAL)
+ self.list_sizer.Add(self.spool_list, 1, wx.EXPAND)
+ self.list_sizer.Add(self.button_sizer, 0, wx.ALIGN_CENTER)
+
+ ## Layout the whole thing
+ self.full_sizer = wx.BoxSizer(wx.VERTICAL)
+ self.full_sizer.Add(self.current_spools_dialog, 0, wx.EXPAND)
+ self.full_sizer.Add(self.list_sizer, 1, wx.ALL | wx.EXPAND, 10)
+
+ self.SetSizerAndFit(self.full_sizer)
+
+ def onClickAdd(self, event):
+ """Open the window for customizing the new spool."""
+ SpoolManagerAddWindow(self).Show(True)
+
+ def onClickLoad(self, event, extruder):
+ """Load the selected spool to the correspondent extruder."""
+
+ # Check whether there is a spool selected
+ spool_index = self.spool_list.GetFirstSelected()
+ if spool_index == -1 :
+ self.statusbar.SetStatusText(
+ "Could not load the spool. No spool selected.")
+ return 0
+ else:
+ spool_name = self.spool_list.GetItemText(spool_index)
+ self.statusbar.SetStatusText("")
+
+ # If selected spool is already loaded, do nothing
+ spool_extruder = self.spool_manager.isLoaded(spool_name)
+ if spool_extruder > -1:
+ self.statusbar.SetStatusText(
+ "Spool '%s' is already loaded for Extruder %d." %
+ (spool_name, spool_extruder))
+ return 0
+
+ # Load the selected spool and refresh the current spools dialog
+ self.spool_manager.load(spool_name, extruder)
+ self.current_spools_dialog.refreshDialog(self.spool_manager)
+ self.statusbar.SetStatusText(
+ "Loaded spool '%s' for Extruder %d." % (spool_name, extruder))
+
+ def onClickUnload(self, event, extruder):
+ """Unload the spool from the correspondent extruder."""
+
+ spool_name = self.spool_manager.getSpoolName(extruder)
+ if spool_name != None:
+ self.spool_manager.unload(extruder)
+ self.current_spools_dialog.refreshDialog(self.spool_manager)
+ self.statusbar.SetStatusText(
+ "Unloaded spool from Extruder %d." % extruder)
+ else:
+ self.statusbar.SetStatusText(
+ "There is no spool loaded for Extruder %d." % extruder)
+
+ def onClickEdit(self, event):
+ """Open the window for editing the data of the selected spool."""
+
+ # Check whether there is a spool selected
+ spool_index = self.spool_list.GetFirstSelected()
+ if spool_index == -1 :
+ self.statusbar.SetStatusText(
+ "Could not edit the spool. No spool selected.")
+ return 0
+
+ # Open the edit window
+ spool_name = self.spool_list.GetItemText(spool_index)
+ spool_length = self.spool_list.GetItemText(spool_index, 1)
+ SpoolManagerEditWindow(self, spool_name, spool_length).Show(True)
+ self.statusbar.SetStatusText("")
+
+ def onClickDelete(self, event):
+ """Delete the selected spool."""
+
+ # Get the selected spool
+ spool_index = self.spool_list.GetFirstSelected()
+ if spool_index == -1 :
+ self.statusbar.SetStatusText(
+ "Could not delete the spool. No spool selected.")
+ return 0
+ else:
+ spool_name = self.spool_list.GetItemText(spool_index)
+ self.statusbar.SetStatusText("")
+
+ # Ask confirmation for deleting
+ delete_dialog = wx.MessageDialog(self,
+ message = "Are you sure you want to delete the '%s' spool" %
+ spool_name,
+ caption = "Delete Spool",
+ style = wx.YES_NO | wx.ICON_EXCLAMATION)
+
+ if delete_dialog.ShowModal() == wx.ID_YES:
+ # Remove spool
+ self.spool_manager.remove(spool_name)
+ self.spool_list.refreshList(self.spool_manager)
+ self.current_spools_dialog.refreshDialog(self.spool_manager)
+ self.statusbar.SetStatusText(
+ "Deleted spool '%s'." % spool_name)
+
+
+class SpoolListView(wx.ListView):
+ """
+ Custom wxListView object which visualizes the list of available spools.
+ """
+
+ def __init__(self, parent, spool_manager):
+ wx.ListView.__init__(self, parent,
+ style = wx.LC_REPORT | wx.LC_SINGLE_SEL)
+ self.InsertColumn(0, "Spool", width = wx.LIST_AUTOSIZE_USEHEADER)
+ self.InsertColumn(1, "Filament", width = wx.LIST_AUTOSIZE_USEHEADER)
+ self.populateList(spool_manager)
+
+ # "Program" the layout
+ self.Bind(wx.EVT_SIZE, self.onResizeList)
+
+ def populateList(self, spool_manager):
+ """Get the list of recorded spools from the Spool Manager."""
+ spool_list = spool_manager.getSpoolList()
+ for i in range(len(spool_list)):
+ self.Append(spool_list[i])
+
+ def refreshList(self, spool_manager):
+ """Refresh the list by re-reading the Spool Manager list."""
+ self.DeleteAllItems()
+ self.populateList(spool_manager)
+
+ def onResizeList(self, event):
+ list_size = self.GetSize()
+ self.SetColumnWidth(1, -2)
+ filament_column_width = self.GetColumnWidth(1)
+ self.SetColumnWidth(col = 0,
+ width = list_size.width - filament_column_width)
+ event.Skip()
+
+
+class CurrentSpoolDialog(wx.Panel):
+ """
+ Custom wxStaticText object to display the currently loaded spools and
+ their remaining filament.
+ """
+
+ def __init__(self, parent, spool_manager):
+ wx.Panel.__init__(self, parent)
+ self.parent = parent
+ self.extruders = spool_manager.getExtruderCount()
+
+ full_sizer = wx.BoxSizer(wx.VERTICAL)
+
+ # Calculate the minimum size needed to properly display the
+ # extruder information
+ min_size = self.GetTextExtent(" Remaining filament: 0000000.00")
+
+ # Generate a dialog for every extruder
+ self.extruder_dialog = []
+ load_button = []
+ unload_button = []
+ button_sizer = []
+ dialog_sizer = []
+ for i in range(self.extruders):
+ # Generate the dialog with the spool information
+ self.extruder_dialog.append(
+ wx.StaticText(self, style = wx.ST_ELLIPSIZE_END))
+ self.extruder_dialog[i].SetMinSize(wx.Size(min_size.width, -1))
+
+ # Generate the "load" and "unload" buttons
+ load_button.append(wx.Button(self, label = "Load"))
+ load_button[i].SetToolTip(
+ "Load selected spool for Extruder %d" % i)
+ unload_button.append(wx.Button(self, label = "Unload"))
+ unload_button[i].SetToolTip(
+ "Unload the spool for Extruder %d" % i)
+
+ # "Program" the buttons
+ load_button[i].Bind(wx.EVT_BUTTON,
+ lambda event, extruder=i: parent.onClickLoad(event, extruder))
+ unload_button[i].Bind(wx.EVT_BUTTON,
+ lambda event, extruder=i: parent.onClickUnload(event, extruder))
+
+ # Layout
+ button_sizer.append(wx.BoxSizer(wx.VERTICAL))
+ button_sizer[i].Add(load_button[i], 0,
+ wx.FIXED_MINSIZE | wx.ALIGN_CENTER)
+ button_sizer[i].Add(unload_button[i], 0,
+ wx.FIXED_MINSIZE | wx.ALIGN_CENTER)
+
+ dialog_sizer.append(wx.BoxSizer(wx.HORIZONTAL))
+ dialog_sizer[i].Add(self.extruder_dialog[i], 1, wx.ALIGN_CENTER)
+ dialog_sizer[i].AddSpacer(10)
+ dialog_sizer[i].Add(button_sizer[i], 0, wx.EXPAND)
+
+ full_sizer.Add(dialog_sizer[i], 0, wx.ALL | wx.EXPAND, 10)
+
+ self.refreshDialog(spool_manager)
+
+ self.SetSizerAndFit(full_sizer)
+
+
+ def refreshDialog(self, spool_manager):
+ """Retrieve the current spools from the Spool Manager."""
+
+ for i in range(self.extruders):
+ spool_name = spool_manager.getSpoolName(i)
+ spool_filament = spool_manager.getRemainingFilament(i)
+ label = ("Spool for Extruder %d:\n" % i +
+ " Name: %s\n" % spool_name +
+ " Remaining filament: %.2f" % spool_filament)
+ self.extruder_dialog[i].SetLabelText(label)
+
+
+# ---------------------------------------------------------------------------
+def checkOverwrite(parent, spool_name):
+ """Ask the user whether or not to overwrite the existing spool."""
+
+ overwrite_dialog = wx.MessageDialog(parent,
+ message = "A spool with the name '%s'' already exists." %
+ spool_name +
+ "Do you wish to overwrite it?",
+ caption = "Overwrite",
+ style = wx.YES_NO | wx.ICON_EXCLAMATION)
+
+ if overwrite_dialog.ShowModal() == wx.ID_YES:
+ return True
+ else:
+ return False
+
+def getFloat(parent, number):
+ """
+ Check whether the input number is a float. Either return the number or
+ return False.
+ """
+ try:
+ return float(number)
+ except ValueError:
+ parent.statusbar.SetStatusText("Unrecognized number: %s" % number)
+ return False
+
+
+# ---------------------------------------------------------------------------
+class SpoolManagerAddWindow(wx.Frame):
+ """Window for adding spools."""
+
+ def __init__(self, parent):
+
+ wx.Frame.__init__(self, parent,
+ title = "Add Spool",
+ style = wx.DEFAULT_FRAME_STYLE | wx.FRAME_FLOAT_ON_PARENT)
+
+ self.statusbar = self.CreateStatusBar()
+
+ self.parent = parent
+
+ self.SetIcon(parent.GetIcon())
+
+ # Generate the dialogs
+ self.name_dialog = LabeledTextCtrl(self,
+ "Name", "Default Spool", "")
+ self.diameter_dialog = LabeledTextCtrl(self,
+ "Diameter", "1.75", "mm")
+ self.diameter_dialog.SetToolTip(
+ "Typically, either 1.75 mm or 2.85 mm (a.k.a '3')")
+ self.weight_dialog = LabeledTextCtrl(self,
+ "Weight", "1", "Kg")
+ self.density_dialog = LabeledTextCtrl(self,
+ "Density", "1.25", "g/cm^3")
+ self.density_dialog.SetToolTip(
+ "Typical densities are 1.25 g/cm^3 for PLA and 1.08 g/cm^3 for" +
+ " ABS")
+ self.length_dialog = LabeledTextCtrl(self,
+ "Length", "332601.35", "mm")
+
+ # "Program" the dialogs
+ self.diameter_dialog.Bind(wx.EVT_TEXT, self.calculateLength)
+ self.weight_dialog.Bind(wx.EVT_TEXT, self.calculateLength)
+ self.density_dialog.Bind(wx.EVT_TEXT, self.calculateLength)
+ self.length_dialog.Bind(wx.EVT_TEXT, self.calculateWeight)
+
+ # Generate the bottom buttons
+ self.add_button = wx.Button(self, wx.ID_ADD)
+ self.cancel_button = wx.Button(self, wx.ID_CANCEL)
+
+ # "Program" the bottom buttons
+ self.add_button.Bind(wx.EVT_BUTTON, self.onClickAdd)
+ self.cancel_button.Bind(wx.EVT_BUTTON, self.onClickCancel)
+
+ # Layout
+ ## Group the bottom buttons
+ self.bottom_buttons_sizer = wx.BoxSizer(wx.HORIZONTAL)
+ self.bottom_buttons_sizer.Add(self.add_button, 0, wx.FIXED_MINSIZE)
+ self.bottom_buttons_sizer.Add(self.cancel_button, 0, wx.FIXED_MINSIZE)
+
+ ## Group the whole window
+ self.full_sizer = wx.BoxSizer(wx.VERTICAL)
+ self.full_sizer.Add(self.name_dialog, 0,
+ wx.TOP | wx.BOTTOM | wx.EXPAND, 10)
+ self.full_sizer.Add(self.diameter_dialog, 0, wx.EXPAND)
+ self.full_sizer.Add(self.weight_dialog, 0, wx.EXPAND)
+ self.full_sizer.Add(self.density_dialog, 0, wx.EXPAND)
+ self.full_sizer.Add(self.length_dialog, 0, wx.EXPAND)
+ self.full_sizer.Add(self.bottom_buttons_sizer, 0,
+ wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 10)
+
+ self.SetSizerAndFit(self.full_sizer)
+
+ # Don't allow this window to be resized in height
+ add_window_size = self.GetSize()
+ self.SetMaxSize((-1, add_window_size.height))
+
+ def onClickAdd(self, event):
+ """Add the new spool and close the window."""
+
+ spool_name = self.name_dialog.field.GetValue()
+ spool_length = getFloat(self, self.length_dialog.field.GetValue())
+
+ # Check whether the length is actually a number
+ if not spool_length:
+ self.statusbar.SetStatusText(
+ "ERROR: Unrecognized length: %s." %
+ self.length_dialog.field.GetValue())
+ return -1
+
+ # The remaining filament should always be a positive number
+ if not spool_length > 0:
+ self.statusbar.SetStatusText(
+ "ERROR: Length is zero or negative: %.2f." % spool_length)
+ return -1
+
+ # Check whether the name is already used. If it is used, prompt the
+ # user before overwriting it
+ if self.parent.spool_manager.isListed(spool_name):
+ if checkOverwrite(self, spool_name):
+ # Remove the "will be overwritten" spool
+ self.parent.spool_manager.remove(spool_name)
+ else:
+ return 0
+
+ # Add the new spool
+ self.parent.spool_manager.add(spool_name, spool_length)
+ self.parent.spool_list.refreshList(self.parent.spool_manager)
+ self.parent.current_spools_dialog.refreshDialog(
+ self.parent.spool_manager)
+ self.parent.statusbar.SetStatusText(
+ "Added new spool '%s'" % spool_name +
+ " with %.2f mm of remaining filament." % spool_length)
+
+ self.Close(True)
+
+ def onClickCancel(self, event):
+ """Do nothing and close the window."""
+ self.Close(True)
+ self.parent.statusbar.SetStatusText("")
+
+ def calculateLength(self, event):
+ """
+ Calculate the length of the filament given the mass, diameter and
+ density of the filament. Set the 'Length' field to this quantity.
+ """
+
+ mass = getFloat(self, self.weight_dialog.field.GetValue())
+ diameter = getFloat(self, self.diameter_dialog.field.GetValue())
+ density = getFloat(self, self.density_dialog.field.GetValue())
+ if mass and diameter and density:
+ pi = 3.14159265359
+ length = 4e6 * mass / pi / diameter**2 / density
+ self.length_dialog.field.ChangeValue("%.2f" % length)
+ self.statusbar.SetStatusText("")
+ else:
+ self.length_dialog.field.ChangeValue("---")
+
+ def calculateWeight(self, event):
+ """
+ Calculate the weight of the filament given the length, diameter and
+ density of the filament. Set the 'Weight' field to this value.
+ """
+
+ length = getFloat(self, self.length_dialog.field.GetValue())
+ diameter = getFloat(self, self.diameter_dialog.field.GetValue())
+ density = getFloat(self, self.density_dialog.field.GetValue())
+ if length and diameter and density:
+ pi = 3.14159265359
+ mass = length * pi * diameter**2 * density / 4e6
+ self.weight_dialog.field.ChangeValue("%.2f" % mass)
+ self.statusbar.SetStatusText("")
+ else:
+ self.weight_dialog.field.ChangeValue("---")
+
+
+class LabeledTextCtrl(wx.Panel):
+ """
+ Group together a wxTextCtrl with a preceding and a subsequent wxStaticText.
+ """
+
+ def __init__(self, parent, preceding_text, field_value, subsequent_text):
+ wx.Panel.__init__(self, parent)
+ self.pretext = wx.StaticText(self, label = preceding_text,
+ style = wx.ALIGN_RIGHT)
+ self.field = wx.TextCtrl(self, value = field_value)
+ self.subtext = wx.StaticText(self, label = subsequent_text)
+
+ # Layout the panel
+ self.sizer = wx.BoxSizer(wx.HORIZONTAL)
+ self.sizer.Add(self.pretext, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 10)
+ self.sizer.SetItemMinSize(self.pretext, (80, -1))
+ self.sizer.Add(self.field, 1, wx.EXPAND)
+ self.sizer.Add(self.subtext, 0, wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 10)
+ self.sizer.SetItemMinSize(self.subtext, (50, -1))
+
+ self.SetSizerAndFit(self.sizer)
+
+
+# ---------------------------------------------------------------------------
+class SpoolManagerEditWindow(wx.Frame):
+ """Window for editing the name or the length of a spool."""
+
+ def __init__(self, parent, spool_name, spool_length):
+
+ wx.Frame.__init__(self, parent,
+ title = "Edit Spool",
+ style = wx.DEFAULT_FRAME_STYLE | wx.FRAME_FLOAT_ON_PARENT)
+
+ self.statusbar = self.CreateStatusBar()
+
+ self.parent = parent
+
+ self.SetIcon(parent.GetIcon())
+
+ self.old_spool_name = spool_name
+ self.old_spool_length = getFloat(self, spool_length)
+
+ # Set how many millimeters will the buttons add or subtract
+ self.quantities = [-100.0, -50.0, -10.0, 10.0, 50.0, 100.0]
+
+ # Generate the name field
+ self.name_field = LabeledTextCtrl(self,
+ "Name", self.old_spool_name, "")
+
+ # Generate the length field and buttons
+ self.length_title = wx.StaticText(self, label = "Remaining filament:")
+ self.minus3_button = wx.Button(self,
+ label = str(self.quantities[0]), style = wx.BU_EXACTFIT)
+ self.minus2_button = wx.Button(self,
+ label = str(self.quantities[1]), style = wx.BU_EXACTFIT)
+ self.minus1_button = wx.Button(self,
+ label = str(self.quantities[2]), style = wx.BU_EXACTFIT)
+ self.length_field = wx.TextCtrl(self,
+ value = str(self.old_spool_length))
+ self.plus1_button = wx.Button(self,
+ label = "+" + str(self.quantities[3]), style = wx.BU_EXACTFIT)
+ self.plus2_button = wx.Button(self,
+ label = "+" + str(self.quantities[4]), style = wx.BU_EXACTFIT)
+ self.plus3_button = wx.Button(self,
+ label = "+" + str(self.quantities[5]), style = wx.BU_EXACTFIT)
+
+ # "Program" the length buttons
+ self.minus3_button.Bind(wx.EVT_BUTTON, self.changeLength)
+ self.minus2_button.Bind(wx.EVT_BUTTON, self.changeLength)
+ self.minus1_button.Bind(wx.EVT_BUTTON, self.changeLength)
+ self.plus1_button.Bind(wx.EVT_BUTTON, self.changeLength)
+ self.plus2_button.Bind(wx.EVT_BUTTON, self.changeLength)
+ self.plus3_button.Bind(wx.EVT_BUTTON, self.changeLength)
+
+ # Generate the bottom buttons
+ self.save_button = wx.Button(self, wx.ID_SAVE)
+ self.cancel_button = wx.Button(self, wx.ID_CANCEL)
+
+ # "Program" the bottom buttons
+ self.save_button.Bind(wx.EVT_BUTTON, self.onClickSave)
+ self.cancel_button.Bind(wx.EVT_BUTTON, self.onClickCancel)
+
+ # Layout
+ ## Group the length field and its correspondent buttons
+ self.length_sizer = wx.BoxSizer(wx.HORIZONTAL)
+ self.length_sizer.Add(self.minus3_button, 0,
+ wx.FIXED_MINSIZE | wx.ALIGN_CENTER)
+ self.length_sizer.Add(self.minus2_button, 0,
+ wx.FIXED_MINSIZE | wx.ALIGN_CENTER)
+ self.length_sizer.Add(self.minus1_button, 0,
+ wx.FIXED_MINSIZE | wx.ALIGN_CENTER)
+ self.length_sizer.Add(self.length_field, 1, wx.EXPAND)
+ self.length_sizer.Add(self.plus1_button, 0,
+ wx.FIXED_MINSIZE | wx.ALIGN_CENTER)
+ self.length_sizer.Add(self.plus2_button, 0,
+ wx.FIXED_MINSIZE | wx.ALIGN_CENTER)
+ self.length_sizer.Add(self.plus3_button, 0,
+ wx.FIXED_MINSIZE | wx.ALIGN_CENTER)
+
+ ## Group the bottom buttons
+ self.bottom_buttons_sizer = wx.BoxSizer(wx.HORIZONTAL)
+ self.bottom_buttons_sizer.Add(self.save_button, 0, wx.EXPAND)
+ self.bottom_buttons_sizer.Add(self.cancel_button, 0, wx.EXPAND)
+
+ ## Lay out the whole window
+ self.full_sizer = wx.BoxSizer(wx.VERTICAL)
+ self.full_sizer.Add(self.name_field, 0, wx.EXPAND)
+ self.full_sizer.AddSpacer(10)
+ self.full_sizer.Add(self.length_title, 0,
+ wx.LEFT | wx.RIGHT | wx.EXPAND, 10)
+ self.full_sizer.Add(self.length_sizer, 0,
+ wx.LEFT | wx.RIGHT | wx.EXPAND, 10)
+ self.full_sizer.AddSpacer(10)
+ self.full_sizer.Add(self.bottom_buttons_sizer, 0, wx.ALIGN_CENTER)
+
+ self.SetSizerAndFit(self.full_sizer)
+
+ # Don't allow this window to be resized in height
+ edit_window_size = self.GetSize()
+ self.SetMaxSize((-1, edit_window_size.height))
+
+ def changeLength(self, event):
+ new_length = getFloat(self, self.length_field.GetValue())
+ if new_length:
+ new_length = new_length + float(event.GetEventObject().GetLabel())
+ self.length_field.ChangeValue("%.2f" % new_length)
+ self.statusbar.SetStatusText("")
+
+ def onClickSave(self, event):
+
+ new_spool_name = self.name_field.field.GetValue()
+ new_spool_length = getFloat(self, self.length_field.GetValue())
+
+ # Check whether the length is actually a number
+ if not new_spool_length:
+ self.statusbar.SetStatusText(
+ "ERROR: Unrecognized length: %s." %
+ self.length_field.GetValue())
+ return -1
+
+ if not new_spool_length > 0:
+ self.statusbar.SetStatusText(
+ "ERROR: Length is zero or negative: %.2f." % new_spool_length)
+ return -1
+
+ # Check whether the "old" spool was loaded
+ new_spool_extruder = self.parent.spool_manager.isLoaded(
+ self.old_spool_name)
+
+ # Check whether the name has changed
+ if new_spool_name == self.old_spool_name:
+ # Remove only the "old" spool
+ self.parent.spool_manager.remove(self.old_spool_name)
+ else:
+ # Check whether the new name is already used
+ if self.parent.spool_manager.isListed(new_spool_name):
+ if checkOverwrite(self, new_spool_name):
+ # Remove the "old" and the "will be overwritten" spools
+ self.parent.spool_manager.remove(self.old_spool_name)
+ self.parent.spool_manager.remove(new_spool_name)
+ else:
+ return 0
+ else:
+ # Remove only the "old" spool
+ self.parent.spool_manager.remove(self.old_spool_name)
+
+ # Add "new" or edited spool
+ self.parent.spool_manager.add(new_spool_name, new_spool_length)
+ self.parent.spool_manager.load(new_spool_name, new_spool_extruder)
+ self.parent.spool_list.refreshList(self.parent.spool_manager)
+ self.parent.current_spools_dialog.refreshDialog(
+ self.parent.spool_manager)
+ self.parent.statusbar.SetStatusText(
+ "Edited spool '%s'" % new_spool_name +
+ " with %.2f mm of remaining filament." % new_spool_length)
+
+ self.Close(True)
+
+ def onClickCancel(self, event):
+ self.Close(True)
+ self.parent.statusbar.SetStatusText("")