Просмотр исходного кода

Fix some things that I broke and further cleanup

David Robertson 5 лет назад
Родитель
Сommit
a05c174ec8
41 измененных файлов с 314 добавлено и 308 удалено
  1. 99 215
      FlatCAMApp.py
  2. 1 1
      FlatCAMBookmark.py
  3. 4 4
      FlatCAMDB.py
  4. 18 5
      defaults.py
  5. 4 4
      flatcamEditors/FlatCAMGeoEditor.py
  6. 1 1
      flatcamEditors/FlatCAMGrbEditor.py
  7. 6 6
      flatcamEditors/FlatCAMTextEditor.py
  8. 137 28
      flatcamGUI/PreferencesUI.py
  9. 1 1
      flatcamObjects/FlatCAMCNCJob.py
  10. 3 3
      flatcamObjects/FlatCAMExcellon.py
  11. 1 1
      flatcamObjects/FlatCAMGeometry.py
  12. 3 3
      flatcamObjects/FlatCAMGerber.py
  13. 2 2
      flatcamObjects/FlatCAMObj.py
  14. 1 1
      flatcamTools/ToolAlignObjects.py
  15. 1 1
      flatcamTools/ToolCalculators.py
  16. 1 1
      flatcamTools/ToolCalibration.py
  17. 1 1
      flatcamTools/ToolCopperThieving.py
  18. 1 1
      flatcamTools/ToolCutOut.py
  19. 1 1
      flatcamTools/ToolDblSided.py
  20. 1 1
      flatcamTools/ToolDistance.py
  21. 1 1
      flatcamTools/ToolDistanceMin.py
  22. 1 1
      flatcamTools/ToolExtractDrills.py
  23. 1 1
      flatcamTools/ToolFiducials.py
  24. 3 3
      flatcamTools/ToolFilm.py
  25. 2 2
      flatcamTools/ToolImage.py
  26. 1 1
      flatcamTools/ToolInvertGerber.py
  27. 1 1
      flatcamTools/ToolMove.py
  28. 2 2
      flatcamTools/ToolNCC.py
  29. 1 1
      flatcamTools/ToolOptimal.py
  30. 2 2
      flatcamTools/ToolPDF.py
  31. 2 2
      flatcamTools/ToolPaint.py
  32. 1 1
      flatcamTools/ToolPanelize.py
  33. 1 1
      flatcamTools/ToolPcbWizard.py
  34. 1 1
      flatcamTools/ToolProperties.py
  35. 1 1
      flatcamTools/ToolPunchGerber.py
  36. 1 1
      flatcamTools/ToolQRCode.py
  37. 1 1
      flatcamTools/ToolRulesCheck.py
  38. 1 1
      flatcamTools/ToolShell.py
  39. 1 1
      flatcamTools/ToolSolderPaste.py
  40. 1 1
      flatcamTools/ToolSub.py
  41. 1 1
      flatcamTools/ToolTransform.py

+ 99 - 215
FlatCAMApp.py

@@ -543,7 +543,8 @@ class App(QtCore.QObject):
         # ##################################### UPDATE PREFERENCES GUI FORMS ########################################
         # ##################################### UPDATE PREFERENCES GUI FORMS ########################################
         # ###########################################################################################################
         # ###########################################################################################################
 
 
-        self.preferencesUiManager = PreferencesUIManager(defaults=self.defaults, data_path=self.data_path, ui=self.ui, inform=self.inform)
+        self.preferencesUiManager = PreferencesUIManager(defaults=self.defaults, data_path=self.data_path, ui=self.ui,
+                                                         inform=self.inform, app=self)
         self.preferencesUiManager.defaults_write_form()
         self.preferencesUiManager.defaults_write_form()
 
 
         # When the self.defaults dictionary changes will update the Preferences GUI forms
         # When the self.defaults dictionary changes will update the Preferences GUI forms
@@ -2137,7 +2138,7 @@ class App(QtCore.QObject):
 
 
         :return: None
         :return: None
         """
         """
-        self.report_usage("object2editor()")
+        self.defaults.report_usage("object2editor()")
 
 
         # disable the objects menu as it may interfere with the Editors
         # disable the objects menu as it may interfere with the Editors
         self.ui.menuobjects.setDisabled(True)
         self.ui.menuobjects.setDisabled(True)
@@ -2231,7 +2232,7 @@ class App(QtCore.QObject):
 
 
         :return: None
         :return: None
         """
         """
-        self.report_usage("editor2object()")
+        self.defaults.report_usage("editor2object()")
 
 
         # 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)
@@ -2409,19 +2410,6 @@ class App(QtCore.QObject):
             loc = os.path.dirname(__file__)
             loc = os.path.dirname(__file__)
         return loc
         return loc
 
 
-    def report_usage(self, resource):
-        """
-        Increments usage counter for the given resource
-        in self.defaults['global_stats'].
-
-        :param resource: Name of the resource.
-        :return: None
-        """
-
-        if resource in self.defaults['global_stats']:
-            self.defaults['global_stats'][resource] += 1
-        else:
-            self.defaults['global_stats'][resource] = 1
 
 
     def info(self, msg):
     def info(self, msg):
         """
         """
@@ -2530,7 +2518,7 @@ class App(QtCore.QObject):
         :return: None
         :return: None
         """
         """
 
 
-        self.report_usage("on_import_preferences")
+        self.defaults.report_usage("on_import_preferences")
         App.log.debug("App.on_import_preferences()")
         App.log.debug("App.on_import_preferences()")
 
 
         # Show file chooser
         # Show file chooser
@@ -2550,7 +2538,7 @@ class App(QtCore.QObject):
         # Load in the defaults from the chosen file
         # Load in the defaults from the chosen file
         self.defaults.load(filename=filename)
         self.defaults.load(filename=filename)
 
 
-        self.on_preferences_edited()
+        self.preferencesUiManager.on_preferences_edited()
         self.inform.emit('[success] %s: %s' % (_("Imported Defaults from"), filename))
         self.inform.emit('[success] %s: %s' % (_("Imported Defaults from"), filename))
 
 
     def on_export_preferences(self):
     def on_export_preferences(self):
@@ -2559,7 +2547,7 @@ class App(QtCore.QObject):
 
 
         :return: None
         :return: None
         """
         """
-        self.report_usage("on_export_preferences")
+        self.defaults.report_usage("on_export_preferences")
         App.log.debug("on_export_preferences()")
         App.log.debug("on_export_preferences()")
 
 
         defaults_file_content = None
         defaults_file_content = None
@@ -2604,7 +2592,7 @@ class App(QtCore.QObject):
 
 
         :return: None
         :return: None
         """
         """
-        self.report_usage("save_to_file")
+        self.defaults.report_usage("save_to_file")
         App.log.debug("save_to_file()")
         App.log.debug("save_to_file()")
 
 
         self.date = str(datetime.today()).rpartition('.')[0]
         self.date = str(datetime.today()).rpartition('.')[0]
@@ -2902,7 +2890,7 @@ class App(QtCore.QObject):
 
 
         :return: None
         :return: None
         """
         """
-        self.report_usage("new_excellon_object()")
+        self.defaults.report_usage("new_excellon_object()")
 
 
         self.new_object('excellon', 'new_exc', lambda x, y: None, plot=False)
         self.new_object('excellon', 'new_exc', lambda x, y: None, plot=False)
 
 
@@ -2912,7 +2900,7 @@ class App(QtCore.QObject):
 
 
         :return: None
         :return: None
         """
         """
-        self.report_usage("new_geometry_object()")
+        self.defaults.report_usage("new_geometry_object()")
 
 
         def initialize(obj, app):
         def initialize(obj, app):
             obj.multitool = False
             obj.multitool = False
@@ -2925,7 +2913,7 @@ class App(QtCore.QObject):
 
 
         :return: None
         :return: None
         """
         """
-        self.report_usage("new_gerber_object()")
+        self.defaults.report_usage("new_gerber_object()")
 
 
         def initialize(grb_obj, app):
         def initialize(grb_obj, app):
             grb_obj.multitool = False
             grb_obj.multitool = False
@@ -2952,7 +2940,7 @@ class App(QtCore.QObject):
         :param text: pass a source file to the newly created script to be loaded in it
         :param text: pass a source file to the newly created script to be loaded in it
         :return: None
         :return: None
         """
         """
-        self.report_usage("new_script_object()")
+        self.defaults.report_usage("new_script_object()")
 
 
         if text is not None:
         if text is not None:
             new_source_file = text
             new_source_file = text
@@ -2991,7 +2979,7 @@ class App(QtCore.QObject):
 
 
         :return: None
         :return: None
         """
         """
-        self.report_usage("new_document_object()")
+        self.defaults.report_usage("new_document_object()")
 
 
         def initialize(obj, app):
         def initialize(obj, app):
             obj.source_file = ""
             obj.source_file = ""
@@ -3117,7 +3105,7 @@ class App(QtCore.QObject):
 
 
         :return: None
         :return: None
         """
         """
-        self.report_usage("on_about")
+        self.defaults.report_usage("on_about")
 
 
         version = self.version
         version = self.version
         version_date = self.version_date
         version_date = self.version_date
@@ -3521,46 +3509,6 @@ class App(QtCore.QObject):
         """
         """
         self.preferencesUiManager.save_defaults()
         self.preferencesUiManager.save_defaults()
 
 
-    def save_toolbar_view(self):
-        """
-        Will save the toolbar view state to the defaults
-
-        :return:            None
-        """
-
-        # Save the toolbar view
-        tb_status = 0
-        if self.ui.toolbarfile.isVisible():
-            tb_status += 1
-
-        if self.ui.toolbargeo.isVisible():
-            tb_status += 2
-
-        if self.ui.toolbarview.isVisible():
-            tb_status += 4
-
-        if self.ui.toolbartools.isVisible():
-            tb_status += 8
-
-        if self.ui.exc_edit_toolbar.isVisible():
-            tb_status += 16
-
-        if self.ui.geo_edit_toolbar.isVisible():
-            tb_status += 32
-
-        if self.ui.grb_edit_toolbar.isVisible():
-            tb_status += 64
-
-        if self.ui.snap_toolbar.isVisible():
-            tb_status += 128
-
-        if self.ui.toolbarshell.isVisible():
-            tb_status += 256
-
-        self.defaults["global_toolbar_view"] = tb_status
-
-
-
     def final_save(self):
     def final_save(self):
         """
         """
         Callback for doing a preferences save to file whenever the application is about to quit.
         Callback for doing a preferences save to file whenever the application is about to quit.
@@ -4053,7 +4001,7 @@ class App(QtCore.QObject):
 
 
         :return: None
         :return: None
         """
         """
-        self.report_usage("on_edit_join()")
+        self.defaults.report_usage("on_edit_join()")
 
 
         obj_name_single = str(name) if name else "Combo_SingleGeo"
         obj_name_single = str(name) if name else "Combo_SingleGeo"
         obj_name_multi = str(name) if name else "Combo_MultiGeo"
         obj_name_multi = str(name) if name else "Combo_MultiGeo"
@@ -4112,7 +4060,7 @@ class App(QtCore.QObject):
 
 
         :return: None
         :return: None
         """
         """
-        self.report_usage("on_edit_join_exc()")
+        self.defaults.report_usage("on_edit_join_exc()")
 
 
         objs = self.collection.get_selected()
         objs = self.collection.get_selected()
 
 
@@ -4127,7 +4075,7 @@ class App(QtCore.QObject):
             return 'fail'
             return 'fail'
 
 
         def initialize(exc_obj, app):
         def initialize(exc_obj, app):
-            ExcellonObject.merge(self, exc_list=objs, exc_final=exc_obj)
+            ExcellonObject.merge(exc_list=objs, exc_final=exc_obj)
             app.inform.emit('[success] %s.' % _("Excellon merging finished"))
             app.inform.emit('[success] %s.' % _("Excellon merging finished"))
 
 
         self.new_object("excellon", 'Combo_Excellon', initialize)
         self.new_object("excellon", 'Combo_Excellon', initialize)
@@ -4140,7 +4088,7 @@ class App(QtCore.QObject):
 
 
         :return: None
         :return: None
         """
         """
