From aea67a4a1d2ce9eca973b9a64652241019da38be Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 15 Feb 2019 16:41:42 +0200 Subject: [PATCH] - rearranged the FIle and Edit menu's and added some explanatory tooltips on certain menu items that could be seen as cryptic - added Excellon Export Options in Edit -> Preferences - started to work in using the Excellon Export parameters --- FlatCAMApp.py | 44 +++++++----- FlatCAMGUI.py | 189 ++++++++++++++++++++++++++++++++++++++++++++++++-- FlatCAMObj.py | 8 +-- README.md | 4 +- 4 files changed, 219 insertions(+), 26 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 1bcabed4..6420210a 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -373,6 +373,12 @@ class App(QtCore.QObject): "excellon_slot_tooldia": self.excellon_defaults_form.excellon_opt_group.slot_tooldia_entry, "excellon_gcode_type": self.excellon_defaults_form.excellon_opt_group.excellon_gcode_type_radio, + "excellon_exp_units": self.excellon_defaults_form.excellon_exp_group.excellon_units_radio, + "excellon_exp_format": self.excellon_defaults_form.excellon_exp_group.format_radio, + "excellon_exp_integer": self.excellon_defaults_form.excellon_exp_group.format_whole_entry, + "excellon_exp_decimals": self.excellon_defaults_form.excellon_exp_group.format_dec_entry, + "excellon_exp_zeros": self.excellon_defaults_form.excellon_exp_group.zeros_radio, + "geometry_plot": self.geometry_defaults_form.geometry_gen_group.plot_cb, "geometry_cnctooldia": self.geometry_defaults_form.geometry_gen_group.cnctooldia_entry, "geometry_circle_steps": self.geometry_defaults_form.geometry_gen_group.circle_steps_entry, @@ -578,6 +584,12 @@ class App(QtCore.QObject): "excellon_f_retract": False, "excellon_gcode_type": "drills", + "excellon_exp_units": 'INCH', + "excellon_exp_format": 'ndec', + "excellon_exp_integer": 2, + "excellon_exp_decimals": 4, + "excellon_exp_zeros": 'LZ', + "geometry_plot": True, "geometry_segx": 0.0, "geometry_segy": 0.0, @@ -1048,7 +1060,10 @@ class App(QtCore.QObject): ## Standard signals # Menu - self.ui.menufilenew.triggered.connect(self.on_file_new_click) + self.ui.menufilenewproject.triggered.connect(self.on_file_new_click) + self.ui.menufilenewgeo.triggered.connect(self.new_geometry_object) + self.ui.menufilenewexc.triggered.connect(self.new_excellon_object) + self.ui.menufileopengerber.triggered.connect(self.on_fileopengerber) self.ui.menufileopengerber_follow.triggered.connect(self.on_fileopengerber_follow) self.ui.menufileopenexcellon.triggered.connect(self.on_fileopenexcellon) @@ -1075,8 +1090,6 @@ class App(QtCore.QObject): self.ui.menufilesavedefaults.triggered.connect(self.on_file_savedefaults) self.ui.menufile_exit.triggered.connect(self.on_app_exit) - self.ui.menueditnew.triggered.connect(self.new_geometry_object) - self.ui.menueditnewexc.triggered.connect(self.new_excellon_object) self.ui.menueditedit.triggered.connect(self.object2editor) self.ui.menueditok.triggered.connect(self.editor2object) @@ -5489,7 +5502,7 @@ class App(QtCore.QObject): else: make_black_film() - def export_excellon(self, obj_name, filename, altium_format=None, use_thread=True): + def export_excellon(self, obj_name, filename, use_thread=True): """ Exports a Geometry Object to an Excellon file. @@ -5503,7 +5516,9 @@ class App(QtCore.QObject): self.log.debug("export_excellon()") - format_exc = ';FILE_FORMAT=2:4\n' + format_exc = ';FILE_FORMAT=%d:%d\n' % (self.defaults["excellon_exp_integer"], + self.defaults["excellon_exp_decimals"] + ) units = '' try: @@ -5513,12 +5528,9 @@ class App(QtCore.QObject): return "Could not retrieve object: %s" % obj_name # updated units - units = self.general_options_form.general_app_group.units_radio.get_value().upper() - if units == 'IN' or units == 'INCH': - units = 'INCH' - - elif units == 'MM' or units == 'METRIC': - units ='METRIC' + units = self.defaults["excellon_exp_units"] + whole = self.defaults["excellon_exp_integer"] + fract = self.defaults["excellon_exp_decimals"] def make_excellon(): try: @@ -5531,8 +5543,8 @@ class App(QtCore.QObject): header += ';Filename: %s' % str(obj_name) + '\n' header += ';Created on : %s' % time_str + '\n' - if altium_format == None: - has_slots, excellon_code = obj.export_excellon() + if self.defaults["excellon_exp_format"] == 'dec': + has_slots, excellon_code = obj.export_excellon_decimals(whole, fract, units) header += units + '\n' for tool in obj.tools: @@ -5541,14 +5553,14 @@ class App(QtCore.QObject): else: header += 'T' + str(tool) + 'F00S00' + 'C' + '%.4f' % float(obj.tools[tool]['C']) + '\n' else: - has_slots, excellon_code = obj.export_excellon_altium() - header += 'INCH,LZ\n' + has_slots, excellon_code = obj.export_excellon_ndecimals(whole, fract, units) + header += '%s,%s\n' % (units, self.defaults["excellon_exp_zeros"]) header += format_exc for tool in obj.tools: if units == 'METRIC': header += 'T' + str(tool) + 'F00S00' + 'C' + \ - '%.4f' % (float(obj.tools[tool]['C']) / 25.4) + '\n' + '%.2f' % (float(obj.tools[tool]['C']) / 25.4) + '\n' else: header += 'T' + str(tool) + 'F00S00' + 'C' + '%.4f' % float(obj.tools[tool]['C']) + '\n' diff --git a/FlatCAMGUI.py b/FlatCAMGUI.py index 75124df4..20bf1442 100644 --- a/FlatCAMGUI.py +++ b/FlatCAMGUI.py @@ -37,12 +37,31 @@ class FlatCAMGUI(QtWidgets.QMainWindow): ### File ### self.menufile = self.menu.addMenu('&File') + self.menufile.setToolTipsVisible(True) - # New - self.menufilenew = QtWidgets.QAction(QtGui.QIcon('share/file16.png'), '&New Project ...\tCTRL+N', self) - self.menufile.addAction(self.menufilenew) + # New Project + self.menufilenewproject = QtWidgets.QAction(QtGui.QIcon('share/file16.png'), '&New Project ...\tCTRL+N', self) + self.menufilenewproject.setToolTip( + "Will create a new, blank project" + ) + self.menufile.addAction(self.menufilenewproject) + + # New Category (Excellon, Geometry) + self.menufilenew = self.menufile.addMenu(QtGui.QIcon('share/file16.png'), '&New') + self.menufilenew.setToolTipsVisible(True) + + self.menufilenewgeo = self.menufilenew.addAction(QtGui.QIcon('share/new_geo16.png'), '&New Geometry\tN') + self.menufilenewgeo.setToolTip( + "Will create a new, empty Geometry Object." + ) + self.menufilenewexc = self.menufilenew.addAction(QtGui.QIcon('share/new_geo16.png'), 'New Excellon\tL') + self.menufilenewexc.setToolTip( + "Will create a new, empty Excellon Object." + ) self.menufile_open = self.menufile.addMenu(QtGui.QIcon('share/folder32_bis.png'), 'Open') + self.menufile_open.setToolTipsVisible(True) + # Open gerber ... self.menufileopengerber = QtWidgets.QAction(QtGui.QIcon('share/flatcam_icon24.png'), 'Open &Gerber ...\tCTRL+G', self) @@ -51,6 +70,12 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # Open gerber with follow... self.menufileopengerber_follow = QtWidgets.QAction(QtGui.QIcon('share/flatcam_icon24.png'), 'Open &Gerber (w/ Follow) ...', self) + self.menufileopengerber_follow.setToolTip( + "Will open a Gerber file with the 'follow' attribute.\n" + "This will actually 'trace' the features of a Gerber file and\n" + "the resulting Gerber geometry will have no volume, it will be\n" + "made out of lines." + ) self.menufile_open.addAction(self.menufileopengerber_follow) self.menufile_open.addSeparator() @@ -76,6 +101,11 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # Run Scripts self.menufilerunscript = QtWidgets.QAction(QtGui.QIcon('share/script16.png'), 'Run Script ...\tSHIFT+S', self) + self.menufilerunscript.setToolTip( + "Will run the opened Tcl Script thus\n" + "enabling the automation of certain\n" + "functions of FlatCAM." + ) self.menufile.addAction(self.menufilerunscript) # Separator @@ -101,6 +131,8 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # Export ... self.menufileexport = self.menufile.addMenu(QtGui.QIcon('share/export.png'), 'Export') + self.menufileexport.setToolTipsVisible(True) + self.menufileexportsvg = QtWidgets.QAction(QtGui.QIcon('share/export.png'), 'Export &SVG ...', self) self.menufileexport.addAction(self.menufileexportsvg) @@ -110,15 +142,30 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.menufileexport.addSeparator() self.menufileexportpng = QtWidgets.QAction(QtGui.QIcon('share/export_png32.png'), 'Export &PNG ...', self) + self.menufileexportpng.setToolTip( + "Will export an image in PNG format,\n" + "the saved image will contain the visual \n" + "information currently in FlatCAM Plot Area." + ) self.menufileexport.addAction(self.menufileexportpng) self.menufileexport.addSeparator() self.menufileexportexcellon = QtWidgets.QAction(QtGui.QIcon('share/drill32.png'), 'Export &Excellon ...', self) + self.menufileexportexcellon.setToolTip( + "Will export an Excellon Object as Excellon file,\n" + "the coordinates format is decimal and the file units\n" + "are the current units set in FlatCAM." + ) self.menufileexport.addAction(self.menufileexportexcellon) self.menufileexportexcellon_altium = QtWidgets.QAction(QtGui.QIcon('share/drill32.png'), 'Export Excellon 2:4 LZ INCH ...', self) + self.menufileexportexcellon_altium.setToolTip( + "Will export an Excellon Object as Excellon file,\n" + "the coordinates format is 2:4, excellon zeros are LZ \n" + "and the file units are INCH." + ) self.menufileexport.addAction(self.menufileexportexcellon_altium) # Separator @@ -157,8 +204,6 @@ class FlatCAMGUI(QtWidgets.QMainWindow): ### Edit ### self.menuedit = self.menu.addMenu('&Edit') - self.menueditnew = self.menuedit.addAction(QtGui.QIcon('share/new_geo16.png'), '&New Geometry\tN') - self.menueditnewexc = self.menuedit.addAction(QtGui.QIcon('share/new_geo16.png'), 'New Excellon\tL') # Separator self.menuedit.addSeparator() self.menueditedit = self.menuedit.addAction(QtGui.QIcon('share/edit16.png'), 'Edit Object\tE') @@ -2373,9 +2418,13 @@ class ExcellonPreferencesUI(QtWidgets.QWidget): self.excellon_gen_group.setFixedWidth(220) self.excellon_opt_group = ExcellonOptPrefGroupUI() self.excellon_opt_group.setFixedWidth(250) + self.excellon_exp_group = ExcellonExpPrefGroupUI() + self.excellon_exp_group.setFixedWidth(250) self.layout.addWidget(self.excellon_gen_group) self.layout.addWidget(self.excellon_opt_group) + self.layout.addWidget(self.excellon_exp_group) + self.layout.addStretch() @@ -3557,6 +3606,136 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): self.layout.addStretch() +class ExcellonExpPrefGroupUI(OptionsGroupUI): + + def __init__(self, parent=None): + super(ExcellonExpPrefGroupUI, self).__init__(self) + + self.setTitle(str("Excellon Export")) + + # Plot options + self.export_options_label = QtWidgets.QLabel("Export Options:") + self.export_options_label.setToolTip( + "The parameters set here are used in the file exported" + "when using the File -> Export -> Export Excellon menu entry." + ) + self.layout.addWidget(self.export_options_label) + + form = QtWidgets.QFormLayout() + self.layout.addLayout(form) + + # Excellon Units + self.excellon_units_label = QtWidgets.QLabel('Units:') + self.excellon_units_label.setToolTip( + "The units used in the Excellon file." + ) + + self.excellon_units_radio = RadioSet([{'label': 'INCH', 'value': 'INCH'}, {'label': 'MM', 'value': 'METRIC'}]) + self.excellon_units_radio.setToolTip( + "The units used in the Excellon file." + ) + + form.addRow(self.excellon_units_label, self.excellon_units_radio) + + # Select the Excellon Format + self.format_label = QtWidgets.QLabel("Format:") + self.format_label.setToolTip( + "Select the kind of coordinates format used.\n" + "Coordinates can be saved with decimal point or without.\n" + "When there is no decimal point, it is required to specify\n" + "the number of digits for integer part and the number of decimals.\n" + "Also it will have to be specified if LZ = leading zeros are kept\n" + "or TZ = trailing zeros are kept." + ) + self.format_radio = RadioSet([{'label': 'Decimal', 'value': 'dec'}, {'label': 'No-Decimal', 'value': 'ndec'}]) + self.format_radio.setToolTip( + "Select the kind of coordinates format used.\n" + "Coordinates can be saved with decimal point or without.\n" + "When there is no decimal point, it is required to specify\n" + "the number of digits for integer part and the number of decimals.\n" + "Also it will have to be specified if LZ = leading zeros are kept\n" + "or TZ = trailing zeros are kept." + ) + + form.addRow(self.format_label, self.format_radio) + + # Excellon non-decimal format + self.digits_label = QtWidgets.QLabel("Int/Decimals:") + self.digits_label.setToolTip( + "The NC drill files, usually named Excellon files\n" + "are files that can be found in different formats.\n" + "Here we set the format used when the provided\n" + "coordinates are not using period." + ) + + hlay1 = QtWidgets.QHBoxLayout() + + self.format_whole_entry = IntEntry() + self.format_whole_entry.setMaxLength(1) + self.format_whole_entry.setAlignment(QtCore.Qt.AlignRight) + self.format_whole_entry.setFixedWidth(30) + self.format_whole_entry.setToolTip( + "This numbers signify the number of digits in\n" + "the whole part of Excellon coordinates." + ) + hlay1.addWidget(self.format_whole_entry, QtCore.Qt.AlignLeft) + + excellon_separator_label= QtWidgets.QLabel(':') + excellon_separator_label.setFixedWidth(5) + hlay1.addWidget(excellon_separator_label, QtCore.Qt.AlignLeft) + + self.format_dec_entry = IntEntry() + self.format_dec_entry.setMaxLength(1) + self.format_dec_entry.setAlignment(QtCore.Qt.AlignRight) + self.format_dec_entry.setFixedWidth(30) + self.format_dec_entry.setToolTip( + "This numbers signify the number of digits in\n" + "the decimal part of Excellon coordinates." + ) + hlay1.addWidget(self.format_dec_entry, QtCore.Qt.AlignLeft) + hlay1.addStretch() + + form.addRow(self.digits_label, hlay1) + + # Excellon Zeros + self.zeros_label = QtWidgets.QLabel('Zeros:') + self.zeros_label.setAlignment(QtCore.Qt.AlignLeft) + self.zeros_label.setToolTip( + "This sets the type of Excellon zeros.\n" + "If LZ then Leading Zeros are kept and\n" + "Trailing Zeros are removed.\n" + "If TZ is checked then Trailing Zeros are kept\n" + "and Leading Zeros are removed." + ) + + self.zeros_radio = RadioSet([{'label': 'LZ', 'value': 'LZ'}, + {'label': 'TZ', 'value': 'TZ'}]) + self.zeros_radio.setToolTip( + "This sets the default type of Excellon zeros.\n" + "If LZ then Leading Zeros are kept and\n" + "Trailing Zeros are removed.\n" + "If TZ is checked then Trailing Zeros are kept\n" + "and Leading Zeros are removed." + ) + + form.addRow(self.zeros_label, self.zeros_radio) + + self.layout.addStretch() + self.format_radio.activated_custom.connect(self.optimization_selection) + + def optimization_selection(self): + if self.format_radio.get_value() == 'dec': + self.digits_label.setDisabled(True) + + self.zeros_label.setDisabled(True) + self.zeros_radio.setDisabled(True) + else: + self.digits_label.setDisabled(False) + + self.zeros_label.setDisabled(False) + self.zeros_radio.setDisabled(False) + + class GeometryGenPrefGroupUI(OptionsGroupUI): def __init__(self, parent=None): # OptionsGroupUI.__init__(self, "Geometry General Preferences", parent=parent) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index bf6c744f..f98cebf3 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -1612,14 +1612,14 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): item[0] = str(item[0]) return table_tools_items - def export_excellon(self): + def export_excellon_decimals(self, whole, fract, units): """ Returns two values, first is a boolean , if 1 then the file has slots and second contain the Excellon code :return: has_slots and Excellon_code """ excellon_code = '' - units = self.app.general_options_form.general_app_group.units_radio.get_value().upper() + units = units # store here if the file has slots, return 1 if any slots, 0 if only drills has_slots = 0 @@ -1672,14 +1672,14 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): return has_slots, excellon_code - def export_excellon_altium(self): + def export_excellon_ndecimals(self, whole, fract, units): """ Returns two values, first is a boolean , if 1 then the file has slots and second contain the Excellon code :return: has_slots and Excellon_code """ excellon_code = '' - units = self.app.general_options_form.general_app_group.units_radio.get_value().upper() + units = units # store here if the file has slots, return 1 if any slots, 0 if only drills has_slots = 0 diff --git a/README.md b/README.md index 796944b3..1bd12791 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,9 @@ CAD program, and create G-Code for Isolation routing. 15.02.2019 -- +- rearranged the FIle and Edit menu's and added some explanatory tooltips on certain menu items that could be seen as cryptic +- added Excellon Export Options in Edit -> Preferences +- started to work in using the Excellon Export parameters 14.02.2019