Pārlūkot izejas kodu

- moved all the new_object related methods in their own class AppObjects.AppObject

Marius Stanciu 5 gadi atpakaļ
vecāks
revīzija
2bcdeff7ef
55 mainītis faili ar 579 papildinājumiem un 554 dzēšanām
  1. 2 2
      AppEditors/FlatCAMExcEditor.py
  2. 1 1
      AppEditors/FlatCAMGeoEditor.py
  3. 2 2
      AppEditors/FlatCAMGrbEditor.py
  4. 3 3
      AppGUI/MainGUI.py
  5. 3 3
      AppGUI/PlotCanvasLegacy.py
  6. 1 1
      AppGUI/preferences/PreferencesUIManager.py
  7. 56 422
      AppMain.py
  8. 393 0
      AppObjects/AppObject.py
  9. 9 9
      AppObjects/FlatCAMExcellon.py
  10. 12 12
      AppObjects/FlatCAMGeometry.py
  11. 5 5
      AppObjects/FlatCAMGerber.py
  12. 4 4
      AppObjects/FlatCAMObj.py
  13. 1 1
      AppObjects/ObjectCollection.py
  14. 1 1
      AppParsers/ParseExcellon.py
  15. 1 1
      AppTool.py
  16. 3 3
      AppTools/ToolCalibration.py
  17. 1 1
      AppTools/ToolCopperThieving.py
  18. 3 3
      AppTools/ToolCutOut.py
  19. 4 4
      AppTools/ToolDblSided.py
  20. 1 1
      AppTools/ToolExtractDrills.py
  21. 2 2
      AppTools/ToolFilm.py
  22. 1 1
      AppTools/ToolImage.py
  23. 1 1
      AppTools/ToolInvertGerber.py
  24. 5 5
      AppTools/ToolNCC.py
  25. 2 2
      AppTools/ToolPDF.py
  26. 5 5
      AppTools/ToolPaint.py
  27. 2 2
      AppTools/ToolPanelize.py
  28. 1 1
      AppTools/ToolPcbWizard.py
  29. 4 4
      AppTools/ToolPunchGerber.py
  30. 1 1
      AppTools/ToolRulesCheck.py
  31. 6 6
      AppTools/ToolSolderPaste.py
  32. 2 2
      AppTools/ToolSub.py
  33. 6 6
      AppTools/ToolTransform.py
  34. 2 1
      CHANGELOG.md
  35. 1 1
      FlatCAM.py
  36. 2 2
      tclCommands/TclCommand.py
  37. 2 2
      tclCommands/TclCommandAlignDrill.py
  38. 1 1
      tclCommands/TclCommandAlignDrillGrid.py
  39. 1 1
      tclCommands/TclCommandBbox.py
  40. 1 1
      tclCommands/TclCommandCutout.py
  41. 1 1
      tclCommands/TclCommandDrillcncjob.py
  42. 1 1
      tclCommands/TclCommandExteriors.py
  43. 2 5
      tclCommands/TclCommandGeoCutout.py
  44. 1 1
      tclCommands/TclCommandImportSvg.py
  45. 1 1
      tclCommands/TclCommandInteriors.py
  46. 1 1
      tclCommands/TclCommandJoinExcellon.py
  47. 1 1
      tclCommands/TclCommandJoinGeometry.py
  48. 1 1
      tclCommands/TclCommandNewExcellon.py
  49. 1 1
      tclCommands/TclCommandNewGeometry.py
  50. 1 1
      tclCommands/TclCommandNewGerber.py
  51. 1 1
      tclCommands/TclCommandNregions.py
  52. 2 2
      tclCommands/TclCommandOpenDXF.py
  53. 2 2
      tclCommands/TclCommandOpenSVG.py
  54. 6 6
      tclCommands/TclCommandPanelize.py
  55. 3 3
      tclCommands/TclCommandWriteGCode.py

+ 2 - 2
AppEditors/FlatCAMExcEditor.py

@@ -2239,7 +2239,7 @@ class FlatCAMExcEditor(QtCore.QObject):
 
 
         # store the status of the editor so the Delete at object level will not work until the edit is finished
         # store the status of the editor so the Delete at object level will not work until the edit is finished
         self.editor_active = False
         self.editor_active = False
-        log.debug("Initialization of the FlatCAM Excellon Editor is finished ...")
+        log.debug("Initialization of the Excellon Editor is finished ...")
 
 
     def pool_recreated(self, pool):
     def pool_recreated(self, pool):
         self.shapes.pool = pool
         self.shapes.pool = pool
@@ -3336,7 +3336,7 @@ class FlatCAMExcEditor(QtCore.QObject):
         with self.app.proc_container.new(_("Creating Excellon.")):
         with self.app.proc_container.new(_("Creating Excellon.")):
 
 
             try:
             try:
-                edited_obj = self.app.new_object("excellon", outname, obj_init)
+                edited_obj = self.app.app_obj.new_object("excellon", outname, obj_init)
                 edited_obj.source_file = self.app.export_excellon(obj_name=edited_obj.options['name'],
                 edited_obj.source_file = self.app.export_excellon(obj_name=edited_obj.options['name'],
                                                                   local_use=edited_obj,
                                                                   local_use=edited_obj,
                                                                   filename=None,
                                                                   filename=None,

+ 1 - 1
AppEditors/FlatCAMGeoEditor.py

@@ -3552,7 +3552,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
 
 
         # store the status of the editor so the Delete at object level will not work until the edit is finished
         # store the status of the editor so the Delete at object level will not work until the edit is finished
         self.editor_active = False
         self.editor_active = False
-        log.debug("Initialization of the FlatCAM Geometry Editor is finished ...")
+        log.debug("Initialization of the Geometry Editor is finished ...")
 
 
     def pool_recreated(self, pool):
     def pool_recreated(self, pool):
         self.shapes.pool = pool
         self.shapes.pool = pool

+ 2 - 2
AppEditors/FlatCAMGrbEditor.py

@@ -3110,7 +3110,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
         self.complete = True
         self.complete = True
 
 
         self.set_ui()
         self.set_ui()
-        log.debug("Initialization of the FlatCAM Gerber Editor is finished ...")
+        log.debug("Initialization of the Gerber Editor is finished ...")
 
 
     def pool_recreated(self, pool):
     def pool_recreated(self, pool):
         self.shapes.pool = pool
         self.shapes.pool = pool
@@ -4346,7 +4346,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
 
 
         with self.app.proc_container.new(_("Creating Gerber.")):
         with self.app.proc_container.new(_("Creating Gerber.")):
             try:
             try:
-                self.app.new_object("gerber", outname, obj_init)
+                self.app.app_obj.new_object("gerber", outname, obj_init)
             except Exception as e:
             except Exception as e:
                 log.error("Error on Edited object creation: %s" % str(e))
                 log.error("Error on Edited object creation: %s" % str(e))
                 # make sure to clean the previous results
                 # make sure to clean the previous results

+ 3 - 3
AppGUI/MainGUI.py

@@ -2477,7 +2477,7 @@ class MainGUI(QtWidgets.QMainWindow):
 
 
                 # New Geometry
                 # New Geometry
                 if key == QtCore.Qt.Key_B:
                 if key == QtCore.Qt.Key_B:
-                    self.app.new_gerber_object()
+                    self.app.app_obj.new_gerber_object()
 
 
                 # New Geometry
                 # New Geometry
                 if key == QtCore.Qt.Key_D:
                 if key == QtCore.Qt.Key_D:
@@ -2497,7 +2497,7 @@ class MainGUI(QtWidgets.QMainWindow):
 
 
                 # New Excellon
                 # New Excellon
                 if key == QtCore.Qt.Key_L:
                 if key == QtCore.Qt.Key_L:
-                    self.app.new_excellon_object()
+                    self.app.app_obj.new_excellon_object()
 
 
                 # Move tool toggle
                 # Move tool toggle
                 if key == QtCore.Qt.Key_M:
                 if key == QtCore.Qt.Key_M:
@@ -2505,7 +2505,7 @@ class MainGUI(QtWidgets.QMainWindow):
 
 
                 # New Geometry
                 # New Geometry
                 if key == QtCore.Qt.Key_N:
                 if key == QtCore.Qt.Key_N:
-                    self.app.new_geometry_object()
+                    self.app.app_obj.new_geometry_object()
 
 
                 # Set Origin
                 # Set Origin
                 if key == QtCore.Qt.Key_O:
                 if key == QtCore.Qt.Key_O:

+ 3 - 3
AppGUI/PlotCanvasLegacy.py

@@ -48,9 +48,9 @@ class CanvasCache(QtCore.QObject):
     Case story #1:
     Case story #1:
 
 
     1) No objects in the project.
     1) No objects in the project.
-    2) Object is created (new_object() emits object_created(obj)).
+    2) Object is created (app_obj.new_object() emits object_created(obj)).
        on_object_created() adds (i) object to collection and emits
        on_object_created() adds (i) object to collection and emits
-       (ii) new_object_available() then calls (iii) object.plot()
+       (ii) app_obj.new_object_available() then calls (iii) object.plot()
     3) object.plot() creates axes if necessary on
     3) object.plot() creates axes if necessary on
        app.collection.figure. Then plots on it.
        app.collection.figure. Then plots on it.
     4) Plots on a cache-size canvas (in background).
     4) Plots on a cache-size canvas (in background).
@@ -116,7 +116,7 @@ class CanvasCache(QtCore.QObject):
 
 
         # Continue to update the cache.
         # Continue to update the cache.
 
 
-    # def on_new_object_available(self):
+    # def on_app_obj.new_object_available(self):
     #
     #
     #     log.debug("A new object is available. Should plot it!")
     #     log.debug("A new object is available. Should plot it!")
 
 

+ 1 - 1
AppGUI/preferences/PreferencesUIManager.py

@@ -43,7 +43,7 @@ class PreferencesUIManager:
         self.preferences_changed_flag = False
         self.preferences_changed_flag = False
 
 
         # when adding entries here read the comments in the  method found below named:
         # when adding entries here read the comments in the  method found below named:
