diff --git a/FlatCAMApp.py b/FlatCAMApp.py index a6875fca..77a89668 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -871,6 +871,8 @@ class App(QtCore.QObject): "tools_copper_thieving_squares_spacing": 0.0787402, "tools_copper_thieving_lines_size": 0.01, "tools_copper_thieving_lines_spacing": 0.0787402, + "tools_copper_thieving_rb_margin": 0.039, + "tools_copper_thieving_rb_thickness": 0.039, # Fiducials Tool "tools_fiducials_dia": 0.0393701, @@ -1423,6 +1425,8 @@ class App(QtCore.QObject): self.ui.tools2_defaults_form.tools2_cfill_group.squares_spacing_entry, "tools_copper_thieving_lines_size": self.ui.tools2_defaults_form.tools2_cfill_group.line_size_entry, "tools_copper_thieving_lines_spacing": self.ui.tools2_defaults_form.tools2_cfill_group.lines_spacing_entry, + "tools_copper_thieving_rb_margin": self.ui.tools2_defaults_form.tools2_cfill_group.rb_margin_entry, + "tools_copper_thieving_rb_thickness": self.ui.tools2_defaults_form.tools2_cfill_group.rb_thickness_entry, # Fiducials Tool "tools_fiducials_dia": self.ui.tools2_defaults_form.tools2_fiducials_group.dia_entry, @@ -1541,12 +1545,19 @@ class App(QtCore.QObject): # if user_defaults: # QtCore.QTimer.singleShot(self.defaults["global_defaults_save_period_ms"], auto_save_defaults) + # ############################################################################# + # ########################### UPDATE THE OPTIONS ############################## + # ############################################################################# + self.options = LoudDict() # ---------------------------------------------------------------------------------------------------- # Update the self.options from the self.defaults # The self.defaults holds the application defaults while the self.options holds the object defaults # ----------------------------------------------------------------------------------------------------- - self.options.update(self.defaults) # Copy app defaults to project options + # Copy app defaults to project options + for def_key, def_val in self.defaults.items(): + self.options[def_key] = deepcopy(def_val) + # self.options.update(self.defaults) self.gen_form = None self.ger_form = None @@ -5541,7 +5552,7 @@ class App(QtCore.QObject): if self.toggle_units_ignore: return - new_units = self.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + new_units = self.defaults['units'].upper() # If option is the same, then ignore if new_units == self.defaults["units"].upper(): @@ -5584,6 +5595,11 @@ class App(QtCore.QObject): "tools_cr_h2h_val", "tools_cr_dh_val", "tools_fiducials_dia", "tools_fiducials_margin", "tools_fiducials_mode", "tools_fiducials_second_pos", "tools_fiducials_type", "tools_fiducials_line_thickness", + "tools_copper_thieving_clearance", "tools_copper_thieving_margin", + "tools_copper_thieving_dots_dia", "tools_copper_thieving_dots_spacing", + "tools_copper_thieving_squares_size", "tools_copper_thieving_squares_spacing", + "tools_copper_thieving_lines_size", "tools_copper_thieving_lines_spacing", + "tools_copper_thieving_rb_margin", "tools_copper_thieving_rb_thickness", 'global_gridx', 'global_gridy', 'global_snap_max', "global_tolerance"] def scale_defaults(sfactor): @@ -5682,7 +5698,7 @@ class App(QtCore.QObject): msgbox.setInformativeText(_("Changing the units of the project causes all geometrical " "properties of all objects to be scaled accordingly.\nContinue?")) bt_ok = msgbox.addButton(_('Ok'), QtWidgets.QMessageBox.AcceptRole) - bt_cancel = msgbox.addButton(_('Cancel'), QtWidgets.QMessageBox.RejectRole) + msgbox.addButton(_('Cancel'), QtWidgets.QMessageBox.RejectRole) msgbox.setDefaultButton(bt_ok) msgbox.exec_() @@ -5734,7 +5750,7 @@ class App(QtCore.QObject): else: # Undo toggling self.toggle_units_ignore = True - if self.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() == 'MM': + if self.defaults['units'].upper() == 'MM': self.ui.general_defaults_form.general_app_group.units_radio.set_value('IN') else: self.ui.general_defaults_form.general_app_group.units_radio.set_value('MM') @@ -6861,7 +6877,7 @@ class App(QtCore.QObject): def on_tool_add_keypress(self): # ## Current application units in Upper Case - self.units = self.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.defaults['units'].upper() notebook_widget_name = self.ui.notebook.currentWidget().objectName() @@ -6968,7 +6984,7 @@ class App(QtCore.QObject): msgbox.setText(_("Are you sure you want to permanently delete\n" "the selected objects?")) bt_ok = msgbox.addButton(_('Ok'), QtWidgets.QMessageBox.AcceptRole) - bt_cancel = msgbox.addButton(_('Cancel'), QtWidgets.QMessageBox.RejectRole) + msgbox.addButton(_('Cancel'), QtWidgets.QMessageBox.RejectRole) msgbox.setDefaultButton(bt_ok) msgbox.exec_() @@ -8127,7 +8143,7 @@ class App(QtCore.QObject): return False def populate_cmenu_grids(self): - units = self.ui.general_defaults_form.general_app_group.units_radio.get_value().lower() + units = self.defaults['units'].lower() self.ui.cmenu_gridmenu.clear() sorted_list = sorted(self.defaults["global_grid_context_menu"][str(units)]) @@ -8157,7 +8173,7 @@ class App(QtCore.QObject): def on_grid_add(self): # ## Current application units in lower Case - units = self.ui.general_defaults_form.general_app_group.units_radio.get_value().lower() + units = self.defaults['units'].lower() grid_add_popup = FCInputDialog(title=_("New Grid ..."), text=_('Enter a Grid Value:'), @@ -8184,7 +8200,7 @@ class App(QtCore.QObject): def on_grid_delete(self): # ## Current application units in lower Case - units = self.ui.general_defaults_form.general_app_group.units_radio.get_value().lower() + units = self.defaults['units'].lower() grid_del_popup = FCInputDialog(title="Delete Grid ...", text='Enter a Grid Value:', @@ -8694,7 +8710,7 @@ class App(QtCore.QObject): pt4 = (float(sel_obj.options['xmin']), float(sel_obj.options['ymax'])) hover_rect = Polygon([pt1, pt2, pt3, pt4]) - if self.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() == 'MM': + if self.defaults['units'].upper() == 'MM': hover_rect = hover_rect.buffer(-0.1) hover_rect = hover_rect.buffer(0.2) @@ -8743,7 +8759,7 @@ class App(QtCore.QObject): pt4 = (float(sel_obj.options['xmin']), float(sel_obj.options['ymax'])) sel_rect = Polygon([pt1, pt2, pt3, pt4]) - if self.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() == 'MM': + if self.defaults['units'].upper() == 'MM': sel_rect = sel_rect.buffer(-0.1) sel_rect = sel_rect.buffer(0.2) else: @@ -10396,7 +10412,7 @@ class App(QtCore.QObject): eformat = self.defaults["excellon_exp_format"] slot_type = self.defaults["excellon_exp_slot_type"] - fc_units = self.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + fc_units = self.defaults['units'].upper() if fc_units == 'MM': factor = 1 if eunits == 'METRIC' else 0.03937 else: @@ -10541,7 +10557,7 @@ class App(QtCore.QObject): gfract = self.defaults["gerber_exp_decimals"] gzeros = self.defaults["gerber_exp_zeros"] - fc_units = self.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + fc_units = self.defaults['units'].upper() if fc_units == 'MM': factor = 1 if gunits == 'MM' else 0.03937 else: @@ -10720,7 +10736,7 @@ class App(QtCore.QObject): "Only Geometry and Gerber are supported")) return - units = self.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + units = self.defaults['units'].upper() def obj_init(geo_obj, app_obj): geo_obj.import_svg(filename, obj_type, units=units) @@ -10762,7 +10778,7 @@ class App(QtCore.QObject): _("Not supported type is picked as parameter. Only Geometry and Gerber are supported")) return - units = self.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + units = self.defaults['units'].upper() def obj_init(geo_obj, app_obj): geo_obj.import_dxf(filename, obj_type, units=units) @@ -10815,7 +10831,7 @@ class App(QtCore.QObject): # Object name name = outname or filename.split('/')[-1].split('\\')[-1] - units = self.ui.general_defaults_form.general_app_group.units_radio.get_value() + units = self.defaults['units'] self.new_object(obj_type, name, obj_init) self.progress.emit(20) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index e3afec24..fd7bf0d0 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -99,17 +99,14 @@ class FlatCAMObj(QtCore.QObject): # 2D mode # Axes must exist and be attached to canvas. self.axes = None - self.kind = None # Override with proper name - # self.shapes = ShapeCollection(parent=self.app.plotcanvas.view.scene) if self.app.is_legacy is False: self.shapes = self.app.plotcanvas.new_shape_group() else: self.shapes = ShapeCollectionLegacy(obj=self, app=self.app, name=name) - # self.mark_shapes = self.app.plotcanvas.new_shape_collection(layers=2) - self.mark_shapes = {} + self.mark_shapes = dict() self.item = None # Link with project view item @@ -126,7 +123,7 @@ class FlatCAMObj(QtCore.QObject): self.notHovering = True # self.units = 'IN' - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'] self.plot_single_object.connect(self.single_object_plot) @@ -165,6 +162,7 @@ class FlatCAMObj(QtCore.QObject): def on_options_change(self, key): # Update form on programmatically options change self.set_form_item(key) + # Set object visibility if key == 'plot': self.visible = self.options['plot'] @@ -308,7 +306,7 @@ class FlatCAMObj(QtCore.QObject): for option in self.options: try: self.set_form_item(option) - except Exception as e: + except Exception: self.app.log.warning("Unexpected error:", sys.exc_info()) def read_form(self): @@ -322,7 +320,7 @@ class FlatCAMObj(QtCore.QObject): for option in self.options: try: self.read_form_item(option) - except Exception as e: + except Exception: self.app.log.warning("Unexpected error:", sys.exc_info()) def set_form_item(self, option): @@ -478,13 +476,13 @@ class FlatCAMObj(QtCore.QObject): @property def drawing_tolerance(self): - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() tol = self._drawing_tolerance if self.units == 'MM' or not self.units else self._drawing_tolerance / 25.4 return tol @drawing_tolerance.setter def drawing_tolerance(self, value): - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() self._drawing_tolerance = value if self.units == 'MM' or not self.units else value / 25.4 def clear(self, update=False): @@ -637,7 +635,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber): FlatCAMObj.set_ui(self, ui) FlatCAMApp.App.log.debug("FlatCAMGerber.set_ui()") - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() if self.units == 'MM': self.decimals = 2 @@ -2253,7 +2251,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): def build_ui(self): FlatCAMObj.build_ui(self) - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.udefaults['units'].upper() try: # if connected, disconnect the signal from the slot on item_changed as it creates issues @@ -2472,7 +2470,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): FlatCAMApp.App.log.debug("FlatCAMExcellon.set_ui()") - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() if self.units == 'MM': self.decimals = 2 @@ -2571,7 +2569,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.ui.tools_table.itemChanged.disconnect() # self.tools_table_exc.selectionModel().currentChanged.disconnect() - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() self.is_modified = True @@ -3434,7 +3432,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.ui_disconnect() FlatCAMObj.build_ui(self) - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'] offset = 0 tool_idx = 0 @@ -3581,7 +3579,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): assert isinstance(self.ui, GeometryObjectUI), \ "Expected a GeometryObjectUI, got %s" % type(self.ui) - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() if self.units == 'MM': self.decimals = 2 @@ -3630,7 +3628,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.ui.cutz_entry.setDisabled(False) # store here the default data for Geometry Data - self.default_data = {} + self.default_data = dict() self.default_data.update({ "name": None, "plot": None, @@ -3675,6 +3673,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): if not self.tools: for toold in tools_list: + new_data = deepcopy(self.default_data) self.tools.update({ self.tooluid: { 'tooldia': float('%.*f' % (self.decimals, float(toold))), @@ -3682,7 +3681,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): 'offset_value': 0.0, 'type': _('Rough'), 'tool_type': 'C1', - 'data': self.default_data, + 'data': new_data, 'solid_geometry': self.solid_geometry } }) @@ -3915,7 +3914,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): def on_tool_add(self, dia=None): self.ui_disconnect() - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() # if a Tool diameter entered is a char instead a number the final message of Tool adding is changed # because the Default value for Tool is used. @@ -4042,7 +4041,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): """ self.ui_disconnect() - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() tooldia = float(tool['tooldia']) @@ -4440,7 +4439,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): if widget_idx == 1 or widget_idx == 3: self.update_cutz() - # the original connect() function of the OptionalInpuSelection is no longer working because of the + # the original connect() function of the OptionalInputSelection is no longer working because of the # ui_diconnect() so I use this 'hack' if isinstance(widget_changed, FCCheckBox): if widget_changed.text() == 'Multi-Depth:': @@ -4529,7 +4528,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.ui.geo_tools_table.setCurrentItem(self.ui.geo_tools_table.item(row, 0)) def export_dxf(self): - units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + units = self.app.defaults['units'].upper() dwg = None try: dwg = ezdxf.new('R2010') @@ -4741,10 +4740,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): """ # use the name of the first tool selected in self.geo_tools_table which has the diameter passed as tool_dia - if outname is None: - outname = "%s_%s" % (self.options["name"], 'cnc') - else: - outname = outname + outname = "%s_%s" % (self.options["name"], 'cnc') if outname is None else outname tools_dict = self.sel_tools if tools_dict is None else tools_dict tools_in_use = tools_in_use if tools_in_use is not None else self.get_selected_tools_table_items() @@ -5832,7 +5828,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): else: self.ui.cnc_tools_table.hide() - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() offset = 0 tool_idx = 0 @@ -5942,7 +5938,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): assert isinstance(self.ui, CNCObjectUI), \ "Expected a CNCObjectUI, got %s" % type(self.ui) - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() if self.units == "IN": self.decimals = 4 @@ -6845,7 +6841,7 @@ class FlatCAMDocument(FlatCAMObj): assert isinstance(self.ui, DocumentObjectUI), \ "Expected a DocumentObjectUI, got %s" % type(self.ui) - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() if self.units == "IN": self.decimals = 4 diff --git a/README.md b/README.md index 16936ffc..ff787596 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,10 @@ CAD program, and create G-Code for Isolation routing. - in Tool Fiducials added a new fiducial type: chess pattern - work in Calibrate Excellon Tool - fixed the line numbers in the TextPlainEdit to fit all digits of the line number; activated the line numbers for FlatCAMScript objects too +- line numbers in the TextPlainEdit for the selected line are bold +- made sure that the self.defaults dictionary is deepcopy-ed in the self.options dictionary +- made sure that the units are read from the self.defaults and not from the GUI +- added Robber Bar option to Copper Thieving Tool 22.11.2019 diff --git a/camlib.py b/camlib.py index 164f0a98..b794dfe6 100644 --- a/camlib.py +++ b/camlib.py @@ -4799,7 +4799,7 @@ class CNCjob(Geometry): temp_gcode = '' header_start = False header_stop = False - units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + units = self.app.defaults['units'].upper() lines = StringIO(g) for line in lines: diff --git a/flatcamEditors/FlatCAMExcEditor.py b/flatcamEditors/FlatCAMExcEditor.py index 57625ec8..e36384a8 100644 --- a/flatcamEditors/FlatCAMExcEditor.py +++ b/flatcamEditors/FlatCAMExcEditor.py @@ -2150,7 +2150,7 @@ class FlatCAMExcEditor(QtCore.QObject): def set_ui(self): # updated units - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() if self.units == "IN": self.decimals = 4 @@ -2249,7 +2249,7 @@ class FlatCAMExcEditor(QtCore.QObject): pass # updated units - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() # make a new name for the new Excellon object (the one with edited content) self.edited_obj_name = self.exc_obj.options['name'] diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py index 4a69ec95..ddde8695 100644 --- a/flatcamEditors/FlatCAMGeoEditor.py +++ b/flatcamEditors/FlatCAMGeoEditor.py @@ -367,7 +367,7 @@ class TextInputTool(FlatCAMTool): font_name=self.font_name, font_size=font_to_geo_size, font_type=font_to_geo_type, - units=self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper()) + units=self.app.defaults['units'].upper()) def font_family(self, font): self.text_input_entry.selectAll() @@ -1513,7 +1513,7 @@ class TransformEditorTool(FlatCAMTool): _("Geometry shape rotate cancelled")) def on_offx_key(self): - units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().lower() + units = self.app.defaults['units'].lower() val_box = FCInputDialog(title=_("Offset on X axis ..."), text='%s: (%s)' % (_('Enter a distance Value'), str(units)), @@ -1532,7 +1532,7 @@ class TransformEditorTool(FlatCAMTool): _("Geometry shape offset X cancelled")) def on_offy_key(self): - units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().lower() + units = self.app.defaults['units'].lower() val_box = FCInputDialog(title=_("Offset on Y axis ..."), text='%s: (%s)' % (_('Enter a distance Value'), str(units)), @@ -3165,7 +3165,7 @@ class FlatCAMGeoEditor(QtCore.QObject): except ValueError: return - units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + units = self.app.defaults['units'].upper() dec = 6 if units == 'IN' else 4 if self.app.ui.grid_gap_link_cb.isChecked(): self.app.ui.grid_gap_y_entry.set_value(val, decimals=dec) @@ -3644,7 +3644,7 @@ class FlatCAMGeoEditor(QtCore.QObject): self.replot() # updated units - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() if self.units == "IN": self.decimals = 4 diff --git a/flatcamEditors/FlatCAMGrbEditor.py b/flatcamEditors/FlatCAMGrbEditor.py index d50197bd..2e727312 100644 --- a/flatcamEditors/FlatCAMGrbEditor.py +++ b/flatcamEditors/FlatCAMGrbEditor.py @@ -3081,7 +3081,7 @@ class FlatCAMGrbEditor(QtCore.QObject): pass # updated units - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() # make a new name for the new Excellon object (the one with edited content) self.edited_obj_name = self.gerber_obj.options['name'] @@ -4883,7 +4883,7 @@ class FlatCAMGrbEditor(QtCore.QObject): # clear previous marking self.ma_annotation.clear(update=True) - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() text = [] position = [] @@ -5976,7 +5976,7 @@ class TransformEditorTool(FlatCAMTool): _("Geometry shape rotate cancelled")) def on_offx_key(self): - units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().lower() + units = self.app.defaults['units'].lower() val_box = FCInputDialog(title=_("Offset on X axis ..."), text='%s: (%s)' % (_('Enter a distance Value'), str(units)), @@ -5995,7 +5995,7 @@ class TransformEditorTool(FlatCAMTool): _("Geometry shape offset X cancelled")) def on_offy_key(self): - units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().lower() + units = self.app.defaults['units'].lower() val_box = FCInputDialog(title=_("Offset on Y axis ..."), text='%s: (%s)' % (_('Enter a distance Value'), str(units)), diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index 5899f3f5..76525986 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -2422,12 +2422,12 @@ class FCTextAreaLineNumber(QtWidgets.QFrame): # We want the line number for the selected line to be bold. if line_count == current_line: font = painter.font() - # font.setBold(True) + font.setBold(True) painter.setPen(QtCore.Qt.blue) painter.setFont(font) else: font = painter.font() - # font.setBold(False) + font.setBold(False) painter.setPen(self.palette().base().color()) painter.setFont(font) diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index 453ffa53..2c704b80 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -5921,6 +5921,40 @@ class Tools2CThievingPrefGroupUI(OptionsGroupUI): grid_lay.addWidget(self.lines_spacing_label, 16, 0) grid_lay.addWidget(self.lines_spacing_entry, 16, 1) + self.robber_bar_label = QtWidgets.QLabel('%s' % _('Robber Bar Parameters')) + self.robber_bar_label.setToolTip( + _("Parameters used for the robber bar.\n" + "Robber bar = copper border to help in pattern hole plating.") + ) + grid_lay.addWidget(self.robber_bar_label, 17, 0, 1, 2) + + # ROBBER BAR MARGIN # + self.rb_margin_label = QtWidgets.QLabel('%s:' % _("Margin")) + self.rb_margin_label.setToolTip( + _("Bounding box margin for robber bar.") + ) + self.rb_margin_entry = FCDoubleSpinner() + self.rb_margin_entry.set_range(-9999.9999, 9999.9999) + self.rb_margin_entry.set_precision(self.decimals) + self.rb_margin_entry.setSingleStep(0.1) + + grid_lay.addWidget(self.rb_margin_label, 18, 0) + grid_lay.addWidget(self.rb_margin_entry, 18, 1) + + # THICKNESS # + self.rb_thickness_label = QtWidgets.QLabel('%s:' % _("Thickness")) + self.rb_thickness_label.setToolTip( + _("The robber bar thickness.") + ) + self.rb_thickness_entry = FCDoubleSpinner() + self.rb_thickness_entry.set_range(0.0000, 9999.9999) + self.rb_thickness_entry.set_precision(self.decimals) + self.rb_thickness_entry.setSingleStep(0.1) + + grid_lay.addWidget(self.rb_thickness_label, 19, 0) + grid_lay.addWidget(self.rb_thickness_entry, 19, 1) + + self.layout.addStretch() @@ -5929,7 +5963,7 @@ class Tools2FiducialsPrefGroupUI(OptionsGroupUI): super(Tools2FiducialsPrefGroupUI, self).__init__(self) - self.setTitle(str(_("Copper Thieving Tool Options"))) + self.setTitle(str(_("Fiducials Tools Options"))) self.decimals = 4 # ## Grid Layout diff --git a/flatcamTools/ToolCalculators.py b/flatcamTools/ToolCalculators.py index 6a43a3aa..a31efd0a 100644 --- a/flatcamTools/ToolCalculators.py +++ b/flatcamTools/ToolCalculators.py @@ -288,7 +288,7 @@ class ToolCalculator(FlatCAMTool): FlatCAMTool.install(self, icon, separator, shortcut='ALT+C', **kwargs) def set_tool_ui(self): - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() # ## Initialize form self.mm_entry.set_value('%.*f' % (self.decimals, 0)) diff --git a/flatcamTools/ToolCalibrateExcellon.py b/flatcamTools/ToolCalibrateExcellon.py index 2efa4ea7..cc2c1381 100644 --- a/flatcamTools/ToolCalibrateExcellon.py +++ b/flatcamTools/ToolCalibrateExcellon.py @@ -620,7 +620,7 @@ class ToolCalibrateExcellon(FlatCAMTool): FlatCAMTool.install(self, icon, separator, shortcut='ALT+E', **kwargs) def set_tool_ui(self): - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() # ## Initialize form # self.mm_entry.set_value('%.*f' % (self.decimals, 0)) diff --git a/flatcamTools/ToolCopperThieving.py b/flatcamTools/ToolCopperThieving.py index d5a45c8c..5c55ffd2 100644 --- a/flatcamTools/ToolCopperThieving.py +++ b/flatcamTools/ToolCopperThieving.py @@ -329,6 +329,62 @@ class ToolCopperThieving(FlatCAMTool): ) self.layout.addWidget(self.fill_button) + # ## Grid Layout + grid_lay_1 = QtWidgets.QGridLayout() + self.layout.addLayout(grid_lay_1) + grid_lay_1.setColumnStretch(0, 0) + grid_lay_1.setColumnStretch(1, 1) + + separator_line_1 = QtWidgets.QFrame() + separator_line_1.setFrameShape(QtWidgets.QFrame.HLine) + separator_line_1.setFrameShadow(QtWidgets.QFrame.Sunken) + grid_lay_1.addWidget(separator_line_1, 0, 0, 1, 2) + + grid_lay_1.addWidget(QtWidgets.QLabel('')) + + self.robber_bar_label = QtWidgets.QLabel('%s' % _('Robber Bar Parameters')) + self.robber_bar_label.setToolTip( + _("Parameters used for the robber bar.\n" + "Robber bar = copper border to help in pattern hole plating.") + ) + grid_lay_1.addWidget(self.robber_bar_label, 1, 0, 1, 2) + + # ROBBER BAR MARGIN # + self.rb_margin_label = QtWidgets.QLabel('%s:' % _("Margin")) + self.rb_margin_label.setToolTip( + _("Bounding box margin for robber bar.") + ) + self.rb_margin_entry = FCDoubleSpinner() + self.rb_margin_entry.set_range(-9999.9999, 9999.9999) + self.rb_margin_entry.set_precision(self.decimals) + self.rb_margin_entry.setSingleStep(0.1) + + grid_lay_1.addWidget(self.rb_margin_label, 2, 0) + grid_lay_1.addWidget(self.rb_margin_entry, 2, 1) + + # THICKNESS # + self.rb_thickness_label = QtWidgets.QLabel('%s:' % _("Thickness")) + self.rb_thickness_label.setToolTip( + _("The robber bar thickness.") + ) + self.rb_thickness_entry = FCDoubleSpinner() + self.rb_thickness_entry.set_range(0.0000, 9999.9999) + self.rb_thickness_entry.set_precision(self.decimals) + self.rb_thickness_entry.setSingleStep(0.1) + + grid_lay_1.addWidget(self.rb_thickness_label, 3, 0) + grid_lay_1.addWidget(self.rb_thickness_entry, 3, 1) + + # ## Insert Robber Bar + self.rb_button = QtWidgets.QPushButton(_("Insert Robber Bar")) + self.rb_button.setToolTip( + _("Will add a polygon with a defined thickness\n" + "that will surround the actual Gerber object\n" + "at a certain distance.\n" + "Required when doing holes pattern plating.") + ) + self.layout.addWidget(self.rb_button) + self.layout.addStretch() # Objects involved in Copper thieving @@ -360,6 +416,7 @@ class ToolCopperThieving(FlatCAMTool): self.box_combo_type.currentIndexChanged.connect(self.on_combo_box_type) self.reference_radio.group_toggle_fn = self.on_toggle_reference self.fill_type_radio.activated_custom.connect(self.on_thieving_type) + self.rb_button.clicked.connect(self.add_robber_bar) def run(self, toggle=True): self.app.report_usage("ToolCopperThieving()") @@ -393,7 +450,7 @@ class ToolCopperThieving(FlatCAMTool): FlatCAMTool.install(self, icon, separator, shortcut='ALT+F', **kwargs) def set_tool_ui(self): - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value() + self.units = self.app.defaults['units'] self.clearance_entry.set_value(float(self.app.defaults["tools_copper_thieving_clearance"])) self.margin_entry.set_value(float(self.app.defaults["tools_copper_thieving_margin"])) self.reference_radio.set_value(self.app.defaults["tools_copper_thieving_reference"]) @@ -408,6 +465,9 @@ class ToolCopperThieving(FlatCAMTool): self.line_size_entry.set_value(self.app.defaults["tools_copper_thieving_lines_size"]) self.lines_spacing_entry.set_value(self.app.defaults["tools_copper_thieving_lines_spacing"]) + self.rb_margin_entry.set_value(self.app.defaults["tools_copper_thieving_rb_margin"]) + self.rb_thickness_entry.set_value(self.app.defaults["tools_copper_thieving_rb_thickness"]) + # INIT SECTION self.area_method = False @@ -464,6 +524,85 @@ class ToolCopperThieving(FlatCAMTool): self.squares_frame.hide() self.lines_frame.show() + def add_robber_bar(self): + rb_margin = self.rb_margin_entry.get_value() + rb_thickness = self.rb_thickness_entry.get_value() + + # get the Gerber object on which the Robber bar will be inserted + selection_index = self.grb_object_combo.currentIndex() + model_index = self.app.collection.index(selection_index, 0, self.grb_object_combo.rootModelIndex()) + + try: + self.grb_object = model_index.internalPointer().obj + except Exception as e: + log.debug("ToolCopperThieving.add_robber_bar() --> %s" % str(e)) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("There is no Gerber object loaded ...")) + return 'fail' + + try: + outline_pol = self.grb_object.solid_geometry.envelope + except TypeError: + outline_pol = MultiPolygon(self.grb_object.solid_geometry).envelope + + rb_distance = rb_margin + (rb_thickness / 2.0) + robber_line = outline_pol.buffer(rb_distance).exterior + + robber_geo = robber_line.buffer(rb_thickness / 2.0) + + self.app.proc_container.update_view_text(' %s' % _("Append geometry")) + + aperture_found = None + for ap_id, ap_val in self.grb_object.apertures.items(): + if ap_val['type'] == 'C' and ap_val['size'] == rb_thickness: + aperture_found = ap_id + break + + if aperture_found: + geo_elem = dict() + geo_elem['solid'] = robber_geo + geo_elem['follow'] = robber_line + self.grb_object.apertures[aperture_found]['geometry'].append(deepcopy(geo_elem)) + else: + ap_keys = list(self.grb_object.apertures.keys()) + if ap_keys: + new_apid = str(int(max(ap_keys)) + 1) + else: + new_apid = '10' + + self.grb_object.apertures[new_apid] = dict() + self.grb_object.apertures[new_apid]['type'] = 'C' + self.grb_object.apertures[new_apid]['size'] = rb_thickness + self.grb_object.apertures[new_apid]['geometry'] = list() + + geo_elem = dict() + geo_elem['solid'] = robber_geo + geo_elem['follow'] = robber_line + self.grb_object.apertures[new_apid]['geometry'].append(deepcopy(geo_elem)) + + geo_obj = self.grb_object.solid_geometry + if isinstance(geo_obj, MultiPolygon): + s_list = list() + for pol in geo_obj.geoms: + s_list.append(pol) + s_list.append(robber_geo) + geo_obj = MultiPolygon(s_list) + elif isinstance(geo_obj, list): + geo_obj.append(robber_geo) + elif isinstance(geo_obj, Polygon): + geo_obj = MultiPolygon([geo_obj, robber_geo]) + + self.grb_object.solid_geometry = geo_obj + + self.app.proc_container.update_view_text(' %s' % _("Append source file")) + # update the source file with the new geometry: + self.grb_object.source_file = self.app.export_gerber(obj_name=self.grb_object.options['name'], + filename=None, + local_use=self.grb_object, + use_thread=False) + self.app.proc_container.update_view_text(' %s' % '') + self.on_exit() + self.app.inform.emit('[success] %s' % _("Copper Thieving Tool done.")) + def execute(self): self.app.call_source = "copper_thieving_tool" diff --git a/flatcamTools/ToolDistance.py b/flatcamTools/ToolDistance.py index 92e5a937..00aa8b4c 100644 --- a/flatcamTools/ToolDistance.py +++ b/flatcamTools/ToolDistance.py @@ -182,7 +182,7 @@ class Distance(FlatCAMTool): # Switch notebook to tool page self.app.ui.notebook.setCurrentWidget(self.app.ui.tool_tab) - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().lower() + self.units = self.app.defaults['units'].lower() self.app.command_active = "Distance" @@ -210,7 +210,7 @@ class Distance(FlatCAMTool): self.original_call_source = copy(self.app.call_source) self.app.inform.emit(_("MEASURING: Click on the Start point ...")) - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().lower() + self.units = self.app.defaults['units'].lower() # we can connect the app mouse events to the measurement tool # NEVER DISCONNECT THOSE before connecting some other handlers; it breaks something in VisPy diff --git a/flatcamTools/ToolDistanceMin.py b/flatcamTools/ToolDistanceMin.py index 9777ac7e..ea138df6 100644 --- a/flatcamTools/ToolDistanceMin.py +++ b/flatcamTools/ToolDistanceMin.py @@ -175,7 +175,7 @@ class DistanceMin(FlatCAMTool): # Switch notebook to tool page self.app.ui.notebook.setCurrentWidget(self.app.ui.tool_tab) - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().lower() + self.units = self.app.defaults['units'].lower() # initial view of the layout self.start_entry.set_value('(0, 0)') @@ -195,7 +195,7 @@ class DistanceMin(FlatCAMTool): # ENABLE the Measuring TOOL self.jump_hp_btn.setDisabled(False) - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().lower() + self.units = self.app.defaults['units'].lower() if self.app.call_source == 'app': selected_objs = self.app.collection.get_selected() diff --git a/flatcamTools/ToolFiducials.py b/flatcamTools/ToolFiducials.py index 45baf480..26ca9add 100644 --- a/flatcamTools/ToolFiducials.py +++ b/flatcamTools/ToolFiducials.py @@ -370,7 +370,7 @@ class ToolFiducials(FlatCAMTool): FlatCAMTool.install(self, icon, separator, shortcut='ALT+J', **kwargs) def set_tool_ui(self): - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value() + self.units = self.app.defaults['units'] self.fid_size_entry.set_value(self.app.defaults["tools_fiducials_dia"]) self.margin_entry.set_value(float(self.app.defaults["tools_fiducials_margin"])) self.mode_radio.set_value(self.app.defaults["tools_fiducials_mode"]) diff --git a/flatcamTools/ToolMove.py b/flatcamTools/ToolMove.py index fcf2d262..398933ff 100644 --- a/flatcamTools/ToolMove.py +++ b/flatcamTools/ToolMove.py @@ -314,7 +314,7 @@ class ToolMove(FlatCAMTool): def draw_shape(self, shape): - if self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() == 'MM': + if self.app.defaults['units'].upper() == 'MM': proc_shape = shape.buffer(-0.1) proc_shape = proc_shape.buffer(0.2) else: diff --git a/flatcamTools/ToolNonCopperClear.py b/flatcamTools/ToolNonCopperClear.py index 9ccf4f7d..4a56c66e 100644 --- a/flatcamTools/ToolNonCopperClear.py +++ b/flatcamTools/ToolNonCopperClear.py @@ -617,7 +617,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.app.ui.notebook.setTabText(2, _("NCC Tool")) def set_tool_ui(self): - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() if self.units == "IN": self.decimals = 4 @@ -715,13 +715,13 @@ class NonCopperClear(FlatCAMTool, Gerber): self.bound_obj = None self.tool_type_item_options = ["C1", "C2", "C3", "C4", "B", "V"] - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() def build_ui(self): self.ui_disconnect() # updated units - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() sorted_tools = [] for k, v in self.ncc_tools.items(): @@ -954,7 +954,7 @@ class NonCopperClear(FlatCAMTool, Gerber): def on_tool_add(self, dia=None, muted=None): self.ui_disconnect() - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() if dia: tool_dia = dia @@ -1404,7 +1404,7 @@ class NonCopperClear(FlatCAMTool, Gerber): # ####### Read the parameters ######################################### # ##################################################################### - units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value() + units = self.app.defaults['units'] log.debug("NCC Tool started. Reading parameters.") self.app.inform.emit(_("NCC Tool started. Reading parameters.")) diff --git a/flatcamTools/ToolOptimal.py b/flatcamTools/ToolOptimal.py index 380752de..99aa0ff3 100644 --- a/flatcamTools/ToolOptimal.py +++ b/flatcamTools/ToolOptimal.py @@ -308,7 +308,7 @@ class ToolOptimal(FlatCAMTool): self.reset_fields() def find_minimum_distance(self): - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() self.decimals = int(self.precision_spinner.get_value()) selection_index = self.gerber_object_combo.currentIndex() diff --git a/flatcamTools/ToolPDF.py b/flatcamTools/ToolPDF.py index ae57301a..cef1993e 100644 --- a/flatcamTools/ToolPDF.py +++ b/flatcamTools/ToolPDF.py @@ -180,7 +180,7 @@ class ToolPDF(FlatCAMTool): self.pdf_decompressed[short_name] = '' # the UNITS in PDF files are points and here we set the factor to convert them to real units (either MM or INCH) - if self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() == 'MM': + if self.app.defaults['units'].upper() == 'MM': # 1 inch = 72 points => 1 point = 1 / 72 = 0.01388888888 inch = 0.01388888888 inch * 25.4 = 0.35277777778 mm self.point_to_unit_factor = 25.4 / 72 else: diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 0fe52c6b..112ed4d6 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -575,7 +575,7 @@ class ToolPaint(FlatCAMTool, Gerber): # make the default object type, "Geometry" self.type_obj_combo.setCurrentIndex(2) # updated units - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() if self.units == "IN": self.decimals = 4 @@ -637,7 +637,7 @@ class ToolPaint(FlatCAMTool, Gerber): pass # updated units - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() sorted_tools = [] for k, v in self.paint_tools.items(): diff --git a/flatcamTools/ToolProperties.py b/flatcamTools/ToolProperties.py index b05dc289..939de162 100644 --- a/flatcamTools/ToolProperties.py +++ b/flatcamTools/ToolProperties.py @@ -175,7 +175,7 @@ class Properties(FlatCAMTool): log.debug("PropertiesTool.addItems() --> %s" % str(e)) # calculate box area - if self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().lower() == 'mm': + if self.app.defaults['units'].lower() == 'mm': area = (length * width) / 100 else: area = length * width @@ -205,7 +205,7 @@ class Properties(FlatCAMTool): width = abs(ymax - ymin) # calculate box area - if self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().lower() == 'mm': + if self.app.defaults['units'].lower() == 'mm': area = (length * width) / 100 else: area = length * width @@ -238,7 +238,7 @@ class Properties(FlatCAMTool): area_chull = None log.debug("Properties.addItems() --> %s" % str(e)) - if self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().lower() == 'mm': + if self.app.defaults['units'].lower() == 'mm': area_chull = area_chull / 100 self.calculations_finished.emit(area, length, width, area_chull, dims) @@ -251,7 +251,7 @@ class Properties(FlatCAMTool): 'in': _('Inch'), 'mm': _('Metric') } - [str(self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().lower())] + [str(self.app.defaults['units'].lower())] ], True ) @@ -353,12 +353,12 @@ class Properties(FlatCAMTool): # add dimensions self.addChild(location, ['%s:' % _('Length'), '%.4f %s' % ( - length, self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().lower())], True) + length, self.app.defaults['units'].lower())], True) self.addChild(location, ['%s:' % _('Width'), '%.4f %s' % ( - width, self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().lower())], True) + width, self.app.defaults['units'].lower())], True) # add box area - if self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().lower() == 'mm': + if self.app.defaults['units'].lower() == 'mm': self.addChild(location, ['%s:' % _('Box Area'), '%.4f %s' % (area, 'cm2')], True) self.addChild(location, ['%s:' % _('Convex_Hull Area'), '%.4f %s' % (chull_area, 'cm2')], True) diff --git a/flatcamTools/ToolQRCode.py b/flatcamTools/ToolQRCode.py index 6781418d..9fff40fe 100644 --- a/flatcamTools/ToolQRCode.py +++ b/flatcamTools/ToolQRCode.py @@ -353,7 +353,7 @@ class QRCode(FlatCAMTool): FlatCAMTool.install(self, icon, separator, shortcut='ALT+Q', **kwargs) def set_tool_ui(self): - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value() + self.units = self.app.defaults['units'] self.version_entry.set_value(int(self.app.defaults["tools_qrcode_version"])) self.error_radio.set_value(self.app.defaults["tools_qrcode_error"]) self.bsize_entry.set_value(int(self.app.defaults["tools_qrcode_box_size"])) diff --git a/flatcamTools/ToolSolderPaste.py b/flatcamTools/ToolSolderPaste.py index af75915c..76688ec3 100644 --- a/flatcamTools/ToolSolderPaste.py +++ b/flatcamTools/ToolSolderPaste.py @@ -578,7 +578,7 @@ class SolderPaste(FlatCAMTool): self.name = "" self.obj = None - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() if self.units == "IN": self.decimals = 4 @@ -601,7 +601,7 @@ class SolderPaste(FlatCAMTool): self.ui_disconnect() # updated units - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + self.units = self.app.defaults['units'].upper() sorted_tools = [] for k, v in self.tooltable_tools.items(): diff --git a/tclCommands/TclCommandDrillcncjob.py b/tclCommands/TclCommandDrillcncjob.py index 23eb8fd0..f831b387 100644 --- a/tclCommands/TclCommandDrillcncjob.py +++ b/tclCommands/TclCommandDrillcncjob.py @@ -113,7 +113,7 @@ class TclCommandDrillcncjob(TclCommandSignaled): def job_init(job_obj, app_obj): # tools = args["tools"] if "tools" in args else 'all' - units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + units = self.app.defaults['units'].upper() try: if 'drilled_dias' in args and args['drilled_dias'] != 'all': diff --git a/tclCommands/TclCommandMillDrills.py b/tclCommands/TclCommandMillDrills.py index cb441758..8c336462 100644 --- a/tclCommands/TclCommandMillDrills.py +++ b/tclCommands/TclCommandMillDrills.py @@ -82,7 +82,7 @@ class TclCommandMillDrills(TclCommandSignaled): if not obj.drills: self.raise_tcl_error("The Excellon object has no drills: %s" % name) - units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + units = self.app.defaults['units'].upper() try: if 'milled_dias' in args and args['milled_dias'] != 'all': diff --git a/tclCommands/TclCommandMillSlots.py b/tclCommands/TclCommandMillSlots.py index 28991320..a44eb5b0 100644 --- a/tclCommands/TclCommandMillSlots.py +++ b/tclCommands/TclCommandMillSlots.py @@ -82,7 +82,7 @@ class TclCommandMillSlots(TclCommandSignaled): if not obj.slots: self.raise_tcl_error("The Excellon object has no slots: %s" % name) - units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() + units = self.app.defaults['units'].upper() try: if 'milled_dias' in args and args['milled_dias'] != 'all': diameters = [x.strip() for x in args['milled_dias'].split(",")]