Kaynağa Gözat

Merged marius_stanciu/flatcam_beta/Beta_8.994 into Beta
NCC Tool fix.

Marius Stanciu 5 yıl önce
ebeveyn
işleme
4d83756f51
4 değiştirilmiş dosya ile 203 ekleme ve 194 silme
  1. 1 0
      CHANGELOG.md
  2. 3 0
      appEditors/AppGeoEditor.py
  3. 118 116
      appTools/ToolNCC.py
  4. 81 78
      app_Main.py

+ 1 - 0
CHANGELOG.md

@@ -14,6 +14,7 @@ CHANGELOG for FlatCAM beta
 - updated Punch Gerber Tool: the Excellon method now takes into consideration the pads choice 
 - updated Punch Gerber Tool: the Excellon method now takes into consideration the pads choice 
 - minor change for the FCComboBox UI element by setting its size policy as ignored so it will not expand the notebook when the name of one of its items is very long
 - minor change for the FCComboBox UI element by setting its size policy as ignored so it will not expand the notebook when the name of one of its items is very long
 - added a protection on opening the tools database UI if the tools DB file is not loaded
 - added a protection on opening the tools database UI if the tools DB file is not loaded
+- fixed NCC Tool not working with the new changes; the check for not having complete isolation is just a Warning
 
 
 28.10.2020
 28.10.2020
 
 

+ 3 - 0
appEditors/AppGeoEditor.py

@@ -27,6 +27,7 @@ from shapely.geometry.polygon import orient
 
 
 import numpy as np
 import numpy as np
 from numpy.linalg import norm as numpy_norm
 from numpy.linalg import norm as numpy_norm
+import logging
 
 
 from rtree import index as rtindex
 from rtree import index as rtindex
 
 
@@ -40,6 +41,8 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
     _ = gettext.gettext
 
 
+log = logging.getLogger('base')
+
 
 
 class BufferSelectionTool(AppTool):
 class BufferSelectionTool(AppTool):
     """
     """

+ 118 - 116
appTools/ToolNCC.py

@@ -8,7 +8,7 @@
 from PyQt5 import QtWidgets, QtCore, QtGui
 from PyQt5 import QtWidgets, QtCore, QtGui
 
 
 from appTool import AppTool
 from appTool import AppTool
-from appGUI.GUIElements import FCCheckBox, FCDoubleSpinner, RadioSet, FCTable, FCInputDialog, FCButton,\
+from appGUI.GUIElements import FCCheckBox, FCDoubleSpinner, RadioSet, FCTable, FCButton,\
     FCComboBox, OptionalInputSection, FCLabel, FCInputDialogSpinnerButton, FCComboBox2
     FCComboBox, OptionalInputSection, FCLabel, FCInputDialogSpinnerButton, FCComboBox2
 from appParsers.ParseGerber import Gerber
 from appParsers.ParseGerber import Gerber
 
 
@@ -463,8 +463,8 @@ class NonCopperClear(AppTool, Gerber):
                                                     callback=self.on_find_optimal_tooldia)
                                                     callback=self.on_find_optimal_tooldia)
         tool_add_popup.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/letter_t_32.png'))
         tool_add_popup.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/letter_t_32.png'))
 
 
-        def find_optimal(val):
-            tool_add_popup.set_value(float(val))
+        def find_optimal(valor):
+            tool_add_popup.set_value(float(valor))
 
 
         self.optimal_found_sig.connect(find_optimal)
         self.optimal_found_sig.connect(find_optimal)
 
 
@@ -629,7 +629,7 @@ class NonCopperClear(AppTool, Gerber):
         # read the table tools uid
         # read the table tools uid
         current_uid_list = []
         current_uid_list = []
         for row in range(self.ui.tools_table.rowCount()):
         for row in range(self.ui.tools_table.rowCount()):
-            uid = int(self.ui.tools_table.item(row,3).text())
+            uid = int(self.ui.tools_table.item(row, 3).text())
             current_uid_list.append(uid)
             current_uid_list.append(uid)
 
 
         new_tools = {}
         new_tools = {}
@@ -675,7 +675,8 @@ class NonCopperClear(AppTool, Gerber):
                     tool_id += 1
                     tool_id += 1
 
 
                     id_ = QtWidgets.QTableWidgetItem('%d' % int(tool_id))
                     id_ = QtWidgets.QTableWidgetItem('%d' % int(tool_id))
-                    id_.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
+                    flags = QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled
+                    id_.setFlags(flags)
                     row_no = tool_id - 1
                     row_no = tool_id - 1
                     self.ui.tools_table.setItem(row_no, 0, id_)  # Tool name/id
                     self.ui.tools_table.setItem(row_no, 0, id_)  # Tool name/id
 
 
@@ -696,8 +697,8 @@ class NonCopperClear(AppTool, Gerber):
 
 
         # make the diameter column editable
         # make the diameter column editable
         for row in range(tool_id):
         for row in range(tool_id):