-        self.report_usage("on_edit_join_grb()")
+        self.defaults.report_usage("on_edit_join_grb()")
 
 
         objs = self.collection.get_selected()
         objs = self.collection.get_selected()
 
 
@@ -4171,7 +4119,7 @@ class App(QtCore.QObject):
 
 
         :return: None
         :return: None
         """
         """
-        self.report_usage("on_convert_singlegeo_to_multigeo()")
+        self.defaults.report_usage("on_convert_singlegeo_to_multigeo()")
 
 
         obj = self.collection.get_active()
         obj = self.collection.get_active()
 
 
@@ -4205,7 +4153,7 @@ class App(QtCore.QObject):
 
 
         :return: None
         :return: None
         """
         """
-        self.report_usage("on_convert_multigeo_to_singlegeo()")
+        self.defaults.report_usage("on_convert_multigeo_to_singlegeo()")
 
 
         obj = self.collection.get_active()
         obj = self.collection.get_active()
 
 
@@ -4241,7 +4189,7 @@ class App(QtCore.QObject):
         :param field: the key of the self.defaults dictionary that was changed.
         :param field: the key of the self.defaults dictionary that was changed.
         :return: None
         :return: None
         """
         """
-        self.preferencesUiManager.defaults_write_form(field)
+        self.preferencesUiManager.defaults_write_form_field(field=field)
 
 
         if field == "units":
         if field == "units":
             self.set_screen_units(self.defaults['units'])
             self.set_screen_units(self.defaults['units'])
@@ -4281,7 +4229,7 @@ class App(QtCore.QObject):
         :return: None
         :return: None
         """
         """
 
 
-        self.report_usage("on_toggle_units")
+        self.defaults.report_usage("on_toggle_units")
 
 
         if self.toggle_units_ignore:
         if self.toggle_units_ignore:
             return
             return
@@ -4538,7 +4486,7 @@ class App(QtCore.QObject):
         self.ui.grid_gap_y_entry.set_value(val_y, decimals=self.decimals)
         self.ui.grid_gap_y_entry.set_value(val_y, decimals=self.decimals)
 
 
     def on_fullscreen(self, disable=False):
     def on_fullscreen(self, disable=False):
-        self.report_usage("on_fullscreen()")
+        self.defaults.report_usage("on_fullscreen()")
 
 
         flags = self.ui.windowFlags()
         flags = self.ui.windowFlags()
         if self.toggle_fscreen is False and disable is False:
         if self.toggle_fscreen is False and disable is False:
@@ -4579,7 +4527,7 @@ class App(QtCore.QObject):
             self.toggle_fscreen = False
             self.toggle_fscreen = False
 
 
     def on_toggle_plotarea(self):
     def on_toggle_plotarea(self):
-        self.report_usage("on_toggle_plotarea()")
+        self.defaults.report_usage("on_toggle_plotarea()")
 
 
         try:
         try:
             name = self.ui.plot_tab_area.widget(0).objectName()
             name = self.ui.plot_tab_area.widget(0).objectName()
@@ -4605,7 +4553,7 @@ class App(QtCore.QObject):
             self.ui.menu_toggle_nb.setChecked(False)
             self.ui.menu_toggle_nb.setChecked(False)
 
 
     def on_toggle_axis(self):
     def on_toggle_axis(self):
-        self.report_usage("on_toggle_axis()")
+        self.defaults.report_usage("on_toggle_axis()")
 
 
         if self.toggle_axis is False:
         if self.toggle_axis is False:
             if self.is_legacy is False:
             if self.is_legacy is False:
@@ -4635,13 +4583,13 @@ class App(QtCore.QObject):
             self.toggle_axis = False
             self.toggle_axis = False
 
 
     def on_toggle_grid(self):
     def on_toggle_grid(self):
-        self.report_usage("on_toggle_grid()")
+        self.defaults.report_usage("on_toggle_grid()")
 
 
         self.ui.grid_snap_btn.trigger()
         self.ui.grid_snap_btn.trigger()
         self.on_grid_snap_triggered(state=True)
         self.on_grid_snap_triggered(state=True)
 
 
     def on_toggle_grid_lines(self):
     def on_toggle_grid_lines(self):
-        self.report_usage("on_toggle_grd_lines()")
+        self.defaults.report_usage("on_toggle_grd_lines()")
 
 
         tt_settings = QtCore.QSettings("Open Source", "FlatCAM")
         tt_settings = QtCore.QSettings("Open Source", "FlatCAM")
         if tt_settings.contains("theme"):
         if tt_settings.contains("theme"):
@@ -4839,7 +4787,7 @@ class App(QtCore.QObject):
 
 
         # if new color is different then mark that the Preferences are changed
         # if new color is different then mark that the Preferences are changed
         if film_color != current_color:
         if film_color != current_color:
