diff --git a/FlatCAMApp.py b/FlatCAMApp.py
index ad0d3ff0..f6508e0f 100644
--- a/FlatCAMApp.py
+++ b/FlatCAMApp.py
@@ -1510,7 +1510,12 @@ class App(QtCore.QObject):
"tools_panelize_rows": 1,
"tools_panelize_constrain": False,
"tools_panelize_constrainx": 0.0,
- "tools_panelize_constrainy": 0.0
+ "tools_panelize_constrainy": 0.0,
+
+ "script_text": "",
+ "script_plot": True,
+ "notes_text": "",
+ "notes_plot": True,
})
@@ -3958,7 +3963,9 @@ class App(QtCore.QObject):
"gerber": FlatCAMGerber,
"excellon": FlatCAMExcellon,
"cncjob": FlatCAMCNCjob,
- "geometry": FlatCAMGeometry
+ "geometry": FlatCAMGeometry,
+ "script": FlatCAMScript,
+ "notes": FlatCAMNotes
}
App.log.debug("Calling object constructor...")
@@ -4022,15 +4029,17 @@ class App(QtCore.QObject):
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
- 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("The object has no bounds properties. %s" % str(e))
- return "fail"
+ # But not for Scripts or for Notes
+ if kind != 'notes' 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("The object has no bounds properties. %s" % str(e))
+ return "fail"
FlatCAMApp.App.log.debug("Moving new object back to main thread.")
@@ -4090,6 +4099,34 @@ class App(QtCore.QObject):
self.new_object('gerber', 'new_grb', initialize, plot=False)
+
+ def new_script_object(self):
+ """
+ Creates a new, blank TCL Script object.
+
+ :return: None
+ """
+ self.report_usage("new_script_object()")
+
+ def initialize(obj, self):
+ obj.source_file = ""
+
+ self.new_object('script', 'new_script', initialize, plot=False)
+
+
+ def new_notes_object(self):
+ """
+ Creates a new, blank Notes object.
+
+ :return: None
+ """
+ self.report_usage("new_notes_object()")
+
+ def initialize(obj, self):
+ obj.source_file = ""
+
+ self.new_object('notes', 'new_notes', initialize, plot=False)
+
def on_object_created(self, obj, plot, autoselect):
"""
Event callback for object creation.
@@ -4123,6 +4160,12 @@ class App(QtCore.QObject):
elif obj.kind == 'geometry':
self.inform.emit(_('[selected] {kind} created/selected: {name}').format(
kind=obj.kind.capitalize(), color='red', name=str(obj.options['name'])))
+ elif obj.kind == 'script':
+ self.inform.emit(_('[selected] {kind} created/selected: {name}').format(
+ kind=obj.kind.capitalize(), color='orange', name=str(obj.options['name'])))
+ elif obj.kind == 'notes':
+ self.inform.emit(_('[selected] {kind} created/selected: {name}').format(
+ kind=obj.kind.capitalize(), color='violet', name=str(obj.options['name'])))
# update the SHELL auto-completer model with the name of the new object
self.myKeywords.append(obj.options['name'])
@@ -9248,6 +9291,8 @@ class App(QtCore.QObject):
self.handleTextChanged()
self.ui.code_editor.show()
+ self.new_script_object()
+
def on_fileopenscript(self, name=None, silent=False):
"""
Will open a Tcl script file into the Code Editor
diff --git a/FlatCAMObj.py b/FlatCAMObj.py
index 1eec75ee..dd81be80 100644
--- a/FlatCAMObj.py
+++ b/FlatCAMObj.py
@@ -6439,4 +6439,60 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
self.cnc_tools.clear()
self.cnc_tools = deepcopy(temp_tools_dict)
+
+class FlatCAMScript(FlatCAMObj):
+ """
+ Represents a TCL script object.
+ """
+ optionChanged = QtCore.pyqtSignal(str)
+ ui_type = ScriptObjectUI
+
+ def __init__(self, name):
+ FlatCAMApp.App.log.debug("Creating a FlatCAMScript object...")
+ FlatCAMObj.__init__(self, name)
+
+ self.kind = "script"
+
+ def set_ui(self, ui):
+ FlatCAMObj.set_ui(self, ui)
+ FlatCAMApp.App.log.debug("FlatCAMScript.set_ui()")
+
+ self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper()
+
+ if self.units == "IN":
+ self.decimals = 4
+ else:
+ self.decimals = 2
+
+ def build_ui(self):
+ pass
+
+
+class FlatCAMNotes(FlatCAMObj):
+ """
+ Represents a Notes object.
+ """
+ optionChanged = QtCore.pyqtSignal(str)
+ ui_type = NotesObjectUI
+
+ def __init__(self, name):
+ FlatCAMApp.App.log.debug("Creating a Notes object...")
+ FlatCAMObj.__init__(self, name)
+
+ self.kind = "notes"
+
+ def set_ui(self, ui):
+ FlatCAMObj.set_ui(self, ui)
+ FlatCAMApp.App.log.debug("FlatCAMNotes.set_ui()")
+
+ self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper()
+
+ if self.units == "IN":
+ self.decimals = 4
+ else:
+ self.decimals = 2
+
+ def build_ui(self):
+ pass
+
# end of file
diff --git a/ObjectCollection.py b/ObjectCollection.py
index 98d6cd61..7d5e82e5 100644
--- a/ObjectCollection.py
+++ b/ObjectCollection.py
@@ -186,21 +186,27 @@ class ObjectCollection(QtCore.QAbstractItemModel):
("gerber", "Gerber"),
("excellon", "Excellon"),
("geometry", "Geometry"),
- ("cncjob", "CNC Job")
+ ("cncjob", "CNC Job"),
+ ("script", "Scripts"),
+ ("notes", "Notes"),
]
classdict = {
"gerber": FlatCAMGerber,
"excellon": FlatCAMExcellon,
"cncjob": FlatCAMCNCjob,
- "geometry": FlatCAMGeometry
+ "geometry": FlatCAMGeometry,
+ "script": FlatCAMScript,
+ "notes": FlatCAMNotes
}
icon_files = {
"gerber": "share/flatcam_icon16.png",
"excellon": "share/drill16.png",
"cncjob": "share/cnc16.png",
- "geometry": "share/geometry16.png"
+ "geometry": "share/geometry16.png",
+ "script": "share/script_new16.png",
+ "notes": "share/notes16_1.png"
}
root_item = None
diff --git a/README.md b/README.md
index 644a3b52..a8a7431a 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,7 @@ CAD program, and create G-Code for Isolation routing.
- added new settings for the Gerber newly introduced feature to isolate with the V-Shape tools (tip dia, tip angle, tool_type and cut Z) in Edit -> Preferences -> Gerber Advanced
- made those settings just added for Gerber, to be updated on object creation
- added the Geo Tolerance parameter to those that are converted from MM to INCH
+- added two new FlatCAM objects: FlatCAMScript and FlatCAMNotes
30.09.2019
diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py
index a778394b..1a4d8605 100644
--- a/flatcamGUI/ObjectUI.py
+++ b/flatcamGUI/ObjectUI.py
@@ -1714,4 +1714,585 @@ class CNCObjectUI(ObjectUI):
h_lay.addWidget(self.export_gcode_button)
# self.custom_box.addWidget(self.export_gcode_button)
+
+class ScriptObjectUI(ObjectUI):
+ """
+ User interface for Script objects.
+ """
+
+ def __init__(self, parent=None):
+ """
+ Creates the user interface for Script objects. GUI elements should
+ be placed in ``self.custom_box`` to preserve the layout.
+ """
+
+ ObjectUI.__init__(self, title=_('Script Object'), icon_file='share/cnc32.png', parent=parent)
+
+ # Scale and offset ans skew are not available for CNCJob objects.
+ # Hiding from the GUI.
+ for i in range(0, self.scale_grid.count()):
+ self.scale_grid.itemAt(i).widget().hide()
+ self.scale_label.hide()
+ self.scale_button.hide()
+
+ for i in range(0, self.offset_grid.count()):
+ self.offset_grid.itemAt(i).widget().hide()
+ self.offset_label.hide()
+ self.offset_button.hide()
+
+ # ## Plot options
+ self.plot_options_label = QtWidgets.QLabel("%s:" % _("Plot Options"))
+ self.custom_box.addWidget(self.plot_options_label)
+
+ self.cncplot_method_label = QtWidgets.QLabel("%s:" % _("Plot kind"))
+ self.cncplot_method_label.setToolTip(
+ _(
+ "This selects the kind of geometries on the canvas to plot.\n"
+ "Those can be either of type 'Travel' which means the moves\n"
+ "above the work piece or it can be of type 'Cut',\n"
+ "which means the moves that cut into the material."
+ )
+ )
+
+ self.cncplot_method_combo = RadioSet([
+ {"label": _("All"), "value": "all"},
+ {"label": _("Travel"), "value": "travel"},
+ {"label": _("Cut"), "value": "cut"}
+ ], stretch=False)
+
+ self.annotation_label = QtWidgets.QLabel("%s:" % _("Display Annotation"))
+ self.annotation_label.setToolTip(
+ _("This selects if to display text annotation on the plot.\n"
+ "When checked it will display numbers in order for each end\n"
+ "of a travel line.")
+ )
+ self.annotation_cb = FCCheckBox()
+
+ # ## Object name
+ self.name_hlay = QtWidgets.QHBoxLayout()
+ self.custom_box.addLayout(self.name_hlay)
+ name_label = QtWidgets.QLabel("%s:" % _("Name"))
+ self.name_entry = FCEntry()
+ self.name_entry.setFocusPolicy(QtCore.Qt.StrongFocus)
+ self.name_hlay.addWidget(name_label)
+ self.name_hlay.addWidget(self.name_entry)
+
+ self.t_distance_label = QtWidgets.QLabel("%s:" % _("Travelled dist."))
+ self.t_distance_label.setToolTip(
+ _("This is the total travelled distance on X-Y plane.\n"
+ "In current units.")
+ )
+ self.t_distance_entry = FCEntry()
+ self.t_distance_entry.setToolTip(
+ _("This is the total travelled distance on X-Y plane.\n"
+ "In current units.")
+ )
+ self.units_label = QtWidgets.QLabel()
+
+ self.t_time_label = QtWidgets.QLabel("%s:" % _("Estimated time"))
+ self.t_time_label.setToolTip(
+ _("This is the estimated time to do the routing/drilling,\n"
+ "without the time spent in ToolChange events.")
+ )
+ self.t_time_entry = FCEntry()
+ self.t_time_entry.setToolTip(
+ _("This is the estimated time to do the routing/drilling,\n"
+ "without the time spent in ToolChange events.")
+ )
+ self.units_time_label = QtWidgets.QLabel()
+
+ f_lay = QtWidgets.QGridLayout()
+ f_lay.setColumnStretch(1, 1)
+ f_lay.setColumnStretch(2, 1)
+
+ self.custom_box.addLayout(f_lay)
+ f_lay.addWidget(self.cncplot_method_label, 0, 0)
+ f_lay.addWidget(self.cncplot_method_combo, 0, 1)
+ f_lay.addWidget(QtWidgets.QLabel(''), 0, 2)
+ f_lay.addWidget(self.annotation_label, 1, 0)
+ f_lay.addWidget(self.annotation_cb, 1, 1)
+ f_lay.addWidget(QtWidgets.QLabel(''), 1, 2)
+ f_lay.addWidget(self.t_distance_label, 2, 0)
+ f_lay.addWidget(self.t_distance_entry, 2, 1)
+ f_lay.addWidget(self.units_label, 2, 2)
+ f_lay.addWidget(self.t_time_label, 3, 0)
+ f_lay.addWidget(self.t_time_entry, 3, 1)
+ f_lay.addWidget(self.units_time_label, 3, 2)
+
+ self.t_distance_label.hide()
+ self.t_distance_entry.setVisible(False)
+ self.t_time_label.hide()
+ self.t_time_entry.setVisible(False)
+
+ e1_lbl = QtWidgets.QLabel('')
+ self.custom_box.addWidget(e1_lbl)
+
+ hlay = QtWidgets.QHBoxLayout()
+ self.custom_box.addLayout(hlay)
+
+ # CNC Tools Table for plot
+ self.cnc_tools_table_label = QtWidgets.QLabel('%s' % _('CNC Tools Table'))
+ self.cnc_tools_table_label.setToolTip(
+ _(
+ "Tools in this CNCJob object used for cutting.\n"
+ "The tool diameter is used for plotting on canvas.\n"
+ "The 'Offset' entry will set an offset for the cut.\n"
+ "'Offset' can be inside, outside, on path (none) and custom.\n"
+ "'Type' entry is only informative and it allow to know the \n"
+ "intent of using the current tool. \n"
+ "It can be Rough(ing), Finish(ing) or Iso(lation).\n"
+ "The 'Tool type'(TT) can be circular with 1 to 4 teeths(C1..C4),\n"
+ "ball(B), or V-Shaped(V)."
+ )
+ )
+ hlay.addWidget(self.cnc_tools_table_label)
+
+ # Plot CB
+ # self.plot_cb = QtWidgets.QCheckBox('Plot')
+ self.plot_cb = FCCheckBox(_('Plot Object'))
+ self.plot_cb.setToolTip(
+ _("Plot (show) this object.")
+ )
+ self.plot_cb.setLayoutDirection(QtCore.Qt.RightToLeft)
+ hlay.addStretch()
+ hlay.addWidget(self.plot_cb)
+
+ self.cnc_tools_table = FCTable()
+ self.custom_box.addWidget(self.cnc_tools_table)
+
+ # self.cnc_tools_table.setColumnCount(4)
+ # self.cnc_tools_table.setHorizontalHeaderLabels(['#', 'Dia', 'Plot', ''])
+ # self.cnc_tools_table.setColumnHidden(3, True)
+ self.cnc_tools_table.setColumnCount(7)
+ self.cnc_tools_table.setColumnWidth(0, 20)
+ self.cnc_tools_table.setHorizontalHeaderLabels(['#', _('Dia'), _('Offset'), _('Type'), _('TT'), '',
+ _('P')])
+ self.cnc_tools_table.setColumnHidden(5, True)
+ # stylesheet = "::section{Background-color:rgb(239,239,245)}"
+ # self.cnc_tools_table.horizontalHeader().setStyleSheet(stylesheet)
+
+ # Update plot button
+ self.updateplot_button = QtWidgets.QPushButton(_('Update Plot'))
+ self.updateplot_button.setToolTip(
+ _("Update the plot.")
+ )
+ self.custom_box.addWidget(self.updateplot_button)
+
+ # ####################
+ # ## Export G-Code ##
+ # ####################
+ self.export_gcode_label = QtWidgets.QLabel("%s:" % _("Export CNC Code"))
+ self.export_gcode_label.setToolTip(
+ _("Export and save G-Code to\n"
+ "make this object to a file.")
+ )
+ self.custom_box.addWidget(self.export_gcode_label)
+
+ # Prepend text to GCode
+ prependlabel = QtWidgets.QLabel('%s:' % _('Prepend to CNC Code'))
+ prependlabel.setToolTip(
+ _("Type here any G-Code commands you would\n"
+ "like to add at the beginning of the G-Code file.")
+ )
+ self.custom_box.addWidget(prependlabel)
+
+ self.prepend_text = FCTextArea()
+ self.custom_box.addWidget(self.prepend_text)
+
+ # Append text to GCode
+ appendlabel = QtWidgets.QLabel('%s:' % _('Append to CNC Code'))
+ appendlabel.setToolTip(
+ _("Type here any G-Code commands you would\n"
+ "like to append to the generated file.\n"
+ "I.e.: M2 (End of program)")
+ )
+ self.custom_box.addWidget(appendlabel)
+
+ self.append_text = FCTextArea()
+ self.custom_box.addWidget(self.append_text)
+
+ self.cnc_frame = QtWidgets.QFrame()
+ self.cnc_frame.setContentsMargins(0, 0, 0, 0)
+ self.custom_box.addWidget(self.cnc_frame)
+ self.cnc_box = QtWidgets.QVBoxLayout()
+ self.cnc_box.setContentsMargins(0, 0, 0, 0)
+ self.cnc_frame.setLayout(self.cnc_box)
+
+ # Toolchange Custom G-Code
+ self.toolchangelabel = QtWidgets.QLabel('%s:' % _('Toolchange G-Code'))
+ self.toolchangelabel.setToolTip(
+ _(
+ "Type here any G-Code commands you would\n"
+ "like to be executed when Toolchange event is encountered.\n"
+ "This will constitute a Custom Toolchange GCode,\n"
+ "or a Toolchange Macro.\n"
+ "The FlatCAM variables are surrounded by '%' symbol.\n\n"
+ "WARNING: it can be used only with a postprocessor file\n"
+ "that has 'toolchange_custom' in it's name and this is built\n"
+ "having as template the 'Toolchange Custom' posprocessor file."
+ )
+ )
+ self.cnc_box.addWidget(self.toolchangelabel)
+
+ self.toolchange_text = FCTextArea()
+ self.cnc_box.addWidget(self.toolchange_text)
+
+ cnclay = QtWidgets.QHBoxLayout()
+ self.cnc_box.addLayout(cnclay)
+
+ # Toolchange Replacement Enable
+ self.toolchange_cb = FCCheckBox(label='%s' % _('Use Toolchange Macro'))
+ self.toolchange_cb.setToolTip(
+ _("Check this box if you want to use\n"
+ "a Custom Toolchange GCode (macro).")
+ )
+
+ # Variable list
+ self.tc_variable_combo = FCComboBox()
+ self.tc_variable_combo.setToolTip(
+ _(
+ "A list of the FlatCAM variables that can be used\n"
+ "in the Toolchange event.\n"
+ "They have to be surrounded by the '%' symbol"
+ )
+ )
+
+ # Populate the Combo Box
+ variables = [_('Parameters'), 'tool', 'tooldia', 't_drills', 'x_toolchange', 'y_toolchange', 'z_toolchange',
+ 'z_cut', 'z_move', 'z_depthpercut', 'spindlespeed', 'dwelltime']
+ self.tc_variable_combo.addItems(variables)
+ self.tc_variable_combo.setItemData(0, _("FlatCAM CNC parameters"), Qt.ToolTipRole)
+ self.tc_variable_combo.setItemData(1, _("tool = tool number"), Qt.ToolTipRole)
+ self.tc_variable_combo.setItemData(2, _("tooldia = tool diameter"), Qt.ToolTipRole)
+ self.tc_variable_combo.setItemData(3, _("t_drills = for Excellon, total number of drills"), Qt.ToolTipRole)
+ self.tc_variable_combo.setItemData(4, _("x_toolchange = X coord for Toolchange"), Qt.ToolTipRole)
+ self.tc_variable_combo.setItemData(5, _("y_toolchange = Y coord for Toolchange"), Qt.ToolTipRole)
+ self.tc_variable_combo.setItemData(6, _("z_toolchange = Z coord for Toolchange"), Qt.ToolTipRole)
+ self.tc_variable_combo.setItemData(7, _("z_cut = depth where to cut"), Qt.ToolTipRole)
+ self.tc_variable_combo.setItemData(8, _("z_move = height where to travel"), Qt.ToolTipRole)
+ self.tc_variable_combo.setItemData(9, _("z_depthpercut = the step value for multidepth cut"), Qt.ToolTipRole)
+ self.tc_variable_combo.setItemData(10, _("spindlesspeed = the value for the spindle speed"), Qt.ToolTipRole)
+ self.tc_variable_combo.setItemData(11, _("dwelltime = time to dwell to allow the "
+ "spindle to reach it's set RPM"),
+ Qt.ToolTipRole)
+
+ cnclay.addWidget(self.toolchange_cb)
+ cnclay.addStretch()
+ cnclay.addWidget(self.tc_variable_combo)
+
+ self.toolch_ois = OptionalInputSection(self.toolchange_cb,
+ [self.toolchangelabel, self.toolchange_text, self.tc_variable_combo])
+
+ h_lay = QtWidgets.QHBoxLayout()
+ h_lay.setAlignment(QtCore.Qt.AlignVCenter)
+ self.custom_box.addLayout(h_lay)
+
+ # Edit GCode Button
+ self.modify_gcode_button = QtWidgets.QPushButton(_('View CNC Code'))
+ self.modify_gcode_button.setToolTip(
+ _("Opens TAB to view/modify/print G-Code\n"
+ "file.")
+ )
+
+ # GO Button
+ self.export_gcode_button = QtWidgets.QPushButton(_('Save CNC Code'))
+ self.export_gcode_button.setToolTip(
+ _("Opens dialog to save G-Code\n"
+ "file.")
+ )
+
+ h_lay.addWidget(self.modify_gcode_button)
+ h_lay.addWidget(self.export_gcode_button)
+ # self.custom_box.addWidget(self.export_gcode_button)
+
+class NotesObjectUI(ObjectUI):
+ """
+ User interface for Notes objects.
+ """
+
+ def __init__(self, parent=None):
+ """
+ Creates the user interface for Notes objects. GUI elements should
+ be placed in ``self.custom_box`` to preserve the layout.
+ """
+
+ ObjectUI.__init__(self, title=_('Notes Object'), icon_file='share/cnc32.png', parent=parent)
+
+ # Scale and offset ans skew are not available for CNCJob objects.
+ # Hiding from the GUI.
+ for i in range(0, self.scale_grid.count()):
+ self.scale_grid.itemAt(i).widget().hide()
+ self.scale_label.hide()
+ self.scale_button.hide()
+
+ for i in range(0, self.offset_grid.count()):
+ self.offset_grid.itemAt(i).widget().hide()
+ self.offset_label.hide()
+ self.offset_button.hide()
+
+ # ## Plot options
+ self.plot_options_label = QtWidgets.QLabel("%s:" % _("Plot Options"))
+ self.custom_box.addWidget(self.plot_options_label)
+
+ self.cncplot_method_label = QtWidgets.QLabel("%s:" % _("Plot kind"))
+ self.cncplot_method_label.setToolTip(
+ _(
+ "This selects the kind of geometries on the canvas to plot.\n"
+ "Those can be either of type 'Travel' which means the moves\n"
+ "above the work piece or it can be of type 'Cut',\n"
+ "which means the moves that cut into the material."
+ )
+ )
+
+ self.cncplot_method_combo = RadioSet([
+ {"label": _("All"), "value": "all"},
+ {"label": _("Travel"), "value": "travel"},
+ {"label": _("Cut"), "value": "cut"}
+ ], stretch=False)
+
+ self.annotation_label = QtWidgets.QLabel("%s:" % _("Display Annotation"))
+ self.annotation_label.setToolTip(
+ _("This selects if to display text annotation on the plot.\n"
+ "When checked it will display numbers in order for each end\n"
+ "of a travel line.")
+ )
+ self.annotation_cb = FCCheckBox()
+
+ # ## Object name
+ self.name_hlay = QtWidgets.QHBoxLayout()
+ self.custom_box.addLayout(self.name_hlay)
+ name_label = QtWidgets.QLabel("%s:" % _("Name"))
+ self.name_entry = FCEntry()
+ self.name_entry.setFocusPolicy(QtCore.Qt.StrongFocus)
+ self.name_hlay.addWidget(name_label)
+ self.name_hlay.addWidget(self.name_entry)
+
+ self.t_distance_label = QtWidgets.QLabel("%s:" % _("Travelled dist."))
+ self.t_distance_label.setToolTip(
+ _("This is the total travelled distance on X-Y plane.\n"
+ "In current units.")
+ )
+ self.t_distance_entry = FCEntry()
+ self.t_distance_entry.setToolTip(
+ _("This is the total travelled distance on X-Y plane.\n"
+ "In current units.")
+ )
+ self.units_label = QtWidgets.QLabel()
+
+ self.t_time_label = QtWidgets.QLabel("%s:" % _("Estimated time"))
+ self.t_time_label.setToolTip(
+ _("This is the estimated time to do the routing/drilling,\n"
+ "without the time spent in ToolChange events.")
+ )
+ self.t_time_entry = FCEntry()
+ self.t_time_entry.setToolTip(
+ _("This is the estimated time to do the routing/drilling,\n"
+ "without the time spent in ToolChange events.")
+ )
+ self.units_time_label = QtWidgets.QLabel()
+
+ f_lay = QtWidgets.QGridLayout()
+ f_lay.setColumnStretch(1, 1)
+ f_lay.setColumnStretch(2, 1)
+
+ self.custom_box.addLayout(f_lay)
+ f_lay.addWidget(self.cncplot_method_label, 0, 0)
+ f_lay.addWidget(self.cncplot_method_combo, 0, 1)
+ f_lay.addWidget(QtWidgets.QLabel(''), 0, 2)
+ f_lay.addWidget(self.annotation_label, 1, 0)
+ f_lay.addWidget(self.annotation_cb, 1, 1)
+ f_lay.addWidget(QtWidgets.QLabel(''), 1, 2)
+ f_lay.addWidget(self.t_distance_label, 2, 0)
+ f_lay.addWidget(self.t_distance_entry, 2, 1)
+ f_lay.addWidget(self.units_label, 2, 2)
+ f_lay.addWidget(self.t_time_label, 3, 0)
+ f_lay.addWidget(self.t_time_entry, 3, 1)
+ f_lay.addWidget(self.units_time_label, 3, 2)
+
+ self.t_distance_label.hide()
+ self.t_distance_entry.setVisible(False)
+ self.t_time_label.hide()
+ self.t_time_entry.setVisible(False)
+
+ e1_lbl = QtWidgets.QLabel('')
+ self.custom_box.addWidget(e1_lbl)
+
+ hlay = QtWidgets.QHBoxLayout()
+ self.custom_box.addLayout(hlay)
+
+ # CNC Tools Table for plot
+ self.cnc_tools_table_label = QtWidgets.QLabel('%s' % _('CNC Tools Table'))
+ self.cnc_tools_table_label.setToolTip(
+ _(
+ "Tools in this CNCJob object used for cutting.\n"
+ "The tool diameter is used for plotting on canvas.\n"
+ "The 'Offset' entry will set an offset for the cut.\n"
+ "'Offset' can be inside, outside, on path (none) and custom.\n"
+ "'Type' entry is only informative and it allow to know the \n"
+ "intent of using the current tool. \n"
+ "It can be Rough(ing), Finish(ing) or Iso(lation).\n"
+ "The 'Tool type'(TT) can be circular with 1 to 4 teeths(C1..C4),\n"
+ "ball(B), or V-Shaped(V)."
+ )
+ )
+ hlay.addWidget(self.cnc_tools_table_label)
+
+ # Plot CB
+ # self.plot_cb = QtWidgets.QCheckBox('Plot')
+ self.plot_cb = FCCheckBox(_('Plot Object'))
+ self.plot_cb.setToolTip(
+ _("Plot (show) this object.")
+ )
+ self.plot_cb.setLayoutDirection(QtCore.Qt.RightToLeft)
+ hlay.addStretch()
+ hlay.addWidget(self.plot_cb)
+
+ self.cnc_tools_table = FCTable()
+ self.custom_box.addWidget(self.cnc_tools_table)
+
+ # self.cnc_tools_table.setColumnCount(4)
+ # self.cnc_tools_table.setHorizontalHeaderLabels(['#', 'Dia', 'Plot', ''])
+ # self.cnc_tools_table.setColumnHidden(3, True)
+ self.cnc_tools_table.setColumnCount(7)
+ self.cnc_tools_table.setColumnWidth(0, 20)
+ self.cnc_tools_table.setHorizontalHeaderLabels(['#', _('Dia'), _('Offset'), _('Type'), _('TT'), '',
+ _('P')])
+ self.cnc_tools_table.setColumnHidden(5, True)
+ # stylesheet = "::section{Background-color:rgb(239,239,245)}"
+ # self.cnc_tools_table.horizontalHeader().setStyleSheet(stylesheet)
+
+ # Update plot button
+ self.updateplot_button = QtWidgets.QPushButton(_('Update Plot'))
+ self.updateplot_button.setToolTip(
+ _("Update the plot.")
+ )
+ self.custom_box.addWidget(self.updateplot_button)
+
+ # ####################
+ # ## Export G-Code ##
+ # ####################
+ self.export_gcode_label = QtWidgets.QLabel("%s:" % _("Export CNC Code"))
+ self.export_gcode_label.setToolTip(
+ _("Export and save G-Code to\n"
+ "make this object to a file.")
+ )
+ self.custom_box.addWidget(self.export_gcode_label)
+
+ # Prepend text to GCode
+ prependlabel = QtWidgets.QLabel('%s:' % _('Prepend to CNC Code'))
+ prependlabel.setToolTip(
+ _("Type here any G-Code commands you would\n"
+ "like to add at the beginning of the G-Code file.")
+ )
+ self.custom_box.addWidget(prependlabel)
+
+ self.prepend_text = FCTextArea()
+ self.custom_box.addWidget(self.prepend_text)
+
+ # Append text to GCode
+ appendlabel = QtWidgets.QLabel('%s:' % _('Append to CNC Code'))
+ appendlabel.setToolTip(
+ _("Type here any G-Code commands you would\n"
+ "like to append to the generated file.\n"
+ "I.e.: M2 (End of program)")
+ )
+ self.custom_box.addWidget(appendlabel)
+
+ self.append_text = FCTextArea()
+ self.custom_box.addWidget(self.append_text)
+
+ self.cnc_frame = QtWidgets.QFrame()
+ self.cnc_frame.setContentsMargins(0, 0, 0, 0)
+ self.custom_box.addWidget(self.cnc_frame)
+ self.cnc_box = QtWidgets.QVBoxLayout()
+ self.cnc_box.setContentsMargins(0, 0, 0, 0)
+ self.cnc_frame.setLayout(self.cnc_box)
+
+ # Toolchange Custom G-Code
+ self.toolchangelabel = QtWidgets.QLabel('%s:' % _('Toolchange G-Code'))
+ self.toolchangelabel.setToolTip(
+ _(
+ "Type here any G-Code commands you would\n"
+ "like to be executed when Toolchange event is encountered.\n"
+ "This will constitute a Custom Toolchange GCode,\n"
+ "or a Toolchange Macro.\n"
+ "The FlatCAM variables are surrounded by '%' symbol.\n\n"
+ "WARNING: it can be used only with a postprocessor file\n"
+ "that has 'toolchange_custom' in it's name and this is built\n"
+ "having as template the 'Toolchange Custom' posprocessor file."
+ )
+ )
+ self.cnc_box.addWidget(self.toolchangelabel)
+
+ self.toolchange_text = FCTextArea()
+ self.cnc_box.addWidget(self.toolchange_text)
+
+ cnclay = QtWidgets.QHBoxLayout()
+ self.cnc_box.addLayout(cnclay)
+
+ # Toolchange Replacement Enable
+ self.toolchange_cb = FCCheckBox(label='%s' % _('Use Toolchange Macro'))
+ self.toolchange_cb.setToolTip(
+ _("Check this box if you want to use\n"
+ "a Custom Toolchange GCode (macro).")
+ )
+
+ # Variable list
+ self.tc_variable_combo = FCComboBox()
+ self.tc_variable_combo.setToolTip(
+ _(
+ "A list of the FlatCAM variables that can be used\n"
+ "in the Toolchange event.\n"
+ "They have to be surrounded by the '%' symbol"
+ )
+ )
+
+ # Populate the Combo Box
+ variables = [_('Parameters'), 'tool', 'tooldia', 't_drills', 'x_toolchange', 'y_toolchange', 'z_toolchange',
+ 'z_cut', 'z_move', 'z_depthpercut', 'spindlespeed', 'dwelltime']
+ self.tc_variable_combo.addItems(variables)
+ self.tc_variable_combo.setItemData(0, _("FlatCAM CNC parameters"), Qt.ToolTipRole)
+ self.tc_variable_combo.setItemData(1, _("tool = tool number"), Qt.ToolTipRole)
+ self.tc_variable_combo.setItemData(2, _("tooldia = tool diameter"), Qt.ToolTipRole)
+ self.tc_variable_combo.setItemData(3, _("t_drills = for Excellon, total number of drills"), Qt.ToolTipRole)
+ self.tc_variable_combo.setItemData(4, _("x_toolchange = X coord for Toolchange"), Qt.ToolTipRole)
+ self.tc_variable_combo.setItemData(5, _("y_toolchange = Y coord for Toolchange"), Qt.ToolTipRole)
+ self.tc_variable_combo.setItemData(6, _("z_toolchange = Z coord for Toolchange"), Qt.ToolTipRole)
+ self.tc_variable_combo.setItemData(7, _("z_cut = depth where to cut"), Qt.ToolTipRole)
+ self.tc_variable_combo.setItemData(8, _("z_move = height where to travel"), Qt.ToolTipRole)
+ self.tc_variable_combo.setItemData(9, _("z_depthpercut = the step value for multidepth cut"), Qt.ToolTipRole)
+ self.tc_variable_combo.setItemData(10, _("spindlesspeed = the value for the spindle speed"), Qt.ToolTipRole)
+ self.tc_variable_combo.setItemData(11, _("dwelltime = time to dwell to allow the "
+ "spindle to reach it's set RPM"),
+ Qt.ToolTipRole)
+
+ cnclay.addWidget(self.toolchange_cb)
+ cnclay.addStretch()
+ cnclay.addWidget(self.tc_variable_combo)
+
+ self.toolch_ois = OptionalInputSection(self.toolchange_cb,
+ [self.toolchangelabel, self.toolchange_text, self.tc_variable_combo])
+
+ h_lay = QtWidgets.QHBoxLayout()
+ h_lay.setAlignment(QtCore.Qt.AlignVCenter)
+ self.custom_box.addLayout(h_lay)
+
+ # Edit GCode Button
+ self.modify_gcode_button = QtWidgets.QPushButton(_('View CNC Code'))
+ self.modify_gcode_button.setToolTip(
+ _("Opens TAB to view/modify/print G-Code\n"
+ "file.")
+ )
+
+ # GO Button
+ self.export_gcode_button = QtWidgets.QPushButton(_('Save CNC Code'))
+ self.export_gcode_button.setToolTip(
+ _("Opens dialog to save G-Code\n"
+ "file.")
+ )
+
+ h_lay.addWidget(self.modify_gcode_button)
+ h_lay.addWidget(self.export_gcode_button)
+ # self.custom_box.addWidget(self.export_gcode_button)
+
# end of file
diff --git a/share/notes16.png b/share/notes16.png
new file mode 100644
index 00000000..49d3a42b
Binary files /dev/null and b/share/notes16.png differ
diff --git a/share/notes16_1.png b/share/notes16_1.png
new file mode 100644
index 00000000..c0fe81e4
Binary files /dev/null and b/share/notes16_1.png differ