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