-            self.on_preferences_edited()
+            self.preferencesUiManager.on_preferences_edited()
 
 
         self.ui.tools_defaults_form.tools_film_group.film_color_button.setStyleSheet(
         self.ui.tools_defaults_form.tools_film_group.film_color_button.setStyleSheet(
             "background-color:%s;"
             "background-color:%s;"
@@ -4868,7 +4816,7 @@ class App(QtCore.QObject):
 
 
         # if new color is different then mark that the Preferences are changed
         # if new color is different then mark that the Preferences are changed
         if fill_color != current_color:
         if fill_color != current_color:
-            self.on_preferences_edited()
+            self.preferencesUiManager.on_preferences_edited()
 
 
         self.ui.tools2_defaults_form.tools2_qrcode_group.fill_color_button.setStyleSheet(
         self.ui.tools2_defaults_form.tools2_qrcode_group.fill_color_button.setStyleSheet(
             "background-color:%s;"
             "background-color:%s;"
@@ -4898,7 +4846,7 @@ class App(QtCore.QObject):
 
 
         # if new color is different then mark that the Preferences are changed
         # if new color is different then mark that the Preferences are changed
         if back_color != current_color:
         if back_color != current_color:
-            self.on_preferences_edited()
+            self.preferencesUiManager.on_preferences_edited()
 
 
         self.ui.tools2_defaults_form.tools2_qrcode_group.back_color_button.setStyleSheet(
         self.ui.tools2_defaults_form.tools2_qrcode_group.back_color_button.setStyleSheet(
             "background-color:%s;"
             "background-color:%s;"
@@ -5077,7 +5025,7 @@ class App(QtCore.QObject):
         :param force_deletion:  used by Tcl command
         :param force_deletion:  used by Tcl command
         :return: None
         :return: None
         """
         """
-        self.report_usage("on_delete()")
+        self.defaults.report_usage("on_delete()")
 
 
         response = None
         response = None
         bt_ok = None
         bt_ok = None
@@ -5175,7 +5123,7 @@ class App(QtCore.QObject):
 
 
         # display the message for the user
         # display the message for the user
         # and ask him to click on the desired position
         # and ask him to click on the desired position
-        self.report_usage("on_set_origin()")
+        self.defaults.report_usage("on_set_origin()")
 
 
         def origin_replot():
         def origin_replot():
 
 
@@ -5345,7 +5293,7 @@ class App(QtCore.QObject):
         :return:
         :return:
 
 
         """
         """
-        self.report_usage("on_jump_to()")
+        self.defaults.report_usage("on_jump_to()")
 
 
         if not custom_location:
         if not custom_location:
             dia_box_location = None
             dia_box_location = None
@@ -5466,7 +5414,7 @@ class App(QtCore.QObject):
         :return:            A point location. (x, y) tuple.
         :return:            A point location. (x, y) tuple.
 
 
         """
         """
-        self.report_usage("on_locate()")
+        self.defaults.report_usage("on_locate()")
 
 
         if obj is None:
         if obj is None:
             self.inform.emit('[WARNING_NOTCL] %s' % _("No object selected."))
             self.inform.emit('[WARNING_NOTCL] %s' % _("No object selected."))
@@ -5611,7 +5559,7 @@ class App(QtCore.QObject):
         Will copy a selection of objects, creating new objects.
         Will copy a selection of objects, creating new objects.
         :return:
         :return:
         """
         """
-        self.report_usage("on_copy_command()")
+        self.defaults.report_usage("on_copy_command()")
 
 
         def initialize(obj_init, app):
         def initialize(obj_init, app):
             obj_init.solid_geometry = deepcopy(obj.solid_geometry)
             obj_init.solid_geometry = deepcopy(obj.solid_geometry)
@@ -5724,7 +5672,7 @@ class App(QtCore.QObject):
         :param text:    New name for the object.
         :param text:    New name for the object.
         :return:
         :return:
         """
         """
-        self.report_usage("on_rename_object()")
+        self.defaults.report_usage("on_rename_object()")
 
 
         named_obj = self.collection.get_active()
         named_obj = self.collection.get_active()
         for obj in named_obj:
         for obj in named_obj:
@@ -5741,7 +5689,7 @@ class App(QtCore.QObject):
         Will convert any object out of Gerber, Excellon, Geometry to Geometry object.
         Will convert any object out of Gerber, Excellon, Geometry to Geometry object.
         :return:
         :return:
         """
         """
-        self.report_usage("convert_any2geo()")
+        self.defaults.report_usage("convert_any2geo()")
 
 
         def initialize(obj_init, app):
         def initialize(obj_init, app):
             obj_init.solid_geometry = obj.solid_geometry
             obj_init.solid_geometry = obj.solid_geometry
@@ -5793,7 +5741,7 @@ class App(QtCore.QObject):
         :return:
         :return:
         """
         """
 
 
-        self.report_usage("convert_any2gerber()")
+        self.defaults.report_usage("convert_any2gerber()")
 
 
         def initialize_geometry(obj_init, app):
         def initialize_geometry(obj_init, app):
             apertures = {}
             apertures = {}
@@ -5890,7 +5838,7 @@ class App(QtCore.QObject):
 
 
         :return:
         :return:
         """
         """
-        self.report_usage("on_selectall()")
+        self.defaults.report_usage("on_selectall()")
 
 
         # delete the possible selection box around a possible selected object
         # delete the possible selection box around a possible selected object
         self.delete_selection_shape()
         self.delete_selection_shape()
@@ -5924,65 +5872,49 @@ class App(QtCore.QObject):
             for tb in self.ui.pref_tab_area.widget(idx).findChildren(QtCore.QObject):
             for tb in self.ui.pref_tab_area.widget(idx).findChildren(QtCore.QObject):
                 try:
                 try:
                     try:
                     try:
-                        tb.textEdited.disconnect(self.on_preferences_edited)
+                        tb.textEdited.disconnect(self.preferencesUiManager.on_preferences_edited)
                     except (TypeError, AttributeError):
                     except (TypeError, AttributeError):
                         pass
                         pass
-                    tb.textEdited.connect(self.on_preferences_edited)
+                    tb.textEdited.connect(self.preferencesUiManager.on_preferences_edited)
                 except AttributeError:
                 except AttributeError:
                     pass
                     pass
 
 
                 try:
                 try:
                     try:
                     try:
-                        tb.modificationChanged.disconnect(self.on_preferences_edited)
+                        tb.modificationChanged.disconnect(self.preferencesUiManager.on_preferences_edited)
                     except (TypeError, AttributeError):
                     except (TypeError, AttributeError):
                         pass
                         pass
-                    tb.modificationChanged.connect(self.on_preferences_edited)
+                    tb.modificationChanged.connect(self.preferencesUiManager.on_preferences_edited)
                 except AttributeError:
                 except AttributeError:
                     pass
                     pass
 
 
                 try:
                 try:
                     try:
                     try:
-                        tb.toggled.disconnect(self.on_preferences_edited)
+                        tb.toggled.disconnect(self.preferencesUiManager.on_preferences_edited)
                     except (TypeError, AttributeError):
                     except (TypeError, AttributeError):
                         pass
                         pass
-                    tb.toggled.connect(self.on_preferences_edited)
+                    tb.toggled.connect(self.preferencesUiManager.on_preferences_edited)
                 except AttributeError:
                 except AttributeError:
                     pass
                     pass
 
 
                 try:
                 try:
                     try:
                     try:
-                        tb.valueChanged.disconnect(self.on_preferences_edited)
+                        tb.valueChanged.disconnect(self.preferencesUiManager.on_preferences_edited)
                     except (TypeError, AttributeError):
                     except (TypeError, AttributeError):
                         pass
                         pass
-                    tb.valueChanged.connect(self.on_preferences_edited)
+                    tb.valueChanged.connect(self.preferencesUiManager.on_preferences_edited)
                 except AttributeError:
                 except AttributeError:
                     pass
                     pass
 
 
                 try:
                 try:
                     try:
                     try:
-                        tb.currentIndexChanged.disconnect(self.on_preferences_edited)
+                        tb.currentIndexChanged.disconnect(self.preferencesUiManager.on_preferences_edited)
                     except (TypeError, AttributeError):
                     except (TypeError, AttributeError):
                         pass
                         pass
-                    tb.currentIndexChanged.connect(self.on_preferences_edited)
+                    tb.currentIndexChanged.connect(self.preferencesUiManager.on_preferences_edited)
                 except AttributeError:
                 except AttributeError:
                     pass
                     pass
 
 
-    def on_preferences_edited(self):
-        """
-        Executed when a preference was changed in the Edit -> Preferences tab.
-        Will color the Preferences tab text to Red color.
-        :return:
-        """
-        if self.preferencesUiManager.preferences_changed_flag is False:
-            self.inform.emit('[WARNING_NOTCL] %s' % _("Preferences edited but not saved."))
-
-            for idx in range(self.ui.plot_tab_area.count()):
-                if self.ui.plot_tab_area.tabText(idx) == _("Preferences"):
-                    self.ui.plot_tab_area.tabBar.setTabTextColor(idx, QtGui.QColor('red'))
-
-            self.ui.pref_apply_button.setStyleSheet("QPushButton {color: red;}")
-
-            self.preferencesUiManager.preferences_changed_flag = True
 
 
     def on_tools_database(self, source='app'):
     def on_tools_database(self, source='app'):
         """
         """
@@ -6080,57 +6012,10 @@ class App(QtCore.QObject):
         :param title: The name of the tab that was closed.
         :param title: The name of the tab that was closed.
         :return:
         :return:
         """
         """
+        # FIXME: doing this based on translated title doesn't seem very robust.
 
 
         if title == _("Preferences"):
         if title == _("Preferences"):
-            # disconnect
-            for idx in range(self.ui.pref_tab_area.count()):
-                for tb in self.ui.pref_tab_area.widget(idx).findChildren(QtCore.QObject):
-                    try:
-                        tb.textEdited.disconnect(self.on_preferences_edited)
-                    except (TypeError, AttributeError):
-                        pass
-
-                    try:
-                        tb.modificationChanged.disconnect(self.on_preferences_edited)
-                    except (TypeError, AttributeError):
-                        pass
-
-                    try:
-                        tb.toggled.disconnect(self.on_preferences_edited)
-                    except (TypeError, AttributeError):
-                        pass
-
-                    try:
-                        tb.valueChanged.disconnect(self.on_preferences_edited)
-                    except (TypeError, AttributeError):
-                        pass
-
-                    try:
-                        tb.currentIndexChanged.disconnect(self.on_preferences_edited)
-                    except (TypeError, AttributeError):
-                        pass
-
-            if self.preferencesUiManager.preferences_changed_flag is True:
-                msgbox = QtWidgets.QMessageBox()
-                msgbox.setText(_("One or more values are changed.\n"
-                                 "Do you want to save the Preferences?"))
-                msgbox.setWindowTitle(_("Save Preferences"))
-                msgbox.setWindowIcon(QtGui.QIcon(self.resource_location + '/save_as.png'))
-
-                bt_yes = msgbox.addButton(_('Yes'), QtWidgets.QMessageBox.YesRole)
-                msgbox.addButton(_('No'), QtWidgets.QMessageBox.NoRole)
-
-                msgbox.setDefaultButton(bt_yes)
-                msgbox.exec_()
-                response = msgbox.clickedButton()
-
-                if response == bt_yes:
-                    self.preferencesUiManager.on_save_button(save_to_file=True)
-                    self.inform.emit('[success] %s' % _("Preferences saved."))
-                else:
-                    self.preferencesUiManager.preferences_changed_flag = False
-                    self.inform.emit('')
-                    return
+            self.uiPreferencesManager.on_close_preferences_tab()
 
 
         if title == _("Tools Database"):
         if title == _("Tools Database"):
             # disconnect the signals from the table widget in tab
             # disconnect the signals from the table widget in tab
@@ -6172,7 +6057,7 @@ class App(QtCore.QObject):
 
 
         :return:
         :return:
         """
         """
-        self.report_usage("on_flipy()")
+        self.defaults.report_usage("on_flipy()")
 
 
         obj_list = self.collection.get_selected()
         obj_list = self.collection.get_selected()
         xminlist = []
         xminlist = []
@@ -6219,7 +6104,7 @@ class App(QtCore.QObject):
         :return:
         :return:
         """
         """
 
 
-        self.report_usage("on_flipx()")
+        self.defaults.report_usage("on_flipx()")
 
 
         obj_list = self.collection.get_selected()
         obj_list = self.collection.get_selected()
         xminlist = []
         xminlist = []
@@ -6268,7 +6153,7 @@ class App(QtCore.QObject):
         :param preset:  A value to be used as predefined angle for rotation.
         :param preset:  A value to be used as predefined angle for rotation.
         :return:
         :return:
         """
         """
-        self.report_usage("on_rotate()")
+        self.defaults.report_usage("on_rotate()")
 
 
         obj_list = self.collection.get_selected()
         obj_list = self.collection.get_selected()
         xminlist = []
         xminlist = []
@@ -6323,7 +6208,7 @@ class App(QtCore.QObject):
         :return:
         :return:
         """
         """
 
 
-        self.report_usage("on_skewx()")
+        self.defaults.report_usage("on_skewx()")
 
 
         obj_list = self.collection.get_selected()
         obj_list = self.collection.get_selected()
         xminlist = []
         xminlist = []
@@ -6362,7 +6247,7 @@ class App(QtCore.QObject):
         :return:
         :return:
         """
         """
 
 
-        self.report_usage("on_skewy()")
+        self.defaults.report_usage("on_skewy()")
 
 
         obj_list = self.collection.get_selected()
         obj_list = self.collection.get_selected()
         xminlist = []
         xminlist = []
@@ -6417,7 +6302,7 @@ class App(QtCore.QObject):
         :return: None
         :return: None
         """
         """
 
 
-        self.report_usage("on_toolbar_replot")
+        self.defaults.report_usage("on_toolbar_replot")
         self.log.debug("on_toolbar_replot()")
         self.log.debug("on_toolbar_replot()")
 
 
         try:
         try:
@@ -6722,7 +6607,7 @@ class App(QtCore.QObject):
                              _("Delete Grid value cancelled"))
                              _("Delete Grid value cancelled"))
 
 
     def on_shortcut_list(self):
     def on_shortcut_list(self):
-        self.report_usage("on_shortcut_list()")
+        self.defaults.report_usage("on_shortcut_list()")
 
 
         # add the tab if it was closed
         # add the tab if it was closed
         self.ui.plot_tab_area.addTab(self.ui.shortcuts_tab, _("Key Shortcut List"))
         self.ui.plot_tab_area.addTab(self.ui.shortcuts_tab, _("Key Shortcut List"))
@@ -6751,7 +6636,7 @@ class App(QtCore.QObject):
             self.ui.notebook.setCurrentWidget(self.ui.tool_tab)
             self.ui.notebook.setCurrentWidget(self.ui.tool_tab)
 
 
     def on_copy_name(self):
     def on_copy_name(self):
-        self.report_usage("on_copy_name()")
+        self.defaults.report_usage("on_copy_name()")
 
 
         obj = self.collection.get_active()
         obj = self.collection.get_active()
         try:
         try:
@@ -7419,7 +7304,7 @@ class App(QtCore.QObject):
         :return:        None
         :return:        None
         """
         """
 
 
-        self.report_usage("on_file_new")
+        self.defaults.report_usage("on_file_new")
 
 
         # Remove everything from memory
         # Remove everything from memory
         App.log.debug("on_file_new()")
         App.log.debug("on_file_new()")
@@ -7467,7 +7352,7 @@ class App(QtCore.QObject):
         self.project_filename = None
         self.project_filename = None
 
 
         # Load the application defaults
         # Load the application defaults
-        self.load_defaults(filename='current_defaults')
+        self.defaults.load(filename=os.path.join(self.data_path, 'current_defaults.FlatConfig'))
 
 
         # Re-fresh project options
         # Re-fresh project options
         self.on_options_app2project()
         self.on_options_app2project()
@@ -7498,7 +7383,7 @@ class App(QtCore.QObject):
         :return:
         :return:
         """
         """
 
 
-        self.report_usage("obj_properties()")
+        self.defaults.report_usage("obj_properties()")
         self.properties_tool.run(toggle=False)
         self.properties_tool.run(toggle=False)
 
 
     def on_project_context_save(self):
     def on_project_context_save(self):
@@ -7529,7 +7414,7 @@ class App(QtCore.QObject):
         :return:
         :return:
         """
         """
 
 
-        self.report_usage("obj_move()")
+        self.defaults.report_usage("obj_move()")
         self.move_tool.run(toggle=False)
         self.move_tool.run(toggle=False)
 
 
     def on_fileopengerber(self, signal, name=None):
     def on_fileopengerber(self, signal, name=None):
@@ -7541,7 +7426,7 @@ class App(QtCore.QObject):
         :return: None
         :return: None
         """
         """
 
 
-        self.report_usage("on_fileopengerber")
+        self.defaults.report_usage("on_fileopengerber")
         App.log.debug("on_fileopengerber()")
         App.log.debug("on_fileopengerber()")
 
 
         _filter_ = "Gerber Files (*.gbr *.ger *.gtl *.gbl *.gts *.gbs *.gtp *.gbp *.gto *.gbo *.gm1 *.gml *.gm3 *" \
         _filter_ = "Gerber Files (*.gbr *.ger *.gtl *.gbl *.gts *.gbs *.gtp *.gbp *.gto *.gbo *.gm1 *.gml *.gm3 *" \
@@ -7588,7 +7473,7 @@ class App(QtCore.QObject):
         :return: None
         :return: None
         """
         """
 
 
-        self.report_usage("on_fileopenexcellon")
+        self.defaults.report_usage("on_fileopenexcellon")
         App.log.debug("on_fileopenexcellon()")
         App.log.debug("on_fileopenexcellon()")
 
 
         _filter_ = "Excellon Files (*.drl *.txt *.xln *.drd *.tap *.exc *.ncd);;" \
         _filter_ = "Excellon Files (*.drl *.txt *.xln *.drd *.tap *.exc *.ncd);;" \
@@ -7626,7 +7511,7 @@ class App(QtCore.QObject):
         :return:
         :return:
         """
         """
 
 
-        self.report_usage("on_fileopengcode")
+        self.defaults.report_usage("on_fileopengcode")
         App.log.debug("on_fileopengcode()")
         App.log.debug("on_fileopengcode()")
 
 
         # https://bobcadsupport.com/helpdesk/index.php?/Knowledgebase/Article/View/13/5/known-g-code-file-extensions
         # https://bobcadsupport.com/helpdesk/index.php?/Knowledgebase/Article/View/13/5/known-g-code-file-extensions
@@ -7666,7 +7551,7 @@ class App(QtCore.QObject):
         :return: None
         :return: None
         """
         """
 
 
-        self.report_usage("on_file_openproject")
+        self.defaults.report_usage("on_file_openproject")
         App.log.debug("on_file_openproject()")
         App.log.debug("on_file_openproject()")
         _filter_ = "FlatCAM Project (*.FlatPrj);;All Files (*.*)"
         _filter_ = "FlatCAM Project (*.FlatPrj);;All Files (*.*)"
         try:
         try:
@@ -7698,7 +7583,7 @@ class App(QtCore.QObject):
         :return:        None
         :return:        None
         """
         """
 
 
-        self.report_usage("on_fileopenhpgl2")
+        self.defaults.report_usage("on_fileopenhpgl2")
         App.log.debug("on_fileopenhpgl2()")
         App.log.debug("on_fileopenhpgl2()")
 
 
         _filter_ = "HPGL2 Files (*.plt);;" \
         _filter_ = "HPGL2 Files (*.plt);;" \
@@ -7736,7 +7621,7 @@ class App(QtCore.QObject):
         :return:        None
         :return:        None
         """
         """
 
 
-        self.report_usage("on_file_openconfig")
+        self.defaults.report_usage("on_file_openconfig")
         App.log.debug("on_file_openconfig()")
         App.log.debug("on_file_openconfig()")
         _filter_ = "FlatCAM Config (*.FlatConfig);;FlatCAM Config (*.json);;All Files (*.*)"
         _filter_ = "FlatCAM Config (*.FlatConfig);;FlatCAM Config (*.json);;All Files (*.*)"
         try:
         try:
@@ -7757,7 +7642,7 @@ class App(QtCore.QObject):
 
 
         :return: None
         :return: None
         """
         """
-        self.report_usage("on_file_exportsvg")
+        self.defaults.report_usage("on_file_exportsvg")
         App.log.debug("on_file_exportsvg()")
         App.log.debug("on_file_exportsvg()")
 
 
         obj = self.collection.get_active()
         obj = self.collection.get_active()
@@ -7808,7 +7693,7 @@ class App(QtCore.QObject):
             self.file_saved.emit("SVG", filename)
             self.file_saved.emit("SVG", filename)
 
 
     def on_file_exportpng(self):
     def on_file_exportpng(self):
-        self.report_usage("on_file_exportpng")
+        self.defaults.report_usage("on_file_exportpng")
         App.log.debug("on_file_exportpng()")
         App.log.debug("on_file_exportpng()")
 
 
         self.date = str(datetime.today()).rpartition('.')[0]
         self.date = str(datetime.today()).rpartition('.')[0]
@@ -7852,7 +7737,7 @@ class App(QtCore.QObject):
 
 
         :return: None
         :return: None
         """
         """
-        self.report_usage("on_file_savegerber")
+        self.defaults.report_usage("on_file_savegerber")
         App.log.debug("on_file_savegerber()")
         App.log.debug("on_file_savegerber()")
 
 
         obj = self.collection.get_active()
         obj = self.collection.get_active()
@@ -7893,7 +7778,7 @@ class App(QtCore.QObject):
 
 
         :return: None
         :return: None
         """
         """
-        self.report_usage("on_file_savescript")
+        self.defaults.report_usage("on_file_savescript")
         App.log.debug("on_file_savescript()")
         App.log.debug("on_file_savescript()")
 
 
         obj = self.collection.get_active()
         obj = self.collection.get_active()
@@ -7934,7 +7819,7 @@ class App(QtCore.QObject):
 
 
         :return: None
         :return: None
         """
         """
-        self.report_usage("on_file_savedocument")
+        self.defaults.report_usage("on_file_savedocument")
         App.log.debug("on_file_savedocument()")
         App.log.debug("on_file_savedocument()")
 
 
         obj = self.collection.get_active()
         obj = self.collection.get_active()
@@ -7975,7 +7860,7 @@ class App(QtCore.QObject):
 
 
         :return: None
         :return: None
         """
         """
-        self.report_usage("on_file_saveexcellon")
+        self.defaults.report_usage("on_file_saveexcellon")
         App.log.debug("on_file_saveexcellon()")
         App.log.debug("on_file_saveexcellon()")
 
 
         obj = self.collection.get_active()
         obj = self.collection.get_active()
@@ -8016,7 +7901,7 @@ class App(QtCore.QObject):
 
 
         :return: None
         :return: None
         """
         """
-        self.report_usage("on_file_exportexcellon")
+        self.defaults.report_usage("on_file_exportexcellon")
         App.log.debug("on_file_exportexcellon()")
         App.log.debug("on_file_exportexcellon()")
 
 
         obj = self.collection.get_active()
         obj = self.collection.get_active()
@@ -8060,7 +7945,7 @@ class App(QtCore.QObject):
 
 
         :return: None
         :return: None
         """
         """
-        self.report_usage("on_file_exportgerber")
+        self.defaults.report_usage("on_file_exportgerber")
         App.log.debug("on_file_exportgerber()")
         App.log.debug("on_file_exportgerber()")
 
 
         obj = self.collection.get_active()
         obj = self.collection.get_active()
@@ -8104,7 +7989,7 @@ class App(QtCore.QObject):
 
 
                 :return: None
                 :return: None
                 """
                 """
-        self.report_usage("on_file_exportdxf")
+        self.defaults.report_usage("on_file_exportdxf")
         App.log.debug("on_file_exportdxf()")
         App.log.debug("on_file_exportdxf()")
 
 
         obj = self.collection.get_active()
         obj = self.collection.get_active()
@@ -8158,7 +8043,7 @@ class App(QtCore.QObject):
         :type type_of_obj: str
         :type type_of_obj: str
         :return: None
         :return: None
         """
         """
-        self.report_usage("on_file_importsvg")
+        self.defaults.report_usage("on_file_importsvg")
         App.log.debug("on_file_importsvg()")
         App.log.debug("on_file_importsvg()")
 
 
         _filter_ = "SVG File .svg (*.svg);;All Files (*.*)"
         _filter_ = "SVG File .svg (*.svg);;All Files (*.*)"
@@ -8189,7 +8074,7 @@ class App(QtCore.QObject):
         :type type_of_obj: str
         :type type_of_obj: str
         :return: None
         :return: None
         """
         """
-        self.report_usage("on_file_importdxf")
+        self.defaults.report_usage("on_file_importdxf")
         App.log.debug("on_file_importdxf()")
         App.log.debug("on_file_importdxf()")
 
 
         _filter_ = "DXF File .dxf (*.DXF);;All Files (*.*)"
         _filter_ = "DXF File .dxf (*.DXF);;All Files (*.*)"
@@ -8344,7 +8229,7 @@ class App(QtCore.QObject):
         # self.ui.show()
         # self.ui.show()
 
 
     def on_toggle_code_editor(self):
     def on_toggle_code_editor(self):
-        self.report_usage("on_toggle_code_editor()")
+        self.defaults.report_usage("on_toggle_code_editor()")
 
 
         if self.toggle_codeeditor is False:
         if self.toggle_codeeditor is False:
             self.init_code_editor(name=_("Code Editor"))
             self.init_code_editor(name=_("Code Editor"))
@@ -8427,7 +8312,7 @@ class App(QtCore.QObject):
         :return:
         :return:
         """
         """
 
 
-        self.report_usage("on_fileopenscript")
+        self.defaults.report_usage("on_fileopenscript")
         App.log.debug("on_fileopenscript()")
         App.log.debug("on_fileopenscript()")
 
 
         _filter_ = "TCL script .FlatScript (*.FlatScript);;TCL script .tcl (*.TCL);;TCL script .txt (*.TXT);;" \
         _filter_ = "TCL script .FlatScript (*.FlatScript);;TCL script .tcl (*.TCL);;TCL script .txt (*.TXT);;" \
@@ -8459,7 +8344,7 @@ class App(QtCore.QObject):
         :return: None
         :return: None
         """
         """
 
 
-        self.report_usage("on_filerunscript")
+        self.defaults.report_usage("on_filerunscript")
         App.log.debug("on_file_runscript()")
         App.log.debug("on_file_runscript()")
 
 
         if name:
         if name:
@@ -8517,7 +8402,7 @@ class App(QtCore.QObject):
         :return: None
         :return: None
         """
         """
 
 
-        self.report_usage("on_file_saveproject")
+        self.defaults.report_usage("on_file_saveproject")
 
 
         if self.project_filename is None:
         if self.project_filename is None:
             self.on_file_saveprojectas()
             self.on_file_saveprojectas()
@@ -8544,7 +8429,7 @@ class App(QtCore.QObject):
         :return: None
         :return: None
         """
         """
 
 
-        self.report_usage("on_file_saveprojectas")
+        self.defaults.report_usage("on_file_saveprojectas")
 
 
         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 ':-')
@@ -8813,7 +8698,7 @@ class App(QtCore.QObject):
         :param scale_stroke_factor: factor by which to change/scale the thickness of the features
         :param scale_stroke_factor: factor by which to change/scale the thickness of the features
         :return:
         :return:
         """
         """
-        self.report_usage("export_svg()")
+        self.defaults.report_usage("export_svg()")
 
 
         if filename is None:
         if filename is None:
             filename = self.defaults["global_last_save_folder"] if self.defaults["global_last_save_folder"] \
             filename = self.defaults["global_last_save_folder"] if self.defaults["global_last_save_folder"] \
@@ -8881,7 +8766,7 @@ class App(QtCore.QObject):
         :param use_thread: if to be run in a separate thread
         :param use_thread: if to be run in a separate thread
         :return:
         :return:
         """
         """
-        self.report_usage("save source file()")
+        self.defaults.report_usage("save source file()")
 
 
         if filename is None:
         if filename is None:
             filename = self.defaults["global_last_save_folder"] if self.defaults["global_last_save_folder"] \
             filename = self.defaults["global_last_save_folder"] if self.defaults["global_last_save_folder"] \
@@ -8925,7 +8810,7 @@ class App(QtCore.QObject):
         :param use_thread: if to be run in a separate thread
         :param use_thread: if to be run in a separate thread
         :return:
         :return:
         """
         """
-        self.report_usage("export_excellon()")
+        self.defaults.report_usage("export_excellon()")
 
 
         if filename is None:
         if filename is None:
             if self.defaults["global_last_save_folder"]:
             if self.defaults["global_last_save_folder"]:
@@ -9080,7 +8965,7 @@ class App(QtCore.QObject):
         :param use_thread: if to be run in a separate thread
         :param use_thread: if to be run in a separate thread
         :return:
         :return:
         """
         """
-        self.report_usage("export_gerber()")
+        self.defaults.report_usage("export_gerber()")
 
 
         if filename is None:
         if filename is None:
             filename = self.defaults["global_last_save_folder"] if self.defaults["global_last_save_folder"] \
             filename = self.defaults["global_last_save_folder"] if self.defaults["global_last_save_folder"] \
@@ -9213,7 +9098,7 @@ class App(QtCore.QObject):
         :param use_thread: if to be run in a separate thread
         :param use_thread: if to be run in a separate thread
         :return:
         :return:
         """
         """
-        self.report_usage("export_dxf()")
+        self.defaults.report_usage("export_dxf()")
 
 
         if filename is None:
         if filename is None:
             filename = self.defaults["global_last_save_folder"] if self.defaults["global_last_save_folder"] \
             filename = self.defaults["global_last_save_folder"] if self.defaults["global_last_save_folder"] \
@@ -9265,7 +9150,7 @@ class App(QtCore.QObject):
         :param outname:
         :param outname:
         :return:
         :return:
         """
         """
-        self.report_usage("import_svg()")
+        self.defaults.report_usage("import_svg()")
         log.debug("App.import_svg()")
         log.debug("App.import_svg()")
 
 
         obj_type = ""
         obj_type = ""
@@ -9308,7 +9193,7 @@ class App(QtCore.QObject):
         :param outname:     Name for the imported Geometry
         :param outname:     Name for the imported Geometry
         :return:
         :return:
         """
         """
-        self.report_usage("import_dxf()")
+        self.defaults.report_usage("import_dxf()")
 
 
         obj_type = ""
         obj_type = ""
         if geo_type is None or geo_type == "geometry":
         if geo_type is None or geo_type == "geometry":
@@ -10319,21 +10204,21 @@ class App(QtCore.QObject):
         self.plotcanvas.zoom(float(self.defaults['global_zoom_ratio']))
         self.plotcanvas.zoom(float(self.defaults['global_zoom_ratio']))
 
 
     def disable_all_plots(self):
     def disable_all_plots(self):
-        self.report_usage("disable_all_plots()")
+        self.defaults.report_usage("disable_all_plots()")
 
 
         self.disable_plots(self.collection.get_list())
         self.disable_plots(self.collection.get_list())
         self.inform.emit('[success] %s' %
         self.inform.emit('[success] %s' %
                          _("All plots disabled."))
                          _("All plots disabled."))
 
 
     def disable_other_plots(self):
     def disable_other_plots(self):
-        self.report_usage("disable_other_plots()")
+        self.defaults.report_usage("disable_other_plots()")
 
 
         self.disable_plots(self.collection.get_non_selected())
         self.disable_plots(self.collection.get_non_selected())
         self.inform.emit('[success] %s' %
         self.inform.emit('[success] %s' %
                          _("All non selected plots disabled."))
                          _("All non selected plots disabled."))
 
 
     def enable_all_plots(self):
     def enable_all_plots(self):
-        self.report_usage("enable_all_plots()")
+        self.defaults.report_usage("enable_all_plots()")
 
 
         self.enable_plots(self.collection.get_list())
         self.enable_plots(self.collection.get_list())
         self.inform.emit('[success] %s' %
         self.inform.emit('[success] %s' %
@@ -10624,7 +10509,7 @@ class App(QtCore.QObject):
         :param objects:     Selected objects in the Project Tab
         :param objects:     Selected objects in the Project Tab
         :return:
         :return:
         """
         """
-        self.report_usage("generate_cnc_job()")
+        self.defaults.report_usage("generate_cnc_job()")
 
 
         # for obj in objects:
         # for obj in objects:
         #     obj.generatecncjob()
         #     obj.generatecncjob()
@@ -10797,11 +10682,10 @@ class App(QtCore.QObject):
         :return:    None
         :return:    None
         """
         """
 
 
-        self.report_usage("on_options_app2project")
+        self.defaults.report_usage("on_options_app2project")
 
 
         self.preferencesUiManager.defaults_read_form()
         self.preferencesUiManager.defaults_read_form()
         self.options.update(self.defaults)
         self.options.update(self.defaults)
-        # self.options_write_form()
 
 
     def toggle_shell(self):
     def toggle_shell(self):
         """
         """
@@ -10809,7 +10693,7 @@ class App(QtCore.QObject):
         :return: None
         :return: None
         """
         """
 
 
-        self.report_usage("toggle_shell()")
+        self.defaults.report_usage("toggle_shell()")
 
 
         if self.ui.shell_dock.isVisible():
         if self.ui.shell_dock.isVisible():
             self.ui.shell_dock.hide()
             self.ui.shell_dock.hide()
@@ -10837,7 +10721,7 @@ class App(QtCore.QObject):
         :return: None
         :return: None
         """
         """
 
 
-        self.report_usage("on_toggle_shell_from_settings()")
+        self.defaults.report_usage("on_toggle_shell_from_settings()")
 
 
         if state is True:
         if state is True:
             if not self.ui.shell_dock.isVisible():
             if not self.ui.shell_dock.isVisible():

+ 1 - 1
FlatCAMBookmark.py

@@ -270,7 +270,7 @@ class BookmarkManager(QtWidgets.QWidget):
         self.build_bm_ui()
         self.build_bm_ui()
 
 
     def on_export_bookmarks(self):
     def on_export_bookmarks(self):
-        self.app.report_usage("on_export_bookmarks")
+        self.app.defaults.report_usage("on_export_bookmarks")
         self.app.log.debug("on_export_bookmarks()")
         self.app.log.debug("on_export_bookmarks()")
 
 
         date = str(datetime.today()).rpartition('.')[0]
         date = str(datetime.today()).rpartition('.')[0]

+ 4 - 4
FlatCAMDB.py

@@ -642,7 +642,7 @@ class ToolsDB(QtWidgets.QWidget):
         self.app.inform.emit('[success] %s' % _("Tool removed from Tools DB."))
         self.app.inform.emit('[success] %s' % _("Tool removed from Tools DB."))
 
 
     def on_export_tools_db_file(self):
     def on_export_tools_db_file(self):
-        self.app.report_usage("on_export_tools_db_file")
+        self.app.defaults.report_usage("on_export_tools_db_file")
         self.app.log.debug("on_export_tools_db_file()")
         self.app.log.debug("on_export_tools_db_file()")
 
 
         date = str(datetime.today()).rpartition('.')[0]
         date = str(datetime.today()).rpartition('.')[0]
@@ -699,7 +699,7 @@ class ToolsDB(QtWidgets.QWidget):
         self.app.inform.emit('[success] %s: %s' % (_("Exported Tools DB to"), filename))
         self.app.inform.emit('[success] %s: %s' % (_("Exported Tools DB to"), filename))
 
 
     def on_import_tools_db_file(self):
     def on_import_tools_db_file(self):
-        self.app.report_usage("on_import_tools_db_file")
+        self.app.defaults.report_usage("on_import_tools_db_file")
         self.app.log.debug("on_import_tools_db_file()")
         self.app.log.debug("on_import_tools_db_file()")
 
 
         filter__ = "Text File (*.TXT);;All Files (*.*)"
         filter__ = "Text File (*.TXT);;All Files (*.*)"
@@ -2072,7 +2072,7 @@ class ToolsDB2(QtWidgets.QWidget):
         self.app.inform.emit('[success] %s' % _("Tool removed from Tools DB."))
         self.app.inform.emit('[success] %s' % _("Tool removed from Tools DB."))
 
 
     def on_export_tools_db_file(self):
     def on_export_tools_db_file(self):
-        self.app.report_usage("on_export_tools_db_file")
+        self.app.defaults.report_usage("on_export_tools_db_file")
         self.app.log.debug("on_export_tools_db_file()")
         self.app.log.debug("on_export_tools_db_file()")
 
 
         date = str(datetime.today()).rpartition('.')[0]
         date = str(datetime.today()).rpartition('.')[0]
@@ -2129,7 +2129,7 @@ class ToolsDB2(QtWidgets.QWidget):
         self.app.inform.emit('[success] %s: %s' % (_("Exported Tools DB to"), filename))
         self.app.inform.emit('[success] %s: %s' % (_("Exported Tools DB to"), filename))
 
 
     def on_import_tools_db_file(self):
     def on_import_tools_db_file(self):
-        self.app.report_usage("on_import_tools_db_file")
+        self.app.defaults.report_usage("on_import_tools_db_file")
         self.app.log.debug("on_import_tools_db_file()")
         self.app.log.debug("on_import_tools_db_file()")
 
 
         filter__ = "Text File (*.TXT);;All Files (*.*)"
         filter__ = "Text File (*.TXT);;All Files (*.*)"

+ 18 - 5
defaults.py

@@ -709,11 +709,10 @@ class FlatCAMDefaults:
     def __iter__(self):
     def __iter__(self):
         return self.defaults.__iter__()
         return self.defaults.__iter__()
 
 
-    def set_change_callback(self, callback):
-        self.defaults.set_change_callback(callback)
+    def __getattr__(self, item):
+        # Unfortunately this method alone is not enough to pass through the other magic methods above.
+        return self.defaults.__getattribute__(item)
 
 
-    def update(self, *args, **kwargs):
-        return self.defaults.update(*args, **kwargs)
 
 
     ##### Additional Methods #####
     ##### Additional Methods #####
 
 
@@ -828,4 +827,18 @@ class FlatCAMDefaults:
                 if param.find(routes[param].__name__.lower() + "_") == 0:
                 if param.find(routes[param].__name__.lower() + "_") == 0:
                     p = param[len(routes[param].__name__) + 1:]
                     p = param[len(routes[param].__name__) + 1:]
                     if p in routes[param].defaults:
                     if p in routes[param].defaults:
-                        routes[param].defaults[p] = self.defaults[param]
+                        routes[param].defaults[p] = self.defaults[param]
+
+    def report_usage(self, resource):
+        """
+        Increments usage counter for the given resource
+        in self.defaults['global_stats'].
+
+        :param resource: Name of the resource.
+        :return: None
+        """
+
+        if resource in self.defaults['global_stats']:
+            self.defaults['global_stats'][resource] += 1
+        else:
+            self.defaults['global_stats'][resource] = 1

+ 4 - 4
flatcamEditors/FlatCAMGeoEditor.py

@@ -122,7 +122,7 @@ class BufferSelectionTool(FlatCAMTool):
         self.buffer_distance_entry.set_value(0.01)
         self.buffer_distance_entry.set_value(0.01)
 
 
     def run(self):
     def run(self):
-        self.app.report_usage("Geo Editor ToolBuffer()")
+        self.app.defaults.report_usage("Geo Editor ToolBuffer()")
         FlatCAMTool.run(self)
         FlatCAMTool.run(self)
 
 
         # if the splitter us hidden, display it
         # if the splitter us hidden, display it
@@ -339,7 +339,7 @@ class TextInputTool(FlatCAMTool):
         self.font_italic_tb.clicked.connect(self.on_italic_button)
         self.font_italic_tb.clicked.connect(self.on_italic_button)
 
 
     def run(self):
     def run(self):
-        self.app.report_usage("Geo Editor TextInputTool()")
+        self.app.defaults.report_usage("Geo Editor TextInputTool()")
         FlatCAMTool.run(self)
         FlatCAMTool.run(self)
 
 
         # if the splitter us hidden, display it
         # if the splitter us hidden, display it
@@ -537,7 +537,7 @@ class PaintOptionsTool(FlatCAMTool):
         self.set_tool_ui()
         self.set_tool_ui()
 
 
     def run(self):
     def run(self):
-        self.app.report_usage("Geo Editor ToolPaint()")
+        self.app.defaults.report_usage("Geo Editor ToolPaint()")
         FlatCAMTool.run(self)
         FlatCAMTool.run(self)
 
 
         # if the splitter us hidden, display it
         # if the splitter us hidden, display it
@@ -980,7 +980,7 @@ class TransformEditorTool(FlatCAMTool):
         self.set_tool_ui()
         self.set_tool_ui()
 
 
     def run(self):
     def run(self):
-        self.app.report_usage("Geo Editor Transform Tool()")
+        self.app.defaults.report_usage("Geo Editor Transform Tool()")
         FlatCAMTool.run(self)
         FlatCAMTool.run(self)
         self.set_tool_ui()
         self.set_tool_ui()
 
 

+ 1 - 1
flatcamEditors/FlatCAMGrbEditor.py

@@ -5516,7 +5516,7 @@ class TransformEditorTool(FlatCAMTool):
         self.set_tool_ui()
         self.set_tool_ui()
 
 
     def run(self, toggle=True):
     def run(self, toggle=True):
-        self.app.report_usage("Geo Editor Transform Tool()")
+        self.app.defaults.report_usage("Geo Editor Transform Tool()")
 
 
         # if the splitter is hidden, display it, else hide it but only if the current widget is the same
         # if the splitter is hidden, display it, else hide it but only if the current widget is the same
         if self.app.ui.splitter.sizes()[0] == 0:
         if self.app.ui.splitter.sizes()[0] == 0:

+ 6 - 6
flatcamEditors/FlatCAMTextEditor.py

@@ -152,14 +152,14 @@ class TextEditor(QtWidgets.QWidget):
         self.code_edited = ''
         self.code_edited = ''
 
 
     def handlePrint(self):
     def handlePrint(self):
-        self.app.report_usage("handlePrint()")
+        self.app.defaults.report_usage("handlePrint()")
 
 
         dialog = QtPrintSupport.QPrintDialog()
         dialog = QtPrintSupport.QPrintDialog()
         if dialog.exec_() == QtWidgets.QDialog.Accepted:
         if dialog.exec_() == QtWidgets.QDialog.Accepted:
             self.code_editor.document().print_(dialog.printer())
             self.code_editor.document().print_(dialog.printer())
 
 
     def handlePreview(self):
     def handlePreview(self):
-        self.app.report_usage("handlePreview()")
+        self.app.defaults.report_usage("handlePreview()")
 
 
         dialog = QtPrintSupport.QPrintPreviewDialog()
         dialog = QtPrintSupport.QPrintPreviewDialog()
         dialog.paintRequested.connect(self.code_editor.print_)
         dialog.paintRequested.connect(self.code_editor.print_)
@@ -172,7 +172,7 @@ class TextEditor(QtWidgets.QWidget):
         pass
         pass
 
 
     def handleOpen(self, filt=None):
     def handleOpen(self, filt=None):
-        self.app.report_usage("handleOpen()")
+        self.app.defaults.report_usage("handleOpen()")
 
 
         if filt:
         if filt:
             _filter_ = filt
             _filter_ = filt
@@ -192,7 +192,7 @@ class TextEditor(QtWidgets.QWidget):
                 file.close()
                 file.close()
 
 
     def handleSaveGCode(self, name=None, filt=None, callback=None):
     def handleSaveGCode(self, name=None, filt=None, callback=None):
-        self.app.report_usage("handleSaveGCode()")
+        self.app.defaults.report_usage("handleSaveGCode()")
 
 
         if filt:
         if filt:
             _filter_ = filt
             _filter_ = filt
@@ -287,7 +287,7 @@ class TextEditor(QtWidgets.QWidget):
             callback()
             callback()
 
 
     def handleFindGCode(self):
     def handleFindGCode(self):
-        self.app.report_usage("handleFindGCode()")
+        self.app.defaults.report_usage("handleFindGCode()")
 
 
         flags = QtGui.QTextDocument.FindCaseSensitively
         flags = QtGui.QTextDocument.FindCaseSensitively
         text_to_be_found = self.entryFind.get_value()
         text_to_be_found = self.entryFind.get_value()
@@ -298,7 +298,7 @@ class TextEditor(QtWidgets.QWidget):
             r = self.code_editor.find(str(text_to_be_found), flags)
             r = self.code_editor.find(str(text_to_be_found), flags)
 
 
     def handleReplaceGCode(self):
     def handleReplaceGCode(self):
-        self.app.report_usage("handleReplaceGCode()")
+        self.app.defaults.report_usage("handleReplaceGCode()")
 
 
         old = self.entryFind.get_value()
         old = self.entryFind.get_value()
         new = self.entryReplace.get_value()
         new = self.entryReplace.get_value()

+ 137 - 28
flatcamGUI/PreferencesUI.py

@@ -28,11 +28,14 @@ else:
 
 
 class PreferencesUIManager():
 class PreferencesUIManager():
 
 
-    def __init__(self, defaults: FlatCAMDefaults, data_path: str, ui, inform):
+    def __init__(self, defaults: FlatCAMDefaults, data_path: str, ui, inform, app):
+        # FIXME: Ideally we would not pass in the app here
+        self.app = app
         self.defaults = defaults
         self.defaults = defaults
         self.data_path = data_path
         self.data_path = data_path
         self.ui = ui
         self.ui = ui
         self.inform = inform
         self.inform = inform
+        self.ignore_tab_close_event = False
 
 
         # 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
@@ -621,21 +624,19 @@ class PreferencesUIManager():
         """
         """
 
 
         def_dict = self.defaults if defaults_dict is None else defaults_dict
         def_dict = self.defaults if defaults_dict is None else defaults_dict
+
         try:
         try:
-            if factor is None:
-                if units is None:
-                    self.defaults_form_fields[field].set_value(def_dict[field])
-                elif units == 'IN' and (field == 'global_gridx' or field == 'global_gridy'):
-                    self.defaults_form_fields[field].set_value(def_dict[field])
-                elif units == 'MM' and (field == 'global_gridx' or field == 'global_gridy'):
-                    self.defaults_form_fields[field].set_value(def_dict[field])
-            else:
-                if units is None:
-                    self.defaults_form_fields[field].set_value(def_dict[field] * factor)
-                elif units == 'IN' and (field == 'global_gridx' or field == 'global_gridy'):
-                    self.defaults_form_fields[field].set_value((def_dict[field] * factor))
-                elif units == 'MM' and (field == 'global_gridx' or field == 'global_gridy'):
-                    self.defaults_form_fields[field].set_value((def_dict[field] * factor))
+            value = def_dict[field]
+            log.debug("value is "+str(value)+ " and factor is "+str(factor))
+            if factor is not None:
+                value *= factor
+
+            form_field = self.defaults_form_fields[field]
+            if units is None:
+                form_field.set_value(value)
+            elif (units == 'IN' or units == 'MM') and (field == 'global_gridx' or field == 'global_gridy'):
+                form_field.set_value(value)
+
         except KeyError:
         except KeyError:
             pass
             pass
         except AttributeError:
         except AttributeError:
@@ -909,10 +910,10 @@ class PreferencesUIManager():
         if save_to_file:
         if save_to_file:
             self.save_defaults(silent=False)
             self.save_defaults(silent=False)
             # load the defaults so they are updated into the app
             # load the defaults so they are updated into the app
-            self.load_defaults(filename='current_defaults')
+            self.defaults.load(filename=os.path.join(self.data_path, 'current_defaults.FlatConfig'))
 
 
         # Re-fresh project options
         # Re-fresh project options
-        self.on_options_app2project()
+        self.app.on_options_app2project()
 
 
         settgs = QSettings("Open Source", "FlatCAM")
         settgs = QSettings("Open Source", "FlatCAM")
 
 
@@ -947,10 +948,7 @@ class PreferencesUIManager():
     def on_pref_close_button(self):
     def on_pref_close_button(self):
         # Preferences saved, update flag
         # Preferences saved, update flag
         self.preferences_changed_flag = False
         self.preferences_changed_flag = False
-        try:
-            self.ui.plot_tab_area.tab_closed_signal.disconnect(self.on_plot_area_tab_closed)
-        except TypeError:
-            pass
+        self.ignore_tab_close_event = True
 
 
         try:
         try:
             self.ui.general_defaults_form.general_app_group.units_radio.activated_custom.disconnect()
             self.ui.general_defaults_form.general_app_group.units_radio.activated_custom.disconnect()
@@ -958,7 +956,7 @@ class PreferencesUIManager():
             pass
             pass
         self.defaults_write_form(source_dict=self.defaults.current_defaults)
         self.defaults_write_form(source_dict=self.defaults.current_defaults)
         self.ui.general_defaults_form.general_app_group.units_radio.activated_custom.connect(
         self.ui.general_defaults_form.general_app_group.units_radio.activated_custom.connect(
-            lambda: self.on_toggle_units(no_pref=False))
+            lambda: self.app.on_toggle_units(no_pref=False))
         self.defaults.update(self.defaults.current_defaults)
         self.defaults.update(self.defaults.current_defaults)
 
 
         # Preferences save, update the color of the Preferences Tab text
         # Preferences save, update the color of the Preferences Tab text
@@ -969,7 +967,7 @@ class PreferencesUIManager():
                 break
                 break
 
 
         self.inform.emit('%s' % _("Preferences closed without saving."))
         self.inform.emit('%s' % _("Preferences closed without saving."))
-        self.ui.plot_tab_area.tab_closed_signal.connect(self.on_plot_area_tab_closed)
+        self.ignore_tab_close_event = False
 
 
     def on_restore_defaults_preferences(self):
     def on_restore_defaults_preferences(self):
         """
         """
@@ -995,12 +993,12 @@ class PreferencesUIManager():
         :param first_time:  Boolean. If True will execute some code when the app is run first time
         :param first_time:  Boolean. If True will execute some code when the app is run first time
         :return:            None
         :return:            None
         """
         """
-        self.report_usage("save_defaults")
+        self.defaults.report_usage("save_defaults")
 
 
         if data_path is None:
         if data_path is None:
             data_path = self.data_path
             data_path = self.data_path
 
 
-        self.propagate_defaults()
+        self.defaults.propagate_defaults()
 
 
         if first_time is False:
         if first_time is False:
             self.save_toolbar_view()
             self.save_toolbar_view()
@@ -1018,7 +1016,118 @@ class PreferencesUIManager():
             self.inform.emit('[success] %s' % _("Preferences saved."))
             self.inform.emit('[success] %s' % _("Preferences saved."))
 
 
         # update the autosave timer
         # update the autosave timer
-        self.save_project_auto_update()
+        self.app.save_project_auto_update()
+
+    def save_toolbar_view(self):
+        """
+        Will save the toolbar view state to the defaults
+
+        :return:            None
+        """
+
+        # Save the toolbar view
+        tb_status = 0
+        if self.ui.toolbarfile.isVisible():
+            tb_status += 1
+
+        if self.ui.toolbargeo.isVisible():
+            tb_status += 2
+
+        if self.ui.toolbarview.isVisible():
+            tb_status += 4
+
+        if self.ui.toolbartools.isVisible():
+            tb_status += 8
+
+        if self.ui.exc_edit_toolbar.isVisible():
+            tb_status += 16
+
+        if self.ui.geo_edit_toolbar.isVisible():
+            tb_status += 32
+
+        if self.ui.grb_edit_toolbar.isVisible():
+            tb_status += 64
+
+        if self.ui.snap_toolbar.isVisible():
+            tb_status += 128
+
+        if self.ui.toolbarshell.isVisible():
+            tb_status += 256
+
+        self.defaults["global_toolbar_view"] = tb_status
+
+    def on_preferences_edited(self):
+        """
+        Executed when a preference was changed in the Edit -> Preferences tab.
+        Will color the Preferences tab text to Red color.
+        :return:
+        """
+        if self.preferences_changed_flag is False:
+            self.inform.emit('[WARNING_NOTCL] %s' % _("Preferences edited but not saved."))
+
+            for idx in range(self.ui.plot_tab_area.count()):
+                if self.ui.plot_tab_area.tabText(idx) == _("Preferences"):
+                    self.ui.plot_tab_area.tabBar.setTabTextColor(idx, QtGui.QColor('red'))
+
+            self.ui.pref_apply_button.setStyleSheet("QPushButton {color: red;}")
+
+            self.preferences_changed_flag = True
+
+    def on_close_preferences_tab(self):
+        if self.ignore_tab_close_event:
+            return
+
+        # disconnect
+        for idx in range(self.ui.pref_tab_area.count()):
+            for tb in self.ui.pref_tab_area.widget(idx).findChildren(QtCore.QObject):
+                try:
+                    tb.textEdited.disconnect(self.on_preferences_edited)
+                except (TypeError, AttributeError):
+                    pass
+
+                try:
+                    tb.modificationChanged.disconnect(self.on_preferences_edited)
+                except (TypeError, AttributeError):
+                    pass
+
+                try:
+                    tb.toggled.disconnect(self.on_preferences_edited)
+                except (TypeError, AttributeError):
+                    pass
+
+                try:
+                    tb.valueChanged.disconnect(self.on_preferences_edited)
+                except (TypeError, AttributeError):
+                    pass
+
+                try:
+                    tb.currentIndexChanged.disconnect(self.on_preferences_edited)
+                except (TypeError, AttributeError):
+                    pass
+
+        # Prompt user to save
+        if self.preferences_changed_flag is True:
+            msgbox = QtWidgets.QMessageBox()
+            msgbox.setText(_("One or more values are changed.\n"
+                             "Do you want to save the Preferences?"))
+            msgbox.setWindowTitle(_("Save Preferences"))
+            msgbox.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/save_as.png'))
+
+            bt_yes = msgbox.addButton(_('Yes'), QtWidgets.QMessageBox.YesRole)
+            msgbox.addButton(_('No'), QtWidgets.QMessageBox.NoRole)
+
+            msgbox.setDefaultButton(bt_yes)
+            msgbox.exec_()
+            response = msgbox.clickedButton()
+
+            if response == bt_yes:
+                self.on_save_button(save_to_file=True)
+                self.inform.emit('[success] %s' % _("Preferences saved."))
+            else:
+                self.preferences_changed_flag = False
+                self.inform.emit('')
+                return
+
 
 
 class OptionsGroupUI(QtWidgets.QGroupBox):
 class OptionsGroupUI(QtWidgets.QGroupBox):
     app = None
     app = None
@@ -1954,7 +2063,7 @@ class GeneralGUIPrefGroupUI(OptionsGroupUI):
         :param lay:     Type of layout to be set on the toolbard
         :param lay:     Type of layout to be set on the toolbard
         :return:        None
         :return:        None
         """
         """
-        self.app.report_usage("on_layout()")
+        self.app.defaults.report_usage("on_layout()")
         if lay:
         if lay:
             current_layout = lay
             current_layout = lay
         else:
         else:
@@ -3158,7 +3267,7 @@ class GerberGenPrefGroupUI(OptionsGroupUI):
     def on_pl_color_entry(self):
     def on_pl_color_entry(self):
         self.app.defaults['gerber_plot_line'] = self.pl_color_entry.get_value()[:7] + \
         self.app.defaults['gerber_plot_line'] = self.pl_color_entry.get_value()[:7] + \
                                                 self.app.defaults['gerber_plot_line'][7:9]
                                                 self.app.defaults['gerber_plot_line'][7:9]
-        self.pl_color_button.setStyleSheet("background-color:%s" % str(self.defaults['gerber_plot_line'])[:7])
+        self.pl_color_button.setStyleSheet("background-color:%s" % str(self.app.defaults['gerber_plot_line'])[:7])
 
 
     def on_pl_color_button(self):
     def on_pl_color_button(self):
         current_color = QtGui.QColor(self.app.defaults['gerber_plot_line'][:7])
         current_color = QtGui.QColor(self.app.defaults['gerber_plot_line'][:7])

+ 1 - 1
flatcamObjects/FlatCAMCNCJob.py

@@ -487,7 +487,7 @@ class CNCJobObject(FlatCAMObj, CNCjob):
         :param args:
         :param args:
         :return:
         :return:
         """
         """
-        self.app.report_usage("cncjob_on_exportgcode_button")
+        self.app.defaults.report_usage("cncjob_on_exportgcode_button")
 
 
         self.read_form()
         self.read_form()
         name = self.app.collection.get_active().options['name']
         name = self.app.collection.get_active().options['name']

+ 3 - 3
flatcamObjects/FlatCAMExcellon.py

@@ -1234,13 +1234,13 @@ class ExcellonObject(FlatCAMObj, Excellon):
         return True, ""
         return True, ""
 
 
     def on_generate_milling_button_click(self, *args):
     def on_generate_milling_button_click(self, *args):
-        self.app.report_usage("excellon_on_create_milling_drills button")
+        self.app.defaults.report_usage("excellon_on_create_milling_drills button")
         self.read_form()
         self.read_form()
 
 
         self.generate_milling_drills(use_thread=False)
         self.generate_milling_drills(use_thread=False)
 
 
     def on_generate_milling_slots_button_click(self, *args):
     def on_generate_milling_slots_button_click(self, *args):
-        self.app.report_usage("excellon_on_create_milling_slots_button")
+        self.app.defaults.report_usage("excellon_on_create_milling_slots_button")
         self.read_form()
         self.read_form()
 
 
         self.generate_milling_slots(use_thread=False)
         self.generate_milling_slots(use_thread=False)
@@ -1338,7 +1338,7 @@ class ExcellonObject(FlatCAMObj, Excellon):
                 pass
                 pass
 
 
     def on_create_cncjob_button_click(self, *args):
     def on_create_cncjob_button_click(self, *args):
-        self.app.report_usage("excellon_on_create_cncjob_button")
+        self.app.defaults.report_usage("excellon_on_create_cncjob_button")
         self.read_form()
         self.read_form()
 
 
         # Get the tools from the list
         # Get the tools from the list

+ 1 - 1
flatcamObjects/FlatCAMGeometry.py

@@ -1575,7 +1575,7 @@ class GeometryObject(FlatCAMObj, Geometry):
 
 
     def on_generatecnc_button_click(self, *args):
     def on_generatecnc_button_click(self, *args):
         log.debug("Generating CNCJob from Geometry ...")
         log.debug("Generating CNCJob from Geometry ...")
-        self.app.report_usage("geometry_on_generatecnc_button")
+        self.app.defaults.report_usage("geometry_on_generatecnc_button")
 
 
         # this reads the values in the UI form to the self.options dictionary
         # this reads the values in the UI form to the self.options dictionary
         self.read_form()
         self.read_form()

+ 3 - 3
flatcamObjects/FlatCAMGerber.py

@@ -505,7 +505,7 @@ class GerberObject(FlatCAMObj, Gerber):
         self.app.worker_task.emit({'fcn': buffer_task, 'params': []})
         self.app.worker_task.emit({'fcn': buffer_task, 'params': []})
 
 
     def on_generatenoncopper_button_click(self, *args):
     def on_generatenoncopper_button_click(self, *args):
-        self.app.report_usage("gerber_on_generatenoncopper_button")
+        self.app.defaults.report_usage("gerber_on_generatenoncopper_button")
 
 
         self.read_form()
         self.read_form()
         name = self.options["name"] + "_noncopper"
         name = self.options["name"] + "_noncopper"
@@ -532,7 +532,7 @@ class GerberObject(FlatCAMObj, Gerber):
         self.app.new_object("geometry", name, geo_init)
         self.app.new_object("geometry", name, geo_init)
 
 
     def on_generatebb_button_click(self, *args):
     def on_generatebb_button_click(self, *args):
-        self.app.report_usage("gerber_on_generatebb_button")
+        self.app.defaults.report_usage("gerber_on_generatebb_button")
         self.read_form()
         self.read_form()
         name = self.options["name"] + "_bbox"
         name = self.options["name"] + "_bbox"
 
 
@@ -574,7 +574,7 @@ class GerberObject(FlatCAMObj, Gerber):
                     # in the end toggle the visibility of the origin object so we can see the generated Geometry
                     # in the end toggle the visibility of the origin object so we can see the generated Geometry
                     iso_obj.ui.plot_cb.toggle()
                     iso_obj.ui.plot_cb.toggle()
                 else:
                 else:
-                    app_obj.report_usage("gerber_on_iso_button")
+                    app_obj.defaults.report_usage("gerber_on_iso_button")
                     self.read_form()
                     self.read_form()
 
 
                     iso_scope = 'all' if self.ui.iso_scope_radio.get_value() == 'all' else 'single'
                     iso_scope = 'all' if self.ui.iso_scope_radio.get_value() == 'all' else 'single'

+ 2 - 2
flatcamObjects/FlatCAMObj.py

@@ -236,7 +236,7 @@ class FlatCAMObj(QtCore.QObject):
                                      )
                                      )
 
 
     def on_offset_button_click(self):
     def on_offset_button_click(self):
-        self.app.report_usage("obj_on_offset_button")
+        self.app.defaults.report_usage("obj_on_offset_button")
 
 
         self.read_form()
         self.read_form()
         vector_val = self.ui.offsetvector_entry.get_value()
         vector_val = self.ui.offsetvector_entry.get_value()
@@ -283,7 +283,7 @@ class FlatCAMObj(QtCore.QObject):
         self.app.worker_task.emit({'fcn': worker_task, 'params': []})
         self.app.worker_task.emit({'fcn': worker_task, 'params': []})
 
 
     def on_skew_button_click(self):
     def on_skew_button_click(self):
-        self.app.report_usage("obj_on_skew_button")
+        self.app.defaults.report_usage("obj_on_skew_button")
         self.read_form()
         self.read_form()
         x_angle = self.ui.xangle_entry.get_value()
         x_angle = self.ui.xangle_entry.get_value()
         y_angle = self.ui.yangle_entry.get_value()
         y_angle = self.ui.yangle_entry.get_value()

+ 1 - 1
flatcamTools/ToolAlignObjects.py

@@ -217,7 +217,7 @@ class AlignObjects(FlatCAMTool):
         self.aligned_old_line_color = None
         self.aligned_old_line_color = None
 
 
     def run(self, toggle=True):
     def run(self, toggle=True):
-        self.app.report_usage("ToolAlignObjects()")
+        self.app.defaults.report_usage("ToolAlignObjects()")
 
 
         if toggle:
         if toggle:
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same

+ 1 - 1
flatcamTools/ToolCalculators.py

@@ -271,7 +271,7 @@ class ToolCalculator(FlatCAMTool):
         self.reset_button.clicked.connect(self.set_tool_ui)
         self.reset_button.clicked.connect(self.set_tool_ui)
 
 
     def run(self, toggle=True):
     def run(self, toggle=True):
-        self.app.report_usage("ToolCalculators()")
+        self.app.defaults.report_usage("ToolCalculators()")
 
 
         if toggle:
         if toggle:
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same

+ 1 - 1
flatcamTools/ToolCalibration.py

@@ -731,7 +731,7 @@ class ToolCalibration(FlatCAMTool):
         self.reset_button.clicked.connect(self.set_tool_ui)
         self.reset_button.clicked.connect(self.set_tool_ui)
 
 
     def run(self, toggle=True):
     def run(self, toggle=True):
-        self.app.report_usage("ToolCalibration()")
+        self.app.defaults.report_usage("ToolCalibration()")
 
 
         if toggle:
         if toggle:
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same

+ 1 - 1
flatcamTools/ToolCopperThieving.py

@@ -540,7 +540,7 @@ class ToolCopperThieving(FlatCAMTool):
         self.work_finished.connect(self.on_new_pattern_plating_object)
         self.work_finished.connect(self.on_new_pattern_plating_object)
 
 
     def run(self, toggle=True):
     def run(self, toggle=True):
-        self.app.report_usage("ToolCopperThieving()")
+        self.app.defaults.report_usage("ToolCopperThieving()")
 
 
         if toggle:
         if toggle:
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same

+ 1 - 1
flatcamTools/ToolCutOut.py

@@ -419,7 +419,7 @@ class CutOut(FlatCAMTool):
         self.obj_combo.obj_type = {"grb": "Gerber", "geo": "Geometry"}[val]
         self.obj_combo.obj_type = {"grb": "Gerber", "geo": "Geometry"}[val]
 
 
     def run(self, toggle=True):
     def run(self, toggle=True):
-        self.app.report_usage("ToolCutOut()")
+        self.app.defaults.report_usage("ToolCutOut()")
 
 
         if toggle:
         if toggle:
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same

+ 1 - 1
flatcamTools/ToolDblSided.py

@@ -514,7 +514,7 @@ class DblSidedTool(FlatCAMTool):
         FlatCAMTool.install(self, icon, separator, shortcut='Alt+D', **kwargs)
         FlatCAMTool.install(self, icon, separator, shortcut='Alt+D', **kwargs)
 
 
     def run(self, toggle=True):
     def run(self, toggle=True):
-        self.app.report_usage("Tool2Sided()")
+        self.app.defaults.report_usage("Tool2Sided()")
 
 
         if toggle:
         if toggle:
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same

+ 1 - 1
flatcamTools/ToolDistance.py

@@ -180,7 +180,7 @@ class Distance(FlatCAMTool):
         self.measure_btn.clicked.connect(self.activate_measure_tool)
         self.measure_btn.clicked.connect(self.activate_measure_tool)
 
 
     def run(self, toggle=False):
     def run(self, toggle=False):
-        self.app.report_usage("ToolDistance()")
+        self.app.defaults.report_usage("ToolDistance()")
 
 
         self.points[:] = []
         self.points[:] = []
 
 

+ 1 - 1
flatcamTools/ToolDistanceMin.py

@@ -136,7 +136,7 @@ class DistanceMin(FlatCAMTool):
         self.jump_hp_btn.clicked.connect(self.on_jump_to_half_point)
         self.jump_hp_btn.clicked.connect(self.on_jump_to_half_point)
 
 
     def run(self, toggle=False):
     def run(self, toggle=False):
-        self.app.report_usage("ToolDistanceMin()")
+        self.app.defaults.report_usage("ToolDistanceMin()")
 
 
         if self.app.tool_tab_locked is True:
         if self.app.tool_tab_locked is True:
             return
             return

+ 1 - 1
flatcamTools/ToolExtractDrills.py

@@ -366,7 +366,7 @@ class ToolExtractDrills(FlatCAMTool):
         FlatCAMTool.install(self, icon, separator, shortcut='Alt+I', **kwargs)
         FlatCAMTool.install(self, icon, separator, shortcut='Alt+I', **kwargs)
 
 
     def run(self, toggle=True):
     def run(self, toggle=True):
-        self.app.report_usage("Extract Drills()")
+        self.app.defaults.report_usage("Extract Drills()")
 
 
         if toggle:
         if toggle:
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same

+ 1 - 1
flatcamTools/ToolFiducials.py

@@ -367,7 +367,7 @@ class ToolFiducials(FlatCAMTool):
         self.reset_button.clicked.connect(self.set_tool_ui)
         self.reset_button.clicked.connect(self.set_tool_ui)
 
 
     def run(self, toggle=True):
     def run(self, toggle=True):
-        self.app.report_usage("ToolFiducials()")
+        self.app.defaults.report_usage("ToolFiducials()")
 
 
         if toggle:
         if toggle:
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same

+ 3 - 3
flatcamTools/ToolFilm.py

@@ -558,7 +558,7 @@ class Film(FlatCAMTool):
         }[self.tf_type_obj_combo.get_value()]
         }[self.tf_type_obj_combo.get_value()]
 
 
     def run(self, toggle=True):
     def run(self, toggle=True):
-        self.app.report_usage("ToolFilm()")
+        self.app.defaults.report_usage("ToolFilm()")
 
 
         if toggle:
         if toggle:
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same
@@ -933,7 +933,7 @@ class Film(FlatCAMTool):
         :param ftype: the type of file for saving the film: 'svg', 'png' or 'pdf'
         :param ftype: the type of file for saving the film: 'svg', 'png' or 'pdf'
         :return:
         :return:
         """
         """
-        self.app.report_usage("export_negative()")
+        self.app.defaults.report_usage("export_negative()")
 
 
         if filename is None:
         if filename is None:
             filename = self.app.defaults["global_last_save_folder"]
             filename = self.app.defaults["global_last_save_folder"]
@@ -1116,7 +1116,7 @@ class Film(FlatCAMTool):
 
 
         :return:
         :return:
         """
         """
-        self.app.report_usage("export_positive()")
+        self.app.defaults.report_usage("export_positive()")
 
 
         if filename is None:
         if filename is None:
             filename = self.app.defaults["global_last_save_folder"]
             filename = self.app.defaults["global_last_save_folder"]

+ 2 - 2
flatcamTools/ToolImage.py

@@ -155,7 +155,7 @@ class ToolImage(FlatCAMTool):
         self.image_type.activated_custom.connect(self.on_image_type)
         self.image_type.activated_custom.connect(self.on_image_type)
 
 
     def run(self, toggle=True):
     def run(self, toggle=True):
-        self.app.report_usage("ToolImage()")
+        self.app.defaults.report_usage("ToolImage()")
 
 
         if toggle:
         if toggle:
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same
@@ -263,7 +263,7 @@ class ToolImage(FlatCAMTool):
         :return:
         :return:
         """
         """
 
 
-        self.app.report_usage("import_image()")
+        self.app.defaults.report_usage("import_image()")
 
 
         if mask is None:
         if mask is None:
             mask = [250, 250, 250, 250]
             mask = [250, 250, 250, 250]

+ 1 - 1
flatcamTools/ToolInvertGerber.py

@@ -156,7 +156,7 @@ class ToolInvertGerber(FlatCAMTool):
         FlatCAMTool.install(self, icon, separator, shortcut='', **kwargs)
         FlatCAMTool.install(self, icon, separator, shortcut='', **kwargs)
 
 
     def run(self, toggle=True):
     def run(self, toggle=True):
-        self.app.report_usage("ToolInvertGerber()")
+        self.app.defaults.report_usage("ToolInvertGerber()")
         log.debug("ToolInvertGerber() is running ...")
         log.debug("ToolInvertGerber() is running ...")
 
 
         if toggle:
         if toggle:

+ 1 - 1
flatcamTools/ToolMove.py

@@ -63,7 +63,7 @@ class ToolMove(FlatCAMTool):
         FlatCAMTool.install(self, icon, separator, shortcut='M', **kwargs)
         FlatCAMTool.install(self, icon, separator, shortcut='M', **kwargs)
 
 
     def run(self, toggle):
     def run(self, toggle):
-        self.app.report_usage("ToolMove()")
+        self.app.defaults.report_usage("ToolMove()")
 
 
         if self.app.tool_tab_locked is True:
         if self.app.tool_tab_locked is True:
             return
             return

+ 2 - 2
flatcamTools/ToolNCC.py

@@ -939,7 +939,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
         FlatCAMTool.install(self, icon, separator, shortcut='Alt+N', **kwargs)
         FlatCAMTool.install(self, icon, separator, shortcut='Alt+N', **kwargs)
 
 
     def run(self, toggle=True):
     def run(self, toggle=True):
-        self.app.report_usage("ToolNonCopperClear()")
+        self.app.defaults.report_usage("ToolNonCopperClear()")
         log.debug("ToolNCC().run() was launched ...")
         log.debug("ToolNCC().run() was launched ...")
 
 
         if toggle:
         if toggle:
@@ -1582,7 +1582,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
         # init values for the next usage
         # init values for the next usage
         self.reset_usage()
         self.reset_usage()
 
 
-        self.app.report_usage("on_paint_button_click")
+        self.app.defaults.report_usage("on_paint_button_click")
 
 
         self.grb_circle_steps = int(self.app.defaults["gerber_circle_steps"])
         self.grb_circle_steps = int(self.app.defaults["gerber_circle_steps"])
         self.obj_name = self.object_combo.currentText()
         self.obj_name = self.object_combo.currentText()

+ 1 - 1
flatcamTools/ToolOptimal.py

@@ -280,7 +280,7 @@ class ToolOptimal(FlatCAMTool):
         FlatCAMTool.install(self, icon, separator, shortcut='Alt+O', **kwargs)
         FlatCAMTool.install(self, icon, separator, shortcut='Alt+O', **kwargs)
 
 
     def run(self, toggle=True):
     def run(self, toggle=True):
-        self.app.report_usage("ToolOptimal()")
+        self.app.defaults.report_usage("ToolOptimal()")
 
 
         if toggle:
         if toggle:
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same

+ 2 - 2
flatcamTools/ToolPDF.py

@@ -129,7 +129,7 @@ class ToolPDF(FlatCAMTool):
         self.point_to_unit_factor = 0.01388888888
         self.point_to_unit_factor = 0.01388888888
 
 
     def run(self, toggle=True):
     def run(self, toggle=True):
-        self.app.report_usage("ToolPDF()")
+        self.app.defaults.report_usage("ToolPDF()")
 
 
         self.set_tool_ui()
         self.set_tool_ui()
         self.on_open_pdf_click()
         self.on_open_pdf_click()
@@ -147,7 +147,7 @@ class ToolPDF(FlatCAMTool):
         :return: None
         :return: None
         """
         """
 
 
-        self.app.report_usage("ToolPDF.on_open_pdf_click()")
+        self.app.defaults.report_usage("ToolPDF.on_open_pdf_click()")
         self.app.log.debug("ToolPDF.on_open_pdf_click()")
         self.app.log.debug("ToolPDF.on_open_pdf_click()")
 
 
         _filter_ = "Adobe PDF Files (*.pdf);;" \
         _filter_ = "Adobe PDF Files (*.pdf);;" \

+ 2 - 2
flatcamTools/ToolPaint.py

@@ -710,7 +710,7 @@ class ToolPaint(FlatCAMTool, Gerber):
         FlatCAMTool.install(self, icon, separator, shortcut='Alt+P', **kwargs)
         FlatCAMTool.install(self, icon, separator, shortcut='Alt+P', **kwargs)
 
 
     def run(self, toggle=True):
     def run(self, toggle=True):
-        self.app.report_usage("ToolPaint()")
+        self.app.defaults.report_usage("ToolPaint()")
         log.debug("ToolPaint().run() was launched ...")
         log.debug("ToolPaint().run() was launched ...")
 
 
         if toggle:
         if toggle:
@@ -1374,7 +1374,7 @@ class ToolPaint(FlatCAMTool, Gerber):
         # init values for the next usage
         # init values for the next usage
         self.reset_usage()
         self.reset_usage()
 
 
-        self.app.report_usage("on_paint_button_click")
+        self.app.defaults.report_usage("on_paint_button_click")
         # self.app.call_source = 'paint'
         # self.app.call_source = 'paint'
 
 
         self.select_method = self.selectmethod_combo.get_value()
         self.select_method = self.selectmethod_combo.get_value()

+ 1 - 1
flatcamTools/ToolPanelize.py

@@ -293,7 +293,7 @@ class Panelize(FlatCAMTool):
         self.constrain_flag = False
         self.constrain_flag = False
 
 
     def run(self, toggle=True):
     def run(self, toggle=True):
-        self.app.report_usage("ToolPanelize()")
+        self.app.defaults.report_usage("ToolPanelize()")
 
 
         if toggle:
         if toggle:
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same

+ 1 - 1
flatcamTools/ToolPcbWizard.py

@@ -170,7 +170,7 @@ class PcbWizard(FlatCAMTool):
         self.tools_from_inf = {}
         self.tools_from_inf = {}
 
 
     def run(self, toggle=False):
     def run(self, toggle=False):
-        self.app.report_usage("PcbWizard Tool()")
+        self.app.defaults.report_usage("PcbWizard Tool()")
 
 
         if toggle:
         if toggle:
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same

+ 1 - 1
flatcamTools/ToolProperties.py

@@ -73,7 +73,7 @@ class Properties(FlatCAMTool):
         self.calculations_finished.connect(self.show_area_chull)
         self.calculations_finished.connect(self.show_area_chull)
 
 
     def run(self, toggle=True):
     def run(self, toggle=True):
-        self.app.report_usage("ToolProperties()")
+        self.app.defaults.report_usage("ToolProperties()")
 
 
         if self.app.tool_tab_locked is True:
         if self.app.tool_tab_locked is True:
             return
             return

+ 1 - 1
flatcamTools/ToolPunchGerber.py

@@ -397,7 +397,7 @@ class ToolPunchGerber(FlatCAMTool):
         )
         )
 
 
     def run(self, toggle=True):
     def run(self, toggle=True):