-        # def new_object(self, kind, name, initialize, active=True, fit=True, plot=True)
+        # def app_obj.new_object(self, kind, name, initialize, active=True, fit=True, plot=True)
         self.defaults_form_fields = {
         self.defaults_form_fields = {
             # General App
             # General App
             "decimals_inch": self.ui.general_defaults_form.general_app_group.precision_inch_entry,
             "decimals_inch": self.ui.general_defaults_form.general_app_group.precision_inch_entry,

+ 56 - 422
App.py → AppMain.py

@@ -4,6 +4,7 @@
 # Author: Juan Pablo Caram (c)                              #
 # Author: Juan Pablo Caram (c)                              #
 # Date: 2/5/2014                                            #
 # Date: 2/5/2014                                            #
 # MIT Licence                                               #
 # MIT Licence                                               #
+# Modified by Marius Stanciu (2019)                         #
 # ###########################################################
 # ###########################################################
 
 
 import urllib.request
 import urllib.request
@@ -55,12 +56,7 @@ from AppGUI.preferences.OptionsGroupUI import OptionsGroupUI
 from AppGUI.preferences.PreferencesUIManager import PreferencesUIManager
 from AppGUI.preferences.PreferencesUIManager import PreferencesUIManager
 from AppObjects.ObjectCollection import *
 from AppObjects.ObjectCollection import *
 from AppObjects.FlatCAMObj import FlatCAMObj
 from AppObjects.FlatCAMObj import FlatCAMObj
-from AppObjects.FlatCAMCNCJob import CNCJobObject
-from AppObjects.FlatCAMDocument import DocumentObject
-from AppObjects.FlatCAMExcellon import ExcellonObject
-from AppObjects.FlatCAMGeometry import GeometryObject
-from AppObjects.FlatCAMGerber import GerberObject
-from AppObjects.FlatCAMScript import ScriptObject
+from AppObjects.AppObject import AppObject
 
 
 # FlatCAM Parsing files
 # FlatCAM Parsing files
 from AppParsers.ParseExcellon import Excellon
 from AppParsers.ParseExcellon import Excellon
@@ -226,20 +222,6 @@ class App(QtCore.QObject):
     # Percentage of progress
     # Percentage of progress
     progress = QtCore.pyqtSignal(int)
     progress = QtCore.pyqtSignal(int)
 
 
-    plots_updated = QtCore.pyqtSignal()
-
-    # Emitted by new_object() and passes the new object as argument, plot flag.
-    # on_object_created() adds the object to the collection, plots on appropriate flag
-    # and emits new_object_available.
-    object_created = QtCore.pyqtSignal(object, bool, bool)
-
-    # Emitted when a object has been changed (like scaled, mirrored)
-    object_changed = QtCore.pyqtSignal(object)
-
-    # Emitted after object has been plotted.
-    # Calls 'on_zoom_fit' method to fit object in scene view in main thread to prevent drawing glitches.
-    object_plotted = QtCore.pyqtSignal(object)
-
     # Emitted when a new object has been added or deleted from/to the collection
     # Emitted when a new object has been added or deleted from/to the collection
     object_status_changed = QtCore.pyqtSignal(object, str, str)
     object_status_changed = QtCore.pyqtSignal(object, str, str)
 
 
@@ -674,9 +656,11 @@ class App(QtCore.QObject):
         # #################################### SETUP OBJECT COLLECTION ##############################################
         # #################################### SETUP OBJECT COLLECTION ##############################################
         # ###########################################################################################################
         # ###########################################################################################################
 
 
-        self.collection = ObjectCollection(self)
+        self.collection = ObjectCollection(app=self)
         self.ui.project_tab_layout.addWidget(self.collection.view)
         self.ui.project_tab_layout.addWidget(self.collection.view)
 
 
+        self.app_obj = AppObject(app=self)
+
         # ### Adjust tabs width ## ##
         # ### Adjust tabs width ## ##
         # self.collection.view.setMinimumWidth(self.ui.options_scroll_area.widget().sizeHint().width() +
         # self.collection.view.setMinimumWidth(self.ui.options_scroll_area.widget().sizeHint().width() +
         #     self.ui.options_scroll_area.verticalScrollBar().sizeHint().width())
         #     self.ui.options_scroll_area.verticalScrollBar().sizeHint().width())
@@ -779,12 +763,6 @@ class App(QtCore.QObject):
         self.message.connect(lambda: message_dialog(parent=self.ui))
         self.message.connect(lambda: message_dialog(parent=self.ui))
         # self.progress.connect(self.set_progress_bar)
         # self.progress.connect(self.set_progress_bar)
 
 
-        # signals that are emitted when object state changes
-        self.object_created.connect(self.on_object_created)
-        self.object_changed.connect(self.on_object_changed)
-        self.object_plotted.connect(self.on_object_plotted)
-        self.plots_updated.connect(self.on_plots_updated)
-
         # signals emitted when file state change
         # signals emitted when file state change
         self.file_opened.connect(self.register_recent)
         self.file_opened.connect(self.register_recent)
         self.file_opened.connect(lambda kind, filename: self.register_folder(filename))
         self.file_opened.connect(lambda kind, filename: self.register_folder(filename))
@@ -793,10 +771,10 @@ class App(QtCore.QObject):
         # ########################################## Standard signals ###############################################
         # ########################################## Standard signals ###############################################
         # ### Menu
         # ### Menu
         self.ui.menufilenewproject.triggered.connect(self.on_file_new_click)
         self.ui.menufilenewproject.triggered.connect(self.on_file_new_click)
-        self.ui.menufilenewgeo.triggered.connect(self.new_geometry_object)
-        self.ui.menufilenewgrb.triggered.connect(self.new_gerber_object)
-        self.ui.menufilenewexc.triggered.connect(self.new_excellon_object)
-        self.ui.menufilenewdoc.triggered.connect(self.new_document_object)
+        self.ui.menufilenewgeo.triggered.connect(self.app_obj.new_geometry_object)
+        self.ui.menufilenewgrb.triggered.connect(self.app_obj.new_gerber_object)
+        self.ui.menufilenewexc.triggered.connect(self.app_obj.new_excellon_object)
+        self.ui.menufilenewdoc.triggered.connect(self.app_obj.new_document_object)
 
 
         self.ui.menufileopengerber.triggered.connect(self.on_fileopengerber)
         self.ui.menufileopengerber.triggered.connect(self.on_fileopengerber)
         self.ui.menufileopenexcellon.triggered.connect(self.on_fileopenexcellon)
         self.ui.menufileopenexcellon.triggered.connect(self.on_fileopenexcellon)
@@ -935,9 +913,9 @@ class App(QtCore.QObject):
         self.ui.popmenu_disable.triggered.connect(lambda: self.toggle_plots(self.collection.get_selected()))
         self.ui.popmenu_disable.triggered.connect(lambda: self.toggle_plots(self.collection.get_selected()))
         self.ui.popmenu_panel_toggle.triggered.connect(self.ui.on_toggle_notebook)
         self.ui.popmenu_panel_toggle.triggered.connect(self.ui.on_toggle_notebook)
 
 
-        self.ui.popmenu_new_geo.triggered.connect(self.new_geometry_object)
-        self.ui.popmenu_new_grb.triggered.connect(self.new_gerber_object)
-        self.ui.popmenu_new_exc.triggered.connect(self.new_excellon_object)
+        self.ui.popmenu_new_geo.triggered.connect(self.app_obj.new_geometry_object)
+        self.ui.popmenu_new_grb.triggered.connect(self.app_obj.new_gerber_object)
+        self.ui.popmenu_new_exc.triggered.connect(self.app_obj.new_excellon_object)
         self.ui.popmenu_new_prj.triggered.connect(self.on_file_new)
         self.ui.popmenu_new_prj.triggered.connect(self.on_file_new)
 
 
         self.ui.zoomfit.triggered.connect(self.on_zoom_fit)
         self.ui.zoomfit.triggered.connect(self.on_zoom_fit)
@@ -1918,7 +1896,7 @@ class App(QtCore.QObject):
         self.calculator_tool = ToolCalculator(self)
         self.calculator_tool = ToolCalculator(self)
         self.calculator_tool.install(icon=QtGui.QIcon(self.resource_location + '/calculator16.png'), separator=True)
         self.calculator_tool.install(icon=QtGui.QIcon(self.resource_location + '/calculator16.png'), separator=True)
 
 
-        self.sub_tool = ToolSub(self)
+        self.sub_tool = ToolSub(app=self)
         self.sub_tool.install(icon=QtGui.QIcon(self.resource_location + '/sub32.png'),
         self.sub_tool.install(icon=QtGui.QIcon(self.resource_location + '/sub32.png'),
                               pos=self.ui.menutool, separator=True)
                               pos=self.ui.menutool, separator=True)
 
 
@@ -2071,9 +2049,9 @@ class App(QtCore.QObject):
         self.ui.zoom_out_btn.triggered.connect(lambda: self.plotcanvas.zoom(1.5))
         self.ui.zoom_out_btn.triggered.connect(lambda: self.plotcanvas.zoom(1.5))
 
 
         # Edit Toolbar Signals
         # Edit Toolbar Signals
-        self.ui.newgeo_btn.triggered.connect(self.new_geometry_object)
-        self.ui.newgrb_btn.triggered.connect(self.new_gerber_object)
-        self.ui.newexc_btn.triggered.connect(self.new_excellon_object)
+        self.ui.newgeo_btn.triggered.connect(self.app_obj.new_geometry_object)
+        self.ui.newgrb_btn.triggered.connect(self.app_obj.new_gerber_object)
+        self.ui.newexc_btn.triggered.connect(self.app_obj.new_excellon_object)
         self.ui.editgeo_btn.triggered.connect(self.object2editor)
         self.ui.editgeo_btn.triggered.connect(self.object2editor)
         self.ui.update_obj_btn.triggered.connect(lambda: self.editor2object())
         self.ui.update_obj_btn.triggered.connect(lambda: self.editor2object())
         self.ui.copy_btn.triggered.connect(self.on_copy_command)
         self.ui.copy_btn.triggered.connect(self.on_copy_command)
@@ -2665,347 +2643,6 @@ class App(QtCore.QObject):
         # Re-build the recent items menu
         # Re-build the recent items menu
         self.setup_recent_items()
         self.setup_recent_items()
 
 
-    def new_object(self, kind, name, initialize, plot=True, autoselected=True):
-        """
-        Creates a new specialized FlatCAMObj and attaches it to the application,
-        this is, updates the GUI accordingly, any other records and plots it.
-        This method is thread-safe.
-
-        Notes:
-            * If the name is in use, the self.collection will modify it
-              when appending it to the collection. There is no need to handle
-              name conflicts here.
-
-        :param kind: The kind of object to create. One of 'gerber', 'excellon', 'cncjob' and 'geometry'.
-        :type kind: str
-        :param name: Name for the object.
-        :type name: str
-        :param initialize: Function to run after creation of the object but before it is attached to the application.
-        The function is called with 2 parameters: the new object and the App instance.
-        :type initialize: function
-        :param plot: If to plot the resulting object
-        :param autoselected: if the resulting object is autoselected in the Project tab and therefore in the
-        self.collection
-        :return: None
-        :rtype: None
-        """
-
-        App.log.debug("new_object()")
-        obj_plot = plot
-        obj_autoselected = autoselected
-
-        t0 = time.time()  # Debug
-
-        # ## Create object
-        classdict = {
-            "gerber": GerberObject,
-            "excellon": ExcellonObject,
-            "cncjob": CNCJobObject,
-            "geometry": GeometryObject,
-            "script": ScriptObject,
-            "document": DocumentObject
-        }
-
-        App.log.debug("Calling object constructor...")
-
-        # Object creation/instantiation
-        obj = classdict[kind](name)
-
-        obj.units = self.options["units"]
-
-        # IMPORTANT
-        # The key names in defaults and options dictionary's are not random:
-        # they have to have in name first the type of the object (geometry, excellon, cncjob and gerber) or how it's
-        # called here, the 'kind' followed by an underline. Above the App default values from self.defaults are
-        # copied to self.options. After that, below, depending on the type of
-        # object that is created, it will strip the name of the object and the underline (if the original key was
-        # let's say "excellon_toolchange", it will strip the excellon_) and to the obj.options the key will become
-        # "toolchange"
-
-        for option in self.options:
-            if option.find(kind + "_") == 0:
-                oname = option[len(kind) + 1:]
-                obj.options[oname] = self.options[option]
-
-        obj.isHovering = False
-        obj.notHovering = True
-
-        # Initialize as per user request
-        # User must take care to implement initialize
-        # in a thread-safe way as is is likely that we
-        # have been invoked in a separate thread.
-        t1 = time.time()
-        self.log.debug("%f seconds before initialize()." % (t1 - t0))
-        try:
-            return_value = initialize(obj, self)
-        except Exception as e:
-            msg = '[ERROR_NOTCL] %s' % _("An internal error has occurred. See shell.\n")
-            msg += _("Object ({kind}) failed because: {error} \n\n").format(kind=kind, error=str(e))
-            msg += traceback.format_exc()
-            self.inform.emit(msg)
-            return "fail"
-
-        t2 = time.time()
-        self.log.debug("%f seconds executing initialize()." % (t2 - t1))
-
-        if return_value == 'fail':
-            log.debug("Object (%s) parsing and/or geometry creation failed." % kind)
-            return "fail"
-
-        # Check units and convert if necessary
-        # This condition CAN be true because initialize() can change obj.units
-        if self.options["units"].upper() != obj.units.upper():
-            self.inform.emit('%s: %s' % (_("Converting units to "), self.options["units"]))
-            obj.convert_units(self.options["units"])
-            t3 = time.time()
-            self.log.debug("%f seconds converting units." % (t3 - t2))
-
-        # Create the bounding box for the object and then add the results to the obj.options
-        # But not for Scripts or for Documents
-        if kind != 'document' and kind != 'script':
-            try:
-                xmin, ymin, xmax, ymax = obj.bounds()
-                obj.options['xmin'] = xmin
-                obj.options['ymin'] = ymin
-                obj.options['xmax'] = xmax
-                obj.options['ymax'] = ymax
-            except Exception as e:
-                log.warning("App.new_object() -> The object has no bounds properties. %s" % str(e))
-                return "fail"
-
-            try:
-                if kind == 'excellon':
-                    obj.fill_color = self.defaults["excellon_plot_fill"]
-                    obj.outline_color = self.defaults["excellon_plot_line"]
-
-                if kind == 'gerber':
-                    obj.fill_color = self.defaults["gerber_plot_fill"]
-                    obj.outline_color = self.defaults["gerber_plot_line"]
-            except Exception as e:
-                log.warning("App.new_object() -> setting colors error. %s" % str(e))
-
-        # update the KeyWords list with the name of the file
-        self.myKeywords.append(obj.options['name'])
-
-        log.debug("Moving new object back to main thread.")
-
-        # Move the object to the main thread and let the app know that it is available.
-        obj.moveToThread(self.main_thread)
-        self.object_created.emit(obj, obj_plot, obj_autoselected)
-
-        return obj
-
-    def new_excellon_object(self):
-        """
-        Creates a new, blank Excellon object.
-
-        :return: None
-        """
-        self.defaults.report_usage("new_excellon_object()")
-
-        self.new_object('excellon', 'new_exc', lambda x, y: None, plot=False)
-
-    def new_geometry_object(self):
-        """
-        Creates a new, blank and single-tool Geometry object.
-
-        :return: None
-        """
-        self.defaults.report_usage("new_geometry_object()")
-
-        def initialize(obj, app):
-            obj.multitool = False
-
-        self.new_object('geometry', 'new_geo', initialize, plot=False)
-
-    def new_gerber_object(self):
-        """
-        Creates a new, blank Gerber object.
-
-        :return: None
-        """
-        self.defaults.report_usage("new_gerber_object()")
-
-        def initialize(grb_obj, app):
-            grb_obj.multitool = False
-            grb_obj.source_file = []
-            grb_obj.multigeo = False
-            grb_obj.follow = False
-            grb_obj.apertures = {}
-            grb_obj.solid_geometry = []
-
-            try:
-                grb_obj.options['xmin'] = 0
-                grb_obj.options['ymin'] = 0
-                grb_obj.options['xmax'] = 0
-                grb_obj.options['ymax'] = 0
-            except KeyError:
-                pass
-
-        self.new_object('gerber', 'new_grb', initialize, plot=False)
-
-    def new_script_object(self):
-        """
-        Creates a new, blank TCL Script object.
-
-        :return: None
-        """
-        self.defaults.report_usage("new_script_object()")
-
-        # commands_list = "# AddCircle, AddPolygon, AddPolyline, AddRectangle, AlignDrill, " \
-        #                 "AlignDrillGrid, Bbox, Bounds, ClearShell, CopperClear,\n" \
-        #                 "# Cncjob, Cutout, Delete, Drillcncjob, ExportDXF, ExportExcellon, ExportGcode,\n" \
-        #                 "# ExportGerber, ExportSVG, Exteriors, Follow, GeoCutout, GeoUnion, GetNames,\n" \
-        #                 "# GetSys, ImportSvg, Interiors, Isolate, JoinExcellon, JoinGeometry, " \
-        #                 "ListSys, MillDrills,\n" \
-        #                 "# MillSlots, Mirror, New, NewExcellon, NewGeometry, NewGerber, Nregions, " \
-        #                 "Offset, OpenExcellon, OpenGCode, OpenGerber, OpenProject,\n" \
-        #                 "# Options, Paint, Panelize, PlotAl, PlotObjects, SaveProject, " \
-        #                 "SaveSys, Scale, SetActive, SetSys, SetOrigin, Skew, SubtractPoly,\n" \
-        #                 "# SubtractRectangle, Version, WriteGCode\n"
-
-        new_source_file = '# %s\n' % _('CREATE A NEW FLATCAM TCL SCRIPT') + \
-                          '# %s:\n' % _('TCL Tutorial is here') + \
-                          '# https://www.tcl.tk/man/tcl8.5/tutorial/tcltutorial.html\n' + '\n\n' + \
-                          '# %s:\n' % _("FlatCAM commands list")
-        new_source_file += '# %s\n\n' % _("Type >help< followed by Run Code for a list of FlatCAM Tcl Commands "
-                                          "(displayed in Tcl Shell).")
-
-        def initialize(obj, app):
-            obj.source_file = deepcopy(new_source_file)
-
-        outname = 'new_script'
-        self.new_object('script', outname, initialize, plot=False)
-
-    def new_document_object(self):
-        """
-        Creates a new, blank Document object.
-
-        :return: None
-        """
-        self.defaults.report_usage("new_document_object()")
-
-        def initialize(obj, app):
-            obj.source_file = ""
-
-        self.new_object('document', 'new_document', initialize, plot=False)
-
-    def on_object_created(self, obj, plot, auto_select):
-        """
-        Event callback for object creation.
-        It will add the new object to the collection. After that it will plot the object in a threaded way
-
-        :param obj: The newly created FlatCAM object.
-        :param plot: if the newly create object t obe plotted
-        :param auto_select: if the newly created object to be autoselected after creation
-        :return: None
-        """
-        t0 = time.time()  # DEBUG
-        self.log.debug("on_object_created()")
-
-        # The Collection might change the name if there is a collision
-        self.collection.append(obj)
-
-        # after adding the object to the collection always update the list of objects that are in the collection
-        self.all_objects_list = self.collection.get_list()
-
-        # self.inform.emit('[selected] %s created & selected: %s' %
-        #                  (str(obj.kind).capitalize(), str(obj.options['name'])))
-        if obj.kind == 'gerber':
-            self.inform.emit('[selected] {kind} {tx}: <span style="color:{color};">{name}</span>'.format(
-                kind=obj.kind.capitalize(),
-                color='green',
-                name=str(obj.options['name']), tx=_("created/selected"))
-            )
-        elif obj.kind == 'excellon':
-            self.inform.emit('[selected] {kind} {tx}: <span style="color:{color};">{name}</span>'.format(
-                kind=obj.kind.capitalize(),
-                color='brown',
-                name=str(obj.options['name']), tx=_("created/selected"))
-            )
-        elif obj.kind == 'cncjob':
-            self.inform.emit('[selected] {kind} {tx}: <span style="color:{color};">{name}</span>'.format(
-                kind=obj.kind.capitalize(),
-                color='blue',
-                name=str(obj.options['name']), tx=_("created/selected"))
-            )
-        elif obj.kind == 'geometry':
-            self.inform.emit('[selected] {kind} {tx}: <span style="color:{color};">{name}</span>'.format(
-                kind=obj.kind.capitalize(),
-                color='red',
-                name=str(obj.options['name']), tx=_("created/selected"))
-            )
-        elif obj.kind == 'script':
-            self.inform.emit('[selected] {kind} {tx}: <span style="color:{color};">{name}</span>'.format(
-                kind=obj.kind.capitalize(),
-                color='orange',
-                name=str(obj.options['name']), tx=_("created/selected"))
-            )
-        elif obj.kind == 'document':
-            self.inform.emit('[selected] {kind} {tx}: <span style="color:{color};">{name}</span>'.format(
-                kind=obj.kind.capitalize(),
-                color='darkCyan',
-                name=str(obj.options['name']), tx=_("created/selected"))
-            )
-
-        # update the SHELL auto-completer model with the name of the new object
-        self.shell._edit.set_model_data(self.myKeywords)
-
-        if auto_select:
-            # select the just opened object but deselect the previous ones
-            self.collection.set_all_inactive()
-            self.collection.set_active(obj.options["name"])
-        else:
-            self.collection.set_all_inactive()
-
-        # here it is done the object plotting
-        def worker_task(t_obj):
-            with self.proc_container.new(_("Plotting")):
-                if isinstance(t_obj, CNCJobObject):
-                    t_obj.plot(kind=self.defaults["cncjob_plot_kind"])
-                else:
-                    t_obj.plot()
-                t1 = time.time()  # DEBUG
-                self.log.debug("%f seconds adding object and plotting." % (t1 - t0))
-                self.object_plotted.emit(t_obj)
-
-        # Send to worker
-        # self.worker.add_task(worker_task, [self])
-        if plot is True:
-            self.worker_task.emit({'fcn': worker_task, 'params': [obj]})
-
-    def on_object_changed(self, obj):
-        """
-        Called whenever the geometry of the object was changed in some way.
-        This require the update of it's bounding values so it can be the selected on canvas.
-        Update the bounding box data from obj.options
-
-        :param obj: the object that was changed
-        :return: None
-        """
-
-        try:
-            xmin, ymin, xmax, ymax = obj.bounds()
-        except TypeError:
-            return
-        obj.options['xmin'] = xmin
-        obj.options['ymin'] = ymin
-        obj.options['xmax'] = xmax
-        obj.options['ymax'] = ymax
-
-        log.debug("Object changed, updating the bounding box data on self.options")
-        # delete the old selection shape
-        self.delete_selection_shape()
-        self.should_we_save = True
-
-    def on_object_plotted(self):
-        """
-        Callback called whenever the plotted object needs to be fit into the viewport (canvas)
-
-        :return: None
-        """
-        self.on_zoom_fit(None)
-
     def on_about(self):
     def on_about(self):
         """
         """
         Displays the "about" dialog found in the Menu --> Help.
         Displays the "about" dialog found in the Menu --> Help.
@@ -3976,7 +3613,7 @@ class App(QtCore.QObject):
                 for v in geo_obj.tools.values():
                 for v in geo_obj.tools.values():
                     v['data']['name'] = obj_name_multi
                     v['data']['name'] = obj_name_multi
 
 
-            self.new_object("geometry", obj_name_multi, initialize)
+            self.app_obj.new_object("geometry", obj_name_multi, initialize)
         else:
         else:
             def initialize(geo_obj, app):
             def initialize(geo_obj, app):
                 GeometryObject.merge(geo_list=objs, geo_final=geo_obj, multigeo=False)
                 GeometryObject.merge(geo_list=objs, geo_final=geo_obj, multigeo=False)
@@ -3986,7 +3623,7 @@ class App(QtCore.QObject):
                 for v in geo_obj.tools.values():
                 for v in geo_obj.tools.values():
                     v['data']['name'] = obj_name_single
                     v['data']['name'] = obj_name_single
 
 
-            self.new_object("geometry", obj_name_single, initialize)
+            self.app_obj.new_object("geometry", obj_name_single, initialize)
 
 
         self.should_we_save = True
         self.should_we_save = True
 
 
@@ -4015,7 +3652,7 @@ class App(QtCore.QObject):
             ExcellonObject.merge(exc_list=objs, exc_final=exc_obj, decimals=self.decimals)
             ExcellonObject.merge(exc_list=objs, exc_final=exc_obj, decimals=self.decimals)
             app.inform.emit('[success] %s.' % _("Excellon merging finished"))
             app.inform.emit('[success] %s.' % _("Excellon merging finished"))
 
 
-        self.new_object("excellon", 'Combo_Excellon', initialize)
+        self.app_obj.new_object("excellon", 'Combo_Excellon', initialize)
         self.should_we_save = True
         self.should_we_save = True
 
 
     def on_edit_join_grb(self):
     def on_edit_join_grb(self):
@@ -4043,7 +3680,7 @@ class App(QtCore.QObject):
             GerberObject.merge(grb_list=objs, grb_final=grb_obj)
             GerberObject.merge(grb_list=objs, grb_final=grb_obj)
             app.inform.emit('[success] %s.' % _("Gerber merging finished"))
             app.inform.emit('[success] %s.' % _("Gerber merging finished"))
 
 
-        self.new_object("gerber", 'Combo_Gerber', initialize)
+        self.app_obj.new_object("gerber", 'Combo_Gerber', initialize)
         self.should_we_save = True
         self.should_we_save = True
 
 
     def on_convert_singlegeo_to_multigeo(self):
     def on_convert_singlegeo_to_multigeo(self):
@@ -4352,7 +3989,7 @@ class App(QtCore.QObject):
                 obj.convert_units(new_units)
                 obj.convert_units(new_units)
 
 
                 # make that the properties stored in the object are also updated
                 # make that the properties stored in the object are also updated
-                self.object_changed.emit(obj)
+                self.app_obj.object_changed.emit(obj)
                 # rebuild the object UI
                 # rebuild the object UI
                 obj.build_ui()
                 obj.build_ui()
 
 
@@ -5017,7 +4654,7 @@ class App(QtCore.QObject):
 
 
                 for obj in obj_list:
                 for obj in obj_list:
                     obj.offset((x, y))
                     obj.offset((x, y))
-                    self.object_changed.emit(obj)
+                    self.app_obj.object_changed.emit(obj)
 
 
                     # Update the object bounding box options
                     # Update the object bounding box options
                     a, b, c, d = obj.bounds()
                     a, b, c, d = obj.bounds()
@@ -5105,7 +4742,7 @@ class App(QtCore.QObject):
 
 
                 for obj in obj_list:
                 for obj in obj_list:
                     obj.offset((-x, -y))
                     obj.offset((-x, -y))
-                    self.object_changed.emit(obj)
+                    self.app_obj.object_changed.emit(obj)
 
 
                     # Update the object bounding box options
                     # Update the object bounding box options
                     a, b, c, d = obj.bounds()
                     a, b, c, d = obj.bounds()
@@ -5468,15 +5105,15 @@ class App(QtCore.QObject):
 
 
             try:
             try:
                 if isinstance(obj, ExcellonObject):
                 if isinstance(obj, ExcellonObject):
-                    self.new_object("excellon", str(obj_name) + "_copy", initialize_excellon)
+                    self.app_obj.new_object("excellon", str(obj_name) + "_copy", initialize_excellon)
                 elif isinstance(obj, GerberObject):
                 elif isinstance(obj, GerberObject):
-                    self.new_object("gerber", str(obj_name) + "_copy", initialize)
+                    self.app_obj.new_object("gerber", str(obj_name) + "_copy", initialize)
                 elif isinstance(obj, GeometryObject):
                 elif isinstance(obj, GeometryObject):
-                    self.new_object("geometry", str(obj_name) + "_copy", initialize)
+                    self.app_obj.new_object("geometry", str(obj_name) + "_copy", initialize)
                 elif isinstance(obj, ScriptObject):
                 elif isinstance(obj, ScriptObject):
-                    self.new_object("script", str(obj_name) + "_copy", initialize_script)
+                    self.app_obj.new_object("script", str(obj_name) + "_copy", initialize_script)
                 elif isinstance(obj, DocumentObject):
                 elif isinstance(obj, DocumentObject):
-                    self.new_object("document", str(obj_name) + "_copy", initialize_document)
+                    self.app_obj.new_object("document", str(obj_name) + "_copy", initialize_document)
             except Exception as e:
             except Exception as e:
                 return "Operation failed: %s" % str(e)
                 return "Operation failed: %s" % str(e)
 
 
@@ -5517,11 +5154,11 @@ class App(QtCore.QObject):
             obj_name = obj.options["name"]
             obj_name = obj.options["name"]
             try:
             try:
                 if isinstance(obj, ExcellonObject):
                 if isinstance(obj, ExcellonObject):
-                    self.new_object("excellon", str(obj_name) + custom_name, initialize_excellon)
+                    self.app_obj.new_object("excellon", str(obj_name) + custom_name, initialize_excellon)
                 elif isinstance(obj, GerberObject):
                 elif isinstance(obj, GerberObject):
-                    self.new_object("gerber", str(obj_name) + custom_name, initialize_gerber)
+                    self.app_obj.new_object("gerber", str(obj_name) + custom_name, initialize_gerber)
                 elif isinstance(obj, GeometryObject):
                 elif isinstance(obj, GeometryObject):
-                    self.new_object("geometry", str(obj_name) + custom_name, initialize_geometry)
+                    self.app_obj.new_object("geometry", str(obj_name) + custom_name, initialize_geometry)
             except Exception as er:
             except Exception as er:
                 return "Operation failed: %s" % str(er)
                 return "Operation failed: %s" % str(er)
 
 
@@ -5588,9 +5225,9 @@ class App(QtCore.QObject):
 
 
             try:
             try:
                 if isinstance(obj, ExcellonObject):
                 if isinstance(obj, ExcellonObject):
-                    self.new_object("geometry", str(obj_name) + "_conv", initialize_excellon)
+                    self.app_obj.new_object("geometry", str(obj_name) + "_conv", initialize_excellon)
                 else:
                 else:
-                    self.new_object("geometry", str(obj_name) + "_conv", initialize)
+                    self.app_obj.new_object("geometry", str(obj_name) + "_conv", initialize)
             except Exception as e:
             except Exception as e:
                 return "Operation failed: %s" % str(e)
                 return "Operation failed: %s" % str(e)
 
 
@@ -5666,9 +5303,9 @@ class App(QtCore.QObject):
 
 
             try:
             try:
                 if isinstance(obj, ExcellonObject):
                 if isinstance(obj, ExcellonObject):
-                    self.new_object("gerber", str(obj_name) + "_conv", initialize_excellon)
+                    self.app_obj.new_object("gerber", str(obj_name) + "_conv", initialize_excellon)
                 elif isinstance(obj, GeometryObject):
                 elif isinstance(obj, GeometryObject):
-                    self.new_object("gerber", str(obj_name) + "_conv", initialize_geometry)
+                    self.app_obj.new_object("gerber", str(obj_name) + "_conv", initialize_geometry)
                 else:
                 else:
                     log.warning("App.convert_any2gerber --> This is no vaild object for conversion.")
                     log.warning("App.convert_any2gerber --> This is no vaild object for conversion.")
 
 
@@ -5960,7 +5597,7 @@ class App(QtCore.QObject):
                 for obj in obj_list:
                 for obj in obj_list:
                     obj.mirror('X', [px, py])
                     obj.mirror('X', [px, py])
                     obj.plot()
                     obj.plot()
-                    self.object_changed.emit(obj)
+                    self.app_obj.object_changed.emit(obj)
                 self.inform.emit('[success] %s' %
                 self.inform.emit('[success] %s' %
                                  _("Flip on Y axis done."))
                                  _("Flip on Y axis done."))
             except Exception as e:
             except Exception as e:
@@ -6008,7 +5645,7 @@ class App(QtCore.QObject):
                 for obj in obj_list:
                 for obj in obj_list:
                     obj.mirror('Y', [px, py])
                     obj.mirror('Y', [px, py])
                     obj.plot()
                     obj.plot()
-                    self.object_changed.emit(obj)
+                    self.app_obj.object_changed.emit(obj)
                 self.inform.emit('[success] %s' %
                 self.inform.emit('[success] %s' %
                                  _("Flip on X axis done."))
                                  _("Flip on X axis done."))
             except Exception as e:
             except Exception as e:
@@ -6064,7 +5701,7 @@ class App(QtCore.QObject):
                     for sel_obj in obj_list:
                     for sel_obj in obj_list:
                         sel_obj.rotate(-float(num), point=(px, py))
                         sel_obj.rotate(-float(num), point=(px, py))
                         sel_obj.plot()
                         sel_obj.plot()
-                        self.object_changed.emit(sel_obj)
+                        self.app_obj.object_changed.emit(sel_obj)
                     self.inform.emit('[success] %s' % _("Rotation done."))
                     self.inform.emit('[success] %s' % _("Rotation done."))
                 except Exception as e:
                 except Exception as e:
                     self.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Rotation movement was not executed."), str(e)))
                     self.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Rotation movement was not executed."), str(e)))
@@ -6104,7 +5741,7 @@ class App(QtCore.QObject):
                 for obj in obj_list:
                 for obj in obj_list:
                     obj.skew(num, 0, point=(xminimal, yminimal))
                     obj.skew(num, 0, point=(xminimal, yminimal))
                     obj.plot()
                     obj.plot()
-                    self.object_changed.emit(obj)
+                    self.app_obj.object_changed.emit(obj)
                 self.inform.emit('[success] %s' % _("Skew on X axis done."))
                 self.inform.emit('[success] %s' % _("Skew on X axis done."))
 
 
     def on_skewy(self):
     def on_skewy(self):
@@ -6141,7 +5778,7 @@ class App(QtCore.QObject):
                 for obj in obj_list:
                 for obj in obj_list:
                     obj.skew(0, num, point=(xminimal, yminimal))
                     obj.skew(0, num, point=(xminimal, yminimal))
                     obj.plot()
                     obj.plot()
-                    self.object_changed.emit(obj)
+                    self.app_obj.object_changed.emit(obj)
                 self.inform.emit('[success] %s' % _("Skew on Y axis done."))
                 self.inform.emit('[success] %s' % _("Skew on Y axis done."))
 
 
     def on_plots_updated(self):
     def on_plots_updated(self):
@@ -7970,7 +7607,7 @@ class App(QtCore.QObject):
         self.ui.position_label.setText("")
         self.ui.position_label.setText("")
         # self.ui.rel_position_label.setText("")
         # self.ui.rel_position_label.setText("")
 
 
-        self.new_script_object()
+        self.app_obj.new_script_object()
 
 
         # script_text = script_obj.source_file
         # script_text = script_obj.source_file
         #
         #
@@ -8891,7 +8528,7 @@ class App(QtCore.QObject):
             # Object name
             # Object name
             name = outname or filename.split('/')[-1].split('\\')[-1]
             name = outname or filename.split('/')[-1].split('\\')[-1]
 
 
-            ret = self.new_object(obj_type, name, obj_init, autoselected=False, plot=plot)
+            ret = self.app_obj.new_object(obj_type, name, obj_init, autoselected=False, plot=plot)
 
 
             if ret == 'fail':
             if ret == 'fail':
                 self.inform.emit('[ERROR_NOTCL]%s' % _('Import failed.'))
                 self.inform.emit('[ERROR_NOTCL]%s' % _('Import failed.'))
@@ -8937,7 +8574,7 @@ class App(QtCore.QObject):
             # Object name
             # Object name
             name = outname or filename.split('/')[-1].split('\\')[-1]
             name = outname or filename.split('/')[-1].split('\\')[-1]
 
 
-            ret = self.new_object(obj_type, name, obj_init, autoselected=False, plot=plot)
+            ret = self.app_obj.new_object(obj_type, name, obj_init, autoselected=False, plot=plot)
 
 
             if ret == 'fail':
             if ret == 'fail':
                 self.inform.emit('[ERROR_NOTCL]%s' % _('Import failed.'))
                 self.inform.emit('[ERROR_NOTCL]%s' % _('Import failed.'))
@@ -8998,11 +8635,11 @@ class App(QtCore.QObject):
             name = outname or filename.split('/')[-1].split('\\')[-1]
             name = outname or filename.split('/')[-1].split('\\')[-1]
 
 
             # # ## Object creation # ##
             # # ## Object creation # ##
-            ret_val = self.new_object("gerber", name, obj_init, autoselected=False, plot=plot)
+            ret_val = self.app_obj.new_object("gerber", name, obj_init, autoselected=False, plot=plot)
             if ret_val == 'fail':
             if ret_val == 'fail':
                 if from_tcl:
                 if from_tcl:
                     filename = self.defaults['global_tcl_path'] + '/' + name
                     filename = self.defaults['global_tcl_path'] + '/' + name
-                    ret_val = self.new_object("gerber", name, obj_init, autoselected=False, plot=plot)
+                    ret_val = self.app_obj.new_object("gerber", name, obj_init, autoselected=False, plot=plot)
                 if ret_val == 'fail':
                 if ret_val == 'fail':
                     self.inform.emit('[ERROR_NOTCL]%s' % _('Open Gerber failed. Probable not a Gerber file.'))
                     self.inform.emit('[ERROR_NOTCL]%s' % _('Open Gerber failed. Probable not a Gerber file.'))
                     return 'fail'
                     return 'fail'
@@ -9064,11 +8701,11 @@ class App(QtCore.QObject):
         with self.proc_container.new(_("Opening Excellon.")):
         with self.proc_container.new(_("Opening Excellon.")):
             # Object name
             # Object name
             name = outname or filename.split('/')[-1].split('\\')[-1]
             name = outname or filename.split('/')[-1].split('\\')[-1]
-            ret_val = self.new_object("excellon", name, obj_init, autoselected=False, plot=plot)
+            ret_val = self.app_obj.new_object("excellon", name, obj_init, autoselected=False, plot=plot)
             if ret_val == 'fail':
             if ret_val == 'fail':
                 if from_tcl:
                 if from_tcl:
                     filename = self.defaults['global_tcl_path'] + '/' + name
                     filename = self.defaults['global_tcl_path'] + '/' + name
-                    ret_val = self.new_object("excellon", name, obj_init, autoselected=False, plot=plot)
+                    ret_val = self.app_obj.new_object("excellon", name, obj_init, autoselected=False, plot=plot)
                 if ret_val == 'fail':
                 if ret_val == 'fail':
                     self.inform.emit('[ERROR_NOTCL] %s' %
                     self.inform.emit('[ERROR_NOTCL] %s' %
                                      _('Open Excellon file failed. Probable not an Excellon file.'))
                                      _('Open Excellon file failed. Probable not an Excellon file.'))
@@ -9127,11 +8764,11 @@ class App(QtCore.QObject):
             name = outname or filename.split('/')[-1].split('\\')[-1]
             name = outname or filename.split('/')[-1].split('\\')[-1]
 
 
             # New object creation and file processing
             # New object creation and file processing
-            ret_val = self.new_object("cncjob", name, obj_init, autoselected=False, plot=plot)
+            ret_val = self.app_obj.new_object("cncjob", name, obj_init, autoselected=False, plot=plot)
             if ret_val == 'fail':
             if ret_val == 'fail':
                 if from_tcl:
                 if from_tcl:
                     filename = self.defaults['global_tcl_path'] + '/' + name
                     filename = self.defaults['global_tcl_path'] + '/' + name
-                    ret_val = self.new_object("cncjob", name, obj_init, autoselected=False, plot=plot)
+                    ret_val = self.app_obj.new_object("cncjob", name, obj_init, autoselected=False, plot=plot)
                 if ret_val == 'fail':
                 if ret_val == 'fail':
                     self.inform.emit('[ERROR_NOTCL] %s' %
                     self.inform.emit('[ERROR_NOTCL] %s' %
                                      _("Failed to create CNCJob Object. Probable not a GCode file. "
                                      _("Failed to create CNCJob Object. Probable not a GCode file. "
@@ -9200,7 +8837,7 @@ class App(QtCore.QObject):
             name = outname or filename.split('/')[-1].split('\\')[-1]
             name = outname or filename.split('/')[-1].split('\\')[-1]
 
 
             # # ## Object creation # ##
             # # ## Object creation # ##
-            ret = self.new_object("geometry", name, obj_init, autoselected=False)
+            ret = self.app_obj.new_object("geometry", name, obj_init, autoselected=False)
             if ret == 'fail':
             if ret == 'fail':
                 self.inform.emit('[ERROR_NOTCL]%s' % _(' Open HPGL2 failed. Probable not a HPGL2 file.'))
                 self.inform.emit('[ERROR_NOTCL]%s' % _(' Open HPGL2 failed. Probable not a HPGL2 file.'))
                 return 'fail'
                 return 'fail'
@@ -9254,10 +8891,10 @@ class App(QtCore.QObject):
             script_name = outname or filename.split('/')[-1].split('\\')[-1]
             script_name = outname or filename.split('/')[-1].split('\\')[-1]
 
 
             # Object creation
             # Object creation
-            ret_val = self.new_object("script", script_name, obj_init, autoselected=False, plot=False)
+            ret_val = self.app_obj.new_object("script", script_name, obj_init, autoselected=False, plot=False)
             if ret_val == 'fail':
             if ret_val == 'fail':
                 filename = self.defaults['global_tcl_path'] + '/' + script_name
                 filename = self.defaults['global_tcl_path'] + '/' + script_name
-                ret_val = self.new_object("script", script_name, obj_init, autoselected=False, plot=False)
+                ret_val = self.app_obj.new_object("script", script_name, obj_init, autoselected=False, plot=False)
                 if ret_val == 'fail':
                 if ret_val == 'fail':
                     self.inform.emit('[ERROR_NOTCL]%s' % _('Failed to open TCL Script.'))
                     self.inform.emit('[ERROR_NOTCL]%s' % _('Failed to open TCL Script.'))
                     return 'fail'
                     return 'fail'
@@ -9320,7 +8957,7 @@ class App(QtCore.QObject):
         2) Registers the file as recently opened.
         2) Registers the file as recently opened.
         3) Calls on_file_new()
         3) Calls on_file_new()
         4) Updates options
         4) Updates options
