diff --git a/AppEditors/FlatCAMExcEditor.py b/AppEditors/FlatCAMExcEditor.py index 2a4745f5..3d948f66 100644 --- a/AppEditors/FlatCAMExcEditor.py +++ b/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 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): self.shapes.pool = pool @@ -3336,7 +3336,7 @@ class FlatCAMExcEditor(QtCore.QObject): with self.app.proc_container.new(_("Creating Excellon.")): 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'], local_use=edited_obj, filename=None, diff --git a/AppEditors/FlatCAMGeoEditor.py b/AppEditors/FlatCAMGeoEditor.py index 8dd1f61b..aeaf24ec 100644 --- a/AppEditors/FlatCAMGeoEditor.py +++ b/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 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): self.shapes.pool = pool diff --git a/AppEditors/FlatCAMGrbEditor.py b/AppEditors/FlatCAMGrbEditor.py index 4952e74b..0053ac5a 100644 --- a/AppEditors/FlatCAMGrbEditor.py +++ b/AppEditors/FlatCAMGrbEditor.py @@ -3110,7 +3110,7 @@ class FlatCAMGrbEditor(QtCore.QObject): self.complete = True 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): self.shapes.pool = pool @@ -4346,7 +4346,7 @@ class FlatCAMGrbEditor(QtCore.QObject): with self.app.proc_container.new(_("Creating Gerber.")): try: - self.app.new_object("gerber", outname, obj_init) + self.app.app_obj.new_object("gerber", outname, obj_init) except Exception as e: log.error("Error on Edited object creation: %s" % str(e)) # make sure to clean the previous results diff --git a/AppGUI/MainGUI.py b/AppGUI/MainGUI.py index 38deda4b..147c90b2 100644 --- a/AppGUI/MainGUI.py +++ b/AppGUI/MainGUI.py @@ -2477,7 +2477,7 @@ class MainGUI(QtWidgets.QMainWindow): # New Geometry if key == QtCore.Qt.Key_B: - self.app.new_gerber_object() + self.app.app_obj.new_gerber_object() # New Geometry if key == QtCore.Qt.Key_D: @@ -2497,7 +2497,7 @@ class MainGUI(QtWidgets.QMainWindow): # New Excellon if key == QtCore.Qt.Key_L: - self.app.new_excellon_object() + self.app.app_obj.new_excellon_object() # Move tool toggle if key == QtCore.Qt.Key_M: @@ -2505,7 +2505,7 @@ class MainGUI(QtWidgets.QMainWindow): # New Geometry if key == QtCore.Qt.Key_N: - self.app.new_geometry_object() + self.app.app_obj.new_geometry_object() # Set Origin if key == QtCore.Qt.Key_O: diff --git a/AppGUI/PlotCanvasLegacy.py b/AppGUI/PlotCanvasLegacy.py index 429c5d2b..752d1546 100644 --- a/AppGUI/PlotCanvasLegacy.py +++ b/AppGUI/PlotCanvasLegacy.py @@ -48,9 +48,9 @@ class CanvasCache(QtCore.QObject): Case story #1: 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 - (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 app.collection.figure. Then plots on it. 4) Plots on a cache-size canvas (in background). @@ -116,7 +116,7 @@ class CanvasCache(QtCore.QObject): # 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!") diff --git a/AppGUI/preferences/PreferencesUIManager.py b/AppGUI/preferences/PreferencesUIManager.py index 640029d3..2cc2487c 100644 --- a/AppGUI/preferences/PreferencesUIManager.py +++ b/AppGUI/preferences/PreferencesUIManager.py @@ -43,7 +43,7 @@ class PreferencesUIManager: self.preferences_changed_flag = False # 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 = { # General App "decimals_inch": self.ui.general_defaults_form.general_app_group.precision_inch_entry, diff --git a/App.py b/AppMain.py similarity index 96% rename from App.py rename to AppMain.py index dbd28abf..297707c6 100644 --- a/App.py +++ b/AppMain.py @@ -4,6 +4,7 @@ # Author: Juan Pablo Caram (c) # # Date: 2/5/2014 # # MIT Licence # +# Modified by Marius Stanciu (2019) # # ########################################################### import urllib.request @@ -55,12 +56,7 @@ from AppGUI.preferences.OptionsGroupUI import OptionsGroupUI from AppGUI.preferences.PreferencesUIManager import PreferencesUIManager from AppObjects.ObjectCollection import * 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 from AppParsers.ParseExcellon import Excellon @@ -226,20 +222,6 @@ class App(QtCore.QObject): # Percentage of progress 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 object_status_changed = QtCore.pyqtSignal(object, str, str) @@ -674,9 +656,11 @@ class App(QtCore.QObject): # #################################### SETUP OBJECT COLLECTION ############################################## # ########################################################################################################### - self.collection = ObjectCollection(self) + self.collection = ObjectCollection(app=self) self.ui.project_tab_layout.addWidget(self.collection.view) + self.app_obj = AppObject(app=self) + # ### Adjust tabs width ## ## # self.collection.view.setMinimumWidth(self.ui.options_scroll_area.widget().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.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 self.file_opened.connect(self.register_recent) self.file_opened.connect(lambda kind, filename: self.register_folder(filename)) @@ -793,10 +771,10 @@ class App(QtCore.QObject): # ########################################## Standard signals ############################################### # ### Menu 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.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_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.zoomfit.triggered.connect(self.on_zoom_fit) @@ -1918,7 +1896,7 @@ class App(QtCore.QObject): self.calculator_tool = ToolCalculator(self) 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'), 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)) # 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.update_obj_btn.triggered.connect(lambda: self.editor2object()) self.ui.copy_btn.triggered.connect(self.on_copy_command) @@ -2665,347 +2643,6 @@ class App(QtCore.QObject): # Re-build the recent items menu 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}: {name}'.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}: {name}'.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}: {name}'.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}: {name}'.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}: {name}'.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}: {name}'.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): """ Displays the "about" dialog found in the Menu --> Help. @@ -3976,7 +3613,7 @@ class App(QtCore.QObject): for v in geo_obj.tools.values(): 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: def initialize(geo_obj, app): 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(): 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 @@ -4015,7 +3652,7 @@ class App(QtCore.QObject): ExcellonObject.merge(exc_list=objs, exc_final=exc_obj, decimals=self.decimals) 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 def on_edit_join_grb(self): @@ -4043,7 +3680,7 @@ class App(QtCore.QObject): GerberObject.merge(grb_list=objs, grb_final=grb_obj) 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 def on_convert_singlegeo_to_multigeo(self): @@ -4352,7 +3989,7 @@ class App(QtCore.QObject): obj.convert_units(new_units) # 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 obj.build_ui() @@ -5017,7 +4654,7 @@ class App(QtCore.QObject): for obj in obj_list: obj.offset((x, y)) - self.object_changed.emit(obj) + self.app_obj.object_changed.emit(obj) # Update the object bounding box options a, b, c, d = obj.bounds() @@ -5105,7 +4742,7 @@ class App(QtCore.QObject): for obj in obj_list: obj.offset((-x, -y)) - self.object_changed.emit(obj) + self.app_obj.object_changed.emit(obj) # Update the object bounding box options a, b, c, d = obj.bounds() @@ -5468,15 +5105,15 @@ class App(QtCore.QObject): try: 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): - self.new_object("gerber", str(obj_name) + "_copy", initialize) + self.app_obj.new_object("gerber", str(obj_name) + "_copy", initialize) 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): - 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): - 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: return "Operation failed: %s" % str(e) @@ -5517,11 +5154,11 @@ class App(QtCore.QObject): obj_name = obj.options["name"] try: 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): - 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): - 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: return "Operation failed: %s" % str(er) @@ -5588,9 +5225,9 @@ class App(QtCore.QObject): try: 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: - self.new_object("geometry", str(obj_name) + "_conv", initialize) + self.app_obj.new_object("geometry", str(obj_name) + "_conv", initialize) except Exception as e: return "Operation failed: %s" % str(e) @@ -5666,9 +5303,9 @@ class App(QtCore.QObject): try: 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): - self.new_object("gerber", str(obj_name) + "_conv", initialize_geometry) + self.app_obj.new_object("gerber", str(obj_name) + "_conv", initialize_geometry) else: 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: obj.mirror('X', [px, py]) obj.plot() - self.object_changed.emit(obj) + self.app_obj.object_changed.emit(obj) self.inform.emit('[success] %s' % _("Flip on Y axis done.")) except Exception as e: @@ -6008,7 +5645,7 @@ class App(QtCore.QObject): for obj in obj_list: obj.mirror('Y', [px, py]) obj.plot() - self.object_changed.emit(obj) + self.app_obj.object_changed.emit(obj) self.inform.emit('[success] %s' % _("Flip on X axis done.")) except Exception as e: @@ -6064,7 +5701,7 @@ class App(QtCore.QObject): for sel_obj in obj_list: sel_obj.rotate(-float(num), point=(px, py)) sel_obj.plot() - self.object_changed.emit(sel_obj) + self.app_obj.object_changed.emit(sel_obj) self.inform.emit('[success] %s' % _("Rotation done.")) except Exception as 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: obj.skew(num, 0, point=(xminimal, yminimal)) obj.plot() - self.object_changed.emit(obj) + self.app_obj.object_changed.emit(obj) self.inform.emit('[success] %s' % _("Skew on X axis done.")) def on_skewy(self): @@ -6141,7 +5778,7 @@ class App(QtCore.QObject): for obj in obj_list: obj.skew(0, num, point=(xminimal, yminimal)) obj.plot() - self.object_changed.emit(obj) + self.app_obj.object_changed.emit(obj) self.inform.emit('[success] %s' % _("Skew on Y axis done.")) def on_plots_updated(self): @@ -7970,7 +7607,7 @@ class App(QtCore.QObject): self.ui.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 # @@ -8891,7 +8528,7 @@ class App(QtCore.QObject): # Object name 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': self.inform.emit('[ERROR_NOTCL]%s' % _('Import failed.')) @@ -8937,7 +8574,7 @@ class App(QtCore.QObject): # Object name 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': self.inform.emit('[ERROR_NOTCL]%s' % _('Import failed.')) @@ -8998,11 +8635,11 @@ class App(QtCore.QObject): name = outname or filename.split('/')[-1].split('\\')[-1] # # ## 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 from_tcl: 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': self.inform.emit('[ERROR_NOTCL]%s' % _('Open Gerber failed. Probable not a Gerber file.')) return 'fail' @@ -9064,11 +8701,11 @@ class App(QtCore.QObject): with self.proc_container.new(_("Opening Excellon.")): # Object name 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 from_tcl: 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': self.inform.emit('[ERROR_NOTCL] %s' % _('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] # 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 from_tcl: 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': self.inform.emit('[ERROR_NOTCL] %s' % _("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] # # ## 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': self.inform.emit('[ERROR_NOTCL]%s' % _(' Open HPGL2 failed. Probable not a HPGL2 file.')) return 'fail' @@ -9254,10 +8891,10 @@ class App(QtCore.QObject): script_name = outname or filename.split('/')[-1].split('\\')[-1] # 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': 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': self.inform.emit('[ERROR_NOTCL]%s' % _('Failed to open TCL Script.')) return 'fail' @@ -9320,7 +8957,7 @@ class App(QtCore.QObject): 2) Registers the file as recently opened. 3) Calls on_file_new() 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 :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: print('App.open_project() --> ' + str(e)) @@ -9459,7 +9096,7 @@ class App(QtCore.QObject): with self.proc_container.new("Plotting"): obj.plot(kind=self.defaults["cncjob_plot_kind"]) if fit_view is True: - self.object_plotted.emit(obj) + self.app_obj.object_plotted.emit(obj) if use_thread is True: # Send to worker @@ -10044,8 +9681,6 @@ class App(QtCore.QObject): self.worker_task.emit({'fcn': worker_task, 'params': [objects]}) - # self.plots_updated.emit() - def disable_plots(self, objects): """ Disables plots @@ -10084,7 +9719,6 @@ class App(QtCore.QObject): except Exception as e: log.debug("App.disable_plots() --> %s" % str(e)) - # self.plots_updated.emit() def worker_task(objs): with self.proc_container.new(_("Disabling plots ...")): for plot_obj in objs: @@ -10115,7 +9749,7 @@ class App(QtCore.QObject): obj.options['plot'] = True else: obj.options['plot'] = False - self.plots_updated.emit() + self.app_obj.plots_updated.emit() def clear_plots(self): """ diff --git a/AppObjects/AppObject.py b/AppObjects/AppObject.py new file mode 100644 index 00000000..361663ed --- /dev/null +++ b/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}: {name}'.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}: {name}'.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}: {name}'.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}: {name}'.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}: {name}'.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}: {name}'.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) diff --git a/AppObjects/FlatCAMExcellon.py b/AppObjects/FlatCAMExcellon.py index a46d6388..30f5f841 100644 --- a/AppObjects/FlatCAMExcellon.py +++ b/AppObjects/FlatCAMExcellon.py @@ -1196,8 +1196,8 @@ class ExcellonObject(FlatCAMObj, Excellon): Point(hole['point']).buffer(buffer_value).exterior) 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 self.app.collection.promise(outname) @@ -1205,7 +1205,7 @@ class ExcellonObject(FlatCAMObj, Excellon): # Send to worker self.app.worker_task.emit({'fcn': geo_thread, 'params': [self.app]}) 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, "" @@ -1300,8 +1300,8 @@ class ExcellonObject(FlatCAMObj, Excellon): geo_obj.solid_geometry.append(poly) 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 self.app.collection.promise(outname) @@ -1309,7 +1309,7 @@ class ExcellonObject(FlatCAMObj, Excellon): # Send to worker self.app.worker_task.emit({'fcn': geo_thread, 'params': [self.app]}) 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, "" @@ -1443,7 +1443,7 @@ class ExcellonObject(FlatCAMObj, Excellon): job_name = self.options["name"] + "_cnc" 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): 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() # 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")): - 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. self.app.collection.promise(job_name) diff --git a/AppObjects/FlatCAMGeometry.py b/AppObjects/FlatCAMGeometry.py index 2ff677d1..bb418dc3 100644 --- a/AppObjects/FlatCAMGeometry.py +++ b/AppObjects/FlatCAMGeometry.py @@ -1778,7 +1778,7 @@ class GeometryObject(FlatCAMObj, Geometry): self.app.inform.emit(msg) return - # Object initialization function for app.new_object() + # Object initialization function for app.app_obj.new_object() # RUNNING ON SEPARATE THREAD! def job_init_single_geometry(job_obj, app_obj): log.debug("Creating a CNCJob out of a single-geometry") @@ -1918,7 +1918,7 @@ class GeometryObject(FlatCAMObj, Geometry): }) dia_cnc_dict.clear() - # Object initialization function for app.new_object() + # Object initialization function for app.app_obj.new_object() # RUNNING ON SEPARATE THREAD! def job_init_multi_geometry(job_obj, app_obj): log.debug("Creating a CNCJob out of a multi-geometry") @@ -2072,15 +2072,15 @@ class GeometryObject(FlatCAMObj, Geometry): if use_thread: # To be run in separate thread - def job_thread(app_obj): + def job_thread(a_obj): if self.multigeo is False: 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: 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 self.app.collection.promise(outname) @@ -2088,9 +2088,9 @@ class GeometryObject(FlatCAMObj, Geometry): self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]}) else: 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: - 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, 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"] - # Object initialization function for app.new_object() + # Object initialization function for app.app_obj.new_object() # RUNNING ON SEPARATE THREAD! def job_init(job_obj, app_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 def job_thread(app_obj): 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) # Create a promise with the name @@ -2238,7 +2238,7 @@ class GeometryObject(FlatCAMObj, Geometry): # Send to worker self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]}) 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): # if self.muted_ui: diff --git a/AppObjects/FlatCAMGerber.py b/AppObjects/FlatCAMGerber.py index bda1ffd5..98049513 100644 --- a/AppObjects/FlatCAMGerber.py +++ b/AppObjects/FlatCAMGerber.py @@ -530,7 +530,7 @@ class GerberObject(FlatCAMObj, Gerber): return "fail" 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): self.app.defaults.report_usage("gerber_on_generatebb_button") @@ -556,7 +556,7 @@ class GerberObject(FlatCAMObj, Gerber): return "fail" 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): @@ -605,7 +605,7 @@ class GerberObject(FlatCAMObj, Gerber): # TODO: Do something if this is None. Offer changing name? 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: 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) # 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: for i in range(passes): @@ -1072,7 +1072,7 @@ class GerberObject(FlatCAMObj, Gerber): geo_obj.solid_geometry = self.area_subtraction(geo_obj.solid_geometry) # 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): # isolation_geometry produces an envelope that is going on the left of the geometry diff --git a/AppObjects/FlatCAMObj.py b/AppObjects/FlatCAMObj.py index fda1a0c7..282c2ced 100644 --- a/AppObjects/FlatCAMObj.py +++ b/AppObjects/FlatCAMObj.py @@ -245,7 +245,7 @@ class FlatCAMObj(QtCore.QObject): self.app.proc_container.update_view_text('') with self.app.proc_container.new('%s...' % _("Plotting")): 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': []}) @@ -276,7 +276,7 @@ class FlatCAMObj(QtCore.QObject): self.app.proc_container.update_view_text('') with self.app.proc_container.new('%s...' % _("Plotting")): 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': []}) @@ -292,7 +292,7 @@ class FlatCAMObj(QtCore.QObject): self.app.proc_container.update_view_text('') with self.app.proc_container.new('%s...' % _("Plotting")): 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': []}) @@ -372,7 +372,7 @@ class FlatCAMObj(QtCore.QObject): def plot_task(): with self.app.proc_container.new('%s...' % _("Plotting")): 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': []}) diff --git a/AppObjects/ObjectCollection.py b/AppObjects/ObjectCollection.py index fb1318fd..8fc25560 100644 --- a/AppObjects/ObjectCollection.py +++ b/AppObjects/ObjectCollection.py @@ -553,7 +553,7 @@ class ObjectCollection(QtCore.QAbstractItemModel): while name in self.get_names(): # ## Create a new name # 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) if match: # Yes: Increment the number! base = match.group(1) or '' diff --git a/AppParsers/ParseExcellon.py b/AppParsers/ParseExcellon.py index f350ba28..d853b427 100644 --- a/AppParsers/ParseExcellon.py +++ b/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 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 inside the file to the FlatCAM units. diff --git a/AppTool.py b/AppTool.py index 1f3c1ba4..2c2362c4 100644 --- a/AppTool.py +++ b/AppTool.py @@ -28,7 +28,7 @@ class AppTool(QtWidgets.QWidget): """ :param app: The application this tool will run in. - :type app: App + :type app: AppMain :param parent: Qt Parent :return: AppTool """ diff --git a/AppTools/ToolCalibration.py b/AppTools/ToolCalibration.py index 71bbd1e3..b220f1c0 100644 --- a/AppTools/ToolCalibration.py +++ b/AppTools/ToolCalibration.py @@ -1352,11 +1352,11 @@ class ToolCalibration(AppTool): try: 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': - 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': - 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: log.debug("ToolCalibration.new_calibrated_object() --> %s" % str(e)) return "Operation failed: %s" % str(e) diff --git a/AppTools/ToolCopperThieving.py b/AppTools/ToolCopperThieving.py index aa5510f7..a166866f 100644 --- a/AppTools/ToolCopperThieving.py +++ b/AppTools/ToolCopperThieving.py @@ -1474,7 +1474,7 @@ class ToolCopperThieving(AppTool): obj_name, separatpr, obj_extension = self.sm_object.options['name'].rpartition('.') 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 self.app.file_opened.emit("gerber", name) diff --git a/AppTools/ToolCutOut.py b/AppTools/ToolCutOut.py index 45415b1c..196da2b6 100644 --- a/AppTools/ToolCutOut.py +++ b/AppTools/ToolCutOut.py @@ -700,7 +700,7 @@ class CutOut(AppTool): geo_obj.tools[1]['data']['depthperpass'] = self.maxdepth_entry.get_value() 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() 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() 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': # cutout_obj.plot() @@ -1056,7 +1056,7 @@ class CutOut(AppTool): geo_obj.tools[1]['data']['depthperpass'] = self.maxdepth_entry.get_value() 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): self.cutting_dia = float(self.dia.get_value()) diff --git a/AppTools/ToolDblSided.py b/AppTools/ToolDblSided.py index a987ee55..1cf2f8ab 100644 --- a/AppTools/ToolDblSided.py +++ b/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, 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.app.inform.emit('[success] %s' % _("Excellon object with alignment drills created...")) @@ -686,7 +686,7 @@ class DblSidedTool(AppTool): py = 0.5 * (ymin + ymax) fcobj.mirror(axis, [px, py]) - self.app.object_changed.emit(fcobj) + self.app.app_obj.object_changed.emit(fcobj) fcobj.plot() 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) fcobj.mirror(axis, [px, py]) - self.app.object_changed.emit(fcobj) + self.app.app_obj.object_changed.emit(fcobj) fcobj.plot() 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) fcobj.mirror(axis, [px, py]) - self.app.object_changed.emit(fcobj) + self.app.app_obj.object_changed.emit(fcobj) fcobj.plot() self.app.inform.emit('[success] Geometry %s %s...' % (str(fcobj.options['name']), _("was mirrored"))) diff --git a/AppTools/ToolExtractDrills.py b/AppTools/ToolExtractDrills.py index d9ac5d4b..71e8fb41 100644 --- a/AppTools/ToolExtractDrills.py +++ b/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, 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): if val == "fixed": diff --git a/AppTools/ToolFilm.py b/AppTools/ToolFilm.py index a2ffd94f..a4209ce3 100644 --- a/AppTools/ToolFilm.py +++ b/AppTools/ToolFilm.py @@ -775,7 +775,7 @@ class Film(AppTool): new_obj.solid_geometry = deepcopy(punched_solid_geometry) 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) else: @@ -826,7 +826,7 @@ class Film(AppTool): new_obj.solid_geometry = deepcopy(punched_solid_geometry) 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) diff --git a/AppTools/ToolImage.py b/AppTools/ToolImage.py index 1c2f1a5e..5d520c78 100644 --- a/AppTools/ToolImage.py +++ b/AppTools/ToolImage.py @@ -288,7 +288,7 @@ class ToolImage(AppTool): name = outname or filename.split('/')[-1].split('\\')[-1] 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 self.app.file_opened.emit("image", filename) diff --git a/AppTools/ToolInvertGerber.py b/AppTools/ToolInvertGerber.py index bcdb394f..6acc013b 100644 --- a/AppTools/ToolInvertGerber.py +++ b/AppTools/ToolInvertGerber.py @@ -293,7 +293,7 @@ class ToolInvertGerber(AppTool): new_obj.source_file = self.app.export_gerber(obj_name=outname, filename=None, 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): self.gerber_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) diff --git a/AppTools/ToolNCC.py b/AppTools/ToolNCC.py index 65898339..0a637997 100644 --- a/AppTools/ToolNCC.py +++ b/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 ####### # ########################################################################################### - def job_thread(app_obj): + def job_thread(a_obj): try: 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: - app_obj.new_object("geometry", name, gen_clear_area) + a_obj.app_obj.new_object("geometry", name, gen_clear_area) except grace: if run_threaded: proc.done() @@ -3881,9 +3881,9 @@ class NonCopperClear(AppTool, Gerber): def job_thread(app_obj): try: 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: - 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: if run_threaded: proc.done() diff --git a/AppTools/ToolPDF.py b/AppTools/ToolPDF.py index 5e56092c..2e3cace3 100644 --- a/AppTools/ToolPDF.py +++ b/AppTools/ToolPDF.py @@ -205,7 +205,7 @@ class ToolPDF(AppTool): 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': self.app.inform.emit('[ERROR_NOTCL] %s' % _('Open PDF file failed.')) return @@ -278,7 +278,7 @@ class ToolPDF(AppTool): 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': self.app.inform.emit('[ERROR_NOTCL] %s' % _('Open PDF file failed.')) return diff --git a/AppTools/ToolPaint.py b/AppTools/ToolPaint.py index 5a88e1b5..bfa4891b 100644 --- a/AppTools/ToolPaint.py +++ b/AppTools/ToolPaint.py @@ -2315,7 +2315,7 @@ class ToolPaint(AppTool, Gerber): def job_thread(app_obj): 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: proc.done() return @@ -2823,9 +2823,9 @@ class ToolPaint(AppTool, Gerber): def job_thread(app_obj): try: 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: - 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: proc.done() return @@ -3320,9 +3320,9 @@ class ToolPaint(AppTool, Gerber): def job_thread(app_obj): try: 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: - 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: proc.done() return diff --git a/AppTools/ToolPanelize.py b/AppTools/ToolPanelize.py index 82e41491..3d774c97 100644 --- a/AppTools/ToolPanelize.py +++ b/AppTools/ToolPanelize.py @@ -794,9 +794,9 @@ class Panelize(AppTool): self.app.inform.emit('%s: %d' % (_("Generating panel... Spawning copies"), (int(rows * columns)))) 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: - 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: self.app.inform.emit('[success] %s' % _("Panel done...")) diff --git a/AppTools/ToolPcbWizard.py b/AppTools/ToolPcbWizard.py index 108a99ea..a9fc6075 100644 --- a/AppTools/ToolPcbWizard.py +++ b/AppTools/ToolPcbWizard.py @@ -452,7 +452,7 @@ class PcbWizard(AppTool): # Object name 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': self.app.inform.emit('[ERROR_NOTCL] %s' % _('Import Excellon file failed.')) return diff --git a/AppTools/ToolPunchGerber.py b/AppTools/ToolPunchGerber.py index 3dcc99f2..28d42ef4 100644 --- a/AppTools/ToolPunchGerber.py +++ b/AppTools/ToolPunchGerber.py @@ -591,7 +591,7 @@ class ToolPunchGerber(AppTool): new_obj.source_file = self.app.export_gerber(obj_name=outname, filename=None, 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': 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, 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': circ_r_val = self.circular_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, 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': 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, 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): self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) diff --git a/AppTools/ToolRulesCheck.py b/AppTools/ToolRulesCheck.py index 54376bb3..7864964a 100644 --- a/AppTools/ToolRulesCheck.py +++ b/AppTools/ToolRulesCheck.py @@ -1625,7 +1625,7 @@ class RulesCheck(AppTool): new_obj.source_file = txt 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): # self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) diff --git a/AppTools/ToolSolderPaste.py b/AppTools/ToolSolderPaste.py index 2dce9d2d..cd9fbc08 100644 --- a/AppTools/ToolSolderPaste.py +++ b/AppTools/ToolSolderPaste.py @@ -9,7 +9,7 @@ from AppTool import AppTool from Common import LoudDict from AppGUI.GUIElements import FCComboBox, FCEntry, FCTable, \ FCInputDialog, FCDoubleSpinner, FCSpinner, FCFileSaveDialog -from App import log +from AppMain import log from camlib import distance from AppEditors.FlatCAMTextEditor import TextEditor @@ -1257,7 +1257,7 @@ class SolderPaste(AppTool): if use_thread: def job_thread(app_obj): 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: log.error("SolderPaste.on_create_geo() --> %s" % str(e)) proc.done() @@ -1271,7 +1271,7 @@ class SolderPaste(AppTool): # Background self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]}) 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): """ @@ -1331,7 +1331,7 @@ class SolderPaste(AppTool): self.app.inform.emit(msg) return - # Object initialization function for app.new_object() + # Object initialization function for app.app_obj.new_object() # RUNNING ON SEPARATE THREAD! def job_init(job_obj): assert job_obj.kind == 'cncjob', \ @@ -1388,7 +1388,7 @@ class SolderPaste(AppTool): # To be run in separate thread def job_thread(app_obj): 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' % (_("ToolSolderPaste CNCjob created"), name)) # Create a promise with the name @@ -1396,7 +1396,7 @@ class SolderPaste(AppTool): # Send to worker self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]}) else: - self.app.new_object("cncjob", name, job_init) + self.app.app_obj.new_object("cncjob", name, job_init) def on_view_gcode(self): """ diff --git a/AppTools/ToolSub.py b/AppTools/ToolSub.py index c1f14d64..b80bea1c 100644 --- a/AppTools/ToolSub.py +++ b/AppTools/ToolSub.py @@ -456,7 +456,7 @@ class ToolSub(AppTool): grb_obj.follow_geometry = deepcopy(follow_buff) 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': self.app.inform.emit('[ERROR_NOTCL] %s' % _('Generating new object failed.')) @@ -659,7 +659,7 @@ class ToolSub(AppTool): geo_obj.multigeo = False 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': self.app.inform.emit('[ERROR_NOTCL] %s' % _('Generating new object failed.')) diff --git a/AppTools/ToolTransform.py b/AppTools/ToolTransform.py index f0619ddb..41e6ff91 100644 --- a/AppTools/ToolTransform.py +++ b/AppTools/ToolTransform.py @@ -702,7 +702,7 @@ class ToolTransform(AppTool): self.app.inform.emit(_("CNCJob objects can't be rotated.")) else: 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 sel_obj.options['rotate'] = num @@ -776,7 +776,7 @@ class ToolTransform(AppTool): else: sel_obj.options['mirror_x'] = True 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() except Exception as e: self.app.inform.emit('[ERROR_NOTCL] %s %s, %s.' % @@ -825,7 +825,7 @@ class ToolTransform(AppTool): sel_obj.skew(0, num, point=(xminimal, yminimal)) # add information to the object that it was changed and how much 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() self.app.inform.emit('[success] %s %s %s...' % (_('Skew on the'), str(axis), _("axis done"))) except Exception as e: @@ -878,7 +878,7 @@ class ToolTransform(AppTool): # add information to the object that it was changed and how much sel_obj.options['scale_x'] = xfactor 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() 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)) # add information to the object that it was changed and how much 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() 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': 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() self.app.inform.emit('[success] %s...' % _('Buffer done')) diff --git a/CHANGELOG.md b/CHANGELOG.md index a312d76f..75255b79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ CHANGELOG for FlatCAM beta - removed reference to postprocessors and replaced it with preprocessors - more refactoring class names - 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 @@ -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 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 -- 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. - 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 diff --git a/FlatCAM.py b/FlatCAM.py index 1a309537..0bb79f1f 100644 --- a/FlatCAM.py +++ b/FlatCAM.py @@ -3,7 +3,7 @@ import os from PyQt5 import QtWidgets from PyQt5.QtCore import QSettings, Qt -from App import App +from AppMain import App from AppGUI import VisPyPatches from multiprocessing import freeze_support diff --git a/tclCommands/TclCommand.py b/tclCommands/TclCommand.py index d89eb0c4..5c008671 100644 --- a/tclCommands/TclCommand.py +++ b/tclCommands/TclCommand.py @@ -1,6 +1,6 @@ import sys import re -import App +import AppMain import abc import collections from PyQt5 import QtCore @@ -53,7 +53,7 @@ class TclCommand(object): if self.app is None: 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)) self.log = self.app.log diff --git a/tclCommands/TclCommandAlignDrill.py b/tclCommands/TclCommandAlignDrill.py index ebf2099d..250d82be 100644 --- a/tclCommands/TclCommandAlignDrill.py +++ b/tclCommands/TclCommandAlignDrill.py @@ -189,7 +189,7 @@ class TclCommandAlignDrill(TclCommandSignaled): px = 0.5 * (xmin + xmax) 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: return "Operation failed: %s" % str(e) @@ -205,7 +205,7 @@ class TclCommandAlignDrill(TclCommandSignaled): try: px = 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: return "Operation failed: %s" % str(e) diff --git a/tclCommands/TclCommandAlignDrillGrid.py b/tclCommands/TclCommandAlignDrillGrid.py index 6fe6188b..e560290d 100644 --- a/tclCommands/TclCommandAlignDrillGrid.py +++ b/tclCommands/TclCommandAlignDrillGrid.py @@ -111,4 +111,4 @@ class TclCommandAlignDrillGrid(TclCommandSignaled): init_obj.create_geometry() # 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) diff --git a/tclCommands/TclCommandBbox.py b/tclCommands/TclCommandBbox.py index 012fe433..c8fd1273 100644 --- a/tclCommands/TclCommandBbox.py +++ b/tclCommands/TclCommandBbox.py @@ -100,6 +100,6 @@ class TclCommandBbox(TclCommand): bounding_box = bounding_box.envelope 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: return "Operation failed: %s" % str(e) diff --git a/tclCommands/TclCommandCutout.py b/tclCommands/TclCommandCutout.py index f780a8cf..ddfd0614 100644 --- a/tclCommands/TclCommandCutout.py +++ b/tclCommands/TclCommandCutout.py @@ -137,7 +137,7 @@ class TclCommandCutout(TclCommand): geo_obj.solid_geometry = cascaded_union([LineString(segment) for segment in cuts]) 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.") except Exception as e: return "Operation failed: %s" % str(e) diff --git a/tclCommands/TclCommandDrillcncjob.py b/tclCommands/TclCommandDrillcncjob.py index 39d2f28e..95b271d8 100644 --- a/tclCommands/TclCommandDrillcncjob.py +++ b/tclCommands/TclCommandDrillcncjob.py @@ -343,4 +343,4 @@ class TclCommandDrillcncjob(TclCommandSignaled): job_obj.gcode_parse() 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) diff --git a/tclCommands/TclCommandExteriors.py b/tclCommands/TclCommandExteriors.py index de4e6901..00461aeb 100644 --- a/tclCommands/TclCommandExteriors.py +++ b/tclCommands/TclCommandExteriors.py @@ -66,4 +66,4 @@ class TclCommandExteriors(TclCommandSignaled): geo_obj.solid_geometry = obj_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) diff --git a/tclCommands/TclCommandGeoCutout.py b/tclCommands/TclCommandGeoCutout.py index 91a7f660..9a1c29bc 100644 --- a/tclCommands/TclCommandGeoCutout.py +++ b/tclCommands/TclCommandGeoCutout.py @@ -300,11 +300,8 @@ class TclCommandGeoCutout(TclCommandSignaled): 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': def geo_init(geo_obj, app_obj): @@ -358,7 +355,7 @@ class TclCommandGeoCutout(TclCommandSignaled): geo_obj.options['ymax'] = cutout_obj.options['ymax'] 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) else: diff --git a/tclCommands/TclCommandImportSvg.py b/tclCommands/TclCommandImportSvg.py index 9ef67e27..c65b46d8 100644 --- a/tclCommands/TclCommandImportSvg.py +++ b/tclCommands/TclCommandImportSvg.py @@ -76,7 +76,7 @@ class TclCommandImportSvg(TclCommandSignaled): with self.app.proc_container.new("Import SVG"): # 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 self.app.file_opened.emit("svg", filename) diff --git a/tclCommands/TclCommandInteriors.py b/tclCommands/TclCommandInteriors.py index a7655204..9cd60367 100644 --- a/tclCommands/TclCommandInteriors.py +++ b/tclCommands/TclCommandInteriors.py @@ -67,4 +67,4 @@ class TclCommandInteriors(TclCommandSignaled): geo_obj.solid_geometry = obj_interiors obj_interiors = obj.get_interiors() - self.app.new_object('geometry', outname, geo_init) + self.app.app_obj.new_object('geometry', outname, geo_init) diff --git a/tclCommands/TclCommandJoinExcellon.py b/tclCommands/TclCommandJoinExcellon.py index 0e25c829..e3c342e8 100644 --- a/tclCommands/TclCommandJoinExcellon.py +++ b/tclCommands/TclCommandJoinExcellon.py @@ -65,6 +65,6 @@ class TclCommandJoinExcellon(TclCommand): ExcellonObject.merge(objs, obj_, decimals=self.app.decimals) 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: return "No Excellon objects to be joined or less than two Excellon objects specified for merging." diff --git a/tclCommands/TclCommandJoinGeometry.py b/tclCommands/TclCommandJoinGeometry.py index cb119856..44cfd9b2 100644 --- a/tclCommands/TclCommandJoinGeometry.py +++ b/tclCommands/TclCommandJoinGeometry.py @@ -65,6 +65,6 @@ class TclCommandJoinGeometry(TclCommand): GeometryObject.merge(objs, obj_) 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: return "No Geometry objects to be joined or less than two Geometry objects specified for merging." diff --git a/tclCommands/TclCommandNewExcellon.py b/tclCommands/TclCommandNewExcellon.py index 61689d6f..c5072ffb 100644 --- a/tclCommands/TclCommandNewExcellon.py +++ b/tclCommands/TclCommandNewExcellon.py @@ -58,4 +58,4 @@ class TclCommandNewExcellon(TclCommandSignaled): name = args['name'] else: 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) diff --git a/tclCommands/TclCommandNewGeometry.py b/tclCommands/TclCommandNewGeometry.py index 8fee996e..08c3c7ce 100644 --- a/tclCommands/TclCommandNewGeometry.py +++ b/tclCommands/TclCommandNewGeometry.py @@ -52,4 +52,4 @@ class TclCommandNewGeometry(TclCommandSignaled): else: 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) diff --git a/tclCommands/TclCommandNewGerber.py b/tclCommands/TclCommandNewGerber.py index 9c162965..3a63422c 100644 --- a/tclCommands/TclCommandNewGerber.py +++ b/tclCommands/TclCommandNewGerber.py @@ -75,4 +75,4 @@ class TclCommandNewGerber(TclCommandSignaled): except KeyError: pass - self.app.new_object('gerber', name, initialize, plot=False) + self.app.app_obj.new_object('gerber', name, initialize, plot=False) diff --git a/tclCommands/TclCommandNregions.py b/tclCommands/TclCommandNregions.py index 3663f0f0..e4ba7ac5 100644 --- a/tclCommands/TclCommandNregions.py +++ b/tclCommands/TclCommandNregions.py @@ -100,7 +100,7 @@ class TclCommandNregions(TclCommand): non_copper = bounding_box.difference(geo) 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: return "Operation failed: %s" % str(e) diff --git a/tclCommands/TclCommandOpenDXF.py b/tclCommands/TclCommandOpenDXF.py index 4e46d2a4..87ab0639 100644 --- a/tclCommands/TclCommandOpenDXF.py +++ b/tclCommands/TclCommandOpenDXF.py @@ -77,10 +77,10 @@ class TclCommandOpenDXF(TclCommandSignaled): with self.app.proc_container.new("Open DXF"): # 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': 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( "No path provided or path is wrong. Using the default Path... \n") diff --git a/tclCommands/TclCommandOpenSVG.py b/tclCommands/TclCommandOpenSVG.py index 9c2b514e..bfe2784e 100644 --- a/tclCommands/TclCommandOpenSVG.py +++ b/tclCommands/TclCommandOpenSVG.py @@ -77,10 +77,10 @@ class TclCommandOpenSVG(TclCommandSignaled): with self.app.proc_container.new("Import SVG"): # 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': 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( "No path provided or path is wrong. Using the default Path... \n") if ret_val == 'fail': diff --git a/tclCommands/TclCommandPanelize.py b/tclCommands/TclCommandPanelize.py index 99fd0bc5..af6f1a0f 100644 --- a/tclCommands/TclCommandPanelize.py +++ b/tclCommands/TclCommandPanelize.py @@ -167,19 +167,19 @@ class TclCommandPanelize(TclCommand): # for col in range(columns): # local_outname = outname + ".tmp." + str(col) + "." + str(row) # 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) # 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) # # currentx += lenghtx # currenty += lenghty # # if isinstance(obj, ExcellonObject): - # self.app.new_object("excellon", outname, initialize_excellon) + # self.app.app_obj.new_object("excellon", outname, initialize_excellon) # 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 # self.app.collection.set_all_inactive() @@ -287,9 +287,9 @@ class TclCommandPanelize(TclCommand): currenty += lenghty 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: - 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: proc = self.app.proc_container.new("Generating panel ... Please wait.") diff --git a/tclCommands/TclCommandWriteGCode.py b/tclCommands/TclCommandWriteGCode.py index 331fa8bc..dae8bdbb 100644 --- a/tclCommands/TclCommandWriteGCode.py +++ b/tclCommands/TclCommandWriteGCode.py @@ -80,15 +80,15 @@ class TclCommandWriteGCode(TclCommandSignaled): # This is not needed any more? All targets should be present. # If there are promised objects, wait until all promises have been fulfilled. # 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.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) # # # 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(): 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