-        self.app.report_usage("ToolPunchGerber()")
+        self.app.defaults.report_usage("ToolPunchGerber()")
 
 
         if toggle:
         if toggle:
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same

+ 1 - 1
flatcamTools/ToolQRCode.py

@@ -354,7 +354,7 @@ class QRCode(FlatCAMTool):
         self.reset_button.clicked.connect(self.set_tool_ui)
         self.reset_button.clicked.connect(self.set_tool_ui)
 
 
     def run(self, toggle=True):
     def run(self, toggle=True):
-        self.app.report_usage("QRCode()")
+        self.app.defaults.report_usage("QRCode()")
 
 
         if toggle:
         if toggle:
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same

+ 1 - 1
flatcamTools/ToolRulesCheck.py

@@ -589,7 +589,7 @@ class RulesCheck(FlatCAMTool):
                 cb.setChecked(False)
                 cb.setChecked(False)
 
 
     def run(self, toggle=True):
     def run(self, toggle=True):
-        self.app.report_usage("ToolRulesCheck()")
+        self.app.defaults.report_usage("ToolRulesCheck()")
 
 
         if toggle:
         if toggle:
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same

+ 1 - 1
flatcamTools/ToolShell.py

@@ -370,7 +370,7 @@ class FCShell(TermWidget):
         :return: output if there was any
         :return: output if there was any
         """
         """
 
 
