From 9557e1af60e2248aee3796e987153b074b248d0a Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 21 Feb 2019 03:04:38 +0200 Subject: [PATCH] - added protection against creating CNCJob from an empty Geometry object (with no geometry inside) - changed the shortcut key for YouTube channel from F2 to key F4 - changed the way APP LEVEL is showed both in Edit -> Preferences -> General tab and in each Selected Tab. Changed the ToolTips content for this. - added the functions for GCode View and GCode Save in Tool SolderPaste --- FlatCAMApp.py | 4 +-- FlatCAMGUI.py | 21 +++++------ FlatCAMObj.py | 24 ++++++------- ObjectUI.py | 53 +++++++-------------------- README.md | 4 ++- flatcamTools/ToolSolderPaste.py | 64 ++++++++++++++++++++++++++++----- 6 files changed, 96 insertions(+), 74 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 47116142..d3441e20 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -312,7 +312,7 @@ class App(QtCore.QObject): "global_send_stats": self.general_defaults_form.general_app_group.send_stats_cb, "global_project_at_startup": self.general_defaults_form.general_app_group.project_startup_cb, "global_project_autohide": self.general_defaults_form.general_app_group.project_autohide_cb, - "global_advanced": self.general_defaults_form.general_app_group.advanced_cb, + "global_app_level": self.general_defaults_form.general_app_group.app_level_radio, "global_compression_level": self.general_defaults_form.general_app_group.compress_combo, "global_save_compressed": self.general_defaults_form.general_app_group.save_type_cb, @@ -531,7 +531,7 @@ class App(QtCore.QObject): "global_send_stats": True, "global_project_at_startup": False, "global_project_autohide": True, - "global_advanced": False, + "global_app_level": 'b', "global_gridx": 1.0, "global_gridy": 1.0, diff --git a/FlatCAMGUI.py b/FlatCAMGUI.py index 1e12ab44..85a6b439 100644 --- a/FlatCAMGUI.py +++ b/FlatCAMGUI.py @@ -3009,6 +3009,16 @@ class GeneralAppPrefGroupUI(OptionsGroupUI): self.units_radio = RadioSet([{'label': 'IN', 'value': 'IN'}, {'label': 'MM', 'value': 'MM'}]) + # Application Level for FlatCAM + self.app_level_label = QtWidgets.QLabel('APP. LEVEL:') + self.app_level_label.setToolTip("Choose the default level of usage for FlatCAM.\n" + "BASIC level -> reduced functionality, best for beginner's.\n" + "ADVANCED level -> full functionality.\n\n" + "The choice here will influence the parameters in\n" + "the Selected Tab for all kinds of FlatCAM objects.") + self.app_level_radio = RadioSet([{'label': 'Basic', 'value': 'b'}, + {'label': 'Advanced', 'value': 'a'}]) + # Languages for FlatCAM self.languagelabel = QtWidgets.QLabel('Languages:') self.languagelabel.setToolTip("Set the language used throughout FlatCAM.") @@ -3099,6 +3109,7 @@ class GeneralAppPrefGroupUI(OptionsGroupUI): # Add (label - input field) pair to the QFormLayout self.form_box.addRow(self.unitslabel, self.units_radio) + self.form_box.addRow(self.app_level_label, self.app_level_radio) self.form_box.addRow(self.languagelabel, self.language_cb) self.form_box.addRow(self.languagespace, self.language_apply_btn) @@ -3122,16 +3133,6 @@ class GeneralAppPrefGroupUI(OptionsGroupUI): # self.layout.addLayout(hlay) # hlay.addStretch() - # Advanced CB - self.advanced_cb = FCCheckBox('Show Advanced Options') - self.advanced_cb.setToolTip( - "When checked, Advanced Options will be\n" - "displayed in the Selected Tab for all\n" - "kind of objects." - ) - # self.advanced_cb.setLayoutDirection(QtCore.Qt.RightToLeft) - self.layout.addWidget(self.advanced_cb) - # Save compressed project CB self.save_type_cb = FCCheckBox('Save Compressed Project') self.save_type_cb.setToolTip( diff --git a/FlatCAMObj.py b/FlatCAMObj.py index a8201a95..3f549f91 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -491,8 +491,8 @@ class FlatCAMGerber(FlatCAMObj, Gerber): self.ui.follow_cb.stateChanged.connect(self.on_follow_cb_click) # Show/Hide Advanced Options - if self.app.defaults["global_advanced"] is False: - self.ui.level.setText('BASIC Mode') + if self.app.defaults["global_app_level"] == 'b': + self.ui.level.setText('Basic') self.ui.apertures_table_label.hide() self.ui.aperture_table_visibility_cb.hide() self.ui.milling_type_label.hide() @@ -501,7 +501,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber): self.ui.generate_int_iso_button.hide() else: - self.ui.level.setText('ADVANCED Mode') + self.ui.level.setText('Advanced') self.build_ui() @@ -1571,8 +1571,8 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.tool_offset[dia] = t_default_offset # Show/Hide Advanced Options - if self.app.defaults["global_advanced"] is False: - self.ui.level.setText('BASIC Mode') + if self.app.defaults["global_app_level"] == 'b': + self.ui.level.setText('Basic') self.ui.tools_table.setColumnHidden(4, True) self.ui.estartz_label.hide() @@ -1586,7 +1586,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.ui.feedrate_probe_label.hide() self.ui.feedrate_probe_entry.hide() else: - self.ui.level.setText('ADVANCED Mode') + self.ui.level.setText('Advanced') assert isinstance(self.ui, ExcellonObjectUI), \ "Expected a ExcellonObjectUI, got %s" % type(self.ui) @@ -2805,8 +2805,8 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): "Delete", lambda: self.on_tool_delete(all=None), icon=QtGui.QIcon("share/delete32.png")) # Show/Hide Advanced Options - if self.app.defaults["global_advanced"] is False: - self.ui.level.setText('BASIC Mode') + if self.app.defaults["global_app_level"] == 'b': + self.ui.level.setText('Basic') self.ui.geo_tools_table.setColumnHidden(2, True) self.ui.geo_tools_table.setColumnHidden(3, True) @@ -2826,7 +2826,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.ui.feedrate_probe_label.hide() self.ui.feedrate_probe_entry.hide() else: - self.ui.level.setText('ADVANCED Mode') + self.ui.level.setText('Advanced') self.ui.plot_cb.stateChanged.connect(self.on_plot_cb_click) self.ui.generate_cnc_button.clicked.connect(self.on_generatecnc_button_click) @@ -4857,11 +4857,11 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): self.ui.cncplot_method_combo.set_value(self.app.defaults["cncjob_plot_kind"]) # Show/Hide Advanced Options - if self.app.defaults["global_advanced"] is False: - self.ui.level.setText('BASIC Mode') + if self.app.defaults["global_app_level"] == 'b': + self.ui.level.setText('Basic') else: - self.ui.level.setText('ADVANCED Mode') + self.ui.level.setText('Advanced') self.ui.updateplot_button.clicked.connect(self.on_updateplot_button_click) self.ui.export_gcode_button.clicked.connect(self.on_exportgcode_button_click) diff --git a/ObjectUI.py b/ObjectUI.py index 225af137..f8d38493 100644 --- a/ObjectUI.py +++ b/ObjectUI.py @@ -32,6 +32,19 @@ class ObjectUI(QtWidgets.QWidget): self.title_label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) self.title_box.addWidget(self.title_label, stretch=1) + ## App Level label + self.level = QtWidgets.QLabel("") + self.level.setToolTip( + "BASIC is suitable for a beginner. Many parameters\n" + "are hidden from the user in this mode.\n" + "ADVANCED mode will make available all parameters.\n\n" + "To change the application LEVEL, go to:\n" + "Edit -> Preferences -> General and check:\n" + "'APP. LEVEL' radio button." + ) + self.level.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) + self.title_box.addWidget(self.level) + ## Box box for custom widgets # This gets populated in offspring implementations. self.custom_box = QtWidgets.QVBoxLayout() @@ -108,16 +121,6 @@ class GerberObjectUI(ObjectUI): def __init__(self, parent=None): ObjectUI.__init__(self, title='Gerber Object', parent=parent) - self.level = QtWidgets.QLabel("") - self.level.setToolTip( - "In the BASIC mode certain functionality's\n" - "are hidden from the user.\n" - "To enable them, go to:\n" - "Edit -> Preferences -> General and check:\n" - "'Show Advanced Options' checkbox." - ) - self.custom_box.addWidget(self.level) - # Plot options grid0 = QtWidgets.QGridLayout() grid0.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) @@ -442,16 +445,6 @@ class ExcellonObjectUI(ObjectUI): icon_file='share/drill32.png', parent=parent) - self.level = QtWidgets.QLabel("") - self.level.setToolTip( - "In the BASIC mode certain functionality's\n" - "are hidden from the user.\n" - "To enable them, go to:\n" - "Edit -> Preferences -> General and check:\n" - "'Show Advanced Options' checkbox." - ) - self.custom_box.addWidget(self.level) - #### Plot options #### hlay_plot = QtWidgets.QHBoxLayout() self.custom_box.addLayout(hlay_plot) @@ -775,16 +768,6 @@ class GeometryObjectUI(ObjectUI): def __init__(self, parent=None): super(GeometryObjectUI, self).__init__(title='Geometry Object', icon_file='share/geometry32.png', parent=parent) - self.level = QtWidgets.QLabel("") - self.level.setToolTip( - "In the BASIC mode certain functionality's\n" - "are hidden from the user.\n" - "To enable them, go to:\n" - "Edit -> Preferences -> General and check:\n" - "'Show Advanced Options' checkbox." - ) - self.custom_box.addWidget(self.level) - # Plot options self.plot_options_label = QtWidgets.QLabel("Plot Options:") self.custom_box.addWidget(self.plot_options_label) @@ -1213,16 +1196,6 @@ class CNCObjectUI(ObjectUI): ObjectUI.__init__(self, title='CNC Job Object', icon_file='share/cnc32.png', parent=parent) - self.level = QtWidgets.QLabel("") - self.level.setToolTip( - "In the BASIC mode certain functionality's\n" - "are hidden from the user.\n" - "To enable them, go to:\n" - "Edit -> Preferences -> General and check:\n" - "'Show Advanced Options' checkbox." - ) - self.custom_box.addWidget(self.level) - # Scale and offset ans skew are not available for CNCJob objects. # Hiding from the GUI. for i in range(0, self.scale_grid.count()): diff --git a/README.md b/README.md index 7312b717..d5f4b321 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,9 @@ CAD program, and create G-Code for Isolation routing. 21.02.2019 - added protection against creating CNCJob from an empty Geometry object (with no geometry inside) -- changed the shortcut key for YOuTube channel from F2 to key F4 +- changed the shortcut key for YouTube channel from F2 to key F4 +- changed the way APP LEVEL is showed both in Edit -> Preferences -> General tab and in each Selected Tab. Changed the ToolTips content for this. +- added the functions for GCode View and GCode Save in Tool SolderPaste 20.02.2019 diff --git a/flatcamTools/ToolSolderPaste.py b/flatcamTools/ToolSolderPaste.py index d4f17235..af976b3a 100644 --- a/flatcamTools/ToolSolderPaste.py +++ b/flatcamTools/ToolSolderPaste.py @@ -854,18 +854,24 @@ class ToolSolderPaste(FlatCAMTool): # self.app.ui.notebook.setCurrentWidget(self.app.ui.project_tab) def on_view_gcode(self): - name = self.obj_combo.currentText() + # add the tab if it was closed + self.app.ui.plot_tab_area.addTab(self.app.ui.cncjob_tab, "Code Editor") + + # Switch plot_area to CNCJob tab + self.app.ui.plot_tab_area.setCurrentWidget(self.app.ui.cncjob_tab) + + name = self.cnc_obj_combo.currentText() obj = self.app.collection.get_by_name(name) # then append the text from GCode to the text editor try: file = StringIO(obj.gcode) except: - pass + self.app.inform.emit("[ERROR_NOTCL] No Gcode in the object...") + return try: for line in file: - print(line) proc_line = str(line).strip('\n') self.app.ui.code_editor.append(proc_line) except Exception as e: @@ -879,14 +885,54 @@ class ToolSolderPaste(FlatCAMTool): self.app.ui.show() def on_save_gcode(self): - name = self.obj_combo.currentText() + time_str = "{:%A, %d %B %Y at %H:%M}".format(datetime.now()) + name = self.cnc_obj_combo.currentText() + obj = self.app.collection.get_by_name(name) - def geo_init(geo_obj, app_obj): - pass + _filter_ = "G-Code Files (*.nc);;G-Code Files (*.txt);;G-Code Files (*.tap);;G-Code Files (*.cnc);;" \ + "G-Code Files (*.g-code);;All Files (*.*)" - # self.app.new_object("geometry", name + "_cutout", geo_init) - # self.app.inform.emit("[success] Rectangular CutOut operation finished.") - # self.app.ui.notebook.setCurrentWidget(self.app.ui.project_tab) + try: + dir_file_to_save = self.app.get_last_save_folder() + '/' + str(name) + filename, _ = QtWidgets.QFileDialog.getSaveFileName( + caption="Export GCode ...", + directory=dir_file_to_save, + filter=_filter_ + ) + except TypeError: + filename, _ = QtWidgets.QFileDialog.getSaveFileName(caption="Export Machine Code ...", filter=_filter_) + + if filename == '': + self.app.inform.emit("[WARNING_NOTCL]Export Machine Code cancelled ...") + return + + gcode = '(G-CODE GENERATED BY FLATCAM v%s - www.flatcam.org - Version Date: %s)\n' % \ + (str(self.app.version), str(self.app.version_date)) + '\n' + + gcode += '(Name: ' + str(name) + ')\n' + gcode += '(Type: ' + "G-code from " + str(obj.options['type']) + " for Solder Paste dispenser" + ')\n' + + # if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry': + # gcode += '(Tools in use: ' + str(p['options']['Tools_in_use']) + ')\n' + + gcode += '(Units: ' + self.units.upper() + ')\n' + "\n" + gcode += '(Created on ' + time_str + ')\n' + '\n' + + gcode += obj.gcode + lines = StringIO(gcode) + + ## Write + if filename is not None: + try: + with open(filename, 'w') as f: + for line in lines: + f.write(line) + except FileNotFoundError: + self.app.inform.emit("[WARNING_NOTCL] No such file or directory") + return + + self.app.file_saved.emit("gcode", filename) + self.app.inform.emit("[success] Solder paste dispenser GCode file saved to: %s" % filename) def on_create_gcode(self, use_thread=True): """