Procházet zdrojové kódy

Merged in Beta_8.994 (pull request #328)

Beta 8.994 - bug fixes
Marius Stanciu před 5 roky
rodič
revize
c70cf12792

+ 13 - 1
CHANGELOG.md

@@ -7,6 +7,16 @@ CHANGELOG for FlatCAM beta
 
 
 =================================================
 =================================================
 
 
+30.10.2020
+
+- fixed the Punch Gerber Tool bug that did not allowed the projects to be loaded or to create a new project. Fixed issue #456
+- in Tool Subtract added an option to delete the source objects after a successful operation. Fixed issue #455
+- when entering into an Editor now the Project tab is disabled and the Properties tab where the Editor is installed change the text to 'Editor' and the color is set in Red. After exiting the Tab text is reverted to previous state.
+- fixed and issue where the Tab color that was changed in various states of the app was reverted back to a default color 'black'. Now it reverts to whatever color had before therefore being compatible with an usage of black theme
+- fixed bug that did not allow joining of any object to a Geometry object
+- working on solving the lost triggered signals for the Editor Toolbars buttons after changing the layout
+- fixed issue #454; trigger signals for Editor Toolbars lost after changing the layout
+
 29.10.2020
 29.10.2020
 
 
 - added icons in most application Tools
 - added icons in most application Tools
@@ -20,7 +30,7 @@ CHANGELOG for FlatCAM beta
 - fixed a small issue in GCode Editor where the signals for the buttons were attached again at each launch of the GCode Editor
 - fixed a small issue in GCode Editor where the signals for the buttons were attached again at each launch of the GCode Editor
 - fixed issues in the Tools Database due of recent changes in how the data structure is created
 - fixed issues in the Tools Database due of recent changes in how the data structure is created
 - made sure that the right tools go only to the intended use, in Tools Database otherwise an error status message is created and Tools DB is closed on adding a wrong tool
 - made sure that the right tools go only to the intended use, in Tools Database otherwise an error status message is created and Tools DB is closed on adding a wrong tool
-- fixed the usage for Tools Database in Unix-like OS's
+- fixed the usage for Tools Database in Unix-like OS's; fixed issue #453
 - done some modest refactoring
 - done some modest refactoring
 - fixed the Search and Add feature in Geometry Object UI
 - fixed the Search and Add feature in Geometry Object UI
 - fixed issue with preamble not being inserted when used alone
 - fixed issue with preamble not being inserted when used alone
@@ -29,6 +39,8 @@ CHANGELOG for FlatCAM beta
 - improvements in the Punch Gerber Tool aperture markings
 - improvements in the Punch Gerber Tool aperture markings
 - improved the Geometry Object functionality in regards of Tools DB, deleting a tool and adding a tool
 - improved the Geometry Object functionality in regards of Tools DB, deleting a tool and adding a tool
 - when using the 'T' shortcut key with Properties Tab in focus and populated with the properties of a Geometry Object made the popped up spinner to have the value autoselected
 - when using the 'T' shortcut key with Properties Tab in focus and populated with the properties of a Geometry Object made the popped up spinner to have the value autoselected
+- optimized the UI in Extract Drills Tool
+- added some more icons for buttons
 
 
 28.10.2020
 28.10.2020
 
 

+ 1 - 0
appCommon/Common.py

@@ -230,6 +230,7 @@ class ExclusionAreas(QtCore.QObject):
 
 
         self.app = app
         self.app = app
 
 
+        self.app.log.debug("+ Adding Exclusion Areas")
         # Storage for shapes, storage that can be used by FlatCAm tools for utility geometry
         # Storage for shapes, storage that can be used by FlatCAm tools for utility geometry
         # VisPy visuals
         # VisPy visuals
         if self.app.is_legacy is False:
         if self.app.is_legacy is False:

+ 9 - 1
appDatabase.py

@@ -1425,6 +1425,8 @@ class ToolsDB2(QtWidgets.QWidget):
         '''
         '''
         self.db_tool_dict = {}
         self.db_tool_dict = {}
 
 
+        self.old_color = QtGui.QColor('black')
+
         # ##############################################################################
         # ##############################################################################
         # ##############################################################################
         # ##############################################################################
         # TOOLS DATABASE UI
         # TOOLS DATABASE UI
@@ -1719,6 +1721,12 @@ class ToolsDB2(QtWidgets.QWidget):
         self.ui_connect()
         self.ui_connect()
 
 
     def setup_db_ui(self):
     def setup_db_ui(self):
+
+        # set the old color for the Tools Database Tab
+        for idx in range(self.app.ui.plot_tab_area.count()):
+            if self.app.ui.plot_tab_area.tabText(idx) == _("Tools Database"):
+                self.old_color = self.app.ui.plot_tab_area.tabBar.tabTextColor(idx)
+
         filename = self.app.tools_database_path()
         filename = self.app.tools_database_path()
 
 
         # load the database tools from the file
         # load the database tools from the file
@@ -2155,7 +2163,7 @@ class ToolsDB2(QtWidgets.QWidget):
         # Preferences save, update the color of the Tools DB Tab text
         # Preferences save, update the color of the Tools DB Tab text
         for idx in range(self.app_ui.plot_tab_area.count()):
         for idx in range(self.app_ui.plot_tab_area.count()):
             if self.app_ui.plot_tab_area.tabText(idx) == _("Tools Database"):
             if self.app_ui.plot_tab_area.tabText(idx) == _("Tools Database"):
-                self.app_ui.plot_tab_area.tabBar.setTabTextColor(idx, QtGui.QColor('black'))
+                self.app_ui.plot_tab_area.tabBar.setTabTextColor(idx, self.old_color)
                 self.ui.save_db_btn.setStyleSheet("")
                 self.ui.save_db_btn.setStyleSheet("")
 
 
                 # clean the dictionary and leave only keys of interest
                 # clean the dictionary and leave only keys of interest

+ 30 - 20
appEditors/AppExcEditor.py

@@ -1530,7 +1530,13 @@ class AppExcEditor(QtCore.QObject):
 
 
         self.e_ui = AppExcEditorUI(app=self.app)
         self.e_ui = AppExcEditorUI(app=self.app)
         
         
-        # SIGNALS
+        # #############################################################################################################
+        # ######################### Excellon Editor Signals ###########################################################
+        # #############################################################################################################
+
+        # connect the toolbar signals
+        self.connect_exc_toolbar_signals()
+
         self.e_ui.convert_slots_btn.clicked.connect(self.on_slots_conversion)
         self.e_ui.convert_slots_btn.clicked.connect(self.on_slots_conversion)
         self.app.ui.delete_drill_btn.triggered.connect(self.on_delete_btn)
         self.app.ui.delete_drill_btn.triggered.connect(self.on_delete_btn)
         self.e_ui.name_entry.returnPressed.connect(self.on_name_activate)
         self.e_ui.name_entry.returnPressed.connect(self.on_name_activate)
@@ -1564,16 +1570,7 @@ class AppExcEditor(QtCore.QObject):
         self.exc_obj = None
         self.exc_obj = None
 
 
         # ## Toolbar events and properties
         # ## Toolbar events and properties
-        self.tools_exc = {
-            "drill_select":     {"button": self.app.ui.select_drill_btn, "constructor": FCDrillSelect},
-            "drill_add":        {"button": self.app.ui.add_drill_btn, "constructor": FCDrillAdd},
-            "drill_array":      {"button": self.app.ui.add_drill_array_btn, "constructor": FCDrillArray},
-            "slot_add":         {"button": self.app.ui.add_slot_btn, "constructor": FCSlot},
-            "slot_array":       {"button": self.app.ui.add_slot_array_btn, "constructor": FCSlotArray},
-            "drill_resize":     {"button": self.app.ui.resize_drill_btn, "constructor": FCDrillResize},
-            "drill_copy":       {"button": self.app.ui.copy_drill_btn, "constructor": FCDrillCopy},
-            "drill_move":       {"button": self.app.ui.move_drill_btn, "constructor": FCDrillMove},
-        }
+        self.tools_exc = {}
 
 
         # ## Data
         # ## Data
         self.active_tool = None
         self.active_tool = None
@@ -1650,15 +1647,6 @@ class AppExcEditor(QtCore.QObject):
 
 
         self.complete = False
         self.complete = False
 
 
-        def make_callback(thetool):
-            def f():
-                self.on_tool_select(thetool)
-            return f
-
-        for tool in self.tools_exc:
-            self.tools_exc[tool]["button"].triggered.connect(make_callback(tool))  # Events
-            self.tools_exc[tool]["button"].setCheckable(True)  # Checkable
-
         self.options = {
         self.options = {
             "global_gridx":     0.1,
             "global_gridx":     0.1,
             "global_gridy":     0.1,
             "global_gridy":     0.1,
@@ -1706,6 +1694,28 @@ class AppExcEditor(QtCore.QObject):
         self.editor_active = False
         self.editor_active = False
         log.debug("Initialization of the Excellon Editor is finished ...")
         log.debug("Initialization of the Excellon Editor is finished ...")
 
 
+    def make_callback(self, thetool):
+        def f():
+            self.on_tool_select(thetool)
+
+        return f
+
+    def connect_exc_toolbar_signals(self):
+        self.tools_exc.update({
+            "drill_select":     {"button": self.app.ui.select_drill_btn,    "constructor": FCDrillSelect},
+            "drill_add":        {"button": self.app.ui.add_drill_btn,       "constructor": FCDrillAdd},
+            "drill_array":      {"button": self.app.ui.add_drill_array_btn, "constructor": FCDrillArray},
+            "slot_add":         {"button": self.app.ui.add_slot_btn,        "constructor": FCSlot},
+            "slot_array":       {"button": self.app.ui.add_slot_array_btn,  "constructor": FCSlotArray},
+            "drill_resize":     {"button": self.app.ui.resize_drill_btn,    "constructor": FCDrillResize},
+            "drill_copy":       {"button": self.app.ui.copy_drill_btn,      "constructor": FCDrillCopy},
+            "drill_move":       {"button": self.app.ui.move_drill_btn,      "constructor": FCDrillMove},
+        })
+
+        for tool in self.tools_exc:
+            self.tools_exc[tool]["button"].triggered.connect(self.make_callback(tool))  # Events
+            self.tools_exc[tool]["button"].setCheckable(True)  # Checkable
+
     def pool_recreated(self, pool):
     def pool_recreated(self, pool):
         self.shapes.pool = pool
         self.shapes.pool = pool
         self.tool_shape.pool = pool
         self.tool_shape.pool = pool

+ 37 - 25
appEditors/AppGeoEditor.py

@@ -3317,22 +3317,7 @@ class AppGeoEditor(QtCore.QObject):
         self.exit_editor_button.clicked.connect(lambda: self.app.editor2object())
         self.exit_editor_button.clicked.connect(lambda: self.app.editor2object())
 
 
         # ## Toolbar events and properties
         # ## Toolbar events and properties
-        self.tools = {
-            "select": {"button": self.app.ui.geo_select_btn, "constructor": FCSelect},
-            "arc": {"button": self.app.ui.geo_add_arc_btn, "constructor": FCArc},
-            "circle": {"button": self.app.ui.geo_add_circle_btn, "constructor": FCCircle},
-            "path": {"button": self.app.ui.geo_add_path_btn, "constructor": FCPath},
-            "rectangle": {"button": self.app.ui.geo_add_rectangle_btn, "constructor": FCRectangle},
-            "polygon": {"button": self.app.ui.geo_add_polygon_btn, "constructor": FCPolygon},
-            "text": {"button": self.app.ui.geo_add_text_btn, "constructor": FCText},
-            "buffer": {"button": self.app.ui.geo_add_buffer_btn, "constructor": FCBuffer},
-            "paint": {"button": self.app.ui.geo_add_paint_btn, "constructor": FCPaint},
-            "eraser": {"button": self.app.ui.geo_eraser_btn, "constructor": FCEraser},
-            "move": {"button": self.app.ui.geo_move_btn, "constructor": FCMove},
-            "transform": {"button": self.app.ui.geo_transform_btn, "constructor": FCTransform},
-            "copy": {"button": self.app.ui.geo_copy_btn, "constructor": FCCopy},
-            "explode": {"button": self.app.ui.geo_explode_btn, "constructor": FCExplode}
-        }
+        self.tools = {}
 
 
         # # ## Data
         # # ## Data
         self.active_tool = None
         self.active_tool = None
@@ -3388,15 +3373,6 @@ class AppGeoEditor(QtCore.QObject):
         # this will flag if the Editor "tools" are launched from key shortcuts (True) or from menu toolbar (False)
         # this will flag if the Editor "tools" are launched from key shortcuts (True) or from menu toolbar (False)
         self.launched_from_shortcuts = False
         self.launched_from_shortcuts = False
 
 
-        def make_callback(thetool):
-            def f():
-                self.on_tool_select(thetool)
-            return f
-
-        for tool in self.tools:
-            self.tools[tool]["button"].triggered.connect(make_callback(tool))  # Events
-            self.tools[tool]["button"].setCheckable(True)  # Checkable
-
         self.app.ui.grid_snap_btn.triggered.connect(self.on_grid_toggled)
         self.app.ui.grid_snap_btn.triggered.connect(self.on_grid_toggled)
         self.app.ui.corner_snap_btn.setCheckable(True)
         self.app.ui.corner_snap_btn.setCheckable(True)
         self.app.ui.corner_snap_btn.triggered.connect(lambda: self.toolbar_tool_toggle("corner_snap"))
         self.app.ui.corner_snap_btn.triggered.connect(lambda: self.toolbar_tool_toggle("corner_snap"))
@@ -3438,6 +3414,14 @@ class AppGeoEditor(QtCore.QObject):
         self.paint_tool = PaintOptionsTool(self.app, self)
         self.paint_tool = PaintOptionsTool(self.app, self)
         self.transform_tool = TransformEditorTool(self.app, self)
         self.transform_tool = TransformEditorTool(self.app, self)
 
 
+        # #############################################################################################################
+        # ####################### GEOMETRY Editor Signals #############################################################
+        # #############################################################################################################
+
+        # connect the toolbar signals
+        self.connect_geo_toolbar_signals()
+
+        # connect Geometry Editor Menu signals
         self.app.ui.geo_add_circle_menuitem.triggered.connect(lambda: self.select_tool('circle'))
         self.app.ui.geo_add_circle_menuitem.triggered.connect(lambda: self.select_tool('circle'))
         self.app.ui.geo_add_arc_menuitem.triggered.connect(lambda: self.select_tool('arc'))
         self.app.ui.geo_add_arc_menuitem.triggered.connect(lambda: self.select_tool('arc'))
         self.app.ui.geo_add_rectangle_menuitem.triggered.connect(lambda: self.select_tool('rectangle'))
         self.app.ui.geo_add_rectangle_menuitem.triggered.connect(lambda: self.select_tool('rectangle'))
@@ -3475,6 +3459,34 @@ class AppGeoEditor(QtCore.QObject):
         self.editor_active = False
         self.editor_active = False
         log.debug("Initialization of the Geometry Editor is finished ...")
         log.debug("Initialization of the Geometry Editor is finished ...")
 
 
+    def make_callback(self, thetool):
+        def f():
+            self.on_tool_select(thetool)
+
+        return f
+
+    def connect_geo_toolbar_signals(self):
+        self.tools.update({
+            "select": {"button": self.app.ui.geo_select_btn, "constructor": FCSelect},
+            "arc": {"button": self.app.ui.geo_add_arc_btn, "constructor": FCArc},
+            "circle": {"button": self.app.ui.geo_add_circle_btn, "constructor": FCCircle},
+            "path": {"button": self.app.ui.geo_add_path_btn, "constructor": FCPath},
+            "rectangle": {"button": self.app.ui.geo_add_rectangle_btn, "constructor": FCRectangle},
+            "polygon": {"button": self.app.ui.geo_add_polygon_btn, "constructor": FCPolygon},
+            "text": {"button": self.app.ui.geo_add_text_btn, "constructor": FCText},
+            "buffer": {"button": self.app.ui.geo_add_buffer_btn, "constructor": FCBuffer},
+            "paint": {"button": self.app.ui.geo_add_paint_btn, "constructor": FCPaint},
+            "eraser": {"button": self.app.ui.geo_eraser_btn, "constructor": FCEraser},
+            "move": {"button": self.app.ui.geo_move_btn, "constructor": FCMove},
+            "transform": {"button": self.app.ui.geo_transform_btn, "constructor": FCTransform},
+            "copy": {"button": self.app.ui.geo_copy_btn, "constructor": FCCopy},
+            "explode": {"button": self.app.ui.geo_explode_btn, "constructor": FCExplode}
+        })
+
+        for tool in self.tools:
+            self.tools[tool]["button"].triggered.connect(self.make_callback(tool))  # Events
+            self.tools[tool]["button"].setCheckable(True)  # Checkable
+
     def pool_recreated(self, pool):
     def pool_recreated(self, pool):
         self.shapes.pool = pool
         self.shapes.pool = pool
         self.tool_shape.pool = pool
         self.tool_shape.pool = pool

+ 37 - 42
appEditors/AppGerberEditor.py

@@ -2912,38 +2912,7 @@ class AppGerberEditor(QtCore.QObject):
         self.exit_editor_button.clicked.connect(lambda: self.app.editor2object())
         self.exit_editor_button.clicked.connect(lambda: self.app.editor2object())
 
 
         # Toolbar events and properties
         # Toolbar events and properties
-        self.tools_gerber = {
-            "select": {"button": self.app.ui.grb_select_btn,
-                       "constructor": FCApertureSelect},
-            "pad": {"button": self.app.ui.grb_add_pad_btn,
-                    "constructor": FCPad},
-            "array": {"button": self.app.ui.add_pad_ar_btn,
-                      "constructor": FCPadArray},
-            "track": {"button": self.app.ui.grb_add_track_btn,
-                      "constructor": FCTrack},
-            "region": {"button": self.app.ui.grb_add_region_btn,
-                       "constructor": FCRegion},
-            "poligonize": {"button": self.app.ui.grb_convert_poly_btn,
-                           "constructor": FCPoligonize},
-            "semidisc": {"button": self.app.ui.grb_add_semidisc_btn,
-                         "constructor": FCSemiDisc},
-            "disc": {"button": self.app.ui.grb_add_disc_btn,
-                     "constructor": FCDisc},
-            "buffer": {"button": self.app.ui.aperture_buffer_btn,
-                       "constructor": FCBuffer},
-            "scale": {"button": self.app.ui.aperture_scale_btn,
-                      "constructor": FCScale},
-            "markarea": {"button": self.app.ui.aperture_markarea_btn,
-                         "constructor": FCMarkArea},
-            "eraser": {"button": self.app.ui.aperture_eraser_btn,
-                       "constructor": FCEraser},
-            "copy": {"button": self.app.ui.aperture_copy_btn,
-                     "constructor": FCApertureCopy},
-            "transform": {"button": self.app.ui.grb_transform_btn,
-                          "constructor": FCTransform},
-            "move": {"button": self.app.ui.aperture_move_btn,
-                     "constructor": FCApertureMove},
-        }
+        self.tools_gerber = {}
 
 
         # # ## Data
         # # ## Data
         self.active_tool = None
         self.active_tool = None
@@ -3034,15 +3003,6 @@ class AppGerberEditor(QtCore.QObject):
         def_tol_val = float(self.app.defaults["global_tolerance"])
         def_tol_val = float(self.app.defaults["global_tolerance"])
         self.tolerance = def_tol_val if self.units == 'MM'else def_tol_val / 20
         self.tolerance = def_tol_val if self.units == 'MM'else def_tol_val / 20
 
 
-        def make_callback(the_tool):
-            def f():
-                self.on_tool_select(the_tool)
-            return f
-
-        for tool in self.tools_gerber:
-            self.tools_gerber[tool]["button"].triggered.connect(make_callback(tool))  # Events
-            self.tools_gerber[tool]["button"].setCheckable(True)
-
         self.options = {
         self.options = {
             "global_gridx": 0.1,
             "global_gridx": 0.1,
             "global_gridy": 0.1,
             "global_gridy": 0.1,
@@ -3082,7 +3042,13 @@ class AppGerberEditor(QtCore.QObject):
 
 
         self.transform_tool = TransformEditorTool(self.app, self)
         self.transform_tool = TransformEditorTool(self.app, self)
 
 
-        # Signals
+        # #############################################################################################################
+        # ######################### Gerber Editor Signals #############################################################
+        # #############################################################################################################
+
+        # connect the toolbar signals
+        self.connect_grb_toolbar_signals()
+
         self.buffer_button.clicked.connect(self.on_buffer)
         self.buffer_button.clicked.connect(self.on_buffer)
         self.scale_button.clicked.connect(self.on_scale)
         self.scale_button.clicked.connect(self.on_scale)
 
 
@@ -3136,6 +3102,35 @@ class AppGerberEditor(QtCore.QObject):
         self.set_ui()
         self.set_ui()
         log.debug("Initialization of the Gerber Editor is finished ...")
         log.debug("Initialization of the Gerber Editor is finished ...")
 
 
+    def make_callback(self, the_tool):
+        def f():
+            self.on_tool_select(the_tool)
+
+        return f
+
+    def connect_grb_toolbar_signals(self):
+        self.tools_gerber.update({
+            "select": {"button": self.app.ui.grb_select_btn,            "constructor": FCApertureSelect},
+            "pad": {"button": self.app.ui.grb_add_pad_btn,              "constructor": FCPad},
+            "array": {"button": self.app.ui.add_pad_ar_btn,             "constructor": FCPadArray},
+            "track": {"button": self.app.ui.grb_add_track_btn,          "constructor": FCTrack},
+            "region": {"button": self.app.ui.grb_add_region_btn,        "constructor": FCRegion},
+            "poligonize": {"button": self.app.ui.grb_convert_poly_btn,  "constructor": FCPoligonize},
+            "semidisc": {"button": self.app.ui.grb_add_semidisc_btn,    "constructor": FCSemiDisc},
+            "disc": {"button": self.app.ui.grb_add_disc_btn,            "constructor": FCDisc},
+            "buffer": {"button": self.app.ui.aperture_buffer_btn,       "constructor": FCBuffer},
+            "scale": {"button": self.app.ui.aperture_scale_btn,         "constructor": FCScale},
+            "markarea": {"button": self.app.ui.aperture_markarea_btn,   "constructor": FCMarkArea},
+            "eraser": {"button": self.app.ui.aperture_eraser_btn,       "constructor": FCEraser},
+            "copy": {"button": self.app.ui.aperture_copy_btn,           "constructor": FCApertureCopy},
+            "transform": {"button": self.app.ui.grb_transform_btn,      "constructor": FCTransform},
+            "move": {"button": self.app.ui.aperture_move_btn,           "constructor": FCApertureMove},
+        })
+
+        for tool in self.tools_gerber:
+            self.tools_gerber[tool]["button"].triggered.connect(self.make_callback(tool))  # Events
+            self.tools_gerber[tool]["button"].setCheckable(True)
+
     def pool_recreated(self, pool):
     def pool_recreated(self, pool):
         self.shapes.pool = pool
         self.shapes.pool = pool
         self.tool_shape.pool = pool
         self.tool_shape.pool = pool

+ 6 - 5
appGUI/MainGUI.py

@@ -2128,9 +2128,10 @@ class MainGUI(QtWidgets.QMainWindow):
 
 
         :return: None
         :return: None
         """
         """
+        self.app.log.debug(" -> Add actions to new Toolbars")
 
 
         # ########################################################################
         # ########################################################################
-        # ## File Toolbar # ##
+        # ##################### File Toolbar #####################################
         # ########################################################################
         # ########################################################################
         self.file_open_gerber_btn = self.toolbarfile.addAction(
         self.file_open_gerber_btn = self.toolbarfile.addAction(
             QtGui.QIcon(self.app.resource_location + '/flatcam_icon32.png'), _("Open Gerber"))
             QtGui.QIcon(self.app.resource_location + '/flatcam_icon32.png'), _("Open Gerber"))
@@ -2143,7 +2144,7 @@ class MainGUI(QtWidgets.QMainWindow):
             QtGui.QIcon(self.app.resource_location + '/project_save32.png'), _("Save project"))
             QtGui.QIcon(self.app.resource_location + '/project_save32.png'), _("Save project"))
 
 
         # ########################################################################
         # ########################################################################
-        # ## Edit Toolbar # ##
+        # ######################### Edit Toolbar #################################
         # ########################################################################
         # ########################################################################
         self.editgeo_btn = self.toolbaredit.addAction(
         self.editgeo_btn = self.toolbaredit.addAction(
             QtGui.QIcon(self.app.resource_location + '/edit32.png'), _("Editor"))
             QtGui.QIcon(self.app.resource_location + '/edit32.png'), _("Editor"))
@@ -2257,7 +2258,7 @@ class MainGUI(QtWidgets.QMainWindow):
             QtGui.QIcon(self.app.resource_location + '/etch_32.png'), _("Etch Compensation Tool"))
             QtGui.QIcon(self.app.resource_location + '/etch_32.png'), _("Etch Compensation Tool"))
 
 
         # ########################################################################
         # ########################################################################
-        # ## Excellon Editor Toolbar # ##
+        # ################### Excellon Editor Toolbar ############################
         # ########################################################################
         # ########################################################################
         self.select_drill_btn = self.exc_edit_toolbar.addAction(
         self.select_drill_btn = self.exc_edit_toolbar.addAction(
             QtGui.QIcon(self.app.resource_location + '/pointer32.png'), _("Select"))
             QtGui.QIcon(self.app.resource_location + '/pointer32.png'), _("Select"))
@@ -2283,7 +2284,7 @@ class MainGUI(QtWidgets.QMainWindow):
             QtGui.QIcon(self.app.resource_location + '/move32.png'), _("Move Drill"))
             QtGui.QIcon(self.app.resource_location + '/move32.png'), _("Move Drill"))
 
 
         # ########################################################################
         # ########################################################################