-        self.app.report_usage('exec_command')
+        self.app.defaults.report_usage('exec_command')
 
 
         return self.exec_command_test(text, False, no_echo=no_echo)
         return self.exec_command_test(text, False, no_echo=no_echo)
 
 

+ 1 - 1
flatcamTools/ToolSolderPaste.py

@@ -525,7 +525,7 @@ class SolderPaste(FlatCAMTool):
         self.reset_button.clicked.connect(self.set_tool_ui)
         self.reset_button.clicked.connect(self.set_tool_ui)
 
 
     def run(self, toggle=True):
     def run(self, toggle=True):
-        self.app.report_usage("ToolSolderPaste()")
+        self.app.defaults.report_usage("ToolSolderPaste()")
 
 
         if toggle:
         if toggle:
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same

+ 1 - 1
flatcamTools/ToolSub.py

@@ -236,7 +236,7 @@ class ToolSub(FlatCAMTool):
         FlatCAMTool.install(self, icon, separator, shortcut='Alt+W', **kwargs)
         FlatCAMTool.install(self, icon, separator, shortcut='Alt+W', **kwargs)
 
 
     def run(self, toggle=True):
     def run(self, toggle=True):
-        self.app.report_usage("ToolSub()")
+        self.app.defaults.report_usage("ToolSub()")
 
 
         if toggle:
         if toggle:
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same

+ 1 - 1
flatcamTools/ToolTransform.py

@@ -433,7 +433,7 @@ class ToolTransform(FlatCAMTool):
         # self.buffer_entry.returnPressed.connect(self.on_buffer_by_distance)
         # self.buffer_entry.returnPressed.connect(self.on_buffer_by_distance)
 
 
     def run(self, toggle=True):
     def run(self, toggle=True):
-        self.app.report_usage("ToolTransform()")
+        self.app.defaults.report_usage("ToolTransform()")
 
 
         if toggle:
         if toggle:
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same