-        5) Calls new_object() with the object's from_dict() as init method.
+        5) Calls app_obj.new_object() with the object's from_dict() as init method.
         6) Calls plot_all() if plot=True
         6) Calls plot_all() if plot=True
 
 
         :param filename:        Name of the file from which to load.
         :param filename:        Name of the file from which to load.
@@ -9422,7 +9059,7 @@ class App(QtCore.QObject):
                                                               )
                                                               )
                                       )
                                       )
 
 
-                self.new_object(obj['kind'], obj['options']['name'], obj_init, plot=plot)
+                self.app_obj.new_object(obj['kind'], obj['options']['name'], obj_init, plot=plot)
             except Exception as e:
             except Exception as e:
                 print('App.open_project() --> ' + str(e))
                 print('App.open_project() --> ' + str(e))
 
 
@@ -9459,7 +9096,7 @@ class App(QtCore.QObject):
                 with self.proc_container.new("Plotting"):
                 with self.proc_container.new("Plotting"):
                     obj.plot(kind=self.defaults["cncjob_plot_kind"])
                     obj.plot(kind=self.defaults["cncjob_plot_kind"])
                     if fit_view is True:
                     if fit_view is True:
-                        self.object_plotted.emit(obj)
+                        self.app_obj.object_plotted.emit(obj)
 
 
             if use_thread is True:
             if use_thread is True:
                 # Send to worker
                 # Send to worker