-        # ## Geometry Editor Toolbar # ##
+        # ################### Geometry Editor Toolbar ############################
         # ########################################################################
         # ########################################################################
         self.geo_select_btn = self.geo_edit_toolbar.addAction(
         self.geo_select_btn = self.geo_edit_toolbar.addAction(
             QtGui.QIcon(self.app.resource_location + '/pointer32.png'), _("Select 'Esc'"))
             QtGui.QIcon(self.app.resource_location + '/pointer32.png'), _("Select 'Esc'"))
@@ -2335,7 +2336,7 @@ class MainGUI(QtWidgets.QMainWindow):
             QtGui.QIcon(self.app.resource_location + '/move32.png'), _("Move Objects"))
             QtGui.QIcon(self.app.resource_location + '/move32.png'), _("Move Objects"))
 
 
         # ########################################################################
         # ########################################################################
-        # ## Gerber Editor Toolbar # ##
+        # ################### Gerber Editor Toolbar ##############################
         # ########################################################################
         # ########################################################################
         self.grb_select_btn = self.grb_edit_toolbar.addAction(
         self.grb_select_btn = self.grb_edit_toolbar.addAction(
             QtGui.QIcon(self.app.resource_location + '/pointer32.png'), _("Select"))
             QtGui.QIcon(self.app.resource_location + '/pointer32.png'), _("Select"))

