From ee0742db7ad3397e27e602319d138456164a4a83 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Tue, 1 Oct 2019 18:24:15 +0300 Subject: [PATCH] - added two new FlatCAM objects: FlatCAMScript and FlatCAMNotes --- FlatCAMApp.py | 67 ++++- FlatCAMObj.py | 56 ++++ ObjectCollection.py | 12 +- README.md | 1 + flatcamGUI/ObjectUI.py | 581 +++++++++++++++++++++++++++++++++++++++++ share/notes16.png | Bin 0 -> 306 bytes share/notes16_1.png | Bin 0 -> 291 bytes 7 files changed, 703 insertions(+), 14 deletions(-) create mode 100644 share/notes16.png create mode 100644 share/notes16_1.png 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 0000000000000000000000000000000000000000..49d3a42b3f6e7c2bbd9079a508168cba8f98724b GIT binary patch literal 306 zcmeAS@N?(olHy`uVBq!ia0vp@KrFz)1|-ie{%Q%NSc;uILpXq-h9ji|$mcBZh%9Dc z;1&j9Muu5)B!GffJY5_^G$u~Hu-D7kQQ+vu_(NScIK@6PD=wH2<&mqsLVpQIob-IP z)OikXa&>fd-Zn+dS}k_&YH4wP2m3Tz>ofB$t^d4QbaeYwm6)Tp2RP(!98bNYeC1*O zhkM7Rv}7K!q+1-w4YTgQRr+Oh(yKflpBs@utAnQPJQnt2uLW({X(?Z`<)EWcmtgLXU-Q5xGVa8h4MZB zHD(!4UB7$~N)OFd-xKxchf%JI&xU{eFFtZ}SZf|?kh$rclOH7gE z>6`s;)`G^<4D}Q03RfN!(r5f9Iy<3tKEwJX+2nxZp$+*3;>jPTgihh(UAE(R`N_F1 mR>~*((?yr7vPHivKERj0M{})IUT+uBj|`r!elF{r5}E*`%63Em literal 0 HcmV?d00001