-            self.ui.tools_table.item(row, 1).setFlags(
-                QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
+            flags = QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled
+            self.ui.tools_table.item(row, 1).setFlags(flags)
 
 
         self.ui.tools_table.resizeColumnsToContents()
         self.ui.tools_table.resizeColumnsToContents()
         self.ui.tools_table.resizeRowsToContents()
         self.ui.tools_table.resizeRowsToContents()
@@ -862,113 +863,113 @@ class NonCopperClear(AppTool, Gerber):
             self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Object not found"), str(obj_name)))
             self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Object not found"), str(obj_name)))
             return
             return
 
 
-        proc = self.app.proc_container.new(_("Working..."))
-
         def job_thread(app_obj, is_display):
         def job_thread(app_obj, is_display):
-            try:
-                old_disp_number = 0
-                pol_nr = 0
-                app_obj.proc_container.update_view_text(' %d%%' % 0)
-                total_geo = []
-
-                for ap in list(fcobj.apertures.keys()):
-                    if 'geometry' in fcobj.apertures[ap]:
-                        for geo_el in fcobj.apertures[ap]['geometry']:
-                            if self.app.abort_flag:
-                                # graceful abort requested by the user
-                                raise grace
-
-                            if 'solid' in geo_el and geo_el['solid'] is not None and geo_el['solid'].is_valid:
-                                total_geo.append(geo_el['solid'])
+            with self.app.proc_container.new(_("Working...")):
+                try:
+                    old_disp_number = 0
+                    pol_nr = 0
+                    app_obj.proc_container.update_view_text(' %d%%' % 0)
+                    total_geo = []
 
 
-                total_geo = MultiPolygon(total_geo)
-                total_geo = total_geo.buffer(0)
+                    for ap in list(fcobj.apertures.keys()):
+                        if 'geometry' in fcobj.apertures[ap]:
+                            for geo_el in fcobj.apertures[ap]['geometry']:
+                                if self.app.abort_flag:
+                                    # graceful abort requested by the user
+                                    raise grace
 
 
-                try:
-                    __ = iter(total_geo)
-                    geo_len = len(total_geo)
-                    geo_len = (geo_len * (geo_len - 1)) / 2
-                except TypeError:
-                    app_obj.inform.emit('[ERROR_NOTCL] %s' %
-                                        _("The Gerber object has one Polygon as geometry.\n"
-                                          "There are no distances between geometry elements to be found."))
-                    return 'fail'
+                                if 'solid' in geo_el and geo_el['solid'] is not None and geo_el['solid'].is_valid:
+                                    total_geo.append(geo_el['solid'])
 
 
-                min_dict = {}
-                idx = 1
-                for geo in total_geo:
-                    for s_geo in total_geo[idx:]:
-                        if self.app.abort_flag:
-                            # graceful abort requested by the user
-                            raise grace
+                    total_geo = MultiPolygon(total_geo)
+                    total_geo = total_geo.buffer(0)
 
 
-                        # minimize the number of distances by not taking into considerations those that are too small
-                        dist = geo.distance(s_geo)
-                        dist = float('%.*f' % (self.decimals, dist))
-                        loc_1, loc_2 = nearest_points(geo, s_geo)
+                    try:
+                        __ = iter(total_geo)
+                        geo_len = len(total_geo)
+                        geo_len = (geo_len * (geo_len - 1)) / 2
+                    except TypeError:
+                        app_obj.inform.emit('[ERROR_NOTCL] %s' %
+                                            _("The Gerber object has one Polygon as geometry.\n"
+                                              "There are no distances between geometry elements to be found."))
+                        return 'fail'
 
 
-                        proc_loc = (
-                            (float('%.*f' % (self.decimals, loc_1.x)), float('%.*f' % (self.decimals, loc_1.y))),
-                            (float('%.*f' % (self.decimals, loc_2.x)), float('%.*f' % (self.decimals, loc_2.y)))
-                        )
+                    min_dict = {}
+                    idx = 1
+                    for geo in total_geo:
+                        for s_geo in total_geo[idx:]:
+                            if self.app.abort_flag:
+                                # graceful abort requested by the user
+                                raise grace
 
 
-                        if dist in min_dict:
-                            min_dict[dist].append(proc_loc)
-                        else:
-                            min_dict[dist] = [proc_loc]
+                            # minimize the number of distances by not taking into considerations
+                            # those that are too small
+                            dist = geo.distance(s_geo)
+                            dist = float('%.*f' % (self.decimals, dist))
+                            loc_1, loc_2 = nearest_points(geo, s_geo)
 
 
-                        pol_nr += 1
-                        disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
+                            proc_loc = (
+                                (float('%.*f' % (self.decimals, loc_1.x)), float('%.*f' % (self.decimals, loc_1.y))),
+                                (float('%.*f' % (self.decimals, loc_2.x)), float('%.*f' % (self.decimals, loc_2.y)))
+                            )
 
 
-                        if old_disp_number < disp_number <= 100:
-                            app_obj.proc_container.update_view_text(' %d%%' % disp_number)
-                            old_disp_number = disp_number
-                    idx += 1
+                            if dist in min_dict:
+                                min_dict[dist].append(proc_loc)
+                            else:
+                                min_dict[dist] = [proc_loc]
 
 
-                min_list = list(min_dict.keys())
-                min_dist = min(min_list)
+                            pol_nr += 1
+                            disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
 
 
-                min_dist_truncated = self.app.dec_format(float(min_dist), self.decimals)
-                self.safe_tooldia = min_dist_truncated
+                            if old_disp_number < disp_number <= 100:
+                                app_obj.proc_container.update_view_text(' %d%%' % disp_number)
+                                old_disp_number = disp_number
+                        idx += 1
 
 
-                if is_display:
-                    self.optimal_found_sig.emit(min_dist_truncated)
+                    min_list = list(min_dict.keys())
+                    min_dist = min(min_list)
 
 
-                    app_obj.inform.emit('[success] %s: %s %s' %
-                                        (_("Optimal tool diameter found"), str(min_dist_truncated),
-                                         self.units.lower()))
-                else:
-                    # find the selected tool ID's
-                    sorted_tools = []
-                    table_items = self.ui.tools_table.selectedItems()
-                    sel_rows = {t.row() for t in table_items}
-                    for row in sel_rows:
-                        tid = int(self.ui.tools_table.item(row, 3).text())
-                        sorted_tools.append(tid)
-                    if not sorted_tools:
-                        msg = _("There are no tools selected in the Tool Table.")
-                        self.app.inform.emit('[ERROR_NOTCL] %s' % msg)
-                        return 'fail'
+                    min_dist_truncated = self.app.dec_format(float(min_dist), self.decimals)
+                    self.safe_tooldia = min_dist_truncated
 
 
-                    # check if the tools diameters are less then the safe tool diameter
-                    suitable_tools = []
-                    for tool in sorted_tools:
-                        tool_dia = float(self.ncc_tools[tool]['tooldia'])
-                        if tool_dia <= self.safe_tooldia:
-                            suitable_tools.append(tool_dia)
+                    if is_display:
+                        self.optimal_found_sig.emit(min_dist_truncated)
 
 
-                    if not suitable_tools:
-                        msg = _("Incomplete isolation. None of the selected tools could do a complete isolation.")
-                        self.app.inform.emit('[WARNING] %s' % msg)
+                        app_obj.inform.emit('[success] %s: %s %s' %
+                                            (_("Optimal tool diameter found"), str(min_dist_truncated),
+                                             self.units.lower()))
                     else:
                     else:
-                        msg = _("At least one of the selected tools can do a complete isolation.")
-                        self.app.inform.emit('[success] %s' % msg)
+                        # find the selected tool ID's
+                        sorted_tools = []
+                        table_items = self.ui.tools_table.selectedItems()
+                        sel_rows = {t.row() for t in table_items}
+                        for row in sel_rows:
+                            tid = int(self.ui.tools_table.item(row, 3).text())
+                            sorted_tools.append(tid)
+                        if not sorted_tools:
+                            msg = _("There are no tools selected in the Tool Table.")
+                            self.app.inform.emit('[ERROR_NOTCL] %s' % msg)
+                            return 'fail'
+
+                        # check if the tools diameters are less then the safe tool diameter
+                        suitable_tools = []
+                        for tool in sorted_tools:
+                            tool_dia = float(self.ncc_tools[tool]['tooldia'])
+                            if tool_dia <= self.safe_tooldia:
+                                suitable_tools.append(tool_dia)
+
+                        if not suitable_tools:
+                            msg = _("Incomplete isolation. None of the selected tools could do a complete isolation.")
+                            self.app.inform.emit('[WARNING] %s' % msg)
+                        else:
+                            msg = _("At least one of the selected tools can do a complete isolation.")
+                            self.app.inform.emit('[success] %s' % msg)
 
 
-                    # reset the value to prepare for another isolation
-                    self.safe_tooldia = None
-            except Exception as ee:
-                log.debug(str(ee))
-                return
+                        # reset the value to prepare for another isolation
+                        self.safe_tooldia = None
+                except Exception as ee:
+                    log.debug(str(ee))
+                    return
 
 
         self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app, is_displayed]})
         self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app, is_displayed]})
 
 
@@ -1374,7 +1375,7 @@ class NonCopperClear(AppTool, Gerber):
                               isotooldia=self.iso_dia_list,
                               isotooldia=self.iso_dia_list,
                               outname=self.o_name,
                               outname=self.o_name,
                               tools_storage=self.ncc_tools)
                               tools_storage=self.ncc_tools)
-        elif self.select_method == 1: # Area Selection
+        elif self.select_method == 1:   # Area Selection
             self.app.inform.emit('[WARNING_NOTCL] %s' % _("Click the start point of the area."))
             self.app.inform.emit('[WARNING_NOTCL] %s' % _("Click the start point of the area."))
 
 
             if self.app.is_legacy is False:
             if self.app.is_legacy is False:
@@ -1676,7 +1677,7 @@ class NonCopperClear(AppTool, Gerber):
         box_kind = box_obj.kind if box_obj is not None else None
         box_kind = box_obj.kind if box_obj is not None else None
 
 
         env_obj = None
         env_obj = None
-        if ncc_select == _('Itself'):
+        if ncc_select == 0:     # _('Itself')
             geo_n = ncc_obj.solid_geometry
             geo_n = ncc_obj.solid_geometry
 
 
             try:
             try:
@@ -1692,13 +1693,13 @@ class NonCopperClear(AppTool, Gerber):
                 log.debug("NonCopperClear.calculate_bounding_box() 'itself'  --> %s" % str(e))
                 log.debug("NonCopperClear.calculate_bounding_box() 'itself'  --> %s" % str(e))
                 self.app.inform.emit('[ERROR_NOTCL] %s' % _("No object available."))
                 self.app.inform.emit('[ERROR_NOTCL] %s' % _("No object available."))
                 return None
                 return None
-        elif ncc_select == _("Area Selection"):
+        elif ncc_select == 1:   # _("Area Selection")
             env_obj = unary_union(self.sel_rect)
             env_obj = unary_union(self.sel_rect)
             try:
             try:
                 __ = iter(env_obj)
                 __ = iter(env_obj)
             except Exception:
             except Exception:
                 env_obj = [env_obj]
                 env_obj = [env_obj]
-        elif ncc_select == _("Reference Object"):
+        elif ncc_select == 2:   # _("Reference Object")
             if box_obj is None:
             if box_obj is None:
                 return None, None
                 return None, None
 
 
@@ -1740,14 +1741,14 @@ class NonCopperClear(AppTool, Gerber):
             return 'fail'
             return 'fail'
 
 
         new_bounding_box = None
         new_bounding_box = None