+ 9 - 3
appGUI/preferences/PreferencesUIManager.py

@@ -42,6 +42,8 @@ class PreferencesUIManager:
         # if Preferences are changed in the Edit -> Preferences tab the value will be set to True
         # if Preferences are changed in the Edit -> Preferences tab the value will be set to True
         self.preferences_changed_flag = False
         self.preferences_changed_flag = False
 
 
+        self.old_color = QtGui.QColor('black')
+
         # when adding entries here read the comments in the  method found below named:
         # when adding entries here read the comments in the  method found below named:
         # def app_obj.new_object(self, kind, name, initialize, active=True, fit=True, plot=True)
         # def app_obj.new_object(self, kind, name, initialize, active=True, fit=True, plot=True)
         self.defaults_form_fields = {
         self.defaults_form_fields = {
@@ -538,7 +540,10 @@ class PreferencesUIManager:
             "tools_solderpaste_speedrev": self.ui.tools_defaults_form.tools_solderpaste_group.speedrev_entry,
             "tools_solderpaste_speedrev": self.ui.tools_defaults_form.tools_solderpaste_group.speedrev_entry,
             "tools_solderpaste_dwellrev": self.ui.tools_defaults_form.tools_solderpaste_group.dwellrev_entry,
             "tools_solderpaste_dwellrev": self.ui.tools_defaults_form.tools_solderpaste_group.dwellrev_entry,
             "tools_solderpaste_pp": self.ui.tools_defaults_form.tools_solderpaste_group.pp_combo,
             "tools_solderpaste_pp": self.ui.tools_defaults_form.tools_solderpaste_group.pp_combo,
+
+            # Subtractor Tool
             "tools_sub_close_paths": self.ui.tools_defaults_form.tools_sub_group.close_paths_cb,
             "tools_sub_close_paths": self.ui.tools_defaults_form.tools_sub_group.close_paths_cb,
+            "tools_sub_delete_sources":  self.ui.tools_defaults_form.tools_sub_group.delete_sources_cb,
 
 
             # Corner Markers Tool
             # Corner Markers Tool
 
 
@@ -905,7 +910,7 @@ class PreferencesUIManager:
         # Preferences save, update the color of the Preferences Tab text
         # Preferences save, update the color of the Preferences Tab text
         for idx in range(self.ui.plot_tab_area.count()):
         for idx in range(self.ui.plot_tab_area.count()):
             if self.ui.plot_tab_area.tabText(idx) == _("Preferences"):
             if self.ui.plot_tab_area.tabText(idx) == _("Preferences"):
-                self.ui.plot_tab_area.tabBar.setTabTextColor(idx, QtGui.QColor('black'))
+                self.ui.plot_tab_area.tabBar.setTabTextColor(idx, self.old_color)
 
 
         # restore the default stylesheet by setting a blank one
         # restore the default stylesheet by setting a blank one
         self.ui.pref_apply_button.setStyleSheet("")
         self.ui.pref_apply_button.setStyleSheet("")
@@ -998,7 +1003,7 @@ class PreferencesUIManager:
             # close the tab and delete it
             # close the tab and delete it
             for idx in range(self.ui.plot_tab_area.count()):
             for idx in range(self.ui.plot_tab_area.count()):
                 if self.ui.plot_tab_area.tabText(idx) == _("Preferences"):
                 if self.ui.plot_tab_area.tabText(idx) == _("Preferences"):
-                    self.ui.plot_tab_area.tabBar.setTabTextColor(idx, QtGui.QColor('black'))
+                    self.ui.plot_tab_area.tabBar.setTabTextColor(idx, self.old_color)
                     self.ui.plot_tab_area.closeTab(idx)
                     self.ui.plot_tab_area.closeTab(idx)
                     break
                     break
 
 
@@ -1026,7 +1031,7 @@ class PreferencesUIManager:
         # Preferences save, update the color of the Preferences Tab text
         # Preferences save, update the color of the Preferences Tab text
         for idx in range(self.ui.plot_tab_area.count()):
         for idx in range(self.ui.plot_tab_area.count()):
             if self.ui.plot_tab_area.tabText(idx) == _("Preferences"):
             if self.ui.plot_tab_area.tabText(idx) == _("Preferences"):
-                self.ui.plot_tab_area.tabBar.setTabTextColor(idx, QtGui.QColor('black'))
+                self.ui.plot_tab_area.tabBar.setTabTextColor(idx, self.old_color)
                 self.ui.plot_tab_area.closeTab(idx)
                 self.ui.plot_tab_area.closeTab(idx)
                 break
                 break
 
 
@@ -1131,6 +1136,7 @@ class PreferencesUIManager:
 
 
             for idx in range(self.ui.plot_tab_area.count()):
             for idx in range(self.ui.plot_tab_area.count()):
                 if self.ui.plot_tab_area.tabText(idx) == _("Preferences"):
                 if self.ui.plot_tab_area.tabText(idx) == _("Preferences"):
+                    self.old_color = self.ui.plot_tab_area.tabBar.tabTextColor(idx)
                     self.ui.plot_tab_area.tabBar.setTabTextColor(idx, QtGui.QColor('red'))
                     self.ui.plot_tab_area.tabBar.setTabTextColor(idx, QtGui.QColor('red'))
 
 
             self.ui.pref_apply_button.setStyleSheet("QPushButton {color: red;}")
             self.ui.pref_apply_button.setStyleSheet("QPushButton {color: red;}")

+ 1 - 141
appGUI/preferences/general/GeneralGUIPrefGroupUI.py

@@ -326,7 +326,7 @@ class GeneralGUIPrefGroupUI(OptionsGroupUI):
         self.proj_color_entry.editingFinished.connect(self.on_proj_color_entry)
         self.proj_color_entry.editingFinished.connect(self.on_proj_color_entry)
         self.proj_color_dis_entry.editingFinished.connect(self.on_proj_color_dis_entry)
         self.proj_color_dis_entry.editingFinished.connect(self.on_proj_color_dis_entry)
 
 
-        self.layout_combo.activated.connect(self.on_layout)
+        self.layout_combo.activated.connect(self.app.on_layout)
 
 
     @staticmethod
     @staticmethod
     def handle_style(style):
     def handle_style(style):
@@ -407,143 +407,3 @@ class GeneralGUIPrefGroupUI(OptionsGroupUI):
 
 
     def on_proj_color_dis_entry(self):
     def on_proj_color_dis_entry(self):
         self.app.defaults['global_proj_item_dis_color'] = self.proj_color_dis_entry.get_value()
         self.app.defaults['global_proj_item_dis_color'] = self.proj_color_dis_entry.get_value()
-
-    def on_layout(self, index=None, lay=None):
-        """
-        Set the toolbars layout (location)
-
-        :param index:
-        :param lay:     Type of layout to be set on the toolbard
-        :return:        None
-        """
-
-        self.app.defaults.report_usage("on_layout()")
-        if lay:
-            current_layout = lay
-        else:
-            current_layout = self.layout_combo.get_value()
-
-        lay_settings = QSettings("Open Source", "FlatCAM")
-        lay_settings.setValue('layout', current_layout)
-
-        # This will write the setting to the platform specific storage.
-        del lay_settings
-
-        # first remove the toolbars:
-        try:
-            self.app.ui.removeToolBar(self.app.ui.toolbarfile)
-            self.app.ui.removeToolBar(self.app.ui.toolbaredit)
-            self.app.ui.removeToolBar(self.app.ui.toolbarview)
-            self.app.ui.removeToolBar(self.app.ui.toolbarshell)
-            self.app.ui.removeToolBar(self.app.ui.toolbartools)
-            self.app.ui.removeToolBar(self.app.ui.exc_edit_toolbar)
-            self.app.ui.removeToolBar(self.app.ui.geo_edit_toolbar)
-            self.app.ui.removeToolBar(self.app.ui.grb_edit_toolbar)
-            self.app.ui.removeToolBar(self.app.ui.toolbarshell)
-        except Exception:
-            pass
-
-        if current_layout == 'compact':
-            # ## TOOLBAR INSTALLATION # ##
-            self.app.ui.toolbarfile = QtWidgets.QToolBar('File Toolbar')
-            self.app.ui.toolbarfile.setObjectName('File_TB')
-            self.app.ui.addToolBar(Qt.LeftToolBarArea, self.app.ui.toolbarfile)
-
-            self.app.ui.toolbaredit = QtWidgets.QToolBar('Edit Toolbar')
-            self.app.ui.toolbaredit.setObjectName('Edit_TB')
-            self.app.ui.addToolBar(Qt.LeftToolBarArea, self.app.ui.toolbaredit)
-
-            self.app.ui.toolbarshell = QtWidgets.QToolBar('Shell Toolbar')
-            self.app.ui.toolbarshell.setObjectName('Shell_TB')
-            self.app.ui.addToolBar(Qt.LeftToolBarArea, self.app.ui.toolbarshell)
-
-            self.app.ui.toolbartools = QtWidgets.QToolBar('Tools Toolbar')
-            self.app.ui.toolbartools.setObjectName('Tools_TB')
-            self.app.ui.addToolBar(Qt.LeftToolBarArea, self.app.ui.toolbartools)
-
-            self.app.ui.geo_edit_toolbar = QtWidgets.QToolBar('Geometry Editor Toolbar')
-            # self.app.ui.geo_edit_toolbar.setVisible(False)
-            self.app.ui.geo_edit_toolbar.setObjectName('GeoEditor_TB')
-            self.app.ui.addToolBar(Qt.RightToolBarArea, self.app.ui.geo_edit_toolbar)
-
-            self.app.ui.toolbarview = QtWidgets.QToolBar('View Toolbar')
-            self.app.ui.toolbarview.setObjectName('View_TB')
-            self.app.ui.addToolBar(Qt.RightToolBarArea, self.app.ui.toolbarview)
-
-            self.app.ui.addToolBarBreak(area=Qt.RightToolBarArea)
-
-            self.app.ui.grb_edit_toolbar = QtWidgets.QToolBar('Gerber Editor Toolbar')
-            # self.app.ui.grb_edit_toolbar.setVisible(False)
-            self.app.ui.grb_edit_toolbar.setObjectName('GrbEditor_TB')
-            self.app.ui.addToolBar(Qt.RightToolBarArea, self.app.ui.grb_edit_toolbar)
-
-            self.app.ui.exc_edit_toolbar = QtWidgets.QToolBar('Excellon Editor Toolbar')
-            self.app.ui.exc_edit_toolbar.setObjectName('ExcEditor_TB')
-            self.app.ui.addToolBar(Qt.RightToolBarArea, self.app.ui.exc_edit_toolbar)
-
-        else:
-            # ## TOOLBAR INSTALLATION # ##
-            self.app.ui.toolbarfile = QtWidgets.QToolBar('File Toolbar')
-            self.app.ui.toolbarfile.setObjectName('File_TB')
-            self.app.ui.addToolBar(self.app.ui.toolbarfile)
-
-            self.app.ui.toolbaredit = QtWidgets.QToolBar('Edit Toolbar')
-            self.app.ui.toolbaredit.setObjectName('Edit_TB')
-            self.app.ui.addToolBar(self.app.ui.toolbaredit)
-
-            self.app.ui.toolbarview = QtWidgets.QToolBar('View Toolbar')
-            self.app.ui.toolbarview.setObjectName('View_TB')
-            self.app.ui.addToolBar(self.app.ui.toolbarview)
-
-            self.app.ui.toolbarshell = QtWidgets.QToolBar('Shell Toolbar')
-            self.app.ui.toolbarshell.setObjectName('Shell_TB')
-            self.app.ui.addToolBar(self.app.ui.toolbarshell)
-
-            self.app.ui.toolbartools = QtWidgets.QToolBar('Tools Toolbar')
-            self.app.ui.toolbartools.setObjectName('Tools_TB')
-            self.app.ui.addToolBar(self.app.ui.toolbartools)
-
-            self.app.ui.exc_edit_toolbar = QtWidgets.QToolBar('Excellon Editor Toolbar')
-            # self.app.ui.exc_edit_toolbar.setVisible(False)
-            self.app.ui.exc_edit_toolbar.setObjectName('ExcEditor_TB')
-            self.app.ui.addToolBar(self.app.ui.exc_edit_toolbar)
-
-            self.app.ui.addToolBarBreak()
-
-            self.app.ui.geo_edit_toolbar = QtWidgets.QToolBar('Geometry Editor Toolbar')
-            # self.app.ui.geo_edit_toolbar.setVisible(False)
-            self.app.ui.geo_edit_toolbar.setObjectName('GeoEditor_TB')
-            self.app.ui.addToolBar(self.app.ui.geo_edit_toolbar)
-
-            self.app.ui.grb_edit_toolbar = QtWidgets.QToolBar('Gerber Editor Toolbar')
-            # self.app.ui.grb_edit_toolbar.setVisible(False)
-            self.app.ui.grb_edit_toolbar.setObjectName('GrbEditor_TB')
-            self.app.ui.addToolBar(self.app.ui.grb_edit_toolbar)
-
-        if current_layout == 'minimal':
-            self.app.ui.toolbarview.setVisible(False)
-            self.app.ui.toolbarshell.setVisible(False)
-            self.app.ui.geo_edit_toolbar.setVisible(False)
-            self.app.ui.grb_edit_toolbar.setVisible(False)
-            self.app.ui.exc_edit_toolbar.setVisible(False)
-            self.app.ui.lock_toolbar(lock=True)
-
-        # add all the actions to the toolbars
-        self.app.ui.populate_toolbars()
-
-        try:
-            # reconnect all the signals to the toolbar actions
-            self.app.connect_toolbar_signals(ui=self.app.ui)
-        except Exception as e:
-            self.app.log.debug(
-                "appGUI.preferences.general.GeneralGUIPrefGroupUI.on_layout() - connect toolbar signals -> %s" % str(e))
-
-        self.app.ui.grid_snap_btn.setChecked(True)
-
-        self.app.ui.corner_snap_btn.setVisible(False)
-        self.app.ui.snap_magnet.setVisible(False)
-
-        self.app.ui.grid_gap_x_entry.setText(str(self.app.defaults["global_gridx"]))
-        self.app.ui.grid_gap_y_entry.setText(str(self.app.defaults["global_gridy"]))
-        self.app.ui.snap_max_dist_entry.setText(str(self.app.defaults["global_snap_max"]))
-        self.app.ui.grid_gap_link_cb.setChecked(True)

+ 10 - 1
appGUI/preferences/tools/ToolsSubPrefGroupUI.py

@@ -38,5 +38,14 @@ class ToolsSubPrefGroupUI(OptionsGroupUI):
         self.close_paths_cb = FCCheckBox(_("Close paths"))
         self.close_paths_cb = FCCheckBox(_("Close paths"))
         self.close_paths_cb.setToolTip(_("Checking this will close the paths cut by the Geometry substractor object."))
         self.close_paths_cb.setToolTip(_("Checking this will close the paths cut by the Geometry substractor object."))
         self.layout.addWidget(self.close_paths_cb)
         self.layout.addWidget(self.close_paths_cb)
-
+        self.delete_sources_cb = FCCheckBox(_("Delete source"))
+        self.delete_sources_cb.setToolTip(
+            _("If checked will delete the source objects.")
+        )
+        self.delete_sources_cb = FCCheckBox(_("Delete source"))
+        self.delete_sources_cb.setToolTip(
+            _("When checked will delete the source objects\n"
+              "after a successful operation.")
+        )
+        self.layout.addWidget(self.delete_sources_cb)
         self.layout.addStretch()
         self.layout.addStretch()

+ 1 - 0
appTools/ToolAlignObjects.py

@@ -479,6 +479,7 @@ class AlignUI:
 
 
         # Buttons
         # Buttons
         self.align_object_button =FCButton(_("Align Object"))
         self.align_object_button =FCButton(_("Align Object"))
+        self.align_object_button.setIcon(QtGui.QIcon(self.app.resource_location + '/align16.png'))
         self.align_object_button.setToolTip(
         self.align_object_button.setToolTip(
             _("Align the specified object to the aligner object.\n"
             _("Align the specified object to the aligner object.\n"
               "If only one point is used then it assumes translation.\n"
               "If only one point is used then it assumes translation.\n"

+ 3 - 0
appTools/ToolDblSided.py

@@ -706,6 +706,7 @@ class DsidedUI:
 
 
         # Add a reference
         # Add a reference
         self.add_point_button = QtWidgets.QPushButton(_("Add"))
         self.add_point_button = QtWidgets.QPushButton(_("Add"))
+        self.add_point_button.setIcon(QtGui.QIcon(self.app.resource_location + '/plus16.png'))
         self.add_point_button.setToolTip(
         self.add_point_button.setToolTip(
             _("Add the coordinates in format <b>(x, y)</b> through which the mirroring axis\n "
             _("Add the coordinates in format <b>(x, y)</b> through which the mirroring axis\n "
               "selected in 'MIRROR AXIS' pass.\n"
               "selected in 'MIRROR AXIS' pass.\n"
@@ -893,6 +894,7 @@ class DsidedUI:
         grid5.addWidget(self.alignment_holes, 1, 0, 1, 2)
         grid5.addWidget(self.alignment_holes, 1, 0, 1, 2)
 
 
         self.add_drill_point_button = FCButton(_("Add"))
         self.add_drill_point_button = FCButton(_("Add"))
+        self.add_drill_point_button.setIcon(QtGui.QIcon(self.app.resource_location + '/plus16.png'))
         self.add_drill_point_button.setToolTip(
         self.add_drill_point_button.setToolTip(
             _("Add alignment drill holes coordinates in the format: (x1, y1), (x2, y2), ... \n"
             _("Add alignment drill holes coordinates in the format: (x1, y1), (x2, y2), ... \n"
               "on one side of the alignment axis.\n\n"
               "on one side of the alignment axis.\n\n"
@@ -910,6 +912,7 @@ class DsidedUI:
         #                 """)
         #                 """)
 
 
         self.delete_drill_point_button = FCButton(_("Delete Last"))
         self.delete_drill_point_button = FCButton(_("Delete Last"))
+        self.delete_drill_point_button.setIcon(QtGui.QIcon(self.app.resource_location + '/trash32.png'))
         self.delete_drill_point_button.setToolTip(
         self.delete_drill_point_button.setToolTip(
             _("Delete the last coordinates tuple in the list.")
             _("Delete the last coordinates tuple in the list.")
         )
         )

+ 33 - 38
appTools/ToolExtractDrills.py

@@ -381,35 +381,35 @@ class ToolExtractDrills(AppTool):
 
 
     def on_hole_size_toggle(self, val):
     def on_hole_size_toggle(self, val):
         if val == "fixed":
         if val == "fixed":
-            self.ui.fixed_label.setDisabled(False)
-            self.ui.dia_entry.setDisabled(False)
-            self.ui.dia_label.setDisabled(False)
+            self.ui.fixed_label.setVisible(True)
+            self.ui.dia_entry.setVisible(True)
+            self.ui.dia_label.setVisible(True)
 
 
-            self.ui.ring_frame.setDisabled(True)
+            self.ui.ring_frame.setVisible(False)
 
 
-            self.ui.prop_label.setDisabled(True)
-            self.ui.factor_label.setDisabled(True)
-            self.ui.factor_entry.setDisabled(True)
+            self.ui.prop_label.setVisible(False)
+            self.ui.factor_label.setVisible(False)
+            self.ui.factor_entry.setVisible(False)
         elif val == "ring":
         elif val == "ring":
-            self.ui.fixed_label.setDisabled(True)
-            self.ui.dia_entry.setDisabled(True)
-            self.ui.dia_label.setDisabled(True)
+            self.ui.fixed_label.setVisible(False)
+            self.ui.dia_entry.setVisible(False)
+            self.ui.dia_label.setVisible(False)
 
 
-            self.ui.ring_frame.setDisabled(False)
+            self.ui.ring_frame.setVisible(True)
 
 
-            self.ui.prop_label.setDisabled(True)
-            self.ui.factor_label.setDisabled(True)
-            self.ui.factor_entry.setDisabled(True)
+            self.ui.prop_label.setVisible(False)
+            self.ui.factor_label.setVisible(False)
+            self.ui.factor_entry.setVisible(False)
         elif val == "prop":
         elif val == "prop":
-            self.ui.fixed_label.setDisabled(True)
-            self.ui.dia_entry.setDisabled(True)
-            self.ui.dia_label.setDisabled(True)
+            self.ui.fixed_label.setVisible(False)
+            self.ui.dia_entry.setVisible(False)
+            self.ui.dia_label.setVisible(False)
 
 
-            self.ui.ring_frame.setDisabled(True)
+            self.ui.ring_frame.setVisible(False)
 
 
-            self.ui.prop_label.setDisabled(False)
-            self.ui.factor_label.setDisabled(False)
-            self.ui.factor_entry.setDisabled(False)
+            self.ui.prop_label.setVisible(True)
+            self.ui.factor_label.setVisible(True)
+            self.ui.factor_entry.setVisible(True)
 
 
     def reset_fields(self):
     def reset_fields(self):
         self.ui.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
         self.ui.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
@@ -530,8 +530,8 @@ class ExtractDrillsUI:
         self.hole_size_radio = RadioSet(
         self.hole_size_radio = RadioSet(
             [
             [
                 {'label': _("Fixed Diameter"), 'value': 'fixed'},
                 {'label': _("Fixed Diameter"), 'value': 'fixed'},
-                {'label': _("Fixed Annular Ring"), 'value': 'ring'},
-                {'label': _("Proportional"), 'value': 'prop'}
+                {'label': _("Proportional"), 'value': 'prop'},
+                {'label': _("Fixed Annular Ring"), 'value': 'ring'}
             ],
             ],
             orientation='vertical',
             orientation='vertical',
             stretch=False)
             stretch=False)
@@ -562,11 +562,6 @@ class ExtractDrillsUI:
         grid1.addWidget(self.dia_label, 8, 0)
         grid1.addWidget(self.dia_label, 8, 0)
         grid1.addWidget(self.dia_entry, 8, 1)
         grid1.addWidget(self.dia_entry, 8, 1)
 
 
-        separator_line = QtWidgets.QFrame()
-        separator_line.setFrameShape(QtWidgets.QFrame.HLine)
-        separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
-        grid1.addWidget(separator_line, 9, 0, 1, 2)
-
         self.ring_frame = QtWidgets.QFrame()
         self.ring_frame = QtWidgets.QFrame()
         self.ring_frame.setContentsMargins(0, 0, 0, 0)
         self.ring_frame.setContentsMargins(0, 0, 0, 0)
         self.layout.addWidget(self.ring_frame)
         self.layout.addWidget(self.ring_frame)
@@ -660,11 +655,6 @@ class ExtractDrillsUI:
         grid3.setColumnStretch(0, 0)
         grid3.setColumnStretch(0, 0)
         grid3.setColumnStretch(1, 1)
         grid3.setColumnStretch(1, 1)
 
 
-        separator_line = QtWidgets.QFrame()
-        separator_line.setFrameShape(QtWidgets.QFrame.HLine)
-        separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
-        grid3.addWidget(separator_line, 1, 0, 1, 2)
-
         # Annular Ring value
         # Annular Ring value
         self.prop_label = QtWidgets.QLabel('<b>%s</b>' % _("Proportional Diameter"))
         self.prop_label = QtWidgets.QLabel('<b>%s</b>' % _("Proportional Diameter"))
         grid3.addWidget(self.prop_label, 2, 0, 1, 2)
         grid3.addWidget(self.prop_label, 2, 0, 1, 2)
@@ -684,6 +674,11 @@ class ExtractDrillsUI:
         grid3.addWidget(self.factor_label, 3, 0)
         grid3.addWidget(self.factor_label, 3, 0)
         grid3.addWidget(self.factor_entry, 3, 1)
         grid3.addWidget(self.factor_entry, 3, 1)
 
 
+        separator_line = QtWidgets.QFrame()
+        separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+        separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+        grid3.addWidget(separator_line, 5, 0, 1, 2)
+
         # Extract drills from Gerber apertures flashes (pads)
         # Extract drills from Gerber apertures flashes (pads)
         self.e_drills_button = QtWidgets.QPushButton(_("Extract Drills"))
         self.e_drills_button = QtWidgets.QPushButton(_("Extract Drills"))
         self.e_drills_button.setIcon(QtGui.QIcon(self.app.resource_location + '/drill16.png'))
         self.e_drills_button.setIcon(QtGui.QIcon(self.app.resource_location + '/drill16.png'))
@@ -720,12 +715,12 @@ class ExtractDrillsUI:
         self.rectangular_ring_entry.setEnabled(False)
         self.rectangular_ring_entry.setEnabled(False)
         self.other_ring_entry.setEnabled(False)
         self.other_ring_entry.setEnabled(False)
 
 
-        self.dia_entry.setDisabled(True)
-        self.dia_label.setDisabled(True)
-        self.factor_label.setDisabled(True)
-        self.factor_entry.setDisabled(True)
+        self.dia_entry.setVisible(False)
+        self.dia_label.setVisible(False)
+        self.factor_label.setVisible(False)
+        self.factor_entry.setVisible(False)
 
 
-        self.ring_frame.setDisabled(True)
+        self.ring_frame.setVisible(False)
         # #################################### FINSIHED GUI ###########################
         # #################################### FINSIHED GUI ###########################
         # #############################################################################
         # #############################################################################
 
 

+ 9 - 7
appTools/ToolPunchGerber.py

@@ -98,17 +98,19 @@ class ToolPunchGerber(AppTool):
 
 
         if self.old_name != '':
         if self.old_name != '':
             old_obj = self.app.collection.get_by_name(self.old_name)
             old_obj = self.app.collection.get_by_name(self.old_name)
-            old_obj.clear_plot_apertures()
-            old_obj.mark_shapes.enabled = False
+            if old_obj:
+                old_obj.clear_plot_apertures()
+                old_obj.mark_shapes.enabled = False
 
 
         # enable mark shapes
         # enable mark shapes
-        grb_obj.mark_shapes.enabled = True
+        if grb_obj:
+            grb_obj.mark_shapes.enabled = True
 
 
-        # create storage for shapes
-        for ap_code in grb_obj.apertures:
-            grb_obj.mark_shapes_storage[ap_code] = []
+            # create storage for shapes
+            for ap_code in grb_obj.apertures:
+                grb_obj.mark_shapes_storage[ap_code] = []
 
 
-        self.old_name = grb_obj.options['name']
+            self.old_name = grb_obj.options['name']
 
 
     def run(self, toggle=True):
     def run(self, toggle=True):
         self.app.defaults.report_usage("ToolPunchGerber()")
         self.app.defaults.report_usage("ToolPunchGerber()")

+ 40 - 15
appTools/ToolSub.py

@@ -133,6 +133,7 @@ class ToolSub(AppTool):
 
 
         self.ui.tools_frame.show()
         self.ui.tools_frame.show()
         self.ui.close_paths_cb.setChecked(self.app.defaults["tools_sub_close_paths"])
         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"])
 
 
     def on_subtract_gerber_click(self):
     def on_subtract_gerber_click(self):
         # reset previous values
         # reset previous values
@@ -359,6 +360,11 @@ class ToolSub(AppTool):
             # GUI feedback
             # GUI feedback
             self.app.inform.emit('[success] %s: %s' % (_("Created"), outname))
             self.app.inform.emit('[success] %s: %s' % (_("Created"), outname))
 
 
+            # Delete source objects if it was selected
+            if self.ui.delete_sources_cb.get_value():
+                self.app.collection.delete_by_name(self.target_grb_obj_name)
+                self.app.collection.delete_by_name(self.sub_grb_obj_name)
+
             # cleanup
             # cleanup
             self.new_apertures.clear()
             self.new_apertures.clear()
             self.new_solid_geometry[:] = []
             self.new_solid_geometry[:] = []
@@ -549,6 +555,11 @@ class ToolSub(AppTool):
             # GUI feedback
             # GUI feedback
             self.app.inform.emit('[success] %s: %s' % (_("Created"), outname))
             self.app.inform.emit('[success] %s: %s' % (_("Created"), outname))
 
 
+            # Delete source objects if it was selected
+            if self.ui.delete_sources_cb.get_value():
+                self.app.collection.delete_by_name(self.target_geo_obj_name)
+                self.app.collection.delete_by_name(self.sub_geo_obj_name)
+
             # cleanup
             # cleanup
             self.new_tools.clear()
             self.new_tools.clear()
             self.new_solid_geometry[:] = []
             self.new_solid_geometry[:] = []
@@ -667,8 +678,22 @@ class SubUI:
         grid0.setColumnStretch(1, 1)
         grid0.setColumnStretch(1, 1)
         self.tools_box.addLayout(grid0)
         self.tools_box.addLayout(grid0)
 
 
+        self.delete_sources_cb = FCCheckBox(_("Delete source"))
+        self.delete_sources_cb.setToolTip(
+            _("When checked will delete the source objects\n"
+              "after a successful operation.")
+        )
+        grid0.addWidget(self.delete_sources_cb, 0, 0, 1, 2)
+
+        separator_line = QtWidgets.QFrame()
+        separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+        separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+        grid0.addWidget(separator_line, 2, 0, 1, 3)
+
+        grid0.addWidget(QtWidgets.QLabel(''), 4, 0, 1, 2)
+
         self.gerber_title = QtWidgets.QLabel("<b>%s</b>" % _("GERBER"))
         self.gerber_title = QtWidgets.QLabel("<b>%s</b>" % _("GERBER"))
-        grid0.addWidget(self.gerber_title, 0, 0, 1, 2)
+        grid0.addWidget(self.gerber_title, 6, 0, 1, 2)
 
 
         # Target Gerber Object
         # Target Gerber Object
         self.target_gerber_combo = FCComboBox()
         self.target_gerber_combo = FCComboBox()
@@ -684,8 +709,8 @@ class SubUI:
               "the subtractor Gerber object.")
               "the subtractor Gerber object.")
         )
         )
 
 
-        grid0.addWidget(self.target_gerber_label, 2, 0)
-        grid0.addWidget(self.target_gerber_combo, 2, 1)
+        grid0.addWidget(self.target_gerber_label, 8, 0)
+        grid0.addWidget(self.target_gerber_combo, 8, 1)
 
 
         # Substractor Gerber Object
         # Substractor Gerber Object
         self.sub_gerber_combo = FCComboBox()
         self.sub_gerber_combo = FCComboBox()
@@ -700,8 +725,8 @@ class SubUI:
               "from the target Gerber object.")
               "from the target Gerber object.")
         )
         )
 
 
-        grid0.addWidget(self.sub_gerber_label, 4, 0)
-        grid0.addWidget(self.sub_gerber_combo, 4, 1)
+        grid0.addWidget(self.sub_gerber_label, 10, 0)
+        grid0.addWidget(self.sub_gerber_combo, 10, 1)
 
 
         self.intersect_btn = FCButton(_('Subtract Gerber'))
         self.intersect_btn = FCButton(_('Subtract Gerber'))
         self.intersect_btn.setIcon(QtGui.QIcon(self.app.resource_location + '/subtract_btn32.png'))
         self.intersect_btn.setIcon(QtGui.QIcon(self.app.resource_location + '/subtract_btn32.png'))
@@ -717,11 +742,11 @@ class SubUI:
                                     font-weight: bold;
                                     font-weight: bold;
                                 }
                                 }
                                 """)
                                 """)
-        grid0.addWidget(self.intersect_btn, 6, 0, 1, 2)
-        grid0.addWidget(QtWidgets.QLabel(''), 8, 0, 1, 2)
+        grid0.addWidget(self.intersect_btn, 12, 0, 1, 2)
+        grid0.addWidget(QtWidgets.QLabel(''), 14, 0, 1, 2)
 
 
         self.geo_title = QtWidgets.QLabel("<b>%s</b>" % _("GEOMETRY"))
         self.geo_title = QtWidgets.QLabel("<b>%s</b>" % _("GEOMETRY"))
-        grid0.addWidget(self.geo_title, 10, 0, 1, 2)
+        grid0.addWidget(self.geo_title, 16, 0, 1, 2)
 
 
         # Target Geometry Object
         # Target Geometry Object
         self.target_geo_combo = FCComboBox()
         self.target_geo_combo = FCComboBox()
@@ -737,8 +762,8 @@ class SubUI:
               "the subtractor Geometry object.")
               "the subtractor Geometry object.")
         )
         )
 
 