@@ -10044,8 +9681,6 @@ class App(QtCore.QObject):
 
 
         self.worker_task.emit({'fcn': worker_task, 'params': [objects]})
         self.worker_task.emit({'fcn': worker_task, 'params': [objects]})
 
 
-        # self.plots_updated.emit()
-
     def disable_plots(self, objects):
     def disable_plots(self, objects):
         """
         """
         Disables plots
         Disables plots
@@ -10084,7 +9719,6 @@ class App(QtCore.QObject):
         except Exception as e:
         except Exception as e:
             log.debug("App.disable_plots() --> %s" % str(e))
             log.debug("App.disable_plots() --> %s" % str(e))
 
 
-        # self.plots_updated.emit()
         def worker_task(objs):
         def worker_task(objs):
             with self.proc_container.new(_("Disabling plots ...")):
             with self.proc_container.new(_("Disabling plots ...")):
                 for plot_obj in objs:
                 for plot_obj in objs:
@@ -10115,7 +9749,7 @@ class App(QtCore.QObject):
                 obj.options['plot'] = True
                 obj.options['plot'] = True
             else:
             else:
                 obj.options['plot'] = False
                 obj.options['plot'] = False
-        self.plots_updated.emit()
+        self.app_obj.plots_updated.emit()
 
 
     def clear_plots(self):
     def clear_plots(self):
         """
         """

+ 393 - 0
AppObjects/AppObject.py

@@ -0,0 +1,393 @@
+# ###########################################################
+# FlatCAM: 2D Post-processing for Manufacturing             #
+# http://flatcam.org                                        #
+# Author: Juan Pablo Caram (c)                              #
+# Date: 2/5/2014                                            #
+# MIT Licence                                               #
+# Modified by Marius Stanciu (2020)                         #
+# ###########################################################
+
+from PyQt5 import QtCore
+from AppObjects.ObjectCollection import *
+from AppObjects.FlatCAMCNCJob import CNCJobObject
+from AppObjects.FlatCAMDocument import DocumentObject
+from AppObjects.FlatCAMExcellon import ExcellonObject
+from AppObjects.FlatCAMGeometry import GeometryObject
+from AppObjects.FlatCAMGerber import GerberObject
+from AppObjects.FlatCAMScript import ScriptObject
+
+import time
+import traceback
+
+# FlatCAM Translation
+import gettext
+import AppTranslation as fcTranslate
+import builtins
+
+fcTranslate.apply_language('strings')
+if '_' not in builtins.__dict__:
+    _ = gettext.gettext
+
+
+class AppObject(QtCore.QObject):
+
+    # Emitted by app_obj.new_object() and passes the new object as argument, plot flag.
+    # on_object_created() adds the object to the collection, plots on appropriate flag
+    # and emits app_obj.new_object_available.
+    object_created = QtCore.pyqtSignal(object, bool, bool)
+
+    # Emitted when a object has been changed (like scaled, mirrored)
+    object_changed = QtCore.pyqtSignal(object)
+
+    # Emitted after object has been plotted.
+    # Calls 'on_zoom_fit' method to fit object in scene view in main thread to prevent drawing glitches.
+    object_plotted = QtCore.pyqtSignal(object)
+
+    plots_updated = QtCore.pyqtSignal()
+
+    def __init__(self, app):
+        super(AppObject, self).__init__()
+        self.app = app
+
+        # signals that are emitted when object state changes
+        self.object_created.connect(self.on_object_created)
+        self.object_changed.connect(self.on_object_changed)
+        self.object_plotted.connect(self.on_object_plotted)
+        self.plots_updated.connect(self.app.on_plots_updated)
+
+    def new_object(self, kind, name, initialize, plot=True, autoselected=True):
+        """
+        Creates a new specialized FlatCAMObj and attaches it to the application,
+        this is, updates the GUI accordingly, any other records and plots it.
+        This method is thread-safe.
+
+        Notes:
+            * If the name is in use, the self.collection will modify it
+              when appending it to the collection. There is no need to handle
+              name conflicts here.
+
+        :param kind: The kind of object to create. One of 'gerber', 'excellon', 'cncjob' and 'geometry'.
+        :type kind: str
+        :param name: Name for the object.
+        :type name: str
+        :param initialize: Function to run after creation of the object but before it is attached to the application.
+        The function is called with 2 parameters: the new object and the App instance.
+        :type initialize: function
+        :param plot: If to plot the resulting object
+        :param autoselected: if the resulting object is autoselected in the Project tab and therefore in the
+        self.collection
+        :return: None
+        :rtype: None
+        """
+
+        log.debug("AppObject.new_object()")
+        obj_plot = plot
+        obj_autoselected = autoselected
+
+        t0 = time.time()  # Debug
+
+        # ## Create object
+        classdict = {
+            "gerber": GerberObject,
+            "excellon": ExcellonObject,
+            "cncjob": CNCJobObject,
+            "geometry": GeometryObject,
+            "script": ScriptObject,
+            "document": DocumentObject
+        }
+
+        log.debug("Calling object constructor...")
+
+        # Object creation/instantiation
+        obj = classdict[kind](name)
+
+        obj.units = self.app.options["units"]
+
+        # IMPORTANT
+        # The key names in defaults and options dictionary's are not random:
+        # they have to have in name first the type of the object (geometry, excellon, cncjob and gerber) or how it's
+        # called here, the 'kind' followed by an underline. Above the App default values from self.defaults are
+        # copied to self.options. After that, below, depending on the type of
+        # object that is created, it will strip the name of the object and the underline (if the original key was
+        # let's say "excellon_toolchange", it will strip the excellon_) and to the obj.options the key will become
+        # "toolchange"
+
+        for option in self.app.options:
+            if option.find(kind + "_") == 0:
+                oname = option[len(kind) + 1:]
+                obj.options[oname] = self.app.options[option]
+
+        obj.isHovering = False
+        obj.notHovering = True
+
+        # Initialize as per user request
+        # User must take care to implement initialize
+        # in a thread-safe way as is is likely that we
+        # have been invoked in a separate thread.
+        t1 = time.time()
+        log.debug("%f seconds before initialize()." % (t1 - t0))
+        try:
+            return_value = initialize(obj, self)
+        except Exception as e:
+            msg = '[ERROR_NOTCL] %s' % _("An internal error has occurred. See shell.\n")
+            msg += _("Object ({kind}) failed because: {error} \n\n").format(kind=kind, error=str(e))
+            msg += traceback.format_exc()
+            self.app.inform.emit(msg)
+            return "fail"
+
+        t2 = time.time()
+        log.debug("%f seconds executing initialize()." % (t2 - t1))
+
+        if return_value == 'fail':
+            log.debug("Object (%s) parsing and/or geometry creation failed." % kind)
+            return "fail"
+
+        # Check units and convert if necessary
+        # This condition CAN be true because initialize() can change obj.units
+        if self.app.options["units"].upper() != obj.units.upper():
+            self.app.inform.emit('%s: %s' % (_("Converting units to "), self.app.options["units"]))
+            obj.convert_units(self.app.options["units"])
+            t3 = time.time()
+            log.debug("%f seconds converting units." % (t3 - t2))
+
+        # Create the bounding box for the object and then add the results to the obj.options
+        # But not for Scripts or for Documents
+        if kind != 'document' and kind != 'script':
+            try:
+                xmin, ymin, xmax, ymax = obj.bounds()
+                obj.options['xmin'] = xmin
+                obj.options['ymin'] = ymin
+                obj.options['xmax'] = xmax
+                obj.options['ymax'] = ymax
+            except Exception as e:
+                log.warning("AppObject.new_object() -> The object has no bounds properties. %s" % str(e))
+                return "fail"
+
+            try:
+                if kind == 'excellon':
+                    obj.fill_color = self.app.defaults["excellon_plot_fill"]
+                    obj.outline_color = self.app.defaults["excellon_plot_line"]
+
+                if kind == 'gerber':
+                    obj.fill_color = self.app.defaults["gerber_plot_fill"]
+                    obj.outline_color = self.app.defaults["gerber_plot_line"]
+            except Exception as e:
+                log.warning("AppObject.new_object() -> setting colors error. %s" % str(e))
+
+        # update the KeyWords list with the name of the file
+        self.app.myKeywords.append(obj.options['name'])
+
+        log.debug("Moving new object back to main thread.")
+
+        # Move the object to the main thread and let the app know that it is available.
+        obj.moveToThread(self.app.main_thread)
+        self.object_created.emit(obj, obj_plot, obj_autoselected)
+
+        return obj
+
+    def new_excellon_object(self):
+        """
+        Creates a new, blank Excellon object.
+
+        :return: None
+        """
+
+        self.new_object('excellon', 'new_exc', lambda x, y: None, plot=False)
+
+    def new_geometry_object(self):
+        """
+        Creates a new, blank and single-tool Geometry object.
+
+        :return: None
+        """
+
+        def initialize(obj, app):
+            obj.multitool = False
+
+        self.new_object('geometry', 'new_geo', initialize, plot=False)
+
+    def new_gerber_object(self):
+        """
+        Creates a new, blank Gerber object.
+
+        :return: None
+        """
+
+        def initialize(grb_obj, app):
+            grb_obj.multitool = False
+            grb_obj.source_file = []
+            grb_obj.multigeo = False
+            grb_obj.follow = False
+            grb_obj.apertures = {}
+            grb_obj.solid_geometry = []
+
+            try:
+                grb_obj.options['xmin'] = 0
+                grb_obj.options['ymin'] = 0
+                grb_obj.options['xmax'] = 0
+                grb_obj.options['ymax'] = 0
+            except KeyError:
+                pass
+
+        self.new_object('gerber', 'new_grb', initialize, plot=False)
+
+    def new_script_object(self):
+        """
+        Creates a new, blank TCL Script object.
+
+        :return: None
+        """
+
+        # commands_list = "# AddCircle, AddPolygon, AddPolyline, AddRectangle, AlignDrill, " \
+        #                 "AlignDrillGrid, Bbox, Bounds, ClearShell, CopperClear,\n" \
+        #                 "# Cncjob, Cutout, Delete, Drillcncjob, ExportDXF, ExportExcellon, ExportGcode,\n" \
+        #                 "# ExportGerber, ExportSVG, Exteriors, Follow, GeoCutout, GeoUnion, GetNames,\n" \
+        #                 "# GetSys, ImportSvg, Interiors, Isolate, JoinExcellon, JoinGeometry, " \
+        #                 "ListSys, MillDrills,\n" \
+        #                 "# MillSlots, Mirror, New, NewExcellon, NewGeometry, NewGerber, Nregions, " \
+        #                 "Offset, OpenExcellon, OpenGCode, OpenGerber, OpenProject,\n" \
+        #                 "# Options, Paint, Panelize, PlotAl, PlotObjects, SaveProject, " \
+        #                 "SaveSys, Scale, SetActive, SetSys, SetOrigin, Skew, SubtractPoly,\n" \
+        #                 "# SubtractRectangle, Version, WriteGCode\n"
+
+        new_source_file = '# %s\n' % _('CREATE A NEW FLATCAM TCL SCRIPT') + \
+                          '# %s:\n' % _('TCL Tutorial is here') + \
+                          '# https://www.tcl.tk/man/tcl8.5/tutorial/tcltutorial.html\n' + '\n\n' + \
+                          '# %s:\n' % _("FlatCAM commands list")
+        new_source_file += '# %s\n\n' % _("Type >help< followed by Run Code for a list of FlatCAM Tcl Commands "
+                                          "(displayed in Tcl Shell).")
+
+        def initialize(obj, app):
+            obj.source_file = deepcopy(new_source_file)
+
+        outname = 'new_script'
+        self.new_object('script', outname, initialize, plot=False)
+
+    def new_document_object(self):
+        """
+        Creates a new, blank Document object.
+
+        :return: None
+        """
+
+        def initialize(obj, app):
+            obj.source_file = ""
+
+        self.new_object('document', 'new_document', initialize, plot=False)
+
+    def on_object_created(self, obj, plot, auto_select):
+        """
+        Event callback for object creation.
+        It will add the new object to the collection. After that it will plot the object in a threaded way
+
+        :param obj: The newly created FlatCAM object.
+        :param plot: if the newly create object t obe plotted
+        :param auto_select: if the newly created object to be autoselected after creation
+        :return: None
+        """
+        t0 = time.time()  # DEBUG
+        log.debug("on_object_created()")
+
+        # The Collection might change the name if there is a collision
+        self.app.collection.append(obj)
+
+        # after adding the object to the collection always update the list of objects that are in the collection
+        self.all_objects_list = self.app.collection.get_list()
+
+        # self.app.inform.emit('[selected] %s created & selected: %s' %
+        #                  (str(obj.kind).capitalize(), str(obj.options['name'])))
+        if obj.kind == 'gerber':
+            self.app.inform.emit('[selected] {kind} {tx}: <span style="color:{color};">{name}</span>'.format(
+                kind=obj.kind.capitalize(),
+                color='green',
+                name=str(obj.options['name']), tx=_("created/selected"))
+            )
+        elif obj.kind == 'excellon':
+            self.app.inform.emit('[selected] {kind} {tx}: <span style="color:{color};">{name}</span>'.format(
+                kind=obj.kind.capitalize(),
+                color='brown',
+                name=str(obj.options['name']), tx=_("created/selected"))
+            )
+        elif obj.kind == 'cncjob':
+            self.app.inform.emit('[selected] {kind} {tx}: <span style="color:{color};">{name}</span>'.format(
+                kind=obj.kind.capitalize(),
+                color='blue',
+                name=str(obj.options['name']), tx=_("created/selected"))
+            )
+        elif obj.kind == 'geometry':
+            self.app.inform.emit('[selected] {kind} {tx}: <span style="color:{color};">{name}</span>'.format(
+                kind=obj.kind.capitalize(),
+                color='red',
+                name=str(obj.options['name']), tx=_("created/selected"))
+            )
+        elif obj.kind == 'script':
+            self.app.inform.emit('[selected] {kind} {tx}: <span style="color:{color};">{name}</span>'.format(
+                kind=obj.kind.capitalize(),
+                color='orange',
+                name=str(obj.options['name']), tx=_("created/selected"))
+            )
+        elif obj.kind == 'document':
+            self.app.inform.emit('[selected] {kind} {tx}: <span style="color:{color};">{name}</span>'.format(
+                kind=obj.kind.capitalize(),
+                color='darkCyan',
+                name=str(obj.options['name']), tx=_("created/selected"))
+            )
+
+        # update the SHELL auto-completer model with the name of the new object
+        self.app.shell._edit.set_model_data(self.app.myKeywords)
+
+        if auto_select:
+            # select the just opened object but deselect the previous ones
+            self.app.collection.set_all_inactive()
+            self.app.collection.set_active(obj.options["name"])
+        else:
+            self.app.collection.set_all_inactive()
+
+        # here it is done the object plotting
+        def task(t_obj):
+            with self.app.proc_container.new(_("Plotting")):
+                if t_obj.kind == 'cncjob':
+                    t_obj.plot(kind=self.defaults["cncjob_plot_kind"])
+                else:
+                    t_obj.plot()
+
+                t1 = time.time()  # DEBUG
+                log.debug("%f seconds adding object and plotting." % (t1 - t0))
+                self.object_plotted.emit(t_obj)
+
+        # Send to worker
+        # self.worker.add_task(worker_task, [self])
+        if plot is True:
+            self.worker_task.emit({'fcn': task, 'params': [obj]})
+
+    def on_object_changed(self, obj):
+        """
+        Called whenever the geometry of the object was changed in some way.
+        This require the update of it's bounding values so it can be the selected on canvas.
+        Update the bounding box data from obj.options
+
+        :param obj: the object that was changed
+        :return: None
+        """
+
+        try:
+            xmin, ymin, xmax, ymax = obj.bounds()
+        except TypeError:
+            return
+        obj.options['xmin'] = xmin
+        obj.options['ymin'] = ymin
+        obj.options['xmax'] = xmax
+        obj.options['ymax'] = ymax
+
+        log.debug("Object changed, updating the bounding box data on self.options")
+        # delete the old selection shape
+        self.app.delete_selection_shape()
+        self.app.should_we_save = True
+
+    def on_object_plotted(self):
+        """
+        Callback called whenever the plotted object needs to be fit into the viewport (canvas)
+
+        :return: None
+        """
+        self.app.on_zoom_fit(None)

