diff --git a/FlatCAMApp.py b/FlatCAMApp.py index d4887e14..a6875fca 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -4139,23 +4139,24 @@ class App(QtCore.QObject): if text is not None: new_source_file = text else: - new_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" - ) + commands_list = "# AddCircle, AddPolygon, AddPolyline, AddRectangle, AlignDrill, " \ + "AlignDrillGrid, Bbox, Bounds, ClearShell, CopperClear,\n"\ + "# Cncjob, Cutout, Delete, Drillcncjob, ExportGcode, ExportSVG, Exteriors, " \ + "Follow, GeoCutout, GeoUnion, GetNames,\n"\ + "# GetSys, ImportSvg, Interiors, Isolate, JoinExcellon, JoinGeometry, " \ + "ListSys, MillDrills,\n"\ + "# MillSlots, Mirror, New, NewExcellon, NewGeometry, NewGerber, Nregions, " \ + "Offset, OpenExcellon, OpenGCode, OpenGerber, OpenProject,\n"\ + "# Options, Paint, Panelize, PlotAl, PlotObjects, SaveProject, " \ + "SaveSys, Scale, SetActive, SetSys, SetOrigin, Skew, SubtractPoly,\n" \ + "# SubtractRectangle, Version, WriteGCode\n" + + new_source_file = '# %s\n' % _('CREATE A NEW FLATCAM TCL SCRIPT') + \ + '# %s:\n' % _('TCL Tutorial is here') + \ + '# https://www.tcl.tk/man/tcl8.5/tutorial/tcltutorial.html\n' + '\n\n' + \ + '# %s:\n' % _("FlatCAM commands list") + new_source_file += commands_list + '\n' + def initialize(obj, app): obj.source_file = deepcopy(new_source_file) @@ -8113,7 +8114,11 @@ class App(QtCore.QObject): act.setChecked(False) except Exception: pass - self.inform.emit('%s' % _("Objects selection is cleared.")) + + if obj_list: + self.inform.emit('%s' % _("Objects selection is cleared.")) + else: + self.inform.emit('') def grid_status(self): if self.ui.grid_snap_btn.isChecked(): @@ -8442,43 +8447,50 @@ class App(QtCore.QObject): # if the released mouse button was LMB then test if we had a right-to-left selection or a left-to-right # selection and then select a type of selection ("enclosing" or "touching") - try: - if event.button == 1: # left click - modifiers = QtWidgets.QApplication.keyboardModifiers() - # If the SHIFT key is pressed when LMB is clicked then the coordinates are copied to clipboard - if modifiers == QtCore.Qt.ShiftModifier: - # do not auto open the Project Tab - self.click_noproject = True - self.clipboard.setText(self.defaults["global_point_clipboard_format"] % (self.pos[0], self.pos[1])) - self.inform.emit('[success] %s' % - _("Coordinates copied to clipboard.")) - return + if event.button == 1: # left click + modifiers = QtWidgets.QApplication.keyboardModifiers() + # If the SHIFT key is pressed when LMB is clicked then the coordinates are copied to clipboard + if modifiers == QtCore.Qt.ShiftModifier: + # do not auto open the Project Tab + self.click_noproject = True - if self.doubleclick is True: - self.doubleclick = False - if self.collection.get_selected(): - self.ui.notebook.setCurrentWidget(self.ui.selected_tab) - if self.ui.splitter.sizes()[0] == 0: - self.ui.splitter.setSizes([1, 1]) + self.clipboard.setText(self.defaults["global_point_clipboard_format"] % (self.pos[0], self.pos[1])) + self.inform.emit('[success] %s' % _("Coordinates copied to clipboard.")) + return + if self.doubleclick is True: + self.doubleclick = False + if self.collection.get_selected(): + self.ui.notebook.setCurrentWidget(self.ui.selected_tab) + if self.ui.splitter.sizes()[0] == 0: + self.ui.splitter.setSizes([1, 1]) + try: # delete the selection shape(S) as it may be in the way self.delete_selection_shape() self.delete_hover_shape() - else: - if self.selection_type is not None: + except Exception as e: + log.warning("FlatCAMApp.on_mouse_click_release_over_plot() double click --> Error: %s" % str(e)) + return + else: + if self.selection_type is not None: + try: self.selection_area_handler(self.pos, pos, self.selection_type) self.selection_type = None + except Exception as e: + log.warning("FlatCAMApp.on_mouse_click_release_over_plot() select area --> Error: %s" % str(e)) + return + else: + key_modifier = QtWidgets.QApplication.keyboardModifiers() + + if key_modifier == QtCore.Qt.ShiftModifier: + mod_key = 'Shift' + elif key_modifier == QtCore.Qt.ControlModifier: + mod_key = 'Control' else: - key_modifier = QtWidgets.QApplication.keyboardModifiers() - - if key_modifier == QtCore.Qt.ShiftModifier: - mod_key = 'Shift' - elif key_modifier == QtCore.Qt.ControlModifier: - mod_key = 'Control' - else: - mod_key = None + mod_key = None + try: if mod_key == self.defaults["global_mselect_key"]: # If the CTRL key is pressed when the LMB is clicked then if the object is selected it will # deselect, and if it's not selected then it will be selected @@ -8493,10 +8505,9 @@ class App(QtCore.QObject): if self.command_active is None: self.select_objects() self.delete_hover_shape() - - except Exception as e: - log.warning("Error: %s" % str(e)) - return + except Exception as e: + log.warning("FlatCAMApp.on_mouse_click_release_over_plot() select click --> Error: %s" % str(e)) + return def selection_area_handler(self, start_pos, end_pos, sel_type): """ @@ -8554,6 +8565,10 @@ class App(QtCore.QObject): curr_x, curr_y = self.pos for obj in self.all_objects_list: + # FlatCAMScript and FlatCAMDocument objects can't be selected + if isinstance(obj, FlatCAMScript) or isinstance(obj, FlatCAMDocument): + continue + if (curr_x >= obj.options['xmin']) and (curr_x <= obj.options['xmax']) and \ (curr_y >= obj.options['ymin']) and (curr_y <= obj.options['ymax']): if obj.options['name'] not in objects_under_the_click_list: @@ -11245,7 +11260,7 @@ class App(QtCore.QObject): self.log.debug(" " + param + " OK") except KeyError: if silent is False: - self.log.debug(" ERROR: " + param + " not in defaults.") + self.log.debug("FlatCAMApp.propagate_defaults() --> ERROR: " + param + " not in defaults.") else: # Try extracting the name: # classname_param here is param in the object diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 7e6ad524..23f2b4df 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -6179,8 +6179,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): self.gcode_editor_tab.t_frame.show() self.app.proc_container.view.set_idle() - self.app.inform.emit('[success] %s...' % - _('Loaded Machine Code into Code Editor')) + self.app.inform.emit('[success] %s...' % _('Loaded Machine Code into Code Editor')) def gcode_header(self, comment_start_symbol=None, comment_stop_symbol=None): """ @@ -6650,7 +6649,8 @@ class FlatCAMScript(FlatCAMObj): self.source_file = '' self.script_code = '' - self.script_editor_tab = None + # self.script_editor_tab = TextEditor(app=self.app, plain_text=True) + self.script_editor_tab = TextEditor(app=self.app) def set_ui(self, ui): FlatCAMObj.set_ui(self, ui) @@ -6659,12 +6659,8 @@ class FlatCAMScript(FlatCAMObj): assert isinstance(self.ui, ScriptObjectUI), \ "Expected a ScriptObjectUI, got %s" % type(self.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 + self.units = self.app.defaults['units'].upper() + self.decimals = 4 if self.units == "IN" else 2 # Fill form fields only on object create self.to_form() @@ -6679,17 +6675,33 @@ class FlatCAMScript(FlatCAMObj): 'Advanced' )) - self.script_editor_tab = TextEditor(app=self.app) + # tab_here = False + # # try to not add too many times a tab that it is already installed + # for idx in range(self.app.ui.plot_tab_area.count()): + # if self.app.ui.plot_tab_area.widget(idx).objectName() == self.options['name']: + # tab_here = True + # break + # + # # add the tab if it is not already added + # if tab_here is False: + # self.app.ui.plot_tab_area.addTab(self.script_editor_tab, '%s' % _("Script Editor")) + # self.script_editor_tab.setObjectName(self.options['name']) + + self.app.ui.plot_tab_area.addTab(self.script_editor_tab, '%s' % _("Script Editor")) + self.script_editor_tab.setObjectName(self.options['name']) # 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.buttonRun.show() + # self.script_editor_tab.code_editor.clear() + # self.script_editor_tab.code_editor.setReadOnly(False) self.ui.autocomplete_cb.set_value(self.app.defaults['script_autocompleter']) self.on_autocomplete_changed(state=self.app.defaults['script_autocompleter']) + self.script_editor_tab.buttonRun.show() + + # Switch plot_area to CNCJob tab + self.app.ui.plot_tab_area.setCurrentWidget(self.script_editor_tab) + flt = "FlatCAM Scripts (*.FlatScript);;All Files (*.*)" self.script_editor_tab.buttonOpen.clicked.disconnect() self.script_editor_tab.buttonOpen.clicked.connect(lambda: self.script_editor_tab.handleOpen(filt=flt)) @@ -6697,35 +6709,34 @@ class FlatCAMScript(FlatCAMObj): self.script_editor_tab.buttonSave.clicked.connect(lambda: self.script_editor_tab.handleSaveGCode(filt=flt)) self.script_editor_tab.buttonRun.clicked.connect(self.handle_run_code) - self.script_editor_tab.handleTextChanged() self.ui.autocomplete_cb.stateChanged.connect(self.on_autocomplete_changed) self.ser_attrs = ['options', 'kind', 'source_file'] - for line in self.source_file.splitlines(): - self.script_editor_tab.code_editor.append(line) + # ---------------------------------------------------- # + # ----------- LOAD THE TEXT SOURCE FILE -------------- # + # ---------------------------------------------------- # + self.app.proc_container.view.set_busy(_("Loading...")) + self.script_editor_tab.t_frame.hide() + try: + # self.script_editor_tab.code_editor.setPlainText(self.source_file) + for line in self.source_file.splitlines(): + QtWidgets.QApplication.processEvents() + self.script_editor_tab.code_editor.append(line) + except Exception as e: + log.debug("FlatCAMScript.set_ui() --> %s" % str(e)) + + self.script_editor_tab.code_editor.moveCursor(QtGui.QTextCursor.End) + self.script_editor_tab.t_frame.show() + + self.app.proc_container.view.set_idle() self.build_ui() def build_ui(self): FlatCAMObj.build_ui(self) - tab_here = False - - # try to not add too many times a tab that it is already installed - for idx in range(self.app.ui.plot_tab_area.count()): - if self.app.ui.plot_tab_area.widget(idx).objectName() == self.options['name']: - tab_here = True - break - - # add the tab if it is not already added - if tab_here is False: - self.app.ui.plot_tab_area.addTab(self.script_editor_tab, '%s' % _("Script Editor")) - self.script_editor_tab.setObjectName(self.options['name']) - - # Switch plot_area to CNCJob tab - self.app.ui.plot_tab_area.setCurrentWidget(self.script_editor_tab) def handle_run_code(self): # trying to run a Tcl command without having the Shell open will create some warnings because the Tcl Shell @@ -6762,7 +6773,7 @@ class FlatCAMScript(FlatCAMObj): except tk.TclError: old_line = old_line + tcl_command_line + '\n' except Exception as e: - log.debug("App.handleRunCode() --> %s" % str(e)) + log.debug("FlatCAMScript.handleRunCode() --> %s" % str(e)) if old_line != '': # it means that the script finished with an error diff --git a/README.md b/README.md index 2414ee74..683b4428 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ CAD program, and create G-Code for Isolation routing. - Tool Fiducials - added GUI in Preferences and entries in self.defaults dict - Tool Fiducials - updated the source_file object for the modified Gerber files - working on adding line numbers to the TextPlainEdit +- GCode view now has line numbers +- solved a bug that made selection of objects on canvas impossible if there is an object of type FlatCAMScript or FlatCAMDocument opened 21.11.2019 diff --git a/flatcamEditors/FlatCAMExcEditor.py b/flatcamEditors/FlatCAMExcEditor.py index 99a76115..57625ec8 100644 --- a/flatcamEditors/FlatCAMExcEditor.py +++ b/flatcamEditors/FlatCAMExcEditor.py @@ -3530,7 +3530,7 @@ class FlatCAMExcEditor(QtCore.QObject): self.app.ui.popMenu.popup(self.app.cursor.pos()) except Exception as e: - log.warning("Error: %s" % str(e)) + log.warning("FlatCAMExcEditor.on_exc_click_release() RMB click --> Error: %s" % str(e)) raise # if the released mouse button was LMB then test if we had a right-to-left selection or a left-to-right @@ -3548,7 +3548,7 @@ class FlatCAMExcEditor(QtCore.QObject): if self.selected: self.replot() except Exception as e: - log.warning("Error: %s" % str(e)) + log.warning("FlatCAMExcEditor.on_exc_click_release() LMB click --> Error: %s" % str(e)) raise def draw_selection_area_handler(self, start, end, sel_type): diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py index 7706a275..4a69ec95 100644 --- a/flatcamEditors/FlatCAMGeoEditor.py +++ b/flatcamEditors/FlatCAMGeoEditor.py @@ -3911,7 +3911,7 @@ class FlatCAMGeoEditor(QtCore.QObject): _("Done.")) self.select_tool(self.active_tool.name) except Exception as e: - log.warning("Error: %s" % str(e)) + log.warning("FLatCAMGeoEditor.on_geo_click_release() --> Error: %s" % str(e)) return def draw_selection_area_handler(self, start_pos, end_pos, sel_type): diff --git a/flatcamEditors/FlatCAMGrbEditor.py b/flatcamEditors/FlatCAMGrbEditor.py index 9a8360c1..d50197bd 100644 --- a/flatcamEditors/FlatCAMGrbEditor.py +++ b/flatcamEditors/FlatCAMGrbEditor.py @@ -4349,7 +4349,7 @@ class FlatCAMGrbEditor(QtCore.QObject): else: self.select_tool("select") except Exception as e: - log.warning("Error: %s" % str(e)) + log.warning("FlatCAMGrbEditor.on_grb_click_release() RMB click --> Error: %s" % str(e)) raise # if the released mouse button was LMB then test if we had a right-to-left selection or a left-to-right @@ -4367,7 +4367,7 @@ class FlatCAMGrbEditor(QtCore.QObject): if self.selected: self.plot_all() except Exception as e: - log.warning("Error: %s" % str(e)) + log.warning("FlatCAMGrbEditor.on_grb_click_release() LMB click --> Error: %s" % str(e)) raise def draw_selection_area_handler(self, start_pos, end_pos, sel_type): diff --git a/flatcamEditors/FlatCAMTextEditor.py b/flatcamEditors/FlatCAMTextEditor.py index 24ddca52..10f96a68 100644 --- a/flatcamEditors/FlatCAMTextEditor.py +++ b/flatcamEditors/FlatCAMTextEditor.py @@ -48,6 +48,7 @@ class TextEditor(QtWidgets.QWidget): selection-color:black; } """ + self.work_editor_layout.addWidget(self.editor_class, 0, 0, 1, 5) else: self.code_editor = FCTextAreaExtended() stylesheet = """ @@ -55,6 +56,7 @@ class TextEditor(QtWidgets.QWidget): selection-color:black; } """ + self.work_editor_layout.addWidget(self.code_editor, 0, 0, 1, 5) self.code_editor.setStyleSheet(stylesheet) @@ -100,7 +102,6 @@ class TextEditor(QtWidgets.QWidget): 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) @@ -140,7 +141,7 @@ class TextEditor(QtWidgets.QWidget): self.code_editor.set_model_data(self.app.myKeywords) - self.gcode_edited = '' + self.code_edited = '' def handlePrint(self): self.app.report_usage("handlePrint()") @@ -178,8 +179,8 @@ class TextEditor(QtWidgets.QWidget): 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) + self.code_edited = stream.readAll() + self.code_editor.setPlainText(self.code_edited) file.close() def handleSaveGCode(self, name=None, filt=None): diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index 89ae9d5c..a40b420d 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -2382,11 +2382,9 @@ class FCTextAreaLineNumber(QtWidgets.QFrame): FCPlainTextAreaExtended.__init__(self, *args) #self.setFrameStyle(QFrame.NoFrame) - self.setFrameStyle(QtWidgets.QFrame.NoFrame) self.highlight() #self.setLineWrapMode(QPlainTextEdit.NoWrap) - self.cursorPositionChanged.connect(self.highlight) def highlight(self): @@ -2405,6 +2403,7 @@ class FCTextAreaLineNumber(QtWidgets.QFrame): block = self.firstVisibleBlock() line_count = block.blockNumber() + painter = QtGui.QPainter(number_bar) painter.fillRect(event.rect(), self.palette().base()) @@ -2421,16 +2420,18 @@ class FCTextAreaLineNumber(QtWidgets.QFrame): # We want the line number for the selected line to be bold. if line_count == current_line: font = painter.font() - font.setBold(True) + # font.setBold(True) + painter.setPen(QtCore.Qt.blue) painter.setFont(font) else: font = painter.font() - font.setBold(False) + # font.setBold(False) + painter.setPen(QtCore.Qt.lightGray) painter.setFont(font) # Draw the line number right justified at the position of the line. paint_rect = QtCore.QRect(0, block_top, number_bar.width(), font_metrics.height()) - painter.drawText(paint_rect, Qt.AlignRight, str(line_count)) + painter.drawText(paint_rect, Qt.AlignRight, ' ' + str(line_count) + ' ') block = block.next()