-        grid0.addWidget(self.target_geo_label, 12, 0)
-        grid0.addWidget(self.target_geo_combo, 12, 1)
+        grid0.addWidget(self.target_geo_label, 18, 0)
+        grid0.addWidget(self.target_geo_combo, 18, 1)
 
 
         # Substractor Geometry Object
         # Substractor Geometry Object
         self.sub_geo_combo = FCComboBox()
         self.sub_geo_combo = FCComboBox()
@@ -753,13 +778,13 @@ class SubUI:
               "from the target Geometry object.")
               "from the target Geometry object.")
         )
         )
 
 
-        grid0.addWidget(self.sub_geo_label, 14, 0)
-        grid0.addWidget(self.sub_geo_combo, 14, 1)
+        grid0.addWidget(self.sub_geo_label, 20, 0)
+        grid0.addWidget(self.sub_geo_combo, 20, 1)
 
 
         self.close_paths_cb = FCCheckBox(_("Close paths"))
         self.close_paths_cb = FCCheckBox(_("Close paths"))
         self.close_paths_cb.setToolTip(_("Checking this will close the paths cut by the Geometry subtractor object."))
         self.close_paths_cb.setToolTip(_("Checking this will close the paths cut by the Geometry subtractor object."))
 
 
-        grid0.addWidget(self.close_paths_cb, 16, 0, 1, 2)
+        grid0.addWidget(self.close_paths_cb, 22, 0, 1, 2)
 
 
         self.intersect_geo_btn = FCButton(_('Subtract Geometry'))
         self.intersect_geo_btn = FCButton(_('Subtract Geometry'))
         self.intersect_geo_btn.setIcon(QtGui.QIcon(self.app.resource_location + '/subtract_btn32.png'))
         self.intersect_geo_btn.setIcon(QtGui.QIcon(self.app.resource_location + '/subtract_btn32.png'))