+ 9 - 9
AppObjects/FlatCAMExcellon.py

@@ -1196,8 +1196,8 @@ class ExcellonObject(FlatCAMObj, Excellon):
                             Point(hole['point']).buffer(buffer_value).exterior)
                             Point(hole['point']).buffer(buffer_value).exterior)
 
 
         if use_thread:
         if use_thread:
-            def geo_thread(app_obj):
-                app_obj.new_object("geometry", outname, geo_init, plot=plot)
+            def geo_thread(a_obj):
+                a_obj.app_obj.new_object("geometry", outname, geo_init, plot=plot)
 
 
             # Create a promise with the new name
             # Create a promise with the new name
             self.app.collection.promise(outname)
             self.app.collection.promise(outname)
@@ -1205,7 +1205,7 @@ class ExcellonObject(FlatCAMObj, Excellon):
             # Send to worker
             # Send to worker
             self.app.worker_task.emit({'fcn': geo_thread, 'params': [self.app]})
             self.app.worker_task.emit({'fcn': geo_thread, 'params': [self.app]})
         else:
         else:
-            self.app.new_object("geometry", outname, geo_init, plot=plot)
+            self.app.app_obj.new_object("geometry", outname, geo_init, plot=plot)
 
 
         return True, ""
         return True, ""
 
 
@@ -1300,8 +1300,8 @@ class ExcellonObject(FlatCAMObj, Excellon):
                         geo_obj.solid_geometry.append(poly)
                         geo_obj.solid_geometry.append(poly)
 
 
         if use_thread:
         if use_thread:
-            def geo_thread(app_obj):
-                app_obj.new_object("geometry", outname + '_slot', geo_init, plot=plot)
+            def geo_thread(a_obj):
+                a_obj.app_obj.new_object("geometry", outname + '_slot', geo_init, plot=plot)
 
 
             # Create a promise with the new name
             # Create a promise with the new name
             self.app.collection.promise(outname)
             self.app.collection.promise(outname)
@@ -1309,7 +1309,7 @@ class ExcellonObject(FlatCAMObj, Excellon):
             # Send to worker
             # Send to worker
             self.app.worker_task.emit({'fcn': geo_thread, 'params': [self.app]})
             self.app.worker_task.emit({'fcn': geo_thread, 'params': [self.app]})
         else:
         else:
-            self.app.new_object("geometry", outname + '_slot', geo_init, plot=plot)
+            self.app.app_obj.new_object("geometry", outname + '_slot', geo_init, plot=plot)
 
 
         return True, ""
         return True, ""
 
 
@@ -1443,7 +1443,7 @@ class ExcellonObject(FlatCAMObj, Excellon):
         job_name = self.options["name"] + "_cnc"
         job_name = self.options["name"] + "_cnc"
         pp_excellon_name = self.options["ppname_e"]
         pp_excellon_name = self.options["ppname_e"]
 
 
-        # Object initialization function for app.new_object()
+        # Object initialization function for app.app_obj.new_object()
         def job_init(job_obj, app_obj):
         def job_init(job_obj, app_obj):
             assert job_obj.kind == 'cncjob', "Initializer expected a CNCJobObject, got %s" % type(job_obj)
             assert job_obj.kind == 'cncjob', "Initializer expected a CNCJobObject, got %s" % type(job_obj)
 
 
@@ -1506,9 +1506,9 @@ class ExcellonObject(FlatCAMObj, Excellon):
             job_obj.create_geometry()
             job_obj.create_geometry()
 
 
         # To be run in separate thread
         # To be run in separate thread
-        def job_thread(app_obj):
+        def job_thread(a_obj):
             with self.app.proc_container.new(_("Generating CNC Code")):
             with self.app.proc_container.new(_("Generating CNC Code")):
-                app_obj.new_object("cncjob", job_name, job_init)
+                a_obj.app_obj.new_object("cncjob", job_name, job_init)
 
 
         # Create promise for the new name.
         # Create promise for the new name.
         self.app.collection.promise(job_name)
         self.app.collection.promise(job_name)

+ 12 - 12
AppObjects/FlatCAMGeometry.py

@@ -1778,7 +1778,7 @@ class GeometryObject(FlatCAMObj, Geometry):
             self.app.inform.emit(msg)
             self.app.inform.emit(msg)
             return
             return
 
 
-        # Object initialization function for app.new_object()
+        # Object initialization function for app.app_obj.new_object()
         # RUNNING ON SEPARATE THREAD!
         # RUNNING ON SEPARATE THREAD!
         def job_init_single_geometry(job_obj, app_obj):
         def job_init_single_geometry(job_obj, app_obj):
             log.debug("Creating a CNCJob out of a single-geometry")
             log.debug("Creating a CNCJob out of a single-geometry")
@@ -1918,7 +1918,7 @@ class GeometryObject(FlatCAMObj, Geometry):
                 })
                 })
                 dia_cnc_dict.clear()
                 dia_cnc_dict.clear()
 
 
-        # Object initialization function for app.new_object()
+        # Object initialization function for app.app_obj.new_object()
         # RUNNING ON SEPARATE THREAD!
         # RUNNING ON SEPARATE THREAD!
         def job_init_multi_geometry(job_obj, app_obj):
         def job_init_multi_geometry(job_obj, app_obj):
             log.debug("Creating a CNCJob out of a multi-geometry")
             log.debug("Creating a CNCJob out of a multi-geometry")
@@ -2072,15 +2072,15 @@ class GeometryObject(FlatCAMObj, Geometry):
 
 
         if use_thread:
         if use_thread:
             # To be run in separate thread
             # To be run in separate thread
-            def job_thread(app_obj):
+            def job_thread(a_obj):
                 if self.multigeo is False:
                 if self.multigeo is False:
                     with self.app.proc_container.new(_("Generating CNC Code")):
                     with self.app.proc_container.new(_("Generating CNC Code")):
-                        if app_obj.new_object("cncjob", outname, job_init_single_geometry, plot=plot) != 'fail':
-                            app_obj.inform.emit('[success] %s: %s' % (_("CNCjob created"), outname))
+                        if a_obj.app_obj.new_object("cncjob", outname, job_init_single_geometry, plot=plot) != 'fail':
+                            a_obj.inform.emit('[success] %s: %s' % (_("CNCjob created"), outname))
                 else:
                 else:
                     with self.app.proc_container.new(_("Generating CNC Code")):
                     with self.app.proc_container.new(_("Generating CNC Code")):
-                        if app_obj.new_object("cncjob", outname, job_init_multi_geometry) != 'fail':
-                            app_obj.inform.emit('[success] %s: %s' % (_("CNCjob created"), outname))
+                        if a_obj.app_obj.new_object("cncjob", outname, job_init_multi_geometry) != 'fail':
+                            a_obj.inform.emit('[success] %s: %s' % (_("CNCjob created"), outname))
 
 
             # Create a promise with the name
             # Create a promise with the name
             self.app.collection.promise(outname)
             self.app.collection.promise(outname)
@@ -2088,9 +2088,9 @@ class GeometryObject(FlatCAMObj, Geometry):
             self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
             self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
         else:
         else:
             if self.solid_geometry:
             if self.solid_geometry:
-                self.app.new_object("cncjob", outname, job_init_single_geometry, plot=plot)
+                self.app.app_obj.new_object("cncjob", outname, job_init_single_geometry, plot=plot)
             else:
             else:
-                self.app.new_object("cncjob", outname, job_init_multi_geometry, plot=plot)
+                self.app.app_obj.new_object("cncjob", outname, job_init_multi_geometry, plot=plot)
 
 
     def generatecncjob(self, outname=None, dia=None, offset=None, z_cut=None, z_move=None,
     def generatecncjob(self, outname=None, dia=None, offset=None, z_cut=None, z_move=None,
             feedrate=None, feedrate_z=None, feedrate_rapid=None, spindlespeed=None, dwell=None, dwelltime=None,
             feedrate=None, feedrate_z=None, feedrate_rapid=None, spindlespeed=None, dwell=None, dwelltime=None,
@@ -2181,7 +2181,7 @@ class GeometryObject(FlatCAMObj, Geometry):
 
 
         ppname_g = pp if pp else self.options["ppname_g"]
         ppname_g = pp if pp else self.options["ppname_g"]
 
 
-        # Object initialization function for app.new_object()
+        # Object initialization function for app.app_obj.new_object()
         # RUNNING ON SEPARATE THREAD!
         # RUNNING ON SEPARATE THREAD!
         def job_init(job_obj, app_obj):
         def job_init(job_obj, app_obj):
             assert job_obj.kind == 'cncjob', "Initializer expected a CNCJobObject, got %s" % type(job_obj)
             assert job_obj.kind == 'cncjob', "Initializer expected a CNCJobObject, got %s" % type(job_obj)
@@ -2230,7 +2230,7 @@ class GeometryObject(FlatCAMObj, Geometry):
             # To be run in separate thread
             # To be run in separate thread
             def job_thread(app_obj):
             def job_thread(app_obj):
                 with self.app.proc_container.new(_("Generating CNC Code")):
                 with self.app.proc_container.new(_("Generating CNC Code")):
-                    app_obj.new_object("cncjob", outname, job_init, plot=plot)
+                    app_obj.app_obj.new_object("cncjob", outname, job_init, plot=plot)
                     app_obj.inform.emit('[success] %s: %s' % (_("CNCjob created")), outname)
                     app_obj.inform.emit('[success] %s: %s' % (_("CNCjob created")), outname)
 
 
             # Create a promise with the name
             # Create a promise with the name
@@ -2238,7 +2238,7 @@ class GeometryObject(FlatCAMObj, Geometry):
             # Send to worker
             # Send to worker
             self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
             self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
         else:
         else:
-            self.app.new_object("cncjob", outname, job_init, plot=plot)
+            self.app.app_obj.new_object("cncjob", outname, job_init, plot=plot)
 
 
     # def on_plot_cb_click(self, *args):
     # def on_plot_cb_click(self, *args):
     #     if self.muted_ui:
     #     if self.muted_ui:

+ 5 - 5
AppObjects/FlatCAMGerber.py

@@ -530,7 +530,7 @@ class GerberObject(FlatCAMObj, Gerber):
                 return "fail"
                 return "fail"
             geo_obj.solid_geometry = non_copper
             geo_obj.solid_geometry = non_copper
 
 
-        self.app.new_object("geometry", name, geo_init)
+        self.app.app_obj.new_object("geometry", name, geo_init)
 
 
     def on_generatebb_button_click(self, *args):
     def on_generatebb_button_click(self, *args):
         self.app.defaults.report_usage("gerber_on_generatebb_button")
         self.app.defaults.report_usage("gerber_on_generatebb_button")
@@ -556,7 +556,7 @@ class GerberObject(FlatCAMObj, Gerber):
                 return "fail"
                 return "fail"
             geo_obj.solid_geometry = bounding_box
             geo_obj.solid_geometry = bounding_box
 
 
-        self.app.new_object("geometry", name, geo_init)
+        self.app.app_obj.new_object("geometry", name, geo_init)
 
 
     def on_iso_button_click(self, *args):
     def on_iso_button_click(self, *args):
 
 
@@ -605,7 +605,7 @@ class GerberObject(FlatCAMObj, Gerber):
 
 
         # TODO: Do something if this is None. Offer changing name?
         # TODO: Do something if this is None. Offer changing name?
         try:
         try:
-            self.app.new_object("geometry", follow_name, follow_init)
+            self.app.app_obj.new_object("geometry", follow_name, follow_init)
         except Exception as e:
         except Exception as e:
             return "Operation failed: %s" % str(e)
             return "Operation failed: %s" % str(e)
 
 
@@ -942,7 +942,7 @@ class GerberObject(FlatCAMObj, Gerber):
                     geo_obj.solid_geometry = self.area_subtraction(geo_obj.solid_geometry)
                     geo_obj.solid_geometry = self.area_subtraction(geo_obj.solid_geometry)
 
 
             # TODO: Do something if this is None. Offer changing name?
             # TODO: Do something if this is None. Offer changing name?
-            self.app.new_object("geometry", iso_name, iso_init, plot=plot)
+            self.app.app_obj.new_object("geometry", iso_name, iso_init, plot=plot)
         else:
         else:
             for i in range(passes):
             for i in range(passes):
 
 
@@ -1072,7 +1072,7 @@ class GerberObject(FlatCAMObj, Gerber):
                         geo_obj.solid_geometry = self.area_subtraction(geo_obj.solid_geometry)
                         geo_obj.solid_geometry = self.area_subtraction(geo_obj.solid_geometry)
 
 
                 # TODO: Do something if this is None. Offer changing name?
                 # TODO: Do something if this is None. Offer changing name?
-                self.app.new_object("geometry", iso_name, iso_init, plot=plot)
+                self.app.app_obj.new_object("geometry", iso_name, iso_init, plot=plot)
 
 
     def generate_envelope(self, offset, invert, geometry=None, env_iso_type=2, follow=None, nr_passes=0):
     def generate_envelope(self, offset, invert, geometry=None, env_iso_type=2, follow=None, nr_passes=0):
         # isolation_geometry produces an envelope that is going on the left of the geometry
         # isolation_geometry produces an envelope that is going on the left of the geometry

+ 4 - 4
AppObjects/FlatCAMObj.py

@@ -245,7 +245,7 @@ class FlatCAMObj(QtCore.QObject):
             self.app.proc_container.update_view_text('')
             self.app.proc_container.update_view_text('')
             with self.app.proc_container.new('%s...' % _("Plotting")):
             with self.app.proc_container.new('%s...' % _("Plotting")):
                 self.plot()
                 self.plot()
-            self.app.object_changed.emit(self)
+            self.app.app_obj.object_changed.emit(self)
 
 
         self.app.worker_task.emit({'fcn': worker_task, 'params': []})
         self.app.worker_task.emit({'fcn': worker_task, 'params': []})
 
 
@@ -276,7 +276,7 @@ class FlatCAMObj(QtCore.QObject):
             self.app.proc_container.update_view_text('')
             self.app.proc_container.update_view_text('')
             with self.app.proc_container.new('%s...' % _("Plotting")):
             with self.app.proc_container.new('%s...' % _("Plotting")):
                 self.plot()
                 self.plot()
-            self.app.object_changed.emit(self)
+            self.app.app_obj.object_changed.emit(self)
 
 
         self.app.worker_task.emit({'fcn': worker_task, 'params': []})
         self.app.worker_task.emit({'fcn': worker_task, 'params': []})
 
 
@@ -292,7 +292,7 @@ class FlatCAMObj(QtCore.QObject):
             self.app.proc_container.update_view_text('')
             self.app.proc_container.update_view_text('')
             with self.app.proc_container.new('%s...' % _("Plotting")):
             with self.app.proc_container.new('%s...' % _("Plotting")):
                 self.plot()
                 self.plot()
-            self.app.object_changed.emit(self)
+            self.app.app_obj.object_changed.emit(self)
 
 
         self.app.worker_task.emit({'fcn': worker_task, 'params': []})
         self.app.worker_task.emit({'fcn': worker_task, 'params': []})
 
 
@@ -372,7 +372,7 @@ class FlatCAMObj(QtCore.QObject):
         def plot_task():
         def plot_task():
             with self.app.proc_container.new('%s...' % _("Plotting")):
             with self.app.proc_container.new('%s...' % _("Plotting")):
                 self.plot()
                 self.plot()
-            self.app.object_changed.emit(self)
+            self.app.app_obj.object_changed.emit(self)
 
 
         self.app.worker_task.emit({'fcn': plot_task, 'params': []})
         self.app.worker_task.emit({'fcn': plot_task, 'params': []})
 
 

+ 1 - 1
AppObjects/ObjectCollection.py

@@ -553,7 +553,7 @@ class ObjectCollection(QtCore.QAbstractItemModel):
         while name in self.get_names():
         while name in self.get_names():
             # ## Create a new name
             # ## Create a new name
             # Ends with number?
             # Ends with number?
-            log.debug("new_object(): Object name (%s) exists, changing." % name)
+            log.debug("app_obj.new_object(): Object name (%s) exists, changing." % name)
             match = re.search(r'(.*[^\d])?(\d+)$', name)
             match = re.search(r'(.*[^\d])?(\d+)$', name)
             if match:  # Yes: Increment the number!
             if match:  # Yes: Increment the number!
                 base = match.group(1) or ''
                 base = match.group(1) or ''

+ 1 - 1
AppParsers/ParseExcellon.py

@@ -1069,7 +1069,7 @@ class Excellon(Geometry):
         This function first convert to the the units found in the Excellon file but it converts tools that
         This function first convert to the the units found in the Excellon file but it converts tools that
         are not there yet so it has no effect other than it signal that the units are the ones in the file.
         are not there yet so it has no effect other than it signal that the units are the ones in the file.
 
 
-        On object creation, in new_object(), true conversion is done because this is done at the end of the
+        On object creation, in app_obj.new_object(), true conversion is done because this is done at the end of the
         Excellon file parsing, the tools are inside and self.tools is really converted from the units found
         Excellon file parsing, the tools are inside and self.tools is really converted from the units found
         inside the file to the FlatCAM units.
         inside the file to the FlatCAM units.
 
 

+ 1 - 1
AppTool.py

@@ -28,7 +28,7 @@ class AppTool(QtWidgets.QWidget):
         """
         """
 
 
         :param app: The application this tool will run in.
         :param app: The application this tool will run in.
-        :type app: App
+        :type app: AppMain
         :param parent: Qt Parent
         :param parent: Qt Parent
         :return: AppTool
         :return: AppTool
         """
         """

+ 3 - 3
AppTools/ToolCalibration.py

@@ -1352,11 +1352,11 @@ class ToolCalibration(AppTool):
 
 
         try:
         try:
             if obj.kind.lower() == 'excellon':
             if obj.kind.lower() == 'excellon':
-                self.app.new_object("excellon", str(obj_name), initialize_excellon)
+                self.app.app_obj.new_object("excellon", str(obj_name), initialize_excellon)
             elif obj.kind.lower() == 'gerber':
             elif obj.kind.lower() == 'gerber':
-                self.app.new_object("gerber", str(obj_name), initialize_gerber)
+                self.app.app_obj.new_object("gerber", str(obj_name), initialize_gerber)
             elif obj.kind.lower() == 'geometry':
             elif obj.kind.lower() == 'geometry':
-                self.app.new_object("geometry", str(obj_name), initialize_geometry)
+                self.app.app_obj.new_object("geometry", str(obj_name), initialize_geometry)
         except Exception as e:
         except Exception as e:
             log.debug("ToolCalibration.new_calibrated_object() --> %s" % str(e))
             log.debug("ToolCalibration.new_calibrated_object() --> %s" % str(e))
             return "Operation failed: %s" % str(e)
             return "Operation failed: %s" % str(e)

+ 1 - 1
AppTools/ToolCopperThieving.py

@@ -1474,7 +1474,7 @@ class ToolCopperThieving(AppTool):
         obj_name, separatpr, obj_extension = self.sm_object.options['name'].rpartition('.')
         obj_name, separatpr, obj_extension = self.sm_object.options['name'].rpartition('.')
         name = '%s_%s.%s' % (obj_name, 'plating_mask', obj_extension)
         name = '%s_%s.%s' % (obj_name, 'plating_mask', obj_extension)
 
 
-        self.app.new_object('gerber', name, obj_init, autoselected=False)
+        self.app.app_obj.new_object('gerber', name, obj_init, autoselected=False)
 
 
         # Register recent file
         # Register recent file
         self.app.file_opened.emit("gerber", name)
         self.app.file_opened.emit("gerber", name)

+ 3 - 3
AppTools/ToolCutOut.py

@@ -700,7 +700,7 @@ class CutOut(AppTool):
             geo_obj.tools[1]['data']['depthperpass'] = self.maxdepth_entry.get_value()
             geo_obj.tools[1]['data']['depthperpass'] = self.maxdepth_entry.get_value()
 
 
         outname = cutout_obj.options["name"] + "_cutout"
         outname = cutout_obj.options["name"] + "_cutout"
-        self.app.new_object('geometry', outname, geo_init)
+        self.app.app_obj.new_object('geometry', outname, geo_init)
 
 
         cutout_obj.plot()
         cutout_obj.plot()
         self.app.inform.emit('[success] %s' % _("Any form CutOut operation finished."))
         self.app.inform.emit('[success] %s' % _("Any form CutOut operation finished."))
@@ -896,7 +896,7 @@ class CutOut(AppTool):
             geo_obj.tools[1]['data']['depthperpass'] = self.maxdepth_entry.get_value()
             geo_obj.tools[1]['data']['depthperpass'] = self.maxdepth_entry.get_value()
 
 
         outname = cutout_obj.options["name"] + "_cutout"
         outname = cutout_obj.options["name"] + "_cutout"
-        ret = self.app.new_object('geometry', outname, geo_init)
+        ret = self.app.app_obj.new_object('geometry', outname, geo_init)
 
 
         if ret != 'fail':
         if ret != 'fail':
             # cutout_obj.plot()
             # cutout_obj.plot()
@@ -1056,7 +1056,7 @@ class CutOut(AppTool):
             geo_obj.tools[1]['data']['depthperpass'] = self.maxdepth_entry.get_value()
             geo_obj.tools[1]['data']['depthperpass'] = self.maxdepth_entry.get_value()
 
 
         outname = cutout_obj.options["name"] + "_cutout"
         outname = cutout_obj.options["name"] + "_cutout"
-        self.app.new_object('geometry', outname, geo_init)
+        self.app.app_obj.new_object('geometry', outname, geo_init)
 
 
     def cutting_geo(self, pos):
     def cutting_geo(self, pos):
         self.cutting_dia = float(self.dia.get_value())
         self.cutting_dia = float(self.dia.get_value())

+ 4 - 4
AppTools/ToolDblSided.py

@@ -643,7 +643,7 @@ class DblSidedTool(AppTool):
             obj_inst.source_file = app_inst.export_excellon(obj_name=obj_inst.options['name'], local_use=obj_inst,
             obj_inst.source_file = app_inst.export_excellon(obj_name=obj_inst.options['name'], local_use=obj_inst,
                                                             filename=None, use_thread=False)
                                                             filename=None, use_thread=False)
 
 
-        self.app.new_object("excellon", "Alignment Drills", obj_init)
+        self.app.app_obj.new_object("excellon", "Alignment Drills", obj_init)
         self.drill_values = ''
         self.drill_values = ''
         self.app.inform.emit('[success] %s' % _("Excellon object with alignment drills created..."))
         self.app.inform.emit('[success] %s' % _("Excellon object with alignment drills created..."))
 
 
@@ -686,7 +686,7 @@ class DblSidedTool(AppTool):
             py = 0.5 * (ymin + ymax)
             py = 0.5 * (ymin + ymax)
 
 
         fcobj.mirror(axis, [px, py])
         fcobj.mirror(axis, [px, py])
-        self.app.object_changed.emit(fcobj)
+        self.app.app_obj.object_changed.emit(fcobj)
         fcobj.plot()
         fcobj.plot()
         self.app.inform.emit('[success] Gerber %s %s...' % (str(fcobj.options['name']), _("was mirrored")))
         self.app.inform.emit('[success] Gerber %s %s...' % (str(fcobj.options['name']), _("was mirrored")))
 
 
@@ -730,7 +730,7 @@ class DblSidedTool(AppTool):
             py = 0.5 * (ymin + ymax)
             py = 0.5 * (ymin + ymax)
 
 
         fcobj.mirror(axis, [px, py])
         fcobj.mirror(axis, [px, py])
-        self.app.object_changed.emit(fcobj)
+        self.app.app_obj.object_changed.emit(fcobj)
         fcobj.plot()
         fcobj.plot()
         self.app.inform.emit('[success] Excellon %s %s...' % (str(fcobj.options['name']), _("was mirrored")))
         self.app.inform.emit('[success] Excellon %s %s...' % (str(fcobj.options['name']), _("was mirrored")))
 
 
@@ -767,7 +767,7 @@ class DblSidedTool(AppTool):
             py = 0.5 * (ymin + ymax)
             py = 0.5 * (ymin + ymax)
 
 
         fcobj.mirror(axis, [px, py])
         fcobj.mirror(axis, [px, py])
-        self.app.object_changed.emit(fcobj)
+        self.app.app_obj.object_changed.emit(fcobj)
         fcobj.plot()
         fcobj.plot()
         self.app.inform.emit('[success] Geometry %s %s...' % (str(fcobj.options['name']), _("was mirrored")))
         self.app.inform.emit('[success] Geometry %s %s...' % (str(fcobj.options['name']), _("was mirrored")))
 
 

+ 1 - 1
AppTools/ToolExtractDrills.py

@@ -655,7 +655,7 @@ class ToolExtractDrills(AppTool):
             obj_inst.source_file = self.app.export_excellon(obj_name=outname, local_use=obj_inst, filename=None,
             obj_inst.source_file = self.app.export_excellon(obj_name=outname, local_use=obj_inst, filename=None,
                                                             use_thread=False)
                                                             use_thread=False)
 
 
-        self.app.new_object("excellon", outname, obj_init)
+        self.app.app_obj.new_object("excellon", outname, obj_init)
 
 
     def on_hole_size_toggle(self, val):
     def on_hole_size_toggle(self, val):
         if val == "fixed":
         if val == "fixed":

+ 2 - 2
AppTools/ToolFilm.py

@@ -775,7 +775,7 @@ class Film(AppTool):
                 new_obj.solid_geometry = deepcopy(punched_solid_geometry)
                 new_obj.solid_geometry = deepcopy(punched_solid_geometry)
 
 
             outname = name + "_punched"
             outname = name + "_punched"
-            self.app.new_object('gerber', outname, init_func)
+            self.app.app_obj.new_object('gerber', outname, init_func)
 
 
             self.generate_positive_normal_film(outname, boxname, factor=factor, ftype=ftype)
             self.generate_positive_normal_film(outname, boxname, factor=factor, ftype=ftype)
         else:
         else:
@@ -826,7 +826,7 @@ class Film(AppTool):
                 new_obj.solid_geometry = deepcopy(punched_solid_geometry)
                 new_obj.solid_geometry = deepcopy(punched_solid_geometry)
 
 
             outname = name + "_punched"
             outname = name + "_punched"
-            self.app.new_object('gerber', outname, init_func)
+            self.app.app_obj.new_object('gerber', outname, init_func)
 
 
             self.generate_positive_normal_film(outname, boxname, factor=factor, ftype=ftype)
             self.generate_positive_normal_film(outname, boxname, factor=factor, ftype=ftype)
 
 

+ 1 - 1
AppTools/ToolImage.py

@@ -288,7 +288,7 @@ class ToolImage(AppTool):
             name = outname or filename.split('/')[-1].split('\\')[-1]
             name = outname or filename.split('/')[-1].split('\\')[-1]
             units = self.app.defaults['units']
             units = self.app.defaults['units']
 
 
-            self.app.new_object(obj_type, name, obj_init)
+            self.app.app_obj.new_object(obj_type, name, obj_init)
 
 
             # Register recent file
             # Register recent file
             self.app.file_opened.emit("image", filename)
             self.app.file_opened.emit("image", filename)

+ 1 - 1
AppTools/ToolInvertGerber.py

@@ -293,7 +293,7 @@ class ToolInvertGerber(AppTool):
             new_obj.source_file = self.app.export_gerber(obj_name=outname, filename=None,
             new_obj.source_file = self.app.export_gerber(obj_name=outname, filename=None,
                                                          local_use=new_obj, use_thread=False)
                                                          local_use=new_obj, use_thread=False)
 
 
-        self.app.new_object('gerber', outname, init_func)
+        self.app.app_obj.new_object('gerber', outname, init_func)
 
 
     def reset_fields(self):
     def reset_fields(self):
         self.gerber_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
         self.gerber_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))

+ 5 - 5
AppTools/ToolNCC.py

@@ -2881,12 +2881,12 @@ class NonCopperClear(AppTool, Gerber):
         # ###########################################################################################
         # ###########################################################################################
         # Create the Job function and send it to the worker to be processed in another thread #######
         # Create the Job function and send it to the worker to be processed in another thread #######
         # ###########################################################################################
         # ###########################################################################################
-        def job_thread(app_obj):
+        def job_thread(a_obj):
             try:
             try:
                 if rest_machining_choice is True:
                 if rest_machining_choice is True:
-                    app_obj.new_object("geometry", name, gen_clear_area_rest)
+                    a_obj.app_obj.new_object("geometry", name, gen_clear_area_rest)
                 else:
                 else:
-                    app_obj.new_object("geometry", name, gen_clear_area)
+                    a_obj.app_obj.new_object("geometry", name, gen_clear_area)
             except grace:
             except grace:
                 if run_threaded:
                 if run_threaded:
                     proc.done()
                     proc.done()
@@ -3881,9 +3881,9 @@ class NonCopperClear(AppTool, Gerber):
         def job_thread(app_obj):
         def job_thread(app_obj):
             try:
             try:
                 if rest_machining_choice is True:
                 if rest_machining_choice is True:
-                    app_obj.new_object("geometry", name, gen_clear_area_rest, plot=plot)
+                    app_obj.app_obj.new_object("geometry", name, gen_clear_area_rest, plot=plot)
                 else:
                 else:
-                    app_obj.new_object("geometry", name, gen_clear_area, plot=plot)
+                    app_obj.app_obj.new_object("geometry", name, gen_clear_area, plot=plot)
             except grace:
             except grace:
                 if run_threaded:
                 if run_threaded:
                     proc.done()
                     proc.done()

+ 2 - 2
AppTools/ToolPDF.py

@@ -205,7 +205,7 @@ class ToolPDF(AppTool):
 
 
         with self.app.proc_container.new(_("Rendering PDF layer #%d ...") % int(layer_nr)):
         with self.app.proc_container.new(_("Rendering PDF layer #%d ...") % int(layer_nr)):
 
 
-            ret_val = self.app.new_object("excellon", outname, obj_init, autoselected=False)
+            ret_val = self.app.app_obj.new_object("excellon", outname, obj_init, autoselected=False)
             if ret_val == 'fail':
             if ret_val == 'fail':
                 self.app.inform.emit('[ERROR_NOTCL] %s' % _('Open PDF file failed.'))
                 self.app.inform.emit('[ERROR_NOTCL] %s' % _('Open PDF file failed.'))
                 return
                 return
@@ -278,7 +278,7 @@ class ToolPDF(AppTool):
 
 
         with self.app.proc_container.new(_("Rendering PDF layer #%d ...") % int(layer_nr)):
         with self.app.proc_container.new(_("Rendering PDF layer #%d ...") % int(layer_nr)):
 
 
-            ret = self.app.new_object('gerber', outname, obj_init, autoselected=False)
+            ret = self.app.app_obj.new_object('gerber', outname, obj_init, autoselected=False)
             if ret == 'fail':
             if ret == 'fail':
                 self.app.inform.emit('[ERROR_NOTCL] %s' % _('Open PDF file failed.'))
                 self.app.inform.emit('[ERROR_NOTCL] %s' % _('Open PDF file failed.'))
                 return
                 return

+ 5 - 5
AppTools/ToolPaint.py

@@ -2315,7 +2315,7 @@ class ToolPaint(AppTool, Gerber):
 
 
         def job_thread(app_obj):
         def job_thread(app_obj):
             try:
             try:
-                ret = app_obj.new_object("geometry", name, job_init, plot=plot)
+                ret = app_obj.app_obj.new_object("geometry", name, job_init, plot=plot)
             except grace:
             except grace:
                 proc.done()
                 proc.done()
                 return
                 return
@@ -2823,9 +2823,9 @@ class ToolPaint(AppTool, Gerber):
         def job_thread(app_obj):
         def job_thread(app_obj):
             try:
             try:
                 if self.rest_cb.isChecked():
                 if self.rest_cb.isChecked():
-                    ret = app_obj.new_object("geometry", name, gen_paintarea_rest_machining, plot=plot)
+                    ret = app_obj.app_obj.new_object("geometry", name, gen_paintarea_rest_machining, plot=plot)
                 else:
                 else:
-                    ret = app_obj.new_object("geometry", name, gen_paintarea, plot=plot)
+                    ret = app_obj.app_obj.new_object("geometry", name, gen_paintarea, plot=plot)
             except grace:
             except grace:
                 proc.done()
                 proc.done()
                 return
                 return
@@ -3320,9 +3320,9 @@ class ToolPaint(AppTool, Gerber):
         def job_thread(app_obj):
         def job_thread(app_obj):
             try:
             try:
                 if self.rest_cb.isChecked():
                 if self.rest_cb.isChecked():
-                    ret = app_obj.new_object("geometry", name, gen_paintarea_rest_machining, plot=plot)
+                    ret = app_obj.app_obj.new_object("geometry", name, gen_paintarea_rest_machining, plot=plot)
                 else:
                 else:
-                    ret = app_obj.new_object("geometry", name, gen_paintarea, plot=plot)
+                    ret = app_obj.app_obj.new_object("geometry", name, gen_paintarea, plot=plot)
             except grace:
             except grace:
                 proc.done()
                 proc.done()
                 return
                 return

+ 2 - 2
AppTools/ToolPanelize.py

@@ -794,9 +794,9 @@ class Panelize(AppTool):
 
 
                 self.app.inform.emit('%s: %d' % (_("Generating panel... Spawning copies"), (int(rows * columns))))
                 self.app.inform.emit('%s: %d' % (_("Generating panel... Spawning copies"), (int(rows * columns))))
                 if panel_source_obj.kind == 'excellon':
                 if panel_source_obj.kind == 'excellon':
