From 19444fb28c759bf0f1e2984220e78f9e3720f471 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 13 Sep 2019 13:52:55 +0300 Subject: [PATCH] - upgraded the Script Editor to be able to run Tcl commands in batches - added some ToolTips for the buttons in the Code Editor --- FlatCAMApp.py | 38 +++++++++++++++++++++++++++++--------- README.md | 2 ++ flatcamGUI/FlatCAMGUI.py | 23 ++++++++++++++++++++++- flatcamTools/ToolShell.py | 22 +++++++++++----------- 4 files changed, 64 insertions(+), 21 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index d647f7fb..09798c87 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -3056,11 +3056,11 @@ class App(QtCore.QObject): :return: Output from the command """ - text = str(text) + tcl_command_string = str(text) try: self.shell.open_proccessing() # Disables input box. - result = self.tcl.eval(str(text)) + result = self.tcl.eval(str(tcl_command_string)) if result != 'None': self.shell.append_output(result + '\n') @@ -3072,7 +3072,6 @@ class App(QtCore.QObject): # Show error in console and just return or in test raise exception if reraise: raise e - finally: self.shell.close_proccessing() pass @@ -5770,6 +5769,24 @@ class App(QtCore.QObject): # Mark end of undo block cursor.endEditBlock() + def handleRunCode(self): + # trying to run a Tcl command without having the Shell open will create some warnings because the Tcl Shell + # tries to print on a hidden widget, therefore show the dock if hidden + if self.ui.shell_dock.isHidden(): + self.ui.shell_dock.show() + + script_code = self.ui.code_editor.toPlainText() + for tcl_command_line in script_code.splitlines(): + # do not process lines starting with '#' = comment and empty lines + if not tcl_command_line.startswith('#') and tcl_command_line != '': + # id FlatCAM is run in Windows then replace all the slashes with + # the UNIX style slash that TCL understands + if sys.platform == 'win32': + if "open" in tcl_command_line: + tcl_command_line = tcl_command_line.replace('\\', '/') + # execute the actual Tcl command + self.shell._sysShell.exec_command(tcl_command_line) + def on_tool_add_keypress(self): # ## Current application units in Upper Case self.units = self.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() @@ -8013,6 +8030,7 @@ class App(QtCore.QObject): self.ui.code_editor.setReadOnly(False) self.toggle_codeeditor = True self.ui.code_editor.completer_enable = False + self.ui.buttonRun.hide() # Switch plot_area to CNCJob tab self.ui.plot_tab_area.setCurrentWidget(self.ui.cncjob_tab) @@ -8090,17 +8108,19 @@ class App(QtCore.QObject): "# TCL Tutorial here: https://www.tcl.tk/man/tcl8.5/tutorial/tcltutorial.html\n" "#\n\n" "# FlatCAM commands list:\n" - "# AddCircle, AddPolygon, AddPolyline, AddRectangle, AlignDrill, AlignDrillGrid, ClearShell, Cncjob,\n" - "# Cutout, Delete, Drillcncjob, ExportGcode, ExportSVG, Exteriors, GeoCutout, GeoUnion, GetNames, GetSys,\n" - "# ImportSvg, Interiors, Isolate, Follow, JoinExcellon, JoinGeometry, ListSys, MillHoles, Mirror, New,\n" - "# NewGeometry, Offset, OpenExcellon, OpenGCode, OpenGerber, OpenProject, Options, Paint, Panelize,\n" - "# Plot, SaveProject, SaveSys, Scale, SetActive, SetSys, Skew, SubtractPoly,SubtractRectangle, Version,\n" - "# WriteGCode\n" + "# AddCircle, AddPolygon, AddPolyline, AddRectangle, AlignDrill, AlignDrillGrid, ClearShell, ClearCopper,\n" + "# Cncjob, Cutout, Delete, Drillcncjob, ExportGcode, ExportSVG, Exteriors, GeoCutout, GeoUnion, GetNames,\n" + "# GetSys, ImportSvg, Interiors, Isolate, Follow, JoinExcellon, JoinGeometry, ListSys, MillDrills,\n" + "# MillSlots, Mirror, New, NewGeometry, Offset, OpenExcellon, OpenGCode, OpenGerber, OpenProject,\n" + "# Options, Paint, Panelize, Plot, SaveProject, SaveSys, Scale, SetActive, SetSys, Skew, SubtractPoly,\n" + "# SubtractRectangle, Version, WriteGCode\n" "#\n\n" )) self.ui.buttonOpen.clicked.connect(lambda: self.handleOpen(filt=flt)) self.ui.buttonSave.clicked.connect(lambda: self.handleSaveGCode(filt=flt)) + self.ui.buttonRun.show() + self.ui.buttonRun.clicked.connect(self.handleRunCode) self.handleTextChanged() self.ui.code_editor.show() diff --git a/README.md b/README.md index 6455833e..97340c02 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ CAD program, and create G-Code for Isolation routing. - added control for simplification when loading a Gerber file in Preferences -> Gerber -> Gerber General -> Simplify - added some messages for the Edit -> Conversions -> Join methods() to make sure that there are at least 2 objects selected for join - added a grid layout in on_about() +- upgraded the Script Editor to be able to run Tcl commands in batches +- added some ToolTips for the buttons in the Code Editor 12.09.2019 diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index 290c4435..3770ded4 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -1756,24 +1756,43 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.code_editor.setStyleSheet(stylesheet) self.buttonPreview = QtWidgets.QPushButton(_('Print Preview')) + self.buttonPreview.setToolTip(_("Open a OS standard Preview Print window.")) self.buttonPrint = QtWidgets.QPushButton(_('Print Code')) + self.buttonPrint.setToolTip(_("Open a OS standard Print window.")) + self.buttonFind = QtWidgets.QPushButton(_('Find in Code')) + self.buttonFind.setToolTip(_("Will search and highlight in yellow the string in the Find box.")) self.buttonFind.setMinimumWidth(100) + self.buttonPreview.setMinimumWidth(100) + self.entryFind = FCEntry() + self.entryFind.setToolTip(_("Find box. Enter here the strings to be searched in the text.")) self.entryFind.setMaximumWidth(200) + self.buttonReplace = QtWidgets.QPushButton(_('Replace With')) + self.buttonReplace.setToolTip(_("Will replace the string from the Find box with the one in the Replace box.")) + self.buttonReplace.setMinimumWidth(100) self.entryReplace = FCEntry() + self.entryReplace.setToolTip(_("String to replace the one in the Find box throughout the text.")) self.entryReplace.setMaximumWidth(200) + self.sel_all_cb = QtWidgets.QCheckBox(_('All')) self.sel_all_cb.setToolTip( _("When checked it will replace all instances in the 'Find' box\n" "with the text in the 'Replace' box..") ) self.buttonOpen = QtWidgets.QPushButton(_('Open Code')) - self.buttonSave = QtWidgets.QPushButton(_('Save Code')) + self.buttonOpen.setToolTip(_("Will open a text file in the editor.")) + self.buttonSave = QtWidgets.QPushButton(_('Save Code')) + self.buttonSave.setToolTip(_("Will save the text in the editor into a file.")) + + self.buttonRun = QtWidgets.QPushButton(_('Run Code')) + self.buttonRun.setToolTip(_("Will run the TCL commands found in the text file, one by one.")) + + self.buttonRun.hide() self.cncjob_tab_layout.addWidget(self.code_editor, 0, 0, 1, 5) cnc_tab_lay_1 = QtWidgets.QHBoxLayout() @@ -1795,6 +1814,8 @@ class FlatCAMGUI(QtWidgets.QMainWindow): cnc_tab_lay_4.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) cnc_tab_lay_4.addWidget(self.buttonOpen) cnc_tab_lay_4.addWidget(self.buttonSave) + cnc_tab_lay_4.addWidget(self.buttonRun) + self.cncjob_tab_layout.addLayout(cnc_tab_lay_4, 2, 4, 1, 1) # ################################# diff --git a/flatcamTools/ToolShell.py b/flatcamTools/ToolShell.py index f0e41e5b..ce79ab3a 100644 --- a/flatcamTools/ToolShell.py +++ b/flatcamTools/ToolShell.py @@ -24,8 +24,8 @@ if '_' not in builtins.__dict__: class TermWidget(QWidget): """ - Widget wich represents terminal. It only displays text and allows to enter text. - All highlevel logic should be implemented by client classes + Widget which represents terminal. It only displays text and allows to enter text. + All high level logic should be implemented by client classes User pressed Enter. Client class should decide, if command must be executed or user may continue edit it """ @@ -57,7 +57,7 @@ class TermWidget(QWidget): def open_proccessing(self, detail=None): """ - Open processing and disable using shell commands again until all commands are finished + Open processing and disable using shell commands again until all commands are finished :param detail: text detail about what is currently called from TCL to python :return: None @@ -114,10 +114,10 @@ class TermWidget(QWidget): self._browser.moveCursor(QTextCursor.End) self._browser.insertHtml(text) - """TODO When user enters second line to the input, and input is resized, scrollbar changes its positon + """TODO When user enters second line to the input, and input is resized, scrollbar changes its position and stops moving. As quick fix of this problem, now we always scroll down when add new text. - To fix it correctly, srcoll to the bottom, if before intput has been resized, - scrollbar was in the bottom, and remove next lien + To fix it correctly, scroll to the bottom, if before input has been resized, + scrollbar was in the bottom, and remove next line """ scrollattheend = True @@ -129,13 +129,12 @@ class TermWidget(QWidget): def exec_current_command(self): """ Save current command in the history. Append it to the log. Clear edit line - Reimplement in the child classes to actually execute command + Re-implement in the child classes to actually execute command """ text = str(self._edit.toPlainText()) self._append_to_browser('in', '> ' + text + '\n') - if len(self._history) < 2 or\ - self._history[-2] != text: # don't insert duplicating items + if len(self._history) < 2 or self._history[-2] != text: # don't insert duplicating items if text[-1] == '\n': self._history.insert(-1, text[:-1]) else: @@ -153,7 +152,7 @@ class TermWidget(QWidget): def child_exec_command(self, text): """ - Reimplement in the child classes + Re-implement in the child classes """ pass @@ -161,7 +160,8 @@ class TermWidget(QWidget): self._edit.textCursor().insertText('\n') def append_output(self, text): - """Appent text to output widget + """ + Append text to output widget """ self._append_to_browser('out', text)