@@ -774,8 +799,8 @@ class SubUI:
                                 }
                                 }
                                 """)
                                 """)
 
 
-        grid0.addWidget(self.intersect_geo_btn, 18, 0, 1, 2)
-        grid0.addWidget(QtWidgets.QLabel(''), 20, 0, 1, 2)
+        grid0.addWidget(self.intersect_geo_btn, 24, 0, 1, 2)
+        grid0.addWidget(QtWidgets.QLabel(''), 26, 0, 1, 2)
 
 
         self.tools_box.addStretch()
         self.tools_box.addStretch()
 
 

+ 281 - 110
app_Main.py

@@ -281,9 +281,6 @@ class App(QtCore.QObject):
 
 
         self.qapp = qapp
         self.qapp = qapp
 
 
-        # declare it here so there is a reference
-        self.f_handlers = lambda: None
-
         # ############################################################################################################
         # ############################################################################################################
         # ################# Setup the listening thread for another instance launching with args ######################
         # ################# Setup the listening thread for another instance launching with args ######################
         # ############################################################################################################
         # ############################################################################################################
@@ -610,23 +607,6 @@ class App(QtCore.QObject):
         # When the self.defaults dictionary changes will update the Preferences GUI forms
         # When the self.defaults dictionary changes will update the Preferences GUI forms
         self.defaults.set_change_callback(self.on_defaults_dict_change)
         self.defaults.set_change_callback(self.on_defaults_dict_change)
 
 
