diff --git a/FlatCAMApp.py b/FlatCAMApp.py index f6508e0f..40e94743 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -48,6 +48,7 @@ from FlatCAMPostProc import load_postprocessors from flatcamEditors.FlatCAMGeoEditor import FlatCAMGeoEditor from flatcamEditors.FlatCAMExcEditor import FlatCAMExcEditor from flatcamEditors.FlatCAMGrbEditor import FlatCAMGrbEditor +from flatcamEditors.FlatCAMTextEditor import TextEditor from FlatCAMProcess import * from FlatCAMWorkerStack import WorkerStack @@ -1997,16 +1998,6 @@ class App(QtCore.QObject): self.ui.tools_defaults_form.tools_film_group.film_color_button.clicked.connect( self.on_film_color_button) - # ########## Modify G-CODE Plot Area TAB ########### - self.ui.code_editor.textChanged.connect(self.handleTextChanged) - self.ui.buttonOpen.clicked.connect(self.handleOpen) - self.ui.buttonSave.clicked.connect(self.handleSaveGCode) - self.ui.buttonPrint.clicked.connect(self.handlePrint) - self.ui.buttonPreview.clicked.connect(self.handlePreview) - self.ui.buttonFind.clicked.connect(self.handleFindGCode) - self.ui.buttonReplace.clicked.connect(self.handleReplaceGCode) - self.ui.button_copy_all.clicked.connect(self.handleCopyAll) - # portability changed signal self.ui.general_defaults_form.general_app_group.portability_cb.stateChanged.connect(self.on_portable_checked) @@ -2356,7 +2347,6 @@ class App(QtCore.QObject): self.shell = FCShell(self, version=self.version) self.shell._edit.set_model_data(self.myKeywords) - self.ui.code_editor.set_model_data(self.myKeywords) self.shell.setWindowIcon(self.ui.app_icon) self.shell.setWindowTitle("FlatCAM Shell") self.shell.resize(*self.defaults["global_shell_shape"]) @@ -4099,19 +4089,35 @@ class App(QtCore.QObject): self.new_object('gerber', 'new_grb', initialize, plot=False) - - def new_script_object(self): + def new_script_object(self, name=None): """ Creates a new, blank TCL Script object. - + :param name: a name for the new object :return: None """ self.report_usage("new_script_object()") def initialize(obj, self): - obj.source_file = "" + obj.source_file = _( + "#\n" + "# CREATE A NEW FLATCAM TCL SCRIPT\n" + "# 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, 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" + ) + if name is None: + outname = 'new_script' + else: + outname = name - self.new_object('script', 'new_script', initialize, plot=False) + self.new_object('script', outname, initialize, plot=False) def new_notes_object(self): @@ -4170,7 +4176,6 @@ class App(QtCore.QObject): # update the SHELL auto-completer model with the name of the new object self.myKeywords.append(obj.options['name']) self.shell._edit.set_model_data(self.myKeywords) - self.ui.code_editor.set_model_data(self.myKeywords) if autoselect: # select the just opened object but deselect the previous ones @@ -5037,7 +5042,6 @@ class App(QtCore.QObject): self.ui.util_defaults_form.kw_group.kw_list_text.get_value().replace(' ', '').split(',') self.myKeywords = self.tcl_commands_list + self.autocomplete_kw_list + self.tcl_keywords self.shell._edit.set_model_data(self.myKeywords) - self.ui.code_editor.set_model_data(self.myKeywords) def del_extension(self, ext_type): if ext_type == 'excellon': @@ -5090,7 +5094,6 @@ class App(QtCore.QObject): self.ui.util_defaults_form.kw_group.kw_list_text.get_value().replace(' ', '').split(',') self.myKeywords = self.tcl_commands_list + self.autocomplete_kw_list + self.tcl_keywords self.shell._edit.set_model_data(self.myKeywords) - self.ui.code_editor.set_model_data(self.myKeywords) def restore_extensions(self, ext_type): if ext_type == 'excellon': @@ -5114,7 +5117,6 @@ class App(QtCore.QObject): self.autocomplete_kw_list = self.default_keywords self.myKeywords = self.tcl_commands_list + self.autocomplete_kw_list + self.tcl_keywords self.shell._edit.set_model_data(self.myKeywords) - self.ui.code_editor.set_model_data(self.myKeywords) def delete_all_extensions(self, ext_type): if ext_type == 'excellon': @@ -5129,7 +5131,6 @@ class App(QtCore.QObject): # update the self.myKeywords so the model is updated self.myKeywords = self.tcl_commands_list + self.tcl_keywords self.shell._edit.set_model_data(self.myKeywords) - self.ui.code_editor.set_model_data(self.myKeywords) def on_edit_join(self, name=None): """ @@ -6554,192 +6555,6 @@ class App(QtCore.QObject): # This will write the setting to the platform specific storage. del settings - def handlePrint(self): - self.report_usage("handlePrint()") - - dialog = QtPrintSupport.QPrintDialog() - if dialog.exec_() == QtWidgets.QDialog.Accepted: - self.ui.code_editor.document().print_(dialog.printer()) - - def handlePreview(self): - self.report_usage("handlePreview()") - - dialog = QtPrintSupport.QPrintPreviewDialog() - dialog.paintRequested.connect(self.ui.code_editor.print_) - dialog.exec_() - - def handleTextChanged(self): - # enable = not self.ui.code_editor.document().isEmpty() - # self.ui.buttonPrint.setEnabled(enable) - # self.ui.buttonPreview.setEnabled(enable) - pass - - def handleOpen(self, filt=None): - self.report_usage("handleOpen()") - - if filt: - _filter_ = filt - else: - _filter_ = "G-Code Files (*.nc);; G-Code Files (*.txt);; G-Code Files (*.tap);; G-Code Files (*.cnc);; " \ - "All Files (*.*)" - - path, _f = QtWidgets.QFileDialog.getOpenFileName( - caption=_('Open file'), directory=self.get_last_folder(), filter=_filter_) - - if path: - file = QtCore.QFile(path) - if file.open(QtCore.QIODevice.ReadOnly): - stream = QtCore.QTextStream(file) - self.gcode_edited = stream.readAll() - self.ui.code_editor.setPlainText(self.gcode_edited) - file.close() - - def handleSaveGCode(self, name=None, filt=None): - self.report_usage("handleSaveGCode()") - - if filt: - _filter_ = filt - else: - _filter_ = "G-Code Files (*.nc);; G-Code Files (*.txt);; G-Code Files (*.tap);; G-Code Files (*.cnc);; " \ - "All Files (*.*)" - - if name: - obj_name = name - else: - try: - obj_name = self.collection.get_active().options['name'] - except AttributeError: - obj_name = 'file' - if filt is None: - _filter_ = "FlatConfig Files (*.FlatConfig);;All Files (*.*)" - - try: - filename = str(QtWidgets.QFileDialog.getSaveFileName( - caption=_("Export G-Code ..."), - directory=self.defaults["global_last_folder"] + '/' + str(obj_name), - filter=_filter_ - )[0]) - except TypeError: - filename = str(QtWidgets.QFileDialog.getSaveFileName(caption=_("Export G-Code ..."), filter=_filter_)[0]) - - if filename == "": - self.inform.emit('[WARNING_NOTCL] %s' % - _("Export Code cancelled.")) - return - else: - try: - my_gcode = self.ui.code_editor.toPlainText() - with open(filename, 'w') as f: - for line in my_gcode: - f.write(line) - except FileNotFoundError: - self.inform.emit('[WARNING] %s' % - _("No such file or directory")) - return - except PermissionError: - self.inform.emit('[WARNING] %s' % - _("Permission denied, saving not possible.\n" - "Most likely another app is holding the file open and not accessible.")) - return - - # Just for adding it to the recent files list. - if self.defaults["global_open_style"] is False: - self.file_opened.emit("cncjob", filename) - self.file_saved.emit("cncjob", filename) - self.inform.emit('%s: %s' % (_("Saved to"), str(filename))) - - def handleFindGCode(self): - self.report_usage("handleFindGCode()") - - flags = QtGui.QTextDocument.FindCaseSensitively - text_to_be_found = self.ui.entryFind.get_value() - - r = self.ui.code_editor.find(str(text_to_be_found), flags) - if r is False: - self.ui.code_editor.moveCursor(QtGui.QTextCursor.Start) - - def handleReplaceGCode(self): - self.report_usage("handleReplaceGCode()") - - old = self.ui.entryFind.get_value() - new = self.ui.entryReplace.get_value() - - if self.ui.sel_all_cb.isChecked(): - while True: - cursor = self.ui.code_editor.textCursor() - cursor.beginEditBlock() - flags = QtGui.QTextDocument.FindCaseSensitively - # self.ui.editor is the QPlainTextEdit - r = self.ui.code_editor.find(str(old), flags) - if r: - qc = self.ui.code_editor.textCursor() - if qc.hasSelection(): - qc.insertText(new) - else: - self.ui.code_editor.moveCursor(QtGui.QTextCursor.Start) - break - # Mark end of undo block - cursor.endEditBlock() - else: - cursor = self.ui.code_editor.textCursor() - cursor.beginEditBlock() - qc = self.ui.code_editor.textCursor() - if qc.hasSelection(): - qc.insertText(new) - # Mark end of undo block - cursor.endEditBlock() - - def handleCopyAll(self): - text = self.ui.code_editor.toPlainText() - self.clipboard.setText(text) - self.inform.emit(_("Code Editor content copied to clipboard ...")) - - 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() - - self.script_code = deepcopy(self.ui.code_editor.toPlainText()) - # self.shell._sysShell.exec_command(script_code) - - old_line = '' - for tcl_command_line in self.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('\\', '/') - - if old_line != '': - new_command = old_line + tcl_command_line + '\n' - else: - new_command = tcl_command_line - - # execute the actual Tcl command - try: - self.shell.open_proccessing() # Disables input box. - - result = self.tcl.eval(str(new_command)) - if result != 'None': - self.shell.append_output(result + '\n') - - old_line = '' - except tk.TclError: - old_line = old_line + tcl_command_line + '\n' - except Exception as e: - log.debug("App.handleRunCode() --> %s" % str(e)) - - if old_line != '': - # it means that the script finished with an error - result = self.tcl.eval("set errorInfo") - self.log.error("Exec command Exception: %s" % (result + '\n')) - self.shell.append_error('ERROR: ' + result + '\n') - - self.shell.close_proccessing() - 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() @@ -9138,38 +8953,29 @@ class App(QtCore.QObject): # ############################################################################################################### def init_code_editor(self, name): - # Signals section - # Disconnect the old signals - try: - self.ui.buttonOpen.clicked.disconnect() - except TypeError: - pass - try: - self.ui.buttonSave.clicked.disconnect() - except TypeError: - pass + self.ui.text_editor_tab = TextEditor(app=self) # add the tab if it was closed - self.ui.plot_tab_area.addTab(self.ui.cncjob_tab, '%s' % name) - self.ui.cncjob_tab.setObjectName('cncjob_tab') + self.ui.plot_tab_area.addTab(self.ui.text_editor_tab, '%s' % name) + self.ui.text_editor_tab.setObjectName('text_editor_tab') # delete the absolute and relative position and messages in the infobar self.ui.position_label.setText("") self.ui.rel_position_label.setText("") # first clear previous text in text editor (if any) - self.ui.code_editor.clear() - self.ui.code_editor.setReadOnly(False) + self.ui.text_editor_tab.code_editor.clear() + self.ui.text_editor_tab.code_editor.setReadOnly(False) self.toggle_codeeditor = True - self.ui.code_editor.completer_enable = False - self.ui.buttonRun.hide() + self.ui.text_editor_tab.code_editor.completer_enable = False + self.ui.text_editor_tab.buttonRun.hide() # make sure to keep a reference to the code editor - self.reference_code_editor = self.ui.code_editor + self.reference_code_editor = self.ui.text_editor_tab.code_editor # Switch plot_area to CNCJob tab - self.ui.plot_tab_area.setCurrentWidget(self.ui.cncjob_tab) + self.ui.plot_tab_area.setCurrentWidget(self.ui.text_editor_tab) def on_view_source(self): self.inform.emit('%s' % @@ -9193,9 +8999,30 @@ class App(QtCore.QObject): else: flt = "All Files (*.*)" - self.init_code_editor(name=_("Source Editor")) - self.ui.buttonOpen.clicked.connect(lambda: self.handleOpen(filt=flt)) - self.ui.buttonSave.clicked.connect(lambda: self.handleSaveGCode(filt=flt)) + self.source_editor_tab = TextEditor(app=self) + + # add the tab if it was closed + self.ui.plot_tab_area.addTab(self.source_editor_tab, '%s' % _("Source Editor")) + self.source_editor_tab.setObjectName('source_editor_tab') + + # delete the absolute and relative position and messages in the infobar + self.ui.position_label.setText("") + self.ui.rel_position_label.setText("") + + # first clear previous text in text editor (if any) + self.source_editor_tab.code_editor.clear() + self.source_editor_tab.code_editor.setReadOnly(False) + + self.source_editor_tab.code_editor.completer_enable = False + self.source_editor_tab.buttonRun.hide() + + # Switch plot_area to CNCJob tab + self.ui.plot_tab_area.setCurrentWidget(self.source_editor_tab) + + self.source_editor_tab.buttonOpen.clicked.disconnect() + self.source_editor_tab.buttonOpen.clicked.connect(lambda: self.source_editor_tab.handleOpen(filt=flt)) + self.source_editor_tab.buttonSave.clicked.disconnect() + self.source_editor_tab.buttonSave.clicked.connect(lambda: self.source_editor_tab.handleSaveGCode(filt=flt)) # then append the text from GCode to the text editor if obj.kind == 'cncjob': @@ -9218,22 +9045,22 @@ class App(QtCore.QObject): _("There is no selected object for which to see it's source file code.")) return 'fail' - self.ui.cncjob_frame.hide() + self.source_editor_tab.t_frame.hide() try: for line in file: QtWidgets.QApplication.processEvents() proc_line = str(line).strip('\n') - self.ui.code_editor.append(proc_line) + self.source_editor_tab.code_editor.append(proc_line) except Exception as e: log.debug('App.on_view_source() -->%s' % str(e)) self.inform.emit('[ERROR] %s: %s' % (_('Failed to load the source code for the selected object'), str(e))) return - self.handleTextChanged() - self.ui.cncjob_frame.show() + self.source_editor_tab.handleTextChanged() + self.source_editor_tab.t_frame.show() - self.ui.code_editor.moveCursor(QtGui.QTextCursor.Start) + self.source_editor_tab.code_editor.moveCursor(QtGui.QTextCursor.Start) self.proc_container.view.set_idle() # self.ui.show() @@ -9242,16 +9069,18 @@ class App(QtCore.QObject): if self.toggle_codeeditor is False: self.init_code_editor(name=_("Code Editor")) - self.ui.buttonOpen.clicked.connect(lambda: self.handleOpen()) - self.ui.buttonSave.clicked.connect(lambda: self.handleSaveGCode()) + self.ui.text_editor_tab.buttonOpen.clicked.disconnect() + self.ui.text_editor_tab.buttonOpen.clicked.connect(lambda: self.ui.text_editor_tab.handleOpen()) + self.ui.text_editor_tab.buttonSave.clicked.disconnect() + self.ui.text_editor_tab.buttonSave.clicked.connect(lambda: self.ui.text_editor_tab.handleSaveGCode()) else: for idx in range(self.ui.plot_tab_area.count()): - if self.ui.plot_tab_area.widget(idx).objectName() == "cncjob_tab": + if self.ui.plot_tab_area.widget(idx).objectName() == "text_editor_tab": self.ui.plot_tab_area.closeTab(idx) break self.toggle_codeeditor = False - def on_filenewscript(self, silent=False): + def on_filenewscript(self, silent=False, name=None, text=None): """ Will create a new script file and open it in the Code Editor :param silent: if True will not display status messages @@ -9262,36 +9091,64 @@ class App(QtCore.QObject): _("New TCL script file created in Code Editor.")) flt = "FlatCAM Scripts (*.FlatScript);;All Files (*.*)" - self.init_code_editor(name=_("Script Editor")) - self.ui.code_editor.completer_enable = True - self.ui.code_editor.append(_( - "#\n" - "# CREATE A NEW FLATCAM TCL SCRIPT\n" - "# 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, 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.proc_container.view.set_busy(_("Loading...")) + + self.script_editor_tab = TextEditor(app=self) + + # add the tab if it was closed + self.ui.plot_tab_area.addTab(self.script_editor_tab, '%s' % _("Script Editor")) + self.script_editor_tab.setObjectName('script_editor_tab') + + # delete the absolute and relative position and messages in the infobar + self.ui.position_label.setText("") + self.ui.rel_position_label.setText("") + + # first clear previous text in text editor (if any) + self.script_editor_tab.code_editor.clear() + self.script_editor_tab.code_editor.setReadOnly(False) + + self.script_editor_tab.code_editor.completer_enable = True + self.script_editor_tab.buttonRun.show() + + # Switch plot_area to CNCJob tab + self.ui.plot_tab_area.setCurrentWidget(self.script_editor_tab) + + self.script_editor_tab.buttonOpen.clicked.disconnect() + self.script_editor_tab.buttonOpen.clicked.connect(lambda: self.script_editor_tab.handleOpen(filt=flt)) + self.script_editor_tab.buttonSave.clicked.disconnect() + self.script_editor_tab.buttonSave.clicked.connect(lambda: self.script_editor_tab.handleSaveGCode(filt=flt)) + try: - self.ui.buttonRun.clicked.disconnect(self.handleRunCode) + self.script_editor_tab.buttonRun.clicked.disconnect() except TypeError: pass - self.ui.buttonRun.clicked.connect(self.handleRunCode) + self.script_editor_tab.buttonRun.clicked.connect(self.script_editor_tab.handleRunCode) - self.handleTextChanged() - self.ui.code_editor.show() + self.script_editor_tab.handleTextChanged() - self.new_script_object() + if name is not None: + self.new_script_object(name=name) + script_obj = self.collection.get_by_name(name) + else: + self.new_script_object() + script_obj = self.collection.get_by_name('new_script') + + script_text = script_obj.source_file + + self.script_editor_tab.t_frame.hide() + if text is not None: + try: + for line in text: + self.script_editor_tab.code_editor.append(line) + except TypeError: + self.script_editor_tab.code_editor.append(text) + + else: + self.script_editor_tab.code_editor.append(script_text) + self.script_editor_tab.t_frame.show() + + self.proc_container.view.set_idle() def on_fileopenscript(self, name=None, silent=False): """ @@ -9301,6 +9158,8 @@ class App(QtCore.QObject): :param name: name of a Tcl script file to open :return: """ + script_content = [] + if name: filename = name else: @@ -9318,17 +9177,17 @@ class App(QtCore.QObject): if filename == "": if silent is False: - self.inform.emit('[WARNING_NOTCL] %s' % - _("Open TCL script cancelled.")) + self.inform.emit('[WARNING_NOTCL] %s' % _("Open TCL script cancelled.")) else: - self.on_filenewscript() + self.proc_container.view.set_busy(_("Loading...")) try: with open(filename, "r") as opened_script: try: for line in opened_script: + QtWidgets.QApplication.processEvents() proc_line = str(line).strip('\n') - self.ui.code_editor.append(proc_line) + script_content.append(proc_line) except Exception as e: log.debug('App.on_fileopenscript() -->%s' % str(e)) if silent is False: @@ -9336,17 +9195,17 @@ class App(QtCore.QObject): ('App.on_fileopenscript() -->', str(e))) return - self.ui.code_editor.moveCursor(QtGui.QTextCursor.Start) - - self.handleTextChanged() if silent is False: - self.inform.emit('[success] %s' % - _("TCL script file opened in Code Editor.")) - # self.ui.show() + self.inform.emit('[success] %s' % _("TCL script file opened in Code Editor.")) except Exception as e: log.debug("App.on_fileopenscript() -> %s" % str(e)) + self.proc_container.view.set_idle() + + script_name = filename.split('/')[-1].split('\\')[-1] + self.on_filenewscript(name=script_name, text=script_content) + def on_filerunscript(self, name=None, silent=False): """ File menu callback for loading and running a TCL script. @@ -10558,12 +10417,12 @@ class App(QtCore.QObject): alignment=Qt.AlignBottom | Qt.AlignLeft, color=QtGui.QColor("gray")) # add the tab if it was closed - self.ui.plot_tab_area.addTab(self.ui.cncjob_tab, _("Code Editor")) + self.ui.plot_tab_area.addTab(self.ui.text_editor_tab, _("Code Editor")) # first clear previous text in text editor (if any) - self.ui.code_editor.clear() + self.ui.text_editor_tab.code_editor.clear() # Switch plot_area to CNCJob tab - self.ui.plot_tab_area.setCurrentWidget(self.ui.cncjob_tab) + self.ui.plot_tab_area.setCurrentWidget(self.ui.text_editor_tab) try: if filename: @@ -10571,7 +10430,7 @@ class App(QtCore.QObject): if f.open(QtCore.QIODevice.ReadOnly): stream = QtCore.QTextStream(f) gcode_edited = stream.readAll() - self.ui.code_editor.setPlainText(gcode_edited) + self.ui.text_editor_tab.code_editor.setPlainText(gcode_edited) f.close() except IOError: App.log.error("Failed to open config file: %s" % filename) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index dd81be80..b54d019b 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -10,6 +10,8 @@ import copy import inspect # TODO: For debugging only. from datetime import datetime +from flatcamEditors.FlatCAMTextEditor import TextEditor + from flatcamGUI.ObjectUI import * from FlatCAMCommon import LoudDict from flatcamGUI.PlotCanvasLegacy import ShapeCollectionLegacy @@ -5992,6 +5994,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): (_("Machine Code file saved to"), filename)) def on_edit_code_click(self, *args): + self.app.proc_container.view.set_busy(_("Loading...")) preamble = str(self.ui.prepend_text.get_value()) postamble = str(self.ui.append_text.get_value()) @@ -6002,25 +6005,46 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): else: self.app.gcode_edited = gco - self.app.init_code_editor(name=_("Code Editor")) - self.app.ui.buttonOpen.clicked.connect(self.app.handleOpen) - self.app.ui.buttonSave.clicked.connect(self.app.handleSaveGCode) + self.gcode_editor_tab = TextEditor(app=self.app) + # add the tab if it was closed + self.app.ui.plot_tab_area.addTab(self.gcode_editor_tab, '%s' % _("Code Editor")) + self.gcode_editor_tab.setObjectName('code_editor_tab') + + # delete the absolute and relative position and messages in the infobar + self.app.ui.position_label.setText("") + self.app.ui.rel_position_label.setText("") + + # first clear previous text in text editor (if any) + self.gcode_editor_tab.code_editor.clear() + self.gcode_editor_tab.code_editor.setReadOnly(False) + + self.gcode_editor_tab.code_editor.completer_enable = False + self.gcode_editor_tab.buttonRun.hide() + + # Switch plot_area to CNCJob tab + self.app.ui.plot_tab_area.setCurrentWidget(self.gcode_editor_tab) + + self.gcode_editor_tab.t_frame.hide() # then append the text from GCode to the text editor try: for line in self.app.gcode_edited: + QtWidgets.QApplication.processEvents() + proc_line = str(line).strip('\n') - self.app.ui.code_editor.append(proc_line) + self.gcode_editor_tab.code_editor.append(proc_line) except Exception as e: log.debug('FlatCAMCNNJob.on_edit_code_click() -->%s' % str(e)) self.app.inform.emit('[ERROR] %s %s' % ('FlatCAMCNNJob.on_edit_code_click() -->', str(e))) return - self.app.ui.code_editor.moveCursor(QtGui.QTextCursor.Start) + self.gcode_editor_tab.code_editor.moveCursor(QtGui.QTextCursor.Start) + + self.gcode_editor_tab.handleTextChanged() + self.gcode_editor_tab.t_frame.show() + self.app.proc_container.view.set_idle() - self.app.handleTextChanged() - self.app.ui.show() self.app.inform.emit('[success] %s...' % _('Loaded Machine Code into Code Editor')) diff --git a/README.md b/README.md index a8a7431a..56bf1810 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,12 @@ CAD program, and create G-Code for Isolation routing. ================================================= +2.10.2019 + +- fixed bug in Geometry Editor that did not allow the copy of geometric elements +- created a new class that holds all the Code Editor functionality and integrated as a Editor in FlatCAM, the location is in flatcamEditors folder +- remade all the functions for view_source, scripts and view_code to use the new TextEditor class; now all the Code Editor tabs are being kept alive, before only one could be in an open state + 1.10.2019 - fixed the FCSpinner and FCDoubleSpinner GUI elements to select all on first click and deselect on second click in the Spinbox LineEdit diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py index 29fa105e..58373185 100644 --- a/flatcamEditors/FlatCAMGeoEditor.py +++ b/flatcamEditors/FlatCAMGeoEditor.py @@ -4081,7 +4081,12 @@ class FlatCAMGeoEditor(QtCore.QObject): def on_shape_complete(self): self.app.log.debug("on_shape_complete()") - geom = self.active_tool.geometry.geo + geom = [] + try: + for shape in self.active_tool.geometry: + geom.append(shape.geo) + except TypeError: + geom = self.active_tool.geometry.geo if self.app.defaults['geometry_editor_milling_type'] == 'cl': # reverse the geometry coordinates direction to allow creation of Gcode for climb milling @@ -4110,8 +4115,15 @@ class FlatCAMGeoEditor(QtCore.QObject): log.debug("FlatCAMGeoEditor.on_shape_complete() Error --> %s" % str(e)) return 'fail' + shape_list = list() + try: + for geo in geom: + shape_list.append(DrawToolShape(geo)) + except TypeError: + shape_list.append(DrawToolShape(geom)) + # Add shape - self.add_shape(DrawToolShape(geom)) + self.add_shape(shape_list) # Remove any utility shapes self.delete_utility_geometry() diff --git a/flatcamEditors/FlatCAMTextEditor.py b/flatcamEditors/FlatCAMTextEditor.py new file mode 100644 index 00000000..0829c8fa --- /dev/null +++ b/flatcamEditors/FlatCAMTextEditor.py @@ -0,0 +1,347 @@ +from flatcamGUI.GUIElements import * +from PyQt5 import QtPrintSupport + +import tkinter as tk +from copy import deepcopy + +import sys + +import gettext +import FlatCAMTranslation as fcTranslate +import builtins + +fcTranslate.apply_language('strings') +if '_' not in builtins.__dict__: + _ = gettext.gettext + + +class TextEditor(QtWidgets.QWidget): + + def __init__(self, app, text=None): + super().__init__() + + self.app = app + self.setSizePolicy( + QtWidgets.QSizePolicy.MinimumExpanding, + QtWidgets.QSizePolicy.MinimumExpanding + ) + + self.main_editor_layout = QtWidgets.QVBoxLayout(self) + self.main_editor_layout.setContentsMargins(0, 0, 0, 0) + + self.t_frame = QtWidgets.QFrame() + self.t_frame.setContentsMargins(0, 0, 0, 0) + self.main_editor_layout.addWidget(self.t_frame) + + self.work_editor_layout = QtWidgets.QGridLayout(self.t_frame) + self.work_editor_layout.setContentsMargins(2, 2, 2, 2) + self.t_frame.setLayout(self.work_editor_layout) + + self.code_editor = FCTextAreaExtended() + stylesheet = """ + QTextEdit { selection-background-color:yellow; + selection-color:black; + } + """ + + self.code_editor.setStyleSheet(stylesheet) + + if text: + self.code_editor.setPlainText(text) + + self.buttonPreview = QtWidgets.QPushButton(_('Print Preview')) + self.buttonPreview.setToolTip(_("Open a OS standard Preview Print window.")) + self.buttonPreview.setMinimumWidth(100) + + 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.entryFind = FCEntry() + self.entryFind.setToolTip(_("Find box. Enter here the strings to be searched in the text.")) + + 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.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.button_copy_all = QtWidgets.QPushButton(_('Copy All')) + self.button_copy_all.setToolTip(_("Will copy all the text in the Code Editor to the clipboard.")) + self.button_copy_all.setMinimumWidth(100) + + self.buttonOpen = QtWidgets.QPushButton(_('Open 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.work_editor_layout.addWidget(self.code_editor, 0, 0, 1, 5) + + editor_hlay_1 = QtWidgets.QHBoxLayout() + # cnc_tab_lay_1.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) + editor_hlay_1.addWidget(self.buttonFind) + editor_hlay_1.addWidget(self.entryFind) + editor_hlay_1.addWidget(self.buttonReplace) + editor_hlay_1.addWidget(self.entryReplace) + editor_hlay_1.addWidget(self.sel_all_cb) + editor_hlay_1.addWidget(self.button_copy_all) + self.work_editor_layout.addLayout(editor_hlay_1, 1, 0, 1, 5) + + editor_hlay_2 = QtWidgets.QHBoxLayout() + editor_hlay_2.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) + editor_hlay_2.addWidget(self.buttonPreview) + editor_hlay_2.addWidget(self.buttonPrint) + self.work_editor_layout.addLayout(editor_hlay_2, 2, 0, 1, 1, QtCore.Qt.AlignLeft) + + cnc_tab_lay_4 = QtWidgets.QHBoxLayout() + 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.work_editor_layout.addLayout(cnc_tab_lay_4, 2, 4, 1, 1) + + # ################################################################################# + # ################### SIGNALS ##################################################### + # ################################################################################# + + self.code_editor.textChanged.connect(self.handleTextChanged) + self.buttonOpen.clicked.connect(self.handleOpen) + self.buttonSave.clicked.connect(self.handleSaveGCode) + self.buttonPrint.clicked.connect(self.handlePrint) + self.buttonPreview.clicked.connect(self.handlePreview) + self.buttonFind.clicked.connect(self.handleFindGCode) + self.buttonReplace.clicked.connect(self.handleReplaceGCode) + self.button_copy_all.clicked.connect(self.handleCopyAll) + + self.code_editor.set_model_data(self.app.myKeywords) + + self.gcode_edited = '' + self.script_code = '' + + def handlePrint(self): + self.app.report_usage("handlePrint()") + + dialog = QtPrintSupport.QPrintDialog() + if dialog.exec_() == QtWidgets.QDialog.Accepted: + self.code_editor.document().print_(dialog.printer()) + + def handlePreview(self): + self.app.report_usage("handlePreview()") + + dialog = QtPrintSupport.QPrintPreviewDialog() + dialog.paintRequested.connect(self.code_editor.print_) + dialog.exec_() + + def handleTextChanged(self): + # enable = not self.ui.code_editor.document().isEmpty() + # self.ui.buttonPrint.setEnabled(enable) + # self.ui.buttonPreview.setEnabled(enable) + pass + + def handleOpen(self, filt=None): + self.app.report_usage("handleOpen()") + + if filt: + _filter_ = filt + else: + _filter_ = "G-Code Files (*.nc);; G-Code Files (*.txt);; G-Code Files (*.tap);; G-Code Files (*.cnc);; " \ + "All Files (*.*)" + + path, _f = QtWidgets.QFileDialog.getOpenFileName( + caption=_('Open file'), directory=self.app.get_last_folder(), filter=_filter_) + + if path: + file = QtCore.QFile(path) + if file.open(QtCore.QIODevice.ReadOnly): + stream = QtCore.QTextStream(file) + self.gcode_edited = stream.readAll() + self.code_editor.setPlainText(self.gcode_edited) + file.close() + + def handleSaveGCode(self, name=None, filt=None): + self.app.report_usage("handleSaveGCode()") + + if filt: + _filter_ = filt + else: + _filter_ = "G-Code Files (*.nc);; G-Code Files (*.txt);; G-Code Files (*.tap);; G-Code Files (*.cnc);; " \ + "All Files (*.*)" + + if name: + obj_name = name + else: + try: + obj_name = self.app.collection.get_active().options['name'] + except AttributeError: + obj_name = 'file' + if filt is None: + _filter_ = "FlatConfig Files (*.FlatConfig);;All Files (*.*)" + + try: + filename = str(QtWidgets.QFileDialog.getSaveFileName( + caption=_("Export G-Code ..."), + directory=self.app.defaults["global_last_folder"] + '/' + str(obj_name), + filter=_filter_ + )[0]) + except TypeError: + filename = str(QtWidgets.QFileDialog.getSaveFileName(caption=_("Export G-Code ..."), filter=_filter_)[0]) + + if filename == "": + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Export Code cancelled.")) + return + else: + try: + my_gcode = self.code_editor.toPlainText() + with open(filename, 'w') as f: + for line in my_gcode: + f.write(line) + except FileNotFoundError: + self.app.inform.emit('[WARNING] %s' % _("No such file or directory")) + return + except PermissionError: + self.app.inform.emit('[WARNING] %s' % + _("Permission denied, saving not possible.\n" + "Most likely another app is holding the file open and not accessible.")) + return + + # Just for adding it to the recent files list. + if self.app.defaults["global_open_style"] is False: + self.app.file_opened.emit("cncjob", filename) + self.app.file_saved.emit("cncjob", filename) + self.app.inform.emit('%s: %s' % (_("Saved to"), str(filename))) + + def handleFindGCode(self): + self.app.report_usage("handleFindGCode()") + + flags = QtGui.QTextDocument.FindCaseSensitively + text_to_be_found = self.entryFind.get_value() + + r = self.code_editor.find(str(text_to_be_found), flags) + if r is False: + self.code_editor.moveCursor(QtGui.QTextCursor.Start) + + def handleReplaceGCode(self): + self.app.report_usage("handleReplaceGCode()") + + old = self.entryFind.get_value() + new = self.entryReplace.get_value() + + if self.sel_all_cb.isChecked(): + while True: + cursor = self.code_editor.textCursor() + cursor.beginEditBlock() + flags = QtGui.QTextDocument.FindCaseSensitively + # self.ui.editor is the QPlainTextEdit + r = self.code_editor.find(str(old), flags) + if r: + qc = self.code_editor.textCursor() + if qc.hasSelection(): + qc.insertText(new) + else: + self.ui.code_editor.moveCursor(QtGui.QTextCursor.Start) + break + # Mark end of undo block + cursor.endEditBlock() + else: + cursor = self.code_editor.textCursor() + cursor.beginEditBlock() + qc = self.code_editor.textCursor() + if qc.hasSelection(): + qc.insertText(new) + # Mark end of undo block + cursor.endEditBlock() + + def handleCopyAll(self): + text = self.code_editor.toPlainText() + self.app.clipboard.setText(text) + self.app.inform.emit(_("Code Editor content copied to clipboard ...")) + + 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.app.ui.shell_dock.isHidden(): + self.app.ui.shell_dock.show() + + self.script_code = deepcopy(self.code_editor.toPlainText()) + + old_line = '' + for tcl_command_line in self.app.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('\\', '/') + + if old_line != '': + new_command = old_line + tcl_command_line + '\n' + else: + new_command = tcl_command_line + + # execute the actual Tcl command + try: + self.app.shell.open_proccessing() # Disables input box. + + result = self.app.tcl.eval(str(new_command)) + if result != 'None': + self.app.shell.append_output(result + '\n') + + old_line = '' + except tk.TclError: + old_line = old_line + tcl_command_line + '\n' + except Exception as e: + log.debug("App.handleRunCode() --> %s" % str(e)) + + if old_line != '': + # it means that the script finished with an error + result = self.app.tcl.eval("set errorInfo") + log.error("Exec command Exception: %s" % (result + '\n')) + self.app.shell.append_error('ERROR: ' + result + '\n') + + self.app.shell.close_proccessing() + + def closeEvent(self, QCloseEvent): + try: + self.code_editor.textChanged.disconnect() + except TypeError: + pass + try: + self.buttonOpen.clicked.disconnect() + except TypeError: + pass + try: + self.buttonPrint.clicked.disconnect() + except TypeError: + pass + try: + self.buttonPreview.clicked.disconnect() + except TypeError: + pass + try: + self.buttonFind.clicked.disconnect() + except TypeError: + pass + try: + self.buttonReplace.clicked.disconnect() + except TypeError: + pass + try: + self.button_copy_all.clicked.disconnect() + except TypeError: + pass + + super().closeEvent(QCloseEvent) diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index ab2be44a..318e945f 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -934,12 +934,12 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.geometry_scroll_area = QtWidgets.QScrollArea() self.geometry_tab_lay.addWidget(self.geometry_scroll_area) - self.cncjob_tab = QtWidgets.QWidget() - self.cncjob_tab.setObjectName("cncjob_tab") - self.pref_tab_area.addTab(self.cncjob_tab, _("CNC-JOB")) + self.text_editor_tab = QtWidgets.QWidget() + self.text_editor_tab.setObjectName("text_editor_tab") + self.pref_tab_area.addTab(self.text_editor_tab, _("CNC-JOB")) self.cncjob_tab_lay = QtWidgets.QVBoxLayout() self.cncjob_tab_lay.setContentsMargins(2, 2, 2, 2) - self.cncjob_tab.setLayout(self.cncjob_tab_lay) + self.text_editor_tab.setLayout(self.cncjob_tab_lay) self.cncjob_scroll_area = QtWidgets.QScrollArea() self.cncjob_tab_lay.addWidget(self.cncjob_scroll_area) @@ -1843,94 +1843,94 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # self.cncjob_tab_layout.setContentsMargins(2, 2, 2, 2) # self.cncjob_tab.setLayout(self.cncjob_tab_layout) - self.cncjob_tab = QtWidgets.QWidget() - - self.c_temp_layout = QtWidgets.QVBoxLayout(self.cncjob_tab) - self.c_temp_layout.setContentsMargins(0, 0, 0, 0) - - self.cncjob_frame = QtWidgets.QFrame() - self.cncjob_frame.setContentsMargins(0, 0, 0, 0) - self.c_temp_layout.addWidget(self.cncjob_frame) - - self.cncjob_tab_layout = QtWidgets.QGridLayout(self.cncjob_frame) - self.cncjob_tab_layout.setContentsMargins(2, 2, 2, 2) - self.cncjob_frame.setLayout(self.cncjob_tab_layout) - - self.code_editor = FCTextAreaExtended() - stylesheet = """ - QTextEdit { selection-background-color:yellow; - selection-color:black; - } - """ - - 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.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.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.button_copy_all = QtWidgets.QPushButton(_('Copy All')) - self.button_copy_all.setToolTip(_("Will copy all the text in the Code Editor to the clipboard.")) - - self.button_copy_all.setMinimumWidth(100) - - self.buttonOpen = QtWidgets.QPushButton(_('Open 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() - # cnc_tab_lay_1.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) - cnc_tab_lay_1.addWidget(self.buttonFind) - cnc_tab_lay_1.addWidget(self.entryFind) - cnc_tab_lay_1.addWidget(self.buttonReplace) - cnc_tab_lay_1.addWidget(self.entryReplace) - cnc_tab_lay_1.addWidget(self.sel_all_cb) - cnc_tab_lay_1.addWidget(self.button_copy_all) - self.cncjob_tab_layout.addLayout(cnc_tab_lay_1, 1, 0, 1, 5) - - cnc_tab_lay_3 = QtWidgets.QHBoxLayout() - cnc_tab_lay_3.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) - cnc_tab_lay_3.addWidget(self.buttonPreview) - cnc_tab_lay_3.addWidget(self.buttonPrint) - self.cncjob_tab_layout.addLayout(cnc_tab_lay_3, 2, 0, 1, 1, QtCore.Qt.AlignLeft) - - cnc_tab_lay_4 = QtWidgets.QHBoxLayout() - 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) + # self.cncjob_tab = QtWidgets.QWidget() + # + # self.c_temp_layout = QtWidgets.QVBoxLayout(self.cncjob_tab) + # self.c_temp_layout.setContentsMargins(0, 0, 0, 0) + # + # self.cncjob_frame = QtWidgets.QFrame() + # self.cncjob_frame.setContentsMargins(0, 0, 0, 0) + # self.c_temp_layout.addWidget(self.cncjob_frame) + # + # self.cncjob_tab_layout = QtWidgets.QGridLayout(self.cncjob_frame) + # self.cncjob_tab_layout.setContentsMargins(2, 2, 2, 2) + # self.cncjob_frame.setLayout(self.cncjob_tab_layout) + # + # self.code_editor = FCTextAreaExtended() + # stylesheet = """ + # QTextEdit { selection-background-color:yellow; + # selection-color:black; + # } + # """ + # + # 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.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.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.button_copy_all = QtWidgets.QPushButton(_('Copy All')) + # self.button_copy_all.setToolTip(_("Will copy all the text in the Code Editor to the clipboard.")) + # + # self.button_copy_all.setMinimumWidth(100) + # + # self.buttonOpen = QtWidgets.QPushButton(_('Open 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() + # # cnc_tab_lay_1.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) + # cnc_tab_lay_1.addWidget(self.buttonFind) + # cnc_tab_lay_1.addWidget(self.entryFind) + # cnc_tab_lay_1.addWidget(self.buttonReplace) + # cnc_tab_lay_1.addWidget(self.entryReplace) + # cnc_tab_lay_1.addWidget(self.sel_all_cb) + # cnc_tab_lay_1.addWidget(self.button_copy_all) + # self.cncjob_tab_layout.addLayout(cnc_tab_lay_1, 1, 0, 1, 5) + # + # cnc_tab_lay_3 = QtWidgets.QHBoxLayout() + # cnc_tab_lay_3.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) + # cnc_tab_lay_3.addWidget(self.buttonPreview) + # cnc_tab_lay_3.addWidget(self.buttonPrint) + # self.cncjob_tab_layout.addLayout(cnc_tab_lay_3, 2, 0, 1, 1, QtCore.Qt.AlignLeft) + # + # cnc_tab_lay_4 = QtWidgets.QHBoxLayout() + # 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) # ################################# # ## Build InfoBar is done here ### diff --git a/flatcamTools/ToolSolderPaste.py b/flatcamTools/ToolSolderPaste.py index 6e6cbbf7..a9853cd9 100644 --- a/flatcamTools/ToolSolderPaste.py +++ b/flatcamTools/ToolSolderPaste.py @@ -1306,13 +1306,13 @@ class SolderPaste(FlatCAMTool): time_str = "{:%A, %d %B %Y at %H:%M}".format(datetime.now()) # add the tab if it was closed - self.app.ui.plot_tab_area.addTab(self.app.ui.cncjob_tab, _("Code Editor")) + self.app.ui.plot_tab_area.addTab(self.app.ui.text_editor_tab, _("Code Editor")) # first clear previous text in text editor (if any) self.app.ui.code_editor.clear() # Switch plot_area to CNCJob tab - self.app.ui.plot_tab_area.setCurrentWidget(self.app.ui.cncjob_tab) + self.app.ui.plot_tab_area.setCurrentWidget(self.app.ui.text_editor_tab) name = self.cnc_obj_combo.currentText() obj = self.app.collection.get_by_name(name)