-        if ncc_select == _('Itself'):
+        if ncc_select == 0:     # _('Itself')
             try:
             try:
                 new_bounding_box = bbox.buffer(distance=ncc_margin, join_style=base.JOIN_STYLE.mitre)
                 new_bounding_box = bbox.buffer(distance=ncc_margin, join_style=base.JOIN_STYLE.mitre)
             except Exception as e:
             except Exception as e:
                 log.debug("NonCopperClear.apply_margin_to_bounding_box() 'itself'  --> %s" % str(e))
                 log.debug("NonCopperClear.apply_margin_to_bounding_box() 'itself'  --> %s" % str(e))
                 self.app.inform.emit('[ERROR_NOTCL] %s' % _("No object available."))
                 self.app.inform.emit('[ERROR_NOTCL] %s' % _("No object available."))
                 return 'fail'
                 return 'fail'
-        elif ncc_select == _("Area Selection"):
+        elif ncc_select == 1:   # _("Area Selection")
             geo_buff_list = []
             geo_buff_list = []
             for poly in bbox:
             for poly in bbox:
                 if self.app.abort_flag:
                 if self.app.abort_flag:
@@ -1755,7 +1756,7 @@ class NonCopperClear(AppTool, Gerber):
                     raise grace
                     raise grace
                 geo_buff_list.append(poly.buffer(distance=ncc_margin, join_style=base.JOIN_STYLE.mitre))
                 geo_buff_list.append(poly.buffer(distance=ncc_margin, join_style=base.JOIN_STYLE.mitre))
             new_bounding_box = unary_union(geo_buff_list)
             new_bounding_box = unary_union(geo_buff_list)
-        elif ncc_select == _("Reference Object"):
+        elif ncc_select == 2:   # _("Reference Object")
             if box_kind == 'geometry':
             if box_kind == 'geometry':
                 geo_buff_list = []
                 geo_buff_list = []
                 for poly in bbox:
                 for poly in bbox:
@@ -1974,7 +1975,7 @@ class NonCopperClear(AppTool, Gerber):
 
 
         cp = None
         cp = None
 
 