-        # ###########################################################################################################
-        # ##################################### FIRST RUN SECTION ###################################################
-        # ################################ It's done only once after install   #####################################
-        # ###########################################################################################################
-        if self.defaults["first_run"] is True:
-            # ONLY AT FIRST STARTUP INIT THE GUI LAYOUT TO 'minimal'
-            initial_lay = 'minimal'
-            self.ui.general_defaults_form.general_gui_group.on_layout(lay=initial_lay)
-
-            # Set the combobox in Preferences to the current layout
-            idx = self.ui.general_defaults_form.general_gui_group.layout_combo.findText(initial_lay)
-            self.ui.general_defaults_form.general_gui_group.layout_combo.setCurrentIndex(idx)
-
-            # after the first run, this object should be False
-            self.defaults["first_run"] = False
-            self.preferencesUiManager.save_defaults(silent=True)
-
         # ###########################################################################################################
         # ###########################################################################################################
         # ############################################ Data #########################################################
         # ############################################ Data #########################################################
         # ###########################################################################################################
         # ###########################################################################################################
@@ -1184,6 +1164,9 @@ class App(QtCore.QObject):
 
 
         self.text_editor_tab = None
         self.text_editor_tab = None
 
 
+        # here store the color of a Tab text before it is changed so it can be restored in the future
+        self.old_tab_text_color = None
+
         # reference for the self.ui.code_editor
         # reference for the self.ui.code_editor
         self.reference_code_editor = None
         self.reference_code_editor = None
         self.script_code = ''
         self.script_code = ''
@@ -1281,7 +1264,10 @@ class App(QtCore.QObject):
         self.log.debug("Finished adding FlatCAM Editor's.")
         self.log.debug("Finished adding FlatCAM Editor's.")
 
 
         self.ui.set_ui_title(name=_("New Project - Not saved"))
         self.ui.set_ui_title(name=_("New Project - Not saved"))
-
+        
+        # ###########################################################################################################
+        # ########################################## Install OPTIMIZATIONS for GCode generation #####################
+        # ###########################################################################################################
         current_platform = platform.architecture()[0]
         current_platform = platform.architecture()[0]
         if current_platform != '64bit':
         if current_platform != '64bit':
             # set Excellon path optimizations algorithm to TSA if the app is run on a 32bit platform
             # set Excellon path optimizations algorithm to TSA if the app is run on a 32bit platform
@@ -1308,6 +1294,25 @@ class App(QtCore.QObject):
         # this is calculated in the class above (somehow?)
         # this is calculated in the class above (somehow?)
         self.defaults["root_folder_path"] = self.app_home
         self.defaults["root_folder_path"] = self.app_home
 
 
+        # ###########################################################################################################
+        # ##################################### FIRST RUN SECTION ###################################################
+        # ################################ It's done only once after install   #####################################
+        # ###########################################################################################################
+        if self.defaults["first_run"] is True:
+            # ONLY AT FIRST STARTUP INIT THE GUI LAYOUT TO 'minimal'
+            self.log.debug("-> First Run: Setting up the first Layout" )
+            initial_lay = 'minimal'
+            self.on_layout(lay=initial_lay)
+
+            # Set the combobox in Preferences to the current layout
+            idx = self.ui.general_defaults_form.general_gui_group.layout_combo.findText(initial_lay)
+            self.ui.general_defaults_form.general_gui_group.layout_combo.setCurrentIndex(idx)
+
+            # after the first run, this object should be False
+            self.defaults["first_run"] = False
+            self.log.debug("-> First Run: Updating the Defaults file with Factory Defaults")
+            self.preferencesUiManager.save_defaults(silent=True)
+
         # ###########################################################################################################
         # ###########################################################################################################
         # ############################################### SYS TRAY ##################################################
         # ############################################### SYS TRAY ##################################################
         # ###########################################################################################################
         # ###########################################################################################################
@@ -1494,7 +1499,7 @@ class App(QtCore.QObject):
         self.ui.menuprojectproperties.triggered.connect(self.obj_properties)
         self.ui.menuprojectproperties.triggered.connect(self.obj_properties)
 
 
         # ToolBar signals
         # ToolBar signals
-        self.connect_toolbar_signals(ui=self.ui)
+        self.connect_toolbar_signals()
 
 
         # Context Menu
         # Context Menu
         self.ui.popmenu_disable.triggered.connect(lambda: self.toggle_plots(self.collection.get_selected()))
         self.ui.popmenu_disable.triggered.connect(lambda: self.toggle_plots(self.collection.get_selected()))
@@ -2100,85 +2105,246 @@ class App(QtCore.QObject):
     #     self.worker_task.emit({'fcn': self.f_parse.get_fonts_by_types,
     #     self.worker_task.emit({'fcn': self.f_parse.get_fonts_by_types,
     #                            'params': []})
     #                            'params': []})
 
 
-    def connect_tools_signals_to_toolbar(self, ui):
-        ui.dblsided_btn.triggered.connect(lambda: self.dblsidedtool.run(toggle=True))
-        ui.cal_btn.triggered.connect(lambda: self.cal_exc_tool.run(toggle=True))
-        ui.align_btn.triggered.connect(lambda: self.align_objects_tool.run(toggle=True))
-        ui.extract_btn.triggered.connect(lambda: self.edrills_tool.run(toggle=True))
-
-        ui.cutout_btn.triggered.connect(lambda: self.cutout_tool.run(toggle=True))
-        ui.ncc_btn.triggered.connect(lambda: self.ncclear_tool.run(toggle=True))
-        ui.paint_btn.triggered.connect(lambda: self.paint_tool.run(toggle=True))
-        ui.isolation_btn.triggered.connect(lambda: self.isolation_tool.run(toggle=True))
-        ui.drill_btn.triggered.connect(lambda: self.drilling_tool.run(toggle=True))
-
-        ui.panelize_btn.triggered.connect(lambda: self.panelize_tool.run(toggle=True))
-        ui.film_btn.triggered.connect(lambda: self.film_tool.run(toggle=True))
-        ui.solder_btn.triggered.connect(lambda: self.paste_tool.run(toggle=True))
-        ui.sub_btn.triggered.connect(lambda: self.sub_tool.run(toggle=True))
-        ui.rules_btn.triggered.connect(lambda: self.rules_tool.run(toggle=True))
-        ui.optimal_btn.triggered.connect(lambda: self.optimal_tool.run(toggle=True))
-
-        ui.calculators_btn.triggered.connect(lambda: self.calculator_tool.run(toggle=True))
-        ui.transform_btn.triggered.connect(lambda: self.transform_tool.run(toggle=True))
-        ui.qrcode_btn.triggered.connect(lambda: self.qrcode_tool.run(toggle=True))
-        ui.copperfill_btn.triggered.connect(lambda: self.copper_thieving_tool.run(toggle=True))
-        ui.fiducials_btn.triggered.connect(lambda: self.fiducial_tool.run(toggle=True))
-        ui.punch_btn.triggered.connect(lambda: self.punch_tool.run(toggle=True))
-        ui.invert_btn.triggered.connect(lambda: self.invert_tool.run(toggle=True))
-        ui.corners_tool_btn.triggered.connect(lambda: self.corners_tool.run(toggle=True))
-        ui.etch_btn.triggered.connect(lambda: self.etch_tool.run(toggle=True))
-
-    def connect_toolbar_signals(self, ui):
+    def connect_tools_signals_to_toolbar(self):
+        self.log.debug(" -> Connecting Tools Toolbar Signals")
+
+        self.ui.dblsided_btn.triggered.connect(lambda: self.dblsidedtool.run(toggle=True))
+        self.ui.cal_btn.triggered.connect(lambda: self.cal_exc_tool.run(toggle=True))
+        self.ui.align_btn.triggered.connect(lambda: self.align_objects_tool.run(toggle=True))
+        self.ui.extract_btn.triggered.connect(lambda: self.edrills_tool.run(toggle=True))
+
+        self.ui.cutout_btn.triggered.connect(lambda: self.cutout_tool.run(toggle=True))
+        self.ui.ncc_btn.triggered.connect(lambda: self.ncclear_tool.run(toggle=True))
+        self.ui.paint_btn.triggered.connect(lambda: self.paint_tool.run(toggle=True))
+        self.ui.isolation_btn.triggered.connect(lambda: self.isolation_tool.run(toggle=True))
+        self.ui.drill_btn.triggered.connect(lambda: self.drilling_tool.run(toggle=True))
+
+        self.ui.panelize_btn.triggered.connect(lambda: self.panelize_tool.run(toggle=True))
+        self.ui.film_btn.triggered.connect(lambda: self.film_tool.run(toggle=True))
+        self.ui.solder_btn.triggered.connect(lambda: self.paste_tool.run(toggle=True))
+        self.ui.sub_btn.triggered.connect(lambda: self.sub_tool.run(toggle=True))
+        self.ui.rules_btn.triggered.connect(lambda: self.rules_tool.run(toggle=True))
+        self.ui.optimal_btn.triggered.connect(lambda: self.optimal_tool.run(toggle=True))
+
+        self.ui.calculators_btn.triggered.connect(lambda: self.calculator_tool.run(toggle=True))
+        self.ui.transform_btn.triggered.connect(lambda: self.transform_tool.run(toggle=True))
+        self.ui.qrcode_btn.triggered.connect(lambda: self.qrcode_tool.run(toggle=True))
+        self.ui.copperfill_btn.triggered.connect(lambda: self.copper_thieving_tool.run(toggle=True))
+        self.ui.fiducials_btn.triggered.connect(lambda: self.fiducial_tool.run(toggle=True))
+        self.ui.punch_btn.triggered.connect(lambda: self.punch_tool.run(toggle=True))
+        self.ui.invert_btn.triggered.connect(lambda: self.invert_tool.run(toggle=True))
+        self.ui.corners_tool_btn.triggered.connect(lambda: self.corners_tool.run(toggle=True))
+        self.ui.etch_btn.triggered.connect(lambda: self.etch_tool.run(toggle=True))
+
+    def connect_editors_toolbar_signals(self):
+        self.log.debug(" -> Connecting Editors Toolbar Signals")
+
+        # Geometry Editor Toolbar Signals
+        self.geo_editor.connect_geo_toolbar_signals()
+
+        # Gerber Editor Toolbar Signals
+        self.grb_editor.connect_grb_toolbar_signals()
+
+        # Excellon Editor Toolbar Signals
+        self.exc_editor.connect_exc_toolbar_signals()
+
+    def connect_toolbar_signals(self):
         """
         """
         Reconnect the signals to the actions in the toolbar.
         Reconnect the signals to the actions in the toolbar.
         This has to be done each time after the FlatCAM tools are removed/installed.
         This has to be done each time after the FlatCAM tools are removed/installed.
 
 
         :return: None
         :return: None
         """
         """
-
+        self.log.debug(" -> Connecting Toolbar Signals")
         # Toolbar
         # Toolbar
 
 
         # File Toolbar Signals
         # File Toolbar Signals
         # ui.file_new_btn.triggered.connect(self.on_file_new)
         # ui.file_new_btn.triggered.connect(self.on_file_new)
-        ui.file_open_btn.triggered.connect(self.f_handlers.on_file_openproject)
-        ui.file_save_btn.triggered.connect(self.f_handlers.on_file_saveproject)
-        ui.file_open_gerber_btn.triggered.connect(self.f_handlers.on_fileopengerber)
-        ui.file_open_excellon_btn.triggered.connect(self.f_handlers.on_fileopenexcellon)
+        self.ui.file_open_btn.triggered.connect(self.f_handlers.on_file_openproject)
+        self.ui.file_save_btn.triggered.connect(self.f_handlers.on_file_saveproject)
+        self.ui.file_open_gerber_btn.triggered.connect(self.f_handlers.on_fileopengerber)
+        self.ui.file_open_excellon_btn.triggered.connect(self.f_handlers.on_fileopenexcellon)
 
 
         # View Toolbar Signals
         # View Toolbar Signals
