Przeglądaj źródła

- added two new FlatCAM objects: FlatCAMScript and FlatCAMNotes

Marius Stanciu 6 lat temu
rodzic
commit
ee0742db7a
7 zmienionych plików z 703 dodań i 14 usunięć
  1. 56 11
      FlatCAMApp.py
  2. 56 0
      FlatCAMObj.py
  3. 9 3
      ObjectCollection.py
  4. 1 0
      README.md
  5. 581 0
      flatcamGUI/ObjectUI.py
  6. BIN
      share/notes16.png
  7. BIN
      share/notes16_1.png

+ 56 - 11
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: <span style="color:{color};">{name}</span>').format(
                 kind=obj.kind.capitalize(), color='red', name=str(obj.options['name'])))
+        elif obj.kind == 'script':
+            self.inform.emit(_('[selected] {kind} created/selected: <span style="color:{color};">{name}</span>').format(
+                kind=obj.kind.capitalize(), color='orange', name=str(obj.options['name'])))
+        elif obj.kind == 'notes':
+            self.inform.emit(_('[selected] {kind} created/selected: <span style="color:{color};">{name}</span>').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

+ 56 - 0
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

+ 9 - 3
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

+ 1 - 0
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
 

+ 581 - 0
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("<b>%s:</b>" % _("Plot Options"))
+        self.custom_box.addWidget(self.plot_options_label)
+
+        self.cncplot_method_label = QtWidgets.QLabel("<b>%s:</b>" % _("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("<b>%s:</b>" % _("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("<b>%s:</b>" % _("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("<b>%s:</b>" % _("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("<b>%s:</b>" % _("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('<b>%s</b>' % _('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("<b>%s:</b>" % _("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("<b>%s:</b>" % _("Plot Options"))
+        self.custom_box.addWidget(self.plot_options_label)
+
+        self.cncplot_method_label = QtWidgets.QLabel("<b>%s:</b>" % _("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("<b>%s:</b>" % _("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("<b>%s:</b>" % _("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("<b>%s:</b>" % _("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("<b>%s:</b>" % _("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('<b>%s</b>' % _('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("<b>%s:</b>" % _("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

BIN
share/notes16.png


BIN
share/notes16_1.png