diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e37f8f7..994dec01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ CHANGELOG for FlatCAM beta ================================================= +28.03.2021 + +- upgraded all the plugins such that at each launch the Plugin UI is reinitialized reducing the chances to get errors like "wrapped up C++ object deleted" with the side effect that the performance might be slightly reduced + 22.03.2021 - Milling Plugin - will update the UI form on object change with the data from its last tool diff --git a/appEditors/AppGeoEditor.py b/appEditors/AppGeoEditor.py index 1813262c..fa2dcf07 100644 --- a/appEditors/AppGeoEditor.py +++ b/appEditors/AppGeoEditor.py @@ -153,7 +153,7 @@ class BufferSelectionTool(AppTool): # focus on Tool Tab self.app.ui.notebook.setCurrentWidget(self.app.ui.plugin_tab) - self.app.ui.notebook.callback_on_close = self.on_tab_close + # self.app.ui.notebook.callback_on_close = self.on_tab_close self.app.ui.notebook.setTabText(2, _("Buffer Tool")) @@ -393,7 +393,7 @@ class TextInputTool(AppTool): # focus on Tool Tab self.app.ui.notebook.setCurrentWidget(self.app.ui.plugin_tab) - self.app.ui.notebook.callback_on_close = self.on_tab_close + # self.app.ui.notebook.callback_on_close = self.on_tab_close self.app.ui.notebook.setTabText(2, _("Text Tool")) @@ -609,7 +609,7 @@ class PaintOptionsTool(AppTool): # focus on Tool Tab self.app.ui.notebook.setCurrentWidget(self.app.ui.plugin_tab) - self.app.ui.notebook.callback_on_close = self.on_tab_close + # self.app.ui.notebook.callback_on_close = self.on_tab_close self.app.ui.notebook.setTabText(2, _("Paint Tool")) @@ -1104,7 +1104,7 @@ class TransformEditorTool(AppTool): # focus on Tool Tab self.app.ui.notebook.setCurrentWidget(self.app.ui.plugin_tab) - self.app.ui.notebook.callback_on_close = self.on_tab_close + # self.app.ui.notebook.callback_on_close = self.on_tab_close if toggle: try: diff --git a/appEditors/AppGerberEditor.py b/appEditors/AppGerberEditor.py index 5e138b0c..1ce27b46 100644 --- a/appEditors/AppGerberEditor.py +++ b/appEditors/AppGerberEditor.py @@ -7079,7 +7079,7 @@ class TransformEditorTool(AppTool): # focus on Tool Tab self.app.ui.notebook.setCurrentWidget(self.app.ui.plugin_tab) - self.app.ui.notebook.callback_on_close = self.on_tab_close + # self.app.ui.notebook.callback_on_close = self.on_tab_close if toggle: try: diff --git a/appGUI/GUIElements.py b/appGUI/GUIElements.py index 5bbe9d79..1099b09d 100644 --- a/appGUI/GUIElements.py +++ b/appGUI/GUIElements.py @@ -3306,8 +3306,32 @@ class FCDetachableTab2(FCDetachableTab): except TypeError: pass + self.__auto_remove_closed_tab = True + self.tabBar.onCloseTabSignal.connect(self.on_closetab_middle_button) + @property + def auto_remove_closed_tab(self): + """ + A property that allow the user to handle the tab removal on he's own + + :return: + :rtype: + """ + return self.__auto_remove_closed_tab + + @auto_remove_closed_tab.setter + def auto_remove_closed_tab(self, val): + """ + A property that allow the user to handle the tab removal on he's own + + :param val: If to auto remove the tab + :type val: bool + :return: + :rtype: + """ + self.__auto_remove_closed_tab = val + def on_closetab_middle_button(self, current_index): """ @@ -3330,7 +3354,8 @@ class FCDetachableTab2(FCDetachableTab): tab_name = self.widget(currentIndex).objectName() self.tab_closed_signal.emit(tab_name, currentIndex) - self.removeTab(currentIndex) + if self.__auto_remove_closed_tab: + self.removeTab(currentIndex) class VerticalScrollArea(QtWidgets.QScrollArea): diff --git a/appGUI/MainGUI.py b/appGUI/MainGUI.py index ce549cf8..cbdae3de 100644 --- a/appGUI/MainGUI.py +++ b/appGUI/MainGUI.py @@ -906,6 +906,7 @@ class MainGUI(QtWidgets.QMainWindow): self.notebook = FCDetachableTab2(protect=True, protect_by_name=[_("Project"), _("Properties")], parent=self) # self.notebook.setTabsClosable(False) self.notebook.useOldIndex(True) + self.notebook.auto_remove_closed_tab = False self.splitter.addWidget(self.notebook) diff --git a/appObjects/FlatCAMGeometry.py b/appObjects/FlatCAMGeometry.py index d99841d6..56f9907a 100644 --- a/appObjects/FlatCAMGeometry.py +++ b/appObjects/FlatCAMGeometry.py @@ -1567,7 +1567,7 @@ class GeometryObject(FlatCAMObj, Geometry): try: self.ser_attrs.remove('tools') self.ser_attrs.append('tools') - except (TypeError, ValueError): + except (TypeError, ValueError, RuntimeError): pass self.app.inform.emit('[success] %s' % _("Tool was edited in Tool Table.")) diff --git a/appParsers/ParseGerber.py b/appParsers/ParseGerber.py index c02b17fb..bdf60c22 100644 --- a/appParsers/ParseGerber.py +++ b/appParsers/ParseGerber.py @@ -2502,7 +2502,7 @@ class Gerber(Geometry): self.geo_len = 0 try: self.geo_len = len(self.solid_geometry) - except (TypeError, ValueError): + except (TypeError, ValueError, RuntimeError): self.geo_len = 1 self.old_disp_number = 0 diff --git a/appPlugins/ToolAlignObjects.py b/appPlugins/ToolAlignObjects.py index d974c08a..c78d1b06 100644 --- a/appPlugins/ToolAlignObjects.py +++ b/appPlugins/ToolAlignObjects.py @@ -44,12 +44,7 @@ class AlignObjects(AppTool): # ############################################################################# self.ui = AlignUI(layout=self.layout, app=self.app) self.pluginName = self.ui.pluginName - - # Signals - self.ui.align_object_button.clicked.connect(self.on_align) - self.ui.type_obj_radio.activated_custom.connect(self.on_type_obj_changed) - self.ui.type_aligner_obj_radio.activated_custom.connect(self.on_type_aligner_changed) - self.ui.reset_button.clicked.connect(self.set_tool_ui) + self.connect_signals_at_init() self.mr = None @@ -76,6 +71,13 @@ class AlignObjects(AppTool): self.aligned_old_fill_color = None self.aligned_old_line_color = None + def connect_signals_at_init(self): + # Signals + self.ui.align_object_button.clicked.connect(self.on_align) + self.ui.type_obj_radio.activated_custom.connect(self.on_type_obj_changed) + self.ui.type_aligner_obj_radio.activated_custom.connect(self.on_type_aligner_changed) + self.ui.reset_button.clicked.connect(self.set_tool_ui) + def run(self, toggle=True): self.app.defaults.report_usage("ToolAlignObjects()") @@ -125,6 +127,12 @@ class AlignObjects(AppTool): AppTool.install(self, icon, separator, shortcut='Alt+A', **kwargs) def set_tool_ui(self): + + self.clear_ui(self.layout) + self.ui = AlignUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() + self.reset_fields() self.clicked_points = [] diff --git a/appPlugins/ToolCalculators.py b/appPlugins/ToolCalculators.py index 7d165fcb..54f4d6ce 100644 --- a/appPlugins/ToolCalculators.py +++ b/appPlugins/ToolCalculators.py @@ -35,14 +35,6 @@ class ToolCalculator(AppTool): self.units = '' - # ## Signals - self.ui.mm_entry.editingFinished.connect(self.on_calculate_inch_units) - self.ui.inch_entry.editingFinished.connect(self.on_calculate_mm_units) - - self.ui.reset_button.clicked.connect(self.set_tool_ui) - - self.ui.area_sel_radio.activated_custom.connect(self.on_area_calculation_radio) - def run(self, toggle=True): self.app.defaults.report_usage("ToolCalculators()") @@ -89,12 +81,24 @@ class ToolCalculator(AppTool): self.app.ui.notebook.setTabText(2, _("Calculators")) + def connect_signals_at_init(self): + # ## Signals + self.ui.mm_entry.editingFinished.connect(self.on_calculate_inch_units) + self.ui.inch_entry.editingFinished.connect(self.on_calculate_mm_units) + self.ui.reset_button.clicked.connect(self.set_tool_ui) + self.ui.area_sel_radio.activated_custom.connect(self.on_area_calculation_radio) + def install(self, icon=None, separator=None, **kwargs): AppTool.install(self, icon, separator, shortcut='Alt+C', **kwargs) def set_tool_ui(self): self.units = self.app.defaults['units'].lower() + self.clear_ui(self.layout) + self.ui = CalcUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() + # ## Initialize form self.ui.mm_entry.set_value('%.*f' % (self.decimals, 0)) self.ui.inch_entry.set_value('%.*f' % (self.decimals, 0)) diff --git a/appPlugins/ToolCalibration.py b/appPlugins/ToolCalibration.py index 05bca8b8..8a920bb3 100644 --- a/appPlugins/ToolCalibration.py +++ b/appPlugins/ToolCalibration.py @@ -47,6 +47,7 @@ class ToolCalibration(AppTool): # ############################################################################# self.ui = CalibrationUI(layout=self.layout, app=self.app) self.pluginName = self.ui.pluginName + self.connect_signals_at_init() self.mr = None self.units = '' @@ -68,24 +69,6 @@ class ToolCalibration(AppTool): # calibrated object self.cal_object = None - # ## Signals - self.ui.cal_source_radio.activated_custom.connect(self.on_cal_source_radio) - self.ui.obj_type_combo.currentIndexChanged.connect(self.on_obj_type_combo) - self.ui.adj_object_type_combo.currentIndexChanged.connect(self.on_adj_obj_type_combo) - - self.ui.start_button.clicked.connect(self.on_start_collect_points) - - self.ui.gcode_button.clicked.connect(self.generate_verification_gcode) - self.ui.adj_gcode_button.clicked.connect(self.generate_verification_gcode) - - self.ui.generate_factors_button.clicked.connect(self.calculate_factors) - - self.ui.scale_button.clicked.connect(self.on_scale_button) - self.ui.skew_button.clicked.connect(self.on_skew_button) - - self.ui.cal_button.clicked.connect(self.on_cal_button_click) - self.ui.reset_button.clicked.connect(self.set_tool_ui) - def run(self, toggle=True): self.app.defaults.report_usage("ToolCalibration()") @@ -135,9 +118,33 @@ class ToolCalibration(AppTool): def install(self, icon=None, separator=None, **kwargs): AppTool.install(self, icon, separator, shortcut='Alt+E', **kwargs) + def connect_signals_at_init(self): + # ## Signals + self.ui.cal_source_radio.activated_custom.connect(self.on_cal_source_radio) + self.ui.obj_type_combo.currentIndexChanged.connect(self.on_obj_type_combo) + self.ui.adj_object_type_combo.currentIndexChanged.connect(self.on_adj_obj_type_combo) + + self.ui.start_button.clicked.connect(self.on_start_collect_points) + + self.ui.gcode_button.clicked.connect(self.generate_verification_gcode) + self.ui.adj_gcode_button.clicked.connect(self.generate_verification_gcode) + + self.ui.generate_factors_button.clicked.connect(self.calculate_factors) + + self.ui.scale_button.clicked.connect(self.on_scale_button) + self.ui.skew_button.clicked.connect(self.on_skew_button) + + self.ui.cal_button.clicked.connect(self.on_cal_button_click) + self.ui.reset_button.clicked.connect(self.set_tool_ui) + def set_tool_ui(self): self.units = self.app.defaults['units'].upper() + self.clear_ui(self.layout) + self.ui = CalibrationUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() + if self.local_connected is True: self.disconnect_cal_events() diff --git a/appPlugins/ToolCopperThieving.py b/appPlugins/ToolCopperThieving.py index 0f48c09f..386f7eaa 100644 --- a/appPlugins/ToolCopperThieving.py +++ b/appPlugins/ToolCopperThieving.py @@ -51,6 +51,7 @@ class ToolCopperThieving(AppTool): # ############################################################################# self.ui = ThievingUI(layout=self.layout, app=self.app) self.pluginName = self.ui.pluginName + self.connect_signals_at_init() # Objects involved in Copper thieving self.grb_object = None @@ -86,18 +87,6 @@ class ToolCopperThieving(AppTool): self.rb_thickness = None - # SIGNALS - self.ui.ref_combo_type.currentIndexChanged.connect(self.on_ref_combo_type_change) - self.ui.reference_radio.group_toggle_fn = self.on_toggle_reference - self.ui.fill_type_radio.activated_custom.connect(self.on_thieving_type) - - self.ui.fill_button.clicked.connect(self.on_add_copper_thieving_click) - self.ui.rb_button.clicked.connect(self.on_add_robber_bar_click) - self.ui.ppm_button.clicked.connect(self.on_add_ppm_click) - self.ui.reset_button.clicked.connect(self.set_tool_ui) - - self.work_finished.connect(self.on_new_pattern_plating_object) - def run(self, toggle=True): self.app.defaults.report_usage("ToolCopperThieving()") @@ -147,10 +136,28 @@ class ToolCopperThieving(AppTool): def install(self, icon=None, separator=None, **kwargs): AppTool.install(self, icon, separator, shortcut='Alt+J', **kwargs) + def connect_signals_at_init(self): + # SIGNALS + self.ui.ref_combo_type.currentIndexChanged.connect(self.on_ref_combo_type_change) + self.ui.reference_radio.group_toggle_fn = self.on_toggle_reference + self.ui.fill_type_radio.activated_custom.connect(self.on_thieving_type) + + self.ui.fill_button.clicked.connect(self.on_add_copper_thieving_click) + self.ui.rb_button.clicked.connect(self.on_add_robber_bar_click) + self.ui.ppm_button.clicked.connect(self.on_add_ppm_click) + self.ui.reset_button.clicked.connect(self.set_tool_ui) + + self.work_finished.connect(self.on_new_pattern_plating_object) + def set_tool_ui(self): self.units = self.app.defaults['units'] self.geo_steps_per_circle = int(self.app.defaults["tools_copper_thieving_circle_steps"]) + self.clear_ui(self.layout) + self.ui = ThievingUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() + self.ui.clearance_entry.set_value(float(self.app.defaults["tools_copper_thieving_clearance"])) self.ui.margin_entry.set_value(float(self.app.defaults["tools_copper_thieving_margin"])) self.ui.reference_radio.set_value(self.app.defaults["tools_copper_thieving_reference"]) diff --git a/appPlugins/ToolCorners.py b/appPlugins/ToolCorners.py index bd4f157a..d0a13fc8 100644 --- a/appPlugins/ToolCorners.py +++ b/appPlugins/ToolCorners.py @@ -46,6 +46,7 @@ class ToolCorners(AppTool): # ############################################################################# self.ui = CornersUI(layout=self.layout, app=self.app) self.pluginName = self.ui.pluginName + self.connect_signals_at_init() # Objects involved in Copper thieving self.grb_object = None @@ -58,15 +59,6 @@ class ToolCorners(AppTool): self.grb_steps_per_circle = self.app.defaults["gerber_circle_steps"] - # ############################################################################# - # ############################ SIGNALS ######################################## - # ############################################################################# - self.ui.level.toggled.connect(self.on_level_changed) - self.ui.add_marker_button.clicked.connect(self.add_markers) - self.ui.toggle_all_cb.toggled.connect(self.on_toggle_all) - self.ui.drill_button.clicked.connect(self.on_create_drill_object) - self.ui.check_button.clicked.connect(self.on_create_check_object) - def run(self, toggle=True): self.app.defaults.report_usage("ToolCorners()") @@ -116,8 +108,25 @@ class ToolCorners(AppTool): def install(self, icon=None, separator=None, **kwargs): AppTool.install(self, icon, separator, shortcut='Alt+B', **kwargs) + def connect_signals_at_init(self): + + # ############################################################################# + # ############################ SIGNALS ######################################## + # ############################################################################# + self.ui.level.toggled.connect(self.on_level_changed) + self.ui.add_marker_button.clicked.connect(self.add_markers) + self.ui.toggle_all_cb.toggled.connect(self.on_toggle_all) + self.ui.drill_button.clicked.connect(self.on_create_drill_object) + self.ui.check_button.clicked.connect(self.on_create_check_object) + def set_tool_ui(self): self.units = self.app.defaults['units'] + + self.clear_ui(self.layout) + self.ui = CornersUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() + self.ui.thick_entry.set_value(self.app.defaults["tools_corners_thickness"]) self.ui.l_entry.set_value(float(self.app.defaults["tools_corners_length"])) self.ui.margin_entry.set_value(float(self.app.defaults["tools_corners_margin"])) diff --git a/appPlugins/ToolCutOut.py b/appPlugins/ToolCutOut.py index a70db1dc..4f7549bc 100644 --- a/appPlugins/ToolCutOut.py +++ b/appPlugins/ToolCutOut.py @@ -48,6 +48,7 @@ class CutOut(AppTool): # ############################################################################# self.ui = CutoutUI(layout=self.layout, app=self.app) self.pluginName = self.ui.pluginName + self.connect_signals_at_init() self.cutting_gapsize = 0.0 self.cutting_dia = 0.0 @@ -96,9 +97,6 @@ class CutOut(AppTool): # here store the tool data for the Cutout Tool self.cut_tool_dict = {} - # Signals - self.connect_signals_at_init() - def on_type_obj_changed(self, val): obj_type = {'grb': 0, 'geo': 2}[val] self.ui.obj_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) @@ -198,6 +196,12 @@ class CutOut(AppTool): self.ui.reset_button.clicked.connect(self.set_tool_ui) def set_tool_ui(self): + + self.clear_ui(self.layout) + self.ui = CutoutUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() + self.reset_fields() # use the current selected object and make it visible in the object combobox diff --git a/appPlugins/ToolDblSided.py b/appPlugins/ToolDblSided.py index 1cadb5ab..9b2951a4 100644 --- a/appPlugins/ToolDblSided.py +++ b/appPlugins/ToolDblSided.py @@ -35,15 +35,10 @@ class DblSidedTool(AppTool): # ############################################################################# self.ui = DsidedUI(layout=self.layout, app=self.app) self.pluginName = self.ui.pluginName + self.connect_signals_at_init() self.mr = None - # ############################################################################################################ - # ######################################### Signals ########################################################## - # ############################################################################################################ - self.connect_signals_at_init() - # ############################################################################################################ - self.drill_values = "" # will hold the Excellon object used for picking a hole as mirror reference @@ -139,6 +134,11 @@ class DblSidedTool(AppTool): self.ui.reset_button.clicked.connect(self.set_tool_ui) def set_tool_ui(self): + self.clear_ui(self.layout) + self.ui = DsidedUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() + self.reset_fields() self.ui.point_entry.set_value("") diff --git a/appPlugins/ToolDrilling.py b/appPlugins/ToolDrilling.py index 7be3f3ed..971416dd 100644 --- a/appPlugins/ToolDrilling.py +++ b/appPlugins/ToolDrilling.py @@ -309,7 +309,7 @@ class ToolDrilling(AppTool, Excellon): def set_tool_ui(self): self.units = self.app.defaults['units'].upper() - self.clear_ui() + self.clear_ui(self.layout) self.init_ui() self.disconnect_main_signals() diff --git a/appPlugins/ToolEtchCompensation.py b/appPlugins/ToolEtchCompensation.py index b7f0737c..85e0f89c 100644 --- a/appPlugins/ToolEtchCompensation.py +++ b/appPlugins/ToolEtchCompensation.py @@ -40,13 +40,7 @@ class ToolEtchCompensation(AppTool): # ############################################################################# self.ui = EtchUI(layout=self.layout, app=self.app) self.pluginName = self.ui.pluginName - - self.ui.compensate_btn.clicked.connect(self.on_compensate) - self.ui.reset_button.clicked.connect(self.set_tool_ui) - self.ui.ratio_radio.activated_custom.connect(self.on_ratio_change) - - self.ui.oz_entry.textChanged.connect(self.on_oz_conversion) - self.ui.mils_entry.textChanged.connect(self.on_mils_conversion) + self.connect_signals_at_init() def install(self, icon=None, separator=None, **kwargs): AppTool.install(self, icon, separator, shortcut='', **kwargs) @@ -97,7 +91,20 @@ class ToolEtchCompensation(AppTool): self.app.ui.notebook.setTabText(2, _("Etch Compensation")) + def connect_signals_at_init(self): + self.ui.compensate_btn.clicked.connect(self.on_compensate) + self.ui.reset_button.clicked.connect(self.set_tool_ui) + self.ui.ratio_radio.activated_custom.connect(self.on_ratio_change) + + self.ui.oz_entry.textChanged.connect(self.on_oz_conversion) + self.ui.mils_entry.textChanged.connect(self.on_mils_conversion) + def set_tool_ui(self): + self.clear_ui(self.layout) + self.ui = EtchUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() + self.ui.thick_entry.set_value(18.0) self.ui.ratio_radio.set_value('factor') diff --git a/appPlugins/ToolExtract.py b/appPlugins/ToolExtract.py index 99aae048..ce8a7ae1 100644 --- a/appPlugins/ToolExtract.py +++ b/appPlugins/ToolExtract.py @@ -42,49 +42,7 @@ class ToolExtract(AppTool): # ############################################################################# self.ui = ExtractUI(layout=self.layout, app=self.app) self.pluginName = self.ui.pluginName - - # ## Signals - self.ui.hole_size_radio.activated_custom.connect(self.on_hole_size_toggle) - - self.ui.circular_cb.stateChanged.connect( - lambda state: - self.ui.circular_ring_entry.setDisabled(False) if state else self.ui.circular_ring_entry.setDisabled(True) - ) - - self.ui.oblong_cb.stateChanged.connect( - lambda state: - self.ui.oblong_ring_entry.setDisabled(False) if state else self.ui.oblong_ring_entry.setDisabled(True) - ) - - self.ui.square_cb.stateChanged.connect( - lambda state: - self.ui.square_ring_entry.setDisabled(False) if state else self.ui.square_ring_entry.setDisabled(True) - ) - - self.ui.rectangular_cb.stateChanged.connect( - lambda state: - self.ui.rectangular_ring_entry.setDisabled(False) if state else - self.ui.rectangular_ring_entry.setDisabled(True) - ) - - self.ui.other_cb.stateChanged.connect( - lambda state: - self.ui.other_ring_entry.setDisabled(False) if state else self.ui.other_ring_entry.setDisabled(True) - ) - - self.ui.e_drills_button.clicked.connect(self.on_extract_drills_click) - self.ui.e_sm_button.clicked.connect(self.on_extract_soldermask_click) - self.ui.e_cut_button.clicked.connect(self.on_extract_cutout_click) - self.ui.reset_button.clicked.connect(self.set_tool_ui) - - self.ui.circular_cb.stateChanged.connect(self.build_tool_ui) - self.ui.oblong_cb.stateChanged.connect(self.build_tool_ui) - self.ui.square_cb.stateChanged.connect(self.build_tool_ui) - self.ui.rectangular_cb.stateChanged.connect(self.build_tool_ui) - self.ui.other_cb.stateChanged.connect(self.build_tool_ui) - - self.ui.gerber_object_combo.currentIndexChanged.connect(self.on_object_combo_changed) - self.ui.gerber_object_combo.currentIndexChanged.connect(self.build_tool_ui) + self.connect_signals_at_init() def on_object_combo_changed(self): # get the Gerber file who is the source of the punched Gerber @@ -161,7 +119,56 @@ class ToolExtract(AppTool): self.app.ui.notebook.setTabText(2, _("Extract")) + def connect_signals_at_init(self): + # ## Signals + self.ui.hole_size_radio.activated_custom.connect(self.on_hole_size_toggle) + + self.ui.circular_cb.stateChanged.connect( + lambda state: + self.ui.circular_ring_entry.setDisabled(False) if state else self.ui.circular_ring_entry.setDisabled(True) + ) + + self.ui.oblong_cb.stateChanged.connect( + lambda state: + self.ui.oblong_ring_entry.setDisabled(False) if state else self.ui.oblong_ring_entry.setDisabled(True) + ) + + self.ui.square_cb.stateChanged.connect( + lambda state: + self.ui.square_ring_entry.setDisabled(False) if state else self.ui.square_ring_entry.setDisabled(True) + ) + + self.ui.rectangular_cb.stateChanged.connect( + lambda state: + self.ui.rectangular_ring_entry.setDisabled(False) if state else + self.ui.rectangular_ring_entry.setDisabled(True) + ) + + self.ui.other_cb.stateChanged.connect( + lambda state: + self.ui.other_ring_entry.setDisabled(False) if state else self.ui.other_ring_entry.setDisabled(True) + ) + + self.ui.e_drills_button.clicked.connect(self.on_extract_drills_click) + self.ui.e_sm_button.clicked.connect(self.on_extract_soldermask_click) + self.ui.e_cut_button.clicked.connect(self.on_extract_cutout_click) + self.ui.reset_button.clicked.connect(self.set_tool_ui) + + self.ui.circular_cb.stateChanged.connect(self.build_tool_ui) + self.ui.oblong_cb.stateChanged.connect(self.build_tool_ui) + self.ui.square_cb.stateChanged.connect(self.build_tool_ui) + self.ui.rectangular_cb.stateChanged.connect(self.build_tool_ui) + self.ui.other_cb.stateChanged.connect(self.build_tool_ui) + + self.ui.gerber_object_combo.currentIndexChanged.connect(self.on_object_combo_changed) + self.ui.gerber_object_combo.currentIndexChanged.connect(self.build_tool_ui) + def set_tool_ui(self): + self.clear_ui(self.layout) + self.ui = ExtractUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() + self.reset_fields() self.ui_disconnect() diff --git a/appPlugins/ToolFiducials.py b/appPlugins/ToolFiducials.py index bb93c72f..95c5d7aa 100644 --- a/appPlugins/ToolFiducials.py +++ b/appPlugins/ToolFiducials.py @@ -46,6 +46,7 @@ class ToolFiducials(AppTool): # ############################################################################# self.ui = FidoUI(layout=self.layout, app=self.app) self.pluginName = self.ui.pluginName + self.connect_signals_at_init() # Objects involved in Copper thieving self.grb_object = None @@ -80,18 +81,6 @@ class ToolFiducials(AppTool): self.handlers_connected = False - # ############################################################################# - # ############################ SIGNALS ######################################## - # ############################################################################# - self.ui.level.toggled.connect(self.on_level_changed) - self.ui.add_cfid_button.clicked.connect(self.add_fiducials) - self.ui.add_sm_opening_button.clicked.connect(self.add_soldermask_opening) - - self.ui.fid_type_radio.activated_custom.connect(self.on_fiducial_type) - self.ui.pos_radio.activated_custom.connect(self.on_second_point) - self.ui.mode_radio.activated_custom.connect(self.on_method_change) - self.ui.reset_button.clicked.connect(self.set_tool_ui) - def run(self, toggle=True): self.app.defaults.report_usage("ToolFiducials()") @@ -141,9 +130,27 @@ class ToolFiducials(AppTool): def install(self, icon=None, separator=None, **kwargs): AppTool.install(self, icon, separator, shortcut='Alt+F', **kwargs) + def connect_signals_at_init(self): + # ############################################################################# + # ############################ SIGNALS ######################################## + # ############################################################################# + self.ui.level.toggled.connect(self.on_level_changed) + self.ui.add_cfid_button.clicked.connect(self.add_fiducials) + self.ui.add_sm_opening_button.clicked.connect(self.add_soldermask_opening) + + self.ui.fid_type_radio.activated_custom.connect(self.on_fiducial_type) + self.ui.pos_radio.activated_custom.connect(self.on_second_point) + self.ui.mode_radio.activated_custom.connect(self.on_method_change) + self.ui.reset_button.clicked.connect(self.set_tool_ui) + def set_tool_ui(self): self.units = self.app.defaults['units'] + self.clear_ui(self.layout) + self.ui = FidoUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() + self.ui.fid_size_entry.set_value(self.app.defaults["tools_fiducials_dia"]) self.ui.margin_entry.set_value(float(self.app.defaults["tools_fiducials_margin"])) self.ui.mode_radio.set_value(self.app.defaults["tools_fiducials_mode"]) diff --git a/appPlugins/ToolFilm.py b/appPlugins/ToolFilm.py index 951d6fba..54dbcb38 100644 --- a/appPlugins/ToolFilm.py +++ b/appPlugins/ToolFilm.py @@ -161,6 +161,12 @@ class Film(AppTool): self.ui.reset_button.clicked.connect(self.set_tool_ui) def set_tool_ui(self): + + self.clear_ui(self.layout) + self.ui = FilmUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() + self.reset_fields() f_type = self.app.defaults["tools_film_type"] if self.app.defaults["tools_film_type"] else 'neg' @@ -214,6 +220,13 @@ class Film(AppTool): self.ui.tf_object_combo.set_value(obj_name) self.ui.tf_box_combo.set_value(obj_name) + else: + # run once to make sure that the obj_type attribute is updated in the FCComboBox + self.ui.tf_type_obj_combo.set_value('grb') + self.ui.tf_type_box_combo.set_value('grb') + # run once to update the obj_type attribute in the FCCombobox so the last object is showed in cb + self.on_type_obj_index_changed(val='grb') + self.on_type_box_index_changed(val='grb') # Show/Hide Advanced Options app_mode = self.app.defaults["global_app_level"] @@ -1472,15 +1485,15 @@ class FilmUI: self.punch_size_label.hide() self.punch_size_spinner.hide() - grid1 = QtWidgets.QGridLayout() - self.layout.addLayout(grid1) - grid1.setColumnStretch(0, 0) - grid1.setColumnStretch(1, 1) + self.grid1 = QtWidgets.QGridLayout() + self.layout.addLayout(self.grid1) + self.grid1.setColumnStretch(0, 0) + self.grid1.setColumnStretch(1, 1) separator_line3 = QtWidgets.QFrame() separator_line3.setFrameShape(QtWidgets.QFrame.HLine) separator_line3.setFrameShadow(QtWidgets.QFrame.Sunken) - grid1.addWidget(separator_line3, 0, 0, 1, 2) + self.grid1.addWidget(separator_line3, 0, 0, 1, 2) # File type self.file_type_radio = RadioSet([{'label': _('SVG'), 'value': 'svg'}, @@ -1495,8 +1508,8 @@ class FilmUI: "- 'PNG' -> raster image\n" "- 'PDF' -> portable document format") ) - grid1.addWidget(self.file_type_label, 1, 0) - grid1.addWidget(self.file_type_radio, 1, 1) + self.grid1.addWidget(self.file_type_label, 1, 0) + self.grid1.addWidget(self.file_type_radio, 1, 1) # Page orientation self.orientation_label = FCLabel('%s:' % _("Page Orientation")) @@ -1512,8 +1525,8 @@ class FilmUI: # ################################ New Grid ################################################################## # ############################################################################################################# - grid1.addWidget(self.orientation_label, 2, 0) - grid1.addWidget(self.orientation_radio, 2, 1) + self.grid1.addWidget(self.orientation_label, 2, 0) + self.grid1.addWidget(self.orientation_radio, 2, 1) # Page Size self.pagesize_label = FCLabel('%s:' % _("Page Size")) @@ -1575,8 +1588,8 @@ class FilmUI: page_size_list = list(self.pagesize.keys()) self.pagesize_combo.addItems(page_size_list) - grid1.addWidget(self.pagesize_label, 3, 0) - grid1.addWidget(self.pagesize_combo, 3, 1) + self.grid1.addWidget(self.pagesize_label, 3, 0) + self.grid1.addWidget(self.pagesize_combo, 3, 1) self.on_film_type(val='hide') @@ -1588,8 +1601,8 @@ class FilmUI: self.png_dpi_spinner = FCSpinner(callback=self.confirmation_message_int) self.png_dpi_spinner.set_range(0, 100000) - grid1.addWidget(self.png_dpi_label, 4, 0) - grid1.addWidget(self.png_dpi_spinner, 4, 1) + self.grid1.addWidget(self.png_dpi_label, 4, 0) + self.grid1.addWidget(self.png_dpi_spinner, 4, 1) self.png_dpi_label.hide() self.png_dpi_spinner.hide() @@ -1609,7 +1622,7 @@ class FilmUI: font-weight: bold; } """) - grid1.addWidget(self.film_object_button, 6, 0, 1, 2) + self.grid1.addWidget(self.film_object_button, 6, 0, 1, 2) self.layout.addStretch() diff --git a/appPlugins/ToolFollow.py b/appPlugins/ToolFollow.py index c62b2ab7..c25119f6 100644 --- a/appPlugins/ToolFollow.py +++ b/appPlugins/ToolFollow.py @@ -48,6 +48,7 @@ class ToolFollow(AppTool, Gerber): # ############################################################################# self.ui = FollowUI(layout=self.layout, app=self.app) self.pluginName = self.ui.pluginName + self.connect_signals_at_init() # disconnect flags self.area_sel_disconnect_flag = False @@ -69,13 +70,6 @@ class ToolFollow(AppTool, Gerber): # it is made False by first click to signify that the shape is complete self.poly_drawn = False - # ############################################################################# - # ############################ SIGNALS ######################################## - # ############################################################################# - self.ui.level.toggled.connect(self.on_level_changed) - self.ui.selectmethod_radio.activated_custom.connect(self.ui.on_selection) - self.ui.generate_geometry_button.clicked.connect(self.on_generate_geometry_click) - def install(self, icon=None, separator=None, **kwargs): AppTool.install(self, icon, separator, shortcut='', **kwargs) @@ -125,8 +119,19 @@ class ToolFollow(AppTool, Gerber): self.app.ui.notebook.setTabText(2, _("Follow")) + def connect_signals_at_init(self): + self.ui.level.toggled.connect(self.on_level_changed) + self.ui.selectmethod_radio.activated_custom.connect(self.ui.on_selection) + self.ui.generate_geometry_button.clicked.connect(self.on_generate_geometry_click) + def set_tool_ui(self): self.units = self.app.defaults['units'].upper() + + self.clear_ui(self.layout) + self.ui = FollowUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() + self.ui.selectmethod_radio.set_value('all') # _("All") self.ui.area_shape_radio.set_value('square') diff --git a/appPlugins/ToolImage.py b/appPlugins/ToolImage.py index d7ad124d..73461491 100644 --- a/appPlugins/ToolImage.py +++ b/appPlugins/ToolImage.py @@ -34,10 +34,7 @@ class ToolImage(AppTool): # ############################################################################# self.ui = ImageUI(layout=self.layout, app=self.app) self.pluginName = self.ui.pluginName - - # ## Signals - self.ui.import_button.clicked.connect(self.on_file_importimage) - self.ui.image_type.activated_custom.connect(self.ui.on_image_type) + self.connect_signals_at_init() def run(self, toggle=True): self.app.defaults.report_usage("ToolImage()") @@ -87,7 +84,17 @@ class ToolImage(AppTool): def install(self, icon=None, separator=None, **kwargs): AppTool.install(self, icon, separator, **kwargs) + def connect_signals_at_init(self): + # ## Signals + self.ui.import_button.clicked.connect(self.on_file_importimage) + self.ui.image_type.activated_custom.connect(self.ui.on_image_type) + def set_tool_ui(self): + self.clear_ui(self.layout) + self.ui = ImageUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() + # ## Initialize form self.ui.dpi_entry.set_value(96) self.ui.image_type.set_value('black') diff --git a/appPlugins/ToolInvertGerber.py b/appPlugins/ToolInvertGerber.py index 84a72966..ce536f48 100644 --- a/appPlugins/ToolInvertGerber.py +++ b/appPlugins/ToolInvertGerber.py @@ -39,9 +39,7 @@ class ToolInvertGerber(AppTool): # ############################################################################# self.ui = InvertUI(layout=self.layout, app=self.app) self.pluginName = self.ui.pluginName - - self.ui.invert_btn.clicked.connect(self.on_grb_invert) - self.ui.reset_button.clicked.connect(self.set_tool_ui) + self.connect_signals_at_init() def install(self, icon=None, separator=None, **kwargs): AppTool.install(self, icon, separator, shortcut='ALT+G', **kwargs) @@ -92,7 +90,16 @@ class ToolInvertGerber(AppTool): self.app.ui.notebook.setTabText(2, _("Invert Gerber")) + def connect_signals_at_init(self): + self.ui.invert_btn.clicked.connect(self.on_grb_invert) + self.ui.reset_button.clicked.connect(self.set_tool_ui) + def set_tool_ui(self): + self.clear_ui(self.layout) + self.ui = InvertUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() + self.ui.margin_entry.set_value(float(self.app.defaults["tools_invert_margin"])) self.ui.join_radio.set_value(self.app.defaults["tools_invert_join_style"]) diff --git a/appPlugins/ToolIsolation.py b/appPlugins/ToolIsolation.py index b731939d..77970711 100644 --- a/appPlugins/ToolIsolation.py +++ b/appPlugins/ToolIsolation.py @@ -52,26 +52,9 @@ class ToolIsolation(AppTool, Gerber): # ############################################################################# self.ui = IsoUI(layout=self.layout, app=self.app) self.pluginName = self.ui.pluginName + self.connect_signals_at_init() - # ############################################################################# - # ###################### Setup CONTEXT MENU ################################### - # ############################################################################# - self.ui.tools_table.setupContextMenu() - self.ui.tools_table.addContextMenu( - _("Search and Add"), - self.on_add_tool_by_key, - icon=QtGui.QIcon(self.app.resource_location + "/plus16.png") - ) - self.ui.tools_table.addContextMenu( - _("Pick from DB"), - self.on_tool_add_from_db_clicked, - icon=QtGui.QIcon(self.app.resource_location + "/search_db32.png") - ) - self.ui.tools_table.addContextMenu( - _("Delete"), - lambda: self.on_tool_delete(rows_to_delete=None, all_tools=None), - icon=QtGui.QIcon(self.app.resource_location + "/trash16.png") - ) + self.init_context_menu() # ############################################################################# # ########################## VARIABLES ######################################## @@ -147,8 +130,6 @@ class ToolIsolation(AppTool, Gerber): "i_iso_type": "tools_iso_isotype" } - self.connect_signals_at_init() - def install(self, icon=None, separator=None, **kwargs): AppTool.install(self, icon, separator, shortcut='Alt+I', **kwargs) @@ -207,6 +188,30 @@ class ToolIsolation(AppTool, Gerber): self.app.ui.notebook.setTabText(2, _("Isolation")) + def clear_contex_menu(self): + self.ui.tools_table.removeContextMenu() + + def init_context_menu(self): + # ############################################################################# + # ###################### Setup CONTEXT MENU ################################### + # ############################################################################# + self.ui.tools_table.setupContextMenu() + self.ui.tools_table.addContextMenu( + _("Search and Add"), + self.on_add_tool_by_key, + icon=QtGui.QIcon(self.app.resource_location + "/plus16.png") + ) + self.ui.tools_table.addContextMenu( + _("Pick from DB"), + self.on_tool_add_from_db_clicked, + icon=QtGui.QIcon(self.app.resource_location + "/search_db32.png") + ) + self.ui.tools_table.addContextMenu( + _("Delete"), + lambda: self.on_tool_delete(rows_to_delete=None, all_tools=None), + icon=QtGui.QIcon(self.app.resource_location + "/trash16.png") + ) + def connect_signals_at_init(self): # ############################################################################# # ############################ SIGNALS ######################################## @@ -250,6 +255,22 @@ class ToolIsolation(AppTool, Gerber): def set_tool_ui(self): self.units = self.app.defaults['units'].upper() + self.clear_ui(self.layout) + self.ui = IsoUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() + + self.clear_contex_menu() + self.init_context_menu() + + self.form_fields = { + "tools_iso_passes": self.ui.passes_entry, + "tools_iso_overlap": self.ui.iso_overlap_entry, + "tools_iso_milling_type": self.ui.milling_type_radio, + "tools_iso_combine": self.ui.combine_passes_cb, + "tools_iso_isotype": self.ui.iso_type_radio + } + # reset the value to prepare for another isolation self.safe_tooldia = None diff --git a/appPlugins/ToolLevelling.py b/appPlugins/ToolLevelling.py index 51f08dc7..75c25cea 100644 --- a/appPlugins/ToolLevelling.py +++ b/appPlugins/ToolLevelling.py @@ -75,6 +75,7 @@ class ToolLevelling(AppTool, CNCjob): # ############################################################################# self.ui = LevelUI(layout=self.layout, app=self.app) self.pluginName = self.ui.pluginName + self.connect_signals_at_init() # updated in the self.set_tool_ui() self.form_fields = {} @@ -127,11 +128,6 @@ class ToolLevelling(AppTool, CNCjob): # store the current selection shape status to be restored after manual adding test points self.old_selection_state = self.app.defaults['global_selection_shape'] - # ############################################################################################################# - # ####################################### Signals ########################################################### - # ############################################################################################################# - self.connect_signals_at_init() - def install(self, icon=None, separator=None, **kwargs): AppTool.install(self, icon, separator, shortcut='', **kwargs) @@ -236,6 +232,11 @@ class ToolLevelling(AppTool, CNCjob): def set_tool_ui(self): self.units = self.app.defaults['units'].upper() + self.clear_ui(self.layout) + self.ui = LevelUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() + # try to select in the CNCJob combobox the active object try: selected_obj = self.app.collection.get_active() diff --git a/appPlugins/ToolMilling.py b/appPlugins/ToolMilling.py index 2eeba2ad..747d847c 100644 --- a/appPlugins/ToolMilling.py +++ b/appPlugins/ToolMilling.py @@ -408,7 +408,7 @@ class ToolMilling(AppTool, Excellon): self.units = self.app.defaults['units'].upper() self.old_tool_dia = self.app.defaults["tools_iso_newdia"] - self.clear_ui() + self.clear_ui(self.layout) self.init_ui() self.unset_context_menu() diff --git a/appPlugins/ToolNCC.py b/appPlugins/ToolNCC.py index e97f84e5..b20cd020 100644 --- a/appPlugins/ToolNCC.py +++ b/appPlugins/ToolNCC.py @@ -54,22 +54,9 @@ class NonCopperClear(AppTool, Gerber): # ############################################################################# self.ui = NccUI(layout=self.layout, app=self.app) self.pluginName = self.ui.pluginName + self.connect_signals_at_init() - # ############################################################################# - # ###################### Setup CONTEXT MENU ################################### - # ############################################################################# - self.ui.tools_table.setupContextMenu() - self.ui.tools_table.addContextMenu( - _("Add"), self.on_tool_add_by_key, icon=QtGui.QIcon(self.app.resource_location + "/plus16.png") - ) - self.ui.tools_table.addContextMenu( - _("Add from DB"), self.on_tool_add_by_key, icon=QtGui.QIcon(self.app.resource_location + "/plus16.png") - ) - self.ui.tools_table.addContextMenu( - _("Delete"), lambda: - self.on_tool_delete(rows_to_delete=None, all_tools=None), - icon=QtGui.QIcon(self.app.resource_location + "/delete32.png") - ) + self.init_context_menu() # ############################################################################# # ########################## VARIABLES ######################################## @@ -156,8 +143,6 @@ class NonCopperClear(AppTool, Gerber): self.old_tool_dia = None - self.connect_signals_at_init() - def install(self, icon=None, separator=None, **kwargs): AppTool.install(self, icon, separator, shortcut='Alt+N', **kwargs) @@ -219,6 +204,27 @@ class NonCopperClear(AppTool, Gerber): self.app.ui.notebook.setTabText(2, _("NCC")) + def clear_context_menu(self): + self.ui.tools_table.removeContextMenu() + + def init_context_menu(self): + + # ############################################################################# + # ###################### Setup CONTEXT MENU ################################### + # ############################################################################# + self.ui.tools_table.setupContextMenu() + self.ui.tools_table.addContextMenu( + _("Add"), self.on_tool_add_by_key, icon=QtGui.QIcon(self.app.resource_location + "/plus16.png") + ) + self.ui.tools_table.addContextMenu( + _("Add from DB"), self.on_tool_add_by_key, icon=QtGui.QIcon(self.app.resource_location + "/plus16.png") + ) + self.ui.tools_table.addContextMenu( + _("Delete"), lambda: + self.on_tool_delete(rows_to_delete=None, all_tools=None), + icon=QtGui.QIcon(self.app.resource_location + "/delete32.png") + ) + def connect_signals_at_init(self): # ############################################################################# # ############################ SIGNALS ######################################## @@ -254,240 +260,31 @@ class NonCopperClear(AppTool, Gerber): # Cleanup on Graceful exit (CTRL+ALT+X combo key) self.app.cleanup.connect(self.set_tool_ui) - def on_type_obj_index_changed(self, val): - obj_type = 0 if val == 'gerber' else 2 - self.ui.object_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) - self.ui.object_combo.setCurrentIndex(0) - self.ui.object_combo.obj_type = { - "gerber": "Gerber", "geometry": "Geometry" - }[self.ui.type_obj_radio.get_value()] - - def on_operation_change(self, val): - self.ui.parameters_ui(val=val) - - current_row = self.ui.tools_table.currentRow() - try: - current_uid = int(self.ui.tools_table.item(current_row, 3).text()) - self.ncc_tools[current_uid]['data']['tools_ncc_operation'] = val - # TODO got a crash here, a KeyError exception; need to see it again and find out the why - except AttributeError: - return - - def on_object_selection_changed(self, current, previous): - try: - name = current.indexes()[0].internalPointer().obj.options['name'] - kind = current.indexes()[0].internalPointer().obj.kind - - if kind in ['gerber', 'geometry']: - self.ui.type_obj_radio.set_value(kind) - - self.ui.object_combo.set_value(name) - except Exception: - pass - - def on_toggle_all_rows(self): - """ - will toggle the selection of all rows in Tools table - - :return: - """ - sel_model = self.ui.tools_table.selectionModel() - sel_indexes = sel_model.selectedIndexes() - - # it will iterate over all indexes which means all items in all columns too but I'm interested only on rows - sel_rows = set() - for idx in sel_indexes: - sel_rows.add(idx.row()) - - if len(sel_rows) == self.ui.tools_table.rowCount(): - self.ui.tools_table.clearSelection() - self.ui.tool_data_label.setText( - "%s: %s" % (_('Parameters for'), _("No Tool Selected")) - ) - else: - self.ui.tools_table.selectAll() - self.ui.tool_data_label.setText( - "%s: %s" % (_('Parameters for'), _("Multiple Tools")) - ) - - def on_row_selection_change(self): - sel_model = self.ui.tools_table.selectionModel() - sel_indexes = sel_model.selectedIndexes() - - # it will iterate over all indexes which means all items in all columns too but I'm interested only on rows - sel_rows = set() - for idx in sel_indexes: - sel_rows.add(idx.row()) - - # update UI only if only one row is selected otherwise having multiple rows selected will deform information - # for the rows other that the current one (first selected) - if len(sel_rows) == 1: - self.update_ui() - - def update_ui(self): - self.blockSignals(True) - - sel_rows = set() - table_items = self.ui.tools_table.selectedItems() - if table_items: - for it in table_items: - sel_rows.add(it.row()) - # sel_rows = sorted(set(index.row() for index in self.ui.tools_table.selectedIndexes())) - - if not sel_rows or len(sel_rows) == 0: - self.ui.generate_ncc_button.setDisabled(True) - self.ui.tool_data_label.setText( - "%s: %s" % (_('Parameters for'), _("No Tool Selected")) - ) - self.blockSignals(False) - return - else: - self.ui.generate_ncc_button.setDisabled(False) - - for current_row in sel_rows: - # populate the form with the data from the tool associated with the row parameter - try: - item = self.ui.tools_table.item(current_row, 3) - if item is not None: - tooluid = int(item.text()) - else: - return - except Exception as e: - log.error("Tool missing. Add a tool in the Tool Table. %s" % str(e)) - return - - # update the QLabel that shows for which Tool we have the parameters in the UI form - if len(sel_rows) == 1: - cr = current_row + 1 - self.ui.tool_data_label.setText( - "%s: %s %d" % (_('Parameters for'), _("Tool"), cr) - ) - try: - # set the form with data from the newly selected tool - for tooluid_key, tooluid_value in list(self.ncc_tools.items()): - if int(tooluid_key) == tooluid: - for key, value in tooluid_value.items(): - if key == 'data': - self.storage_to_form(tooluid_value['data']) - except Exception as e: - log.error("NonCopperClear ---> update_ui() " + str(e)) - else: - self.ui.tool_data_label.setText( - "%s: %s" % (_('Parameters for'), _("Multiple Tools")) - ) - - self.blockSignals(False) - - def storage_to_form(self, dict_storage): - for form_key in self.form_fields: - for storage_key in dict_storage: - if form_key == storage_key: - try: - self.form_fields[form_key].set_value(dict_storage[form_key]) - except Exception as e: - log.error("NonCopperClear.storage_to_form() --> %s" % str(e)) - pass - - def form_to_storage(self): - if self.ui.tools_table.rowCount() == 0: - # there is no tool in tool table so we can't save the GUI elements values to storage - return - - self.blockSignals(True) - - widget_changed = self.sender() - wdg_objname = widget_changed.objectName() - option_changed = self.name2option[wdg_objname] - - # row = self.ui.tools_table.currentRow() - rows = sorted(set(index.row() for index in self.ui.tools_table.selectedIndexes())) - for row in rows: - if row < 0: - row = 0 - tooluid_item = int(self.ui.tools_table.item(row, 3).text()) - - for tooluid_key, tooluid_val in self.ncc_tools.items(): - if int(tooluid_key) == tooluid_item: - new_option_value = self.form_fields[option_changed].get_value() - if option_changed in tooluid_val: - tooluid_val[option_changed] = new_option_value - if option_changed in tooluid_val['data']: - tooluid_val['data'][option_changed] = new_option_value - - self.blockSignals(False) - - def on_apply_param_to_all_clicked(self): - if self.ui.tools_table.rowCount() == 0: - # there is no tool in tool table so we can't save the GUI elements values to storage - log.debug("NonCopperClear.on_apply_param_to_all_clicked() --> no tool in Tools Table, aborting.") - return - - self.blockSignals(True) - - row = self.ui.tools_table.currentRow() - if row < 0: - row = 0 - - tooluid_item = int(self.ui.tools_table.item(row, 3).text()) - temp_tool_data = {} - - for tooluid_key, tooluid_val in self.ncc_tools.items(): - if int(tooluid_key) == tooluid_item: - # this will hold the 'data' key of the self.tools[tool] dictionary that corresponds to - # the current row in the tool table - temp_tool_data = tooluid_val['data'] - break - - for tooluid_key, tooluid_val in self.ncc_tools.items(): - tooluid_val['data'] = deepcopy(temp_tool_data) - - # store all the data associated with the row parameter to the self.tools storage - # tooldia_item = float(self.ui.tools_table.item(row, 1).text()) - # type_item = self.ui.tools_table.cellWidget(row, 2).currentText() - # operation_type_item = self.ui.tools_table.cellWidget(row, 4).currentText() - # - # nccoffset_item = self.ncc_choice_offset_cb.get_value() - # nccoffset_value_item = float(self.ncc_offset_spinner.get_value()) - - # this new dict will hold the actual useful data, another dict that is the value of key 'data' - # temp_tools = {} - # temp_dia = {} - # temp_data = {} - # - # for tooluid_key, tooluid_value in self.ncc_tools.items(): - # for key, value in tooluid_value.items(): - # if key == 'data': - # # update the 'data' section - # for data_key in tooluid_value[key].keys(): - # for form_key, form_value in self.form_fields.items(): - # if form_key == data_key: - # temp_data[data_key] = form_value.get_value() - # # make sure we make a copy of the keys not in the form (we may use 'data' keys that are - # # updated from self.app.defaults - # if data_key not in self.form_fields: - # temp_data[data_key] = value[data_key] - # temp_dia[key] = deepcopy(temp_data) - # temp_data.clear() - # - # elif key == 'solid_geometry': - # temp_dia[key] = deepcopy(self.tools[tooluid_key]['solid_geometry']) - # else: - # temp_dia[key] = deepcopy(value) - # - # temp_tools[tooluid_key] = deepcopy(temp_dia) - # - # self.ncc_tools.clear() - # self.ncc_tools = deepcopy(temp_tools) - # temp_tools.clear() - - self.app.inform.emit('[success] %s' % _("Current Tool parameters were applied to all tools.")) - - self.blockSignals(False) - def set_tool_ui(self): self.units = self.app.defaults['units'].upper() self.old_tool_dia = self.app.defaults["tools_ncc_newdia"] + self.clear_ui(self.layout) + self.ui = NccUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() + + self.clear_context_menu() + self.init_context_menu() + + self.form_fields = { + "tools_ncc_operation": self.ui.op_radio, + "tools_ncc_overlap": self.ui.ncc_overlap_entry, + "tools_ncc_margin": self.ui.ncc_margin_entry, + "tools_ncc_method": self.ui.ncc_method_combo, + "tools_ncc_connect": self.ui.ncc_connect_cb, + "tools_ncc_contour": self.ui.ncc_contour_cb, + "tools_ncc_offset_choice": self.ui.ncc_choice_offset_cb, + "tools_ncc_offset_value": self.ui.ncc_offset_spinner, + "tools_ncc_milling_type": self.ui.milling_type_radio, + "tools_ncc_check_valid": self.ui.valid_cb + } + # reset the value to prepare for another isolation self.safe_tooldia = None @@ -750,6 +547,236 @@ class NonCopperClear(AppTool, Gerber): # Context Menu section self.ui.tools_table.setupContextMenu() + def on_type_obj_index_changed(self, val): + obj_type = 0 if val == 'gerber' else 2 + self.ui.object_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) + self.ui.object_combo.setCurrentIndex(0) + self.ui.object_combo.obj_type = { + "gerber": "Gerber", "geometry": "Geometry" + }[self.ui.type_obj_radio.get_value()] + + def on_operation_change(self, val): + self.ui.parameters_ui(val=val) + + current_row = self.ui.tools_table.currentRow() + try: + current_uid = int(self.ui.tools_table.item(current_row, 3).text()) + self.ncc_tools[current_uid]['data']['tools_ncc_operation'] = val + # TODO got a crash here, a KeyError exception; need to see it again and find out the why + except AttributeError: + return + + def on_object_selection_changed(self, current, previous): + try: + name = current.indexes()[0].internalPointer().obj.options['name'] + kind = current.indexes()[0].internalPointer().obj.kind + + if kind in ['gerber', 'geometry']: + self.ui.type_obj_radio.set_value(kind) + + self.ui.object_combo.set_value(name) + except Exception: + pass + + def on_toggle_all_rows(self): + """ + will toggle the selection of all rows in Tools table + + :return: + """ + sel_model = self.ui.tools_table.selectionModel() + sel_indexes = sel_model.selectedIndexes() + + # it will iterate over all indexes which means all items in all columns too but I'm interested only on rows + sel_rows = set() + for idx in sel_indexes: + sel_rows.add(idx.row()) + + if len(sel_rows) == self.ui.tools_table.rowCount(): + self.ui.tools_table.clearSelection() + self.ui.tool_data_label.setText( + "%s: %s" % (_('Parameters for'), _("No Tool Selected")) + ) + else: + self.ui.tools_table.selectAll() + self.ui.tool_data_label.setText( + "%s: %s" % (_('Parameters for'), _("Multiple Tools")) + ) + + def on_row_selection_change(self): + sel_model = self.ui.tools_table.selectionModel() + sel_indexes = sel_model.selectedIndexes() + + # it will iterate over all indexes which means all items in all columns too but I'm interested only on rows + sel_rows = set() + for idx in sel_indexes: + sel_rows.add(idx.row()) + + # update UI only if only one row is selected otherwise having multiple rows selected will deform information + # for the rows other that the current one (first selected) + if len(sel_rows) == 1: + self.update_ui() + + def update_ui(self): + self.blockSignals(True) + + sel_rows = set() + table_items = self.ui.tools_table.selectedItems() + if table_items: + for it in table_items: + sel_rows.add(it.row()) + # sel_rows = sorted(set(index.row() for index in self.ui.tools_table.selectedIndexes())) + + if not sel_rows or len(sel_rows) == 0: + self.ui.generate_ncc_button.setDisabled(True) + self.ui.tool_data_label.setText( + "%s: %s" % (_('Parameters for'), _("No Tool Selected")) + ) + self.blockSignals(False) + return + else: + self.ui.generate_ncc_button.setDisabled(False) + + for current_row in sel_rows: + # populate the form with the data from the tool associated with the row parameter + try: + item = self.ui.tools_table.item(current_row, 3) + if item is not None: + tooluid = int(item.text()) + else: + return + except Exception as e: + log.error("Tool missing. Add a tool in the Tool Table. %s" % str(e)) + return + + # update the QLabel that shows for which Tool we have the parameters in the UI form + if len(sel_rows) == 1: + cr = current_row + 1 + self.ui.tool_data_label.setText( + "%s: %s %d" % (_('Parameters for'), _("Tool"), cr) + ) + try: + # set the form with data from the newly selected tool + for tooluid_key, tooluid_value in list(self.ncc_tools.items()): + if int(tooluid_key) == tooluid: + for key, value in tooluid_value.items(): + if key == 'data': + self.storage_to_form(tooluid_value['data']) + except Exception as e: + log.error("NonCopperClear ---> update_ui() " + str(e)) + else: + self.ui.tool_data_label.setText( + "%s: %s" % (_('Parameters for'), _("Multiple Tools")) + ) + + self.blockSignals(False) + + def storage_to_form(self, dict_storage): + for form_key in self.form_fields: + for storage_key in dict_storage: + if form_key == storage_key: + try: + self.form_fields[form_key].set_value(dict_storage[form_key]) + except Exception as e: + log.error("NonCopperClear.storage_to_form() --> %s" % str(e)) + pass + + def form_to_storage(self): + if self.ui.tools_table.rowCount() == 0: + # there is no tool in tool table so we can't save the GUI elements values to storage + return + + self.blockSignals(True) + + widget_changed = self.sender() + wdg_objname = widget_changed.objectName() + option_changed = self.name2option[wdg_objname] + + # row = self.ui.tools_table.currentRow() + rows = sorted(set(index.row() for index in self.ui.tools_table.selectedIndexes())) + for row in rows: + if row < 0: + row = 0 + tooluid_item = int(self.ui.tools_table.item(row, 3).text()) + + for tooluid_key, tooluid_val in self.ncc_tools.items(): + if int(tooluid_key) == tooluid_item: + new_option_value = self.form_fields[option_changed].get_value() + if option_changed in tooluid_val: + tooluid_val[option_changed] = new_option_value + if option_changed in tooluid_val['data']: + tooluid_val['data'][option_changed] = new_option_value + + self.blockSignals(False) + + def on_apply_param_to_all_clicked(self): + if self.ui.tools_table.rowCount() == 0: + # there is no tool in tool table so we can't save the GUI elements values to storage + log.debug("NonCopperClear.on_apply_param_to_all_clicked() --> no tool in Tools Table, aborting.") + return + + self.blockSignals(True) + + row = self.ui.tools_table.currentRow() + if row < 0: + row = 0 + + tooluid_item = int(self.ui.tools_table.item(row, 3).text()) + temp_tool_data = {} + + for tooluid_key, tooluid_val in self.ncc_tools.items(): + if int(tooluid_key) == tooluid_item: + # this will hold the 'data' key of the self.tools[tool] dictionary that corresponds to + # the current row in the tool table + temp_tool_data = tooluid_val['data'] + break + + for tooluid_key, tooluid_val in self.ncc_tools.items(): + tooluid_val['data'] = deepcopy(temp_tool_data) + + # store all the data associated with the row parameter to the self.tools storage + # tooldia_item = float(self.ui.tools_table.item(row, 1).text()) + # type_item = self.ui.tools_table.cellWidget(row, 2).currentText() + # operation_type_item = self.ui.tools_table.cellWidget(row, 4).currentText() + # + # nccoffset_item = self.ncc_choice_offset_cb.get_value() + # nccoffset_value_item = float(self.ncc_offset_spinner.get_value()) + + # this new dict will hold the actual useful data, another dict that is the value of key 'data' + # temp_tools = {} + # temp_dia = {} + # temp_data = {} + # + # for tooluid_key, tooluid_value in self.ncc_tools.items(): + # for key, value in tooluid_value.items(): + # if key == 'data': + # # update the 'data' section + # for data_key in tooluid_value[key].keys(): + # for form_key, form_value in self.form_fields.items(): + # if form_key == data_key: + # temp_data[data_key] = form_value.get_value() + # # make sure we make a copy of the keys not in the form (we may use 'data' keys that are + # # updated from self.app.defaults + # if data_key not in self.form_fields: + # temp_data[data_key] = value[data_key] + # temp_dia[key] = deepcopy(temp_data) + # temp_data.clear() + # + # elif key == 'solid_geometry': + # temp_dia[key] = deepcopy(self.tools[tooluid_key]['solid_geometry']) + # else: + # temp_dia[key] = deepcopy(value) + # + # temp_tools[tooluid_key] = deepcopy(temp_dia) + # + # self.ncc_tools.clear() + # self.ncc_tools = deepcopy(temp_tools) + # temp_tools.clear() + + self.app.inform.emit('[success] %s' % _("Current Tool parameters were applied to all tools.")) + + self.blockSignals(False) + def rebuild_ui(self): # read the table tools uid current_uid_list = [] diff --git a/appPlugins/ToolOptimal.py b/appPlugins/ToolOptimal.py index 87788140..cd2cdc55 100644 --- a/appPlugins/ToolOptimal.py +++ b/appPlugins/ToolOptimal.py @@ -45,6 +45,7 @@ class ToolOptimal(AppTool): # ############################################################################# self.ui = OptimalUI(layout=self.layout, app=self.app) self.pluginName = self.ui.pluginName + self.connect_signals_at_init() # this is the line selected in the textbox with the locations of the minimum self.selected_text = '' @@ -56,22 +57,6 @@ class ToolOptimal(AppTool): # distances happen as values self.min_dict = {} - # ############################################################################ - # ############################ Signals ####################################### - # ############################################################################ - self.update_text.connect(self.on_update_text) - self.update_sec_distances.connect(self.on_update_sec_distances_txt) - - self.ui.calculate_button.clicked.connect(self.find_minimum_distance) - self.ui.locate_button.clicked.connect(self.on_locate_position) - self.ui.locations_textb.cursorPositionChanged.connect(self.on_textbox_clicked) - - self.ui.locate_sec_button.clicked.connect(self.on_locate_sec_position) - self.ui.distances_textb.cursorPositionChanged.connect(self.on_distances_textb_clicked) - self.ui.locations_sec_textb.cursorPositionChanged.connect(self.on_locations_sec_clicked) - - self.ui.reset_button.clicked.connect(self.set_tool_ui) - def install(self, icon=None, separator=None, **kwargs): AppTool.install(self, icon, separator, shortcut='Alt+O', **kwargs) @@ -120,7 +105,26 @@ class ToolOptimal(AppTool): self.app.ui.notebook.setTabText(2, _("Find Optimal")) + def connect_signals_at_init(self): + self.update_text.connect(self.on_update_text) + self.update_sec_distances.connect(self.on_update_sec_distances_txt) + + self.ui.calculate_button.clicked.connect(self.find_minimum_distance) + self.ui.locate_button.clicked.connect(self.on_locate_position) + self.ui.locations_textb.cursorPositionChanged.connect(self.on_textbox_clicked) + + self.ui.locate_sec_button.clicked.connect(self.on_locate_sec_position) + self.ui.distances_textb.cursorPositionChanged.connect(self.on_distances_textb_clicked) + self.ui.locations_sec_textb.cursorPositionChanged.connect(self.on_locations_sec_clicked) + + self.ui.reset_button.clicked.connect(self.set_tool_ui) + def set_tool_ui(self): + self.clear_ui(self.layout) + self.ui = OptimalUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() + self.ui.result_entry.set_value(0.0) self.ui.freq_entry.set_value(0) diff --git a/appPlugins/ToolPaint.py b/appPlugins/ToolPaint.py index fd353ff0..ed024c39 100644 --- a/appPlugins/ToolPaint.py +++ b/appPlugins/ToolPaint.py @@ -53,6 +53,7 @@ class ToolPaint(AppTool, Gerber): # ############################################################################# self.ui = PaintUI(layout=self.layout, app=self.app) self.pluginName = self.ui.pluginName + self.connect_signals_at_init() # ############################################################################# # ########################## VARIABLES ######################################## @@ -126,23 +127,10 @@ class ToolPaint(AppTool, Gerber): # it is made False by first click to signify that the shape is complete self.poly_drawn = False - self.connect_signals_at_init() - # ############################################################################# # ###################### Setup CONTEXT MENU ################################### # ############################################################################# - self.ui.tools_table.setupContextMenu() - self.ui.tools_table.addContextMenu( - _("Add"), self.on_add_tool_by_key, icon=QtGui.QIcon(self.app.resource_location + "/plus16.png") - ) - self.ui.tools_table.addContextMenu( - _("Add from DB"), self.on_add_tool_by_key, icon=QtGui.QIcon(self.app.resource_location + "/plus16.png") - ) - self.ui.tools_table.addContextMenu( - _("Delete"), lambda: - self.on_tool_delete(rows_to_delete=None, all_tools=None), - icon=QtGui.QIcon(self.app.resource_location + "/delete32.png") - ) + self.init_context_menu() def on_type_obj_changed(self, val): obj_type = 0 if val == 'gerber' else 2 @@ -164,34 +152,6 @@ class ToolPaint(AppTool, Gerber): self.ui.reference_combo.setCurrentIndex(0) self.ui.reference_combo.obj_type = {0: "Gerber", 1: "Excellon", 2: "Geometry"}[obj_type] - def connect_signals_at_init(self): - # ############################################################################# - # ################################# Signals ################################### - # ############################################################################# - self.ui.level.toggled.connect(self.on_level_changed) - - self.ui.new_tooldia_entry.returnPressed.connect(self.on_tool_add) - self.ui.deltool_btn.clicked.connect(self.on_tool_delete) - - self.ui.generate_paint_button.clicked.connect(self.on_paint_button_click) - self.ui.selectmethod_combo.currentIndexChanged.connect(self.ui.on_selection) - - self.ui.reference_type_combo.currentIndexChanged.connect(self.on_reference_combo_changed) - self.ui.type_obj_radio.activated_custom.connect(self.on_type_obj_changed) - - self.ui.apply_param_to_all.clicked.connect(self.on_apply_param_to_all_clicked) - - # adding tools - self.ui.search_and_add_btn.clicked.connect(lambda: self.on_tool_add()) - self.ui.addtool_from_db_btn.clicked.connect(self.on_paint_tool_add_from_db_clicked) - - self.app.proj_selection_changed.connect(self.on_object_selection_changed) - - self.ui.reset_button.clicked.connect(self.set_tool_ui) - - # Cleanup on Graceful exit (CTRL+ALT+X combo key) - self.app.cleanup.connect(self.set_tool_ui) - def install(self, icon=None, separator=None, **kwargs): AppTool.install(self, icon, separator, shortcut='Alt+P', **kwargs) @@ -246,217 +206,68 @@ class ToolPaint(AppTool, Gerber): self.app.ui.notebook.setTabText(2, _("Paint")) - def on_toggle_all_rows(self): - """ - will toggle the selection of all rows in Tools table + def clear_context_menu(self): + self.ui.tools_table.removeContextMenu() - :return: - """ - sel_model = self.ui.tools_table.selectionModel() - sel_indexes = sel_model.selectedIndexes() + def init_context_menu(self): + self.ui.tools_table.setupContextMenu() + self.ui.tools_table.addContextMenu( + _("Add"), self.on_add_tool_by_key, icon=QtGui.QIcon(self.app.resource_location + "/plus16.png") + ) + self.ui.tools_table.addContextMenu( + _("Add from DB"), self.on_add_tool_by_key, icon=QtGui.QIcon(self.app.resource_location + "/plus16.png") + ) + self.ui.tools_table.addContextMenu( + _("Delete"), lambda: + self.on_tool_delete(rows_to_delete=None, all_tools=None), + icon=QtGui.QIcon(self.app.resource_location + "/delete32.png") + ) - # it will iterate over all indexes which means all items in all columns too but I'm interested only on rows - sel_rows = set() - for idx in sel_indexes: - sel_rows.add(idx.row()) + def connect_signals_at_init(self): + # ############################################################################# + # ################################# Signals ################################### + # ############################################################################# + self.ui.level.toggled.connect(self.on_level_changed) - if len(sel_rows) == self.ui.tools_table.rowCount(): - self.ui.tools_table.clearSelection() - self.ui.tool_data_label.setText( - "%s: %s" % (_('Parameters for'), _("No Tool Selected")) - ) - else: - self.ui.tools_table.selectAll() - self.ui.tool_data_label.setText( - "%s: %s" % (_('Parameters for'), _("Multiple Tools")) - ) + self.ui.new_tooldia_entry.returnPressed.connect(self.on_tool_add) + self.ui.deltool_btn.clicked.connect(self.on_tool_delete) - def on_row_selection_change(self): - sel_model = self.ui.tools_table.selectionModel() - sel_indexes = sel_model.selectedIndexes() + self.ui.generate_paint_button.clicked.connect(self.on_paint_button_click) + self.ui.selectmethod_combo.currentIndexChanged.connect(self.ui.on_selection) - # it will iterate over all indexes which means all items in all columns too but I'm interested only on rows - sel_rows = set() - for idx in sel_indexes: - sel_rows.add(idx.row()) + self.ui.reference_type_combo.currentIndexChanged.connect(self.on_reference_combo_changed) + self.ui.type_obj_radio.activated_custom.connect(self.on_type_obj_changed) - # update UI only if only one row is selected otherwise having multiple rows selected will deform information - # for the rows other that the current one (first selected) - if len(sel_rows) == 1: - self.update_ui() + self.ui.apply_param_to_all.clicked.connect(self.on_apply_param_to_all_clicked) - def on_object_selection_changed(self, current, previous): - try: - name = current.indexes()[0].internalPointer().obj.options['name'] - kind = current.indexes()[0].internalPointer().obj.kind + # adding tools + self.ui.search_and_add_btn.clicked.connect(lambda: self.on_tool_add()) + self.ui.addtool_from_db_btn.clicked.connect(self.on_paint_tool_add_from_db_clicked) - if kind in ['gerber', 'geometry']: - self.ui.type_obj_radio.set_value(kind) + self.app.proj_selection_changed.connect(self.on_object_selection_changed) - self.ui.obj_combo.set_value(name) - except Exception: - pass + self.ui.reset_button.clicked.connect(self.set_tool_ui) - def update_ui(self): - self.blockSignals(True) - - sel_rows = set() - table_items = self.ui.tools_table.selectedItems() - if table_items: - for it in table_items: - sel_rows.add(it.row()) - # sel_rows = sorted(set(index.row() for index in self.ui.tools_table.selectedIndexes())) - - if not sel_rows or len(sel_rows) == 0: - self.ui.generate_paint_button.setDisabled(True) - self.ui.tool_data_label.setText( - "%s: %s" % (_('Parameters for'), _("No Tool Selected")) - ) - self.blockSignals(False) - return - else: - self.ui.generate_paint_button.setDisabled(False) - - for current_row in sel_rows: - # populate the form with the data from the tool associated with the row parameter - try: - item = self.ui.tools_table.item(current_row, 3) - if item is None: - return 'fail' - tooluid = int(item.text()) - except Exception as e: - log.error("Tool missing. Add a tool in the Tool Table. %s" % str(e)) - return - - # update the QLabel that shows for which Tool we have the parameters in the UI form - if len(sel_rows) == 1: - cr = self.ui.tools_table.item(current_row, 0).text() - self.ui.tool_data_label.setText( - "%s: %s %s" % (_('Parameters for'), _("Tool"), cr) - ) - - try: - # set the form with data from the newly selected tool - for tooluid_key, tooluid_value in list(self.paint_tools.items()): - if int(tooluid_key) == tooluid: - self.storage_to_form(tooluid_value['data']) - except Exception as e: - log.error("ToolPaint ---> update_ui() " + str(e)) - else: - self.ui.tool_data_label.setText( - "%s: %s" % (_('Parameters for'), _("Multiple Tools")) - ) - - self.blockSignals(False) - - def storage_to_form(self, dict_storage): - for k in self.form_fields: - try: - self.form_fields[k].set_value(dict_storage[k]) - except Exception as err: - log.error("ToolPaint.storage.form() --> %s" % str(err)) - - def form_to_storage(self): - if self.ui.tools_table.rowCount() == 0: - # there is no tool in tool table so we can't save the GUI elements values to storage - return - - self.blockSignals(True) - - widget_changed = self.sender() - wdg_objname = widget_changed.objectName() - option_changed = self.name2option[wdg_objname] - - # row = self.ui.tools_table.currentRow() - rows = sorted(set(index.row() for index in self.ui.tools_table.selectedIndexes())) - for row in rows: - if row < 0: - row = 0 - tooluid_item = int(self.ui.tools_table.item(row, 3).text()) - - for tooluid_key, tooluid_val in self.paint_tools.items(): - if int(tooluid_key) == tooluid_item: - new_option_value = self.form_fields[option_changed].get_value() - if option_changed in tooluid_val: - tooluid_val[option_changed] = new_option_value - if option_changed in tooluid_val['data']: - tooluid_val['data'][option_changed] = new_option_value - - self.blockSignals(False) - - def on_apply_param_to_all_clicked(self): - if self.ui.tools_table.rowCount() == 0: - # there is no tool in tool table so we can't save the GUI elements values to storage - log.debug("NonCopperClear.on_apply_param_to_all_clicked() --> no tool in Tools Table, aborting.") - return - - self.blockSignals(True) - - row = self.ui.tools_table.currentRow() - if row < 0: - row = 0 - - tooluid_item = int(self.ui.tools_table.item(row, 3).text()) - temp_tool_data = {} - - for tooluid_key, tooluid_val in self.paint_tools.items(): - if int(tooluid_key) == tooluid_item: - # this will hold the 'data' key of the self.tools[tool] dictionary that corresponds to - # the current row in the tool table - temp_tool_data = tooluid_val['data'] - break - - for tooluid_key, tooluid_val in self.paint_tools.items(): - tooluid_val['data'] = deepcopy(temp_tool_data) - - self.app.inform.emit('[success] %s' % _("Current Tool parameters were applied to all tools.")) - - self.blockSignals(False) - - def on_add_tool_by_key(self): - tool_add_popup = FCInputDoubleSpinner(title='%s...' % _("New Tool"), - text='%s:' % _('Enter a Tool Diameter'), - min=0.0000, max=99.9999, decimals=self.decimals, - parent=self.app.ui) - tool_add_popup.set_icon(QtGui.QIcon(self.app.resource_location + '/letter_t_32.png')) - - val, ok = tool_add_popup.get_value() - if ok: - if float(val) == 0: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Please enter a tool diameter with non-zero value, in Float format.")) - return - self.on_tool_add(custom_dia=float(val)) - else: - self.app.inform.emit('[WARNING_NOTCL] %s...' % _("Adding Tool cancelled")) - - def on_tooltable_cellwidget_change(self): - cw = self.sender() - - assert isinstance(cw, QtWidgets.QComboBox), \ - "Expected a QtWidgets.QComboBox, got %s" % isinstance(cw, QtWidgets.QComboBox) - - cw_index = self.ui.tools_table.indexAt(cw.pos()) - cw_row = cw_index.row() - cw_col = cw_index.column() - - current_uid = int(self.ui.tools_table.item(cw_row, 3).text()) - - # if the sender is in the column with index 2 then we update the tool_type key - if cw_col == 2: - tt = cw.currentText() - typ = 'Iso' if tt == 'V' else 'Rough' - - self.paint_tools[current_uid].update({ - 'type': typ, - 'tool_type': tt, - }) - - def on_order_changed(self, order): - if order != 'no': - self.build_ui() + # Cleanup on Graceful exit (CTRL+ALT+X combo key) + self.app.cleanup.connect(self.set_tool_ui) def set_tool_ui(self): + self.clear_ui(self.layout) + self.ui = PaintUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() + + self.form_fields = { + "tools_paint_overlap": self.ui.paintoverlap_entry, + "tools_paint_offset": self.ui.offset_entry, + "tools_paint_method": self.ui.paintmethod_combo, + "tools_paint_connect": self.ui.pathconnect_cb, + "tools_paint_contour": self.ui.paintcontour_cb, + } + + self.clear_context_menu() + self.init_context_menu() + self.ui.tools_frame.show() self.reset_fields() @@ -687,6 +498,216 @@ class ToolPaint(AppTool, Gerber): # Context Menu section self.ui.tools_table.setupContextMenu() + def on_toggle_all_rows(self): + """ + will toggle the selection of all rows in Tools table + + :return: + """ + sel_model = self.ui.tools_table.selectionModel() + sel_indexes = sel_model.selectedIndexes() + + # it will iterate over all indexes which means all items in all columns too but I'm interested only on rows + sel_rows = set() + for idx in sel_indexes: + sel_rows.add(idx.row()) + + if len(sel_rows) == self.ui.tools_table.rowCount(): + self.ui.tools_table.clearSelection() + self.ui.tool_data_label.setText( + "%s: %s" % (_('Parameters for'), _("No Tool Selected")) + ) + else: + self.ui.tools_table.selectAll() + self.ui.tool_data_label.setText( + "%s: %s" % (_('Parameters for'), _("Multiple Tools")) + ) + + def on_row_selection_change(self): + sel_model = self.ui.tools_table.selectionModel() + sel_indexes = sel_model.selectedIndexes() + + # it will iterate over all indexes which means all items in all columns too but I'm interested only on rows + sel_rows = set() + for idx in sel_indexes: + sel_rows.add(idx.row()) + + # update UI only if only one row is selected otherwise having multiple rows selected will deform information + # for the rows other that the current one (first selected) + if len(sel_rows) == 1: + self.update_ui() + + def on_object_selection_changed(self, current, previous): + try: + name = current.indexes()[0].internalPointer().obj.options['name'] + kind = current.indexes()[0].internalPointer().obj.kind + + if kind in ['gerber', 'geometry']: + self.ui.type_obj_radio.set_value(kind) + + self.ui.obj_combo.set_value(name) + except Exception: + pass + + def update_ui(self): + self.blockSignals(True) + + sel_rows = set() + table_items = self.ui.tools_table.selectedItems() + if table_items: + for it in table_items: + sel_rows.add(it.row()) + # sel_rows = sorted(set(index.row() for index in self.ui.tools_table.selectedIndexes())) + + if not sel_rows or len(sel_rows) == 0: + self.ui.generate_paint_button.setDisabled(True) + self.ui.tool_data_label.setText( + "%s: %s" % (_('Parameters for'), _("No Tool Selected")) + ) + self.blockSignals(False) + return + else: + self.ui.generate_paint_button.setDisabled(False) + + for current_row in sel_rows: + # populate the form with the data from the tool associated with the row parameter + try: + item = self.ui.tools_table.item(current_row, 3) + if item is None: + return 'fail' + tooluid = int(item.text()) + except Exception as e: + log.error("Tool missing. Add a tool in the Tool Table. %s" % str(e)) + return + + # update the QLabel that shows for which Tool we have the parameters in the UI form + if len(sel_rows) == 1: + cr = self.ui.tools_table.item(current_row, 0).text() + self.ui.tool_data_label.setText( + "%s: %s %s" % (_('Parameters for'), _("Tool"), cr) + ) + + try: + # set the form with data from the newly selected tool + for tooluid_key, tooluid_value in list(self.paint_tools.items()): + if int(tooluid_key) == tooluid: + self.storage_to_form(tooluid_value['data']) + except Exception as e: + log.error("ToolPaint ---> update_ui() " + str(e)) + else: + self.ui.tool_data_label.setText( + "%s: %s" % (_('Parameters for'), _("Multiple Tools")) + ) + + self.blockSignals(False) + + def storage_to_form(self, dict_storage): + for k in self.form_fields: + try: + self.form_fields[k].set_value(dict_storage[k]) + except Exception as err: + log.error("ToolPaint.storage.form() --> %s" % str(err)) + + def form_to_storage(self): + if self.ui.tools_table.rowCount() == 0: + # there is no tool in tool table so we can't save the GUI elements values to storage + return + + self.blockSignals(True) + + widget_changed = self.sender() + wdg_objname = widget_changed.objectName() + option_changed = self.name2option[wdg_objname] + + # row = self.ui.tools_table.currentRow() + rows = sorted(set(index.row() for index in self.ui.tools_table.selectedIndexes())) + for row in rows: + if row < 0: + row = 0 + tooluid_item = int(self.ui.tools_table.item(row, 3).text()) + + for tooluid_key, tooluid_val in self.paint_tools.items(): + if int(tooluid_key) == tooluid_item: + new_option_value = self.form_fields[option_changed].get_value() + if option_changed in tooluid_val: + tooluid_val[option_changed] = new_option_value + if option_changed in tooluid_val['data']: + tooluid_val['data'][option_changed] = new_option_value + + self.blockSignals(False) + + def on_apply_param_to_all_clicked(self): + if self.ui.tools_table.rowCount() == 0: + # there is no tool in tool table so we can't save the GUI elements values to storage + log.debug("NonCopperClear.on_apply_param_to_all_clicked() --> no tool in Tools Table, aborting.") + return + + self.blockSignals(True) + + row = self.ui.tools_table.currentRow() + if row < 0: + row = 0 + + tooluid_item = int(self.ui.tools_table.item(row, 3).text()) + temp_tool_data = {} + + for tooluid_key, tooluid_val in self.paint_tools.items(): + if int(tooluid_key) == tooluid_item: + # this will hold the 'data' key of the self.tools[tool] dictionary that corresponds to + # the current row in the tool table + temp_tool_data = tooluid_val['data'] + break + + for tooluid_key, tooluid_val in self.paint_tools.items(): + tooluid_val['data'] = deepcopy(temp_tool_data) + + self.app.inform.emit('[success] %s' % _("Current Tool parameters were applied to all tools.")) + + self.blockSignals(False) + + def on_add_tool_by_key(self): + tool_add_popup = FCInputDoubleSpinner(title='%s...' % _("New Tool"), + text='%s:' % _('Enter a Tool Diameter'), + min=0.0000, max=99.9999, decimals=self.decimals, + parent=self.app.ui) + tool_add_popup.set_icon(QtGui.QIcon(self.app.resource_location + '/letter_t_32.png')) + + val, ok = tool_add_popup.get_value() + if ok: + if float(val) == 0: + self.app.inform.emit('[WARNING_NOTCL] %s' % + _("Please enter a tool diameter with non-zero value, in Float format.")) + return + self.on_tool_add(custom_dia=float(val)) + else: + self.app.inform.emit('[WARNING_NOTCL] %s...' % _("Adding Tool cancelled")) + + def on_tooltable_cellwidget_change(self): + cw = self.sender() + + assert isinstance(cw, QtWidgets.QComboBox), \ + "Expected a QtWidgets.QComboBox, got %s" % isinstance(cw, QtWidgets.QComboBox) + + cw_index = self.ui.tools_table.indexAt(cw.pos()) + cw_row = cw_index.row() + cw_col = cw_index.column() + + current_uid = int(self.ui.tools_table.item(cw_row, 3).text()) + + # if the sender is in the column with index 2 then we update the tool_type key + if cw_col == 2: + tt = cw.currentText() + typ = 'Iso' if tt == 'V' else 'Rough' + + self.paint_tools[current_uid].update({ + 'type': typ, + 'tool_type': tt, + }) + + def on_order_changed(self, order): + if order != 'no': + self.build_ui() + def rebuild_ui(self): # read the table tools uid current_uid_list = [] diff --git a/appPlugins/ToolPanelize.py b/appPlugins/ToolPanelize.py index 05f415e8..cfc78450 100644 --- a/appPlugins/ToolPanelize.py +++ b/appPlugins/ToolPanelize.py @@ -45,19 +45,7 @@ class Panelize(AppTool): # ############################################################################# self.ui = PanelizeUI(layout=self.layout, app=self.app) self.pluginName = self.ui.pluginName - - # ############################################################################# - # ############################ SIGNALS ######################################## - # ############################################################################# - self.ui.level.toggled.connect(self.on_level_changed) - self.ui.reference_radio.activated_custom.connect(self.on_reference_radio_changed) - self.ui.panelize_object_button.clicked.connect(self.on_panelize) - self.ui.type_obj_combo.currentIndexChanged.connect(self.on_type_obj_index_changed) - self.ui.type_box_combo.currentIndexChanged.connect(self.on_type_box_index_changed) - - self.app.proj_selection_changed.connect(self.on_object_selection_changed) - - self.ui.reset_button.clicked.connect(self.set_tool_ui) + self.connect_signals_at_init() # list to hold the temporary objects self.objs = [] @@ -116,7 +104,23 @@ class Panelize(AppTool): def install(self, icon=None, separator=None, **kwargs): AppTool.install(self, icon, separator, shortcut='Alt+Z', **kwargs) + def connect_signals_at_init(self): + self.ui.level.toggled.connect(self.on_level_changed) + self.ui.reference_radio.activated_custom.connect(self.on_reference_radio_changed) + self.ui.panelize_object_button.clicked.connect(self.on_panelize) + self.ui.type_obj_combo.currentIndexChanged.connect(self.on_type_obj_index_changed) + self.ui.type_box_combo.currentIndexChanged.connect(self.on_type_box_index_changed) + + self.app.proj_selection_changed.connect(self.on_object_selection_changed) + + self.ui.reset_button.clicked.connect(self.set_tool_ui) + def set_tool_ui(self): + self.clear_ui(self.layout) + self.ui = PanelizeUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() + self.reset_fields() self.ui.reference_radio.set_value('bbox') diff --git a/appPlugins/ToolPcbWizard.py b/appPlugins/ToolPcbWizard.py index a9a4a53a..8abc2401 100644 --- a/appPlugins/ToolPcbWizard.py +++ b/appPlugins/ToolPcbWizard.py @@ -39,6 +39,7 @@ class PcbWizard(AppTool): # ############################################################################# self.ui = WizardUI(layout=self.layout, app=self.app) self.pluginName = self.ui.pluginName + self.connect_signals_at_init() self.excellon_loaded = False self.inf_loaded = False @@ -46,15 +47,6 @@ class PcbWizard(AppTool): self.modified_excellon_file = '' - # ## Signals - self.ui.excellon_brn.clicked.connect(self.on_load_excellon_click) - self.ui.inf_btn.clicked.connect(self.on_load_inf_click) - self.ui.import_button.clicked.connect(lambda: self.on_import_excellon( - excellon_fileobj=self.modified_excellon_file)) - - self.file_loaded.connect(self.on_file_loaded) - self.ui.units_radio.activated_custom.connect(self.ui.on_units_change) - self.units = 'INCH' self.zeros = 'LZ' self.integral = 2 @@ -113,12 +105,27 @@ class PcbWizard(AppTool): def install(self, icon=None, separator=None, **kwargs): AppTool.install(self, icon, separator, **kwargs) + def connect_signals_at_init(self): + # ## Signals + self.ui.excellon_brn.clicked.connect(self.on_load_excellon_click) + self.ui.inf_btn.clicked.connect(self.on_load_inf_click) + self.ui.import_button.clicked.connect(lambda: self.on_import_excellon( + excellon_fileobj=self.modified_excellon_file)) + + self.file_loaded.connect(self.on_file_loaded) + self.ui.units_radio.activated_custom.connect(self.ui.on_units_change) + def set_tool_ui(self): self.units = 'INCH' self.zeros = 'LZ' self.integral = 2 self.fractional = 4 + self.clear_ui(self.layout) + self.ui = WizardUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() + self.outname = 'file' self.exc_file_content = None diff --git a/appPlugins/ToolPunchGerber.py b/appPlugins/ToolPunchGerber.py index de066952..ec704ca4 100644 --- a/appPlugins/ToolPunchGerber.py +++ b/appPlugins/ToolPunchGerber.py @@ -71,54 +71,7 @@ class ToolPunchGerber(AppTool, Gerber): # ############################################################################# self.ui = PunchUI(layout=self.layout, app=self.app) self.pluginName = self.ui.pluginName - - # ############################################################################# - # ############################ SIGNALS ######################################## - # ############################################################################# - self.ui.level.toggled.connect(self.on_level_changed) - self.ui.method_punch.activated_custom.connect(self.on_method) - self.ui.reset_button.clicked.connect(self.set_tool_ui) - self.ui.punch_object_button.clicked.connect(self.on_punch_object_click) - - self.ui.circular_cb.stateChanged.connect( - lambda state: - self.ui.circular_ring_entry.setDisabled(False) if state else - self.ui.circular_ring_entry.setDisabled(True) - ) - - self.ui.oblong_cb.stateChanged.connect( - lambda state: - self.ui.oblong_ring_entry.setDisabled(False) if state else self.ui.oblong_ring_entry.setDisabled(True) - ) - - self.ui.square_cb.stateChanged.connect( - lambda state: - self.ui.square_ring_entry.setDisabled(False) if state else self.ui.square_ring_entry.setDisabled(True) - ) - - self.ui.rectangular_cb.stateChanged.connect( - lambda state: - self.ui.rectangular_ring_entry.setDisabled(False) if state else - self.ui.rectangular_ring_entry.setDisabled(True) - ) - - self.ui.other_cb.stateChanged.connect( - lambda state: - self.ui.other_ring_entry.setDisabled(False) if state else self.ui.other_ring_entry.setDisabled(True) - ) - - self.ui.circular_cb.stateChanged.connect(self.build_tool_ui) - self.ui.oblong_cb.stateChanged.connect(self.build_tool_ui) - self.ui.square_cb.stateChanged.connect(self.build_tool_ui) - self.ui.rectangular_cb.stateChanged.connect(self.build_tool_ui) - self.ui.other_cb.stateChanged.connect(self.build_tool_ui) - - self.ui.gerber_object_combo.currentIndexChanged.connect(self.build_tool_ui) - self.ui.gerber_object_combo.currentIndexChanged.connect(self.on_object_combo_changed) - - self.ui.punch_type_radio.activated_custom.connect(self.on_punch_type) - self.ui.sel_all_btn.clicked.connect(self.on_manual_sel_all) - self.ui.clear_all_btn.clicked.connect(self.on_manual_clear_all) + self.connect_signals_at_init() def on_object_combo_changed(self): # get the Gerber file who is the source of the punched Gerber @@ -196,7 +149,58 @@ class ToolPunchGerber(AppTool, Gerber): def install(self, icon=None, separator=None, **kwargs): AppTool.install(self, icon, separator, shortcut='Alt+H', **kwargs) + def connect_signals_at_init(self): + self.ui.level.toggled.connect(self.on_level_changed) + self.ui.method_punch.activated_custom.connect(self.on_method) + self.ui.reset_button.clicked.connect(self.set_tool_ui) + self.ui.punch_object_button.clicked.connect(self.on_punch_object_click) + + self.ui.circular_cb.stateChanged.connect( + lambda state: + self.ui.circular_ring_entry.setDisabled(False) if state else + self.ui.circular_ring_entry.setDisabled(True) + ) + + self.ui.oblong_cb.stateChanged.connect( + lambda state: + self.ui.oblong_ring_entry.setDisabled(False) if state else self.ui.oblong_ring_entry.setDisabled(True) + ) + + self.ui.square_cb.stateChanged.connect( + lambda state: + self.ui.square_ring_entry.setDisabled(False) if state else self.ui.square_ring_entry.setDisabled(True) + ) + + self.ui.rectangular_cb.stateChanged.connect( + lambda state: + self.ui.rectangular_ring_entry.setDisabled(False) if state else + self.ui.rectangular_ring_entry.setDisabled(True) + ) + + self.ui.other_cb.stateChanged.connect( + lambda state: + self.ui.other_ring_entry.setDisabled(False) if state else self.ui.other_ring_entry.setDisabled(True) + ) + + self.ui.circular_cb.stateChanged.connect(self.build_tool_ui) + self.ui.oblong_cb.stateChanged.connect(self.build_tool_ui) + self.ui.square_cb.stateChanged.connect(self.build_tool_ui) + self.ui.rectangular_cb.stateChanged.connect(self.build_tool_ui) + self.ui.other_cb.stateChanged.connect(self.build_tool_ui) + + self.ui.gerber_object_combo.currentIndexChanged.connect(self.build_tool_ui) + self.ui.gerber_object_combo.currentIndexChanged.connect(self.on_object_combo_changed) + + self.ui.punch_type_radio.activated_custom.connect(self.on_punch_type) + self.ui.sel_all_btn.clicked.connect(self.on_manual_sel_all) + self.ui.clear_all_btn.clicked.connect(self.on_manual_clear_all) + def set_tool_ui(self): + self.clear_ui(self.layout) + self.ui = PunchUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() + self.reset_fields() self.ui_disconnect() diff --git a/appPlugins/ToolQRCode.py b/appPlugins/ToolQRCode.py index 36e93c06..55268092 100644 --- a/appPlugins/ToolQRCode.py +++ b/appPlugins/ToolQRCode.py @@ -54,6 +54,7 @@ class QRCode(AppTool): # ############################################################################# self.ui = QRcodeUI(layout=self.layout, app=self.app) self.pluginName = self.ui.pluginName + self.connect_signals_at_init() self.grb_object = None self.box_poly = None @@ -71,23 +72,6 @@ class QRCode(AppTool): self.old_back_color = '' - # ############################################################################# - # ############################ SIGNALS ######################################## - # ############################################################################# - self.ui.level.toggled.connect(self.on_level_changed) - self.ui.qrcode_button.clicked.connect(self.execute) - self.ui.export_cb.stateChanged.connect(self.on_export_frame) - self.ui.export_png_button.clicked.connect(self.export_png_file) - self.ui.export_svg_button.clicked.connect(self.export_svg_file) - - self.ui.fill_color_entry.editingFinished.connect(self.on_qrcode_fill_color_entry) - self.ui.fill_color_button.clicked.connect(self.on_qrcode_fill_color_button) - self.ui.back_color_entry.editingFinished.connect(self.on_qrcode_back_color_entry) - self.ui.back_color_button.clicked.connect(self.on_qrcode_back_color_button) - - self.ui.transparent_cb.stateChanged.connect(self.on_transparent_back_color) - self.ui.reset_button.clicked.connect(self.set_tool_ui) - def run(self, toggle=True): self.app.defaults.report_usage("QRCode()") @@ -137,8 +121,29 @@ class QRCode(AppTool): def install(self, icon=None, separator=None, **kwargs): AppTool.install(self, icon, separator, shortcut='Alt+Q', **kwargs) + def connect_signals_at_init(self): + self.ui.level.toggled.connect(self.on_level_changed) + self.ui.qrcode_button.clicked.connect(self.execute) + self.ui.export_cb.stateChanged.connect(self.on_export_frame) + self.ui.export_png_button.clicked.connect(self.export_png_file) + self.ui.export_svg_button.clicked.connect(self.export_svg_file) + + self.ui.fill_color_entry.editingFinished.connect(self.on_qrcode_fill_color_entry) + self.ui.fill_color_button.clicked.connect(self.on_qrcode_fill_color_button) + self.ui.back_color_entry.editingFinished.connect(self.on_qrcode_back_color_entry) + self.ui.back_color_button.clicked.connect(self.on_qrcode_back_color_button) + + self.ui.transparent_cb.stateChanged.connect(self.on_transparent_back_color) + self.ui.reset_button.clicked.connect(self.set_tool_ui) + def set_tool_ui(self): self.units = self.app.defaults['units'] + + self.clear_ui(self.layout) + self.ui = QRcodeUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() + self.ui.border_size_entry.set_value(4) self.ui.version_entry.set_value(int(self.app.defaults["tools_qrcode_version"])) diff --git a/appPlugins/ToolRulesCheck.py b/appPlugins/ToolRulesCheck.py index 641c6545..52ae045b 100644 --- a/appPlugins/ToolRulesCheck.py +++ b/appPlugins/ToolRulesCheck.py @@ -42,32 +42,7 @@ class RulesCheck(AppTool): # ############################################################################# self.ui = RulesUI(layout=self.layout, app=self.app) self.pluginName = self.ui.pluginName - - # ####################################################### - # ################ SIGNALS ############################## - # ####################################################### - self.ui.copper_t_cb.stateChanged.connect(lambda st: self.ui.copper_t_object.setDisabled(not st)) - self.ui.copper_b_cb.stateChanged.connect(lambda st: self.ui.copper_b_object.setDisabled(not st)) - - self.ui.sm_t_cb.stateChanged.connect(lambda st: self.ui.sm_t_object.setDisabled(not st)) - self.ui.sm_b_cb.stateChanged.connect(lambda st: self.ui.sm_b_object.setDisabled(not st)) - - self.ui.ss_t_cb.stateChanged.connect(lambda st: self.ui.ss_t_object.setDisabled(not st)) - self.ui.ss_b_cb.stateChanged.connect(lambda st: self.ui.ss_b_object.setDisabled(not st)) - - self.ui.out_cb.stateChanged.connect(lambda st: self.ui.outline_object.setDisabled(not st)) - - self.ui.e1_cb.stateChanged.connect(lambda st: self.ui.e1_object.setDisabled(not st)) - self.ui.e2_cb.stateChanged.connect(lambda st: self.ui.e2_object.setDisabled(not st)) - - self.ui.all_obj_cb.stateChanged.connect(self.ui.on_all_objects_cb_changed) - self.ui.all_cb.stateChanged.connect(self.ui.on_all_cb_changed) - self.ui.run_button.clicked.connect(self.execute) - - self.ui.reset_button.clicked.connect(self.set_tool_ui) - - # Custom Signals - self.tool_finished.connect(self.on_tool_finished) + self.connect_signals_at_init() # list to hold the temporary objects self.objs = [] @@ -135,7 +110,35 @@ class RulesCheck(AppTool): def install(self, icon=None, separator=None, **kwargs): AppTool.install(self, icon, separator, shortcut='Alt+R', **kwargs) + def connect_signals_at_init(self): + self.ui.copper_t_cb.stateChanged.connect(lambda st: self.ui.copper_t_object.setDisabled(not st)) + self.ui.copper_b_cb.stateChanged.connect(lambda st: self.ui.copper_b_object.setDisabled(not st)) + + self.ui.sm_t_cb.stateChanged.connect(lambda st: self.ui.sm_t_object.setDisabled(not st)) + self.ui.sm_b_cb.stateChanged.connect(lambda st: self.ui.sm_b_object.setDisabled(not st)) + + self.ui.ss_t_cb.stateChanged.connect(lambda st: self.ui.ss_t_object.setDisabled(not st)) + self.ui.ss_b_cb.stateChanged.connect(lambda st: self.ui.ss_b_object.setDisabled(not st)) + + self.ui.out_cb.stateChanged.connect(lambda st: self.ui.outline_object.setDisabled(not st)) + + self.ui.e1_cb.stateChanged.connect(lambda st: self.ui.e1_object.setDisabled(not st)) + self.ui.e2_cb.stateChanged.connect(lambda st: self.ui.e2_object.setDisabled(not st)) + + self.ui.all_obj_cb.stateChanged.connect(self.ui.on_all_objects_cb_changed) + self.ui.all_cb.stateChanged.connect(self.ui.on_all_cb_changed) + self.ui.run_button.clicked.connect(self.execute) + + self.ui.reset_button.clicked.connect(self.set_tool_ui) + + # Custom Signals + self.tool_finished.connect(self.on_tool_finished) + def set_tool_ui(self): + self.clear_ui(self.layout) + self.ui = RulesUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() # all object combobox default as disabled self.ui.copper_t_object.setDisabled(True) diff --git a/appPlugins/ToolSolderPaste.py b/appPlugins/ToolSolderPaste.py index 70c67680..23c53ee5 100644 --- a/appPlugins/ToolSolderPaste.py +++ b/appPlugins/ToolSolderPaste.py @@ -48,6 +48,7 @@ class SolderPaste(AppTool): # ############################################################################# self.ui = SolderUI(layout=self.layout, app=self.app, solder_class=self) self.pluginName = self.ui.pluginName + self.connect_signals_at_init() self.tooltable_tools = {} self.tooluid = 0 @@ -67,27 +68,6 @@ class SolderPaste(AppTool): # stpre here the flattened geometry self.flat_geometry = [] - # action to be added in the combobox context menu - self.combo_context_del_action = QtWidgets.QAction(QtGui.QIcon(self.app.resource_location + '/trash16.png'), - _("Delete Object")) - - # ## Signals - self.combo_context_del_action.triggered.connect(self.on_delete_object) - - self.ui.addtool_btn.clicked.connect(self.on_tool_add) - self.ui.addtool_entry.returnPressed.connect(self.on_tool_add) - self.ui.deltool_btn.clicked.connect(self.on_tool_delete) - self.ui.soldergeo_btn.clicked.connect(self.on_create_geo_click) - self.ui.solder_gcode_btn.clicked.connect(self.on_create_gcode_click) - self.ui.solder_gcode_view_btn.clicked.connect(self.on_view_gcode) - self.ui.solder_gcode_save_btn.clicked.connect(self.on_save_gcode) - - self.ui.geo_obj_combo.currentIndexChanged.connect(self.on_geo_select) - self.ui.cnc_obj_combo.currentIndexChanged.connect(self.on_cncjob_select) - - self.app.object_status_changed.connect(self.update_comboboxes) - self.ui.reset_button.clicked.connect(self.set_tool_ui) - def run(self, toggle=True): self.app.defaults.report_usage("ToolSolderPaste()") @@ -137,23 +117,43 @@ class SolderPaste(AppTool): def install(self, icon=None, separator=None, **kwargs): AppTool.install(self, icon, separator, shortcut='Alt+K', **kwargs) - def on_add_tool_by_key(self): - tool_add_popup = FCInputSpinner(title='%s...' % _("New Tool"), - text='%s:' % _('Enter a Tool Diameter'), - min=0.0000, max=100.0000, decimals=self.decimals, step=0.1) - tool_add_popup.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/letter_t_32.png')) + def clear_context_menu(self): + self.ui.tools_table.removeContextMenu() - val, ok = tool_add_popup.get_value() - if ok: - if float(val) == 0: - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("Please enter a tool diameter with non-zero value, in Float format.")) - return - self.on_tool_add(dia=float(val)) - else: - self.app.inform.emit('[WARNING_NOTCL] %s...' % _("Adding Tool cancelled")) + def init_context_menu(self): + self.ui.tools_table.setupContextMenu() + self.ui.tools_table.addContextMenu( + _("Add"), lambda: self.on_tool_add(dia=None, muted=None), + icon=QtGui.QIcon(self.app.resource_location + "/plus16.png")) + self.ui.tools_table.addContextMenu( + _("Delete"), lambda: + self.on_tool_delete(rows_to_delete=None, all_tools=None), + icon=QtGui.QIcon(self.app.resource_location + "/delete32.png") + ) + + def connect_signals_at_init(self): + self.ui.combo_context_del_action.triggered.connect(self.on_delete_object) + + self.ui.addtool_btn.clicked.connect(self.on_tool_add) + self.ui.addtool_entry.returnPressed.connect(self.on_tool_add) + self.ui.deltool_btn.clicked.connect(self.on_tool_delete) + self.ui.soldergeo_btn.clicked.connect(self.on_create_geo_click) + self.ui.solder_gcode_btn.clicked.connect(self.on_create_gcode_click) + self.ui.solder_gcode_view_btn.clicked.connect(self.on_view_gcode) + self.ui.solder_gcode_save_btn.clicked.connect(self.on_save_gcode) + + self.ui.geo_obj_combo.currentIndexChanged.connect(self.on_geo_select) + self.ui.cnc_obj_combo.currentIndexChanged.connect(self.on_cncjob_select) + + self.app.object_status_changed.connect(self.update_comboboxes) + self.ui.reset_button.clicked.connect(self.set_tool_ui) def set_tool_ui(self): + self.clear_ui(self.layout) + self.ui = SolderUI(layout=self.layout, app=self.app, solder_class=self) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() + self.form_fields.update({ "tools_solderpaste_new": self.ui.addtool_entry, "tools_solderpaste_z_start": self.ui.z_start_entry, @@ -174,15 +174,8 @@ class SolderPaste(AppTool): self.set_form_from_defaults() self.read_form_to_options() - self.ui.tools_table.setupContextMenu() - self.ui.tools_table.addContextMenu( - _("Add"), lambda: self.on_tool_add(dia=None, muted=None), - icon=QtGui.QIcon(self.app.resource_location + "/plus16.png")) - self.ui.tools_table.addContextMenu( - _("Delete"), lambda: - self.on_tool_delete(rows_to_delete=None, all_tools=None), - icon=QtGui.QIcon(self.app.resource_location + "/delete32.png") - ) + self.clear_context_menu() + self.init_context_menu() # either originally it was a string or not, xy_end will be made string dias_option = self.app.defaults["tools_solderpaste_tools"] @@ -333,6 +326,22 @@ class SolderPaste(AppTool): self.ui_connect() + def on_add_tool_by_key(self): + tool_add_popup = FCInputSpinner(title='%s...' % _("New Tool"), + text='%s:' % _('Enter a Tool Diameter'), + min=0.0000, max=100.0000, decimals=self.decimals, step=0.1) + tool_add_popup.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/letter_t_32.png')) + + val, ok = tool_add_popup.get_value() + if ok: + if float(val) == 0: + self.app.inform.emit('[WARNING_NOTCL] %s' % + _("Please enter a tool diameter with non-zero value, in Float format.")) + return + self.on_tool_add(dia=float(val)) + else: + self.app.inform.emit('[WARNING_NOTCL] %s...' % _("Adding Tool cancelled")) + def on_row_selection_change(self): sel_model = self.ui.tools_table.selectionModel() sel_indexes = sel_model.selectedIndexes() @@ -642,7 +651,7 @@ class SolderPaste(AppTool): self.obj_to_be_deleted_name = combo.model().itemData(idx)[0] menu = QtWidgets.QMenu() - menu.addAction(self.combo_context_del_action) + menu.addAction(self.ui.combo_context_del_action) menu.exec(view.mapToGlobal(pos)) def on_delete_object(self): @@ -1594,6 +1603,10 @@ class SolderUI: """) self.layout.addWidget(self.reset_button) + # action to be added in the combobox context menu + self.combo_context_del_action = QtWidgets.QAction(QtGui.QIcon(self.app.resource_location + '/trash16.png'), + _("Delete Object")) + # #################################### FINSIHED GUI ########################### # ############################################################################# diff --git a/appPlugins/ToolSub.py b/appPlugins/ToolSub.py index 77230042..1272eadc 100644 --- a/appPlugins/ToolSub.py +++ b/appPlugins/ToolSub.py @@ -48,6 +48,7 @@ class ToolSub(AppTool): # ############################################################################# self.ui = SubUI(layout=self.layout, app=self.app) self.pluginName = self.ui.pluginName + self.connect_signals_at_init() # QTimer for periodic check self.check_thread = QtCore.QTimer() @@ -86,20 +87,6 @@ class ToolSub(AppTool): self.pool = self.app.pool self.results = [] - # ############################################################################# - # ############################ SIGNALS ######################################## - # ############################################################################# - self.ui.level.toggled.connect(self.on_level_changed) - self.ui.intersect_btn.clicked.connect(self.on_subtract_gerber_click) - self.ui.intersect_geo_btn.clicked.connect(self.on_subtract_geo_click) - self.ui.reset_button.clicked.connect(self.set_tool_ui) - - self.app.proj_selection_changed.connect(self.on_object_selection_changed) - - # Custom Signals - self.job_finished.connect(self.on_job_finished) - self.aperture_processing_finished.connect(self.new_gerber_object) - def install(self, icon=None, separator=None, **kwargs): AppTool.install(self, icon, separator, shortcut='Alt+W', **kwargs) @@ -179,12 +166,29 @@ class ToolSub(AppTool): except Exception: pass + def connect_signals_at_init(self): + self.ui.level.toggled.connect(self.on_level_changed) + self.ui.intersect_btn.clicked.connect(self.on_subtract_gerber_click) + self.ui.intersect_geo_btn.clicked.connect(self.on_subtract_geo_click) + self.ui.reset_button.clicked.connect(self.set_tool_ui) + + self.app.proj_selection_changed.connect(self.on_object_selection_changed) + + # Custom Signals + self.job_finished.connect(self.on_job_finished) + self.aperture_processing_finished.connect(self.new_gerber_object) + def set_tool_ui(self): self.new_apertures.clear() self.new_tools.clear() self.new_solid_geometry = [] self.target_options.clear() + self.clear_ui(self.layout) + self.ui = SubUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() + self.ui.tools_frame.show() self.ui.close_paths_cb.setChecked(self.app.defaults["tools_sub_close_paths"]) self.ui.delete_sources_cb.setChecked(self.app.defaults["tools_sub_delete_sources"]) diff --git a/appPlugins/ToolTransform.py b/appPlugins/ToolTransform.py index a38de0fd..170d1f09 100644 --- a/appPlugins/ToolTransform.py +++ b/appPlugins/ToolTransform.py @@ -32,30 +32,7 @@ class ToolTransform(AppTool): # ############################################################################# self.ui = TransformUI(layout=self.layout, app=self.app) self.pluginName = self.ui.pluginName - - # ## Signals - self.ui.ref_combo.currentIndexChanged.connect(self.ui.on_reference_changed) - self.ui.type_obj_combo.currentIndexChanged.connect(self.on_type_obj_index_changed) - self.ui.point_button.clicked.connect(self.on_add_coords) - - self.ui.rotate_button.clicked.connect(self.on_rotate) - - self.ui.skewx_button.clicked.connect(self.on_skewx) - self.ui.skewy_button.clicked.connect(self.on_skewy) - - self.ui.scalex_button.clicked.connect(self.on_scalex) - self.ui.scaley_button.clicked.connect(self.on_scaley) - - self.ui.offx_button.clicked.connect(self.on_offx) - self.ui.offy_button.clicked.connect(self.on_offy) - - self.ui.flipx_button.clicked.connect(self.on_flipx) - self.ui.flipy_button.clicked.connect(self.on_flipy) - - self.ui.buffer_button.clicked.connect(self.on_buffer_by_distance) - self.ui.buffer_factor_button.clicked.connect(self.on_buffer_by_factor) - - self.ui.reset_button.clicked.connect(self.set_tool_ui) + self.connect_signals_at_init() def run(self, toggle=True): self.app.defaults.report_usage("ToolTransform()") @@ -105,7 +82,36 @@ class ToolTransform(AppTool): def install(self, icon=None, separator=None, **kwargs): AppTool.install(self, icon, separator, shortcut='Alt+T', **kwargs) + def connect_signals_at_init(self): + # ## Signals + self.ui.ref_combo.currentIndexChanged.connect(self.ui.on_reference_changed) + self.ui.type_obj_combo.currentIndexChanged.connect(self.on_type_obj_index_changed) + self.ui.point_button.clicked.connect(self.on_add_coords) + + self.ui.rotate_button.clicked.connect(self.on_rotate) + + self.ui.skewx_button.clicked.connect(self.on_skewx) + self.ui.skewy_button.clicked.connect(self.on_skewy) + + self.ui.scalex_button.clicked.connect(self.on_scalex) + self.ui.scaley_button.clicked.connect(self.on_scaley) + + self.ui.offx_button.clicked.connect(self.on_offx) + self.ui.offy_button.clicked.connect(self.on_offy) + + self.ui.flipx_button.clicked.connect(self.on_flipx) + self.ui.flipy_button.clicked.connect(self.on_flipy) + + self.ui.buffer_button.clicked.connect(self.on_buffer_by_distance) + self.ui.buffer_factor_button.clicked.connect(self.on_buffer_by_factor) + + self.ui.reset_button.clicked.connect(self.set_tool_ui) + def set_tool_ui(self): + self.clear_ui(self.layout) + self.ui = TransformUI(layout=self.layout, app=self.app) + self.pluginName = self.ui.pluginName + self.connect_signals_at_init() # ## Initialize form self.ui.ref_combo.set_value(self.app.defaults["tools_transform_reference"]) diff --git a/appTool.py b/appTool.py index cc325a7f..24542ebb 100644 --- a/appTool.py +++ b/appTool.py @@ -101,9 +101,25 @@ class AppTool(QtWidgets.QWidget): self.show() - def clear_ui(self): - for i in reversed(range(self.layout.count())): - self.layout.itemAt(i).widget().setParent(None) + def clear_ui(self, layout): + # for item in reversed(range(layout.count())): + # lay_item = layout.itemAt(item) + # + # # in case that the widget is None + # try: + # widget = lay_item.widget() + # widget.setParent(None) + # except AttributeError: + # pass + + if layout is not None: + while layout.count(): + item = layout.takeAt(0) + widget = item.widget() + if widget is not None: + widget.setParent(None) + else: + self.clear_ui(item.layout()) def draw_tool_selection_shape(self, old_coords, coords, **kwargs): """ diff --git a/app_Main.py b/app_Main.py index 143e7abf..129adb99 100644 --- a/app_Main.py +++ b/app_Main.py @@ -1442,7 +1442,7 @@ class App(QtCore.QObject): # Notebook tab clicking self.ui.notebook.tabBarClicked.connect(self.on_properties_tab_click) - self.ui.notebook.callback_on_close = self.on_close_notebook_tab + # self.ui.notebook.callback_on_close = self.on_close_notebook_tab # ########################################################################################################### # #################################### GUI PREFERENCES SIGNALS ############################################## @@ -2869,7 +2869,7 @@ class App(QtCore.QObject): self.ui.plot_tab_area.protectTab(0) # restore the notebook tab close method to the app - self.ui.notebook.callback_on_close = self.on_close_notebook_tab + # self.ui.notebook.callback_on_close = self.on_close_notebook_tab # make sure that we reenable the selection on Project Tab after returning from Editor Mode: self.ui.project_frame.setDisabled(False) @@ -6500,16 +6500,39 @@ class App(QtCore.QObject): self.ui.toggle_delta_coords(checked=self.defaults["global_delta_coordsbar_show"]) def on_notebook_closed(self, tab_obj_name): - closed_plugin_name = self.ui.plugin_scroll_area.widget().objectName() - # print(closed_plugin_name) - if closed_plugin_name == _("Levelling"): - # clear the possible drawn probing shapes - self.levelling_tool.probing_shapes.clear(update=True) - elif closed_plugin_name in [_("Isolation"), _("NCC"), _("Paint"), _("Punch Gerber")]: - self.tool_shapes.clear(update=True) - def on_close_notebook_tab(self): - self.tool_shapes.clear(update=True) + # closed_plugin_name = self.ui.plugin_scroll_area.widget().objectName() + # # print(closed_plugin_name) + # if closed_plugin_name == _("Levelling"): + # # clear the possible drawn probing shapes + # self.levelling_tool.probing_shapes.clear(update=True) + # elif closed_plugin_name in [_("Isolation"), _("NCC"), _("Paint"), _("Punch Gerber")]: + # self.tool_shapes.clear(update=True) + + try: + # clear the possible drawn probing shapes for Levelling Tool + self.levelling_tool.probing_shapes.clear(update=True) + except AttributeError: + pass + + try: + # clean possible tool shapes for Isolation, NCC, Paint, Punch Gerber Plugins + self.tool_shapes.clear(update=True) + except AttributeError: + pass + + # clean the Tools Tab + found_idx = None + for idx in range(self.ui.notebook.count()): + if self.ui.notebook.widget(idx).objectName() == "plugin_tab": + found_idx = idx + break + if found_idx: + self.ui.notebook.setCurrentWidget(self.ui.properties_tab) + self.ui.notebook.removeTab(2) + + # def on_close_notebook_tab(self): + # self.tool_shapes.clear(update=True) def on_flipy(self): """ diff --git a/defaults.py b/defaults.py index a77f91ad..e6b889f2 100644 --- a/defaults.py +++ b/defaults.py @@ -307,56 +307,6 @@ class FlatCAMDefaults: # Geometry Export "geometry_dxf_format": 'R2010', - # Geometry Options - "tools_mill_tooldia": "2.4", - "tools_mill_offset_type": 0, # _('Path') - "tools_mill_offset": 0.0, - "tools_mill_job_type": 0, # 'Rough' - - "tools_mill_cutz": -2.4, - "tools_mill_vtipdia": 0.1, - "tools_mill_vtipangle": 30, - "tools_mill_multidepth": False, - "tools_mill_depthperpass": 0.8, - "tools_mill_travelz": 2, - - "tools_mill_toolchange": False, - "tools_mill_toolchangez": 15.0, - "tools_mill_endz": 15.0, - "tools_mill_endxy": None, - - "tools_mill_feedrate": 120, - "tools_mill_feedrate_z": 60, - "tools_mill_spindlespeed": 0, - "tools_mill_dwell": False, - "tools_mill_dwelltime": 1, - "tools_mill_ppname_g": 'default', - - # Geometry Advanced Options - "tools_mill_toolchangexy": "0.0, 0.0", - "tools_mill_startz": None, - "tools_mill_feedrate_rapid": 1500, - "tools_mill_extracut": False, - "tools_mill_extracut_length": 0.1, - "tools_mill_z_pdepth": -0.02, - "tools_mill_f_plunge": False, - "tools_mill_spindledir": 'CW', - "tools_mill_feedrate_probe": 75, - - "tools_mill_area_exclusion": False, - "tools_mill_area_shape": "polygon", - "tools_mill_area_strategy": "over", - "tools_mill_area_overz": 1.0, - # Polish - "tools_mill_polish": False, - "tools_mill_polish_margin": 0.0, - "tools_mill_polish_overlap": 5, - "tools_mill_polish_method": 0, - - "tools_mill_milling_type": 'both', - "tools_mill_optimization_type": 'R', - "tools_mill_search_time": 3, - # Geometry Editor "geometry_editor_sel_limit": 30, "geometry_editor_milling_type": "cl", @@ -397,7 +347,7 @@ class FlatCAMDefaults: "cncjob_prepend": "", "cncjob_append": "", - # Isolation Routing Tool + # Isolation Routing Plugin "tools_iso_tooldia": "0.1", "tools_iso_order": 'rev', "tools_iso_tool_type": 'C1', @@ -421,7 +371,7 @@ class FlatCAMDefaults: "tools_iso_area_shape": "square", "tools_iso_plotting": 'normal', - # Drilling Tool + # Drilling Plugin "tools_drill_tool_order": 'no', "tools_drill_cutz": -1.7, "tools_drill_multidepth": False, @@ -458,10 +408,61 @@ class FlatCAMDefaults: "tools_drill_area_strategy": "over", "tools_drill_area_overz": 1.0, - # Milling Tool + # Milling Plugin "tools_mill_tool_type": 'C1', - # Autolevelling Tool + # Milling Plugin Options + "tools_mill_tooldia": "2.4", + "tools_mill_offset_type": 0, # _('Path') + "tools_mill_offset": 0.0, + "tools_mill_job_type": 0, # 'Rough' + + "tools_mill_cutz": -2.4, + "tools_mill_vtipdia": 0.1, + "tools_mill_vtipangle": 30, + "tools_mill_multidepth": False, + "tools_mill_depthperpass": 0.8, + "tools_mill_travelz": 2, + + "tools_mill_toolchange": False, + "tools_mill_toolchangez": 15.0, + "tools_mill_endz": 15.0, + "tools_mill_endxy": None, + + "tools_mill_feedrate": 120, + "tools_mill_feedrate_z": 60, + "tools_mill_spindlespeed": 0, + "tools_mill_dwell": False, + "tools_mill_dwelltime": 1, + "tools_mill_ppname_g": 'default', + + # Milling Plugin Advanced Options + "tools_mill_toolchangexy": "0.0, 0.0", + "tools_mill_startz": None, + "tools_mill_feedrate_rapid": 1500, + "tools_mill_extracut": False, + "tools_mill_extracut_length": 0.1, + "tools_mill_z_pdepth": -0.02, + "tools_mill_f_plunge": False, + "tools_mill_spindledir": 'CW', + "tools_mill_feedrate_probe": 75, + + "tools_mill_area_exclusion": False, + "tools_mill_area_shape": "polygon", + "tools_mill_area_strategy": "over", + "tools_mill_area_overz": 1.0, + + # Polish + "tools_mill_polish": False, + "tools_mill_polish_margin": 0.0, + "tools_mill_polish_overlap": 5, + "tools_mill_polish_method": 0, + + "tools_mill_milling_type": 'both', + "tools_mill_optimization_type": 'R', + "tools_mill_search_time": 3, + + # Autolevelling Plugin "tools_al_status": False, "tools_al_mode": 'grid', "tools_al_method": 'v', @@ -475,7 +476,7 @@ class FlatCAMDefaults: "tools_al_grbl_jog_fr": 1500, "tools_al_grbl_travelz": 15.0, - # NCC Tool + # NCC Plugin "tools_ncc_tools": "0.5", "tools_ncc_order": 'rev', "tools_ncc_operation": 'clear',