-        ui.clear_plot_btn.triggered.connect(self.clear_plots)
-        ui.replot_btn.triggered.connect(self.plot_all)
-        ui.zoom_fit_btn.triggered.connect(self.on_zoom_fit)
-        ui.zoom_in_btn.triggered.connect(lambda: self.plotcanvas.zoom(1 / 1.5))
-        ui.zoom_out_btn.triggered.connect(lambda: self.plotcanvas.zoom(1.5))
+        self.ui.clear_plot_btn.triggered.connect(self.clear_plots)
+        self.ui.replot_btn.triggered.connect(self.plot_all)
+        self.ui.zoom_fit_btn.triggered.connect(self.on_zoom_fit)
+        self.ui.zoom_in_btn.triggered.connect(lambda: self.plotcanvas.zoom(1 / 1.5))
+        self.ui.zoom_out_btn.triggered.connect(lambda: self.plotcanvas.zoom(1.5))
 
 
         # Edit Toolbar Signals
         # Edit Toolbar Signals
-        ui.editgeo_btn.triggered.connect(self.object2editor)
-        ui.update_obj_btn.triggered.connect(lambda: self.editor2object())
-        ui.copy_btn.triggered.connect(self.on_copy_command)
-        ui.delete_btn.triggered.connect(self.on_delete)
+        self.ui.editgeo_btn.triggered.connect(self.object2editor)
+        self.ui.update_obj_btn.triggered.connect(lambda: self.editor2object())
+        self.ui.copy_btn.triggered.connect(self.on_copy_command)
+        self.ui.delete_btn.triggered.connect(self.on_delete)
 
 
-        ui.distance_btn.triggered.connect(lambda: self.distance_tool.run(toggle=True))
-        ui.distance_min_btn.triggered.connect(lambda: self.distance_min_tool.run(toggle=True))
-        ui.origin_btn.triggered.connect(self.on_set_origin)
-        ui.move2origin_btn.triggered.connect(self.on_move2origin)
+        self.ui.distance_btn.triggered.connect(lambda: self.distance_tool.run(toggle=True))
+        self.ui.distance_min_btn.triggered.connect(lambda: self.distance_min_tool.run(toggle=True))
+        self.ui.origin_btn.triggered.connect(self.on_set_origin)
+        self.ui.move2origin_btn.triggered.connect(self.on_move2origin)
 
 
-        ui.jmp_btn.triggered.connect(self.on_jump_to)
-        ui.locate_btn.triggered.connect(lambda: self.on_locate(obj=self.collection.get_active()))
+        self.ui.jmp_btn.triggered.connect(self.on_jump_to)
+        self.ui.locate_btn.triggered.connect(lambda: self.on_locate(obj=self.collection.get_active()))
 
 
         # Scripting Toolbar Signals
         # Scripting Toolbar Signals
-        ui.shell_btn.triggered.connect(ui.toggle_shell_ui)
-        ui.new_script_btn.triggered.connect(self.f_handlers.on_filenewscript)
-        ui.open_script_btn.triggered.connect(self.f_handlers.on_fileopenscript)
-        ui.run_script_btn.triggered.connect(self.f_handlers.on_filerunscript)
+        self.ui.shell_btn.triggered.connect(self.ui.toggle_shell_ui)
+        self.ui.new_script_btn.triggered.connect(self.f_handlers.on_filenewscript)
+        self.ui.open_script_btn.triggered.connect(self.f_handlers.on_fileopenscript)
+        self.ui.run_script_btn.triggered.connect(self.f_handlers.on_filerunscript)
 
 
         # Tools Toolbar Signals
         # Tools Toolbar Signals
         try:
         try:
-            self.connect_tools_signals_to_toolbar(ui=ui)
+            self.connect_tools_signals_to_toolbar()
         except Exception as err:
         except Exception as err:
             self.log.debug("App.connect_toolbar_signals() tools signals -> %s" % str(err))
             self.log.debug("App.connect_toolbar_signals() tools signals -> %s" % str(err))
 
 
+    def on_layout(self, index=None, lay=None):
+        """
+        Set the toolbars layout (location)
+
+        :param index:
+        :param lay:     Type of layout to be set on the toolbard
+        :return:        None
+        """
+
+        self.defaults.report_usage("on_layout()")
+        self.log.debug(" ---> New Layout")
+
+        if lay:
+            current_layout = lay
+        else:
+            current_layout = self.ui.general_defaults_form.general_gui_group.layout_combo.get_value()
+
+        lay_settings = QSettings("Open Source", "FlatCAM")
+        lay_settings.setValue('layout', current_layout)
+
+        # This will write the setting to the platform specific storage.
+        del lay_settings
+
+        # first remove the toolbars:
+        self.log.debug(" -> Remove Toolbars")
+        try:
+            self.ui.removeToolBar(self.ui.toolbarfile)
+            self.ui.removeToolBar(self.ui.toolbaredit)
+            self.ui.removeToolBar(self.ui.toolbarview)
+            self.ui.removeToolBar(self.ui.toolbarshell)
+            self.ui.removeToolBar(self.ui.toolbartools)
+            self.ui.removeToolBar(self.ui.exc_edit_toolbar)
+            self.ui.removeToolBar(self.ui.geo_edit_toolbar)
+            self.ui.removeToolBar(self.ui.grb_edit_toolbar)
+            self.ui.removeToolBar(self.ui.toolbarshell)
+        except Exception:
+            pass
+
+        self.log.debug(" -> Add New Toolbars")
+        if current_layout == 'compact':
+            # ## TOOLBAR INSTALLATION # ##
+            self.ui.toolbarfile = QtWidgets.QToolBar('File Toolbar')
+            self.ui.toolbarfile.setObjectName('File_TB')
+            self.ui.addToolBar(Qt.LeftToolBarArea, self.ui.toolbarfile)
+
+            self.ui.toolbaredit = QtWidgets.QToolBar('Edit Toolbar')
+            self.ui.toolbaredit.setObjectName('Edit_TB')
+            self.ui.addToolBar(Qt.LeftToolBarArea, self.ui.toolbaredit)
+
+            self.ui.toolbarshell = QtWidgets.QToolBar('Shell Toolbar')
+            self.ui.toolbarshell.setObjectName('Shell_TB')
+            self.ui.addToolBar(Qt.LeftToolBarArea, self.ui.toolbarshell)
+
+            self.ui.toolbartools = QtWidgets.QToolBar('Tools Toolbar')
+            self.ui.toolbartools.setObjectName('Tools_TB')
+            self.ui.addToolBar(Qt.LeftToolBarArea, self.ui.toolbartools)
+
+            self.ui.geo_edit_toolbar = QtWidgets.QToolBar('Geometry Editor Toolbar')
+            self.ui.geo_edit_toolbar.setObjectName('GeoEditor_TB')
+            self.ui.addToolBar(Qt.RightToolBarArea, self.ui.geo_edit_toolbar)
+
+            self.ui.toolbarview = QtWidgets.QToolBar('View Toolbar')
+            self.ui.toolbarview.setObjectName('View_TB')
+            self.ui.addToolBar(Qt.RightToolBarArea, self.ui.toolbarview)
+
+            self.ui.addToolBarBreak(area=Qt.RightToolBarArea)
+
+            self.ui.grb_edit_toolbar = QtWidgets.QToolBar('Gerber Editor Toolbar')
+            self.ui.grb_edit_toolbar.setObjectName('GrbEditor_TB')
+            self.ui.addToolBar(Qt.RightToolBarArea, self.ui.grb_edit_toolbar)
+
+            self.ui.exc_edit_toolbar = QtWidgets.QToolBar('Excellon Editor Toolbar')
+            self.ui.exc_edit_toolbar.setObjectName('ExcEditor_TB')
+            self.ui.addToolBar(Qt.RightToolBarArea, self.ui.exc_edit_toolbar)
+        else:
+            # ## TOOLBAR INSTALLATION # ##
+            self.ui.toolbarfile = QtWidgets.QToolBar('File Toolbar')
+            self.ui.toolbarfile.setObjectName('File_TB')
+            self.ui.addToolBar(self.ui.toolbarfile)
+
+            self.ui.toolbaredit = QtWidgets.QToolBar('Edit Toolbar')
+            self.ui.toolbaredit.setObjectName('Edit_TB')
+            self.ui.addToolBar(self.ui.toolbaredit)
+
+            self.ui.toolbarview = QtWidgets.QToolBar('View Toolbar')
+            self.ui.toolbarview.setObjectName('View_TB')
+            self.ui.addToolBar(self.ui.toolbarview)
+
+            self.ui.toolbarshell = QtWidgets.QToolBar('Shell Toolbar')
+            self.ui.toolbarshell.setObjectName('Shell_TB')
+            self.ui.addToolBar(self.ui.toolbarshell)
+
+            self.ui.toolbartools = QtWidgets.QToolBar('Tools Toolbar')
+            self.ui.toolbartools.setObjectName('Tools_TB')
+            self.ui.addToolBar(self.ui.toolbartools)
+
+            self.ui.exc_edit_toolbar = QtWidgets.QToolBar('Excellon Editor Toolbar')
+            # self.ui.exc_edit_toolbar.setVisible(False)
+            self.ui.exc_edit_toolbar.setObjectName('ExcEditor_TB')
+            self.ui.addToolBar(self.ui.exc_edit_toolbar)
+
+            self.ui.addToolBarBreak()
+
+            self.ui.geo_edit_toolbar = QtWidgets.QToolBar('Geometry Editor Toolbar')
+            # self.ui.geo_edit_toolbar.setVisible(False)
+            self.ui.geo_edit_toolbar.setObjectName('GeoEditor_TB')
+            self.ui.addToolBar(self.ui.geo_edit_toolbar)
+
+            self.ui.grb_edit_toolbar = QtWidgets.QToolBar('Gerber Editor Toolbar')
+            # self.ui.grb_edit_toolbar.setVisible(False)
+            self.ui.grb_edit_toolbar.setObjectName('GrbEditor_TB')
+            self.ui.addToolBar(self.ui.grb_edit_toolbar)
+
+        if current_layout == 'minimal':
+            self.ui.toolbarview.setVisible(False)
+            self.ui.toolbarshell.setVisible(False)
+            self.ui.geo_edit_toolbar.setVisible(False)
+            self.ui.grb_edit_toolbar.setVisible(False)
+            self.ui.exc_edit_toolbar.setVisible(False)
+            self.ui.lock_toolbar(lock=True)
+
+        # add all the actions to the toolbars
+        self.ui.populate_toolbars()
+
+        try:
+            # reconnect all the signals to the toolbar actions
+            self.connect_toolbar_signals()
+        except Exception as e:
+            self.log.debug(
+                "App.on_layout() - connect toolbar signals -> %s" % str(e))
+
+        # Editor Toolbars Signals
+        try:
+            self.connect_editors_toolbar_signals()
+        except Exception as err:
+            self.log.debug("App.on_layout() - connect editor signals -> %s" % str(err))
+
+        self.ui.grid_snap_btn.setChecked(True)
+
+        self.ui.corner_snap_btn.setVisible(False)
+        self.ui.snap_magnet.setVisible(False)
+
+        self.ui.grid_gap_x_entry.setText(str(self.defaults["global_gridx"]))
+        self.ui.grid_gap_y_entry.setText(str(self.defaults["global_gridy"]))
+        self.ui.snap_max_dist_entry.setText(str(self.defaults["global_snap_max"]))
+        self.ui.grid_gap_link_cb.setChecked(True)
+
     def object2editor(self):
     def object2editor(self):
         """
         """
         Send the current Geometry, Gerber, Excellon object or CNCJob (if any) into the it's editor.
         Send the current Geometry, Gerber, Excellon object or CNCJob (if any) into the it's editor.
@@ -2186,7 +2352,7 @@ class App(QtCore.QObject):
         :return: None
         :return: None
         """
         """
         self.defaults.report_usage("object2editor()")
         self.defaults.report_usage("object2editor()")
-
+        self.log.debug("######################### Starting the EDITOR ################################")
         # disable the objects menu as it may interfere with the appEditors
         # disable the objects menu as it may interfere with the appEditors
         self.ui.menuobjects.setDisabled(True)
         self.ui.menuobjects.setDisabled(True)
 
 
@@ -2236,7 +2402,6 @@ class App(QtCore.QObject):
 
 
             # set call source to the Editor we go into
             # set call source to the Editor we go into
             self.call_source = 'geo_editor'
             self.call_source = 'geo_editor'