-        if ncc_method == 0: # standard
+        if ncc_method == 0:     # standard
             try:
             try:
                 cp = self.clear_polygon(pol, tooldia,
                 cp = self.clear_polygon(pol, tooldia,
                                         steps_per_circle=self.circle_steps,
                                         steps_per_circle=self.circle_steps,
@@ -2133,7 +2134,7 @@ class NonCopperClear(AppTool, Gerber):
 
 
             app_obj.poly_not_cleared = False    # flag for polygons not cleared
             app_obj.poly_not_cleared = False    # flag for polygons not cleared
 
 
-            if ncc_select == 2: # Reference Object
+            if ncc_select == 2:     # Reference Object
                 bbox_geo, bbox_kind = self.calculate_bounding_box(
                 bbox_geo, bbox_kind = self.calculate_bounding_box(
                     ncc_obj=ncc_obj, box_obj=sel_obj, ncc_select=ncc_select)
                     ncc_obj=ncc_obj, box_obj=sel_obj, ncc_select=ncc_select)
             else:
             else:
@@ -2360,14 +2361,10 @@ class NonCopperClear(AppTool, Gerber):
 
 
             sorted_clear_tools.sort(reverse=True)
             sorted_clear_tools.sort(reverse=True)
 
 
-            cleared_by_last_tool = []
-            rest_geo = []
-            current_uid = 1
-
-            # repurposed flag for final object, geo_obj. True if it has any solid_geometry, False if not.
+            # re purposed flag for final object, geo_obj. True if it has any solid_geometry, False if not.
             app_obj.poly_not_cleared = True
             app_obj.poly_not_cleared = True
 
 
-            if ncc_select == 2: # Reference Object
+            if ncc_select == 2:     # Reference Object
                 env_obj, box_obj_kind = self.calculate_bounding_box(
                 env_obj, box_obj_kind = self.calculate_bounding_box(
                     ncc_obj=ncc_obj, box_obj=sel_obj, ncc_select=ncc_select)
                     ncc_obj=ncc_obj, box_obj=sel_obj, ncc_select=ncc_select)
             else:
             else:
@@ -2718,7 +2715,7 @@ class NonCopperClear(AppTool, Gerber):
         self.app.inform.emit(_("NCC Tool. Preparing non-copper polygons."))
         self.app.inform.emit(_("NCC Tool. Preparing non-copper polygons."))
 
 
         try:
         try:
-            if sel_obj is None or sel_obj == 0: # sel_obj == 'itself'
+            if sel_obj is None or sel_obj == 0:     # sel_obj == 'itself'
                 ncc_sel_obj = ncc_obj
                 ncc_sel_obj = ncc_obj
             else:
             else:
                 ncc_sel_obj = sel_obj
                 ncc_sel_obj = sel_obj
@@ -2727,7 +2724,7 @@ class NonCopperClear(AppTool, Gerber):
             return 'fail'
             return 'fail'
 
 
         bounding_box = None
         bounding_box = None
-        if ncc_select == 0: # itself
+        if ncc_select == 0:     # itself
             geo_n = ncc_sel_obj.solid_geometry
             geo_n = ncc_sel_obj.solid_geometry
 
 
             try:
             try:
@@ -2998,6 +2995,7 @@ class NonCopperClear(AppTool, Gerber):
             log.debug("NCC Tool. Finished calculation of 'empty' area.")
             log.debug("NCC Tool. Finished calculation of 'empty' area.")
             self.app.inform.emit(_("NCC Tool. Finished calculation of 'empty' area."))
             self.app.inform.emit(_("NCC Tool. Finished calculation of 'empty' area."))
 
 
+            tool = 1
             # COPPER CLEARING #
             # COPPER CLEARING #
             for tool in sorted_tools:
             for tool in sorted_tools:
                 log.debug("Starting geometry processing for tool: %s" % str(tool))
                 log.debug("Starting geometry processing for tool: %s" % str(tool))
@@ -3450,7 +3448,7 @@ class NonCopperClear(AppTool, Gerber):
 
 
                                 if isinstance(p, Polygon):
                                 if isinstance(p, Polygon):
                                     try:
                                     try:
-                                        if ncc_method == 0: # standard
+                                        if ncc_method == 0:     # standard
                                             cp = self.clear_polygon(p, tool_used,
                                             cp = self.clear_polygon(p, tool_used,
                                                                     self.circle_steps,
                                                                     self.circle_steps,
                                                                     overlap=overlap, contour=contour, connect=connect,
                                                                     overlap=overlap, contour=contour, connect=connect,
@@ -3479,7 +3477,7 @@ class NonCopperClear(AppTool, Gerber):
                                             QtWidgets.QApplication.processEvents()
                                             QtWidgets.QApplication.processEvents()
 
 
                                             try:
                                             try:
-                                                if ncc_method == 0: # 'standard'
+                                                if ncc_method == 0:     # 'standard'
                                                     cp = self.clear_polygon(poly_p, tool_used,
                                                     cp = self.clear_polygon(poly_p, tool_used,
                                                                             self.circle_steps,
                                                                             self.circle_steps,
                                                                             overlap=overlap, contour=contour,
                                                                             overlap=overlap, contour=contour,
@@ -3636,6 +3634,10 @@ class NonCopperClear(AppTool, Gerber):
             geo_len = 1
             geo_len = 1
         else:
         else:
             geo_len = len(target)
             geo_len = len(target)
+
+        if isinstance(target, list):
+            target = MultiPolygon(target)
+
         pol_nr = 0
         pol_nr = 0
         old_disp_number = 0
         old_disp_number = 0
 
 

+ 81 - 78
app_Main.py

@@ -277,10 +277,13 @@ class App(QtCore.QObject):
 
 
         super().__init__()
         super().__init__()
 
 
-        App.log.info("FlatCAM Starting...")
+        log.info("FlatCAM Starting...")
 
 
         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 ######################
         # ############################################################################################################
         # ############################################################################################################
@@ -302,9 +305,9 @@ class App(QtCore.QObject):
         # Folder for user settings.
         # Folder for user settings.
         if sys.platform == 'win32':
         if sys.platform == 'win32':
             if platform.architecture()[0] == '32bit':
             if platform.architecture()[0] == '32bit':
-                App.log.debug("Win32!")
+                self.log.debug("Win32!")
             else:
             else:
-                App.log.debug("Win64!")
+                self.log.debug("Win64!")
 
 
             # #######################################################################################################
             # #######################################################################################################
             # ####### CONFIG FILE WITH PARAMETERS REGARDING PORTABILITY #############################################
             # ####### CONFIG FILE WITH PARAMETERS REGARDING PORTABILITY #############################################
@@ -333,10 +336,10 @@ class App(QtCore.QObject):
                                 else:
                                 else:
                                     self.cmd_line_headless = None
                                     self.cmd_line_headless = None
                     except Exception as e:
                     except Exception as e:
-                        log.debug('App.__init__() -->%s' % str(e))
+                        self.log.debug('App.__init__() -->%s' % str(e))
                         return
                         return
             except FileNotFoundError as e:
             except FileNotFoundError as e:
-                log.debug(str(e))
+                self.log.debug(str(e))
                 pass
                 pass
 
 
             if portable is False:
             if portable is False:
@@ -355,21 +358,21 @@ class App(QtCore.QObject):
 
 
         if not os.path.exists(self.data_path):
         if not os.path.exists(self.data_path):
             os.makedirs(self.data_path)
             os.makedirs(self.data_path)
-            App.log.debug('Created data folder: ' + self.data_path)
+            self.log.debug('Created data folder: ' + self.data_path)
             os.makedirs(os.path.join(self.data_path, 'preprocessors'))
             os.makedirs(os.path.join(self.data_path, 'preprocessors'))
-            App.log.debug('Created data preprocessors folder: ' + os.path.join(self.data_path, 'preprocessors'))
+            self.log.debug('Created data preprocessors folder: ' + os.path.join(self.data_path, 'preprocessors'))
 
 
         self.preprocessorpaths = os.path.join(self.data_path, 'preprocessors')
         self.preprocessorpaths = os.path.join(self.data_path, 'preprocessors')
         if not os.path.exists(self.preprocessorpaths):
         if not os.path.exists(self.preprocessorpaths):
             os.makedirs(self.preprocessorpaths)
             os.makedirs(self.preprocessorpaths)
-            App.log.debug('Created preprocessors folder: ' + self.preprocessorpaths)
+            self.log.debug('Created preprocessors folder: ' + self.preprocessorpaths)
 
 
         # create tools_db.FlatDB file if there is none
         # create tools_db.FlatDB file if there is none
         try:
         try:
             f = open(self.data_path + '/tools_db.FlatDB')
             f = open(self.data_path + '/tools_db.FlatDB')
             f.close()
             f.close()
         except IOError:
         except IOError:
-            App.log.debug('Creating empty tools_db.FlatDB')
+            self.log.debug('Creating empty tools_db.FlatDB')
             f = open(self.data_path + '/tools_db.FlatDB', 'w')
             f = open(self.data_path + '/tools_db.FlatDB', 'w')
             json.dump({}, f)
             json.dump({}, f)
             f.close()
             f.close()
@@ -379,7 +382,7 @@ class App(QtCore.QObject):
             f = open(self.data_path + '/current_defaults.FlatConfig')
             f = open(self.data_path + '/current_defaults.FlatConfig')
             f.close()
             f.close()
         except IOError:
         except IOError:
-            App.log.debug('Creating empty current_defaults.FlatConfig')
+            self.log.debug('Creating empty current_defaults.FlatConfig')
             f = open(self.data_path + '/current_defaults.FlatConfig', 'w')
             f = open(self.data_path + '/current_defaults.FlatConfig', 'w')
             json.dump({}, f)
             json.dump({}, f)
             f.close()
             f.close()
@@ -392,7 +395,7 @@ class App(QtCore.QObject):
             f = open(self.data_path + '/recent.json')
             f = open(self.data_path + '/recent.json')
             f.close()
             f.close()
         except IOError:
         except IOError:
-            App.log.debug('Creating empty recent.json')
+            self.log.debug('Creating empty recent.json')
             f = open(self.data_path + '/recent.json', 'w')
             f = open(self.data_path + '/recent.json', 'w')
             json.dump([], f)
             json.dump([], f)
             f.close()
             f.close()
@@ -402,7 +405,7 @@ class App(QtCore.QObject):
             fp = open(self.data_path + '/recent_projects.json')
             fp = open(self.data_path + '/recent_projects.json')
             fp.close()
             fp.close()
         except IOError:
         except IOError:
-            App.log.debug('Creating empty recent_projects.json')
+            self.log.debug('Creating empty recent_projects.json')
             fp = open(self.data_path + '/recent_projects.json', 'w')
             fp = open(self.data_path + '/recent_projects.json', 'w')
             json.dump([], fp)
             json.dump([], fp)
             fp.close()
             fp.close()
@@ -411,8 +414,8 @@ class App(QtCore.QObject):
         # This will fail under cx_freeze ...
         # This will fail under cx_freeze ...
         self.app_home = os.path.dirname(os.path.realpath(__file__))
         self.app_home = os.path.dirname(os.path.realpath(__file__))
 
 
-        log.debug("Application path is " + self.app_home)
-        log.debug("Started in " + os.getcwd())
+        self.log.debug("Application path is " + self.app_home)
+        self.log.debug("Started in " + os.getcwd())
 
 
         # cx_freeze workaround
         # cx_freeze workaround
         if os.path.isfile(self.app_home):
         if os.path.isfile(self.app_home):
@@ -649,11 +652,11 @@ class App(QtCore.QObject):
 
 
         if ret_val == "no language":
         if ret_val == "no language":
             self.inform.emit('[ERROR] %s' % _("Could not find the Language files. The App strings are missing."))
             self.inform.emit('[ERROR] %s' % _("Could not find the Language files. The App strings are missing."))
-            log.debug("Could not find the Language files. The App strings are missing.")
+            self.log.debug("Could not find the Language files. The App strings are missing.")
         else:
         else:
             # make the current language the current selection on the language combobox
             # make the current language the current selection on the language combobox
             self.ui.general_defaults_form.general_app_group.language_cb.setCurrentText(ret_val)
             self.ui.general_defaults_form.general_app_group.language_cb.setCurrentText(ret_val)
-            log.debug("App.__init__() --> Applied %s language." % str(ret_val).capitalize())
+            self.log.debug("App.__init__() --> Applied %s language." % str(ret_val).capitalize())
 
 
         # ###########################################################################################################
         # ###########################################################################################################
         # ###################################### CREATE UNIQUE SERIAL NUMBER ########################################
         # ###################################### CREATE UNIQUE SERIAL NUMBER ########################################
@@ -1060,7 +1063,7 @@ class App(QtCore.QObject):
         try:
         try:
             self.install_tools()
             self.install_tools()
         except AttributeError as e:
         except AttributeError as e:
-            log.debug("App.__init__() install_tools() --> %s" % str(e))
+            self.log.debug("App.__init__() install_tools() --> %s" % str(e))
 
 
         # ###########################################################################################################
         # ###########################################################################################################
         # ######################################### BookMarks Manager ###############################################
         # ######################################### BookMarks Manager ###############################################
@@ -1253,22 +1256,22 @@ class App(QtCore.QObject):
         try:
         try:
             self.geo_editor = AppGeoEditor(self)
             self.geo_editor = AppGeoEditor(self)
         except Exception as es:
         except Exception as es:
-            log.debug("app_Main.__init__() --> Geo Editor Error: %s" % str(es))
+            self.log.debug("app_Main.__init__() --> Geo Editor Error: %s" % str(es))
 
 
         try:
         try:
             self.exc_editor = AppExcEditor(self)
             self.exc_editor = AppExcEditor(self)
         except Exception as es:
         except Exception as es:
-            log.debug("app_Main.__init__() --> Excellon Editor Error: %s" % str(es))
+            self.log.debug("app_Main.__init__() --> Excellon Editor Error: %s" % str(es))
 
 
         try:
         try:
             self.grb_editor = AppGerberEditor(self)
             self.grb_editor = AppGerberEditor(self)
         except Exception as es:
         except Exception as es:
-            log.debug("app_Main.__init__() --> Gerber Editor Error: %s" % str(es))
+            self.log.debug("app_Main.__init__() --> Gerber Editor Error: %s" % str(es))
 
 
         try:
         try:
             self.gcode_editor = AppGCodeEditor(self)
             self.gcode_editor = AppGCodeEditor(self)
         except Exception as es:
         except Exception as es:
-            log.debug("app_Main.__init__() --> GCode Editor Error: %s" % str(es))
+            self.log.debug("app_Main.__init__() --> GCode Editor Error: %s" % str(es))
 
 
         self.log.debug("Finished adding FlatCAM Editor's.")
         self.log.debug("Finished adding FlatCAM Editor's.")
 
 
@@ -1628,7 +1631,7 @@ class App(QtCore.QObject):
         # ###########################################################################################################
         # ###########################################################################################################
         # ##################################### Finished the CONSTRUCTOR ############################################
         # ##################################### Finished the CONSTRUCTOR ############################################
         # ###########################################################################################################
         # ###########################################################################################################
-        App.log.debug("END of constructor. Releasing control.")
+        self.log.debug("END of constructor. Releasing control.")
 
 
         # ###########################################################################################################
         # ###########################################################################################################
         # ########################################## SHOW GUI #######################################################
         # ########################################## SHOW GUI #######################################################
@@ -1756,7 +1759,7 @@ class App(QtCore.QObject):
         else:
         else:
             args_to_process = App.args
             args_to_process = App.args
 
 
-        log.debug("Application was started with arguments: %s. Processing ..." % str(args_to_process))
+        self.log.debug("Application was started with arguments: %s. Processing ..." % str(args_to_process))
         for argument in args_to_process:
         for argument in args_to_process:
             if '.FlatPrj'.lower() in argument.lower():
             if '.FlatPrj'.lower() in argument.lower():
                 try:
                 try:
@@ -1772,7 +1775,7 @@ class App(QtCore.QObject):
                         #                        'params': [project_name, run_from_arg]})
                         #                        'params': [project_name, run_from_arg]})
                         self.open_project(filename=project_name, run_from_arg=run_from_arg)
                         self.open_project(filename=project_name, run_from_arg=run_from_arg)
                 except Exception as e:
                 except Exception as e:
-                    log.debug("Could not open FlatCAM project file as App parameter due: %s" % str(e))
+                    self.log.debug("Could not open FlatCAM project file as App parameter due: %s" % str(e))
 
 
             elif '.FlatConfig'.lower() in argument.lower():
             elif '.FlatConfig'.lower() in argument.lower():
                 try:
                 try:
@@ -1787,7 +1790,7 @@ class App(QtCore.QObject):
                         #                        'params': [file_name, run_from_arg]})
                         #                        'params': [file_name, run_from_arg]})
                         self.open_config_file(file_name, run_from_arg=run_from_arg)
                         self.open_config_file(file_name, run_from_arg=run_from_arg)
                 except Exception as e:
                 except Exception as e:
-                    log.debug("Could not open FlatCAM Config file as App parameter due: %s" % str(e))
+                    self.log.debug("Could not open FlatCAM Config file as App parameter due: %s" % str(e))
 
 
             elif '.FlatScript'.lower() in argument.lower() or '.TCL'.lower() in argument.lower():
             elif '.FlatScript'.lower() in argument.lower() or '.TCL'.lower() in argument.lower():
                 try:
                 try:
@@ -1802,14 +1805,14 @@ class App(QtCore.QObject):
                             self.ui.plot_tab_area.setCurrentWidget(self.ui.plot_tab)
                             self.ui.plot_tab_area.setCurrentWidget(self.ui.plot_tab)
                         self.on_filerunscript(name=file_name)
                         self.on_filerunscript(name=file_name)
                 except Exception as e:
                 except Exception as e:
-                    log.debug("Could not open FlatCAM Script file as App parameter due: %s" % str(e))
+                    self.log.debug("Could not open FlatCAM Script file as App parameter due: %s" % str(e))
 
 
             elif 'quit'.lower() in argument.lower() or 'exit'.lower() in argument.lower():
             elif 'quit'.lower() in argument.lower() or 'exit'.lower() in argument.lower():
-                log.debug("App.on_startup_args() --> Quit event.")
+                self.log.debug("App.on_startup_args() --> Quit event.")
                 sys.exit()
                 sys.exit()
 
 
             elif 'save'.lower() in argument.lower():
             elif 'save'.lower() in argument.lower():
-                log.debug("App.on_startup_args() --> Save event. App Defaults saved.")
+                self.log.debug("App.on_startup_args() --> Save event. App Defaults saved.")
                 self.preferencesUiManager.save_defaults()
                 self.preferencesUiManager.save_defaults()
             else:
             else:
                 exc_list = self.ui.util_defaults_form.fa_excellon_group.exc_list_text.get_value().split(',')
                 exc_list = self.ui.util_defaults_form.fa_excellon_group.exc_list_text.get_value().split(',')
@@ -2052,7 +2055,7 @@ class App(QtCore.QObject):
         :return: None
         :return: None
         """
         """
 
 
-        log.debug("init_tools()")
+        self.log.debug("init_tools()")
 
 
         # delete the data currently in the Tools Tab and the Tab itself
         # delete the data currently in the Tools Tab and the Tab itself
         widget = QtWidgets.QTabWidget.widget(self.ui.notebook, 2)
         widget = QtWidgets.QTabWidget.widget(self.ui.notebook, 2)
@@ -2166,7 +2169,7 @@ class App(QtCore.QObject):
         try:
         try:
             self.connect_tools_signals_to_toolbar(ui=ui)
             self.connect_tools_signals_to_toolbar(ui=ui)
         except Exception as err:
         except Exception as err:
-            log.debug("App.connect_toolbar_signals() tools signals -> %s" % str(err))
+            self.log.debug("App.connect_toolbar_signals() tools signals -> %s" % str(err))
 
 
     def object2editor(self):
     def object2editor(self):
         """
         """
@@ -2217,10 +2220,10 @@ class App(QtCore.QObject):
                     if edited_object.tools[tool]['tooldia'] == selected_tooldia:
                     if edited_object.tools[tool]['tooldia'] == selected_tooldia:
                         multi_tool = tool
                         multi_tool = tool
                         break
                         break
-                log.debug("Editing MultiGeo Geometry with tool diameter: %s" % str(multi_tool))
+                self.log.debug("Editing MultiGeo Geometry with tool diameter: %s" % str(multi_tool))
                 self.geo_editor.edit_fcgeometry(edited_object, multigeo_tool=multi_tool)
                 self.geo_editor.edit_fcgeometry(edited_object, multigeo_tool=multi_tool)
             else:
             else:
-                log.debug("Editing SingleGeo Geometry with tool diameter.")
+                self.log.debug("Editing SingleGeo Geometry with tool diameter.")
                 self.geo_editor.edit_fcgeometry(edited_object)
                 self.geo_editor.edit_fcgeometry(edited_object)
 
 
             # set call source to the Editor we go into
             # set call source to the Editor we go into
@@ -2343,7 +2346,7 @@ class App(QtCore.QObject):
                             edited_obj.options['ymax'] = ymax
                             edited_obj.options['ymax'] = ymax
                         except AttributeError as e:
                         except AttributeError as e:
                             self.inform.emit('[WARNING] %s' % _("Object empty after edit."))
                             self.inform.emit('[WARNING] %s' % _("Object empty after edit."))
-                            log.debug("App.editor2object() --> Geometry --> %s" % str(e))
+                            self.log.debug("App.editor2object() --> Geometry --> %s" % str(e))
 
 
                         edited_obj.build_ui()
                         edited_obj.build_ui()
                         edited_obj.plot()
                         edited_obj.plot()
@@ -2577,7 +2580,7 @@ class App(QtCore.QObject):
         :return: None
         :return: None
         """
         """
         self.defaults.report_usage("save_to_file")
         self.defaults.report_usage("save_to_file")
-        App.log.debug("save_to_file()")
+        self.log.debug("save_to_file()")
 
 
         self.date = str(datetime.today()).rpartition('.')[0]
         self.date = str(datetime.today()).rpartition('.')[0]
         self.date = ''.join(c for c in self.date if c not in ':-')
         self.date = ''.join(c for c in self.date if c not in ':-')
@@ -2612,7 +2615,7 @@ class App(QtCore.QObject):
                                    "Most likely another app is holding the file open and not accessible."))
                                    "Most likely another app is holding the file open and not accessible."))
                 return
                 return
             except IOError:
             except IOError:
-                App.log.debug('Creating a new file ...')
+                self.log.debug('Creating a new file ...')
                 f = open(filename, 'w')
                 f = open(filename, 'w')
                 f.close()
                 f.close()
             except Exception:
             except Exception:
@@ -3367,7 +3370,7 @@ class App(QtCore.QObject):
                 self.geo_editor.disconnect()
                 self.geo_editor.disconnect()
             except TypeError:
             except TypeError:
                 pass
                 pass
-            log.debug("App.quit_application() --> Geo Editor deactivated.")
+            self.log.debug("App.quit_application() --> Geo Editor deactivated.")
 
 
         if self.exc_editor.editor_active is True:
         if self.exc_editor.editor_active is True:
             self.exc_editor.deactivate()
             self.exc_editor.deactivate()
@@ -3375,7 +3378,7 @@ class App(QtCore.QObject):
                 self.grb_editor.disconnect()
                 self.grb_editor.disconnect()
             except TypeError:
             except TypeError:
                 pass
                 pass
-            log.debug("App.quit_application() --> Excellon Editor deactivated.")
+            self.log.debug("App.quit_application() --> Excellon Editor deactivated.")
 
 
         if self.grb_editor.editor_active is True:
         if self.grb_editor.editor_active is True:
             self.grb_editor.deactivate_grb_editor()
             self.grb_editor.deactivate_grb_editor()
@@ -3383,7 +3386,7 @@ class App(QtCore.QObject):
                 self.exc_editor.disconnect()
                 self.exc_editor.disconnect()
             except TypeError:
             except TypeError:
                 pass
                 pass
-            log.debug("App.quit_application() --> Gerber Editor deactivated.")
+            self.log.debug("App.quit_application() --> Gerber Editor deactivated.")
 
 
         # disconnect the mouse events
         # disconnect the mouse events
         if self.is_legacy:
         if self.is_legacy:
@@ -3402,7 +3405,7 @@ class App(QtCore.QObject):
             self.kp = self.plotcanvas.graph_event_disconnect('key_press', self.ui.keyPressEvent)
             self.kp = self.plotcanvas.graph_event_disconnect('key_press', self.ui.keyPressEvent)
 
 
         self.preferencesUiManager.save_defaults(silent=True)
         self.preferencesUiManager.save_defaults(silent=True)
-        log.debug("App.quit_application() --> App Defaults saved.")
+        self.log.debug("App.quit_application() --> App Defaults saved.")
 
 
         if self.cmd_line_headless != 1:
         if self.cmd_line_headless != 1:
             # save app state to file
             # save app state to file
@@ -3439,7 +3442,7 @@ class App(QtCore.QObject):
             # This will write the setting to the platform specific storage.
             # This will write the setting to the platform specific storage.
             del stgs
             del stgs
 
 
-        log.debug("App.quit_application() --> App UI state saved.")
+        self.log.debug("App.quit_application() --> App UI state saved.")
 
 
         # try to quit the Socket opened by ArgsThread class
         # try to quit the Socket opened by ArgsThread class
         try:
         try:
@@ -3447,14 +3450,14 @@ class App(QtCore.QObject):
             # self.new_launch.listener.close()
             # self.new_launch.listener.close()
             self.new_launch.stop.emit()
             self.new_launch.stop.emit()
         except Exception as err:
         except Exception as err:
-            log.debug("App.quit_application() --> %s" % str(err))
+            self.log.debug("App.quit_application() --> %s" % str(err))
 
 
         # try to quit the QThread that run ArgsThread class
         # try to quit the QThread that run ArgsThread class
         try:
         try:
             # del self.new_launch
             # del self.new_launch
             self.listen_th.quit()
             self.listen_th.quit()
         except Exception as e:
         except Exception as e:
-            log.debug("App.quit_application() --> %s" % str(e))
+            self.log.debug("App.quit_application() --> %s" % str(e))
 
 
         # terminate workers
         # terminate workers
         # self.workers.__del__()
         # self.workers.__del__()
@@ -3510,7 +3513,7 @@ class App(QtCore.QObject):
                 try:
                 try:
                     data = f.readlines()
                     data = f.readlines()
                 except Exception as e:
                 except Exception as e:
-                    log.debug('App.__init__() -->%s' % str(e))
+                    self.log.debug('App.__init__() -->%s' % str(e))
                     return
                     return
         except FileNotFoundError:
         except FileNotFoundError:
             pass
             pass
@@ -3530,7 +3533,7 @@ class App(QtCore.QObject):
                 f = open(current_data_path + '/current_defaults.FlatConfig')
                 f = open(current_data_path + '/current_defaults.FlatConfig')
                 f.close()
                 f.close()
             except IOError:
             except IOError:
-                App.log.debug('Creating empty current_defaults.FlatConfig')
+                self.log.debug('Creating empty current_defaults.FlatConfig')
                 f = open(current_data_path + '/current_defaults.FlatConfig', 'w')
                 f = open(current_data_path + '/current_defaults.FlatConfig', 'w')
                 json.dump({}, f)
                 json.dump({}, f)
                 f.close()
                 f.close()
@@ -3540,7 +3543,7 @@ class App(QtCore.QObject):
                 f = open(current_data_path + '/factory_defaults.FlatConfig')
                 f = open(current_data_path + '/factory_defaults.FlatConfig')
                 f.close()
                 f.close()
             except IOError:
             except IOError:
-                App.log.debug('Creating empty factory_defaults.FlatConfig')
+                self.log.debug('Creating empty factory_defaults.FlatConfig')
                 f = open(current_data_path + '/factory_defaults.FlatConfig', 'w')
                 f = open(current_data_path + '/factory_defaults.FlatConfig', 'w')
                 json.dump({}, f)
                 json.dump({}, f)
                 f.close()
                 f.close()
@@ -3549,7 +3552,7 @@ class App(QtCore.QObject):
                 f = open(current_data_path + '/recent.json')
                 f = open(current_data_path + '/recent.json')
                 f.close()
                 f.close()
             except IOError:
             except IOError:
-                App.log.debug('Creating empty recent.json')
+                self.log.debug('Creating empty recent.json')
                 f = open(current_data_path + '/recent.json', 'w')
                 f = open(current_data_path + '/recent.json', 'w')
                 json.dump([], f)
                 json.dump([], f)
                 f.close()
                 f.close()
@@ -3558,7 +3561,7 @@ class App(QtCore.QObject):
                 fp = open(current_data_path + '/recent_projects.json')
                 fp = open(current_data_path + '/recent_projects.json')
                 fp.close()
                 fp.close()
             except IOError:
             except IOError:
-                App.log.debug('Creating empty recent_projects.json')
+                self.log.debug('Creating empty recent_projects.json')
                 fp = open(current_data_path + '/recent_projects.json', 'w')
                 fp = open(current_data_path + '/recent_projects.json', 'w')
                 json.dump([], fp)
                 json.dump([], fp)
                 fp.close()
                 fp.close()
@@ -3582,7 +3585,7 @@ class App(QtCore.QObject):
 
 
         :return: None
         :return: None
         """
         """
-        log.debug("Manufacturing files extensions are registered with FlatCAM.")
+        self.log.debug("Manufacturing files extensions are registered with FlatCAM.")
 
 
         new_reg_path = 'Software\\Classes\\'
         new_reg_path = 'Software\\Classes\\'
         # find if the current user is admin
         # find if the current user is admin
@@ -4093,7 +4096,7 @@ class App(QtCore.QObject):
                     try:
                     try:
                         tools_diameters = eval(self.defaults[dim])
                         tools_diameters = eval(self.defaults[dim])
                     except Exception as e:
                     except Exception as e:
-                        log.debug("App.on_toggle_units().scale_defaults() lists --> %s" % str(e))
+                        self.log.debug("App.on_toggle_units().scale_defaults() lists --> %s" % str(e))
                         continue
                         continue
                 elif isinstance(self.defaults[dim], (float, int)):
                 elif isinstance(self.defaults[dim], (float, int)):
                     tools_diameters = [self.defaults[dim]]
                     tools_diameters = [self.defaults[dim]]
@@ -4118,7 +4121,7 @@ class App(QtCore.QObject):
                 try:
                 try:
                     val = float(self.defaults[dim]) * sfactor
                     val = float(self.defaults[dim]) * sfactor
                 except Exception as e:
                 except Exception as e:
-                    log.debug('App.on_toggle_units().scale_defaults() grids --> %s' % str(e))
+                    self.log.debug('App.on_toggle_units().scale_defaults() grids --> %s' % str(e))
                     continue
                     continue
 
 
                 self.defaults[dim] = self.dec_format(val, self.decimals)
                 self.defaults[dim] = self.dec_format(val, self.decimals)
@@ -4128,7 +4131,7 @@ class App(QtCore.QObject):
                     try:
                     try:
                         val = float(self.defaults[dim]) * sfactor
                         val = float(self.defaults[dim]) * sfactor
                     except Exception as e:
                     except Exception as e:
-                        log.debug(
+                        self.log.debug(
                             'App.on_toggle_units().scale_defaults() standard --> Value: %s %s' % (str(dim), str(e))
                             'App.on_toggle_units().scale_defaults() standard --> Value: %s %s' % (str(dim), str(e))
                         )
                         )
                         continue
                         continue
@@ -4561,7 +4564,7 @@ class App(QtCore.QObject):
                                 del obj_active.annotation
                                 del obj_active.annotation
                                 obj_active.probing_shapes.clear(update=True)
                                 obj_active.probing_shapes.clear(update=True)
                             except AttributeError as e:
                             except AttributeError as e:
-                                log.debug(
+                                self.log.debug(
                                     "App.on_delete() --> delete annotations on a FlatCAMCNCJob object. %s" % str(e)
                                     "App.on_delete() --> delete annotations on a FlatCAMCNCJob object. %s" % str(e)
                                 )
                                 )
 
 
@@ -4597,7 +4600,7 @@ class App(QtCore.QObject):
                     # self.plotcanvas.figure.delaxes(self.collection.get_active().axes)
                     # self.plotcanvas.figure.delaxes(self.collection.get_active().axes)
                     self.plotcanvas.figure.delaxes(self.collection.get_active().shapes.axes)
                     self.plotcanvas.figure.delaxes(self.collection.get_active().shapes.axes)
                 except Exception as e:
                 except Exception as e:
-                    log.debug("App.delete_first_selected() --> %s" % str(e))
+                    self.log.debug("App.delete_first_selected() --> %s" % str(e))
 
 
             self.plotcanvas.auto_adjust_axes()
             self.plotcanvas.auto_adjust_axes()
 
 
@@ -5655,7 +5658,7 @@ class App(QtCore.QObject):
             with open(filename) as f:
             with open(filename) as f:
                 __ = f.read()
                 __ = f.read()
         except Exception as eros:
         except Exception as eros:
-            log.debug("The tools DB file is not loaded: %s" % str(eros))
+            self.log.debug("The tools DB file is not loaded: %s" % str(eros))
             log.error("Could not access tools DB file. The file may be locked,\n"
             log.error("Could not access tools DB file. The file may be locked,\n"
                       "not existing or doesn't have the read permissions.\n"
                       "not existing or doesn't have the read permissions.\n"
                       "Check to see if exists, it should be here: %s\n"
                       "Check to see if exists, it should be here: %s\n"
@@ -5704,7 +5707,7 @@ class App(QtCore.QObject):
             self.ui.plot_tab_area.addTab(self.tools_db_tab, _("Tools Database"))
             self.ui.plot_tab_area.addTab(self.tools_db_tab, _("Tools Database"))
             self.tools_db_tab.setObjectName("database_tab")
             self.tools_db_tab.setObjectName("database_tab")
         except Exception as e:
         except Exception as e:
-            log.debug("App.on_tools_database() --> %s" % str(e))
+            self.log.debug("App.on_tools_database() --> %s" % str(e))
             return
             return
 
 
         # delete the absolute and relative position and messages in the infobar
         # delete the absolute and relative position and messages in the infobar
@@ -6056,7 +6059,7 @@ class App(QtCore.QObject):
             else:
             else:
                 self.on_zoom_fit()
                 self.on_zoom_fit()
         except AttributeError as e:
         except AttributeError as e:
-            log.debug("on_toolbar_replot() -> %s" % str(e))
+            self.log.debug("on_toolbar_replot() -> %s" % str(e))
             pass
             pass
 
 
         self.plot_all()
         self.plot_all()
@@ -6188,7 +6191,7 @@ class App(QtCore.QObject):
         try:
         try:
             name = obj.options["name"]
             name = obj.options["name"]
         except AttributeError:
         except AttributeError:
-            log.debug("on_copy_name() --> No object selected to copy it's name")
+            self.log.debug("on_copy_name() --> No object selected to copy it's name")
             self.inform.emit('[WARNING_NOTCL] %s' %
             self.inform.emit('[WARNING_NOTCL] %s' %
                              _(" No object selected to copy it's name"))
                              _(" No object selected to copy it's name"))
             return
             return
@@ -6236,7 +6239,7 @@ class App(QtCore.QObject):
 
 
             self.on_mouse_move_over_plot(event, origin_click=True)
             self.on_mouse_move_over_plot(event, origin_click=True)
         except Exception as e:
         except Exception as e:
-            App.log.debug("App.on_mouse_click_over_plot() --> Outside plot? --> %s" % str(e))
+            self.log.debug("App.on_mouse_click_over_plot() --> Outside plot? --> %s" % str(e))
 
 
     def on_mouse_double_click_over_plot(self, event):
     def on_mouse_double_click_over_plot(self, event):
         if event.button == 1:
         if event.button == 1:
@@ -6371,7 +6374,7 @@ class App(QtCore.QObject):
                             pass
                             pass
 
 
             except Exception as e:
             except Exception as e:
-                log.debug("App.on_mouse_move_over_plot() - rel_point1 is not None -> %s" % str(e))
+                self.log.debug("App.on_mouse_move_over_plot() - rel_point1 is not None -> %s" % str(e))
                 self.ui.position_label.setText("")
                 self.ui.position_label.setText("")
                 self.ui.rel_position_label.setText("")
                 self.ui.rel_position_label.setText("")
                 self.mouse = None
                 self.mouse = None
@@ -6530,7 +6533,7 @@ class App(QtCore.QObject):
                 # the Exception here will happen if we try to select on screen and we have an newly (and empty)
                 # the Exception here will happen if we try to select on screen and we have an newly (and empty)
                 # just created Geometry or Excellon object that do not have the xmin, xmax, ymin, ymax options.
                 # just created Geometry or Excellon object that do not have the xmin, xmax, ymin, ymax options.
                 # In this case poly_obj creation (see above) will fail
                 # In this case poly_obj creation (see above) will fail
-                log.debug("App.selection_area_handler() --> %s" % str(e))
+                self.log.debug("App.selection_area_handler() --> %s" % str(e))
 
 
     def select_objects(self, key=None):
     def select_objects(self, key=None):
         """
         """
@@ -6956,7 +6959,7 @@ class App(QtCore.QObject):
         try:
         try:
             obj = self.collection.get_active()
             obj = self.collection.get_active()
         except Exception as e:
         except Exception as e:
-            log.debug("App.on_view_source() --> %s" % str(e))
+            self.log.debug("App.on_view_source() --> %s" % str(e))
             self.inform.emit('[WARNING_NOTCL] %s' % _("Select an Gerber or Excellon file to view it's source file."))
             self.inform.emit('[WARNING_NOTCL] %s' % _("Select an Gerber or Excellon file to view it's source file."))
             return 'fail'
             return 'fail'
 
 
@@ -7028,7 +7031,7 @@ class App(QtCore.QObject):
         try:
         try:
             self.source_editor_tab.load_text(file.getvalue(), clear_text=True, move_to_start=True)
             self.source_editor_tab.load_text(file.getvalue(), clear_text=True, move_to_start=True)
         except Exception as e:
         except Exception as e:
-            log.debug('App.on_view_source() -->%s' % str(e))
+            self.log.debug('App.on_view_source() -->%s' % str(e))
             self.inform.emit('[ERROR] %s: %s' % (_('Failed to load the source code for the selected object'), str(e)))
             self.inform.emit('[ERROR] %s: %s' % (_('Failed to load the source code for the selected object'), str(e)))
             return
             return
 
 
@@ -7435,7 +7438,7 @@ class App(QtCore.QObject):
             full_url = App.version_url + "?s=" + str(self.defaults['global_serial']) + "&v=" + str(self.version)
             full_url = App.version_url + "?s=" + str(self.defaults['global_serial']) + "&v=" + str(self.version)
             full_url += "&os=" + str(self.os) + "&" + urllib.parse.urlencode(no_ststs_dict["global_ststs"])
             full_url += "&os=" + str(self.os) + "&" + urllib.parse.urlencode(no_ststs_dict["global_ststs"])
 
 
-        App.log.debug("Checking for updates @ %s" % full_url)
+        self.log.debug("Checking for updates @ %s" % full_url)
         # ## Get the data
         # ## Get the data
         try:
         try:
             f = urllib.request.urlopen(full_url)
             f = urllib.request.urlopen(full_url)
@@ -7450,7 +7453,7 @@ class App(QtCore.QObject):
         except Exception as e:
         except Exception as e:
             App.log.error("Could not parse information about latest version.")
             App.log.error("Could not parse information about latest version.")
             self.inform.emit('[ERROR_NOTCL] %s' % _("Could not parse information about latest version."))
             self.inform.emit('[ERROR_NOTCL] %s' % _("Could not parse information about latest version."))
-            App.log.debug("json.load(): %s" % str(e))
+            self.log.debug("json.load(): %s" % str(e))
             f.close()
             f.close()
             return
             return
 
 
@@ -7458,11 +7461,11 @@ class App(QtCore.QObject):
 
 
         # ## Latest version?
         # ## Latest version?
         if self.version >= data["version"]:
         if self.version >= data["version"]:
-            App.log.debug("FlatCAM is up to date!")
+            self.log.debug("FlatCAM is up to date!")
             self.inform.emit('[success] %s' % _("FlatCAM is up to date!"))
             self.inform.emit('[success] %s' % _("FlatCAM is up to date!"))
             return
             return
 
 
-        App.log.debug("Newer version available.")
+        self.log.debug("Newer version available.")
         self.message.emit(
         self.message.emit(
             _("Newer Version Available"),
             _("Newer Version Available"),
             '%s<br><br>><b>%s</b><br>%s' % (
             '%s<br><br>><b>%s</b><br>%s' % (
@@ -7495,8 +7498,8 @@ class App(QtCore.QObject):
                 self.plotcanvas = PlotCanvas(plot_container, self)
                 self.plotcanvas = PlotCanvas(plot_container, self)
             except Exception as er:
             except Exception as er:
                 msg_txt = traceback.format_exc()
                 msg_txt = traceback.format_exc()
-                log.debug("App.on_plotcanvas_setup() failed -> %s" % str(er))
-                log.debug("OpenGL canvas initialization failed with the following error.\n" + msg_txt)
+                self.log.debug("App.on_plotcanvas_setup() failed -> %s" % str(er))
+                self.log.debug("OpenGL canvas initialization failed with the following error.\n" + msg_txt)
                 msg = '[ERROR_NOTCL] %s' % _("An internal error has occurred. See shell.\n")
                 msg = '[ERROR_NOTCL] %s' % _("An internal error has occurred. See shell.\n")
                 msg += _("OpenGL canvas initialization failed. HW or HW configuration not supported."
                 msg += _("OpenGL canvas initialization failed. HW or HW configuration not supported."
                          "Change the graphic engine to Legacy(2D) in Edit -> Preferences -> General tab.\n\n")
                          "Change the graphic engine to Legacy(2D) in Edit -> Preferences -> General tab.\n\n")
@@ -7596,13 +7599,13 @@ class App(QtCore.QObject):
         self.inform.emit('[success] %s' % _("All non selected plots enabled."))
         self.inform.emit('[success] %s' % _("All non selected plots enabled."))
 
 
     def on_enable_sel_plots(self):
     def on_enable_sel_plots(self):
-        log.debug("App.on_enable_sel_plot()")
+        self.log.debug("App.on_enable_sel_plot()")
         object_list = self.collection.get_selected()
         object_list = self.collection.get_selected()
         self.enable_plots(objects=object_list)
         self.enable_plots(objects=object_list)
         self.inform.emit('[success] %s' % _("Selected plots enabled..."))
         self.inform.emit('[success] %s' % _("Selected plots enabled..."))
 
 
     def on_disable_sel_plots(self):
     def on_disable_sel_plots(self):
-        log.debug("App.on_disable_sel_plot()")
+        self.log.debug("App.on_disable_sel_plot()")
 
 
         # self.inform.emit(_("Disabling plots ..."))
         # self.inform.emit(_("Disabling plots ..."))
         object_list = self.collection.get_selected()
         object_list = self.collection.get_selected()
@@ -7616,7 +7619,7 @@ class App(QtCore.QObject):
         :param objects: list of Objects to be enabled
         :param objects: list of Objects to be enabled
         :return:
         :return:
         """
         """
-        log.debug("Enabling plots ...")
+        self.log.debug("Enabling plots ...")
         # self.inform.emit(_("Working ..."))
         # self.inform.emit(_("Working ..."))
 
 
         for obj in objects:
         for obj in objects:
@@ -7659,7 +7662,7 @@ class App(QtCore.QObject):
         :return:
         :return:
         """
         """
 
 
-        log.debug("Disabling plots ...")
+        self.log.debug("Disabling plots ...")
         # self.inform.emit(_("Working ..."))
         # self.inform.emit(_("Working ..."))
 
 
         for obj in objects:
         for obj in objects:
@@ -7683,7 +7686,7 @@ class App(QtCore.QObject):
         try:
         try:
             self.delete_selection_shape()
             self.delete_selection_shape()
         except Exception as e:
         except Exception as e:
-            log.debug("App.disable_plots() --> %s" % str(e))
+            self.log.debug("App.disable_plots() --> %s" % str(e))
 
 
         self.collection.update_view()
         self.collection.update_view()
 
 
@@ -7710,7 +7713,7 @@ class App(QtCore.QObject):
         if not self.collection.get_selected():
         if not self.collection.get_selected():
             return
             return
 
 
-        log.debug("Toggling plots ...")
+        self.log.debug("Toggling plots ...")
         self.inform.emit(_("Working ..."))
         self.inform.emit(_("Working ..."))
         for obj in objects:
         for obj in objects:
             if obj.options['plot'] is False:
             if obj.options['plot'] is False:
@@ -7761,7 +7764,7 @@ class App(QtCore.QObject):
             elif sel_obj.kind == 'geometry':
             elif sel_obj.kind == 'geometry':
                 alpha_level = 'FF'
                 alpha_level = 'FF'
             else:
             else:
-                log.debug(
+                self.log.debug(
                     "App.on_set_color_action_triggered() --> Default alpfa for this object type not supported yet")
                     "App.on_set_color_action_triggered() --> Default alpfa for this object type not supported yet")
                 continue
                 continue
             sel_obj.alpha_level = alpha_level
             sel_obj.alpha_level = alpha_level
@@ -7806,7 +7809,7 @@ class App(QtCore.QObject):
                     new_color = self.defaults['geometry_plot_line']
                     new_color = self.defaults['geometry_plot_line']
                     new_line_color = self.defaults['geometry_plot_line']
                     new_line_color = self.defaults['geometry_plot_line']
                 else:
                 else:
-                    log.debug(
+                    self.log.debug(
                         "App.on_set_color_action_triggered() --> Default color for this object type not supported yet")
                         "App.on_set_color_action_triggered() --> Default color for this object type not supported yet")
                     continue
                     continue
 
 
@@ -7924,7 +7927,7 @@ class App(QtCore.QObject):
         Update the auto save time interval value.
         Update the auto save time interval value.
         :return:
         :return:
         """
         """
-        log.debug("App.save_project_auto_update() --> updated the interval timeout.")
+        self.log.debug("App.save_project_auto_update() --> updated the interval timeout.")
         try:
         try:
             if self.autosave_timer.isActive():
             if self.autosave_timer.isActive():
                 self.autosave_timer.stop()
                 self.autosave_timer.stop()
@@ -7976,7 +7979,7 @@ class App(QtCore.QObject):
             else:
             else:
                 self.shell.append_output(msg + end)
                 self.shell.append_output(msg + end)
         except AttributeError:
         except AttributeError:
-            log.debug("shell_message() is called before Shell Class is instantiated. The message is: %s", str(msg))
+            self.log.debug("shell_message() is called before Shell Class is instantiated. The message is: %s", str(msg))
 
 
     def dec_format(self, val, dec=None):
     def dec_format(self, val, dec=None):
         """
         """