-                    self.app.new_object("excellon", self.outname, job_init_excellon, plot=True, autoselected=True)
+                    self.app.app_obj.new_object("excellon", self.outname, job_init_excellon, plot=True, autoselected=True)
                 else:
                 else:
-                    self.app.new_object(panel_type, self.outname, job_init_geometry, plot=True, autoselected=True)
+                    self.app.app_obj.new_object(panel_type, self.outname, job_init_geometry, plot=True, autoselected=True)
 
 
         if self.constrain_flag is False:
         if self.constrain_flag is False:
             self.app.inform.emit('[success] %s' % _("Panel done..."))
             self.app.inform.emit('[success] %s' % _("Panel done..."))

+ 1 - 1
AppTools/ToolPcbWizard.py

@@ -452,7 +452,7 @@ class PcbWizard(AppTool):
                     # Object name
                     # Object name
                     name = self.outname
                     name = self.outname
 
 
-                    ret_val = self.app.new_object("excellon", name, obj_init, autoselected=False)
+                    ret_val = self.app.app_obj.new_object("excellon", name, obj_init, autoselected=False)
                     if ret_val == 'fail':
                     if ret_val == 'fail':
                         self.app.inform.emit('[ERROR_NOTCL] %s' % _('Import Excellon file failed.'))
                         self.app.inform.emit('[ERROR_NOTCL] %s' % _('Import Excellon file failed.'))
                         return
                         return

+ 4 - 4
AppTools/ToolPunchGerber.py

@@ -591,7 +591,7 @@ class ToolPunchGerber(AppTool):
                 new_obj.source_file = self.app.export_gerber(obj_name=outname, filename=None,
                 new_obj.source_file = self.app.export_gerber(obj_name=outname, filename=None,
                                                              local_use=new_obj, use_thread=False)
                                                              local_use=new_obj, use_thread=False)
 
 
-            self.app.new_object('gerber', outname, init_func)
+            self.app.app_obj.new_object('gerber', outname, init_func)
         elif punch_method == 'fixed':
         elif punch_method == 'fixed':
             punch_size = float(self.dia_entry.get_value())
             punch_size = float(self.dia_entry.get_value())
 
 
@@ -705,7 +705,7 @@ class ToolPunchGerber(AppTool):
                 new_obj.source_file = self.app.export_gerber(obj_name=outname, filename=None,
                 new_obj.source_file = self.app.export_gerber(obj_name=outname, filename=None,
                                                              local_use=new_obj, use_thread=False)
                                                              local_use=new_obj, use_thread=False)
 
 
-            self.app.new_object('gerber', outname, init_func)
+            self.app.app_obj.new_object('gerber', outname, init_func)
         elif punch_method == 'ring':
         elif punch_method == 'ring':
             circ_r_val = self.circular_ring_entry.get_value()
             circ_r_val = self.circular_ring_entry.get_value()
             oblong_r_val = self.oblong_ring_entry.get_value()
             oblong_r_val = self.oblong_ring_entry.get_value()
@@ -847,7 +847,7 @@ class ToolPunchGerber(AppTool):
                 new_obj.source_file = self.app.export_gerber(obj_name=outname, filename=None,
                 new_obj.source_file = self.app.export_gerber(obj_name=outname, filename=None,
                                                              local_use=new_obj, use_thread=False)
                                                              local_use=new_obj, use_thread=False)
 
 
-            self.app.new_object('gerber', outname, init_func)
+            self.app.app_obj.new_object('gerber', outname, init_func)
 
 
         elif punch_method == 'prop':
         elif punch_method == 'prop':
             prop_factor = self.factor_entry.get_value() / 100.0
             prop_factor = self.factor_entry.get_value() / 100.0
@@ -986,7 +986,7 @@ class ToolPunchGerber(AppTool):
                 new_obj.source_file = self.app.export_gerber(obj_name=outname, filename=None,
                 new_obj.source_file = self.app.export_gerber(obj_name=outname, filename=None,
                                                              local_use=new_obj, use_thread=False)
                                                              local_use=new_obj, use_thread=False)
 
 
-            self.app.new_object('gerber', outname, init_func)
+            self.app.app_obj.new_object('gerber', outname, init_func)
 
 
     def reset_fields(self):
     def reset_fields(self):
         self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
         self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))

+ 1 - 1
AppTools/ToolRulesCheck.py

@@ -1625,7 +1625,7 @@ class RulesCheck(AppTool):
             new_obj.source_file = txt
             new_obj.source_file = txt
             new_obj.read_only = True
             new_obj.read_only = True
 
 
-        self.app.new_object('document', name='Rules Check results', initialize=init, plot=False)
+        self.app.app_obj.new_object('document', name='Rules Check results', initialize=init, plot=False)
 
 
     def reset_fields(self):
     def reset_fields(self):
         # self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
         # self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))

+ 6 - 6
AppTools/ToolSolderPaste.py

@@ -9,7 +9,7 @@ from AppTool import AppTool
 from Common import LoudDict
 from Common import LoudDict
 from AppGUI.GUIElements import FCComboBox, FCEntry, FCTable, \
 from AppGUI.GUIElements import FCComboBox, FCEntry, FCTable, \
     FCInputDialog, FCDoubleSpinner, FCSpinner, FCFileSaveDialog
     FCInputDialog, FCDoubleSpinner, FCSpinner, FCFileSaveDialog
-from App import log
+from AppMain import log
 from camlib import distance
 from camlib import distance
 from AppEditors.FlatCAMTextEditor import TextEditor
 from AppEditors.FlatCAMTextEditor import TextEditor
 
 
@@ -1257,7 +1257,7 @@ class SolderPaste(AppTool):
         if use_thread:
         if use_thread:
             def job_thread(app_obj):
             def job_thread(app_obj):
                 try:
                 try:
-                    app_obj.new_object("geometry", name + "_solderpaste", geo_init)
+                    app_obj.app_obj.new_object("geometry", name + "_solderpaste", geo_init)
                 except Exception as e:
                 except Exception as e:
                     log.error("SolderPaste.on_create_geo() --> %s" % str(e))
                     log.error("SolderPaste.on_create_geo() --> %s" % str(e))
                     proc.done()
                     proc.done()
@@ -1271,7 +1271,7 @@ class SolderPaste(AppTool):
             # Background
             # Background
             self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
             self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
         else:
         else:
-            self.app.new_object("geometry", name + "_solderpaste", geo_init)
+            self.app.app_obj.new_object("geometry", name + "_solderpaste", geo_init)
 
 
     def on_create_gcode_click(self, signal):
     def on_create_gcode_click(self, signal):
         """
         """
@@ -1331,7 +1331,7 @@ class SolderPaste(AppTool):
             self.app.inform.emit(msg)
             self.app.inform.emit(msg)
             return
             return
 
 
-        # Object initialization function for app.new_object()
+        # Object initialization function for app.app_obj.new_object()
         # RUNNING ON SEPARATE THREAD!
         # RUNNING ON SEPARATE THREAD!
         def job_init(job_obj):
         def job_init(job_obj):
             assert job_obj.kind == 'cncjob', \
             assert job_obj.kind == 'cncjob', \
@@ -1388,7 +1388,7 @@ class SolderPaste(AppTool):
             # To be run in separate thread
             # To be run in separate thread
             def job_thread(app_obj):
             def job_thread(app_obj):
                 with self.app.proc_container.new("Generating CNC Code"):
                 with self.app.proc_container.new("Generating CNC Code"):
-                    if app_obj.new_object("cncjob", name, job_init) != 'fail':
+                    if app_obj.app_obj.new_object("cncjob", name, job_init) != 'fail':
                         app_obj.inform.emit('[success] [success] %s: %s' %
                         app_obj.inform.emit('[success] [success] %s: %s' %
                                             (_("ToolSolderPaste CNCjob created"), name))
                                             (_("ToolSolderPaste CNCjob created"), name))
             # Create a promise with the name
             # Create a promise with the name
@@ -1396,7 +1396,7 @@ class SolderPaste(AppTool):
             # Send to worker
             # Send to worker
             self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
             self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
         else:
         else:
-            self.app.new_object("cncjob", name, job_init)
+            self.app.app_obj.new_object("cncjob", name, job_init)
 
 
     def on_view_gcode(self):
     def on_view_gcode(self):
         """
         """

+ 2 - 2
AppTools/ToolSub.py

@@ -456,7 +456,7 @@ class ToolSub(AppTool):
             grb_obj.follow_geometry = deepcopy(follow_buff)
             grb_obj.follow_geometry = deepcopy(follow_buff)
 
 
         with self.app.proc_container.new(_("Generating new object ...")):
         with self.app.proc_container.new(_("Generating new object ...")):
-            ret = self.app.new_object('gerber', outname, obj_init, autoselected=False)
+            ret = self.app.app_obj.new_object('gerber', outname, obj_init, autoselected=False)
             if ret == 'fail':
             if ret == 'fail':
                 self.app.inform.emit('[ERROR_NOTCL] %s' %
                 self.app.inform.emit('[ERROR_NOTCL] %s' %
                                      _('Generating new object failed.'))
                                      _('Generating new object failed.'))
@@ -659,7 +659,7 @@ class ToolSub(AppTool):
                 geo_obj.multigeo = False
                 geo_obj.multigeo = False
 
 
         with self.app.proc_container.new(_("Generating new object ...")):
         with self.app.proc_container.new(_("Generating new object ...")):
-            ret = self.app.new_object('geometry', outname, obj_init, autoselected=False)
+            ret = self.app.app_obj.new_object('geometry', outname, obj_init, autoselected=False)
             if ret == 'fail':
             if ret == 'fail':
                 self.app.inform.emit('[ERROR_NOTCL] %s' %
                 self.app.inform.emit('[ERROR_NOTCL] %s' %
                                      _('Generating new object failed.'))
                                      _('Generating new object failed.'))

+ 6 - 6
AppTools/ToolTransform.py

@@ -702,7 +702,7 @@ class ToolTransform(AppTool):
                             self.app.inform.emit(_("CNCJob objects can't be rotated."))
                             self.app.inform.emit(_("CNCJob objects can't be rotated."))
                         else:
                         else:
                             sel_obj.rotate(-num, point=(px, py))
                             sel_obj.rotate(-num, point=(px, py))
-                            self.app.object_changed.emit(sel_obj)
+                            self.app.app_obj.object_changed.emit(sel_obj)
 
 
                         # add information to the object that it was changed and how much
                         # add information to the object that it was changed and how much
                         sel_obj.options['rotate'] = num
                         sel_obj.options['rotate'] = num
@@ -776,7 +776,7 @@ class ToolTransform(AppTool):
                                 else:
                                 else:
                                     sel_obj.options['mirror_x'] = True
                                     sel_obj.options['mirror_x'] = True
                                 self.app.inform.emit('[success] %s...' % _('Flip on the X axis done'))
                                 self.app.inform.emit('[success] %s...' % _('Flip on the X axis done'))