-
         elif isinstance(edited_object, ExcellonObject):
         elif isinstance(edited_object, ExcellonObject):
             # store the Excellon Editor Toolbar visibility before entering in the Editor
             # store the Excellon Editor Toolbar visibility before entering in the Editor
             self.exc_editor.toolbar_old_state = True if self.ui.exc_edit_toolbar.isVisible() else False
             self.exc_editor.toolbar_old_state = True if self.ui.exc_edit_toolbar.isVisible() else False
@@ -2248,7 +2413,6 @@ class App(QtCore.QObject):
 
 
             # set call source to the Editor we go into
             # set call source to the Editor we go into
             self.call_source = 'exc_editor'
             self.call_source = 'exc_editor'
-
         elif isinstance(edited_object, GerberObject):
         elif isinstance(edited_object, GerberObject):
             # store the Gerber Editor Toolbar visibility before entering in the Editor
             # store the Gerber Editor Toolbar visibility before entering in the Editor
             self.grb_editor.toolbar_old_state = True if self.ui.grb_edit_toolbar.isVisible() else False
             self.grb_editor.toolbar_old_state = True if self.ui.grb_edit_toolbar.isVisible() else False
@@ -2263,7 +2427,6 @@ class App(QtCore.QObject):
 
 
             # reset the following variables so the UI is built again after edit
             # reset the following variables so the UI is built again after edit
             edited_object.ui_build = False
             edited_object.ui_build = False
-
         elif isinstance(edited_object, CNCJobObject):
         elif isinstance(edited_object, CNCJobObject):
 
 
             if self.ui.splitter.sizes()[0] == 0:
             if self.ui.splitter.sizes()[0] == 0:
@@ -2275,9 +2438,19 @@ class App(QtCore.QObject):
             self.gcode_editor.edit_fcgcode(edited_object)
             self.gcode_editor.edit_fcgcode(edited_object)
 
 
         # make sure that we can't select another object while in Editor Mode:
         # make sure that we can't select another object while in Editor Mode:
-        # self.collection.view.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
         self.ui.project_frame.setDisabled(True)
         self.ui.project_frame.setDisabled(True)
 
 
+        for idx in range(self.ui.notebook.count()):
+            # store the Properties Tab text color here and change the color and text
+            if self.ui.notebook.tabText(idx) == _("Properties"):
+                self.old_tab_text_color = self.ui.notebook.tabBar.tabTextColor(idx)
+                self.ui.notebook.tabBar.setTabTextColor(idx, QtGui.QColor('red'))
+                self.ui.notebook.tabBar.setTabText(idx, _("Editor"))
+
+            # disable the Project Tab
+            if self.ui.notebook.tabText(idx) == _("Project"):
+                self.ui.notebook.tabBar.setTabEnabled(idx, False)
+
         # delete any selection shape that might be active as they are not relevant in Editor
         # delete any selection shape that might be active as they are not relevant in Editor
         self.delete_selection_shape()
         self.delete_selection_shape()
 
 
@@ -2302,6 +2475,7 @@ class App(QtCore.QObject):
         :return: None
         :return: None
         """
         """
         self.defaults.report_usage("editor2object()")
         self.defaults.report_usage("editor2object()")
+        self.log.debug("######################### Closing the EDITOR ################################")
 
 
         # re-enable the objects menu that was disabled on entry in Editor mode
         # re-enable the objects menu that was disabled on entry in Editor mode
         self.ui.menuobjects.setDisabled(False)
         self.ui.menuobjects.setDisabled(False)
@@ -2431,7 +2605,6 @@ class App(QtCore.QObject):
                         return
                         return
 
 
                     self.inform.emit('[selected] %s %s' % (obj_type, _("is updated, returning to App...")))
                     self.inform.emit('[selected] %s %s' % (obj_type, _("is updated, returning to App...")))
-
                 elif response == bt_no:
                 elif response == bt_no:
                     # show the Tools Toolbar
                     # show the Tools Toolbar
                     tools_tb = self.ui.toolbartools
                     tools_tb = self.ui.toolbartools
@@ -2498,6 +2671,16 @@ class App(QtCore.QObject):
             if self.ui.splitter.sizes()[0] == 0:
             if self.ui.splitter.sizes()[0] == 0:
                 self.ui.splitter.setSizes([1, 1])
                 self.ui.splitter.setSizes([1, 1])
 
 
+            for idx in range(self.ui.notebook.count()):
+                # restore the Properties Tab text and color
+                if self.ui.notebook.tabText(idx) == _("Editor"):
+                    self.ui.notebook.tabBar.setTabTextColor(idx, self.old_tab_text_color)
+                    self.ui.notebook.tabBar.setTabText(idx, _("Properties"))
+
+                # enable the Project Tab
+                if self.ui.notebook.tabText(idx) == _("Project"):
+                    self.ui.notebook.tabBar.setTabEnabled(idx, True)
+
             # restore the call_source to app
             # restore the call_source to app
             self.call_source = 'app'
             self.call_source = 'app'
 
 
@@ -2506,7 +2689,6 @@ class App(QtCore.QObject):
             self.ui.plot_tab_area.protectTab(0)
             self.ui.plot_tab_area.protectTab(0)
 
 
             # make sure that we reenable the selection on Project Tab after returning from Editor Mode:
             # make sure that we reenable the selection on Project Tab after returning from Editor Mode:
-            # self.collection.view.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
             self.ui.project_frame.setDisabled(False)
             self.ui.project_frame.setDisabled(False)
 
 
     def get_last_folder(self):
     def get_last_folder(self):
@@ -3634,12 +3816,12 @@ class App(QtCore.QObject):
             # register all keys in the Preferences window
             # register all keys in the Preferences window
             for ext in exc_list:
             for ext in exc_list:
                 new_k = new_reg_path + '.%s' % ext
                 new_k = new_reg_path + '.%s' % ext
-                set_reg('', root_path=root_path, new_reg_path=new_k, value='FlatCAM')
+                set_reg('', root_pth=root_path, new_reg_path_par=new_k, value='FlatCAM')
 
 
             # and unregister those that are no longer in the Preferences windows but are in the file
             # and unregister those that are no longer in the Preferences windows but are in the file
             for ext in self.defaults["fa_excellon"].replace(' ', '').split(','):
             for ext in self.defaults["fa_excellon"].replace(' ', '').split(','):
                 if ext not in exc_list:
                 if ext not in exc_list:
-                    delete_reg(root_path=root_path, reg_path=new_reg_path, key_to_del='.%s' % ext)
+                    delete_reg(root_pth=root_path, reg_path=new_reg_path, key_to_del='.%s' % ext)
 
 
             # now write the updated extensions to the self.defaults
             # now write the updated extensions to the self.defaults
             # new_ext = ''
             # new_ext = ''
@@ -3655,18 +3837,13 @@ class App(QtCore.QObject):
             # register all keys in the Preferences window
             # register all keys in the Preferences window
             for ext in gco_list:
             for ext in gco_list:
                 new_k = new_reg_path + '.%s' % ext
                 new_k = new_reg_path + '.%s' % ext
-                set_reg('', root_path=root_path, new_reg_path=new_k, value='FlatCAM')
+                set_reg('', root_pth=root_path, new_reg_path_par=new_k, value='FlatCAM')
 
 
             # and unregister those that are no longer in the Preferences windows but are in the file
             # and unregister those that are no longer in the Preferences windows but are in the file
             for ext in self.defaults["fa_gcode"].replace(' ', '').split(','):
             for ext in self.defaults["fa_gcode"].replace(' ', '').split(','):
                 if ext not in gco_list:
                 if ext not in gco_list:
-                    delete_reg(root_path=root_path, reg_path=new_reg_path, key_to_del='.%s' % ext)
+                    delete_reg(root_pth=root_path, reg_path=new_reg_path, key_to_del='.%s' % ext)
 
 
-            # now write the updated extensions to the self.defaults
-            # new_ext = ''
-            # for ext in gco_list:
-            #     new_ext = new_ext + ext + ', '
-            # self.defaults["fa_gcode"] = new_ext
             self.inform.emit('[success] %s' %
             self.inform.emit('[success] %s' %
                              _("Selected GCode file extensions registered with FlatCAM."))
                              _("Selected GCode file extensions registered with FlatCAM."))
 
 
@@ -3677,20 +3854,14 @@ class App(QtCore.QObject):
             # register all keys in the Preferences window
             # register all keys in the Preferences window
             for ext in grb_list:
             for ext in grb_list:
                 new_k = new_reg_path + '.%s' % ext
                 new_k = new_reg_path + '.%s' % ext
-                set_reg('', root_path=root_path, new_reg_path=new_k, value='FlatCAM')
+                set_reg('', root_pth=root_path, new_reg_path_par=new_k, value='FlatCAM')
 
 
             # and unregister those that are no longer in the Preferences windows but are in the file
             # and unregister those that are no longer in the Preferences windows but are in the file
             for ext in self.defaults["fa_gerber"].replace(' ', '').split(','):
             for ext in self.defaults["fa_gerber"].replace(' ', '').split(','):
                 if ext not in grb_list:
                 if ext not in grb_list:
-                    delete_reg(root_path=root_path, reg_path=new_reg_path, key_to_del='.%s' % ext)
+                    delete_reg(root_pth=root_path, reg_path=new_reg_path, key_to_del='.%s' % ext)
 
 
-            # now write the updated extensions to the self.defaults
-            # new_ext = ''
-            # for ext in grb_list:
-            #     new_ext = new_ext + ext + ', '
-            # self.defaults["fa_gerber"] = new_ext
-            self.inform.emit('[success] %s' %
-                             _("Selected Gerber file extensions registered with FlatCAM."))
+            self.inform.emit('[success] %s' % _("Selected Gerber file extensions registered with FlatCAM."))
 
 
     def add_extension(self, ext_type):
     def add_extension(self, ext_type):
         """
         """
@@ -3900,7 +4071,7 @@ class App(QtCore.QObject):
         # if at least one True object is in the list then due of the previous check, all list elements are True objects
         # if at least one True object is in the list then due of the previous check, all list elements are True objects
         if True in geo_type_set:
         if True in geo_type_set:
             def initialize(geo_obj, app):
             def initialize(geo_obj, app):
-                GeometryObject.merge(geo_list=objs, geo_final=geo_obj, multigeo=True, fuse_tools=fuse_tools)
+                GeometryObject.merge(geo_list=objs, geo_final=geo_obj, multi_geo=True, fuse_tools=fuse_tools)
                 app.inform.emit('[success] %s.' % _("Geometry merging finished"))
                 app.inform.emit('[success] %s.' % _("Geometry merging finished"))
 
 
                 # rename all the ['name] key in obj.tools[tooluid]['data'] to the obj_name_multi
                 # rename all the ['name] key in obj.tools[tooluid]['data'] to the obj_name_multi
@@ -3910,7 +4081,7 @@ class App(QtCore.QObject):
             self.app_obj.new_object("geometry", obj_name_multi, initialize)
             self.app_obj.new_object("geometry", obj_name_multi, initialize)
         else:
         else:
             def initialize(geo_obj, app):
             def initialize(geo_obj, app):
-                GeometryObject.merge(geo_list=objs, geo_final=geo_obj, multigeo=False, fuse_tools=fuse_tools)
+                GeometryObject.merge(geo_list=objs, geo_final=geo_obj, multi_geo=False, fuse_tools=fuse_tools)
                 app.inform.emit('[success] %s.' % _("Geometry merging finished"))
                 app.inform.emit('[success] %s.' % _("Geometry merging finished"))
 
 
                 # rename all the ['name] key in obj.tools[tooluid]['data'] to the obj_name_multi
                 # rename all the ['name] key in obj.tools[tooluid]['data'] to the obj_name_multi
@@ -5598,12 +5769,12 @@ class App(QtCore.QObject):
         # self.ui.show()
         # self.ui.show()
 
 
         self.ui.pref_status_label.setStyleSheet("""
         self.ui.pref_status_label.setStyleSheet("""
-                                                            QLabel
-                                                            {
-                                                                color: black;
-                                                                background-color: lightseagreen;
-                                                            }
-                                                            """
+                                                QLabel
+                                                {
+                                                    color: black;
+                                                    background-color: lightseagreen;
+                                                }
+                                                """
                                                 )
                                                 )
 
 
         # detect changes in the preferences
         # detect changes in the preferences

+ 1 - 0
defaults.py

@@ -608,6 +608,7 @@ class FlatCAMDefaults:
 
 
         # Subtract Tool
         # Subtract Tool
         "tools_sub_close_paths": True,
         "tools_sub_close_paths": True,
+        "tools_sub_delete_sources": False,
 
 
         # Distance Tool
         # Distance Tool
         "tools_dist_snap_center": False,
         "tools_dist_snap_center": False,