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