-                            self.app.object_changed.emit(sel_obj)
+                            self.app.app_obj.object_changed.emit(sel_obj)
                         sel_obj.plot()
                         sel_obj.plot()
                 except Exception as e:
                 except Exception as e:
                     self.app.inform.emit('[ERROR_NOTCL] %s %s, %s.' %
                     self.app.inform.emit('[ERROR_NOTCL] %s %s, %s.' %
@@ -825,7 +825,7 @@ class ToolTransform(AppTool):
                                 sel_obj.skew(0, num, point=(xminimal, yminimal))
                                 sel_obj.skew(0, num, point=(xminimal, yminimal))
                                 # add information to the object that it was changed and how much
                                 # add information to the object that it was changed and how much
                                 sel_obj.options['skew_y'] = num
                                 sel_obj.options['skew_y'] = num
-                            self.app.object_changed.emit(sel_obj)
+                            self.app.app_obj.object_changed.emit(sel_obj)
                         sel_obj.plot()
                         sel_obj.plot()
                     self.app.inform.emit('[success] %s %s %s...' % (_('Skew on the'),  str(axis), _("axis done")))
                     self.app.inform.emit('[success] %s %s %s...' % (_('Skew on the'),  str(axis), _("axis done")))
                 except Exception as e:
                 except Exception as e:
@@ -878,7 +878,7 @@ class ToolTransform(AppTool):
                             # add information to the object that it was changed and how much
                             # add information to the object that it was changed and how much
                             sel_obj.options['scale_x'] = xfactor
                             sel_obj.options['scale_x'] = xfactor
                             sel_obj.options['scale_y'] = yfactor
                             sel_obj.options['scale_y'] = yfactor
-                            self.app.object_changed.emit(sel_obj)
+                            self.app.app_obj.object_changed.emit(sel_obj)
                         sel_obj.plot()
                         sel_obj.plot()
 
 
                     self.app.inform.emit('[success] %s %s %s...' % (_('Scale on the'), str(axis), _('axis done')))
                     self.app.inform.emit('[success] %s %s %s...' % (_('Scale on the'), str(axis), _('axis done')))
@@ -908,7 +908,7 @@ class ToolTransform(AppTool):
                                 sel_obj.offset((0, num))
                                 sel_obj.offset((0, num))
                                 # add information to the object that it was changed and how much
                                 # add information to the object that it was changed and how much
                                 sel_obj.options['offset_y'] = num
                                 sel_obj.options['offset_y'] = num
-                            self.app.object_changed.emit(sel_obj)
+                            self.app.app_obj.object_changed.emit(sel_obj)
                         sel_obj.plot()
                         sel_obj.plot()
 
 
                     self.app.inform.emit('[success] %s %s %s...' % (_('Offset on the'), str(axis), _('axis done')))
                     self.app.inform.emit('[success] %s %s %s...' % (_('Offset on the'), str(axis), _('axis done')))
@@ -942,7 +942,7 @@ class ToolTransform(AppTool):
                         elif sel_obj.kind.lower() == 'geometry':
                         elif sel_obj.kind.lower() == 'geometry':
                             sel_obj.buffer(value, join, factor)
                             sel_obj.buffer(value, join, factor)
 
 
-                        self.app.object_changed.emit(sel_obj)
+                        self.app.app_obj.object_changed.emit(sel_obj)
                         sel_obj.plot()
                         sel_obj.plot()
 
 
                     self.app.inform.emit('[success] %s...' % _('Buffer done'))
                     self.app.inform.emit('[success] %s...' % _('Buffer done'))

+ 2 - 1
CHANGELOG.md

@@ -20,6 +20,7 @@ CHANGELOG for FlatCAM beta
 - removed reference to postprocessors and replaced it with preprocessors
 - removed reference to postprocessors and replaced it with preprocessors
 - more refactoring class names
 - more refactoring class names
 - moved some of the methods from the App class to the ObjectCollection class
 - moved some of the methods from the App class to the ObjectCollection class
+- moved all the new_object related methods in their own class AppObjects.AppObject
 
 
 17.05.2020
 17.05.2020
 
 
@@ -4239,7 +4240,7 @@ still copper leftovers.
 - modified generate_milling method which had issues from the Python3 port (it could not sort the tools due of dict to dict comparison no longer possible).
 - modified generate_milling method which had issues from the Python3 port (it could not sort the tools due of dict to dict comparison no longer possible).
 - modified the 'default' preprocessor in order to include a space between the value of Xcoord and the following Y
 - modified the 'default' preprocessor in order to include a space between the value of Xcoord and the following Y
 - made optional the using of threads for the milling command; by default it is OFF (False) because in the current configuration it creates issues when it is using threads
 - made optional the using of threads for the milling command; by default it is OFF (False) because in the current configuration it creates issues when it is using threads
-- modified the Panelize function and Tcl command Panelize. It was having issues due to multithreading (kept trying to modify a dictionary in redraw() method)and automatically selecting the last created object (feature introduced by me). I've added a parameter to the new_object method, named autoselected (by default it is True) and in the panelize method I initialized it with False.
+- modified the Panelize function and Tcl command Panelize. It was having issues due to multithreading (kept trying to modify a dictionary in redraw() method)and automatically selecting the last created object (feature introduced by me). I've added a parameter to the app_obj.new_object method, named autoselected (by default it is True) and in the panelize method I initialized it with False.
 By initializing the plot parameter with False for the temporary objects, I have increased dramatically the  generation speed of the panel because now the temporary object are no longer ploted which consumed time.
 By initializing the plot parameter with False for the temporary objects, I have increased dramatically the  generation speed of the panel because now the temporary object are no longer ploted which consumed time.
 - replaced log.warn() with log.warning() in camlib.py. Reason: deprecated
 - replaced log.warn() with log.warning() in camlib.py. Reason: deprecated
 - fixed the issue that the "Defaults" button was having no effect when clicked and Options Combo was in Project Options
 - fixed the issue that the "Defaults" button was having no effect when clicked and Options Combo was in Project Options

+ 1 - 1
FlatCAM.py

@@ -3,7 +3,7 @@ import os
 
 
 from PyQt5 import QtWidgets
 from PyQt5 import QtWidgets
 from PyQt5.QtCore import QSettings, Qt
 from PyQt5.QtCore import QSettings, Qt
-from App import App
+from AppMain import App
 from AppGUI import VisPyPatches
 from AppGUI import VisPyPatches
 
 
 from multiprocessing import freeze_support
 from multiprocessing import freeze_support

+ 2 - 2
tclCommands/TclCommand.py

@@ -1,6 +1,6 @@
 import sys
 import sys
 import re
 import re
-import App
+import AppMain
 import abc
 import abc
 import collections
 import collections
 from PyQt5 import QtCore
 from PyQt5 import QtCore
@@ -53,7 +53,7 @@ class TclCommand(object):
         if self.app is None:
         if self.app is None:
             raise TypeError('Expected app to be FlatCAMApp instance.')
             raise TypeError('Expected app to be FlatCAMApp instance.')
 
 
-        if not isinstance(self.app, App.App):
+        if not isinstance(self.app, AppMain.App):
             raise TypeError('Expected FlatCAMApp, got %s.' % type(app))
             raise TypeError('Expected FlatCAMApp, got %s.' % type(app))
 
 
         self.log = self.app.log
         self.log = self.app.log

+ 2 - 2
tclCommands/TclCommandAlignDrill.py

@@ -189,7 +189,7 @@ class TclCommandAlignDrill(TclCommandSignaled):
                 px = 0.5 * (xmin + xmax)
                 px = 0.5 * (xmin + xmax)
                 py = 0.5 * (ymin + ymax)
                 py = 0.5 * (ymin + ymax)
 
 
-                obj.app.new_object("excellon", outname, alligndrill_init_me, plot=False)
+                obj.app.app_obj.new_object("excellon", outname, alligndrill_init_me, plot=False)
 
 
             except Exception as e:
             except Exception as e:
                 return "Operation failed: %s" % str(e)
                 return "Operation failed: %s" % str(e)
@@ -205,7 +205,7 @@ class TclCommandAlignDrill(TclCommandSignaled):
             try:
             try:
                 px = dist
                 px = dist
                 py = dist
                 py = dist
-                obj.app.new_object("excellon", outname, alligndrill_init_me, plot=False)
+                obj.app.app_obj.new_object("excellon", outname, alligndrill_init_me, plot=False)
             except Exception as e:
             except Exception as e:
                 return "Operation failed: %s" % str(e)
                 return "Operation failed: %s" % str(e)
 
 

+ 1 - 1
tclCommands/TclCommandAlignDrillGrid.py

@@ -111,4 +111,4 @@ class TclCommandAlignDrillGrid(TclCommandSignaled):
             init_obj.create_geometry()
             init_obj.create_geometry()
 
 
         # Create the new object
         # Create the new object
-        self.app.new_object("excellon", outname, aligndrillgrid_init_me, plot=False)
+        self.app.app_obj.new_object("excellon", outname, aligndrillgrid_init_me, plot=False)

+ 1 - 1
tclCommands/TclCommandBbox.py

@@ -100,6 +100,6 @@ class TclCommandBbox(TclCommand):
                     bounding_box = bounding_box.envelope
                     bounding_box = bounding_box.envelope
                 geo_obj.solid_geometry = bounding_box
                 geo_obj.solid_geometry = bounding_box
 
 
-            self.app.new_object("geometry", args['outname'], geo_init, plot=False)
+            self.app.app_obj.new_object("geometry", args['outname'], geo_init, plot=False)
         except Exception as e:
         except Exception as e:
             return "Operation failed: %s" % str(e)
             return "Operation failed: %s" % str(e)

+ 1 - 1
tclCommands/TclCommandCutout.py

@@ -137,7 +137,7 @@ class TclCommandCutout(TclCommand):
             geo_obj.solid_geometry = cascaded_union([LineString(segment) for segment in cuts])
             geo_obj.solid_geometry = cascaded_union([LineString(segment) for segment in cuts])
 
 
         try:
         try:
-            self.app.new_object("geometry", outname, geo_init_me, plot=False)
+            self.app.app_obj.new_object("geometry", outname, geo_init_me, plot=False)
             self.app.inform.emit("[success] Rectangular-form Cutout operation finished.")
             self.app.inform.emit("[success] Rectangular-form Cutout operation finished.")
         except Exception as e:
         except Exception as e:
             return "Operation failed: %s" % str(e)
             return "Operation failed: %s" % str(e)

+ 1 - 1
tclCommands/TclCommandDrillcncjob.py

@@ -343,4 +343,4 @@ class TclCommandDrillcncjob(TclCommandSignaled):
             job_obj.gcode_parse()
             job_obj.gcode_parse()
             job_obj.create_geometry()
             job_obj.create_geometry()
 
 
-        self.app.new_object("cncjob", args['outname'], job_init, plot=False)
+        self.app.app_obj.new_object("cncjob", args['outname'], job_init, plot=False)

+ 1 - 1
tclCommands/TclCommandExteriors.py

@@ -66,4 +66,4 @@ class TclCommandExteriors(TclCommandSignaled):
             geo_obj.solid_geometry = obj_exteriors
             geo_obj.solid_geometry = obj_exteriors
 
 
         obj_exteriors = obj.get_exteriors()
         obj_exteriors = obj.get_exteriors()
-        self.app.new_object('geometry', outname, geo_init, plot=False)
+        self.app.app_obj.new_object('geometry', outname, geo_init, plot=False)

+ 2 - 5
tclCommands/TclCommandGeoCutout.py

@@ -300,11 +300,8 @@ class TclCommandGeoCutout(TclCommandSignaled):
 
 
                 app_obj.inform.emit("[success] %s" % _("Any-form Cutout operation finished."))
                 app_obj.inform.emit("[success] %s" % _("Any-form Cutout operation finished."))
 
 
-            self.app.new_object('geometry', outname, geo_init, plot=False)
+            self.app.app_obj.new_object('geometry', outname, geo_init, plot=False)
 
 
-            # cutout_obj.plot()
-            # self.app.inform.emit("[success] Any-form Cutout operation finished.")
-            # self.app.plots_updated.emit()
         elif cutout_obj.kind == 'gerber':
         elif cutout_obj.kind == 'gerber':
 
 
             def geo_init(geo_obj, app_obj):
             def geo_init(geo_obj, app_obj):
@@ -358,7 +355,7 @@ class TclCommandGeoCutout(TclCommandSignaled):
                 geo_obj.options['ymax'] = cutout_obj.options['ymax']
                 geo_obj.options['ymax'] = cutout_obj.options['ymax']
                 app_obj.inform.emit("[success] %s" % _("Any-form Cutout operation finished."))
                 app_obj.inform.emit("[success] %s" % _("Any-form Cutout operation finished."))
 
 
-            self.app.new_object('geometry', outname, geo_init, plot=False)
+            self.app.app_obj.new_object('geometry', outname, geo_init, plot=False)
 
 
             cutout_obj = self.app.collection.get_by_name(outname)
             cutout_obj = self.app.collection.get_by_name(outname)
         else:
         else:

+ 1 - 1
tclCommands/TclCommandImportSvg.py

@@ -76,7 +76,7 @@ class TclCommandImportSvg(TclCommandSignaled):
         with self.app.proc_container.new("Import SVG"):
         with self.app.proc_container.new("Import SVG"):
 
 
             # Object creation
             # Object creation
-            self.app.new_object(obj_type, outname, obj_init, plot=False)
+            self.app.app_obj.new_object(obj_type, outname, obj_init, plot=False)
 
 
             # Register recent file
             # Register recent file
             self.app.file_opened.emit("svg", filename)
             self.app.file_opened.emit("svg", filename)

+ 1 - 1
tclCommands/TclCommandInteriors.py

@@ -67,4 +67,4 @@ class TclCommandInteriors(TclCommandSignaled):
             geo_obj.solid_geometry = obj_interiors
             geo_obj.solid_geometry = obj_interiors
 
 
         obj_interiors = obj.get_interiors()
         obj_interiors = obj.get_interiors()
-        self.app.new_object('geometry', outname, geo_init)
+        self.app.app_obj.new_object('geometry', outname, geo_init)

+ 1 - 1
tclCommands/TclCommandJoinExcellon.py

@@ -65,6 +65,6 @@ class TclCommandJoinExcellon(TclCommand):
             ExcellonObject.merge(objs, obj_, decimals=self.app.decimals)
             ExcellonObject.merge(objs, obj_, decimals=self.app.decimals)
 
 
         if objs and len(objs) >= 2:
         if objs and len(objs) >= 2:
-            self.app.new_object("excellon", outname, initialize, plot=False)
+            self.app.app_obj.new_object("excellon", outname, initialize, plot=False)
         else:
         else:
             return "No Excellon objects to be joined or less than two Excellon objects specified for merging."
             return "No Excellon objects to be joined or less than two Excellon objects specified for merging."

+ 1 - 1
tclCommands/TclCommandJoinGeometry.py

@@ -65,6 +65,6 @@ class TclCommandJoinGeometry(TclCommand):
             GeometryObject.merge(objs, obj_)
             GeometryObject.merge(objs, obj_)
 
 
         if objs and len(objs) >= 2:
         if objs and len(objs) >= 2:
-            self.app.new_object("geometry", outname, initialize, plot=False)
+            self.app.app_obj.new_object("geometry", outname, initialize, plot=False)
         else:
         else:
             return "No Geometry objects to be joined or less than two Geometry objects specified for merging."
             return "No Geometry objects to be joined or less than two Geometry objects specified for merging."

+ 1 - 1
tclCommands/TclCommandNewExcellon.py

@@ -58,4 +58,4 @@ class TclCommandNewExcellon(TclCommandSignaled):
             name = args['name']
             name = args['name']
         else:
         else:
             name = 'new_exc'
             name = 'new_exc'
-        self.app.new_object('excellon', name, lambda x, y: None, plot=False)
+        self.app.app_obj.new_object('excellon', name, lambda x, y: None, plot=False)

+ 1 - 1
tclCommands/TclCommandNewGeometry.py

@@ -52,4 +52,4 @@ class TclCommandNewGeometry(TclCommandSignaled):
         else:
         else:
             name = 'new_geo'
             name = 'new_geo'
 
 
-        self.app.new_object('geometry', str(name), lambda x, y: None, plot=False)
+        self.app.app_obj.new_object('geometry', str(name), lambda x, y: None, plot=False)

+ 1 - 1
tclCommands/TclCommandNewGerber.py

@@ -75,4 +75,4 @@ class TclCommandNewGerber(TclCommandSignaled):
             except KeyError:
             except KeyError:
                 pass
                 pass
 
 
-        self.app.new_object('gerber', name, initialize, plot=False)
+        self.app.app_obj.new_object('gerber', name, initialize, plot=False)

+ 1 - 1
tclCommands/TclCommandNregions.py

@@ -100,7 +100,7 @@ class TclCommandNregions(TclCommand):
                 non_copper = bounding_box.difference(geo)
                 non_copper = bounding_box.difference(geo)
                 geo_obj.solid_geometry = non_copper
                 geo_obj.solid_geometry = non_copper
 
 
-            self.app.new_object("geometry", args['outname'], geo_init, plot=False)
+            self.app.app_obj.new_object("geometry", args['outname'], geo_init, plot=False)
         except Exception as e:
         except Exception as e:
             return "Operation failed: %s" % str(e)
             return "Operation failed: %s" % str(e)
 
 

+ 2 - 2
tclCommands/TclCommandOpenDXF.py

@@ -77,10 +77,10 @@ class TclCommandOpenDXF(TclCommandSignaled):
         with self.app.proc_container.new("Open DXF"):
         with self.app.proc_container.new("Open DXF"):
 
 
             # Object creation
             # Object creation
-            ret_val = self.app.new_object(obj_type, outname, obj_init, plot=False)
+            ret_val = self.app.app_obj.new_object(obj_type, outname, obj_init, plot=False)
             if ret_val == 'fail':
             if ret_val == 'fail':
                 filename = self.app.defaults['global_tcl_path'] + '/' + outname
                 filename = self.app.defaults['global_tcl_path'] + '/' + outname
-                ret_val = self.app.new_object(obj_type, outname, obj_init, plot=False)
+                ret_val = self.app.app_obj.new_object(obj_type, outname, obj_init, plot=False)
                 self.app.shell.append_output(
                 self.app.shell.append_output(
                     "No path provided or path is wrong. Using the default Path... \n")
                     "No path provided or path is wrong. Using the default Path... \n")
 
 

+ 2 - 2
tclCommands/TclCommandOpenSVG.py

@@ -77,10 +77,10 @@ class TclCommandOpenSVG(TclCommandSignaled):
         with self.app.proc_container.new("Import SVG"):
         with self.app.proc_container.new("Import SVG"):
 
 
             # Object creation
             # Object creation
-            ret_val = self.app.new_object(obj_type, outname, obj_init, plot=False)
+            ret_val = self.app.app_obj.new_object(obj_type, outname, obj_init, plot=False)
             if ret_val == 'fail':
             if ret_val == 'fail':
                 filename = self.app.defaults['global_tcl_path'] + '/' + outname
                 filename = self.app.defaults['global_tcl_path'] + '/' + outname
-                ret_val = self.app.new_object(obj_type, outname, obj_init, plot=False)
+                ret_val = self.app.app_obj.new_object(obj_type, outname, obj_init, plot=False)
                 self.app.shell.append_output(
                 self.app.shell.append_output(
                     "No path provided or path is wrong. Using the default Path... \n")
                     "No path provided or path is wrong. Using the default Path... \n")
                 if ret_val == 'fail':
                 if ret_val == 'fail':

+ 6 - 6
tclCommands/TclCommandPanelize.py

@@ -167,19 +167,19 @@ class TclCommandPanelize(TclCommand):
         #             for col in range(columns):
         #             for col in range(columns):
         #                 local_outname = outname + ".tmp." + str(col) + "." + str(row)
         #                 local_outname = outname + ".tmp." + str(col) + "." + str(row)
         #                 if isinstance(obj, ExcellonObject):
         #                 if isinstance(obj, ExcellonObject):
-        #                     self.app.new_object("excellon", local_outname, initialize_local_excellon, plot=False,
+        #                     self.app.app_obj.new_object("excellon", local_outname, initialize_local_excellon, plot=False,
         #                                         autoselected=False)
         #                                         autoselected=False)
         #                 else:
         #                 else:
-        #                     self.app.new_object("geometry", local_outname, initialize_local, plot=False,
+        #                     self.app.app_obj.new_object("geometry", local_outname, initialize_local, plot=False,
         #                                         autoselected=False)
         #                                         autoselected=False)
         #
         #
         #                 currentx += lenghtx
         #                 currentx += lenghtx
         #             currenty += lenghty
         #             currenty += lenghty
         #
         #
         #         if isinstance(obj, ExcellonObject):
         #         if isinstance(obj, ExcellonObject):
-        #             self.app.new_object("excellon", outname, initialize_excellon)
+        #             self.app.app_obj.new_object("excellon", outname, initialize_excellon)
         #         else:
         #         else:
-        #             self.app.new_object("geometry", outname, initialize_geometry)
+        #             self.app.app_obj.new_object("geometry", outname, initialize_geometry)
         #
         #
         #         # deselect all  to avoid  delete selected object when run  delete  from  shell
         #         # deselect all  to avoid  delete selected object when run  delete  from  shell
         #         self.app.collection.set_all_inactive()
         #         self.app.collection.set_all_inactive()
@@ -287,9 +287,9 @@ class TclCommandPanelize(TclCommand):
                         currenty += lenghty
                         currenty += lenghty
 
 
                 if obj.kind == 'excellon':
                 if obj.kind == 'excellon':
-                    self.app.new_object("excellon", outname, job_init_excellon, plot=False, autoselected=True)
+                    self.app.app_obj.new_object("excellon", outname, job_init_excellon, plot=False, autoselected=True)
                 else:
                 else:
-                    self.app.new_object("geometry", outname, job_init_geometry, plot=False, autoselected=True)
+                    self.app.app_obj.new_object("geometry", outname, job_init_geometry, plot=False, autoselected=True)
 
 
         if threaded is True:
         if threaded is True:
             proc = self.app.proc_container.new("Generating panel ... Please wait.")
             proc = self.app.proc_container.new("Generating panel ... Please wait.")

+ 3 - 3
tclCommands/TclCommandWriteGCode.py

@@ -80,15 +80,15 @@ class TclCommandWriteGCode(TclCommandSignaled):
         # This is not needed any more? All targets should be present.
         # This is not needed any more? All targets should be present.
         # If there are promised objects, wait until all promises have been fulfilled.
         # If there are promised objects, wait until all promises have been fulfilled.
         # if self.collection.has_promises():
         # if self.collection.has_promises():
-        #     def write_gcode_on_object(new_object):
+        #     def write_gcode_on_object(app_obj.new_object):
         #         self.log.debug("write_gcode_on_object(): Disconnecting %s" % write_gcode_on_object)
         #         self.log.debug("write_gcode_on_object(): Disconnecting %s" % write_gcode_on_object)
-        #         self.new_object_available.disconnect(write_gcode_on_object)
+        #         self.app_obj.new_object_available.disconnect(write_gcode_on_object)
         #         write_gcode(obj_name, filename, preamble, postamble)
         #         write_gcode(obj_name, filename, preamble, postamble)
         #
         #
         #     # Try again when a new object becomes available.
         #     # Try again when a new object becomes available.
         #     self.log.debug("write_gcode(): Collection has promises. Queued for %s." % obj_name)
         #     self.log.debug("write_gcode(): Collection has promises. Queued for %s." % obj_name)
         #     self.log.debug("write_gcode(): Queued function: %s" % write_gcode_on_object)
         #     self.log.debug("write_gcode(): Queued function: %s" % write_gcode_on_object)
-        #     self.new_object_available.connect(write_gcode_on_object)
+        #     self.app_obj.new_object_available.connect(write_gcode_on_object)
         #
         #
         #     return
         #     return