diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1f6c6b3d..7770a326 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,16 +7,6 @@ CHANGELOG for FlatCAM beta
=================================================
-11.05.2020
-
-- removed the labels in status bar that display X,Y positions and replaced it with a HUD display on canvas (combo key SHIFT+H) will toggle the display of the HUD
-- made the HUD work in Legacy2D mode
-- fixed situation when the mouse cursor is outside of the canvas and no therefore returning None values
-
-10.05.2020
-
-- fixed the problem with using comma as decimal separator in Grid Snap fields
-
9.05.2020
- modified the GUI for Exclusion areas; now the shapes are displayed in a Table where they can be selected and deleted. Modification applied for Geometry Objects only (for now).
diff --git a/FlatCAMApp.py b/FlatCAMApp.py
index a07f28c4..4641420d 100644
--- a/FlatCAMApp.py
+++ b/FlatCAMApp.py
@@ -285,8 +285,6 @@ class App(QtCore.QObject):
:rtype: App
"""
- super().__init__()
-
App.log.info("FlatCAM Starting...")
self.main_thread = QtWidgets.QApplication.instance().thread()
@@ -454,8 +452,6 @@ class App(QtCore.QObject):
self.current_units = self.defaults['units']
-
-
# ###########################################################################################################
# #################################### SETUP OBJECT CLASSES #################################################
# ###########################################################################################################
@@ -508,6 +504,8 @@ class App(QtCore.QObject):
self.FC_light_blue = '#a5a5ffbf'
self.FC_dark_blue = '#0000ffbf'
+ QtCore.QObject.__init__(self)
+
self.ui = FlatCAMGUI(self)
theme_settings = QtCore.QSettings("Open Source", "FlatCAM")
@@ -605,11 +603,13 @@ class App(QtCore.QObject):
# ################################ It's done only once after install #####################################
# ###########################################################################################################
if self.defaults["first_run"] is True:
- # ONLY AT FIRST STARTUP INIT THE GUI LAYOUT TO 'minimal'
+ # ONLY AT FIRST STARTUP INIT THE GUI LAYOUT TO 'COMPACT'
initial_lay = 'minimal'
- layout_field = self.preferencesUiManager.get_form_field("layout")
- layout_field.setCurrentIndex(layout_field.findText(initial_lay))
- self.ui.set_layout(initial_lay)
+ self.ui.general_defaults_form.general_gui_group.on_layout(lay=initial_lay)
+
+ # Set the combobox in Preferences to the current layout
+ idx = self.ui.general_defaults_form.general_gui_group.layout_combo.findText(initial_lay)
+ self.ui.general_defaults_form.general_gui_group.layout_combo.setCurrentIndex(idx)
# after the first run, this object should be False
self.defaults["first_run"] = False
@@ -632,9 +632,8 @@ class App(QtCore.QObject):
# ###########################################################################################################
self.languages = fcTranslate.load_languages()
- language_field = self.preferencesUiManager.get_form_field("global_language")
for name in sorted(self.languages.values()):
- language_field.addItem(name)
+ self.ui.general_defaults_form.general_app_group.language_cb.addItem(name)
# ###########################################################################################################
# ####################################### APPLY APP LANGUAGE ################################################
@@ -647,7 +646,7 @@ class App(QtCore.QObject):
log.debug("Could not find the Language files. The App strings are missing.")
else:
# make the current language the current selection on the language combobox
- self.preferencesUiManager.get_form_field("global_language").setCurrentText(ret_val)
+ self.ui.general_defaults_form.general_app_group.language_cb.setCurrentText(ret_val)
log.debug("App.__init__() --> Applied %s language." % str(ret_val).capitalize())
# ###########################################################################################################
@@ -967,25 +966,23 @@ class App(QtCore.QObject):
# #################################### GUI PREFERENCES SIGNALS ##############################################
# ###########################################################################################################
- self.preferencesUiManager.get_form_field("units").activated_custom.connect(
+ self.ui.general_defaults_form.general_app_group.units_radio.activated_custom.connect(
lambda: self.on_toggle_units(no_pref=False))
# ##################################### Workspace Setting Signals ###########################################
-
-
- self.preferencesUiManager.get_form_field("global_workspaceT").currentIndexChanged.connect(
+ self.ui.general_defaults_form.general_app_set_group.wk_cb.currentIndexChanged.connect(
self.on_workspace_modified)
- self.preferencesUiManager.get_form_field("global_workspace_orientation").activated_custom.connect(
+ self.ui.general_defaults_form.general_app_set_group.wk_orientation_radio.activated_custom.connect(
self.on_workspace_modified
)
- self.preferencesUiManager.get_form_field("global_workspace").stateChanged.connect(self.on_workspace)
+ self.ui.general_defaults_form.general_app_set_group.workspace_cb.stateChanged.connect(self.on_workspace)
# ###########################################################################################################
# ######################################## GUI SETTINGS SIGNALS #############################################
# ###########################################################################################################
- self.preferencesUiManager.get_form_field("global_graphic_engine").activated_custom.connect(self.on_app_restart)
- self.preferencesUiManager.get_form_field("global_cursor_type").activated_custom.connect(self.on_cursor_type)
+ self.ui.general_defaults_form.general_app_group.ge_radio.activated_custom.connect(self.on_app_restart)
+ self.ui.general_defaults_form.general_app_set_group.cursor_radio.activated_custom.connect(self.on_cursor_type)
# ######################################## Tools related signals ############################################
# Film Tool
@@ -1005,7 +1002,7 @@ class App(QtCore.QObject):
self.on_qrcode_back_color_button)
# portability changed signal
- self.preferencesUiManager.get_form_field("global_portable").stateChanged.connect(self.on_portable_checked)
+ self.ui.general_defaults_form.general_app_group.portability_cb.stateChanged.connect(self.on_portable_checked)
# Object list
self.collection.view.activated.connect(self.on_row_activated)
@@ -1013,6 +1010,15 @@ class App(QtCore.QObject):
self.object_status_changed.connect(self.on_collection_updated)
+ # Make sure that when the Excellon loading parameters are changed, the change is reflected in the
+ # Export Excellon parameters.
+ self.ui.excellon_defaults_form.excellon_gen_group.update_excellon_cb.stateChanged.connect(
+ self.on_update_exc_export
+ )
+
+ # call it once to make sure it is updated at startup
+ self.on_update_exc_export(state=self.defaults["excellon_update"])
+
# when there are arguments at application startup this get launched
self.args_at_startup[list].connect(self.on_startup_args)
@@ -1419,8 +1425,8 @@ class App(QtCore.QObject):
# Separate thread (Not worker)
# Check for updates on startup but only if the user consent and the app is not in Beta version
if (self.beta is False or self.beta is None) and \
- self.preferencesUiManager.get_form_field("global_version_check").get_value() is True:
- App.log.info("Checking for updates in background (this is version %s)." % str(self.version))
+ self.ui.general_defaults_form.general_app_group.version_check_cb.get_value() is True:
+ App.log.info("Checking for updates in backgroud (this is version %s)." % str(self.version))
# self.thr2 = QtCore.QThread()
self.worker_task.emit({'fcn': self.version_check,
@@ -1547,7 +1553,7 @@ class App(QtCore.QObject):
self.abort_flag = False
# set the value used in the Windows Title
- self.engine = self.preferencesUiManager.get_form_field("global_graphic_engine").get_value()
+ self.engine = self.ui.general_defaults_form.general_app_group.ge_radio.get_value()
# this holds a widget that is installed in the Plot Area when View Source option is used
self.source_editor_tab = None
@@ -1592,7 +1598,11 @@ class App(QtCore.QObject):
self.set_ui_title(name=_("New Project - Not saved"))
-
+ # disable the Excellon path optimizations made with Google OR-Tools if the app is run on a 32bit platform
+ current_platform = platform.architecture()[0]
+ if current_platform != '64bit':
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_optimization_radio.set_value('T')
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_optimization_radio.setDisabled(True)
# ###########################################################################################################
# ########################################### EXCLUSION AREAS ###############################################
@@ -3561,24 +3571,24 @@ class App(QtCore.QObject):
stgs.setValue('maximized_gui', self.ui.isMaximized())
stgs.setValue(
'language',
- self.preferencesUiManager.get_form_field("global_language").get_value()
+ self.ui.general_defaults_form.general_app_group.language_cb.get_value()
)
stgs.setValue(
'notebook_font_size',
- self.preferencesUiManager.get_form_field("notebook_font_size").get_value()
+ self.ui.general_defaults_form.general_app_set_group.notebook_font_size_spinner.get_value()
)
stgs.setValue(
'axis_font_size',
- self.preferencesUiManager.get_form_field("axis_font_size").get_value()
+ self.ui.general_defaults_form.general_app_set_group.axis_font_size_spinner.get_value()
)
stgs.setValue(
'textbox_font_size',
- self.preferencesUiManager.get_form_field("textbox_font_size").get_value()
+ self.ui.general_defaults_form.general_app_set_group.textbox_font_size_spinner.get_value()
)
stgs.setValue('toolbar_lock', self.ui.lock_action.isChecked())
stgs.setValue(
'machinist',
- 1 if self.preferencesUiManager.get_form_field("global_machinist_setting").get_value() else 0
+ 1 if self.ui.general_defaults_form.general_app_set_group.machinist_cb.get_value() else 0
)
# This will write the setting to the platform specific storage.
@@ -4201,18 +4211,18 @@ class App(QtCore.QObject):
def on_toggle_units_click(self):
try:
- self.preferencesUiManager.get_form_field("units").activated_custom.disconnect()
+ self.ui.general_defaults_form.general_app_group.units_radio.activated_custom.disconnect()
except (TypeError, AttributeError):
pass
if self.defaults["units"] == 'MM':
- self.preferencesUiManager.get_form_field("units").set_value("IN")
+ self.ui.general_defaults_form.general_app_group.units_radio.set_value("IN")
else:
- self.preferencesUiManager.get_form_field("units").set_value("MM")
+ self.ui.general_defaults_form.general_app_group.units_radio.set_value("MM")
self.on_toggle_units(no_pref=True)
- self.preferencesUiManager.get_form_field("units").activated_custom.connect(
+ self.ui.general_defaults_form.general_app_group.units_radio.activated_custom.connect(
lambda: self.on_toggle_units(no_pref=False))
def on_toggle_units(self, no_pref=False):
@@ -4230,7 +4240,7 @@ class App(QtCore.QObject):
if self.toggle_units_ignore:
return
- new_units = self.preferencesUiManager.get_form_field("units").get_value().upper()
+ new_units = self.ui.general_defaults_form.general_app_group.units_radio.get_value().upper()
# If option is the same, then ignore
if new_units == self.defaults["units"].upper():
@@ -4441,9 +4451,9 @@ class App(QtCore.QObject):
# Undo toggling
self.toggle_units_ignore = True
if self.defaults['units'].upper() == 'MM':
- self.preferencesUiManager.get_form_field("units").set_value('IN')
+ self.ui.general_defaults_form.general_app_group.units_radio.set_value('IN')
else:
- self.preferencesUiManager.get_form_field("units").set_value('MM')
+ self.ui.general_defaults_form.general_app_group.units_radio.set_value('MM')
self.toggle_units_ignore = False
# store the grid values so they are not changed in the next step
@@ -4612,7 +4622,133 @@ class App(QtCore.QObject):
self.app_cursor.enabled = True
self.app_cursor.enabled = False
+ def on_update_exc_export(self, state):
+ """
+ This is handling the update of Excellon Export parameters based on the ones in the Excellon General but only
+ if the update_excellon_cb checkbox is checked
+ :param state: state of the checkbox whose signals is tied to his slot
+ :return:
+ """
+ if state:
+ # first try to disconnect
+ try:
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_upper_in_entry.returnPressed. \
+ disconnect(self.on_excellon_format_changed)
+ except TypeError:
+ pass
+ try:
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_lower_in_entry.returnPressed. \
+ disconnect(self.on_excellon_format_changed)
+ except TypeError:
+ pass
+ try:
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_upper_mm_entry.returnPressed. \
+ disconnect(self.on_excellon_format_changed)
+ except TypeError:
+ pass
+ try:
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_lower_mm_entry.returnPressed. \
+ disconnect(self.on_excellon_format_changed)
+ except TypeError:
+ pass
+
+ try:
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_zeros_radio.activated_custom. \
+ disconnect(self.on_excellon_zeros_changed)
+ except TypeError:
+ pass
+ try:
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_units_radio.activated_custom. \
+ disconnect(self.on_excellon_zeros_changed)
+ except TypeError:
+ pass
+
+ # the connect them
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_upper_in_entry.returnPressed.connect(
+ self.on_excellon_format_changed)
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_lower_in_entry.returnPressed.connect(
+ self.on_excellon_format_changed)
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_upper_mm_entry.returnPressed.connect(
+ self.on_excellon_format_changed)
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_lower_mm_entry.returnPressed.connect(
+ self.on_excellon_format_changed)
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_zeros_radio.activated_custom.connect(
+ self.on_excellon_zeros_changed)
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_units_radio.activated_custom.connect(
+ self.on_excellon_units_changed)
+ else:
+ # disconnect the signals
+ try:
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_upper_in_entry.returnPressed. \
+ disconnect(self.on_excellon_format_changed)
+ except TypeError:
+ pass
+ try:
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_lower_in_entry.returnPressed. \
+ disconnect(self.on_excellon_format_changed)
+ except TypeError:
+ pass
+ try:
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_upper_mm_entry.returnPressed. \
+ disconnect(self.on_excellon_format_changed)
+ except TypeError:
+ pass
+ try:
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_lower_mm_entry.returnPressed. \
+ disconnect(self.on_excellon_format_changed)
+ except TypeError:
+ pass
+
+ try:
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_zeros_radio.activated_custom. \
+ disconnect(self.on_excellon_zeros_changed)
+ except TypeError:
+ pass
+ try:
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_units_radio.activated_custom. \
+ disconnect(self.on_excellon_zeros_changed)
+ except TypeError:
+ pass
+
+ def on_excellon_format_changed(self):
+ """
+ Slot activated when the user changes the Excellon format values in Preferences -> Excellon -> Excellon General
+ :return: None
+ """
+ if self.ui.excellon_defaults_form.excellon_gen_group.excellon_units_radio.get_value().upper() == 'METRIC':
+ self.ui.excellon_defaults_form.excellon_exp_group.format_whole_entry.set_value(
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_upper_mm_entry.get_value()
+ )
+ self.ui.excellon_defaults_form.excellon_exp_group.format_dec_entry.set_value(
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_lower_mm_entry.get_value()
+ )
+ else:
+ self.ui.excellon_defaults_form.excellon_exp_group.format_whole_entry.set_value(
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_upper_in_entry.get_value()
+ )
+ self.ui.excellon_defaults_form.excellon_exp_group.format_dec_entry.set_value(
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_lower_in_entry.get_value()
+ )
+
+ def on_excellon_zeros_changed(self):
+ """
+ Slot activated when the user changes the Excellon zeros values in Preferences -> Excellon -> Excellon General
+ :return: None
+ """
+ self.ui.excellon_defaults_form.excellon_exp_group.zeros_radio.set_value(
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_zeros_radio.get_value() + 'Z'
+ )
+
+ def on_excellon_units_changed(self):
+ """
+ Slot activated when the user changes the Excellon unit values in Preferences -> Excellon -> Excellon General
+ :return: None
+ """
+ self.ui.excellon_defaults_form.excellon_exp_group.excellon_units_radio.set_value(
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_units_radio.get_value()
+ )
+ self.on_excellon_format_changed()
def on_film_color_entry(self):
self.defaults['tools_film_color'] = \
@@ -4739,7 +4875,7 @@ class App(QtCore.QObject):
self.plotcanvas.draw_workspace(workspace_size=self.defaults['global_workspaceT'])
def on_workspace(self):
- if self.preferencesUiManager.get_form_field("global_workspace").get_value():
+ if self.ui.general_defaults_form.general_app_set_group.workspace_cb.get_value():
self.plotcanvas.draw_workspace(workspace_size=self.defaults['global_workspaceT'])
else:
self.plotcanvas.delete_workspace()
@@ -4747,13 +4883,13 @@ class App(QtCore.QObject):
# self.save_defaults(silent=True)
def on_workspace_toggle(self):
- state = False if self.preferencesUiManager.get_form_field("global_workspace").get_value() else True
+ state = False if self.ui.general_defaults_form.general_app_set_group.workspace_cb.get_value() else True
try:
- self.preferencesUiManager.get_form_field("global_workspace").stateChanged.disconnect(self.on_workspace)
+ self.ui.general_defaults_form.general_app_set_group.workspace_cb.stateChanged.disconnect(self.on_workspace)
except TypeError:
pass
- self.preferencesUiManager.get_form_field("global_workspace").set_value(state)
- self.preferencesUiManager.get_form_field("global_workspace").stateChanged.connect(self.on_workspace)
+ self.ui.general_defaults_form.general_app_set_group.workspace_cb.set_value(state)
+ self.ui.general_defaults_form.general_app_set_group.workspace_cb.stateChanged.connect(self.on_workspace)
self.on_workspace()
def on_cursor_type(self, val):
@@ -4765,12 +4901,12 @@ class App(QtCore.QObject):
self.app_cursor.enabled = False
if val == 'small':
- self.preferencesUiManager.get_form_field("global_cursor_size").setDisabled(False)
- #self.ui.general_defaults_form.general_app_set_group.cursor_size_lbl.setDisabled(False)
+ self.ui.general_defaults_form.general_app_set_group.cursor_size_entry.setDisabled(False)
+ self.ui.general_defaults_form.general_app_set_group.cursor_size_lbl.setDisabled(False)
self.app_cursor = self.plotcanvas.new_cursor()
else:
- self.preferencesUiManager.get_form_field("global_cursor_size").setDisabled(False)
- #self.ui.general_defaults_form.general_app_set_group.cursor_size_lbl.setDisabled(True)
+ self.ui.general_defaults_form.general_app_set_group.cursor_size_entry.setDisabled(True)
+ self.ui.general_defaults_form.general_app_set_group.cursor_size_lbl.setDisabled(True)
self.app_cursor = self.plotcanvas.new_cursor(big=True)
if self.ui.grid_snap_btn.isChecked():
@@ -5242,20 +5378,14 @@ class App(QtCore.QObject):
edge_width=self.defaults["global_cursor_width"],
size=self.defaults["global_cursor_size"])
+ # Set the position label
+ self.ui.position_label.setText(" X: %.4f "
+ "Y: %.4f" % (location[0], location[1]))
# Set the relative position label
dx = location[0] - float(self.rel_point1[0])
dy = location[1] - float(self.rel_point1[1])
- # self.ui.position_label.setText(" X: %.4f "
- # "Y: %.4f" % (location[0], location[1]))
- # # Set the position label
- #
- # self.ui.rel_position_label.setText("Dx: %.4f Dy: "
- # "%.4f " % (dx, dy))
-
- units = self.defaults["units"].lower()
- self.plotcanvas.text_hud.text = \
- 'Dx:\t{:<.4f} [{:s}]\nDy:\t{:<.4f} [{:s}]\nX: \t{:<.4f} [{:s}]\nY: \t{:<.4f} [{:s}]'.format(
- dx, units, dy, units, location[0], units, location[1], units)
+ self.ui.rel_position_label.setText("Dx: %.4f Dy: "
+ "%.4f " % (dx, dy))
self.inform.emit('[success] %s' % _("Done."))
return location
@@ -5397,19 +5527,14 @@ class App(QtCore.QObject):
edge_width=self.defaults["global_cursor_width"],
size=self.defaults["global_cursor_size"])
+ # Set the position label
+ self.ui.position_label.setText(" X: %.4f "
+ "Y: %.4f" % (location[0], location[1]))
# Set the relative position label
self.dx = location[0] - float(self.rel_point1[0])
self.dy = location[1] - float(self.rel_point1[1])
- # Set the position label
- # self.ui.position_label.setText(" X: %.4f "
- # "Y: %.4f" % (location[0], location[1]))
- # self.ui.rel_position_label.setText("Dx: %.4f Dy: "
- # "%.4f " % (self.dx, self.dy))
-
- units = self.defaults["units"].lower()
- self.plotcanvas.text_hud.text = \
- 'Dx:\t{:<.4f} [{:s}]\nDy:\t{:<.4f} [{:s}]\nX: \t{:<.4f} [{:s}]\nY: \t{:<.4f} [{:s}]'.format(
- self.dx, units, self.dy, units, location[0], units, location[1], units)
+ self.ui.rel_position_label.setText("Dx: %.4f Dy: "
+ "%.4f " % (self.dx, self.dy))
self.inform.emit('[success] %s' % _("Done."))
return location
@@ -5718,8 +5843,8 @@ class App(QtCore.QObject):
self.ui.plot_tab_area.addTab(self.ui.preferences_tab, _("Preferences"))
# delete the absolute and relative position and messages in the infobar
- # self.ui.position_label.setText("")
- # self.ui.rel_position_label.setText("")
+ self.ui.position_label.setText("")
+ self.ui.rel_position_label.setText("")
# Switch plot_area to preferences page
self.ui.plot_tab_area.setCurrentWidget(self.ui.preferences_tab)
@@ -6613,9 +6738,6 @@ class App(QtCore.QObject):
try: # May fail in case mouse not within axes
pos_canvas = self.plotcanvas.translate_coords(event_pos)
- if pos_canvas[0] is None or pos_canvas[1] is None:
- return
-
if self.grid_status():
pos = self.geo_editor.snap(pos_canvas[0], pos_canvas[1])
@@ -6627,19 +6749,13 @@ class App(QtCore.QObject):
else:
pos = (pos_canvas[0], pos_canvas[1])
+ self.ui.position_label.setText(" X: %.4f "
+ "Y: %.4f" % (pos[0], pos[1]))
+
self.dx = pos[0] - float(self.rel_point1[0])
self.dy = pos[1] - float(self.rel_point1[1])
-
- # self.ui.position_label.setText(" X: %.4f "
- # "Y: %.4f" % (pos[0], pos[1]))
- # self.ui.rel_position_label.setText("Dx: %.4f Dy: "
- # "%.4f " % (self.dx, self.dy))
-
- units = self.defaults["units"].lower()
- self.plotcanvas.text_hud.text = \
- 'Dx:\t{:<.4f} [{:s}]\nDy:\t{:<.4f} [{:s}]\nX: \t{:<.4f} [{:s}]\nY: \t{:<.4f} [{:s}]'.format(
- self.dx, units, self.dy, units, pos[0], units, pos[1], units)
-
+ self.ui.rel_position_label.setText("Dx: %.4f Dy: "
+ "%.4f " % (self.dx, self.dy))
self.mouse = [pos[0], pos[1]]
# if the mouse is moved and the LMB is clicked then the action is a selection
@@ -6688,10 +6804,9 @@ class App(QtCore.QObject):
# In this case poly_obj creation (see above) will fail
pass
- except Exception as e:
- log.debug("App.on_mouse_move_over_plot() - rel_point1 is not None -> %s" % str(e))
- # self.ui.position_label.setText("")
- # self.ui.rel_position_label.setText("")
+ except Exception:
+ self.ui.position_label.setText("")
+ self.ui.rel_position_label.setText("")
self.mouse = None
def on_mouse_click_release_over_plot(self, event):
@@ -10019,8 +10134,7 @@ class App(QtCore.QObject):
self.log.debug("version_check()")
-
- if self.defaults["global_send_stats"] is True:
+ if self.ui.general_defaults_form.general_app_group.send_stats_cb.get_value() is True:
full_url = "%s?s=%s&v=%s&os=%s&%s" % (
App.version_url,
str(self.defaults['global_serial']),
@@ -10359,9 +10473,10 @@ class App(QtCore.QObject):
alpha_level = 'BF'
for sel_obj in sel_obj_list:
if sel_obj.kind == 'excellon':
- alpha_level = self.defaults["excellon_plot_fill"][7:]
+ alpha_level = str(hex(
+ self.ui.excellon_defaults_form.excellon_gen_group.color_alpha_slider.value())[2:])
elif sel_obj.kind == 'gerber':
- alpha_level = self.defaults["gerber_plot_fill"][7:]
+ alpha_level = str(hex(self.ui.gerber_defaults_form.gerber_gen_group.pf_color_alpha_slider.value())[2:])
elif sel_obj.kind == 'geometry':
alpha_level = 'FF'
else:
diff --git a/FlatCAMCommon.py b/FlatCAMCommon.py
index bcd61a98..b95091aa 100644
--- a/FlatCAMCommon.py
+++ b/FlatCAMCommon.py
@@ -466,20 +466,15 @@ class ExclusionAreas(QtCore.QObject):
size=self.app.defaults["global_cursor_size"])
# update the positions on status bar
+ self.app.ui.position_label.setText(" X: %.4f "
+ "Y: %.4f" % (curr_pos[0], curr_pos[1]))
if self.cursor_pos is None:
self.cursor_pos = (0, 0)
self.app.dx = curr_pos[0] - float(self.cursor_pos[0])
self.app.dy = curr_pos[1] - float(self.cursor_pos[1])
- # self.app.ui.position_label.setText(" X: %.4f "
- # "Y: %.4f" % (curr_pos[0], curr_pos[1]))
- # self.app.ui.rel_position_label.setText("Dx: %.4f Dy: "
- # "%.4f " % (self.app.dx, self.app.dy))
-
- units = self.app.defaults["units"].lower()
- self.app.plotcanvas.text_hud.text = \
- 'Dx:\t{:<.4f} [{:s}]\nDy:\t{:<.4f} [{:s}]\nX: \t{:<.4f} [{:s}]\nY: \t{:<.4f} [{:s}]'.format(
- self.app.dx, units, self.app.dy, units, curr_pos[0], units, curr_pos[1], units)
+ self.app.ui.rel_position_label.setText("Dx: %.4f Dy: "
+ "%.4f " % (self.app.dx, self.app.dy))
if self.obj_type == 'excellon':
color = "#FF7400"
diff --git a/FlatCAMTranslation.py b/FlatCAMTranslation.py
index ddd376c7..82a8ac33 100644
--- a/FlatCAMTranslation.py
+++ b/FlatCAMTranslation.py
@@ -79,7 +79,7 @@ def on_language_apply_click(app, restart=False):
:return:
"""
- name = app.preferencesUiManager.get_form_field("global_language").currentText()
+ name = app.ui.general_defaults_form.general_app_group.language_cb.currentText()
theme_settings = QSettings("Open Source", "FlatCAM")
if theme_settings.contains("theme"):
diff --git a/Utils/vispy_example.py b/Utils/vispy_example.py
deleted file mode 100644
index a9eaee12..00000000
--- a/Utils/vispy_example.py
+++ /dev/null
@@ -1,195 +0,0 @@
-from PyQt5.QtGui import QPalette
-from PyQt5 import QtCore, QtWidgets
-
-import vispy.scene as scene
-from vispy.scene.visuals import Rectangle, Text
-from vispy.color import Color
-
-import sys
-
-
-class VisPyCanvas(scene.SceneCanvas):
-
- def __init__(self, config=None):
- super().__init__(config=config, keys=None)
-
- self.unfreeze()
-
- # Colors used by the Scene
- theme_color = Color('#FFFFFF')
- tick_color = Color('#000000')
- back_color = str(QPalette().color(QPalette.Window).name())
-
- # Central Widget Colors
- self.central_widget.bgcolor = back_color
- self.central_widget.border_color = back_color
-
- self.grid_widget = self.central_widget.add_grid(margin=10)
- self.grid_widget.spacing = 0
-
- # TOP Padding
- top_padding = self.grid_widget.add_widget(row=0, col=0, col_span=2)
- top_padding.height_max = 0
-
- # RIGHT Padding
- right_padding = self.grid_widget.add_widget(row=0, col=2, row_span=2)
- right_padding.width_max = 0
-
- # X Axis
- self.xaxis = scene.AxisWidget(
- orientation='bottom', axis_color=tick_color, text_color=tick_color,
- font_size=8, axis_width=1,
- anchors=['center', 'bottom']
- )
- self.xaxis.height_max = 30
- self.grid_widget.add_widget(self.xaxis, row=2, col=1)
-
- # Y Axis
- self.yaxis = scene.AxisWidget(
- orientation='left', axis_color=tick_color, text_color=tick_color,
- font_size=8, axis_width=1
- )
- self.yaxis.width_max = 55
- self.grid_widget.add_widget(self.yaxis, row=1, col=0)
-
- # View & Camera
- self.view = self.grid_widget.add_view(row=1, col=1, border_color=tick_color,
- bgcolor=theme_color)
- self.view.camera = scene.PanZoomCamera(aspect=1, rect=(-25, -25, 150, 150))
-
- self.xaxis.link_view(self.view)
- self.yaxis.link_view(self.view)
-
- self.grid = scene.GridLines(parent=self.view.scene, color='dimgray')
- self.grid.set_gl_state(depth_test=False)
-
- self.rect = Rectangle(center=(65,30), color=Color('#0000FF10'), border_color=Color('#0000FF10'),
- width=120, height=50, radius=[5, 5, 5, 5], parent=self.view)
- self.rect.set_gl_state(depth_test=False)
-
- self.text = Text('', parent=self.view, color='black', pos=(5, 30), method='gpu', anchor_x='left')
- self.text.font_size = 8
- self.text.text = 'Coordinates:\nX: %s\nY: %s' % ('0.0000', '0.0000')
-
- self.freeze()
-
- # self.measure_fps()
-
-
-class PlotCanvas(QtCore.QObject):
-
- def __init__(self, container, my_app):
- """
- The constructor configures the VisPy figure that
- will contain all plots, creates the base axes and connects
- events to the plotting area.
-
- :param container: The parent container in which to draw plots.
- :rtype: PlotCanvas
- """
-
- super().__init__()
-
- # VisPyCanvas instance
- self.vispy_canvas = VisPyCanvas()
-
- self.vispy_canvas.unfreeze()
-
- self.my_app = my_app
-
- # Parent container
- self.container = container
-
- #
- self.vispy_canvas.create_native()
- self.vispy_canvas.native.setParent(self.my_app.ui)
-
- #
- self.container.addWidget(self.vispy_canvas.native)
-
- # add two Infinite Lines to act as markers for the X,Y axis
- self.v_line = scene.visuals.InfiniteLine(
- pos=0, color=(0.0, 0.0, 1.0, 0.3), vertical=True,
- parent=self.vispy_canvas.view.scene)
-
- self.h_line = scene.visuals.InfiniteLine(
- pos=0, color=(0.00, 0.0, 1.0, 0.3), vertical=False,
- parent=self.vispy_canvas.view.scene)
-
- self.vispy_canvas.freeze()
-
- def event_connect(self, event, callback):
- getattr(self.vispy_canvas.events, event).connect(callback)
-
- def event_disconnect(self, event, callback):
- getattr(self.vispy_canvas.events, event).disconnect(callback)
-
- def translate_coords(self, pos):
- """
- Translate pixels to canvas units.
- """
- tr = self.vispy_canvas.grid.get_transform('canvas', 'visual')
- return tr.map(pos)
-
-
-class MyGui(QtWidgets.QMainWindow):
-
- def __init__(self):
- super().__init__()
-
- self.setWindowTitle("VisPy Test")
-
- # add Menubar
- self.menu = self.menuBar()
- self.menufile = self.menu.addMenu("File")
- self.menuedit = self.menu.addMenu("Edit")
- self.menufhelp = self.menu.addMenu("Help")
-
- # add a Toolbar
- self.file_toolbar = QtWidgets.QToolBar("File Toolbar")
- self.addToolBar(self.file_toolbar)
- self.button = self.file_toolbar.addAction("Open")
-
- # add Central Widget
- self.c_widget = QtWidgets.QWidget()
- self.central_layout = QtWidgets.QVBoxLayout()
- self.c_widget.setLayout(self.central_layout)
- self.setCentralWidget(self.c_widget)
-
- # add InfoBar
- # self.infobar = self.statusBar()
- # self.position_label = QtWidgets.QLabel("Position: X: 0.0000\tY: 0.0000")
- # self.infobar.addWidget(self.position_label)
-
-
-class MyApp(QtCore.QObject):
-
- def __init__(self):
- super().__init__()
-
- self.ui = MyGui()
- self.plot = PlotCanvas(container=self.ui.central_layout, my_app=self)
-
- self.ui.show()
-
- self.plot.event_connect(event="mouse_move", callback=self.on_mouse_move)
-
- def on_mouse_move(self, event):
- cursor_pos = event.pos
-
- pos_canvas = self.plot.translate_coords(cursor_pos)
-
- # we don't need all the info in the tuple returned by the translate_coords()
- # only first 2 elements
- pos_canvas = [pos_canvas[0], pos_canvas[1]]
- # self.ui.position_label.setText("Position: X: %.4f\tY: %.4f" % (pos_canvas[0], pos_canvas[1]))
- # pos_text = 'Coordinates: \nX: {:<7.4f}\nY: {:<7.4f}'.format(pos_canvas[0], pos_canvas[1])
- pos_text = 'Coordinates: \nX: {:<.4f}\nY: {:<.4f}'.format(pos_canvas[0], pos_canvas[1])
- self.plot.vispy_canvas.text.text = pos_text
-
-
-if __name__ == '__main__':
- app = QtWidgets.QApplication(sys.argv)
-
- m_app = MyApp()
- sys.exit(app.exec_())
diff --git a/defaults.py b/defaults.py
index 64f0fa70..b446a39a 100644
--- a/defaults.py
+++ b/defaults.py
@@ -43,7 +43,6 @@ class FlatCAMDefaults:
# General
"global_graphic_engine": '3D',
- "global_hud": True,
"global_app_level": 'b',
"global_portable": False,
"global_language": 'English',
diff --git a/flatcamEditors/FlatCAMExcEditor.py b/flatcamEditors/FlatCAMExcEditor.py
index 26666e0a..49dc5eb5 100644
--- a/flatcamEditors/FlatCAMExcEditor.py
+++ b/flatcamEditors/FlatCAMExcEditor.py
@@ -2119,7 +2119,7 @@ class FlatCAMExcEditor(QtCore.QObject):
if self.app.is_legacy is False:
self.shapes = self.app.plotcanvas.new_shape_collection(layers=1)
if self.app.plotcanvas.big_cursor is True:
- self.tool_shape = self.app.plotcanvas.new_shape_collection(layers=1)
+ self.tool_shape = self.app.plotcanvas.new_shape_collection(layers=1, line_width=2)
else:
self.tool_shape = self.app.plotcanvas.new_shape_collection(layers=1)
else:
@@ -3801,22 +3801,18 @@ class FlatCAMExcEditor(QtCore.QObject):
self.snap_x = x
self.snap_y = y
+ # update the position label in the infobar since the APP mouse event handlers are disconnected
+ self.app.ui.position_label.setText(" X: %.4f "
+ "Y: %.4f" % (x, y))
+
if self.pos is None:
self.pos = (0, 0)
self.app.dx = x - self.pos[0]
self.app.dy = y - self.pos[1]
- # # update the position label in the infobar since the APP mouse event handlers are disconnected
- # self.app.ui.position_label.setText(" X: %.4f "
- # "Y: %.4f" % (x, y))
- # # update the reference position label in the infobar since the APP mouse event handlers are disconnected
- # self.app.ui.rel_position_label.setText("Dx: %.4f Dy: "
- # "%.4f " % (self.app.dx, self.app.dy))
-
- units = self.app.defaults["units"].lower()
- self.plotcanvas.text_hud.text = \
- 'Dx:\t{:<.4f} [{:s}]\nDy:\t{:<.4f} [{:s}]\nX: \t{:<.4f} [{:s}]\nY: \t{:<.4f} [{:s}]'.format(
- self.app.dx, units, self.app.dy, units, x, units, y, units)
+ # update the reference position label in the infobar since the APP mouse event handlers are disconnected
+ self.app.ui.rel_position_label.setText("Dx: %.4f Dy: "
+ "%.4f " % (self.app.dx, self.app.dy))
# ## Utility geometry (animated)
self.update_utility_geometry(data=(x, y))
diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py
index e8d969cb..ccf67ce4 100644
--- a/flatcamEditors/FlatCAMGeoEditor.py
+++ b/flatcamEditors/FlatCAMGeoEditor.py
@@ -3467,32 +3467,22 @@ class FlatCAMGeoEditor(QtCore.QObject):
:return:
"""
try:
- text_value = entry.text()
- if ',' in text_value:
- text_value = text_value.replace(',', '.')
- self.options[opt] = float(text_value)
+ self.options[opt] = float(entry.text())
except Exception as e:
- entry.set_value(self.app.defaults[opt])
log.debug("FlatCAMGeoEditor.__init__().entry2option() --> %s" % str(e))
return
- def grid_changed(goption, gentry):
+ def gridx_changed(goption, gentry):
"""
- :param goption: String. Can be either 'global_gridx' or 'global_gridy'
- :param gentry: A GUI element which text value is read and used
+ :param goption: String. Can be either 'global_gridx' or 'global_gridy'
+ :param gentry: A GUI element which text value is read and used
:return:
"""
- if goption not in ['global_gridx', 'global_gridy']:
- return
-
entry2option(opt=goption, entry=gentry)
# if the grid link is checked copy the value in the GridX field to GridY
try:
- text_value = gentry.text()
- if ',' in text_value:
- text_value = text_value.replace(',', '.')
- val = float(text_value)
+ val = float(gentry.get_value())
except ValueError:
return
@@ -3501,7 +3491,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
self.app.ui.grid_gap_x_entry.setValidator(QtGui.QDoubleValidator())
self.app.ui.grid_gap_x_entry.textChanged.connect(
- lambda: grid_changed("global_gridx", self.app.ui.grid_gap_x_entry))
+ lambda: gridx_changed("global_gridx", self.app.ui.grid_gap_x_entry))
self.app.ui.grid_gap_y_entry.setValidator(QtGui.QDoubleValidator())
self.app.ui.grid_gap_y_entry.textChanged.connect(
@@ -4271,23 +4261,18 @@ class FlatCAMGeoEditor(QtCore.QObject):
self.snap_y = y
self.app.mouse = [x, y]
+ # update the position label in the infobar since the APP mouse event handlers are disconnected
+ self.app.ui.position_label.setText(" X: %.4f "
+ "Y: %.4f" % (x, y))
+
if self.pos is None:
self.pos = (0, 0)
self.app.dx = x - self.pos[0]
self.app.dy = y - self.pos[1]
- # # update the position label in the infobar since the APP mouse event handlers are disconnected
- # self.app.ui.position_label.setText(" X: %.4f "
- # "Y: %.4f" % (x, y))
- #
- # # update the reference position label in the infobar since the APP mouse event handlers are disconnected
- # self.app.ui.rel_position_label.setText("Dx: %.4f Dy: "
- # "%.4f " % (self.app.dx, self.app.dy))
-
- units = self.app.defaults["units"].lower()
- self.plotcanvas.text_hud.text = \
- 'Dx:\t{:<.4f} [{:s}]\nDy:\t{:<.4f} [{:s}]\nX: \t{:<.4f} [{:s}]\nY: \t{:<.4f} [{:s}]'.format(
- self.app.dx, units, self.app.dy, units, x, units, y, units)
+ # update the reference position label in the infobar since the APP mouse event handlers are disconnected
+ self.app.ui.rel_position_label.setText("Dx: %.4f Dy: "
+ "%.4f " % (self.app.dx, self.app.dy))
if event.button == 1 and event_is_dragging and isinstance(self.active_tool, FCEraser):
pass
diff --git a/flatcamEditors/FlatCAMGrbEditor.py b/flatcamEditors/FlatCAMGrbEditor.py
index d5659fbf..3362c5ba 100644
--- a/flatcamEditors/FlatCAMGrbEditor.py
+++ b/flatcamEditors/FlatCAMGrbEditor.py
@@ -4774,23 +4774,18 @@ class FlatCAMGrbEditor(QtCore.QObject):
self.app.mouse = [x, y]
+ # update the position label in the infobar since the APP mouse event handlers are disconnected
+ self.app.ui.position_label.setText(" X: %.4f "
+ "Y: %.4f" % (x, y))
+
if self.pos is None:
self.pos = (0, 0)
self.app.dx = x - self.pos[0]
self.app.dy = y - self.pos[1]
- # # update the position label in the infobar since the APP mouse event handlers are disconnected
- # self.app.ui.position_label.setText(" X: %.4f "
- # "Y: %.4f" % (x, y))
- #
- # # update the reference position label in the infobar since the APP mouse event handlers are disconnected
- # self.app.ui.rel_position_label.setText("Dx: %.4f Dy: "
- # "%.4f " % (self.app.dx, self.app.dy))
-
- units = self.app.defaults["units"].lower()
- self.plotcanvas.text_hud.text = \
- 'Dx:\t{:<.4f} [{:s}]\nDy:\t{:<.4f} [{:s}]\nX: \t{:<.4f} [{:s}]\nY: \t{:<.4f} [{:s}]'.format(
- self.app.dx, units, self.app.dy, units, x, units, y, units)
+ # update the reference position label in the infobar since the APP mouse event handlers are disconnected
+ self.app.ui.rel_position_label.setText("Dx: %.4f Dy: "
+ "%.4f " % (self.app.dx, self.app.dy))
self.update_utility_geometry(data=(x, y))
diff --git a/flatcamGUI/ColumnarFlowLayout.py b/flatcamGUI/ColumnarFlowLayout.py
deleted file mode 100644
index 753c070b..00000000
--- a/flatcamGUI/ColumnarFlowLayout.py
+++ /dev/null
@@ -1,174 +0,0 @@
-import sys
-
-from PyQt5.QtCore import QPoint, QRect, QSize, Qt
-from PyQt5.QtWidgets import QLayout, QSizePolicy
-import math
-
-class ColumnarFlowLayout(QLayout):
- def __init__(self, parent=None, margin=0, spacing=-1):
- super().__init__(parent)
-
- if parent is not None:
- self.setContentsMargins(margin, margin, margin, margin)
-
- self.setSpacing(spacing)
- self.itemList = []
-
- def __del__(self):
- item = self.takeAt(0)
- while item:
- item = self.takeAt(0)
-
- def addItem(self, item):
- self.itemList.append(item)
-
- def count(self):
- return len(self.itemList)
-
- def itemAt(self, index):
- if 0 <= index < len(self.itemList):
- return self.itemList[index]
- return None
-
- def takeAt(self, index):
- if 0 <= index < len(self.itemList):
- return self.itemList.pop(index)
- return None
-
- def expandingDirections(self):
- return Qt.Orientations(Qt.Orientation(0))
-
- def hasHeightForWidth(self):
- return True
-
- def heightForWidth(self, width):
- height = self.doLayout(QRect(0, 0, width, 0), True)
- return height
-
- def setGeometry(self, rect):
- super().setGeometry(rect)
- self.doLayout(rect, False)
-
- def sizeHint(self):
- return self.minimumSize()
-
- def minimumSize(self):
- size = QSize()
-
- for item in self.itemList:
- size = size.expandedTo(item.minimumSize())
-
- margin, _, _, _ = self.getContentsMargins()
-
- size += QSize(2 * margin, 2 * margin)
- return size
-
- def doLayout(self, rect: QRect, testOnly: bool) -> int:
- spacing = self.spacing()
- x = rect.x()
- y = rect.y()
-
- # Determine width of widest item
- widest = 0
- for item in self.itemList:
- widest = max(widest, item.sizeHint().width())
-
- # Determine how many equal-width columns we can get, and how wide each one should be
- column_count = math.floor(rect.width() / (widest + spacing))
- column_count = min(column_count, len(self.itemList))
- column_count = max(1, column_count)
- column_width = math.floor((rect.width() - (column_count-1)*spacing - 1) / column_count)
-
- # Get the heights for all of our items
- item_heights = {}
- for item in self.itemList:
- height = item.heightForWidth(column_width) if item.hasHeightForWidth() else item.sizeHint().height()
- item_heights[item] = height
-
- # Prepare our column representation
- column_contents = []
- column_heights = []
- for column_index in range(column_count):
- column_contents.append([])
- column_heights.append(0)
-
- def add_to_column(column: int, item):
- column_contents[column].append(item)
- column_heights[column] += (item_heights[item] + spacing)
-
- def shove_one(from_column: int) -> bool:
- if len(column_contents[from_column]) >= 1:
- item = column_contents[from_column].pop(0)
- column_heights[from_column] -= (item_heights[item] + spacing)
- add_to_column(from_column-1, item)
- return True
- return False
-
- def shove_cascade_consider(from_column: int) -> bool:
- changed = False
-
- if len(column_contents[from_column]) > 1:
- item = column_contents[from_column][0]
- item_height = item_heights[item]
- if column_heights[from_column-1] + item_height < max(column_heights):
- changed = shove_one(from_column) or changed
-
- if from_column+1 < column_count:
- changed = shove_cascade_consider(from_column+1) or changed
-
- return changed
-
- def shove_cascade() -> bool:
- if column_count < 2:
- return False
- changed = True
- while changed:
- changed = shove_cascade_consider(1)
- return changed
-
- def pick_best_shoving_position() -> int:
- best_pos = 1
- best_height = sys.maxsize
- for column_index in range(1, column_count):
- if len(column_contents[column_index]) == 0:
- continue
- item = column_contents[column_index][0]
- height_after_shove = column_heights[column_index-1] + item_heights[item]
- if height_after_shove < best_height:
- best_height = height_after_shove
- best_pos = column_index
- return best_pos
-
- # Calculate the best layout
- column_index = 0
- for item in self.itemList:
- item_height = item_heights[item]
- if column_heights[column_index] != 0 and (column_heights[column_index] + item_height) > max(column_heights):
- column_index += 1
- if column_index >= column_count:
- # Run out of room, need to shove more stuff in each column
- if column_count >= 2:
- changed = shove_cascade()
- if not changed:
- shoving_pos = pick_best_shoving_position()
- shove_one(shoving_pos)
- shove_cascade()
- column_index = column_count-1
-
- add_to_column(column_index, item)
-
- shove_cascade()
-
- # Set geometry according to the layout we have calculated
- if not testOnly:
- for column_index, items in enumerate(column_contents):
- x = column_index * (column_width + spacing)
- y = 0
- for item in items:
- height = item_heights[item]
- item.setGeometry(QRect(x, y, column_width, height))
- y += (height + spacing)
-
- # Return the overall height
- return max(column_heights)
-
diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py
index deda0428..09d7383b 100644
--- a/flatcamGUI/FlatCAMGUI.py
+++ b/flatcamGUI/FlatCAMGUI.py
@@ -1207,6 +1207,89 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
self.pref_tab_area_tabBar.setExpanding(True)
self.pref_tab_layout.addWidget(self.pref_tab_area)
+ self.general_tab = QtWidgets.QWidget()
+ self.general_tab.setObjectName("general_tab")
+ self.pref_tab_area.addTab(self.general_tab, _("General"))
+ self.general_tab_lay = QtWidgets.QVBoxLayout()
+ self.general_tab_lay.setContentsMargins(2, 2, 2, 2)
+ self.general_tab.setLayout(self.general_tab_lay)
+
+ self.hlay1 = QtWidgets.QHBoxLayout()
+ self.general_tab_lay.addLayout(self.hlay1)
+
+ self.hlay1.addStretch()
+
+ self.general_scroll_area = QtWidgets.QScrollArea()
+ self.general_tab_lay.addWidget(self.general_scroll_area)
+
+ self.gerber_tab = QtWidgets.QWidget()
+ self.gerber_tab.setObjectName("gerber_tab")
+ self.pref_tab_area.addTab(self.gerber_tab, _("GERBER"))
+ self.gerber_tab_lay = QtWidgets.QVBoxLayout()
+ self.gerber_tab_lay.setContentsMargins(2, 2, 2, 2)
+ self.gerber_tab.setLayout(self.gerber_tab_lay)
+
+ self.gerber_scroll_area = QtWidgets.QScrollArea()
+ self.gerber_tab_lay.addWidget(self.gerber_scroll_area)
+
+ self.excellon_tab = QtWidgets.QWidget()
+ self.excellon_tab.setObjectName("excellon_tab")
+ self.pref_tab_area.addTab(self.excellon_tab, _("EXCELLON"))
+ self.excellon_tab_lay = QtWidgets.QVBoxLayout()
+ self.excellon_tab_lay.setContentsMargins(2, 2, 2, 2)
+ self.excellon_tab.setLayout(self.excellon_tab_lay)
+
+ self.excellon_scroll_area = QtWidgets.QScrollArea()
+ self.excellon_tab_lay.addWidget(self.excellon_scroll_area)
+
+ self.geometry_tab = QtWidgets.QWidget()
+ self.geometry_tab.setObjectName("geometry_tab")
+ self.pref_tab_area.addTab(self.geometry_tab, _("GEOMETRY"))
+ self.geometry_tab_lay = QtWidgets.QVBoxLayout()
+ self.geometry_tab_lay.setContentsMargins(2, 2, 2, 2)
+ self.geometry_tab.setLayout(self.geometry_tab_lay)
+
+ self.geometry_scroll_area = QtWidgets.QScrollArea()
+ self.geometry_tab_lay.addWidget(self.geometry_scroll_area)
+
+ 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.text_editor_tab.setLayout(self.cncjob_tab_lay)
+
+ self.cncjob_scroll_area = QtWidgets.QScrollArea()
+ self.cncjob_tab_lay.addWidget(self.cncjob_scroll_area)
+
+ self.tools_tab = QtWidgets.QWidget()
+ self.pref_tab_area.addTab(self.tools_tab, _("TOOLS"))
+ self.tools_tab_lay = QtWidgets.QVBoxLayout()
+ self.tools_tab_lay.setContentsMargins(2, 2, 2, 2)
+ self.tools_tab.setLayout(self.tools_tab_lay)
+
+ self.tools_scroll_area = QtWidgets.QScrollArea()
+ self.tools_tab_lay.addWidget(self.tools_scroll_area)
+
+ self.tools2_tab = QtWidgets.QWidget()
+ self.pref_tab_area.addTab(self.tools2_tab, _("TOOLS 2"))
+ self.tools2_tab_lay = QtWidgets.QVBoxLayout()
+ self.tools2_tab_lay.setContentsMargins(2, 2, 2, 2)
+ self.tools2_tab.setLayout(self.tools2_tab_lay)
+
+ self.tools2_scroll_area = QtWidgets.QScrollArea()
+ self.tools2_tab_lay.addWidget(self.tools2_scroll_area)
+
+ self.fa_tab = QtWidgets.QWidget()
+ self.fa_tab.setObjectName("fa_tab")
+ self.pref_tab_area.addTab(self.fa_tab, _("UTILITIES"))
+ self.fa_tab_lay = QtWidgets.QVBoxLayout()
+ self.fa_tab_lay.setContentsMargins(2, 2, 2, 2)
+ self.fa_tab.setLayout(self.fa_tab_lay)
+
+ self.fa_scroll_area = QtWidgets.QScrollArea()
+ self.fa_tab_lay.addWidget(self.fa_scroll_area)
+
self.pref_tab_bottom_layout = QtWidgets.QHBoxLayout()
self.pref_tab_bottom_layout.setAlignment(QtCore.Qt.AlignVCenter)
self.pref_tab_layout.addLayout(self.pref_tab_bottom_layout)
@@ -2223,17 +2306,17 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
self.snap_infobar_label.setPixmap(QtGui.QPixmap(self.app.resource_location + '/snap_16.png'))
self.infobar.addWidget(self.snap_infobar_label)
- # self.rel_position_label = QtWidgets.QLabel(
- # "Dx: 0.0000 Dy: 0.0000 ")
- # self.rel_position_label.setMinimumWidth(110)
- # self.rel_position_label.setToolTip(_("Relative measurement.\nReference is last click position"))
- # self.infobar.addWidget(self.rel_position_label)
- #
- # self.position_label = QtWidgets.QLabel(
- # " X: 0.0000 Y: 0.0000")
- # self.position_label.setMinimumWidth(110)
- # self.position_label.setToolTip(_("Absolute measurement.\nReference is (X=0, Y= 0) position"))
- # self.infobar.addWidget(self.position_label)
+ self.rel_position_label = QtWidgets.QLabel(
+ "Dx: 0.0000 Dy: 0.0000 ")
+ self.rel_position_label.setMinimumWidth(110)
+ self.rel_position_label.setToolTip(_("Relative measurement.\nReference is last click position"))
+ self.infobar.addWidget(self.rel_position_label)
+
+ self.position_label = QtWidgets.QLabel(
+ " X: 0.0000 Y: 0.0000")
+ self.position_label.setMinimumWidth(110)
+ self.position_label.setToolTip(_("Absolute measurement.\nReference is (X=0, Y= 0) position"))
+ self.infobar.addWidget(self.position_label)
self.units_label = QtWidgets.QLabel("[in]")
self.units_label.setMargin(2)
@@ -2910,11 +2993,6 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
if key == QtCore.Qt.Key_G:
self.app.on_toggle_axis()
- # Toggle HUD (Heads-Up Display)
- if key == QtCore.Qt.Key_H:
- state = False if self.app.plotcanvas.hud_enabled else True
- self.app.plotcanvas.on_toggle_hud(state=state)
-
# Locate in Object
if key == QtCore.Qt.Key_J:
self.app.on_locate(obj=self.app.collection.get_active())
@@ -3984,7 +4062,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
if key == QtCore.Qt.Key_T or key == 'T':
self.app.exc_editor.launched_from_shortcuts = True
# ## Current application units in Upper Case
- self.units = self.general_defaults_form.option_dict()["units"].get_field().get_value().upper()
+ self.units = self.general_defaults_form.general_app_group.units_radio.get_value().upper()
tool_add_popup = FCInputDialog(title=_("New Tool ..."),
text='%s:' % _('Enter a Tool Diameter'),
min=0.0000, max=99.9999, decimals=4)
@@ -4202,153 +4280,6 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
self.final_save.emit()
event.ignore()
- def set_layout(self, layout: str):
- """
- Set the toolbars layout (location)
-
- :param index:
- :param lay: Type of layout to be set on the toolbard
- :return: None
- """
-
- self.app.defaults.report_usage("on_layout()")
-
- lay_settings = QSettings("Open Source", "FlatCAM")
- lay_settings.setValue('layout', layout)
- # This will write the setting to the platform specific storage.
- del lay_settings
-
- # first remove the toolbars:
- try:
- self.removeToolBar(self.app.ui.toolbarfile)
- self.removeToolBar(self.app.ui.toolbargeo)
- self.removeToolBar(self.app.ui.toolbarview)
- self.removeToolBar(self.app.ui.toolbarshell)
- self.removeToolBar(self.app.ui.toolbartools)
- self.removeToolBar(self.app.ui.exc_edit_toolbar)
- self.removeToolBar(self.app.ui.geo_edit_toolbar)
- self.removeToolBar(self.app.ui.grb_edit_toolbar)
- self.removeToolBar(self.app.ui.snap_toolbar)
- self.removeToolBar(self.app.ui.toolbarshell)
- except Exception:
- pass
-
- if layout == 'compact':
- # ## TOOLBAR INSTALLATION # ##
- self.toolbarfile = QtWidgets.QToolBar('File Toolbar')
- self.toolbarfile.setObjectName('File_TB')
- self.addToolBar(Qt.LeftToolBarArea, self.app.ui.toolbarfile)
-
- self.toolbargeo = QtWidgets.QToolBar('Edit Toolbar')
- self.toolbargeo.setObjectName('Edit_TB')
- self.addToolBar(Qt.LeftToolBarArea, self.app.ui.toolbargeo)
-
- self.toolbarshell = QtWidgets.QToolBar('Shell Toolbar')
- self.toolbarshell.setObjectName('Shell_TB')
- self.addToolBar(Qt.LeftToolBarArea, self.app.ui.toolbarshell)
-
- self.toolbartools = QtWidgets.QToolBar('Tools Toolbar')
- self.toolbartools.setObjectName('Tools_TB')
- self.addToolBar(Qt.LeftToolBarArea, self.app.ui.toolbartools)
-
- self.geo_edit_toolbar = QtWidgets.QToolBar('Geometry Editor Toolbar')
- # self.geo_edit_toolbar.setVisible(False)
- self.geo_edit_toolbar.setObjectName('GeoEditor_TB')
- self.addToolBar(Qt.RightToolBarArea, self.app.ui.geo_edit_toolbar)
-
- self.toolbarview = QtWidgets.QToolBar('View Toolbar')
- self.toolbarview.setObjectName('View_TB')
- self.addToolBar(Qt.RightToolBarArea, self.app.ui.toolbarview)
-
- self.addToolBarBreak(area=Qt.RightToolBarArea)
-
- self.grb_edit_toolbar = QtWidgets.QToolBar('Gerber Editor Toolbar')
- # self.grb_edit_toolbar.setVisible(False)
- self.grb_edit_toolbar.setObjectName('GrbEditor_TB')
- self.addToolBar(Qt.RightToolBarArea, self.app.ui.grb_edit_toolbar)
-
- self.exc_edit_toolbar = QtWidgets.QToolBar('Excellon Editor Toolbar')
- self.exc_edit_toolbar.setObjectName('ExcEditor_TB')
- self.addToolBar(Qt.RightToolBarArea, self.app.ui.exc_edit_toolbar)
-
- self.snap_toolbar = QtWidgets.QToolBar('Grid Toolbar')
- self.snap_toolbar.setObjectName('Snap_TB')
- self.snap_toolbar.setMaximumHeight(30)
- self.splitter_left.addWidget(self.app.ui.snap_toolbar)
-
- self.corner_snap_btn.setVisible(True)
- self.snap_magnet.setVisible(True)
- else:
- # ## TOOLBAR INSTALLATION # ##
- self.toolbarfile = QtWidgets.QToolBar('File Toolbar')
- self.toolbarfile.setObjectName('File_TB')
- self.addToolBar(self.app.ui.toolbarfile)
-
- self.toolbargeo = QtWidgets.QToolBar('Edit Toolbar')
- self.toolbargeo.setObjectName('Edit_TB')
- self.addToolBar(self.app.ui.toolbargeo)
-
- self.toolbarview = QtWidgets.QToolBar('View Toolbar')
- self.toolbarview.setObjectName('View_TB')
- self.addToolBar(self.app.ui.toolbarview)
-
- self.toolbarshell = QtWidgets.QToolBar('Shell Toolbar')
- self.toolbarshell.setObjectName('Shell_TB')
- self.addToolBar(self.app.ui.toolbarshell)
-
- self.toolbartools = QtWidgets.QToolBar('Tools Toolbar')
- self.toolbartools.setObjectName('Tools_TB')
- self.addToolBar(self.app.ui.toolbartools)
-
- self.exc_edit_toolbar = QtWidgets.QToolBar('Excellon Editor Toolbar')
- # self.exc_edit_toolbar.setVisible(False)
- self.exc_edit_toolbar.setObjectName('ExcEditor_TB')
- self.addToolBar(self.app.ui.exc_edit_toolbar)
-
- self.addToolBarBreak()
-
- self.geo_edit_toolbar = QtWidgets.QToolBar('Geometry Editor Toolbar')
- # self.geo_edit_toolbar.setVisible(False)
- self.geo_edit_toolbar.setObjectName('GeoEditor_TB')
- self.addToolBar(self.app.ui.geo_edit_toolbar)
-
- self.grb_edit_toolbar = QtWidgets.QToolBar('Gerber Editor Toolbar')
- # self.grb_edit_toolbar.setVisible(False)
- self.grb_edit_toolbar.setObjectName('GrbEditor_TB')
- self.addToolBar(self.app.ui.grb_edit_toolbar)
-
- self.snap_toolbar = QtWidgets.QToolBar('Grid Toolbar')
- self.snap_toolbar.setObjectName('Snap_TB')
- # self.snap_toolbar.setMaximumHeight(30)
- self.addToolBar(self.app.ui.snap_toolbar)
-
- self.corner_snap_btn.setVisible(False)
- self.snap_magnet.setVisible(False)
-
- if layout == 'minimal':
- self.toolbarview.setVisible(False)
- self.toolbarshell.setVisible(False)
- self.snap_toolbar.setVisible(False)
- self.geo_edit_toolbar.setVisible(False)
- self.grb_edit_toolbar.setVisible(False)
- self.exc_edit_toolbar.setVisible(False)
- self.lock_toolbar(lock=True)
-
- # add all the actions to the toolbars
- self.populate_toolbars()
-
- # reconnect all the signals to the toolbar actions
- self.app.connect_toolbar_signals()
-
- self.grid_snap_btn.setChecked(True)
- self.on_grid_snap_triggered(state=True)
-
- self.grid_gap_x_entry.setText(str(self.app.defaults["global_gridx"]))
- self.grid_gap_y_entry.setText(str(self.app.defaults["global_gridy"]))
- self.snap_max_dist_entry.setText(str(self.app.defaults["global_snap_max"]))
- self.grid_gap_link_cb.setChecked(True)
-
-
class FlatCAMActivityView(QtWidgets.QWidget):
"""
diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py
index d048a022..7b9b38f4 100644
--- a/flatcamGUI/GUIElements.py
+++ b/flatcamGUI/GUIElements.py
@@ -656,104 +656,6 @@ class EvalEntry2(QtWidgets.QLineEdit):
return QtCore.QSize(EDIT_SIZE_HINT, default_hint_size.height())
-class FCColorEntry(QtWidgets.QFrame):
-
- def __init__(self, **kwargs):
- super().__init__(**kwargs)
-
- self.entry = FCEntry()
-
- self.button = QtWidgets.QPushButton()
- self.button.setFixedSize(15, 15)
- self.button.setStyleSheet("border-color: dimgray;")
-
- self.layout = QtWidgets.QHBoxLayout()
- self.layout.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
- self.layout.setContentsMargins(0, 0, 0, 0)
- self.layout.addWidget(self.entry)
- self.layout.addWidget(self.button)
- self.setLayout(self.layout)
-
- self.entry.editingFinished.connect(self._sync_button_color)
- self.button.clicked.connect(self._on_button_clicked)
-
-
- def get_value(self) -> str:
- return self.entry.get_value()
-
- def set_value(self, value: str):
- self.entry.set_value(value)
- self._sync_button_color()
-
- def _sync_button_color(self):
- value = self.get_value()
- self.button.setStyleSheet("background-color:%s;" % self._extract_color(value))
-
- def _on_button_clicked(self):
- value = self.entry.get_value()
- current_color = QtGui.QColor(self._extract_color(value))
-
- color_dialog = QtWidgets.QColorDialog()
- selected_color = color_dialog.getColor(initial=current_color, options=QtWidgets.QColorDialog.ShowAlphaChannel)
-
- if selected_color.isValid() is False:
- return
-
- new_value = str(selected_color.name()) + self._extract_alpha(value)
- self.set_value(new_value)
-
- def _extract_color(self, value: str) -> str:
- return value[:7]
-
- def _extract_alpha(self, value: str) -> str:
- return value[7:9]
-
-
-class FCSliderWithSpinner(QtWidgets.QFrame):
-
- def __init__(self, min=0, max=100, step=1, **kwargs):
- super().__init__(**kwargs)
-
- self.slider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
- self.slider.setMinimum(min)
- self.slider.setMaximum(max)
- self.slider.setSingleStep(step)
-
- self.spinner = FCSpinner()
- self.spinner.set_range(min, max)
- self.spinner.set_step(step)
- self.spinner.setMinimumWidth(70)
-
- self.layout = QtWidgets.QHBoxLayout()
- self.layout.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
- self.layout.setContentsMargins(0, 0, 0, 0)
- self.layout.addWidget(self.slider)
- self.layout.addWidget(self.spinner)
- self.setLayout(self.layout)
-
- self.slider.valueChanged.connect(self._on_slider)
- self.spinner.valueChanged.connect(self._on_spinner)
-
- self.valueChanged = self.spinner.valueChanged
-
- def get_value(self) -> int:
- return self.spinner.get_value()
-
- def set_value(self, value: int):
- self.spinner.set_value(value)
-
- def _on_spinner(self):
- spinner_value = self.spinner.value()
- self.slider.setValue(spinner_value)
-
- def _on_slider(self):
- slider_value = self.slider.value()
- self.spinner.set_value(slider_value)
-
-
-
-
-
class FCSpinner(QtWidgets.QSpinBox):
returnPressed = QtCore.pyqtSignal()
diff --git a/flatcamGUI/PlotCanvas.py b/flatcamGUI/PlotCanvas.py
index a1be6099..44af74d0 100644
--- a/flatcamGUI/PlotCanvas.py
+++ b/flatcamGUI/PlotCanvas.py
@@ -10,7 +10,7 @@ from PyQt5 import QtCore
import logging
from flatcamGUI.VisPyCanvas import VisPyCanvas, Color
from flatcamGUI.VisPyVisuals import ShapeGroup, ShapeCollection, TextCollection, TextGroup, Cursor
-from vispy.scene.visuals import InfiniteLine, Line, Rectangle, Text
+from vispy.scene.visuals import InfiniteLine, Line
import numpy as np
from vispy.geometry import Rect
@@ -54,12 +54,8 @@ class PlotCanvas(QtCore.QObject, VisPyCanvas):
if theme == 'white':
self.line_color = (0.3, 0.0, 0.0, 1.0)
- self.rect_hud_color = Color('#0000FF10')
- self.text_hud_color = 'black'
else:
self.line_color = (0.4, 0.4, 0.4, 1.0)
- self.rect_hud_color = Color('#0000FF10')
- self.text_hud_color = 'white'
# workspace lines; I didn't use the rectangle because I didn't want to add another VisPy Node,
# which might decrease performance
@@ -150,28 +146,13 @@ class PlotCanvas(QtCore.QObject, VisPyCanvas):
self.cursor_h_line = InfiniteLine(pos=None, color=c_color, vertical=False,
parent=self.line_parent)
- self.rect_hud = Rectangle(center=(90,45), color=self.rect_hud_color, border_color=self.rect_hud_color,
- width=170, height=80, radius=[5, 5, 5, 5], parent=None)
- self.rect_hud.set_gl_state(depth_test=False)
-
- # HUD Display
- self.hud_enabled = False
-
- self.text_hud = Text('', color=self.text_hud_color, pos=(8, 45), method='gpu', anchor_x='left', parent=None)
- self.text_hud.font_size = 8
- units = self.fcapp.defaults["units"].lower()
- self.text_hud.text = 'Dx:\t%s [%s]\nDy:\t%s [%s]\nX: \t%s [%s]\nY: \t%s [%s]' % \
- ('0.0000', units, '0.0000', units, '0.0000', units, '0.0000', units)
-
- if self.fcapp.defaults['global_hud'] is True:
- self.on_toggle_hud(state=True)
-
self.shape_collections = []
self.shape_collection = self.new_shape_collection()
self.fcapp.pool_recreated.connect(self.on_pool_recreated)
self.text_collection = self.new_text_collection()
+ # TODO: Should be setting to show/hide CNC job annotations (global or per object)
self.text_collection.enabled = True
self.c = None
@@ -182,16 +163,6 @@ class PlotCanvas(QtCore.QObject, VisPyCanvas):
self.graph_event_connect('mouse_wheel', self.on_mouse_scroll)
- def on_toggle_hud(self, state):
- if state:
- self.hud_enabled = True
- self.rect_hud.parent = self.view
- self.text_hud.parent = self.view
- else:
- self.hud_enabled = False
- self.rect_hud.parent = None
- self.text_hud.parent = None
-
def draw_workspace(self, workspace_size):
"""
Draw a rectangular shape on canvas to specify our valid workspace.
diff --git a/flatcamGUI/PlotCanvasLegacy.py b/flatcamGUI/PlotCanvasLegacy.py
index 7856bb8f..a9a6216f 100644
--- a/flatcamGUI/PlotCanvasLegacy.py
+++ b/flatcamGUI/PlotCanvasLegacy.py
@@ -29,7 +29,6 @@ mpl_use("Qt5Agg")
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.lines import Line2D
-from matplotlib.offsetbox import AnchoredText
# from matplotlib.widgets import Cursor
fcTranslate.apply_language('strings')
@@ -148,13 +147,9 @@ class PlotCanvasLegacy(QtCore.QObject):
if self.app.defaults['global_theme'] == 'white':
theme_color = '#FFFFFF'
tick_color = '#000000'
- self.rect_hud_color = '#0000FF10'
- self.text_hud_color = '#000000'
else:
theme_color = '#000000'
tick_color = '#FFFFFF'
- self.rect_hud_color = '#0000FF10'
- self.text_hud_color = '#000000'
# workspace lines; I didn't use the rectangle because I didn't want to add another VisPy Node,
# which might decrease performance
@@ -303,79 +298,11 @@ class PlotCanvasLegacy(QtCore.QObject):
# signal if there is a doubleclick
self.is_dblclk = False
- self.hud_enabled = False
- self.text_hud = self.Thud(plotcanvas=self)
-
- # bbox_props = dict(boxstyle="round,pad=0.3", fc="blue", ec="b", lw=0)
- # self.text_hud = self.figure.text(0, 0, "Direction", ha="left", va="center", rotation=0,
- # size=15,
- # bbox=bbox_props)
-
# draw a rectangle made out of 4 lines on the canvas to serve as a hint for the work area
# all CNC have a limited workspace
if self.app.defaults['global_workspace'] is True:
self.draw_workspace(workspace_size=self.app.defaults["global_workspaceT"])
- if self.app.defaults['global_hud'] is True:
- self.on_toggle_hud(state=True)
-
- def on_toggle_hud(self, state):
- if state:
- self.hud_enabled = True
- self.text_hud.add_artist()
- else:
- self.hud_enabled = False
- self.text_hud.remove_artist()
- self.canvas.draw()
-
- class Thud(QtCore.QObject):
- text_changed = QtCore.pyqtSignal(str)
-
- def __init__(self, plotcanvas):
- super().__init__()
-
- self.p = plotcanvas
- units = self.p.app.defaults['units']
- self._text = 'Dx: %s [%s]\nDy: %s [%s]\nX: %s [%s]\nY: %s [%s]' % \
- ('0.0000', units, '0.0000', units, '0.0000', units, '0.0000', units)
-
- self.hud_holder = AnchoredText(self._text,
- prop=dict(size=20), frameon=True,
- loc='upper left',
- )
- self.hud_holder.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
-
- self.hud_holder.patch.set_facecolor('blue')
- self.hud_holder.patch.set_alpha(0.3)
- self.hud_holder.patch.set_edgecolor((0, 0, 0, 0))
-
- self.text_changed.connect(self.on_text_changed)
-
- @property
- def text(self):
- return self._text
-
- @text.setter
- def text(self, val):
- self.text_changed.emit(val)
- self._text = val
-
- def on_text_changed(self, txt):
- try:
- txt = txt.replace('\t', ' ')
- self.hud_holder.txt.set_text(txt)
- self.p.canvas.draw()
- except Exception:
- pass
-
- def add_artist(self):
- if self.hud_holder not in self.p.axes.artists:
- self.p.axes.add_artist(self.hud_holder)
-
- def remove_artist(self):
- if self.hud_holder in self.p.axes.artists:
- self.p.axes.artists.remove(self.hud_holder)
-
def draw_workspace(self, workspace_size):
"""
Draw a rectangular shape on canvas to specify our valid workspace.
diff --git a/flatcamGUI/VisPyCanvas.py b/flatcamGUI/VisPyCanvas.py
index aa55675f..7d7efe13 100644
--- a/flatcamGUI/VisPyCanvas.py
+++ b/flatcamGUI/VisPyCanvas.py
@@ -13,7 +13,6 @@ import numpy as np
import vispy.scene as scene
from vispy.scene.cameras.base_camera import BaseCamera
-# from vispy.scene.widgets import Widget as VisPyWidget
from vispy.color import Color
import time
diff --git a/flatcamGUI/preferences/OptionUI.py b/flatcamGUI/preferences/OptionUI.py
deleted file mode 100644
index 824c417a..00000000
--- a/flatcamGUI/preferences/OptionUI.py
+++ /dev/null
@@ -1,322 +0,0 @@
-from typing import Union, Sequence, List
-
-from PyQt5 import QtWidgets, QtGui
-from PyQt5.QtCore import QSettings
-
-from flatcamGUI.GUIElements import RadioSet, FCCheckBox, FCButton, FCComboBox, FCEntry, FCSpinner, FCColorEntry, \
- FCSliderWithSpinner, FCDoubleSpinner, FloatEntry, FCTextArea
-
-import gettext
-import FlatCAMTranslation as fcTranslate
-import builtins
-
-fcTranslate.apply_language('strings')
-if '_' not in builtins.__dict__:
- _ = gettext.gettext
-
-
-class OptionUI:
-
- def __init__(self, option: str):
- self.option = option
-
- def add_to_grid(self, grid: QtWidgets.QGridLayout, row: int) -> int:
- """
- Adds the necessary widget to the grid, starting at the supplied row.
- Returns the number of rows used (normally 1)
- """
- raise NotImplementedError()
-
- def get_field(self):
- raise NotImplementedError()
-
-
-class BasicOptionUI(OptionUI):
- """Abstract OptionUI that has a label on the left then some other widget on the right"""
- def __init__(self, option: str, label_text: str, label_tooltip: Union[str, None] = None, label_bold: bool = False, label_color: Union[str, None] = None):
- super().__init__(option=option)
- self.label_text = label_text
- self.label_tooltip = label_tooltip
- self.label_bold = label_bold
- self.label_color = label_color
- self.label_widget = self.build_label_widget()
- self.entry_widget = self.build_entry_widget()
-
- def build_label_widget(self) -> QtWidgets.QLabel:
- fmt = "%s:"
- if self.label_bold:
- fmt = "%s" % fmt
- if self.label_color:
- fmt = "%s" % (self.label_color, fmt)
- label_widget = QtWidgets.QLabel(fmt % _(self.label_text))
- if self.label_tooltip is not None:
- label_widget.setToolTip(_(self.label_tooltip))
- return label_widget
-
- def build_entry_widget(self) -> QtWidgets.QWidget:
- raise NotImplementedError()
-
- def add_to_grid(self, grid: QtWidgets.QGridLayout, row: int) -> int:
- grid.addWidget(self.label_widget, row, 0)
- grid.addWidget(self.entry_widget, row, 1)
- return 1
-
- def get_field(self):
- return self.entry_widget
-
-
-class LineEntryOptionUI(BasicOptionUI):
- def build_entry_widget(self) -> QtWidgets.QWidget:
- return FCEntry()
-
-
-# Not sure why this is needed over DoubleSpinnerOptionUI
-class FloatEntryOptionUI(BasicOptionUI):
- def build_entry_widget(self) -> QtWidgets.QWidget:
- return FloatEntry()
-
-
-class RadioSetOptionUI(BasicOptionUI):
-
- def __init__(self, option: str, label_text: str, choices: list, orientation='horizontal', **kwargs):
- self.choices = choices
- self.orientation = orientation
- super().__init__(option=option, label_text=label_text, **kwargs)
-
- def build_entry_widget(self) -> QtWidgets.QWidget:
- return RadioSet(choices=self.choices, orientation=self.orientation)
-
-
-class TextAreaOptionUI(OptionUI):
-
- def __init__(self, option: str, label_text: str, label_tooltip: str):
- super().__init__(option=option)
- self.label_text = label_text
- self.label_tooltip = label_tooltip
- self.label_widget = self.build_label_widget()
- self.textarea_widget = self.build_textarea_widget()
-
- def build_label_widget(self):
- label = QtWidgets.QLabel("%s:" % _(self.label_text))
- label.setToolTip(_(self.label_tooltip))
- return label
-
- def build_textarea_widget(self):
- textarea = FCTextArea()
- textarea.setPlaceholderText(_(self.label_tooltip))
-
- qsettings = QSettings("Open Source", "FlatCAM")
- if qsettings.contains("textbox_font_size"):
- tb_fsize = qsettings.value('textbox_font_size', type=int)
- else:
- tb_fsize = 10
- font = QtGui.QFont()
- font.setPointSize(tb_fsize)
- textarea.setFont(font)
-
- return textarea
-
- def get_field(self):
- return self.textarea_widget
-
- def add_to_grid(self, grid: QtWidgets.QGridLayout, row: int) -> int:
- grid.addWidget(self.label_widget, row, 0, 1, 3)
- grid.addWidget(self.textarea_widget, row+1, 0, 1, 3)
- return 2
-
-
-class CheckboxOptionUI(OptionUI):
-
- def __init__(self, option: str, label_text: str, label_tooltip: str):
- super().__init__(option=option)
- self.label_text = label_text
- self.label_tooltip = label_tooltip
- self.checkbox_widget = self.build_checkbox_widget()
-
- def build_checkbox_widget(self):
- checkbox = FCCheckBox('%s' % _(self.label_text))
- checkbox.setToolTip(_(self.label_tooltip))
- return checkbox
-
- def add_to_grid(self, grid: QtWidgets.QGridLayout, row: int) -> int:
- grid.addWidget(self.checkbox_widget, row, 0, 1, 3)
- return 1
-
- def get_field(self):
- return self.checkbox_widget
-
-
-class ComboboxOptionUI(BasicOptionUI):
-
- def __init__(self, option: str, label_text: str, choices: Sequence, **kwargs):
- self.choices = choices
- super().__init__(option=option, label_text=label_text, **kwargs)
-
- def build_entry_widget(self):
- combo = FCComboBox()
- for choice in self.choices:
- # don't translate the QCombo items as they are used in QSettings and identified by name
- combo.addItem(choice)
- return combo
-
-
-class ColorOptionUI(BasicOptionUI):
- def build_entry_widget(self) -> QtWidgets.QWidget:
- entry = FCColorEntry()
- return entry
-
-
-class SliderWithSpinnerOptionUI(BasicOptionUI):
- def __init__(self, option: str, label_text: str, min_value=0, max_value=100, step=1, **kwargs):
- self.min_value = min_value
- self.max_value = max_value
- self.step = step
- super().__init__(option=option, label_text=label_text, **kwargs)
-
- def build_entry_widget(self) -> QtWidgets.QWidget:
- entry = FCSliderWithSpinner(min=self.min_value, max=self.max_value, step=self.step)
- return entry
-
-
-class ColorAlphaSliderOptionUI(SliderWithSpinnerOptionUI):
- def __init__(self, applies_to: List[str], group, label_text: str, **kwargs):
- self.applies_to = applies_to
- self.group = group
- super().__init__(option="__color_alpha_slider", label_text=label_text, min_value=0, max_value=255, step=1, **kwargs)
- self.get_field().valueChanged.connect(self._on_alpha_change)
-
- def add_to_grid(self, grid: QtWidgets.QGridLayout, row: int) -> int:
- for index, field in enumerate(self._get_target_fields()):
- field.entry.textChanged.connect(lambda value, i=index: self._on_target_change(target_index=i))
- return super().add_to_grid(grid, row)
-
- def _get_target_fields(self):
- return list(map(lambda n: self.group.option_dict()[n].get_field(), self.applies_to))
-
- def _on_target_change(self, target_index: int):
- field = self._get_target_fields()[target_index]
- color = field.get_value()
- alpha_part = color[7:]
- if len(alpha_part) != 2:
- return
- alpha = int(alpha_part, 16)
- if alpha < 0 or alpha > 255 or self.get_field().get_value() == alpha:
- return
- self.get_field().set_value(alpha)
-
- def _on_alpha_change(self):
- alpha = self.get_field().get_value()
- for field in self._get_target_fields():
- old_value = field.get_value()
- new_value = self._modify_color_alpha(old_value, alpha=alpha)
- field.set_value(new_value)
-
- def _modify_color_alpha(self, color: str, alpha: int):
- color_without_alpha = color[:7]
- if alpha > 255:
- return color_without_alpha + "FF"
- elif alpha < 0:
- return color_without_alpha + "00"
- else:
- hexalpha = hex(alpha)[2:]
- if len(hexalpha) == 1:
- hexalpha = "0" + hexalpha
- return color_without_alpha + hexalpha
-
-
-class SpinnerOptionUI(BasicOptionUI):
- def __init__(self, option: str, label_text: str, min_value: int, max_value: int, step: int = 1, **kwargs):
- self.min_value = min_value
- self.max_value = max_value
- self.step = step
- super().__init__(option=option, label_text=label_text, **kwargs)
-
- def build_entry_widget(self) -> QtWidgets.QWidget:
- entry = FCSpinner()
- entry.set_range(self.min_value, self.max_value)
- entry.set_step(self.step)
- entry.setWrapping(True)
- return entry
-
-
-class DoubleSpinnerOptionUI(BasicOptionUI):
- def __init__(self, option: str, label_text: str, step: float, decimals: int, min_value=None, max_value=None, suffix=None, **kwargs):
- self.min_value = min_value
- self.max_value = max_value
- self.step = step
- self.suffix = suffix
- self.decimals = decimals
- super().__init__(option=option, label_text=label_text, **kwargs)
-
- def build_entry_widget(self) -> QtWidgets.QWidget:
- entry = FCDoubleSpinner(suffix=self.suffix)
- entry.set_precision(self.decimals)
- entry.setSingleStep(self.step)
- if self.min_value is None:
- self.min_value = entry.minimum()
- else:
- entry.setMinimum(self.min_value)
- if self.max_value is None:
- self.max_value = entry.maximum()
- else:
- entry.setMaximum(self.max_value)
- return entry
-
-
-class HeadingOptionUI(OptionUI):
- def __init__(self, label_text: str, label_tooltip: Union[str, None] = None):
- super().__init__(option="__heading")
- self.label_text = label_text
- self.label_tooltip = label_tooltip
-
- def build_heading_widget(self):
- heading = QtWidgets.QLabel('%s' % _(self.label_text))
- heading.setToolTip(_(self.label_tooltip))
- return heading
-
- def add_to_grid(self, grid: QtWidgets.QGridLayout, row: int) -> int:
- grid.addWidget(self.build_heading_widget(), row, 0, 1, 2)
- return 1
-
- def get_field(self):
- return None
-
-
-class SeparatorOptionUI(OptionUI):
-
- def __init__(self):
- super().__init__(option="__separator")
-
- def build_separator_widget(self):
- separator = QtWidgets.QFrame()
- separator.setFrameShape(QtWidgets.QFrame.HLine)
- separator.setFrameShadow(QtWidgets.QFrame.Sunken)
- return separator
-
- def add_to_grid(self, grid: QtWidgets.QGridLayout, row: int) -> int:
- grid.addWidget(self.build_separator_widget(), row, 0, 1, 2)
- return 1
-
- def get_field(self):
- return None
-
-
-class FullWidthButtonOptionUI(OptionUI):
- def __init__(self, option: str, label_text: str, label_tooltip: Union[str, None]):
- super().__init__(option=option)
- self.label_text = label_text
- self.label_tooltip = label_tooltip
- self.button_widget = self.build_button_widget()
-
- def build_button_widget(self):
- button = FCButton(_(self.label_text))
- if self.label_tooltip is not None:
- button.setToolTip(_(self.label_tooltip))
- return button
-
- def add_to_grid(self, grid: QtWidgets.QGridLayout, row: int) -> int:
- grid.addWidget(self.button_widget, row, 0, 1, 3)
- return 1
-
- def get_field(self):
- return self.button_widget
\ No newline at end of file
diff --git a/flatcamGUI/preferences/OptionsGroupUI.py b/flatcamGUI/preferences/OptionsGroupUI.py
index 2f519ea9..98780004 100644
--- a/flatcamGUI/preferences/OptionsGroupUI.py
+++ b/flatcamGUI/preferences/OptionsGroupUI.py
@@ -1,32 +1,12 @@
-from typing import Dict
-
from PyQt5 import QtWidgets
-from PyQt5.QtCore import QSettings
-
-import gettext
-import FlatCAMTranslation as fcTranslate
-import builtins
-
-from flatcamGUI.preferences.OptionUI import OptionUI
-
-fcTranslate.apply_language('strings')
-if '_' not in builtins.__dict__:
- _ = gettext.gettext
-
-settings = QSettings("Open Source", "FlatCAM")
-if settings.contains("machinist"):
- machinist_setting = settings.value('machinist', type=int)
-else:
- machinist_setting = 0
-
class OptionsGroupUI(QtWidgets.QGroupBox):
app = None
- def __init__(self, fixme_get_rid_of_this=None, **kwargs):
- super().__init__(**kwargs)
-
+ def __init__(self, title, parent=None):
+ # QtGui.QGroupBox.__init__(self, title, parent=parent)
+ super(OptionsGroupUI, self).__init__()
self.setStyleSheet("""
QGroupBox
{
@@ -36,38 +16,4 @@ class OptionsGroupUI(QtWidgets.QGroupBox):
""")
self.layout = QtWidgets.QVBoxLayout()
- self.setLayout(self.layout)
-
- def option_dict(self) -> Dict[str, OptionUI]:
- # FIXME!
- return {}
-
-
-class OptionsGroupUI2(OptionsGroupUI):
-
- def __init__(self, **kwargs):
- super().__init__(**kwargs)
-
- self.grid = QtWidgets.QGridLayout()
- self.layout.addLayout(self.grid)
- self.grid.setColumnStretch(0, 0)
- self.grid.setColumnStretch(1, 1)
-
- self.options = self.build_options()
-
- row = 0
- for option in self.options:
- row += option.add_to_grid(grid=self.grid, row=row)
-
- self.layout.addStretch()
-
- def build_options(self) -> [OptionUI]:
- return []
-
- def option_dict(self) -> Dict[str, OptionUI]:
- result = {}
- for optionui in self.options:
- result[optionui.option] = optionui
- return result
-
-
+ self.setLayout(self.layout)
\ No newline at end of file
diff --git a/flatcamGUI/preferences/PreferencesSectionUI.py b/flatcamGUI/preferences/PreferencesSectionUI.py
deleted file mode 100644
index 92168377..00000000
--- a/flatcamGUI/preferences/PreferencesSectionUI.py
+++ /dev/null
@@ -1,42 +0,0 @@
-from typing import Dict
-from PyQt5 import QtWidgets, QtCore
-
-from flatcamGUI.ColumnarFlowLayout import ColumnarFlowLayout
-from flatcamGUI.preferences.OptionUI import OptionUI
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
-
-
-class PreferencesSectionUI(QtWidgets.QWidget):
-
- def __init__(self, **kwargs):
- super().__init__(**kwargs)
- self.layout = ColumnarFlowLayout() #QtWidgets.QHBoxLayout()
- self.setLayout(self.layout)
-
- self.groups = self.build_groups()
- for group in self.groups:
- group.setMinimumWidth(250)
- self.layout.addWidget(group)
-
-
- def build_groups(self) -> [OptionsGroupUI]:
- return []
-
- def option_dict(self) -> Dict[str, OptionUI]:
- result = {}
- for group in self.groups:
- groupoptions = group.option_dict()
- result.update(groupoptions)
- return result
-
- def build_tab(self):
- scroll_area = QtWidgets.QScrollArea()
- scroll_area.setWidget(self)
- scroll_area.setWidgetResizable(True)
- return scroll_area
-
- def get_tab_id(self) -> str:
- raise NotImplementedError
-
- def get_tab_label(self) -> str:
- raise NotImplementedError
diff --git a/flatcamGUI/preferences/PreferencesUIManager.py b/flatcamGUI/preferences/PreferencesUIManager.py
index de4468b1..c49841ba 100644
--- a/flatcamGUI/preferences/PreferencesUIManager.py
+++ b/flatcamGUI/preferences/PreferencesUIManager.py
@@ -1,6 +1,4 @@
import os
-from typing import Any, Dict
-
from PyQt5 import QtGui, QtCore, QtWidgets
from PyQt5.QtCore import QSettings
from defaults import FlatCAMDefaults
@@ -10,8 +8,6 @@ import gettext
import FlatCAMTranslation as fcTranslate
import builtins
-from flatcamGUI.preferences.OptionUI import OptionUI
-
fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__:
_ = gettext.gettext
@@ -24,6 +20,7 @@ else:
log = logging.getLogger('PreferencesUIManager')
+
class PreferencesUIManager:
def __init__(self, defaults: FlatCAMDefaults, data_path: str, ui, inform):
@@ -33,7 +30,7 @@ class PreferencesUIManager:
:param defaults: a dictionary storage where all the application settings are stored
:param data_path: a path to the file where all the preferences are stored for persistence
:param ui: reference to the FlatCAMGUI class which constructs the UI
- :param inform: a pyqtSignal used to display information in the StatusBar of the GUI
+ :param inform: a pyqtSignal used to display information's in the StatusBar of the GUI
"""
self.defaults = defaults
@@ -48,6 +45,298 @@ class PreferencesUIManager:
# when adding entries here read the comments in the method found below named:
# def new_object(self, kind, name, initialize, active=True, fit=True, plot=True)
self.defaults_form_fields = {
+ # General App
+ "decimals_inch": self.ui.general_defaults_form.general_app_group.precision_inch_entry,
+ "decimals_metric": self.ui.general_defaults_form.general_app_group.precision_metric_entry,
+ "units": self.ui.general_defaults_form.general_app_group.units_radio,
+ "global_graphic_engine": self.ui.general_defaults_form.general_app_group.ge_radio,
+ "global_app_level": self.ui.general_defaults_form.general_app_group.app_level_radio,
+ "global_portable": self.ui.general_defaults_form.general_app_group.portability_cb,
+ "global_language": self.ui.general_defaults_form.general_app_group.language_cb,
+
+ "global_systray_icon": self.ui.general_defaults_form.general_app_group.systray_cb,
+ "global_shell_at_startup": self.ui.general_defaults_form.general_app_group.shell_startup_cb,
+ "global_project_at_startup": self.ui.general_defaults_form.general_app_group.project_startup_cb,
+ "global_version_check": self.ui.general_defaults_form.general_app_group.version_check_cb,
+ "global_send_stats": self.ui.general_defaults_form.general_app_group.send_stats_cb,
+
+ "global_worker_number": self.ui.general_defaults_form.general_app_group.worker_number_sb,
+ "global_tolerance": self.ui.general_defaults_form.general_app_group.tol_entry,
+
+ "global_compression_level": self.ui.general_defaults_form.general_app_group.compress_spinner,
+ "global_save_compressed": self.ui.general_defaults_form.general_app_group.save_type_cb,
+ "global_autosave": self.ui.general_defaults_form.general_app_group.autosave_cb,
+ "global_autosave_timeout": self.ui.general_defaults_form.general_app_group.autosave_entry,
+
+ "global_tpdf_tmargin": self.ui.general_defaults_form.general_app_group.tmargin_entry,
+ "global_tpdf_bmargin": self.ui.general_defaults_form.general_app_group.bmargin_entry,
+ "global_tpdf_lmargin": self.ui.general_defaults_form.general_app_group.lmargin_entry,
+ "global_tpdf_rmargin": self.ui.general_defaults_form.general_app_group.rmargin_entry,
+
+ # General GUI Preferences
+ "global_theme": self.ui.general_defaults_form.general_gui_group.theme_radio,
+ "global_gray_icons": self.ui.general_defaults_form.general_gui_group.gray_icons_cb,
+ "global_layout": self.ui.general_defaults_form.general_gui_group.layout_combo,
+ "global_hover": self.ui.general_defaults_form.general_gui_group.hover_cb,
+ "global_selection_shape": self.ui.general_defaults_form.general_gui_group.selection_cb,
+
+ "global_sel_fill": self.ui.general_defaults_form.general_gui_group.sf_color_entry,
+ "global_sel_line": self.ui.general_defaults_form.general_gui_group.sl_color_entry,
+ "global_alt_sel_fill": self.ui.general_defaults_form.general_gui_group.alt_sf_color_entry,
+ "global_alt_sel_line": self.ui.general_defaults_form.general_gui_group.alt_sl_color_entry,
+ "global_draw_color": self.ui.general_defaults_form.general_gui_group.draw_color_entry,
+ "global_sel_draw_color": self.ui.general_defaults_form.general_gui_group.sel_draw_color_entry,
+
+ "global_proj_item_color": self.ui.general_defaults_form.general_gui_group.proj_color_entry,
+ "global_proj_item_dis_color": self.ui.general_defaults_form.general_gui_group.proj_color_dis_entry,
+ "global_project_autohide": self.ui.general_defaults_form.general_gui_group.project_autohide_cb,
+
+ # General GUI Settings
+ "global_gridx": self.ui.general_defaults_form.general_app_set_group.gridx_entry,
+ "global_gridy": self.ui.general_defaults_form.general_app_set_group.gridy_entry,
+ "global_snap_max": self.ui.general_defaults_form.general_app_set_group.snap_max_dist_entry,
+ "global_workspace": self.ui.general_defaults_form.general_app_set_group.workspace_cb,
+ "global_workspaceT": self.ui.general_defaults_form.general_app_set_group.wk_cb,
+ "global_workspace_orientation": self.ui.general_defaults_form.general_app_set_group.wk_orientation_radio,
+
+ "global_cursor_type": self.ui.general_defaults_form.general_app_set_group.cursor_radio,
+ "global_cursor_size": self.ui.general_defaults_form.general_app_set_group.cursor_size_entry,
+ "global_cursor_width": self.ui.general_defaults_form.general_app_set_group.cursor_width_entry,
+ "global_cursor_color_enabled": self.ui.general_defaults_form.general_app_set_group.mouse_cursor_color_cb,
+ "global_cursor_color": self.ui.general_defaults_form.general_app_set_group.mouse_cursor_entry,
+ "global_pan_button": self.ui.general_defaults_form.general_app_set_group.pan_button_radio,
+ "global_mselect_key": self.ui.general_defaults_form.general_app_set_group.mselect_radio,
+ "global_delete_confirmation": self.ui.general_defaults_form.general_app_set_group.delete_conf_cb,
+ "global_open_style": self.ui.general_defaults_form.general_app_set_group.open_style_cb,
+ "global_toggle_tooltips": self.ui.general_defaults_form.general_app_set_group.toggle_tooltips_cb,
+ "global_machinist_setting": self.ui.general_defaults_form.general_app_set_group.machinist_cb,
+
+ "global_bookmarks_limit": self.ui.general_defaults_form.general_app_set_group.bm_limit_spinner,
+ "global_activity_icon": self.ui.general_defaults_form.general_app_set_group.activity_combo,
+
+ # Gerber General
+ "gerber_plot": self.ui.gerber_defaults_form.gerber_gen_group.plot_cb,
+ "gerber_solid": self.ui.gerber_defaults_form.gerber_gen_group.solid_cb,
+ "gerber_multicolored": self.ui.gerber_defaults_form.gerber_gen_group.multicolored_cb,
+ "gerber_circle_steps": self.ui.gerber_defaults_form.gerber_gen_group.circle_steps_entry,
+ "gerber_def_units": self.ui.gerber_defaults_form.gerber_gen_group.gerber_units_radio,
+ "gerber_def_zeros": self.ui.gerber_defaults_form.gerber_gen_group.gerber_zeros_radio,
+ "gerber_clean_apertures": self.ui.gerber_defaults_form.gerber_gen_group.gerber_clean_cb,
+ "gerber_extra_buffering": self.ui.gerber_defaults_form.gerber_gen_group.gerber_extra_buffering,
+ "gerber_plot_fill": self.ui.gerber_defaults_form.gerber_gen_group.pf_color_entry,
+ "gerber_plot_line": self.ui.gerber_defaults_form.gerber_gen_group.pl_color_entry,
+
+ # Gerber Options
+ "gerber_isotooldia": self.ui.gerber_defaults_form.gerber_opt_group.iso_tool_dia_entry,
+ "gerber_isopasses": self.ui.gerber_defaults_form.gerber_opt_group.iso_width_entry,
+ "gerber_isooverlap": self.ui.gerber_defaults_form.gerber_opt_group.iso_overlap_entry,
+ "gerber_combine_passes": self.ui.gerber_defaults_form.gerber_opt_group.combine_passes_cb,
+ "gerber_iso_scope": self.ui.gerber_defaults_form.gerber_opt_group.iso_scope_radio,
+ "gerber_milling_type": self.ui.gerber_defaults_form.gerber_opt_group.milling_type_radio,
+ "gerber_noncoppermargin": self.ui.gerber_defaults_form.gerber_opt_group.noncopper_margin_entry,
+ "gerber_noncopperrounded": self.ui.gerber_defaults_form.gerber_opt_group.noncopper_rounded_cb,
+ "gerber_bboxmargin": self.ui.gerber_defaults_form.gerber_opt_group.bbmargin_entry,
+ "gerber_bboxrounded": self.ui.gerber_defaults_form.gerber_opt_group.bbrounded_cb,
+
+ # Gerber Advanced Options
+ "gerber_aperture_display": self.ui.gerber_defaults_form.gerber_adv_opt_group.aperture_table_visibility_cb,
+ # "gerber_aperture_scale_factor": self.ui.gerber_defaults_form.gerber_adv_opt_group.scale_aperture_entry,
+ # "gerber_aperture_buffer_factor": self.ui.gerber_defaults_form.gerber_adv_opt_group.buffer_aperture_entry,
+ "gerber_follow": self.ui.gerber_defaults_form.gerber_adv_opt_group.follow_cb,
+ "gerber_tool_type": self.ui.gerber_defaults_form.gerber_adv_opt_group.tool_type_radio,
+ "gerber_vtipdia": self.ui.gerber_defaults_form.gerber_adv_opt_group.tipdia_spinner,
+ "gerber_vtipangle": self.ui.gerber_defaults_form.gerber_adv_opt_group.tipangle_spinner,
+ "gerber_vcutz": self.ui.gerber_defaults_form.gerber_adv_opt_group.cutz_spinner,
+ "gerber_iso_type": self.ui.gerber_defaults_form.gerber_adv_opt_group.iso_type_radio,
+
+ "gerber_buffering": self.ui.gerber_defaults_form.gerber_adv_opt_group.buffering_radio,
+ "gerber_simplification": self.ui.gerber_defaults_form.gerber_adv_opt_group.simplify_cb,
+ "gerber_simp_tolerance": self.ui.gerber_defaults_form.gerber_adv_opt_group.simplification_tol_spinner,
+
+ # Gerber Export
+ "gerber_exp_units": self.ui.gerber_defaults_form.gerber_exp_group.gerber_units_radio,
+ "gerber_exp_integer": self.ui.gerber_defaults_form.gerber_exp_group.format_whole_entry,
+ "gerber_exp_decimals": self.ui.gerber_defaults_form.gerber_exp_group.format_dec_entry,
+ "gerber_exp_zeros": self.ui.gerber_defaults_form.gerber_exp_group.zeros_radio,
+
+ # Gerber Editor
+ "gerber_editor_sel_limit": self.ui.gerber_defaults_form.gerber_editor_group.sel_limit_entry,
+ "gerber_editor_newcode": self.ui.gerber_defaults_form.gerber_editor_group.addcode_entry,
+ "gerber_editor_newsize": self.ui.gerber_defaults_form.gerber_editor_group.addsize_entry,
+ "gerber_editor_newtype": self.ui.gerber_defaults_form.gerber_editor_group.addtype_combo,
+ "gerber_editor_newdim": self.ui.gerber_defaults_form.gerber_editor_group.adddim_entry,
+ "gerber_editor_array_size": self.ui.gerber_defaults_form.gerber_editor_group.grb_array_size_entry,
+ "gerber_editor_lin_axis": self.ui.gerber_defaults_form.gerber_editor_group.grb_axis_radio,
+ "gerber_editor_lin_pitch": self.ui.gerber_defaults_form.gerber_editor_group.grb_pitch_entry,
+ "gerber_editor_lin_angle": self.ui.gerber_defaults_form.gerber_editor_group.grb_angle_entry,
+ "gerber_editor_circ_dir": self.ui.gerber_defaults_form.gerber_editor_group.grb_circular_dir_radio,
+ "gerber_editor_circ_angle":
+ self.ui.gerber_defaults_form.gerber_editor_group.grb_circular_angle_entry,
+ "gerber_editor_scale_f": self.ui.gerber_defaults_form.gerber_editor_group.grb_scale_entry,
+ "gerber_editor_buff_f": self.ui.gerber_defaults_form.gerber_editor_group.grb_buff_entry,
+ "gerber_editor_ma_low": self.ui.gerber_defaults_form.gerber_editor_group.grb_ma_low_entry,
+ "gerber_editor_ma_high": self.ui.gerber_defaults_form.gerber_editor_group.grb_ma_high_entry,
+
+ # Excellon General
+ "excellon_plot": self.ui.excellon_defaults_form.excellon_gen_group.plot_cb,
+ "excellon_solid": self.ui.excellon_defaults_form.excellon_gen_group.solid_cb,
+ "excellon_format_upper_in":
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_upper_in_entry,
+ "excellon_format_lower_in":
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_lower_in_entry,
+ "excellon_format_upper_mm":
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_upper_mm_entry,
+ "excellon_format_lower_mm":
+ self.ui.excellon_defaults_form.excellon_gen_group.excellon_format_lower_mm_entry,
+ "excellon_zeros": self.ui.excellon_defaults_form.excellon_gen_group.excellon_zeros_radio,
+ "excellon_units": self.ui.excellon_defaults_form.excellon_gen_group.excellon_units_radio,
+ "excellon_update": self.ui.excellon_defaults_form.excellon_gen_group.update_excellon_cb,
+ "excellon_optimization_type": self.ui.excellon_defaults_form.excellon_gen_group.excellon_optimization_radio,
+ "excellon_search_time": self.ui.excellon_defaults_form.excellon_gen_group.optimization_time_entry,
+ "excellon_plot_fill": self.ui.excellon_defaults_form.excellon_gen_group.fill_color_entry,
+ "excellon_plot_line": self.ui.excellon_defaults_form.excellon_gen_group.line_color_entry,
+
+ # Excellon Options
+ "excellon_operation": self.ui.excellon_defaults_form.excellon_opt_group.operation_radio,
+ "excellon_milling_type": self.ui.excellon_defaults_form.excellon_opt_group.milling_type_radio,
+
+ "excellon_milling_dia": self.ui.excellon_defaults_form.excellon_opt_group.mill_dia_entry,
+
+ "excellon_cutz": self.ui.excellon_defaults_form.excellon_opt_group.cutz_entry,
+ "excellon_multidepth": self.ui.excellon_defaults_form.excellon_opt_group.mpass_cb,
+ "excellon_depthperpass": self.ui.excellon_defaults_form.excellon_opt_group.maxdepth_entry,
+ "excellon_travelz": self.ui.excellon_defaults_form.excellon_opt_group.travelz_entry,
+ "excellon_endz": self.ui.excellon_defaults_form.excellon_opt_group.endz_entry,
+ "excellon_endxy": self.ui.excellon_defaults_form.excellon_opt_group.endxy_entry,
+
+ "excellon_feedrate_z": self.ui.excellon_defaults_form.excellon_opt_group.feedrate_z_entry,
+ "excellon_spindlespeed": self.ui.excellon_defaults_form.excellon_opt_group.spindlespeed_entry,
+ "excellon_dwell": self.ui.excellon_defaults_form.excellon_opt_group.dwell_cb,
+ "excellon_dwelltime": self.ui.excellon_defaults_form.excellon_opt_group.dwelltime_entry,
+ "excellon_toolchange": self.ui.excellon_defaults_form.excellon_opt_group.toolchange_cb,
+ "excellon_toolchangez": self.ui.excellon_defaults_form.excellon_opt_group.toolchangez_entry,
+ "excellon_ppname_e": self.ui.excellon_defaults_form.excellon_opt_group.pp_excellon_name_cb,
+ "excellon_tooldia": self.ui.excellon_defaults_form.excellon_opt_group.tooldia_entry,
+ "excellon_slot_tooldia": self.ui.excellon_defaults_form.excellon_opt_group.slot_tooldia_entry,
+ "excellon_gcode_type": self.ui.excellon_defaults_form.excellon_opt_group.excellon_gcode_type_radio,
+
+ # Excellon Advanced Options
+ "excellon_offset": self.ui.excellon_defaults_form.excellon_adv_opt_group.offset_entry,
+ "excellon_toolchangexy": self.ui.excellon_defaults_form.excellon_adv_opt_group.toolchangexy_entry,
+ "excellon_startz": self.ui.excellon_defaults_form.excellon_adv_opt_group.estartz_entry,
+ "excellon_feedrate_rapid": self.ui.excellon_defaults_form.excellon_adv_opt_group.feedrate_rapid_entry,
+ "excellon_z_pdepth": self.ui.excellon_defaults_form.excellon_adv_opt_group.pdepth_entry,
+ "excellon_feedrate_probe": self.ui.excellon_defaults_form.excellon_adv_opt_group.feedrate_probe_entry,
+ "excellon_spindledir": self.ui.excellon_defaults_form.excellon_adv_opt_group.spindledir_radio,
+ "excellon_f_plunge": self.ui.excellon_defaults_form.excellon_adv_opt_group.fplunge_cb,
+ "excellon_f_retract": self.ui.excellon_defaults_form.excellon_adv_opt_group.fretract_cb,
+
+ # Excellon Export
+ "excellon_exp_units": self.ui.excellon_defaults_form.excellon_exp_group.excellon_units_radio,
+ "excellon_exp_format": self.ui.excellon_defaults_form.excellon_exp_group.format_radio,
+ "excellon_exp_integer": self.ui.excellon_defaults_form.excellon_exp_group.format_whole_entry,
+ "excellon_exp_decimals": self.ui.excellon_defaults_form.excellon_exp_group.format_dec_entry,
+ "excellon_exp_zeros": self.ui.excellon_defaults_form.excellon_exp_group.zeros_radio,
+ "excellon_exp_slot_type": self.ui.excellon_defaults_form.excellon_exp_group.slot_type_radio,
+
+ # Excellon Editor
+ "excellon_editor_sel_limit": self.ui.excellon_defaults_form.excellon_editor_group.sel_limit_entry,
+ "excellon_editor_newdia": self.ui.excellon_defaults_form.excellon_editor_group.addtool_entry,
+ "excellon_editor_array_size": self.ui.excellon_defaults_form.excellon_editor_group.drill_array_size_entry,
+ "excellon_editor_lin_dir": self.ui.excellon_defaults_form.excellon_editor_group.drill_axis_radio,
+ "excellon_editor_lin_pitch": self.ui.excellon_defaults_form.excellon_editor_group.drill_pitch_entry,
+ "excellon_editor_lin_angle": self.ui.excellon_defaults_form.excellon_editor_group.drill_angle_entry,
+ "excellon_editor_circ_dir": self.ui.excellon_defaults_form.excellon_editor_group.drill_circular_dir_radio,
+ "excellon_editor_circ_angle":
+ self.ui.excellon_defaults_form.excellon_editor_group.drill_circular_angle_entry,
+ # Excellon Slots
+ "excellon_editor_slot_direction":
+ self.ui.excellon_defaults_form.excellon_editor_group.slot_axis_radio,
+ "excellon_editor_slot_angle":
+ self.ui.excellon_defaults_form.excellon_editor_group.slot_angle_spinner,
+ "excellon_editor_slot_length":
+ self.ui.excellon_defaults_form.excellon_editor_group.slot_length_entry,
+ # Excellon Slots
+ "excellon_editor_slot_array_size":
+ self.ui.excellon_defaults_form.excellon_editor_group.slot_array_size_entry,
+ "excellon_editor_slot_lin_dir": self.ui.excellon_defaults_form.excellon_editor_group.slot_array_axis_radio,
+ "excellon_editor_slot_lin_pitch":
+ self.ui.excellon_defaults_form.excellon_editor_group.slot_array_pitch_entry,
+ "excellon_editor_slot_lin_angle":
+ self.ui.excellon_defaults_form.excellon_editor_group.slot_array_angle_entry,
+ "excellon_editor_slot_circ_dir":
+ self.ui.excellon_defaults_form.excellon_editor_group.slot_array_circular_dir_radio,
+ "excellon_editor_slot_circ_angle":
+ self.ui.excellon_defaults_form.excellon_editor_group.slot_array_circular_angle_entry,
+
+ # Geometry General
+ "geometry_plot": self.ui.geometry_defaults_form.geometry_gen_group.plot_cb,
+ "geometry_circle_steps": self.ui.geometry_defaults_form.geometry_gen_group.circle_steps_entry,
+ "geometry_cnctooldia": self.ui.geometry_defaults_form.geometry_gen_group.cnctooldia_entry,
+ "geometry_plot_line": self.ui.geometry_defaults_form.geometry_gen_group.line_color_entry,
+
+ # Geometry Options
+ "geometry_cutz": self.ui.geometry_defaults_form.geometry_opt_group.cutz_entry,
+ "geometry_travelz": self.ui.geometry_defaults_form.geometry_opt_group.travelz_entry,
+ "geometry_feedrate": self.ui.geometry_defaults_form.geometry_opt_group.cncfeedrate_entry,
+ "geometry_feedrate_z": self.ui.geometry_defaults_form.geometry_opt_group.feedrate_z_entry,
+ "geometry_spindlespeed": self.ui.geometry_defaults_form.geometry_opt_group.cncspindlespeed_entry,
+ "geometry_dwell": self.ui.geometry_defaults_form.geometry_opt_group.dwell_cb,
+ "geometry_dwelltime": self.ui.geometry_defaults_form.geometry_opt_group.dwelltime_entry,
+ "geometry_ppname_g": self.ui.geometry_defaults_form.geometry_opt_group.pp_geometry_name_cb,
+ "geometry_toolchange": self.ui.geometry_defaults_form.geometry_opt_group.toolchange_cb,
+ "geometry_toolchangez": self.ui.geometry_defaults_form.geometry_opt_group.toolchangez_entry,
+ "geometry_endz": self.ui.geometry_defaults_form.geometry_opt_group.endz_entry,
+ "geometry_endxy": self.ui.geometry_defaults_form.geometry_opt_group.endxy_entry,
+ "geometry_depthperpass": self.ui.geometry_defaults_form.geometry_opt_group.depthperpass_entry,
+ "geometry_multidepth": self.ui.geometry_defaults_form.geometry_opt_group.multidepth_cb,
+
+ # Geometry Advanced Options
+ "geometry_toolchangexy": self.ui.geometry_defaults_form.geometry_adv_opt_group.toolchangexy_entry,
+ "geometry_startz": self.ui.geometry_defaults_form.geometry_adv_opt_group.gstartz_entry,
+ "geometry_feedrate_rapid": self.ui.geometry_defaults_form.geometry_adv_opt_group.feedrate_rapid_entry,
+ "geometry_extracut": self.ui.geometry_defaults_form.geometry_adv_opt_group.extracut_cb,
+ "geometry_extracut_length": self.ui.geometry_defaults_form.geometry_adv_opt_group.e_cut_entry,
+ "geometry_z_pdepth": self.ui.geometry_defaults_form.geometry_adv_opt_group.pdepth_entry,
+ "geometry_feedrate_probe": self.ui.geometry_defaults_form.geometry_adv_opt_group.feedrate_probe_entry,
+ "geometry_spindledir": self.ui.geometry_defaults_form.geometry_adv_opt_group.spindledir_radio,
+ "geometry_f_plunge": self.ui.geometry_defaults_form.geometry_adv_opt_group.fplunge_cb,
+ "geometry_segx": self.ui.geometry_defaults_form.geometry_adv_opt_group.segx_entry,
+ "geometry_segy": self.ui.geometry_defaults_form.geometry_adv_opt_group.segy_entry,
+ "geometry_area_exclusion": self.ui.geometry_defaults_form.geometry_adv_opt_group.exclusion_cb,
+ "geometry_area_shape": self.ui.geometry_defaults_form.geometry_adv_opt_group.area_shape_radio,
+ "geometry_area_strategy": self.ui.geometry_defaults_form.geometry_adv_opt_group.strategy_radio,
+ "geometry_area_overz": self.ui.geometry_defaults_form.geometry_adv_opt_group.over_z_entry,
+
+ # Geometry Editor
+ "geometry_editor_sel_limit": self.ui.geometry_defaults_form.geometry_editor_group.sel_limit_entry,
+ "geometry_editor_milling_type": self.ui.geometry_defaults_form.geometry_editor_group.milling_type_radio,
+
+ # CNCJob General
+ "cncjob_plot": self.ui.cncjob_defaults_form.cncjob_gen_group.plot_cb,
+ "cncjob_plot_kind": self.ui.cncjob_defaults_form.cncjob_gen_group.cncplot_method_radio,
+ "cncjob_annotation": self.ui.cncjob_defaults_form.cncjob_gen_group.annotation_cb,
+
+ "cncjob_tooldia": self.ui.cncjob_defaults_form.cncjob_gen_group.tooldia_entry,
+ "cncjob_coords_type": self.ui.cncjob_defaults_form.cncjob_gen_group.coords_type_radio,
+ "cncjob_coords_decimals": self.ui.cncjob_defaults_form.cncjob_gen_group.coords_dec_entry,
+ "cncjob_fr_decimals": self.ui.cncjob_defaults_form.cncjob_gen_group.fr_dec_entry,
+ "cncjob_steps_per_circle": self.ui.cncjob_defaults_form.cncjob_gen_group.steps_per_circle_entry,
+ "cncjob_line_ending": self.ui.cncjob_defaults_form.cncjob_gen_group.line_ending_cb,
+ "cncjob_plot_line": self.ui.cncjob_defaults_form.cncjob_gen_group.line_color_entry,
+ "cncjob_plot_fill": self.ui.cncjob_defaults_form.cncjob_gen_group.fill_color_entry,
+ "cncjob_travel_line": self.ui.cncjob_defaults_form.cncjob_gen_group.tline_color_entry,
+ "cncjob_travel_fill": self.ui.cncjob_defaults_form.cncjob_gen_group.tfill_color_entry,
+
+ # CNC Job Options
+ "cncjob_prepend": self.ui.cncjob_defaults_form.cncjob_opt_group.prepend_text,
+ "cncjob_append": self.ui.cncjob_defaults_form.cncjob_opt_group.append_text,
+
+ # CNC Job Advanced Options
+ "cncjob_toolchange_macro": self.ui.cncjob_defaults_form.cncjob_adv_opt_group.toolchange_text,
+ "cncjob_toolchange_macro_enable": self.ui.cncjob_defaults_form.cncjob_adv_opt_group.toolchange_cb,
+ "cncjob_annotation_fontsize": self.ui.cncjob_defaults_form.cncjob_adv_opt_group.annotation_fontsize_sp,
+ "cncjob_annotation_fontcolor": self.ui.cncjob_defaults_form.cncjob_adv_opt_group.annotation_fontcolor_entry,
# NCC Tool
"tools_ncctools": self.ui.tools_defaults_form.tools_ncc_group.ncc_tool_dia_entry,
@@ -298,49 +587,17 @@ class PreferencesUIManager:
}
- self.sections = [
- ui.general_defaults_form,
- ui.gerber_defaults_form,
- ui.excellon_defaults_form,
- ui.geometry_defaults_form,
- ui.cncjob_defaults_form,
- ui.tools_defaults_form,
- ui.tools2_defaults_form,
- ui.util_defaults_form
- ]
-
- def get_form_fields(self) -> Dict[str, Any]:
- result = {}
- result.update(self.defaults_form_fields)
- result.update(self._option_field_dict())
- return result
-
- def get_form_field(self, option: str) -> Any:
- return self.get_form_fields()[option]
-
- def option_dict(self) -> Dict[str, OptionUI]:
- result = {}
- for section in self.sections:
- sectionoptions = section.option_dict()
- result.update(sectionoptions)
- return result
-
- def _option_field_dict(self):
- result = {k: v.get_field() for k, v in self.option_dict().items()}
- return result
-
def defaults_read_form(self):
"""
Will read all the values in the Preferences GUI and update the defaults dictionary.
:return: None
"""
- for option in self.get_form_fields():
- if option in self.defaults:
- try:
- self.defaults[option] = self.get_form_field(option=option).get_value()
- except Exception as e:
- log.debug("App.defaults_read_form() --> %s" % str(e))
+ for option in self.defaults_form_fields:
+ try:
+ self.defaults[option] = self.defaults_form_fields[option].get_value()
+ except Exception as e:
+ log.debug("App.defaults_read_form() --> %s" % str(e))
def defaults_write_form(self, factor=None, fl_units=None, source_dict=None):
"""
@@ -380,7 +637,7 @@ class PreferencesUIManager:
if factor is not None:
value *= factor
- form_field = self.get_form_field(option=field)
+ form_field = self.defaults_form_fields[field]
if units is None:
form_field.set_value(value)
elif (units == 'IN' or units == 'MM') and (field == 'global_gridx' or field == 'global_gridy'):
@@ -397,12 +654,70 @@ class PreferencesUIManager:
:return: None
"""
- # FIXME this should be done in __init__
- for section in self.sections:
- tab = section.build_tab()
- tab.setObjectName(section.get_tab_id())
- self.ui.pref_tab_area.addTab(tab, section.get_tab_label())
+ gen_form = self.ui.general_defaults_form
+ try:
+ self.ui.general_scroll_area.takeWidget()
+ except Exception:
+ log.debug("Nothing to remove")
+ self.ui.general_scroll_area.setWidget(gen_form)
+ gen_form.show()
+
+ ger_form = self.ui.gerber_defaults_form
+ try:
+ self.ui.gerber_scroll_area.takeWidget()
+ except Exception:
+ log.debug("Nothing to remove")
+ self.ui.gerber_scroll_area.setWidget(ger_form)
+ ger_form.show()
+
+ exc_form = self.ui.excellon_defaults_form
+ try:
+ self.ui.excellon_scroll_area.takeWidget()
+ except Exception:
+ log.debug("Nothing to remove")
+ self.ui.excellon_scroll_area.setWidget(exc_form)
+ exc_form.show()
+
+ geo_form = self.ui.geometry_defaults_form
+ try:
+ self.ui.geometry_scroll_area.takeWidget()
+ except Exception:
+ log.debug("Nothing to remove")
+ self.ui.geometry_scroll_area.setWidget(geo_form)
+ geo_form.show()
+
+ cnc_form = self.ui.cncjob_defaults_form
+ try:
+ self.ui.cncjob_scroll_area.takeWidget()
+ except Exception:
+ log.debug("Nothing to remove")
+ self.ui.cncjob_scroll_area.setWidget(cnc_form)
+ cnc_form.show()
+
+ tools_form = self.ui.tools_defaults_form
+ try:
+ self.ui.tools_scroll_area.takeWidget()
+ except Exception:
+ log.debug("Nothing to remove")
+ self.ui.tools_scroll_area.setWidget(tools_form)
+ tools_form.show()
+
+ tools2_form = self.ui.tools2_defaults_form
+ try:
+ self.ui.tools2_scroll_area.takeWidget()
+ except Exception:
+ log.debug("Nothing to remove")
+ self.ui.tools2_scroll_area.setWidget(tools2_form)
+ tools2_form.show()
+
+ fa_form = self.ui.util_defaults_form
+ try:
+ self.ui.fa_scroll_area.takeWidget()
+ except Exception:
+ log.debug("Nothing to remove")
+ self.ui.fa_scroll_area.setWidget(fa_form)
+ fa_form.show()
# Initialize the color box's color in Preferences -> Global -> Colo
self.__init_color_pickers()
@@ -416,6 +731,148 @@ class PreferencesUIManager:
log.debug("Finished Preferences GUI form initialization.")
def __init_color_pickers(self):
+ # Init Gerber Plot Colors
+ self.ui.gerber_defaults_form.gerber_gen_group.pf_color_entry.set_value(self.defaults['gerber_plot_fill'])
+ self.ui.gerber_defaults_form.gerber_gen_group.pf_color_button.setStyleSheet(
+ "background-color:%s;"
+ "border-color: dimgray" % str(self.defaults['gerber_plot_fill'])[:7])
+ self.ui.gerber_defaults_form.gerber_gen_group.pf_color_alpha_spinner.set_value(
+ int(self.defaults['gerber_plot_fill'][7:9], 16))
+ self.ui.gerber_defaults_form.gerber_gen_group.pf_color_alpha_slider.setValue(
+ int(self.defaults['gerber_plot_fill'][7:9], 16))
+
+ self.ui.gerber_defaults_form.gerber_gen_group.pl_color_entry.set_value(self.defaults['gerber_plot_line'])
+ self.ui.gerber_defaults_form.gerber_gen_group.pl_color_button.setStyleSheet(
+ "background-color:%s;"
+ "border-color: dimgray" % str(self.defaults['gerber_plot_line'])[:7])
+
+ # Init Excellon Plot Colors
+ self.ui.excellon_defaults_form.excellon_gen_group.fill_color_entry.set_value(
+ self.defaults['excellon_plot_fill'])
+ self.ui.excellon_defaults_form.excellon_gen_group.fill_color_button.setStyleSheet(
+ "background-color:%s;"
+ "border-color: dimgray" % str(self.defaults['excellon_plot_fill'])[:7])
+ self.ui.excellon_defaults_form.excellon_gen_group.color_alpha_spinner.set_value(
+ int(self.defaults['excellon_plot_fill'][7:9], 16))
+ self.ui.excellon_defaults_form.excellon_gen_group.color_alpha_slider.setValue(
+ int(self.defaults['excellon_plot_fill'][7:9], 16))
+
+ self.ui.excellon_defaults_form.excellon_gen_group.line_color_entry.set_value(
+ self.defaults['excellon_plot_line'])
+ self.ui.excellon_defaults_form.excellon_gen_group.line_color_button.setStyleSheet(
+ "background-color:%s;"
+ "border-color: dimgray" % str(self.defaults['excellon_plot_line'])[:7])
+
+ # Init Geometry Plot Colors
+ self.ui.geometry_defaults_form.geometry_gen_group.line_color_entry.set_value(
+ self.defaults['geometry_plot_line'])
+ self.ui.geometry_defaults_form.geometry_gen_group.line_color_button.setStyleSheet(
+ "background-color:%s;"
+ "border-color: dimgray" % str(self.defaults['geometry_plot_line'])[:7])
+
+ # Init CNCJob Travel Line Colors
+ self.ui.cncjob_defaults_form.cncjob_gen_group.tfill_color_entry.set_value(
+ self.defaults['cncjob_travel_fill'])
+ self.ui.cncjob_defaults_form.cncjob_gen_group.tfill_color_button.setStyleSheet(
+ "background-color:%s;"
+ "border-color: dimgray" % str(self.defaults['cncjob_travel_fill'])[:7])
+ self.ui.cncjob_defaults_form.cncjob_gen_group.tcolor_alpha_spinner.set_value(
+ int(self.defaults['cncjob_travel_fill'][7:9], 16))
+ self.ui.cncjob_defaults_form.cncjob_gen_group.tcolor_alpha_slider.setValue(
+ int(self.defaults['cncjob_travel_fill'][7:9], 16))
+
+ self.ui.cncjob_defaults_form.cncjob_gen_group.tline_color_entry.set_value(
+ self.defaults['cncjob_travel_line'])
+ self.ui.cncjob_defaults_form.cncjob_gen_group.tline_color_button.setStyleSheet(
+ "background-color:%s;"
+ "border-color: dimgray" % str(self.defaults['cncjob_travel_line'])[:7])
+
+ # Init CNCJob Plot Colors
+ self.ui.cncjob_defaults_form.cncjob_gen_group.fill_color_entry.set_value(
+ self.defaults['cncjob_plot_fill'])
+ self.ui.cncjob_defaults_form.cncjob_gen_group.fill_color_button.setStyleSheet(
+ "background-color:%s;"
+ "border-color: dimgray" % str(self.defaults['cncjob_plot_fill'])[:7])
+
+ self.ui.cncjob_defaults_form.cncjob_gen_group.line_color_entry.set_value(
+ self.defaults['cncjob_plot_line'])
+ self.ui.cncjob_defaults_form.cncjob_gen_group.line_color_button.setStyleSheet(
+ "background-color:%s;"
+ "border-color: dimgray" % str(self.defaults['cncjob_plot_line'])[:7])
+
+ # Init Left-Right Selection colors
+ self.ui.general_defaults_form.general_gui_group.sf_color_entry.set_value(self.defaults['global_sel_fill'])
+ self.ui.general_defaults_form.general_gui_group.sf_color_button.setStyleSheet(
+ "background-color:%s;"
+ "border-color: dimgray" % str(self.defaults['global_sel_fill'])[:7])
+ self.ui.general_defaults_form.general_gui_group.sf_color_alpha_spinner.set_value(
+ int(self.defaults['global_sel_fill'][7:9], 16))
+ self.ui.general_defaults_form.general_gui_group.sf_color_alpha_slider.setValue(
+ int(self.defaults['global_sel_fill'][7:9], 16))
+
+ self.ui.general_defaults_form.general_gui_group.sl_color_entry.set_value(self.defaults['global_sel_line'])
+ self.ui.general_defaults_form.general_gui_group.sl_color_button.setStyleSheet(
+ "background-color:%s;"
+ "border-color: dimgray" % str(self.defaults['global_sel_line'])[:7])
+
+ # Init Right-Left Selection colors
+ self.ui.general_defaults_form.general_gui_group.alt_sf_color_entry.set_value(
+ self.defaults['global_alt_sel_fill'])
+ self.ui.general_defaults_form.general_gui_group.alt_sf_color_button.setStyleSheet(
+ "background-color:%s;"
+ "border-color: dimgray" % str(self.defaults['global_alt_sel_fill'])[:7])
+ self.ui.general_defaults_form.general_gui_group.alt_sf_color_alpha_spinner.set_value(
+ int(self.defaults['global_sel_fill'][7:9], 16))
+ self.ui.general_defaults_form.general_gui_group.alt_sf_color_alpha_slider.setValue(
+ int(self.defaults['global_sel_fill'][7:9], 16))
+
+ self.ui.general_defaults_form.general_gui_group.alt_sl_color_entry.set_value(
+ self.defaults['global_alt_sel_line'])
+ self.ui.general_defaults_form.general_gui_group.alt_sl_color_button.setStyleSheet(
+ "background-color:%s;"
+ "border-color: dimgray" % str(self.defaults['global_alt_sel_line'])[:7])
+
+ # Init Draw color and Selection Draw Color
+ self.ui.general_defaults_form.general_gui_group.draw_color_entry.set_value(
+ self.defaults['global_draw_color'])
+ self.ui.general_defaults_form.general_gui_group.draw_color_button.setStyleSheet(
+ "background-color:%s;"
+ "border-color: dimgray" % str(self.defaults['global_draw_color'])[:7])
+
+ self.ui.general_defaults_form.general_gui_group.sel_draw_color_entry.set_value(
+ self.defaults['global_sel_draw_color'])
+ self.ui.general_defaults_form.general_gui_group.sel_draw_color_button.setStyleSheet(
+ "background-color:%s;"
+ "border-color: dimgray" % str(self.defaults['global_sel_draw_color'])[:7])
+
+ # Init Project Items color
+ self.ui.general_defaults_form.general_gui_group.proj_color_entry.set_value(
+ self.defaults['global_proj_item_color'])
+ self.ui.general_defaults_form.general_gui_group.proj_color_button.setStyleSheet(
+ "background-color:%s;"
+ "border-color: dimgray" % str(self.defaults['global_proj_item_color'])[:7])
+
+ # Init Project Disabled Items color
+ self.ui.general_defaults_form.general_gui_group.proj_color_dis_entry.set_value(
+ self.defaults['global_proj_item_dis_color'])
+ self.ui.general_defaults_form.general_gui_group.proj_color_dis_button.setStyleSheet(
+ "background-color:%s;"
+ "border-color: dimgray" % str(self.defaults['global_proj_item_dis_color'])[:7])
+
+ # Init Project Disabled Items color
+ self.ui.general_defaults_form.general_app_set_group.mouse_cursor_entry.set_value(
+ self.defaults['global_cursor_color'])
+ self.ui.general_defaults_form.general_app_set_group.mouse_cursor_button.setStyleSheet(
+ "background-color:%s;"
+ "border-color: dimgray" % str(self.defaults['global_cursor_color'])[:7])
+
+ # Init the Annotation CNC Job color
+ self.ui.cncjob_defaults_form.cncjob_adv_opt_group.annotation_fontcolor_entry.set_value(
+ self.defaults['cncjob_annotation_fontcolor'])
+ self.ui.cncjob_defaults_form.cncjob_adv_opt_group.annotation_fontcolor_button.setStyleSheet(
+ "background-color:%s;"
+ "border-color: dimgray" % str(self.defaults['cncjob_annotation_fontcolor'])[:7])
+
# Init the Tool Film color
self.ui.tools_defaults_form.tools_film_group.film_color_entry.set_value(
self.defaults['tools_film_color'])
@@ -464,8 +921,7 @@ class PreferencesUIManager:
theme = 'white'
should_restart = False
-
- val = self.get_form_field("global_theme").get_value()
+ val = self.ui.general_defaults_form.general_gui_group.theme_radio.get_value()
if val != theme:
msgbox = QtWidgets.QMessageBox()
msgbox.setText(_("Are you sure you want to continue?"))
@@ -500,20 +956,20 @@ class PreferencesUIManager:
settgs = QSettings("Open Source", "FlatCAM")
# save the notebook font size
- fsize = self.get_form_field("notebook_font_size").get_value()
+ fsize = self.ui.general_defaults_form.general_app_set_group.notebook_font_size_spinner.get_value()
settgs.setValue('notebook_font_size', fsize)
# save the axis font size
- g_fsize = self.get_form_field("axis_font_size").get_value()
+ g_fsize = self.ui.general_defaults_form.general_app_set_group.axis_font_size_spinner.get_value()
settgs.setValue('axis_font_size', g_fsize)
# save the textbox font size
- tb_fsize = self.get_form_field("textbox_font_size").get_value()
+ tb_fsize = self.ui.general_defaults_form.general_app_set_group.textbox_font_size_spinner.get_value()
settgs.setValue('textbox_font_size', tb_fsize)
settgs.setValue(
'machinist',
- 1 if self.get_form_field("global_machinist_setting").get_value() else 0
+ 1 if self.ui.general_defaults_form.general_app_set_group.machinist_cb.get_value() else 0
)
# This will write the setting to the platform specific storage.
@@ -536,11 +992,11 @@ class PreferencesUIManager:
self.ignore_tab_close_event = True
try:
- self.get_form_field("units").activated_custom.disconnect()
+ self.ui.general_defaults_form.general_app_group.units_radio.activated_custom.disconnect()
except (TypeError, AttributeError):
pass
self.defaults_write_form(source_dict=self.defaults.current_defaults)
- self.get_form_field("units").activated_custom.connect(
+ self.ui.general_defaults_form.general_app_group.units_radio.activated_custom.connect(
lambda: self.ui.app.on_toggle_units(no_pref=False))
self.defaults.update(self.defaults.current_defaults)
diff --git a/flatcamGUI/preferences/cncjob/CNCJobAdvOptPrefGroupUI.py b/flatcamGUI/preferences/cncjob/CNCJobAdvOptPrefGroupUI.py
index 5422e297..8d7a1cf0 100644
--- a/flatcamGUI/preferences/cncjob/CNCJobAdvOptPrefGroupUI.py
+++ b/flatcamGUI/preferences/cncjob/CNCJobAdvOptPrefGroupUI.py
@@ -1,7 +1,8 @@
-from PyQt5.QtCore import Qt
+from PyQt5 import QtWidgets, QtGui, QtCore
+from PyQt5.QtCore import QSettings, Qt
-from flatcamGUI.preferences.OptionUI import *
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI2
+from flatcamGUI.GUIElements import FCTextArea, FCCheckBox, FCComboBox, FCSpinner, FCEntry
+from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
import gettext
import FlatCAMTranslation as fcTranslate
import builtins
@@ -10,18 +11,93 @@ fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__:
_ = gettext.gettext
+settings = QSettings("Open Source", "FlatCAM")
+if settings.contains("machinist"):
+ machinist_setting = settings.value('machinist', type=int)
+else:
+ machinist_setting = 0
-class CNCJobAdvOptPrefGroupUI(OptionsGroupUI2):
- def __init__(self, decimals=4, **kwargs):
+class CNCJobAdvOptPrefGroupUI(OptionsGroupUI):
+ def __init__(self, decimals=4, parent=None):
+ # OptionsGroupUI.__init__(self, "CNC Job Advanced Options Preferences", parent=None)
+ super(CNCJobAdvOptPrefGroupUI, self).__init__(self, parent=parent)
self.decimals = decimals
- super().__init__(**kwargs)
+
self.setTitle(str(_("CNC Job Adv. Options")))
- self.toolchange_text = self.option_dict()["cncjob_toolchange_macro"].get_field()
+ # ## Export G-Code
+ self.export_gcode_label = QtWidgets.QLabel("%s:" % _("Export CNC Code"))
+ self.export_gcode_label.setToolTip(
+ _("Export and save G-Code to\n"
+ "make this object to a file.")
+ )
+ self.layout.addWidget(self.export_gcode_label)
+
+ # Prepend to G-Code
+ toolchangelabel = QtWidgets.QLabel('%s' % _('Toolchange G-Code'))
+ toolchangelabel.setToolTip(
+ _(
+ "Type here any G-Code commands you would\n"
+ "like to be executed when Toolchange event is encountered.\n"
+ "This will constitute a Custom Toolchange GCode,\n"
+ "or a Toolchange Macro.\n"
+ "The FlatCAM variables are surrounded by '%' symbol.\n\n"
+ "WARNING: it can be used only with a preprocessor file\n"
+ "that has 'toolchange_custom' in it's name and this is built\n"
+ "having as template the 'Toolchange Custom' posprocessor file."
+ )
+ )
+ self.layout.addWidget(toolchangelabel)
+
+ qsettings = QSettings("Open Source", "FlatCAM")
+ if qsettings.contains("textbox_font_size"):
+ tb_fsize = qsettings.value('textbox_font_size', type=int)
+ else:
+ tb_fsize = 10
+ font = QtGui.QFont()
+ font.setPointSize(tb_fsize)
+
+ self.toolchange_text = FCTextArea()
+ self.toolchange_text.setPlaceholderText(
+ _(
+ "Type here any G-Code commands you would "
+ "like to be executed when Toolchange event is encountered.\n"
+ "This will constitute a Custom Toolchange GCode, "
+ "or a Toolchange Macro.\n"
+ "The FlatCAM variables are surrounded by '%' symbol.\n"
+ "WARNING: it can be used only with a preprocessor file "
+ "that has 'toolchange_custom' in it's name."
+ )
+ )
+ self.layout.addWidget(self.toolchange_text)
+ self.toolchange_text.setFont(font)
+
+ hlay = QtWidgets.QHBoxLayout()
+ self.layout.addLayout(hlay)
+
+ # Toolchange Replacement GCode
+ self.toolchange_cb = FCCheckBox(label='%s' % _('Use Toolchange Macro'))
+ self.toolchange_cb.setToolTip(
+ _("Check this box if you want to use\n"
+ "a Custom Toolchange GCode (macro).")
+ )
+ hlay.addWidget(self.toolchange_cb)
+ hlay.addStretch()
+
+ hlay1 = QtWidgets.QHBoxLayout()
+ self.layout.addLayout(hlay1)
+
+ # Variable list
+ self.tc_variable_combo = FCComboBox()
+ self.tc_variable_combo.setToolTip(
+ _("A list of the FlatCAM variables that can be used\n"
+ "in the Toolchange event.\n"
+ "They have to be surrounded by the '%' symbol")
+ )
+ hlay1.addWidget(self.tc_variable_combo)
# Populate the Combo Box
- self.tc_variable_combo = self.option_dict()["__toolchange_variable"].get_field()
variables = [_('Parameters'), 'tool', 'tooldia', 't_drills', 'x_toolchange', 'y_toolchange', 'z_toolchange',
'z_cut', 'z_move', 'z_depthpercut', 'spindlespeed', 'dwelltime']
self.tc_variable_combo.addItems(variables)
@@ -50,58 +126,83 @@ class CNCJobAdvOptPrefGroupUI(OptionsGroupUI2):
_("dwelltime = time to dwell to allow the spindle to reach it's set RPM"),
Qt.ToolTipRole)
+ # hlay1.addStretch()
+
+ # Insert Variable into the Toolchange G-Code Text Box
+ # self.tc_insert_buton = FCButton("Insert")
+ # self.tc_insert_buton.setToolTip(
+ # "Insert the variable in the GCode Box\n"
+ # "surrounded by the '%' symbol."
+ # )
+ # hlay1.addWidget(self.tc_insert_buton)
+
+ grid0 = QtWidgets.QGridLayout()
+ self.layout.addLayout(grid0)
+
+ grid0.addWidget(QtWidgets.QLabel(''), 1, 0, 1, 2)
+
+ # Annotation Font Size
+ self.annotation_fontsize_label = QtWidgets.QLabel('%s:' % _("Annotation Size"))
+ self.annotation_fontsize_label.setToolTip(
+ _("The font size of the annotation text. In pixels.")
+ )
+ grid0.addWidget(self.annotation_fontsize_label, 2, 0)
+ self.annotation_fontsize_sp = FCSpinner()
+ self.annotation_fontsize_sp.set_range(0, 9999)
+
+ grid0.addWidget(self.annotation_fontsize_sp, 2, 1)
+ grid0.addWidget(QtWidgets.QLabel(''), 2, 2)
+
+ # Annotation Font Color
+ self.annotation_color_label = QtWidgets.QLabel('%s:' % _('Annotation Color'))
+ self.annotation_color_label.setToolTip(
+ _("Set the font color for the annotation texts.")
+ )
+ self.annotation_fontcolor_entry = FCEntry()
+ self.annotation_fontcolor_button = QtWidgets.QPushButton()
+ self.annotation_fontcolor_button.setFixedSize(15, 15)
+
+ self.form_box_child = QtWidgets.QHBoxLayout()
+ self.form_box_child.setContentsMargins(0, 0, 0, 0)
+ self.form_box_child.addWidget(self.annotation_fontcolor_entry)
+ self.form_box_child.addWidget(self.annotation_fontcolor_button, alignment=Qt.AlignRight)
+ self.form_box_child.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
+
+ color_widget = QtWidgets.QWidget()
+ color_widget.setLayout(self.form_box_child)
+ grid0.addWidget(self.annotation_color_label, 3, 0)
+ grid0.addWidget(color_widget, 3, 1)
+ grid0.addWidget(QtWidgets.QLabel(''), 3, 2)
+
+ self.layout.addStretch()
+
self.tc_variable_combo.currentIndexChanged[str].connect(self.on_cnc_custom_parameters)
- def build_options(self) -> [OptionUI]:
- return [
- HeadingOptionUI(
- label_text="Export CNC Code",
- label_tooltip="Export and save G-Code to\n"
- "make this object to a file."
- ),
- CheckboxOptionUI(
- option="cncjob_toolchange_macro_enable",
- label_text="Use Toolchange Macro",
- label_tooltip="Check this box if you want to use\n"
- "a Custom Toolchange GCode (macro)."
- ),
- TextAreaOptionUI(
- option="cncjob_toolchange_macro",
- label_text="Toolchange G-Code",
- label_tooltip="Type here any G-Code commands you would "
- "like to be executed when Toolchange event is encountered.\n"
- "This will constitute a Custom Toolchange GCode, "
- "or a Toolchange Macro.\n"
- "The FlatCAM variables are surrounded by '%' symbol.\n"
- "WARNING: it can be used only with a preprocessor file "
- "that has 'toolchange_custom' in it's name."
- ),
- ComboboxOptionUI(
- option="__toolchange_variable",
- label_text="Insert variable",
- label_tooltip="A list of the FlatCAM variables that can be used\n"
- "in the Toolchange event.\n"
- "They have to be surrounded by the '%' symbol",
- choices=[] # see init.
- ),
-
- SpinnerOptionUI(
- option="cncjob_annotation_fontsize",
- label_text="Annotation Size",
- label_tooltip="The font size of the annotation text. In pixels.",
- min_value=1, max_value=9999, step=1
- ),
- ColorOptionUI(
- option="cncjob_annotation_fontcolor",
- label_text="Annotation Color",
- label_tooltip="Set the font color for the annotation texts."
- )
- ]
+ self.annotation_fontcolor_entry.editingFinished.connect(self.on_annotation_fontcolor_entry)
+ self.annotation_fontcolor_button.clicked.connect(self.on_annotation_fontcolor_button)
def on_cnc_custom_parameters(self, signal_text):
- if signal_text == _("Parameters"):
+ if signal_text == 'Parameters':
return
else:
self.toolchange_text.insertPlainText('%%%s%%' % signal_text)
- self.tc_variable_combo.set_value(_("Parameters"))
+ def on_annotation_fontcolor_entry(self):
+ self.app.defaults['cncjob_annotation_fontcolor'] = self.annotation_fontcolor_entry.get_value()
+ self.annotation_fontcolor_button.setStyleSheet(
+ "background-color:%s" % str(self.app.defaults['cncjob_annotation_fontcolor']))
+
+ def on_annotation_fontcolor_button(self):
+ current_color = QtGui.QColor(self.app.defaults['cncjob_annotation_fontcolor'])
+
+ c_dialog = QtWidgets.QColorDialog()
+ annotation_color = c_dialog.getColor(initial=current_color)
+
+ if annotation_color.isValid() is False:
+ return
+
+ self.annotation_fontcolor_button.setStyleSheet("background-color:%s" % str(annotation_color.name()))
+
+ new_val_sel = str(annotation_color.name())
+ self.annotation_fontcolor_entry.set_value(new_val_sel)
+ self.app.defaults['cncjob_annotation_fontcolor'] = new_val_sel
diff --git a/flatcamGUI/preferences/cncjob/CNCJobGenPrefGroupUI.py b/flatcamGUI/preferences/cncjob/CNCJobGenPrefGroupUI.py
index e999fb6e..66276e23 100644
--- a/flatcamGUI/preferences/cncjob/CNCJobGenPrefGroupUI.py
+++ b/flatcamGUI/preferences/cncjob/CNCJobGenPrefGroupUI.py
@@ -1,142 +1,389 @@
-from flatcamGUI.preferences.OptionUI import *
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI2
+from PyQt5 import QtWidgets, QtCore, QtGui
+from PyQt5.QtCore import QSettings
+from flatcamGUI.GUIElements import FCCheckBox, RadioSet, FCSpinner, FCDoubleSpinner, FCEntry
+from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
import gettext
import FlatCAMTranslation as fcTranslate
import builtins
+
fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__:
_ = gettext.gettext
+settings = QSettings("Open Source", "FlatCAM")
+if settings.contains("machinist"):
+ machinist_setting = settings.value('machinist', type=int)
+else:
+ machinist_setting = 0
-class CNCJobGenPrefGroupUI(OptionsGroupUI2):
- def __init__(self, decimals=4, **kwargs):
- self.decimals = decimals
- super().__init__(**kwargs)
+class CNCJobGenPrefGroupUI(OptionsGroupUI):
+ def __init__(self, decimals=4, parent=None):
+ # OptionsGroupUI.__init__(self, "CNC Job General Preferences", parent=None)
+ super(CNCJobGenPrefGroupUI, self).__init__(self, parent=parent)
+
self.setTitle(str(_("CNC Job General")))
+ self.decimals = decimals
+
+ # ## Plot options
+ self.plot_options_label = QtWidgets.QLabel("%s:" % _("Plot Options"))
+ self.layout.addWidget(self.plot_options_label)
+
+ grid0 = QtWidgets.QGridLayout()
+ self.layout.addLayout(grid0)
+ grid0.setColumnStretch(0, 0)
+ grid0.setColumnStretch(1, 1)
+
+ # Plot CB
+ # self.plot_cb = QtWidgets.QCheckBox('Plot')
+ self.plot_cb = FCCheckBox(_('Plot Object'))
+ self.plot_cb.setToolTip(_("Plot (show) this object."))
+ grid0.addWidget(self.plot_cb, 0, 0, 1, 2)
+
+ # Plot Kind
+ self.cncplot_method_label = QtWidgets.QLabel('%s:' % _("Plot kind"))
+ self.cncplot_method_label.setToolTip(
+ _("This selects the kind of geometries on the canvas to plot.\n"
+ "Those can be either of type 'Travel' which means the moves\n"
+ "above the work piece or it can be of type 'Cut',\n"
+ "which means the moves that cut into the material.")
+ )
+
+ self.cncplot_method_radio = RadioSet([
+ {"label": _("All"), "value": "all"},
+ {"label": _("Travel"), "value": "travel"},
+ {"label": _("Cut"), "value": "cut"}
+ ], orientation='vertical')
+
+ grid0.addWidget(self.cncplot_method_label, 1, 0)
+ grid0.addWidget(self.cncplot_method_radio, 1, 1)
+ grid0.addWidget(QtWidgets.QLabel(''), 1, 2)
+
+ # Display Annotation
+ self.annotation_cb = FCCheckBox(_("Display Annotation"))
+ self.annotation_cb.setToolTip(
+ _("This selects if to display text annotation on the plot.\n"
+ "When checked it will display numbers in order for each end\n"
+ "of a travel line."
+ )
+ )
+
+ grid0.addWidget(self.annotation_cb, 2, 0, 1, 3)
+
+ # ###################################################################
+ # Number of circle steps for circular aperture linear approximation #
+ # ###################################################################
+ self.steps_per_circle_label = QtWidgets.QLabel('%s:' % _("Circle Steps"))
+ self.steps_per_circle_label.setToolTip(
+ _("The number of circle steps for GCode \n"
+ "circle and arc shapes linear approximation.")
+ )
+ grid0.addWidget(self.steps_per_circle_label, 3, 0)
+ self.steps_per_circle_entry = FCSpinner()
+ self.steps_per_circle_entry.set_range(0, 99999)
+ grid0.addWidget(self.steps_per_circle_entry, 3, 1)
+
+ # Tool dia for plot
+ tdlabel = QtWidgets.QLabel('%s:' % _('Travel dia'))
+ tdlabel.setToolTip(
+ _("The width of the travel lines to be\n"
+ "rendered in the plot.")
+ )
+ self.tooldia_entry = FCDoubleSpinner()
+ self.tooldia_entry.set_range(0, 99999)
+ self.tooldia_entry.set_precision(self.decimals)
+ self.tooldia_entry.setSingleStep(0.1)
+ self.tooldia_entry.setWrapping(True)
+
+ grid0.addWidget(tdlabel, 4, 0)
+ grid0.addWidget(self.tooldia_entry, 4, 1)
+
+ # add a space
+ grid0.addWidget(QtWidgets.QLabel('%s:' % _("G-code Decimals")), 5, 0, 1, 2)
+
+ # Number of decimals to use in GCODE coordinates
+ cdeclabel = QtWidgets.QLabel('%s:' % _('Coordinates'))
+ cdeclabel.setToolTip(
+ _("The number of decimals to be used for \n"
+ "the X, Y, Z coordinates in CNC code (GCODE, etc.)")
+ )
+ self.coords_dec_entry = FCSpinner()
+ self.coords_dec_entry.set_range(0, 9)
+ self.coords_dec_entry.setWrapping(True)
+
+ grid0.addWidget(cdeclabel, 6, 0)
+ grid0.addWidget(self.coords_dec_entry, 6, 1)
+
+ # Number of decimals to use in GCODE feedrate
+ frdeclabel = QtWidgets.QLabel('%s:' % _('Feedrate'))
+ frdeclabel.setToolTip(
+ _("The number of decimals to be used for \n"
+ "the Feedrate parameter in CNC code (GCODE, etc.)")
+ )
+ self.fr_dec_entry = FCSpinner()
+ self.fr_dec_entry.set_range(0, 9)
+ self.fr_dec_entry.setWrapping(True)
+
+ grid0.addWidget(frdeclabel, 7, 0)
+ grid0.addWidget(self.fr_dec_entry, 7, 1)
+
+ # The type of coordinates used in the Gcode: Absolute or Incremental
+ coords_type_label = QtWidgets.QLabel('%s:' % _('Coordinates type'))
+ coords_type_label.setToolTip(
+ _("The type of coordinates to be used in Gcode.\n"
+ "Can be:\n"
+ "- Absolute G90 -> the reference is the origin x=0, y=0\n"
+ "- Incremental G91 -> the reference is the previous position")
+ )
+ self.coords_type_radio = RadioSet([
+ {"label": _("Absolute G90"), "value": "G90"},
+ {"label": _("Incremental G91"), "value": "G91"}
+ ], orientation='vertical', stretch=False)
+ grid0.addWidget(coords_type_label, 8, 0)
+ grid0.addWidget(self.coords_type_radio, 8, 1)
# hidden for the time being, until implemented
- self.option_dict()["cncjob_coords_type"].label_widget.hide()
- self.option_dict()["cncjob_coords_type"].get_field().hide()
+ coords_type_label.hide()
+ self.coords_type_radio.hide()
- def build_options(self) -> [OptionUI]:
- return [
- HeadingOptionUI(label_text="Plot Options"),
- CheckboxOptionUI(
- option="cncjob_plot",
- label_text="Plot Object",
- label_tooltip="Plot (show) this object."
- ),
- RadioSetOptionUI(
- option="cncjob_plot_kind",
- label_text="Plot kind",
- label_tooltip="This selects the kind of geometries on the canvas to plot.\n"
- "Those can be either of type 'Travel' which means the moves\n"
- "above the work piece or it can be of type 'Cut',\n"
- "which means the moves that cut into the material.",
- choices=[
- {"label": _("All"), "value": "all"},
- {"label": _("Travel"), "value": "travel"},
- {"label": _("Cut"), "value": "cut"}
- ],
- orientation="vertical"
- ),
- CheckboxOptionUI(
- option="cncjob_annotation",
- label_text="Display Annotation",
- label_tooltip="This selects if to display text annotation on the plot.\n"
- "When checked it will display numbers in order for each end\n"
- "of a travel line."
- ),
- SpinnerOptionUI(
- option="cncjob_steps_per_circle",
- label_text="Circle Steps",
- label_tooltip="The number of circle steps for GCode \n"
- "circle and arc shapes linear approximation.",
- min_value=3, max_value=99999, step=1
- ),
- DoubleSpinnerOptionUI(
- option="cncjob_tooldia",
- label_text="Travel dia",
- label_tooltip="The width of the travel lines to be\n"
- "rendered in the plot.",
- min_value=0, max_value=99999, step=0.1, decimals=self.decimals
- ),
+ # Line Endings
+ self.line_ending_cb = FCCheckBox(_("Force Windows style line-ending"))
+ self.line_ending_cb.setToolTip(
+ _("When checked will force a Windows style line-ending\n"
+ "(\\r\\n) on non-Windows OS's.")
+ )
- HeadingOptionUI(label_text="G-code Decimals"),
- SpinnerOptionUI(
- option="cncjob_coords_decimals",
- label_text="Coordinates",
- label_tooltip="The number of decimals to be used for \n"
- "the X, Y, Z coordinates in CNC code (GCODE, etc.)",
- min_value=0, max_value=9, step=1
- ),
- SpinnerOptionUI(
- option="cncjob_fr_decimals",
- label_text="Feedrate",
- label_tooltip="The number of decimals to be used for \n"
- "the Feedrate parameter in CNC code (GCODE, etc.)",
- min_value=0, max_value=9, step=1
- ),
- RadioSetOptionUI(
- option="cncjob_coords_type",
- label_text="Coordinates type",
- label_tooltip="The type of coordinates to be used in Gcode.\n"
- "Can be:\n"
- "- Absolute G90 -> the reference is the origin x=0, y=0\n"
- "- Incremental G91 -> the reference is the previous position",
- choices=[
- {"label": _("Absolute G90"), "value": "G90"},
- {"label": _("Incremental G91"), "value": "G91"}
- ],
- orientation="vertical"
- ),
- CheckboxOptionUI(
- option="cncjob_line_ending",
- label_text="Force Windows style line-ending",
- label_tooltip="When checked will force a Windows style line-ending\n"
- "(\\r\\n) on non-Windows OS's."
- ),
- SeparatorOptionUI(),
+ grid0.addWidget(self.line_ending_cb, 9, 0, 1, 3)
- HeadingOptionUI(label_text="Travel Line Color"),
- ColorOptionUI(
- option="cncjob_travel_line",
- label_text="Outline",
- label_tooltip="Set the line color for plotted objects.",
- ),
- ColorOptionUI(
- option="cncjob_travel_fill",
- label_text="Fill",
- label_tooltip="Set the fill color for plotted objects.\n"
- "First 6 digits are the color and the last 2\n"
- "digits are for alpha (transparency) level."
- ),
- ColorAlphaSliderOptionUI(
- applies_to=["cncjob_travel_line", "cncjob_travel_fill"],
- group=self,
- label_text="Alpha",
- label_tooltip="Set the transparency for plotted objects."
- ),
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid0.addWidget(separator_line, 12, 0, 1, 2)
- HeadingOptionUI(label_text="CNCJob Object Color"),
- ColorOptionUI(
- option="cncjob_plot_line",
- label_text="Outline",
- label_tooltip="Set the line color for plotted objects.",
- ),
- ColorOptionUI(
- option="cncjob_plot_fill",
- label_text="Fill",
- label_tooltip="Set the fill color for plotted objects.\n"
- "First 6 digits are the color and the last 2\n"
- "digits are for alpha (transparency) level."
- ),
- ColorAlphaSliderOptionUI(
- applies_to=["cncjob_plot_line", "cncjob_plot_fill"],
- group=self,
- label_text="Alpha",
- label_tooltip="Set the transparency for plotted objects."
- )
- ]
\ No newline at end of file
+ # Travel Line Color
+ self.travel_color_label = QtWidgets.QLabel('%s' % _('Travel Line Color'))
+ grid0.addWidget(self.travel_color_label, 13, 0, 1, 2)
+
+ # Plot Line Color
+ self.tline_color_label = QtWidgets.QLabel('%s:' % _('Outline'))
+ self.tline_color_label.setToolTip(
+ _("Set the travel line color for plotted objects.")
+ )
+ self.tline_color_entry = FCEntry()
+ self.tline_color_button = QtWidgets.QPushButton()
+ self.tline_color_button.setFixedSize(15, 15)
+
+ self.form_box_child_2 = QtWidgets.QHBoxLayout()
+ self.form_box_child_2.addWidget(self.tline_color_entry)
+ self.form_box_child_2.addWidget(self.tline_color_button)
+ self.form_box_child_2.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
+
+ grid0.addWidget(self.tline_color_label, 14, 0)
+ grid0.addLayout(self.form_box_child_2, 14, 1)
+
+ # Plot Fill Color
+ self.tfill_color_label = QtWidgets.QLabel('%s:' % _('Fill'))
+ self.tfill_color_label.setToolTip(
+ _("Set the fill color for plotted objects.\n"
+ "First 6 digits are the color and the last 2\n"
+ "digits are for alpha (transparency) level.")
+ )
+ self.tfill_color_entry = FCEntry()
+ self.tfill_color_button = QtWidgets.QPushButton()
+ self.tfill_color_button.setFixedSize(15, 15)
+
+ self.form_box_child_1 = QtWidgets.QHBoxLayout()
+ self.form_box_child_1.addWidget(self.tfill_color_entry)
+ self.form_box_child_1.addWidget(self.tfill_color_button)
+ self.form_box_child_1.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
+
+ grid0.addWidget(self.tfill_color_label, 15, 0)
+ grid0.addLayout(self.form_box_child_1, 15, 1)
+
+ # Plot Fill Transparency Level
+ self.alpha_label = QtWidgets.QLabel('%s:' % _('Alpha'))
+ self.alpha_label.setToolTip(
+ _("Set the fill transparency for plotted objects.")
+ )
+ self.tcolor_alpha_slider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
+ self.tcolor_alpha_slider.setMinimum(0)
+ self.tcolor_alpha_slider.setMaximum(255)
+ self.tcolor_alpha_slider.setSingleStep(1)
+
+ self.tcolor_alpha_spinner = FCSpinner()
+ self.tcolor_alpha_spinner.setMinimumWidth(70)
+ self.tcolor_alpha_spinner.set_range(0, 255)
+
+ self.form_box_child_3 = QtWidgets.QHBoxLayout()
+ self.form_box_child_3.addWidget(self.tcolor_alpha_slider)
+ self.form_box_child_3.addWidget(self.tcolor_alpha_spinner)
+
+ grid0.addWidget(self.alpha_label, 16, 0)
+ grid0.addLayout(self.form_box_child_3, 16, 1)
+
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid0.addWidget(separator_line, 17, 0, 1, 2)
+
+ # CNCJob Object Color
+ self.cnc_color_label = QtWidgets.QLabel('%s' % _('CNCJob Object Color'))
+ grid0.addWidget(self.cnc_color_label, 18, 0, 1, 2)
+
+ # Plot Line Color
+ self.line_color_label = QtWidgets.QLabel('%s:' % _('Outline'))
+ self.line_color_label.setToolTip(
+ _("Set the color for plotted objects.")
+ )
+ self.line_color_entry = FCEntry()
+ self.line_color_button = QtWidgets.QPushButton()
+ self.line_color_button.setFixedSize(15, 15)
+
+ self.form_box_child_2 = QtWidgets.QHBoxLayout()
+ self.form_box_child_2.addWidget(self.line_color_entry)
+ self.form_box_child_2.addWidget(self.line_color_button)
+ self.form_box_child_2.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
+
+ grid0.addWidget(self.line_color_label, 19, 0)
+ grid0.addLayout(self.form_box_child_2, 19, 1)
+
+ # Plot Fill Color
+ self.fill_color_label = QtWidgets.QLabel('%s:' % _('Fill'))
+ self.fill_color_label.setToolTip(
+ _("Set the fill color for plotted objects.\n"
+ "First 6 digits are the color and the last 2\n"
+ "digits are for alpha (transparency) level.")
+ )
+ self.fill_color_entry = FCEntry()
+ self.fill_color_button = QtWidgets.QPushButton()
+ self.fill_color_button.setFixedSize(15, 15)
+
+ self.form_box_child_1 = QtWidgets.QHBoxLayout()
+ self.form_box_child_1.addWidget(self.fill_color_entry)
+ self.form_box_child_1.addWidget(self.fill_color_button)
+ self.form_box_child_1.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
+
+ grid0.addWidget(self.fill_color_label, 20, 0)
+ grid0.addLayout(self.form_box_child_1, 20, 1)
+
+ self.layout.addStretch()
+
+ # Setting plot colors signals
+ self.tline_color_entry.editingFinished.connect(self.on_tline_color_entry)
+ self.tline_color_button.clicked.connect(self.on_tline_color_button)
+ self.tfill_color_entry.editingFinished.connect(self.on_tfill_color_entry)
+ self.tfill_color_button.clicked.connect(self.on_tfill_color_button)
+ self.tcolor_alpha_spinner.valueChanged.connect(self.on_tcolor_spinner)
+ self.tcolor_alpha_slider.valueChanged.connect(self.on_tcolor_slider)
+
+ self.line_color_entry.editingFinished.connect(self.on_line_color_entry)
+ self.line_color_button.clicked.connect(self.on_line_color_button)
+ self.fill_color_entry.editingFinished.connect(self.on_fill_color_entry)
+ self.fill_color_button.clicked.connect(self.on_fill_color_button)
+
+ # ------------------------------------------------------
+ # Setting travel colors handlers
+ # ------------------------------------------------------
+ def on_tfill_color_entry(self):
+ self.app.defaults['cncjob_travel_fill'] = self.tfill_color_entry.get_value()[:7] + \
+ self.app.defaults['cncjob_travel_fill'][7:9]
+ self.tfill_color_button.setStyleSheet(
+ "background-color:%s" % str(self.app.defaults['cncjob_travel_fill'])[:7])
+
+ def on_tfill_color_button(self):
+ current_color = QtGui.QColor(self.app.defaults['cncjob_travel_fill'][:7])
+
+ c_dialog = QtWidgets.QColorDialog()
+ plot_fill_color = c_dialog.getColor(initial=current_color)
+
+ if plot_fill_color.isValid() is False:
+ return
+
+ self.tfill_color_button.setStyleSheet("background-color:%s" % str(plot_fill_color.name()))
+
+ new_val = str(plot_fill_color.name()) + str(self.app.defaults['cncjob_travel_fill'][7:9])
+ self.tfill_color_entry.set_value(new_val)
+ self.app.defaults['cncjob_travel_fill'] = new_val
+
+ def on_tcolor_spinner(self):
+ spinner_value = self.tcolor_alpha_spinner.value()
+ self.tcolor_alpha_slider.setValue(spinner_value)
+ self.app.defaults['cncjob_travel_fill'] = \
+ self.app.defaults['cncjob_travel_fill'][:7] + \
+ (hex(spinner_value)[2:] if int(hex(spinner_value)[2:], 16) > 0 else '00')
+ self.app.defaults['cncjob_travel_line'] = \
+ self.app.defaults['cncjob_travel_line'][:7] + \
+ (hex(spinner_value)[2:] if int(hex(spinner_value)[2:], 16) > 0 else '00')
+
+ def on_tcolor_slider(self):
+ slider_value = self.tcolor_alpha_slider.value()
+ self.tcolor_alpha_spinner.setValue(slider_value)
+
+ def on_tline_color_entry(self):
+ self.app.defaults['cncjob_travel_line'] = self.tline_color_entry.get_value()[:7] + \
+ self.app.defaults['cncjob_travel_line'][7:9]
+ self.tline_color_button.setStyleSheet(
+ "background-color:%s" % str(self.app.defaults['cncjob_travel_line'])[:7])
+
+ def on_tline_color_button(self):
+ current_color = QtGui.QColor(self.app.defaults['cncjob_travel_line'][:7])
+ # print(current_color)
+
+ c_dialog = QtWidgets.QColorDialog()
+ plot_line_color = c_dialog.getColor(initial=current_color)
+
+ if plot_line_color.isValid() is False:
+ return
+
+ self.tline_color_button.setStyleSheet("background-color:%s" % str(plot_line_color.name()))
+
+ new_val_line = str(plot_line_color.name()) + str(self.app.defaults['cncjob_travel_line'][7:9])
+ self.tline_color_entry.set_value(new_val_line)
+ self.app.defaults['cncjob_travel_line'] = new_val_line
+
+ # ------------------------------------------------------
+ # Setting plot colors handlers
+ # ------------------------------------------------------
+ def on_fill_color_entry(self):
+ self.app.defaults['cncjob_plot_fill'] = self.fill_color_entry.get_value()[:7] + \
+ self.app.defaults['cncjob_plot_fill'][7:9]
+ self.fill_color_button.setStyleSheet(
+ "background-color:%s" % str(self.app.defaults['cncjob_plot_fill'])[:7])
+
+ def on_fill_color_button(self):
+ current_color = QtGui.QColor(self.app.defaults['cncjob_plot_fill'][:7])
+
+ c_dialog = QtWidgets.QColorDialog()
+ plot_fill_color = c_dialog.getColor(initial=current_color)
+
+ if plot_fill_color.isValid() is False:
+ return
+
+ self.fill_color_button.setStyleSheet("background-color:%s" % str(plot_fill_color.name()))
+
+ new_val = str(plot_fill_color.name()) + str(self.app.defaults['cncjob_plot_fill'][7:9])
+ self.fill_color_entry.set_value(new_val)
+ self.app.defaults['cncjob_plot_fill'] = new_val
+
+ def on_line_color_entry(self):
+ self.app.defaults['cncjob_plot_line'] = self.line_color_entry.get_value()[:7] + \
+ self.app.defaults['cncjob_plot_line'][7:9]
+ self.line_color_button.setStyleSheet(
+ "background-color:%s" % str(self.app.defaults['cncjob_plot_line'])[:7])
+
+ def on_line_color_button(self):
+ current_color = QtGui.QColor(self.app.defaults['cncjob_plot_line'][:7])
+ # print(current_color)
+
+ c_dialog = QtWidgets.QColorDialog()
+ plot_line_color = c_dialog.getColor(initial=current_color)
+
+ if plot_line_color.isValid() is False:
+ return
+
+ self.line_color_button.setStyleSheet("background-color:%s" % str(plot_line_color.name()))
+
+ new_val_line = str(plot_line_color.name()) + str(self.app.defaults['cncjob_plot_line'][7:9])
+ self.line_color_entry.set_value(new_val_line)
+ self.app.defaults['cncjob_plot_line'] = new_val_line
diff --git a/flatcamGUI/preferences/cncjob/CNCJobOptPrefGroupUI.py b/flatcamGUI/preferences/cncjob/CNCJobOptPrefGroupUI.py
index eefaee28..c8eb7e66 100644
--- a/flatcamGUI/preferences/cncjob/CNCJobOptPrefGroupUI.py
+++ b/flatcamGUI/preferences/cncjob/CNCJobOptPrefGroupUI.py
@@ -1,39 +1,80 @@
-from flatcamGUI.preferences.OptionUI import *
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI2
+from PyQt5 import QtWidgets, QtGui
+from PyQt5.QtCore import QSettings
+
+from flatcamGUI.GUIElements import FCTextArea
+from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
import gettext
import FlatCAMTranslation as fcTranslate
import builtins
+
fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__:
_ = gettext.gettext
+settings = QSettings("Open Source", "FlatCAM")
+if settings.contains("machinist"):
+ machinist_setting = settings.value('machinist', type=int)
+else:
+ machinist_setting = 0
-class CNCJobOptPrefGroupUI(OptionsGroupUI2):
- def __init__(self, decimals=4, **kwargs):
- self.decimals = decimals
- super().__init__(**kwargs)
+class CNCJobOptPrefGroupUI(OptionsGroupUI):
+ def __init__(self, decimals=4, parent=None):
+ # OptionsGroupUI.__init__(self, "CNC Job Options Preferences", parent=None)
+ super(CNCJobOptPrefGroupUI, self).__init__(self, parent=parent)
+
self.setTitle(str(_("CNC Job Options")))
+ self.decimals = decimals
- def build_options(self) -> [OptionUI]:
- return [
- HeadingOptionUI(
- label_text="Export G-Code",
- label_tooltip="Export and save G-Code to\n"
- "make this object to a file."
- ),
- TextAreaOptionUI(
- option="cncjob_prepend",
- label_text="Prepend to G-Code",
- label_tooltip="Type here any G-Code commands you would\n"
- "like to add at the beginning of the G-Code file."
- ),
- TextAreaOptionUI(
- option="cncjob_append",
- label_text="Append to G-Code",
- label_tooltip="Type here any G-Code commands you would\n"
- "like to append to the generated file.\n"
- "I.e.: M2 (End of program)"
- )
- ]
+ # ## Export G-Code
+ self.export_gcode_label = QtWidgets.QLabel("%s:" % _("Export G-Code"))
+ self.export_gcode_label.setToolTip(
+ _("Export and save G-Code to\n"
+ "make this object to a file.")
+ )
+ self.layout.addWidget(self.export_gcode_label)
+
+ qsettings = QSettings("Open Source", "FlatCAM")
+ if qsettings.contains("textbox_font_size"):
+ tb_fsize = qsettings.value('textbox_font_size', type=int)
+ else:
+ tb_fsize = 10
+ font = QtGui.QFont()
+ font.setPointSize(tb_fsize)
+
+ # Prepend to G-Code
+ prependlabel = QtWidgets.QLabel('%s:' % _('Prepend to G-Code'))
+ prependlabel.setToolTip(
+ _("Type here any G-Code commands you would\n"
+ "like to add at the beginning of the G-Code file.")
+ )
+ self.layout.addWidget(prependlabel)
+
+ self.prepend_text = FCTextArea()
+ self.prepend_text.setPlaceholderText(
+ _("Type here any G-Code commands you would "
+ "like to add at the beginning of the G-Code file.")
+ )
+ self.layout.addWidget(self.prepend_text)
+ self.prepend_text.setFont(font)
+
+ # Append text to G-Code
+ appendlabel = QtWidgets.QLabel('%s:' % _('Append to G-Code'))
+ appendlabel.setToolTip(
+ _("Type here any G-Code commands you would\n"
+ "like to append to the generated file.\n"
+ "I.e.: M2 (End of program)")
+ )
+ self.layout.addWidget(appendlabel)
+
+ self.append_text = FCTextArea()
+ self.append_text.setPlaceholderText(
+ _("Type here any G-Code commands you would "
+ "like to append to the generated file.\n"
+ "I.e.: M2 (End of program)")
+ )
+ self.layout.addWidget(self.append_text)
+ self.append_text.setFont(font)
+
+ self.layout.addStretch()
diff --git a/flatcamGUI/preferences/cncjob/CNCJobPreferencesUI.py b/flatcamGUI/preferences/cncjob/CNCJobPreferencesUI.py
index d81134d8..cc9a7e32 100644
--- a/flatcamGUI/preferences/cncjob/CNCJobPreferencesUI.py
+++ b/flatcamGUI/preferences/cncjob/CNCJobPreferencesUI.py
@@ -1,33 +1,27 @@
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
-from flatcamGUI.preferences.PreferencesSectionUI import PreferencesSectionUI
+from PyQt5 import QtWidgets
+
from flatcamGUI.preferences.cncjob.CNCJobAdvOptPrefGroupUI import CNCJobAdvOptPrefGroupUI
from flatcamGUI.preferences.cncjob.CNCJobOptPrefGroupUI import CNCJobOptPrefGroupUI
from flatcamGUI.preferences.cncjob.CNCJobGenPrefGroupUI import CNCJobGenPrefGroupUI
-import gettext
-import FlatCAMTranslation as fcTranslate
-import builtins
-fcTranslate.apply_language('strings')
-if '_' not in builtins.__dict__:
- _ = gettext.gettext
+class CNCJobPreferencesUI(QtWidgets.QWidget):
-class CNCJobPreferencesUI(PreferencesSectionUI):
-
- def __init__(self, decimals, **kwargs):
+ def __init__(self, decimals, parent=None):
+ QtWidgets.QWidget.__init__(self, parent=parent)
+ self.layout = QtWidgets.QHBoxLayout()
+ self.setLayout(self.layout)
self.decimals = decimals
- super().__init__(**kwargs)
- def build_groups(self) -> [OptionsGroupUI]:
- return [
- CNCJobGenPrefGroupUI(decimals=self.decimals),
- CNCJobOptPrefGroupUI(decimals=self.decimals),
- CNCJobAdvOptPrefGroupUI(decimals=self.decimals)
- ]
+ self.cncjob_gen_group = CNCJobGenPrefGroupUI(decimals=self.decimals)
+ self.cncjob_gen_group.setMinimumWidth(260)
+ self.cncjob_opt_group = CNCJobOptPrefGroupUI(decimals=self.decimals)
+ self.cncjob_opt_group.setMinimumWidth(260)
+ self.cncjob_adv_opt_group = CNCJobAdvOptPrefGroupUI(decimals=self.decimals)
+ self.cncjob_adv_opt_group.setMinimumWidth(260)
- def get_tab_id(self):
- # FIXME this doesn't seem right
- return "text_editor_tab"
+ self.layout.addWidget(self.cncjob_gen_group)
+ self.layout.addWidget(self.cncjob_opt_group)
+ self.layout.addWidget(self.cncjob_adv_opt_group)
- def get_tab_label(self):
- return _("CNC-JOB")
\ No newline at end of file
+ self.layout.addStretch()
diff --git a/flatcamGUI/preferences/excellon/ExcellonAdvOptPrefGroupUI.py b/flatcamGUI/preferences/excellon/ExcellonAdvOptPrefGroupUI.py
index 321fc21b..a63998f9 100644
--- a/flatcamGUI/preferences/excellon/ExcellonAdvOptPrefGroupUI.py
+++ b/flatcamGUI/preferences/excellon/ExcellonAdvOptPrefGroupUI.py
@@ -1,97 +1,155 @@
-from flatcamGUI.preferences.OptionUI import *
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI2
+from PyQt5 import QtWidgets
+from PyQt5.QtCore import QSettings
+from flatcamGUI.GUIElements import FCDoubleSpinner, FCEntry, FloatEntry, RadioSet, FCCheckBox
+from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
import gettext
import FlatCAMTranslation as fcTranslate
import builtins
+
fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__:
_ = gettext.gettext
+settings = QSettings("Open Source", "FlatCAM")
+if settings.contains("machinist"):
+ machinist_setting = settings.value('machinist', type=int)
+else:
+ machinist_setting = 0
-class ExcellonAdvOptPrefGroupUI(OptionsGroupUI2):
- def __init__(self, decimals=4, **kwargs):
- self.decimals = decimals
- super().__init__(**kwargs)
+class ExcellonAdvOptPrefGroupUI(OptionsGroupUI):
+
+ def __init__(self, decimals=4, parent=None):
+ # OptionsGroupUI.__init__(self, "Excellon Advanced Options", parent=parent)
+ super(ExcellonAdvOptPrefGroupUI, self).__init__(self, parent=parent)
+
self.setTitle(str(_("Excellon Adv. Options")))
+ self.decimals = decimals
- def build_options(self) -> [OptionUI]:
- return [
- HeadingOptionUI(
- label_text="Advanced Options",
- label_tooltip="A list of Excellon advanced parameters.\n"
- "Those parameters are available only for\n"
- "Advanced App. Level."
- ),
- DoubleSpinnerOptionUI(
- option="excellon_offset",
- label_text="Offset Z",
- label_tooltip="Some drill bits (the larger ones) need to drill deeper\n"
- "to create the desired exit hole diameter due of the tip shape.\n"
- "The value here can compensate the Cut Z parameter.",
- min_value=-999.9999, max_value=999.9999, step=0.1, decimals=self.decimals
- ),
- LineEntryOptionUI(
- option="excellon_toolchangexy",
- label_text="Toolchange X,Y",
- label_tooltip="Toolchange X,Y position."
- ),
- FloatEntryOptionUI(
- option="excellon_startz",
- label_text="Start Z",
- label_tooltip="Height of the tool just after start.\n"
- "Delete the value if you don't need this feature."
- ),
- DoubleSpinnerOptionUI(
- option="excellon_feedrate_rapid",
- label_text="Feedrate Rapids",
- label_tooltip="Tool speed while drilling\n"
- "(in units per minute).\n"
- "This is for the rapid move G00.\n"
- "It is useful only for Marlin,\n"
- "ignore for any other cases.",
- min_value=0.0001, max_value=99999.9999, step=50, decimals=self.decimals
- ),
- DoubleSpinnerOptionUI(
- option="excellon_z_pdepth",
- label_text="Probe Z depth",
- label_tooltip="The maximum depth that the probe is allowed\n"
- "to probe. Negative value, in current units.",
- min_value=-99999.9999, max_value=0.0, step=0.1, decimals=self.decimals
- ),
- DoubleSpinnerOptionUI(
- option="excellon_feedrate_probe",
- label_text="Feedrate Probe",
- label_tooltip="The feedrate used while the probe is probing.",
- min_value=0.0001, max_value=99999.9999, step=0.1, decimals=self.decimals
- ),
- RadioSetOptionUI(
- option="excellon_spindledir",
- label_text="Spindle direction",
- label_tooltip="This sets the direction that the spindle is rotating.\n"
- "It can be either:\n"
- "- CW = clockwise or\n"
- "- CCW = counter clockwise",
- choices=[{'label': _('CW'), 'value': 'CW'},
- {'label': _('CCW'), 'value': 'CCW'}]
- ),
- CheckboxOptionUI(
- option="excellon_f_plunge",
- label_text="Fast Plunge",
- label_tooltip="By checking this, the vertical move from\n"
- "Z_Toolchange to Z_move is done with G0,\n"
- "meaning the fastest speed available.\n"
- "WARNING: the move is done at Toolchange X,Y coords."
- ),
- CheckboxOptionUI(
- option="excellon_f_retract",
- label_text="Fast Retract",
- label_tooltip="Exit hole strategy.\n"
- " - When uncheked, while exiting the drilled hole the drill bit\n"
- "will travel slow, with set feedrate (G1), up to zero depth and then\n"
- "travel as fast as possible (G0) to the Z Move (travel height).\n"
- " - When checked the travel from Z cut (cut depth) to Z_move\n"
- "(travel height) is done as fast as possible (G0) in one move."
- )
- ]
\ No newline at end of file
+ # #######################
+ # ## ADVANCED OPTIONS ###
+ # #######################
+
+ self.exc_label = QtWidgets.QLabel('%s:' % _('Advanced Options'))
+ self.exc_label.setToolTip(
+ _("A list of Excellon advanced parameters.\n"
+ "Those parameters are available only for\n"
+ "Advanced App. Level.")
+ )
+ self.layout.addWidget(self.exc_label)
+
+ grid1 = QtWidgets.QGridLayout()
+ self.layout.addLayout(grid1)
+
+ # Offset Z
+ offsetlabel = QtWidgets.QLabel('%s:' % _('Offset Z'))
+ offsetlabel.setToolTip(
+ _("Some drill bits (the larger ones) need to drill deeper\n"
+ "to create the desired exit hole diameter due of the tip shape.\n"
+ "The value here can compensate the Cut Z parameter."))
+ self.offset_entry = FCDoubleSpinner()
+ self.offset_entry.set_precision(self.decimals)
+ self.offset_entry.set_range(-999.9999, 999.9999)
+
+ grid1.addWidget(offsetlabel, 0, 0)
+ grid1.addWidget(self.offset_entry, 0, 1)
+
+ # ToolChange X,Y
+ toolchange_xy_label = QtWidgets.QLabel('%s:' % _('Toolchange X,Y'))
+ toolchange_xy_label.setToolTip(
+ _("Toolchange X,Y position.")
+ )
+ self.toolchangexy_entry = FCEntry()
+
+ grid1.addWidget(toolchange_xy_label, 1, 0)
+ grid1.addWidget(self.toolchangexy_entry, 1, 1)
+
+ # Start Z
+ startzlabel = QtWidgets.QLabel('%s:' % _('Start Z'))
+ startzlabel.setToolTip(
+ _("Height of the tool just after start.\n"
+ "Delete the value if you don't need this feature.")
+ )
+ self.estartz_entry = FloatEntry()
+
+ grid1.addWidget(startzlabel, 2, 0)
+ grid1.addWidget(self.estartz_entry, 2, 1)
+
+ # Feedrate Rapids
+ fr_rapid_label = QtWidgets.QLabel('%s:' % _('Feedrate Rapids'))
+ fr_rapid_label.setToolTip(
+ _("Tool speed while drilling\n"
+ "(in units per minute).\n"
+ "This is for the rapid move G00.\n"
+ "It is useful only for Marlin,\n"
+ "ignore for any other cases.")
+ )
+ self.feedrate_rapid_entry = FCDoubleSpinner()
+ self.feedrate_rapid_entry.set_precision(self.decimals)
+ self.feedrate_rapid_entry.set_range(0, 99999.9999)
+
+ grid1.addWidget(fr_rapid_label, 3, 0)
+ grid1.addWidget(self.feedrate_rapid_entry, 3, 1)
+
+ # Probe depth
+ self.pdepth_label = QtWidgets.QLabel('%s:' % _("Probe Z depth"))
+ self.pdepth_label.setToolTip(
+ _("The maximum depth that the probe is allowed\n"
+ "to probe. Negative value, in current units.")
+ )
+ self.pdepth_entry = FCDoubleSpinner()
+ self.pdepth_entry.set_precision(self.decimals)
+ self.pdepth_entry.set_range(-99999.9999, 0.0000)
+
+ grid1.addWidget(self.pdepth_label, 4, 0)
+ grid1.addWidget(self.pdepth_entry, 4, 1)
+
+ # Probe feedrate
+ self.feedrate_probe_label = QtWidgets.QLabel('%s:' % _("Feedrate Probe"))
+ self.feedrate_probe_label.setToolTip(
+ _("The feedrate used while the probe is probing.")
+ )
+ self.feedrate_probe_entry = FCDoubleSpinner()
+ self.feedrate_probe_entry.set_precision(self.decimals)
+ self.feedrate_probe_entry.set_range(0, 99999.9999)
+
+ grid1.addWidget(self.feedrate_probe_label, 5, 0)
+ grid1.addWidget(self.feedrate_probe_entry, 5, 1)
+
+ # Spindle direction
+ spindle_dir_label = QtWidgets.QLabel('%s:' % _('Spindle direction'))
+ spindle_dir_label.setToolTip(
+ _("This sets the direction that the spindle is rotating.\n"
+ "It can be either:\n"
+ "- CW = clockwise or\n"
+ "- CCW = counter clockwise")
+ )
+
+ self.spindledir_radio = RadioSet([{'label': _('CW'), 'value': 'CW'},
+ {'label': _('CCW'), 'value': 'CCW'}])
+ grid1.addWidget(spindle_dir_label, 6, 0)
+ grid1.addWidget(self.spindledir_radio, 6, 1)
+
+ self.fplunge_cb = FCCheckBox('%s' % _('Fast Plunge'))
+ self.fplunge_cb.setToolTip(
+ _("By checking this, the vertical move from\n"
+ "Z_Toolchange to Z_move is done with G0,\n"
+ "meaning the fastest speed available.\n"
+ "WARNING: the move is done at Toolchange X,Y coords.")
+ )
+ grid1.addWidget(self.fplunge_cb, 7, 0, 1, 2)
+
+ self.fretract_cb = FCCheckBox('%s' % _('Fast Retract'))
+ self.fretract_cb.setToolTip(
+ _("Exit hole strategy.\n"
+ " - When uncheked, while exiting the drilled hole the drill bit\n"
+ "will travel slow, with set feedrate (G1), up to zero depth and then\n"
+ "travel as fast as possible (G0) to the Z Move (travel height).\n"
+ " - When checked the travel from Z cut (cut depth) to Z_move\n"
+ "(travel height) is done as fast as possible (G0) in one move.")
+ )
+
+ grid1.addWidget(self.fretract_cb, 8, 0, 1, 2)
+
+ self.layout.addStretch()
diff --git a/flatcamGUI/preferences/excellon/ExcellonEditorPrefGroupUI.py b/flatcamGUI/preferences/excellon/ExcellonEditorPrefGroupUI.py
index 162cdf8a..5b04cf2f 100644
--- a/flatcamGUI/preferences/excellon/ExcellonEditorPrefGroupUI.py
+++ b/flatcamGUI/preferences/excellon/ExcellonEditorPrefGroupUI.py
@@ -1,173 +1,306 @@
-from flatcamGUI.preferences.OptionUI import *
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI2
+from PyQt5 import QtWidgets
+from PyQt5.QtCore import QSettings
+
+from flatcamGUI.GUIElements import FCSpinner, FCDoubleSpinner, RadioSet
+from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
import gettext
import FlatCAMTranslation as fcTranslate
import builtins
+
fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__:
_ = gettext.gettext
+settings = QSettings("Open Source", "FlatCAM")
+if settings.contains("machinist"):
+ machinist_setting = settings.value('machinist', type=int)
+else:
+ machinist_setting = 0
-class ExcellonEditorPrefGroupUI(OptionsGroupUI2):
- def __init__(self, decimals=4, **kwargs):
- self.decimals = decimals
- super().__init__(**kwargs)
+class ExcellonEditorPrefGroupUI(OptionsGroupUI):
+ def __init__(self, decimals=4, parent=None):
+ super(ExcellonEditorPrefGroupUI, self).__init__(self, parent=parent)
+
self.setTitle(str(_("Excellon Editor")))
+ self.decimals = decimals
- def build_options(self) -> [OptionUI]:
- return [
- HeadingOptionUI(
- label_text="Parameters",
- label_tooltip="A list of Excellon Editor parameters."
- ),
- SpinnerOptionUI(
- option="excellon_editor_sel_limit",
- label_text="Selection limit",
- label_tooltip="Set the number of selected Excellon geometry\n"
- "items above which the utility geometry\n"
- "becomes just a selection rectangle.\n"
- "Increases the performance when moving a\n"
- "large number of geometric elements.",
- min_value=0, max_value=99999, step=1
- ),
- DoubleSpinnerOptionUI(
- option="excellon_editor_newdia",
- label_text="New Dia",
- label_tooltip="Diameter for the new tool",
- min_value=0.000001, max_value=99.9999, step=0.1, decimals=self.decimals
- ),
- SpinnerOptionUI(
- option="excellon_editor_array_size",
- label_text="Nr of drills",
- label_tooltip="Specify how many drills to be in the array.",
- min_value=0, max_value=9999, step=1
- ),
+ # Excellon Editor Parameters
+ self.param_label = QtWidgets.QLabel("%s:" % _("Parameters"))
+ self.param_label.setToolTip(
+ _("A list of Excellon Editor parameters.")
+ )
+ self.layout.addWidget(self.param_label)
- HeadingOptionUI(label_text="Linear Drill Array"),
- RadioSetOptionUI(
- option="excellon_editor_lin_dir",
- label_text="Linear Direction",
- label_tooltip="Direction on which the linear array is oriented:\n"
- "- 'X' - horizontal axis \n"
- "- 'Y' - vertical axis or \n"
- "- 'Angle' - a custom angle for the array inclination",
- choices=[
- {'label': _('X'), 'value': 'X'},
- {'label': _('Y'), 'value': 'Y'},
- {'label': _('Angle'), 'value': 'A'}
- ]
- ),
- DoubleSpinnerOptionUI(
- option="excellon_editor_lin_pitch",
- label_text="Pitch",
- label_tooltip="Pitch = Distance between elements of the array.",
- min_value=0, max_value=99999.9999, step=0.1, decimals=self.decimals
- ),
- DoubleSpinnerOptionUI(
- option="excellon_editor_lin_angle",
- label_text="Angle",
- label_tooltip="Angle at which each element in circular array is placed.", # FIXME tooltip seems wrong ?
- min_value=-360, max_value=360, step=5, decimals=self.decimals
- ),
+ grid0 = QtWidgets.QGridLayout()
+ self.layout.addLayout(grid0)
- HeadingOptionUI(label_text="Circular Drill Array"),
- RadioSetOptionUI(
- option="excellon_editor_circ_dir",
- label_text="Circular Direction",
- label_tooltip="Direction for circular array.\n"
- "Can be CW = clockwise or CCW = counter clockwise.",
- choices=[
- {'label': _('CW'), 'value': 'CW'},
- {'label': _('CCW'), 'value': 'CCW'}
- ]
- ),
- DoubleSpinnerOptionUI(
- option="excellon_editor_circ_angle",
- label_text="Angle",
- label_tooltip="Angle at which each element in circular array is placed.",
- min_value=-360, max_value=360, step=5, decimals=self.decimals
- ),
+ # Selection Limit
+ self.sel_limit_label = QtWidgets.QLabel('%s:' % _("Selection limit"))
+ self.sel_limit_label.setToolTip(
+ _("Set the number of selected Excellon geometry\n"
+ "items above which the utility geometry\n"
+ "becomes just a selection rectangle.\n"
+ "Increases the performance when moving a\n"
+ "large number of geometric elements.")
+ )
+ self.sel_limit_entry = FCSpinner()
+ self.sel_limit_entry.set_range(0, 99999)
- HeadingOptionUI(label_text="Slots"),
- DoubleSpinnerOptionUI(
- option="excellon_editor_slot_length",
- label_text="Length",
- label_tooltip="Length = The length of the slot.",
- min_value=0, max_value=99999, step=1, decimals=self.decimals
- ),
- RadioSetOptionUI(
- option="excellon_editor_slot_direction",
- label_text="Direction",
- label_tooltip="Direction on which the slot is oriented:\n"
- "- 'X' - horizontal axis \n"
- "- 'Y' - vertical axis or \n"
- "- 'Angle' - a custom angle for the slot inclination",
- choices=[
- {'label': _('X'), 'value': 'X'},
- {'label': _('Y'), 'value': 'Y'},
- {'label': _('Angle'), 'value': 'A'}
- ]
- ),
- DoubleSpinnerOptionUI(
- option="excellon_editor_slot_angle",
- label_text="Angle",
- label_tooltip="Angle at which the slot is placed.\n"
- "The precision is of max 2 decimals.\n"
- "Min value is: -359.99 degrees.\n"
- "Max value is: 360.00 degrees.",
- min_value=-359.99, max_value=360.00, step=5, decimals=self.decimals
- ),
+ grid0.addWidget(self.sel_limit_label, 0, 0)
+ grid0.addWidget(self.sel_limit_entry, 0, 1)
- HeadingOptionUI(label_text="Linear Slot Array"),
- SpinnerOptionUI(
- option="excellon_editor_slot_array_size",
- label_text="Nr of slots",
- label_tooltip="Specify how many slots to be in the array.",
- min_value=0, max_value=999999, step=1
- ),
- RadioSetOptionUI(
- option="excellon_editor_slot_lin_dir",
- label_text="Linear Direction",
- label_tooltip="Direction on which the linear array is oriented:\n"
- "- 'X' - horizontal axis \n"
- "- 'Y' - vertical axis or \n"
- "- 'Angle' - a custom angle for the array inclination",
- choices=[
- {'label': _('X'), 'value': 'X'},
- {'label': _('Y'), 'value': 'Y'},
- {'label': _('Angle'), 'value': 'A'}
- ]
- ),
- DoubleSpinnerOptionUI(
- option="excellon_editor_slot_lin_pitch",
- label_text="Pitch",
- label_tooltip="Pitch = Distance between elements of the array.",
- min_value=0, max_value=999999, step=1, decimals=self.decimals
- ),
- DoubleSpinnerOptionUI(
- option="excellon_editor_slot_lin_angle",
- label_text="Angle",
- label_tooltip="Angle at which each element in circular array is placed.", # FIXME
- min_value=-360, max_value=360, step=5, decimals=self.decimals
- ),
+ # New Diameter
+ self.addtool_entry_lbl = QtWidgets.QLabel('%s:' % _('New Dia'))
+ self.addtool_entry_lbl.setToolTip(
+ _("Diameter for the new tool")
+ )
- HeadingOptionUI(label_text="Circular Slot Array"),
- RadioSetOptionUI(
- option="excellon_editor_slot_circ_dir",
- label_text="Circular Direction",
- label_tooltip="Direction for circular array.\n"
- "Can be CW = clockwise or CCW = counter clockwise.",
- choices=[{'label': _('CW'), 'value': 'CW'},
- {'label': _('CCW'), 'value': 'CCW'}]
- ),
- DoubleSpinnerOptionUI(
- option="excellon_editor_slot_circ_angle",
- label_text="Circular Angle",
- label_tooltip="Angle at which each element in circular array is placed.",
- min_value=-360, max_value=360, step=5, decimals=self.decimals
- )
+ self.addtool_entry = FCDoubleSpinner()
+ self.addtool_entry.set_range(0.000001, 99.9999)
+ self.addtool_entry.set_precision(self.decimals)
- ]
+ grid0.addWidget(self.addtool_entry_lbl, 1, 0)
+ grid0.addWidget(self.addtool_entry, 1, 1)
+ # Number of drill holes in a drill array
+ self.drill_array_size_label = QtWidgets.QLabel('%s:' % _('Nr of drills'))
+ self.drill_array_size_label.setToolTip(
+ _("Specify how many drills to be in the array.")
+ )
+ # self.drill_array_size_label.setMinimumWidth(100)
+
+ self.drill_array_size_entry = FCSpinner()
+ self.drill_array_size_entry.set_range(0, 9999)
+
+ grid0.addWidget(self.drill_array_size_label, 2, 0)
+ grid0.addWidget(self.drill_array_size_entry, 2, 1)
+
+ self.drill_array_linear_label = QtWidgets.QLabel('%s:' % _('Linear Drill Array'))
+ grid0.addWidget(self.drill_array_linear_label, 3, 0, 1, 2)
+
+ # Linear Drill Array direction
+ self.drill_axis_label = QtWidgets.QLabel('%s:' % _('Linear Direction'))
+ self.drill_axis_label.setToolTip(
+ _("Direction on which the linear array is oriented:\n"
+ "- 'X' - horizontal axis \n"
+ "- 'Y' - vertical axis or \n"
+ "- 'Angle' - a custom angle for the array inclination")
+ )
+ # self.drill_axis_label.setMinimumWidth(100)
+ self.drill_axis_radio = RadioSet([{'label': _('X'), 'value': 'X'},
+ {'label': _('Y'), 'value': 'Y'},
+ {'label': _('Angle'), 'value': 'A'}])
+
+ grid0.addWidget(self.drill_axis_label, 4, 0)
+ grid0.addWidget(self.drill_axis_radio, 4, 1)
+
+ # Linear Drill Array pitch distance
+ self.drill_pitch_label = QtWidgets.QLabel('%s:' % _('Pitch'))
+ self.drill_pitch_label.setToolTip(
+ _("Pitch = Distance between elements of the array.")
+ )
+ # self.drill_pitch_label.setMinimumWidth(100)
+ self.drill_pitch_entry = FCDoubleSpinner()
+ self.drill_pitch_entry.set_range(0, 99999.9999)
+ self.drill_pitch_entry.set_precision(self.decimals)
+
+ grid0.addWidget(self.drill_pitch_label, 5, 0)
+ grid0.addWidget(self.drill_pitch_entry, 5, 1)
+
+ # Linear Drill Array custom angle
+ self.drill_angle_label = QtWidgets.QLabel('%s:' % _('Angle'))
+ self.drill_angle_label.setToolTip(
+ _("Angle at which each element in circular array is placed.")
+ )
+ self.drill_angle_entry = FCDoubleSpinner()
+ self.drill_pitch_entry.set_range(-360, 360)
+ self.drill_pitch_entry.set_precision(self.decimals)
+ self.drill_angle_entry.setWrapping(True)
+ self.drill_angle_entry.setSingleStep(5)
+
+ grid0.addWidget(self.drill_angle_label, 6, 0)
+ grid0.addWidget(self.drill_angle_entry, 6, 1)
+
+ self.drill_array_circ_label = QtWidgets.QLabel('%s:' % _('Circular Drill Array'))
+ grid0.addWidget(self.drill_array_circ_label, 7, 0, 1, 2)
+
+ # Circular Drill Array direction
+ self.drill_circular_direction_label = QtWidgets.QLabel('%s:' % _('Circular Direction'))
+ self.drill_circular_direction_label.setToolTip(
+ _("Direction for circular array.\n"
+ "Can be CW = clockwise or CCW = counter clockwise.")
+ )
+
+ self.drill_circular_dir_radio = RadioSet([{'label': _('CW'), 'value': 'CW'},
+ {'label': _('CCW'), 'value': 'CCW'}])
+
+ grid0.addWidget(self.drill_circular_direction_label, 8, 0)
+ grid0.addWidget(self.drill_circular_dir_radio, 8, 1)
+
+ # Circular Drill Array Angle
+ self.drill_circular_angle_label = QtWidgets.QLabel('%s:' % _('Circular Angle'))
+ self.drill_circular_angle_label.setToolTip(
+ _("Angle at which each element in circular array is placed.")
+ )
+ self.drill_circular_angle_entry = FCDoubleSpinner()
+ self.drill_circular_angle_entry.set_range(-360, 360)
+ self.drill_circular_angle_entry.set_precision(self.decimals)
+ self.drill_circular_angle_entry.setWrapping(True)
+ self.drill_circular_angle_entry.setSingleStep(5)
+
+ grid0.addWidget(self.drill_circular_angle_label, 9, 0)
+ grid0.addWidget(self.drill_circular_angle_entry, 9, 1)
+
+ # ##### SLOTS #####
+ # #################
+ self.drill_array_circ_label = QtWidgets.QLabel('%s:' % _('Slots'))
+ grid0.addWidget(self.drill_array_circ_label, 10, 0, 1, 2)
+
+ # Slot length
+ self.slot_length_label = QtWidgets.QLabel('%s:' % _('Length'))
+ self.slot_length_label.setToolTip(
+ _("Length = The length of the slot.")
+ )
+ self.slot_length_label.setMinimumWidth(100)
+
+ self.slot_length_entry = FCDoubleSpinner()
+ self.slot_length_entry.set_range(0, 99999)
+ self.slot_length_entry.set_precision(self.decimals)
+ self.slot_length_entry.setWrapping(True)
+ self.slot_length_entry.setSingleStep(1)
+
+ grid0.addWidget(self.slot_length_label, 11, 0)
+ grid0.addWidget(self.slot_length_entry, 11, 1)
+
+ # Slot direction
+ self.slot_axis_label = QtWidgets.QLabel('%s:' % _('Direction'))
+ self.slot_axis_label.setToolTip(
+ _("Direction on which the slot is oriented:\n"
+ "- 'X' - horizontal axis \n"
+ "- 'Y' - vertical axis or \n"
+ "- 'Angle' - a custom angle for the slot inclination")
+ )
+ self.slot_axis_label.setMinimumWidth(100)
+
+ self.slot_axis_radio = RadioSet([{'label': _('X'), 'value': 'X'},
+ {'label': _('Y'), 'value': 'Y'},
+ {'label': _('Angle'), 'value': 'A'}])
+ grid0.addWidget(self.slot_axis_label, 12, 0)
+ grid0.addWidget(self.slot_axis_radio, 12, 1)
+
+ # Slot custom angle
+ self.slot_angle_label = QtWidgets.QLabel('%s:' % _('Angle'))
+ self.slot_angle_label.setToolTip(
+ _("Angle at which the slot is placed.\n"
+ "The precision is of max 2 decimals.\n"
+ "Min value is: -359.99 degrees.\n"
+ "Max value is: 360.00 degrees.")
+ )
+ self.slot_angle_label.setMinimumWidth(100)
+
+ self.slot_angle_spinner = FCDoubleSpinner()
+ self.slot_angle_spinner.set_precision(self.decimals)
+ self.slot_angle_spinner.setWrapping(True)
+ self.slot_angle_spinner.setRange(-359.99, 360.00)
+ self.slot_angle_spinner.setSingleStep(5)
+
+ grid0.addWidget(self.slot_angle_label, 13, 0)
+ grid0.addWidget(self.slot_angle_spinner, 13, 1)
+
+ # #### SLOTS ARRAY #######
+ # ########################
+
+ self.slot_array_linear_label = QtWidgets.QLabel('%s:' % _('Linear Slot Array'))
+ grid0.addWidget(self.slot_array_linear_label, 14, 0, 1, 2)
+
+ # Number of slot holes in a drill array
+ self.slot_array_size_label = QtWidgets.QLabel('%s:' % _('Nr of slots'))
+ self.drill_array_size_label.setToolTip(
+ _("Specify how many slots to be in the array.")
+ )
+ # self.slot_array_size_label.setMinimumWidth(100)
+
+ self.slot_array_size_entry = FCSpinner()
+ self.slot_array_size_entry.set_range(0, 999999)
+
+ grid0.addWidget(self.slot_array_size_label, 15, 0)
+ grid0.addWidget(self.slot_array_size_entry, 15, 1)
+
+ # Linear Slot Array direction
+ self.slot_array_axis_label = QtWidgets.QLabel('%s:' % _('Linear Direction'))
+ self.slot_array_axis_label.setToolTip(
+ _("Direction on which the linear array is oriented:\n"
+ "- 'X' - horizontal axis \n"
+ "- 'Y' - vertical axis or \n"
+ "- 'Angle' - a custom angle for the array inclination")
+ )
+ # self.slot_axis_label.setMinimumWidth(100)
+ self.slot_array_axis_radio = RadioSet([{'label': _('X'), 'value': 'X'},
+ {'label': _('Y'), 'value': 'Y'},
+ {'label': _('Angle'), 'value': 'A'}])
+
+ grid0.addWidget(self.slot_array_axis_label, 16, 0)
+ grid0.addWidget(self.slot_array_axis_radio, 16, 1)
+
+ # Linear Slot Array pitch distance
+ self.slot_array_pitch_label = QtWidgets.QLabel('%s:' % _('Pitch'))
+ self.slot_array_pitch_label.setToolTip(
+ _("Pitch = Distance between elements of the array.")
+ )
+ # self.drill_pitch_label.setMinimumWidth(100)
+ self.slot_array_pitch_entry = FCDoubleSpinner()
+ self.slot_array_pitch_entry.set_precision(self.decimals)
+ self.slot_array_pitch_entry.setWrapping(True)
+ self.slot_array_pitch_entry.setRange(0, 999999)
+ self.slot_array_pitch_entry.setSingleStep(1)
+
+ grid0.addWidget(self.slot_array_pitch_label, 17, 0)
+ grid0.addWidget(self.slot_array_pitch_entry, 17, 1)
+
+ # Linear Slot Array custom angle
+ self.slot_array_angle_label = QtWidgets.QLabel('%s:' % _('Angle'))
+ self.slot_array_angle_label.setToolTip(
+ _("Angle at which each element in circular array is placed.")
+ )
+ self.slot_array_angle_entry = FCDoubleSpinner()
+ self.slot_array_angle_entry.set_precision(self.decimals)
+ self.slot_array_angle_entry.setWrapping(True)
+ self.slot_array_angle_entry.setRange(-360, 360)
+ self.slot_array_angle_entry.setSingleStep(5)
+
+ grid0.addWidget(self.slot_array_angle_label, 18, 0)
+ grid0.addWidget(self.slot_array_angle_entry, 18, 1)
+
+ self.slot_array_circ_label = QtWidgets.QLabel('%s:' % _('Circular Slot Array'))
+ grid0.addWidget(self.slot_array_circ_label, 19, 0, 1, 2)
+
+ # Circular Slot Array direction
+ self.slot_array_circular_direction_label = QtWidgets.QLabel('%s:' % _('Circular Direction'))
+ self.slot_array_circular_direction_label.setToolTip(
+ _("Direction for circular array.\n"
+ "Can be CW = clockwise or CCW = counter clockwise.")
+ )
+
+ self.slot_array_circular_dir_radio = RadioSet([{'label': _('CW'), 'value': 'CW'},
+ {'label': _('CCW'), 'value': 'CCW'}])
+
+ grid0.addWidget(self.slot_array_circular_direction_label, 20, 0)
+ grid0.addWidget(self.slot_array_circular_dir_radio, 20, 1)
+
+ # Circular Slot Array Angle
+ self.slot_array_circular_angle_label = QtWidgets.QLabel('%s:' % _('Circular Angle'))
+ self.slot_array_circular_angle_label.setToolTip(
+ _("Angle at which each element in circular array is placed.")
+ )
+ self.slot_array_circular_angle_entry = FCDoubleSpinner()
+ self.slot_array_circular_angle_entry.set_precision(self.decimals)
+ self.slot_array_circular_angle_entry.setWrapping(True)
+ self.slot_array_circular_angle_entry.setRange(-360, 360)
+ self.slot_array_circular_angle_entry.setSingleStep(5)
+
+ grid0.addWidget(self.slot_array_circular_angle_label, 21, 0)
+ grid0.addWidget(self.slot_array_circular_angle_entry, 21, 1)
+
+ self.layout.addStretch()
diff --git a/flatcamGUI/preferences/excellon/ExcellonExpPrefGroupUI.py b/flatcamGUI/preferences/excellon/ExcellonExpPrefGroupUI.py
index 52905e30..db2e922a 100644
--- a/flatcamGUI/preferences/excellon/ExcellonExpPrefGroupUI.py
+++ b/flatcamGUI/preferences/excellon/ExcellonExpPrefGroupUI.py
@@ -1,86 +1,168 @@
-from flatcamGUI.preferences.OptionUI import *
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI2
+from PyQt5 import QtWidgets, QtCore
+from PyQt5.QtCore import QSettings
+from flatcamGUI.GUIElements import RadioSet, FCSpinner
+from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
import gettext
import FlatCAMTranslation as fcTranslate
import builtins
+
fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__:
_ = gettext.gettext
+settings = QSettings("Open Source", "FlatCAM")
+if settings.contains("machinist"):
+ machinist_setting = settings.value('machinist', type=int)
+else:
+ machinist_setting = 0
-class ExcellonExpPrefGroupUI(OptionsGroupUI2):
- def __init__(self, decimals=4, **kwargs):
- self.decimals = decimals
- super().__init__(**kwargs)
+class ExcellonExpPrefGroupUI(OptionsGroupUI):
+
+ def __init__(self, decimals=4, parent=None):
+ super(ExcellonExpPrefGroupUI, self).__init__(self, parent=parent)
+
self.setTitle(str(_("Excellon Export")))
+ self.decimals = decimals
- self.option_dict()["excellon_exp_format"].get_field().activated_custom.connect(self.optimization_selection)
+ # Plot options
+ self.export_options_label = QtWidgets.QLabel("%s:" % _("Export Options"))
+ self.export_options_label.setToolTip(
+ _("The parameters set here are used in the file exported\n"
+ "when using the File -> Export -> Export Excellon menu entry.")
+ )
+ self.layout.addWidget(self.export_options_label)
- def build_options(self) -> [OptionUI]:
- return [
- HeadingOptionUI(
- label_text="Export Options",
- label_tooltip="The parameters set here are used in the file exported\n"
- "when using the File -> Export -> Export Excellon menu entry."
- ),
- RadioSetOptionUI(
- option="excellon_exp_units",
- label_text="Units",
- label_tooltip="The units used in the Excellon file.",
- choices=[{'label': _('INCH'), 'value': 'INCH'},
- {'label': _('MM'), 'value': 'METRIC'}]
- ),
- SpinnerOptionUI(
- option="excellon_exp_integer",
- label_text="Int",
- label_tooltip="This number signifies the number of digits in\nthe whole part of Excellon coordinates.",
- min_value=0, max_value=9, step=1
- ),
- SpinnerOptionUI(
- option="excellon_exp_decimals",
- label_text="Decimals",
- label_tooltip="This number signifies the number of digits in\nthe decimal part of Excellon coordinates.",
- min_value=0, max_value=9, step=1
- ),
- RadioSetOptionUI(
- option="excellon_exp_format",
- label_text="Format",
- label_tooltip="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.",
- choices=[{'label': _('Decimal'), 'value': 'dec'},
- {'label': _('No-Decimal'), 'value': 'ndec'}]
- ),
- RadioSetOptionUI(
- option="excellon_exp_zeros",
- label_text="Zeros",
- label_tooltip="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.",
- choices=[{'label': _('LZ'), 'value': 'LZ'},
- {'label': _('TZ'), 'value': 'TZ'}]
- ),
- RadioSetOptionUI(
- option="excellon_exp_slot_type",
- label_text="Slot type",
- label_tooltip="This sets how the slots will be exported.\n"
- "If ROUTED then the slots will be routed\n"
- "using M15/M16 commands.\n"
- "If DRILLED(G85) the slots will be exported\n"
- "using the Drilled slot command (G85).",
- choices=[{'label': _('Routed'), 'value': 'routing'},
- {'label': _('Drilled(G85)'), 'value': 'drilling'}]
- )
- ]
+ form = QtWidgets.QFormLayout()
+ self.layout.addLayout(form)
+
+ # Excellon Units
+ self.excellon_units_label = QtWidgets.QLabel('%s:' % _('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)
+
+ # Excellon non-decimal format
+ self.digits_label = QtWidgets.QLabel("%s:" % _("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 = FCSpinner()
+ self.format_whole_entry.set_range(0, 9)
+ self.format_whole_entry.setMinimumWidth(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 = FCSpinner()
+ self.format_dec_entry.set_range(0, 9)
+ self.format_dec_entry.setMinimumWidth(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)
+
+ # Select the Excellon Format
+ self.format_label = QtWidgets.QLabel("%s:" % _("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 Zeros
+ self.zeros_label = QtWidgets.QLabel('%s:' % _('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)
+
+ # Slot type
+ self.slot_type_label = QtWidgets.QLabel('%s:' % _('Slot type'))
+ self.slot_type_label.setAlignment(QtCore.Qt.AlignLeft)
+ self.slot_type_label.setToolTip(
+ _("This sets how the slots will be exported.\n"
+ "If ROUTED then the slots will be routed\n"
+ "using M15/M16 commands.\n"
+ "If DRILLED(G85) the slots will be exported\n"
+ "using the Drilled slot command (G85).")
+ )
+
+ self.slot_type_radio = RadioSet([{'label': _('Routed'), 'value': 'routing'},
+ {'label': _('Drilled(G85)'), 'value': 'drilling'}])
+ self.slot_type_radio.setToolTip(
+ _("This sets how the slots will be exported.\n"
+ "If ROUTED then the slots will be routed\n"
+ "using M15/M16 commands.\n"
+ "If DRILLED(G85) the slots will be exported\n"
+ "using the Drilled slot command (G85).")
+ )
+
+ form.addRow(self.slot_type_label, self.slot_type_radio)
+
+ self.layout.addStretch()
+ self.format_radio.activated_custom.connect(self.optimization_selection)
def optimization_selection(self):
- disable_zeros = self.option_dict()["excellon_exp_format"].get_field().get_value() == "dec"
- self.option_dict()["excellon_exp_zeros"].label_widget.setDisabled(disable_zeros)
- self.option_dict()["excellon_exp_zeros"].get_field().setDisabled(disable_zeros)
+ if self.format_radio.get_value() == 'dec':
+ self.zeros_label.setDisabled(True)
+ self.zeros_radio.setDisabled(True)
+ else:
+ self.zeros_label.setDisabled(False)
+ self.zeros_radio.setDisabled(False)
diff --git a/flatcamGUI/preferences/excellon/ExcellonGenPrefGroupUI.py b/flatcamGUI/preferences/excellon/ExcellonGenPrefGroupUI.py
index 91b3dcde..06d4dfc7 100644
--- a/flatcamGUI/preferences/excellon/ExcellonGenPrefGroupUI.py
+++ b/flatcamGUI/preferences/excellon/ExcellonGenPrefGroupUI.py
@@ -1,199 +1,415 @@
import platform
-from flatcamGUI.preferences.OptionUI import *
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI2
+from PyQt5 import QtWidgets, QtCore, QtGui
+from PyQt5.QtCore import QSettings
+
+from flatcamGUI.GUIElements import FCCheckBox, FCSpinner, RadioSet, FCEntry
+from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
import gettext
import FlatCAMTranslation as fcTranslate
import builtins
+
fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__:
_ = gettext.gettext
+settings = QSettings("Open Source", "FlatCAM")
+if settings.contains("machinist"):
+ machinist_setting = settings.value('machinist', type=int)
+else:
+ machinist_setting = 0
-class ExcellonGenPrefGroupUI(OptionsGroupUI2):
- def __init__(self, decimals=4, **kwargs):
- self.decimals = decimals
- super().__init__(**kwargs)
+class ExcellonGenPrefGroupUI(OptionsGroupUI):
+
+ def __init__(self, decimals=4, parent=None):
+ # OptionsGroupUI.__init__(self, "Excellon Options", parent=parent)
+ super(ExcellonGenPrefGroupUI, self).__init__(self, parent=parent)
+
self.setTitle(str(_("Excellon General")))
+ self.decimals = decimals
- # disable the Excellon path optimizations made with Google OR-Tools if the app is run on a 32bit platform
- if platform.architecture()[0] != '64bit':
- self.option_dict()["excellon_optimization_type"].get_field().set_value('T')
- self.option_dict()["excellon_optimization_type"].get_field().setDisabled(True)
- self.option_dict()["excellon_optimization_type"].label_widget.setDisabled(True)
+ # Plot options
+ self.plot_options_label = QtWidgets.QLabel("%s:" % _("Plot Options"))
+ self.layout.addWidget(self.plot_options_label)
- # Enable/disable the duration box according to type selected
- self.option_dict()["excellon_optimization_type"].get_field().activated_custom.connect(self.optimization_selection)
- self.optimization_selection()
+ grid1 = QtWidgets.QGridLayout()
+ self.layout.addLayout(grid1)
+
+ self.plot_cb = FCCheckBox(label=_('Plot'))
+ self.plot_cb.setToolTip(
+ "Plot (show) this object."
+ )
+ grid1.addWidget(self.plot_cb, 0, 0)
+
+ self.solid_cb = FCCheckBox(label=_('Solid'))
+ self.solid_cb.setToolTip(
+ "Plot as solid circles."
+ )
+ grid1.addWidget(self.solid_cb, 0, 1)
+
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid1.addWidget(separator_line, 1, 0, 1, 2)
+
+ grid2 = QtWidgets.QGridLayout()
+ self.layout.addLayout(grid2)
+ grid2.setColumnStretch(0, 0)
+ grid2.setColumnStretch(1, 1)
+
+ # Excellon format
+ self.excellon_format_label = QtWidgets.QLabel("%s:" % _("Excellon Format"))
+ self.excellon_format_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.\n"
+ "\n"
+ "Possible presets:\n"
+ "\n"
+ "PROTEUS 3:3 MM LZ\n"
+ "DipTrace 5:2 MM TZ\n"
+ "DipTrace 4:3 MM LZ\n"
+ "\n"
+ "EAGLE 3:3 MM TZ\n"
+ "EAGLE 4:3 MM TZ\n"
+ "EAGLE 2:5 INCH TZ\n"
+ "EAGLE 3:5 INCH TZ\n"
+ "\n"
+ "ALTIUM 2:4 INCH LZ\n"
+ "Sprint Layout 2:4 INCH LZ"
+ "\n"
+ "KiCAD 3:5 INCH TZ")
+ )
+ grid2.addWidget(self.excellon_format_label, 0, 0, 1, 2)
+
+ self.excellon_format_in_label = QtWidgets.QLabel('%s:' % _("INCH"))
+ self.excellon_format_in_label.setToolTip(_("Default values for INCH are 2:4"))
+
+ hlay1 = QtWidgets.QHBoxLayout()
+ self.excellon_format_upper_in_entry = FCSpinner()
+ self.excellon_format_upper_in_entry.set_range(0, 9)
+ self.excellon_format_upper_in_entry.setMinimumWidth(30)
+ self.excellon_format_upper_in_entry.setToolTip(
+ _("This numbers signify the number of digits in\n"
+ "the whole part of Excellon coordinates.")
+ )
+ hlay1.addWidget(self.excellon_format_upper_in_entry)
+
+ excellon_separator_in_label = QtWidgets.QLabel(':')
+ excellon_separator_in_label.setFixedWidth(5)
+ hlay1.addWidget(excellon_separator_in_label)
+
+ self.excellon_format_lower_in_entry = FCSpinner()
+ self.excellon_format_lower_in_entry.set_range(0, 9)
+ self.excellon_format_lower_in_entry.setMinimumWidth(30)
+ self.excellon_format_lower_in_entry.setToolTip(
+ _("This numbers signify the number of digits in\n"
+ "the decimal part of Excellon coordinates.")
+ )
+ hlay1.addWidget(self.excellon_format_lower_in_entry)
+
+ grid2.addWidget(self.excellon_format_in_label, 1, 0)
+ grid2.addLayout(hlay1, 1, 1)
+
+ self.excellon_format_mm_label = QtWidgets.QLabel('%s:' % _("METRIC"))
+ self.excellon_format_mm_label.setToolTip(_("Default values for METRIC are 3:3"))
+
+ hlay2 = QtWidgets.QHBoxLayout()
+ self.excellon_format_upper_mm_entry = FCSpinner()
+ self.excellon_format_upper_mm_entry.set_range(0, 9)
+ self.excellon_format_upper_mm_entry.setMinimumWidth(30)
+ self.excellon_format_upper_mm_entry.setToolTip(
+ _("This numbers signify the number of digits in\n"
+ "the whole part of Excellon coordinates.")
+ )
+ hlay2.addWidget(self.excellon_format_upper_mm_entry)
+
+ excellon_separator_mm_label = QtWidgets.QLabel(':')
+ excellon_separator_mm_label.setFixedWidth(5)
+ hlay2.addWidget(excellon_separator_mm_label, QtCore.Qt.AlignLeft)
+
+ self.excellon_format_lower_mm_entry = FCSpinner()
+ self.excellon_format_lower_mm_entry.set_range(0, 9)
+ self.excellon_format_lower_mm_entry.setMinimumWidth(30)
+ self.excellon_format_lower_mm_entry.setToolTip(
+ _("This numbers signify the number of digits in\n"
+ "the decimal part of Excellon coordinates.")
+ )
+ hlay2.addWidget(self.excellon_format_lower_mm_entry)
+
+ grid2.addWidget(self.excellon_format_mm_label, 2, 0)
+ grid2.addLayout(hlay2, 2, 1)
+
+ self.excellon_zeros_label = QtWidgets.QLabel('%s:' % _('Zeros'))
+ self.excellon_zeros_label.setAlignment(QtCore.Qt.AlignLeft)
+ self.excellon_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.\n\n"
+ "This is used when there is no information\n"
+ "stored in the Excellon file.")
+ )
+ grid2.addWidget(self.excellon_zeros_label, 3, 0)
+
+ self.excellon_zeros_radio = RadioSet([{'label': _('LZ'), 'value': 'L'},
+ {'label': _('TZ'), 'value': 'T'}])
+
+ grid2.addWidget(self.excellon_zeros_radio, 3, 1)
+
+ self.excellon_units_label = QtWidgets.QLabel('%s:' % _('Units'))
+ self.excellon_units_label.setAlignment(QtCore.Qt.AlignLeft)
+ self.excellon_units_label.setToolTip(
+ _("This sets the default units of Excellon files.\n"
+ "If it is not detected in the parsed file the value here\n"
+ "will be used."
+ "Some Excellon files don't have an header\n"
+ "therefore this parameter will be used.")
+ )
+
+ self.excellon_units_radio = RadioSet([{'label': _('INCH'), 'value': 'INCH'},
+ {'label': _('MM'), 'value': 'METRIC'}])
+ self.excellon_units_radio.setToolTip(
+ _("This sets the units of Excellon files.\n"
+ "Some Excellon files don't have an header\n"
+ "therefore this parameter will be used.")
+ )
+
+ grid2.addWidget(self.excellon_units_label, 4, 0)
+ grid2.addWidget(self.excellon_units_radio, 4, 1)
+
+ self.update_excellon_cb = FCCheckBox(label=_('Update Export settings'))
+ self.update_excellon_cb.setToolTip(
+ "If checked, the Excellon Export settings will be updated with the ones above."
+ )
+ grid2.addWidget(self.update_excellon_cb, 5, 0, 1, 2)
+
+ # Adding the Excellon Format Defaults Button
+ self.excellon_defaults_button = QtWidgets.QPushButton()
+ self.excellon_defaults_button.setText(str(_("Restore Defaults")))
+ self.excellon_defaults_button.setMinimumWidth(80)
+ grid2.addWidget(self.excellon_defaults_button, 6, 0, 1, 2)
+
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid2.addWidget(separator_line, 7, 0, 1, 2)
+
+ self.excellon_general_label = QtWidgets.QLabel("%s:" % _("Excellon Optimization"))
+ grid2.addWidget(self.excellon_general_label, 8, 0, 1, 2)
+
+ self.excellon_optimization_label = QtWidgets.QLabel(_('Algorithm:'))
+ self.excellon_optimization_label.setToolTip(
+ _("This sets the optimization type for the Excellon drill path.\n"
+ "If <> is checked then Google OR-Tools algorithm with\n"
+ "MetaHeuristic Guided Local Path is used. Default search time is 3sec.\n"
+ "If <> is checked then Google OR-Tools Basic algorithm is used.\n"
+ "If <> is checked then Travelling Salesman algorithm is used for\n"
+ "drill path optimization.\n"
+ "\n"
+ "If this control is disabled, then FlatCAM works in 32bit mode and it uses\n"
+ "Travelling Salesman algorithm for path optimization.")
+ )
+
+ self.excellon_optimization_radio = RadioSet([{'label': _('MetaHeuristic'), 'value': 'M'},
+ {'label': _('Basic'), 'value': 'B'},
+ {'label': _('TSA'), 'value': 'T'}],
+ orientation='vertical', stretch=False)
+ self.excellon_optimization_radio.setToolTip(
+ _("This sets the optimization type for the Excellon drill path.\n"
+ "If <> is checked then Google OR-Tools algorithm with\n"
+ "MetaHeuristic Guided Local Path is used. Default search time is 3sec.\n"
+ "If <> is checked then Google OR-Tools Basic algorithm is used.\n"
+ "If <> is checked then Travelling Salesman algorithm is used for\n"
+ "drill path optimization.\n"
+ "\n"
+ "If this control is disabled, then FlatCAM works in 32bit mode and it uses\n"
+ "Travelling Salesman algorithm for path optimization.")
+ )
+
+ grid2.addWidget(self.excellon_optimization_label, 9, 0)
+ grid2.addWidget(self.excellon_optimization_radio, 9, 1)
+
+ self.optimization_time_label = QtWidgets.QLabel('%s:' % _('Duration'))
+ self.optimization_time_label.setAlignment(QtCore.Qt.AlignLeft)
+ self.optimization_time_label.setToolTip(
+ _("When OR-Tools Metaheuristic (MH) is enabled there is a\n"
+ "maximum threshold for how much time is spent doing the\n"
+ "path optimization. This max duration is set here.\n"
+ "In seconds.")
+
+ )
+
+ self.optimization_time_entry = FCSpinner()
+ self.optimization_time_entry.set_range(0, 999)
+
+ grid2.addWidget(self.optimization_time_label, 10, 0)
+ grid2.addWidget(self.optimization_time_entry, 10, 1)
+
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid2.addWidget(separator_line, 11, 0, 1, 2)
+
+ # Excellon Object Color
+ self.gerber_color_label = QtWidgets.QLabel('%s' % _('Excellon Object Color'))
+ grid2.addWidget(self.gerber_color_label, 12, 0, 1, 2)
+
+ # Plot Line Color
+ self.line_color_label = QtWidgets.QLabel('%s:' % _('Outline'))
+ self.line_color_label.setToolTip(
+ _("Set the line color for plotted objects.")
+ )
+ self.line_color_entry = FCEntry()
+ self.line_color_button = QtWidgets.QPushButton()
+ self.line_color_button.setFixedSize(15, 15)
+
+ self.form_box_child_2 = QtWidgets.QHBoxLayout()
+ self.form_box_child_2.addWidget(self.line_color_entry)
+ self.form_box_child_2.addWidget(self.line_color_button)
+ self.form_box_child_2.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
+
+ grid2.addWidget(self.line_color_label, 13, 0)
+ grid2.addLayout(self.form_box_child_2, 13, 1)
+
+ # Plot Fill Color
+ self.fill_color_label = QtWidgets.QLabel('%s:' % _('Fill'))
+ self.fill_color_label.setToolTip(
+ _("Set the fill color for plotted objects.\n"
+ "First 6 digits are the color and the last 2\n"
+ "digits are for alpha (transparency) level.")
+ )
+ self.fill_color_entry = FCEntry()
+ self.fill_color_button = QtWidgets.QPushButton()
+ self.fill_color_button.setFixedSize(15, 15)
+
+ self.form_box_child_1 = QtWidgets.QHBoxLayout()
+ self.form_box_child_1.addWidget(self.fill_color_entry)
+ self.form_box_child_1.addWidget(self.fill_color_button)
+ self.form_box_child_1.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
+
+ grid2.addWidget(self.fill_color_label, 14, 0)
+ grid2.addLayout(self.form_box_child_1, 14, 1)
+
+ # Plot Fill Transparency Level
+ self.alpha_label = QtWidgets.QLabel('%s:' % _('Alpha'))
+ self.alpha_label.setToolTip(
+ _("Set the fill transparency for plotted objects.")
+ )
+ self.color_alpha_slider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
+ self.color_alpha_slider.setMinimum(0)
+ self.color_alpha_slider.setMaximum(255)
+ self.color_alpha_slider.setSingleStep(1)
+
+ self.color_alpha_spinner = FCSpinner()
+ self.color_alpha_spinner.setMinimumWidth(70)
+ self.color_alpha_spinner.set_range(0, 255)
+
+ self.form_box_child_3 = QtWidgets.QHBoxLayout()
+ self.form_box_child_3.addWidget(self.color_alpha_slider)
+ self.form_box_child_3.addWidget(self.color_alpha_spinner)
+
+ grid2.addWidget(self.alpha_label, 15, 0)
+ grid2.addLayout(self.form_box_child_3, 15, 1)
+
+ self.layout.addStretch()
+
+ current_platform = platform.architecture()[0]
+ if current_platform == '64bit':
+ self.excellon_optimization_label.setDisabled(False)
+ self.excellon_optimization_radio.setDisabled(False)
+ self.optimization_time_label.setDisabled(False)
+ self.optimization_time_entry.setDisabled(False)
+ self.excellon_optimization_radio.activated_custom.connect(self.optimization_selection)
+
+ else:
+ self.excellon_optimization_label.setDisabled(True)
+ self.excellon_optimization_radio.setDisabled(True)
+ self.optimization_time_label.setDisabled(True)
+ self.optimization_time_entry.setDisabled(True)
+
+ # Setting plot colors signals
+ self.line_color_entry.editingFinished.connect(self.on_line_color_entry)
+ self.line_color_button.clicked.connect(self.on_line_color_button)
+ self.fill_color_entry.editingFinished.connect(self.on_fill_color_entry)
+ self.fill_color_button.clicked.connect(self.on_fill_color_button)
+ self.color_alpha_spinner.valueChanged.connect(self.on_color_spinner)
+ self.color_alpha_slider.valueChanged.connect(self.on_color_slider)
# Load the defaults values into the Excellon Format and Excellon Zeros fields
- self.option_dict()["__excellon_restore_defaults"].get_field().clicked.connect(self.on_defaults_button)
-
-
- def build_options(self) -> [OptionUI]:
- return [
- HeadingOptionUI(label_text="Plot Options"),
- CheckboxOptionUI(
- option="excellon_plot",
- label_text="Plot",
- label_tooltip="Plot (show) this object."
- ),
- CheckboxOptionUI(
- option="excellon_solid",
- label_text="Solid",
- label_tooltip="Plot as solid circles."
- ),
- SeparatorOptionUI(),
-
- HeadingOptionUI(
- label_text="Excellon Format",
- label_tooltip="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.\n"
- "\n"
- "Possible presets:\n"
- "\n"
- "PROTEUS 3:3 MM LZ\n"
- "DipTrace 5:2 MM TZ\n"
- "DipTrace 4:3 MM LZ\n"
- "\n"
- "EAGLE 3:3 MM TZ\n"
- "EAGLE 4:3 MM TZ\n"
- "EAGLE 2:5 INCH TZ\n"
- "EAGLE 3:5 INCH TZ\n"
- "\n"
- "ALTIUM 2:4 INCH LZ\n"
- "Sprint Layout 2:4 INCH LZ"
- "\n"
- "KiCAD 3:5 INCH TZ"
- ),
- SpinnerOptionUI(
- option="excellon_format_upper_in",
- label_text="INCH int",
- label_tooltip="This number signifies the number of digits in\nthe whole part of Excellon coordinates.",
- min_value=0, max_value=9, step=1
- ),
- SpinnerOptionUI(
- option="excellon_format_lower_in",
- label_text="INCH decimals",
- label_tooltip="This number signifies the number of digits in\nthe decimal part of Excellon coordinates.",
- min_value=0, max_value=9, step=1
- ),
- SpinnerOptionUI(
- option="excellon_format_upper_mm",
- label_text="METRIC int",
- label_tooltip="This number signifies the number of digits in\nthe whole part of Excellon coordinates.",
- min_value=0, max_value=9, step=1
- ),
- SpinnerOptionUI(
- option="excellon_format_lower_mm",
- label_text="METRIC decimals",
- label_tooltip="This number signifies the number of digits in\nthe decimal part of Excellon coordinates.",
- min_value=0, max_value=9, step=1
- ),
- RadioSetOptionUI(
- option="excellon_zeros",
- label_text="Zeros",
- label_tooltip="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.\n\n"
- "This is used when there is no information\n"
- "stored in the Excellon file.",
- choices=[
- {'label': _('LZ'), 'value': 'L'},
- {'label': _('TZ'), 'value': 'T'}
- ]
- ),
- RadioSetOptionUI(
- option="excellon_units",
- label_text="Units",
- label_tooltip="This sets the default units of Excellon files.\n"
- "If it is not detected in the parsed file the value here\n"
- "will be used."
- "Some Excellon files don't have an header\n"
- "therefore this parameter will be used.",
- choices=[
- {'label': _('INCH'), 'value': 'INCH'},
- {'label': _('MM'), 'value': 'METRIC'}
- ]
- ),
- CheckboxOptionUI(
- option="excellon_update",
- label_text="Update Export settings",
- label_tooltip="If checked, the Excellon Export settings will be updated with the ones above."
- ),
- FullWidthButtonOptionUI(
- option="__excellon_restore_defaults",
- label_text="Restore Defaults",
- label_tooltip=None
- ),
- SeparatorOptionUI(),
-
- HeadingOptionUI(label_text="Excellon Optimization"),
- RadioSetOptionUI(
- option="excellon_optimization_type",
- label_text="Algorithm",
- label_tooltip="This sets the optimization type for the Excellon drill path.\n"
- "If <> is checked then Google OR-Tools algorithm with\n"
- "MetaHeuristic Guided Local Path is used. Default search time is 3sec.\n"
- "If <> is checked then Google OR-Tools Basic algorithm is used.\n"
- "If <> is checked then Travelling Salesman algorithm is used for\n"
- "drill path optimization.\n"
- "\n"
- "If this control is disabled, then FlatCAM works in 32bit mode and it uses\n"
- "Travelling Salesman algorithm for path optimization.",
- choices=[
- {'label': _('MetaHeuristic'), 'value': 'M'},
- {'label': _('Basic'), 'value': 'B'},
- {'label': _('TSA'), 'value': 'T'}
- ],
- orientation="vertical"
- ),
- SpinnerOptionUI(
- option="excellon_search_time",
- label_text="Duration",
- label_tooltip="When OR-Tools Metaheuristic (MH) is enabled there is a\n"
- "maximum threshold for how much time is spent doing the\n"
- "path optimization. This max duration is set here.\n"
- "In seconds.",
- min_value=1, max_value=999, step=1
- ),
- SeparatorOptionUI(),
-
- HeadingOptionUI(label_text="Excellon Object Color"),
- ColorOptionUI(
- option="excellon_plot_line",
- label_text="Outline",
- label_tooltip="Set the line color for plotted objects.",
- ),
- ColorOptionUI(
- option="excellon_plot_fill",
- label_text="Fill",
- label_tooltip="Set the fill color for plotted objects.\n"
- "First 6 digits are the color and the last 2\n"
- "digits are for alpha (transparency) level."
- ),
- ColorAlphaSliderOptionUI(
- applies_to=["excellon_plot_line", "excellon_plot_fill"],
- group=self,
- label_text="Alpha",
- label_tooltip="Set the transparency for plotted objects."
- )
- ]
+ self.excellon_defaults_button.clicked.connect(self.on_excellon_defaults_button)
def optimization_selection(self):
- disable_time = (self.option_dict()["excellon_optimization_type"].get_field().get_value() != 'M')
- self.option_dict()["excellon_search_time"].label_widget.setDisabled(disable_time)
- self.option_dict()["excellon_search_time"].get_field().setDisabled(disable_time)
+ if self.excellon_optimization_radio.get_value() == 'M':
+ self.optimization_time_label.setDisabled(False)
+ self.optimization_time_entry.setDisabled(False)
+ else:
+ self.optimization_time_label.setDisabled(True)
+ self.optimization_time_entry.setDisabled(True)
- def on_defaults_button(self):
- self.option_dict()["excellon_format_lower_in"].get_field().set_value('4')
- self.option_dict()["excellon_format_upper_in"].get_field().set_value('2')
- self.option_dict()["excellon_format_lower_mm"].get_field().set_value('3')
- self.option_dict()["excellon_format_upper_mm"].get_field().set_value('3')
- self.option_dict()["excellon_zeros"].get_field().set_value('L')
- self.option_dict()["excellon_units"].get_field().set_value('INCH')
+ # Setting plot colors handlers
+ def on_fill_color_entry(self):
+ self.app.defaults['excellon_plot_fill'] = self.fill_color_entry.get_value()[:7] + \
+ self.app.defaults['excellon_plot_fill'][7:9]
+ self.fill_color_button.setStyleSheet("background-color:%s" % str(self.app.defaults['excellon_plot_fill'])[:7])
+
+ def on_fill_color_button(self):
+ current_color = QtGui.QColor(self.app.defaults['excellon_plot_fill'][:7])
+
+ c_dialog = QtWidgets.QColorDialog()
+ plot_fill_color = c_dialog.getColor(initial=current_color)
+
+ if plot_fill_color.isValid() is False:
+ return
+
+ self.fill_color_button.setStyleSheet("background-color:%s" % str(plot_fill_color.name()))
+
+ new_val = str(plot_fill_color.name()) + str(self.app.defaults['excellon_plot_fill'][7:9])
+ self.fill_color_entry.set_value(new_val)
+ self.app.defaults['excellon_plot_fill'] = new_val
+
+ def on_color_spinner(self):
+ spinner_value = self.color_alpha_spinner.value()
+ self.color_alpha_slider.setValue(spinner_value)
+ self.app.defaults['excellon_plot_fill'] = \
+ self.app.defaults['excellon_plot_fill'][:7] + \
+ (hex(spinner_value)[2:] if int(hex(spinner_value)[2:], 16) > 0 else '00')
+ self.app.defaults['excellon_plot_line'] = \
+ self.app.defaults['excellon_plot_line'][:7] + \
+ (hex(spinner_value)[2:] if int(hex(spinner_value)[2:], 16) > 0 else '00')
+
+ def on_color_slider(self):
+ slider_value = self.color_alpha_slider.value()
+ self.color_alpha_spinner.setValue(slider_value)
+
+ def on_line_color_entry(self):
+ self.app.defaults['excellon_plot_line'] = self.line_color_entry.get_value()[:7] + \
+ self.app.defaults['excellon_plot_line'][7:9]
+ self.line_color_button.setStyleSheet("background-color:%s" % str(self.app.defaults['excellon_plot_line'])[:7])
+
+ def on_line_color_button(self):
+ current_color = QtGui.QColor(self.app.defaults['excellon_plot_line'][:7])
+ # print(current_color)
+
+ c_dialog = QtWidgets.QColorDialog()
+ plot_line_color = c_dialog.getColor(initial=current_color)
+
+ if plot_line_color.isValid() is False:
+ return
+
+ self.line_color_button.setStyleSheet("background-color:%s" % str(plot_line_color.name()))
+
+ new_val_line = str(plot_line_color.name()) + str(self.app.defaults['excellon_plot_line'][7:9])
+ self.line_color_entry.set_value(new_val_line)
+ self.app.defaults['excellon_plot_line'] = new_val_line
+
+ def on_excellon_defaults_button(self):
+ self.app.preferencesUiManager.defaults_form_fields["excellon_format_lower_in"].set_value('4')
+ self.app.preferencesUiManager.defaults_form_fields["excellon_format_upper_in"].set_value('2')
+ self.app.preferencesUiManager.defaults_form_fields["excellon_format_lower_mm"].set_value('3')
+ self.app.preferencesUiManager.defaults_form_fields["excellon_format_upper_mm"].set_value('3')
+ self.app.preferencesUiManager.defaults_form_fields["excellon_zeros"].set_value('L')
+ self.app.preferencesUiManager.defaults_form_fields["excellon_units"].set_value('INCH')
diff --git a/flatcamGUI/preferences/excellon/ExcellonOptPrefGroupUI.py b/flatcamGUI/preferences/excellon/ExcellonOptPrefGroupUI.py
index 4f68eaca..cdc6ce5e 100644
--- a/flatcamGUI/preferences/excellon/ExcellonOptPrefGroupUI.py
+++ b/flatcamGUI/preferences/excellon/ExcellonOptPrefGroupUI.py
@@ -1,7 +1,10 @@
-from flatcamGUI.GUIElements import OptionalInputSection
+from PyQt5 import QtWidgets
+from PyQt5.QtCore import Qt, QSettings
+
+from flatcamGUI.GUIElements import RadioSet, FCDoubleSpinner, FCCheckBox, FCEntry, FCSpinner, OptionalInputSection, \
+ FCComboBox
from flatcamGUI.preferences import machinist_setting
-from flatcamGUI.preferences.OptionUI import *
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI2
+from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
import gettext
import FlatCAMTranslation as fcTranslate
import builtins
@@ -17,182 +20,298 @@ else:
machinist_setting = 0
-class ExcellonOptPrefGroupUI(OptionsGroupUI2):
+class ExcellonOptPrefGroupUI(OptionsGroupUI):
+
+ def __init__(self, decimals=4, parent=None):
+ # OptionsGroupUI.__init__(self, "Excellon Options", parent=parent)
+ super(ExcellonOptPrefGroupUI, self).__init__(self, parent=parent)
- def __init__(self, decimals=4, **kwargs):
- self.decimals = decimals
- super().__init__(**kwargs)
self.setTitle(str(_("Excellon Options")))
+ self.decimals = decimals
- self.pp_excellon_name_cb = self.option_dict()["excellon_ppname_e"].get_field()
+ # ## Create CNC Job
+ self.cncjob_label = QtWidgets.QLabel('%s' % _('Create CNC Job'))
+ self.cncjob_label.setToolTip(
+ _("Parameters used to create a CNC Job object\n"
+ "for this drill object.")
+ )
+ self.layout.addWidget(self.cncjob_label)
- self.multidepth_cb = self.option_dict()["excellon_multidepth"].get_field()
- self.depthperpass_entry = self.option_dict()["excellon_depthperpass"].get_field()
- self.ois_multidepth = OptionalInputSection(self.multidepth_cb, [self.depthperpass_entry])
+ grid2 = QtWidgets.QGridLayout()
+ self.layout.addLayout(grid2)
+ grid2.setColumnStretch(0, 0)
+ grid2.setColumnStretch(1, 1)
- self.dwell_cb = self.option_dict()["excellon_dwell"].get_field()
- self.dwelltime_entry = self.option_dict()["excellon_dwelltime"].get_field()
- self.ois_dwell = OptionalInputSection(self.dwell_cb, [self.dwelltime_entry])
+ # Operation Type
+ self.operation_label = QtWidgets.QLabel('%s:' % _('Operation'))
+ self.operation_label.setToolTip(
+ _("Operation type:\n"
+ "- Drilling -> will drill the drills/slots associated with this tool\n"
+ "- Milling -> will mill the drills/slots")
+ )
+ self.operation_radio = RadioSet(
+ [
+ {'label': _('Drilling'), 'value': 'drill'},
+ {'label': _("Milling"), 'value': 'mill'}
+ ]
+ )
- # FIXME until this feature is implemented these are disabled
- self.option_dict()["excellon_gcode_type"].label_widget.hide()
- self.option_dict()["excellon_gcode_type"].get_field().hide()
+ grid2.addWidget(self.operation_label, 0, 0)
+ grid2.addWidget(self.operation_radio, 0, 1)
- def build_options(self) -> [OptionUI]:
- return [
- HeadingOptionUI(
- label_text="Create CNC Job",
- label_tooltip="Parameters used to create a CNC Job object\n"
- "for this drill object."
- ),
- RadioSetOptionUI(
- option="excellon_operation",
- label_text="Operation",
- label_bold=True,
- label_tooltip="Operation type:\n"
- "- Drilling -> will drill the drills/slots associated with this tool\n"
- "- Milling -> will mill the drills/slots",
- choices=[
- {'label': _('Drilling'), 'value': 'drill'},
- {'label': _("Milling"), 'value': 'mill'}
- ]
- ),
- RadioSetOptionUI(
- option="excellon_milling_type",
- label_text="Milling Type",
- label_tooltip="Milling type:\n"
- "- Drills -> will mill the drills associated with this tool\n"
- "- Slots -> will mill the slots associated with this tool\n"
- "- Both -> will mill both drills and mills or whatever is available",
- choices=[
- {'label': _('Drills'), 'value': 'drills'},
- {'label': _("Slots"), 'value': 'slots'},
- {'label': _("Both"), 'value': 'both'},
- ]
- ),
- DoubleSpinnerOptionUI(
- option="excellon_milling_dia",
- label_text="Milling Diameter",
- label_tooltip="The diameter of the tool who will do the milling",
- min_value=0.0, max_value=9999.9999, step=0.1, decimals=self.decimals
- ),
- DoubleSpinnerOptionUI(
- option="excellon_cutz",
- label_text="Cut Z",
- label_tooltip="Drill depth (negative) \nbelow the copper surface.",
- min_value=-9999.9999, max_value=(9999.9999 if machinist_setting else 0.0),
- step=0.1, decimals=self.decimals
- ),
+ self.mill_type_label = QtWidgets.QLabel('%s:' % _('Milling Type'))
+ self.mill_type_label.setToolTip(
+ _("Milling type:\n"
+ "- Drills -> will mill the drills associated with this tool\n"
+ "- Slots -> will mill the slots associated with this tool\n"
+ "- Both -> will mill both drills and mills or whatever is available")
+ )
+ self.milling_type_radio = RadioSet(
+ [
+ {'label': _('Drills'), 'value': 'drills'},
+ {'label': _("Slots"), 'value': 'slots'},
+ {'label': _("Both"), 'value': 'both'},
+ ]
+ )
+ grid2.addWidget(self.mill_type_label, 1, 0)
+ grid2.addWidget(self.milling_type_radio, 1, 1)
- CheckboxOptionUI(
- option="excellon_multidepth",
- label_text="Multi-Depth",
- label_tooltip="Use multiple passes to limit\n"
- "the cut depth in each pass. Will\n"
- "cut multiple times until Cut Z is\n"
- "reached."
- ),
- DoubleSpinnerOptionUI(
- option="excellon_depthperpass",
- label_text="Depth/Pass",
- label_tooltip="Depth of each pass (positive).",
- min_value=0, max_value=99999, step=0.1, decimals=self.decimals
- ),
- DoubleSpinnerOptionUI(
- option="excellon_travelz",
- label_text="Travel Z",
- label_tooltip="Tool height when travelling\nacross the XY plane.",
- min_value=(-9999.9999 if machinist_setting else 0.0001), max_value=9999.9999,
- step=0.1, decimals=self.decimals
- ),
- CheckboxOptionUI(
- option="excellon_toolchange",
- label_text="Tool change",
- label_tooltip="Include tool-change sequence\nin G-Code (Pause for tool change)."
- ),
- DoubleSpinnerOptionUI(
- option="excellon_toolchangez",
- label_text="Toolchange Z",
- label_tooltip="Z-axis position (height) for\ntool change.",
- min_value=(-9999.9999 if machinist_setting else 0.0), max_value=9999.9999,
- step=0.1, decimals=self.decimals
- ),
- DoubleSpinnerOptionUI(
- option="excellon_endz",
- label_text="End move Z",
- label_tooltip="Height of the tool after\nthe last move at the end of the job.",
- min_value=(-9999.9999 if machinist_setting else 0.0), max_value=9999.9999,
- step=0.1, decimals=self.decimals
- ),
- LineEntryOptionUI(
- option="excellon_endxy",
- label_text="End move X,Y",
- label_tooltip="End move X,Y position. In format (x,y).\n"
- "If no value is entered then there is no move\n"
- "on X,Y plane at the end of the job."
- ),
- DoubleSpinnerOptionUI(
- option="excellon_feedrate_z",
- label_text="Feedrate Z",
- label_tooltip="Tool speed while drilling\n"
- "(in units per minute).\n"
- "So called 'Plunge' feedrate.\n"
- "This is for linear move G01.",
- min_value=0, max_value=99999.9999, step=0.1, decimals=self.decimals
- ),
- SpinnerOptionUI(
- option="excellon_spindlespeed",
- label_text="Spindle speed",
- label_tooltip="Speed of the spindle in RPM (optional).",
- min_value=0, max_value=1000000, step=100
- ),
- CheckboxOptionUI(
- option="excellon_dwell",
- label_text="Enable Dwell",
- label_tooltip="Pause to allow the spindle to reach its\nspeed before cutting."
- ),
- DoubleSpinnerOptionUI(
- option="excellon_dwelltime",
- label_text="Duration",
- label_tooltip="Number of time units for spindle to dwell.",
- min_value=0, max_value=999999, step=0.5, decimals=self.decimals
- ),
- ComboboxOptionUI(
- option="excellon_ppname_e",
- label_text="Preprocessor",
- label_tooltip="The preprocessor JSON file that dictates\nGcode output.", # FIXME tooltip incorrect?
- choices=[] # Populated in App (FIXME)
- ),
- RadioSetOptionUI(
- option="excellon_gcode_type",
- label_text="Gcode",
- label_bold=True,
- label_tooltip="Choose what to use for GCode generation:\n"
- "'Drills', 'Slots' or 'Both'.\n"
- "When choosing 'Slots' or 'Both', slots will be\n"
- "converted to drills.",
- choices=[
- {'label': 'Drills', 'value': 'drills'},
- {'label': 'Slots', 'value': 'slots'},
- {'label': 'Both', 'value': 'both'}
- ]
- ),
+ self.mill_dia_label = QtWidgets.QLabel('%s:' % _('Milling Diameter'))
+ self.mill_dia_label.setToolTip(
+ _("The diameter of the tool who will do the milling")
+ )
- HeadingOptionUI(
- label_text="Mill Holes",
- label_tooltip="Create Geometry for milling holes."
- ),
- DoubleSpinnerOptionUI(
- option="excellon_tooldia",
- label_text="Drill Tool dia",
- label_tooltip="Diameter of the cutting tool",
- min_value=0.0, max_value=999.9999, step=0.1, decimals=self.decimals
- ),
- DoubleSpinnerOptionUI(
- option="excellon_slot_tooldia",
- label_text="Slot Tool dia",
- label_tooltip="Diameter of the cutting tool\nwhen milling slots.",
- min_value=0.0, max_value=999.9999, step=0.1, decimals=self.decimals
+ self.mill_dia_entry = FCDoubleSpinner()
+ self.mill_dia_entry.set_precision(self.decimals)
+ self.mill_dia_entry.set_range(0.0000, 9999.9999)
+
+ grid2.addWidget(self.mill_dia_label, 2, 0)
+ grid2.addWidget(self.mill_dia_entry, 2, 1)
+
+ # Cut Z
+ cutzlabel = QtWidgets.QLabel('%s:' % _('Cut Z'))
+ cutzlabel.setToolTip(
+ _("Drill depth (negative)\n"
+ "below the copper surface.")
+ )
+
+ self.cutz_entry = FCDoubleSpinner()
+
+ if machinist_setting == 0:
+ self.cutz_entry.set_range(-9999.9999, 0.0000)
+ else:
+ self.cutz_entry.set_range(-9999.9999, 9999.9999)
+
+ self.cutz_entry.setSingleStep(0.1)
+ self.cutz_entry.set_precision(self.decimals)
+
+ grid2.addWidget(cutzlabel, 3, 0)
+ grid2.addWidget(self.cutz_entry, 3, 1)
+
+ # Multi-Depth
+ self.mpass_cb = FCCheckBox('%s:' % _("Multi-Depth"))
+ self.mpass_cb.setToolTip(
+ _(
+ "Use multiple passes to limit\n"
+ "the cut depth in each pass. Will\n"
+ "cut multiple times until Cut Z is\n"
+ "reached."
)
- ]
+ )
+
+ self.maxdepth_entry = FCDoubleSpinner()
+ self.maxdepth_entry.set_precision(self.decimals)
+ self.maxdepth_entry.set_range(0, 9999.9999)
+ self.maxdepth_entry.setSingleStep(0.1)
+
+ self.maxdepth_entry.setToolTip(_("Depth of each pass (positive)."))
+
+ grid2.addWidget(self.mpass_cb, 4, 0)
+ grid2.addWidget(self.maxdepth_entry, 4, 1)
+
+ # Travel Z
+ travelzlabel = QtWidgets.QLabel('%s:' % _('Travel Z'))
+ travelzlabel.setToolTip(
+ _("Tool height when travelling\n"
+ "across the XY plane.")
+ )
+
+ self.travelz_entry = FCDoubleSpinner()
+ self.travelz_entry.set_precision(self.decimals)
+
+ if machinist_setting == 0:
+ self.travelz_entry.set_range(0.0001, 9999.9999)
+ else:
+ self.travelz_entry.set_range(-9999.9999, 9999.9999)
+
+ grid2.addWidget(travelzlabel, 5, 0)
+ grid2.addWidget(self.travelz_entry, 5, 1)
+
+ # Tool change:
+ self.toolchange_cb = FCCheckBox('%s' % _("Tool change"))
+ self.toolchange_cb.setToolTip(
+ _("Include tool-change sequence\n"
+ "in G-Code (Pause for tool change).")
+ )
+ grid2.addWidget(self.toolchange_cb, 6, 0, 1, 2)
+
+ # Tool Change Z
+ toolchangezlabel = QtWidgets.QLabel('%s:' % _('Toolchange Z'))
+ toolchangezlabel.setToolTip(
+ _("Z-axis position (height) for\n"
+ "tool change.")
+ )
+
+ self.toolchangez_entry = FCDoubleSpinner()
+ self.toolchangez_entry.set_precision(self.decimals)
+
+ if machinist_setting == 0:
+ self.toolchangez_entry.set_range(0.0001, 9999.9999)
+ else:
+ self.toolchangez_entry.set_range(-9999.9999, 9999.9999)
+
+ grid2.addWidget(toolchangezlabel, 7, 0)
+ grid2.addWidget(self.toolchangez_entry, 7, 1)
+
+ # End Move Z
+ endz_label = QtWidgets.QLabel('%s:' % _('End move Z'))
+ endz_label.setToolTip(
+ _("Height of the tool after\n"
+ "the last move at the end of the job.")
+ )
+ self.endz_entry = FCDoubleSpinner()
+ self.endz_entry.set_precision(self.decimals)
+
+ if machinist_setting == 0:
+ self.endz_entry.set_range(0.0000, 9999.9999)
+ else:
+ self.endz_entry.set_range(-9999.9999, 9999.9999)
+
+ grid2.addWidget(endz_label, 8, 0)
+ grid2.addWidget(self.endz_entry, 8, 1)
+
+ # End Move X,Y
+ endmove_xy_label = QtWidgets.QLabel('%s:' % _('End move X,Y'))
+ endmove_xy_label.setToolTip(
+ _("End move X,Y position. In format (x,y).\n"
+ "If no value is entered then there is no move\n"
+ "on X,Y plane at the end of the job.")
+ )
+ self.endxy_entry = FCEntry()
+
+ grid2.addWidget(endmove_xy_label, 9, 0)
+ grid2.addWidget(self.endxy_entry, 9, 1)
+
+ # Feedrate Z
+ frlabel = QtWidgets.QLabel('%s:' % _('Feedrate Z'))
+ frlabel.setToolTip(
+ _("Tool speed while drilling\n"
+ "(in units per minute).\n"
+ "So called 'Plunge' feedrate.\n"
+ "This is for linear move G01.")
+ )
+ self.feedrate_z_entry = FCDoubleSpinner()
+ self.feedrate_z_entry.set_precision(self.decimals)
+ self.feedrate_z_entry.set_range(0, 99999.9999)
+
+ grid2.addWidget(frlabel, 10, 0)
+ grid2.addWidget(self.feedrate_z_entry, 10, 1)
+
+ # Spindle speed
+ spdlabel = QtWidgets.QLabel('%s:' % _('Spindle Speed'))
+ spdlabel.setToolTip(
+ _("Speed of the spindle\n"
+ "in RPM (optional)")
+ )
+
+ self.spindlespeed_entry = FCSpinner()
+ self.spindlespeed_entry.set_range(0, 1000000)
+ self.spindlespeed_entry.set_step(100)
+
+ grid2.addWidget(spdlabel, 11, 0)
+ grid2.addWidget(self.spindlespeed_entry, 11, 1)
+
+ # Dwell
+ self.dwell_cb = FCCheckBox('%s' % _('Enable Dwell'))
+ self.dwell_cb .setToolTip(
+ _("Pause to allow the spindle to reach its\n"
+ "speed before cutting.")
+ )
+
+ grid2.addWidget(self.dwell_cb, 12, 0, 1, 2)
+
+ # Dwell Time
+ dwelltime = QtWidgets.QLabel('%s:' % _('Duration'))
+ dwelltime.setToolTip(_("Number of time units for spindle to dwell."))
+ self.dwelltime_entry = FCDoubleSpinner()
+ self.dwelltime_entry.set_precision(self.decimals)
+ self.dwelltime_entry.set_range(0, 99999.9999)
+
+ grid2.addWidget(dwelltime, 13, 0)
+ grid2.addWidget(self.dwelltime_entry, 13, 1)
+
+ self.ois_dwell_exc = OptionalInputSection(self.dwell_cb, [self.dwelltime_entry])
+
+ # preprocessor selection
+ pp_excellon_label = QtWidgets.QLabel('%s:' % _("Preprocessor"))
+ pp_excellon_label.setToolTip(
+ _("The preprocessor JSON file that dictates\n"
+ "Gcode output.")
+ )
+
+ self.pp_excellon_name_cb = FCComboBox()
+ self.pp_excellon_name_cb.setFocusPolicy(Qt.StrongFocus)
+
+ grid2.addWidget(pp_excellon_label, 14, 0)
+ grid2.addWidget(self.pp_excellon_name_cb, 14, 1)
+
+ # ### Choose what to use for Gcode creation: Drills, Slots or Both
+ excellon_gcode_type_label = QtWidgets.QLabel('%s' % _('Gcode'))
+ excellon_gcode_type_label.setToolTip(
+ _("Choose what to use for GCode generation:\n"
+ "'Drills', 'Slots' or 'Both'.\n"
+ "When choosing 'Slots' or 'Both', slots will be\n"
+ "converted to drills.")
+ )
+ self.excellon_gcode_type_radio = RadioSet([{'label': 'Drills', 'value': 'drills'},
+ {'label': 'Slots', 'value': 'slots'},
+ {'label': 'Both', 'value': 'both'}])
+ grid2.addWidget(excellon_gcode_type_label, 15, 0)
+ grid2.addWidget(self.excellon_gcode_type_radio, 15, 1)
+
+ # until I decide to implement this feature those remain disabled
+ excellon_gcode_type_label.hide()
+ self.excellon_gcode_type_radio.setVisible(False)
+
+ # ### Milling Holes ## ##
+ self.mill_hole_label = QtWidgets.QLabel('%s' % _('Mill Holes'))
+ self.mill_hole_label.setToolTip(
+ _("Create Geometry for milling holes.")
+ )
+ grid2.addWidget(self.mill_hole_label, 16, 0, 1, 2)
+
+ tdlabel = QtWidgets.QLabel('%s:' % _('Drill Tool dia'))
+ tdlabel.setToolTip(
+ _("Diameter of the cutting tool.")
+ )
+ self.tooldia_entry = FCDoubleSpinner()
+ self.tooldia_entry.set_precision(self.decimals)
+ self.tooldia_entry.set_range(0, 999.9999)
+
+ grid2.addWidget(tdlabel, 18, 0)
+ grid2.addWidget(self.tooldia_entry, 18, 1)
+
+ stdlabel = QtWidgets.QLabel('%s:' % _('Slot Tool dia'))
+ stdlabel.setToolTip(
+ _("Diameter of the cutting tool\n"
+ "when milling slots.")
+ )
+ self.slot_tooldia_entry = FCDoubleSpinner()
+ self.slot_tooldia_entry.set_precision(self.decimals)
+ self.slot_tooldia_entry.set_range(0, 999.9999)
+
+ grid2.addWidget(stdlabel, 21, 0)
+ grid2.addWidget(self.slot_tooldia_entry, 21, 1)
+
+ self.layout.addStretch()
diff --git a/flatcamGUI/preferences/excellon/ExcellonPreferencesUI.py b/flatcamGUI/preferences/excellon/ExcellonPreferencesUI.py
index 91176f9d..b3d6d165 100644
--- a/flatcamGUI/preferences/excellon/ExcellonPreferencesUI.py
+++ b/flatcamGUI/preferences/excellon/ExcellonPreferencesUI.py
@@ -1,5 +1,6 @@
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
-from flatcamGUI.preferences.PreferencesSectionUI import PreferencesSectionUI
+from PyQt5 import QtWidgets
+from PyQt5.QtCore import QSettings
+
from flatcamGUI.preferences.excellon.ExcellonEditorPrefGroupUI import ExcellonEditorPrefGroupUI
from flatcamGUI.preferences.excellon.ExcellonExpPrefGroupUI import ExcellonExpPrefGroupUI
from flatcamGUI.preferences.excellon.ExcellonAdvOptPrefGroupUI import ExcellonAdvOptPrefGroupUI
@@ -9,62 +10,44 @@ from flatcamGUI.preferences.excellon.ExcellonGenPrefGroupUI import ExcellonGenPr
import gettext
import FlatCAMTranslation as fcTranslate
import builtins
+
fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__:
_ = gettext.gettext
+settings = QSettings("Open Source", "FlatCAM")
+if settings.contains("machinist"):
+ machinist_setting = settings.value('machinist', type=int)
+else:
+ machinist_setting = 0
-class ExcellonPreferencesUI(PreferencesSectionUI):
- def __init__(self, decimals, **kwargs):
+class ExcellonPreferencesUI(QtWidgets.QWidget):
+
+ def __init__(self, decimals, parent=None):
+ QtWidgets.QWidget.__init__(self, parent=parent)
+ self.layout = QtWidgets.QHBoxLayout()
+ self.setLayout(self.layout)
self.decimals = decimals
- # FIXME: remove the need for external access to excellon_opt_group
+
+ self.excellon_gen_group = ExcellonGenPrefGroupUI(decimals=self.decimals)
+ self.excellon_gen_group.setMinimumWidth(220)
self.excellon_opt_group = ExcellonOptPrefGroupUI(decimals=self.decimals)
- super().__init__(**kwargs)
- self.init_sync_export()
+ self.excellon_opt_group.setMinimumWidth(290)
+ self.excellon_exp_group = ExcellonExpPrefGroupUI(decimals=self.decimals)
+ self.excellon_exp_group.setMinimumWidth(250)
+ self.excellon_adv_opt_group = ExcellonAdvOptPrefGroupUI(decimals=self.decimals)
+ self.excellon_adv_opt_group.setMinimumWidth(250)
+ self.excellon_editor_group = ExcellonEditorPrefGroupUI(decimals=self.decimals)
+ self.excellon_editor_group.setMinimumWidth(260)
- def build_groups(self) -> [OptionsGroupUI]:
- return [
- ExcellonGenPrefGroupUI(decimals=self.decimals),
- self.excellon_opt_group,
- ExcellonExpPrefGroupUI(decimals=self.decimals),
- ExcellonAdvOptPrefGroupUI(decimals=self.decimals),
- ExcellonEditorPrefGroupUI(decimals=self.decimals)
- ]
-
- def get_tab_id(self):
- return "excellon_tab"
-
- def get_tab_label(self):
- return _("EXCELLON")
-
- def init_sync_export(self):
- self.option_dict()["excellon_update"].get_field().stateChanged.connect(self.sync_export)
- self.option_dict()["excellon_format_upper_in"].get_field().returnPressed.connect(self.sync_export)
- self.option_dict()["excellon_format_lower_in"].get_field().returnPressed.connect(self.sync_export)
- self.option_dict()["excellon_format_upper_mm"].get_field().returnPressed.connect(self.sync_export)
- self.option_dict()["excellon_format_lower_mm"].get_field().returnPressed.connect(self.sync_export)
- self.option_dict()["excellon_zeros"].get_field().activated_custom.connect(self.sync_export)
- self.option_dict()["excellon_units"].get_field().activated_custom.connect(self.sync_export)
-
- def sync_export(self):
- if not self.option_dict()["excellon_update"].get_field().get_value():
- # User has disabled sync.
- return
-
- zeros = self.option_dict()["excellon_zeros"].get_field().get_value() + 'Z'
- self.option_dict()["excellon_exp_zeros"].get_field().set_value(zeros)
-
- units = self.option_dict()["excellon_units"].get_field().get_value()
- self.option_dict()["excellon_exp_units"].get_field().set_value(units)
-
- if units.upper() == 'METRIC':
- whole = self.option_dict()["excellon_format_upper_mm"].get_field().get_value()
- dec = self.option_dict()["excellon_format_lower_mm"].get_field().get_value()
- else:
- whole = self.option_dict()["excellon_format_upper_in"].get_field().get_value()
- dec = self.option_dict()["excellon_format_lower_in"].get_field().get_value()
- self.option_dict()["excellon_exp_integer"].get_field().set_value(whole)
- self.option_dict()["excellon_exp_decimals"].get_field().set_value(dec)
+ self.vlay = QtWidgets.QVBoxLayout()
+ self.vlay.addWidget(self.excellon_opt_group)
+ self.vlay.addWidget(self.excellon_exp_group)
+ self.layout.addWidget(self.excellon_gen_group)
+ self.layout.addLayout(self.vlay)
+ self.layout.addWidget(self.excellon_adv_opt_group)
+ self.layout.addWidget(self.excellon_editor_group)
+ self.layout.addStretch()
diff --git a/flatcamGUI/preferences/general/GeneralAPPSetGroupUI.py b/flatcamGUI/preferences/general/GeneralAPPSetGroupUI.py
new file mode 100644
index 00000000..3daff809
--- /dev/null
+++ b/flatcamGUI/preferences/general/GeneralAPPSetGroupUI.py
@@ -0,0 +1,483 @@
+from PyQt5 import QtCore, QtWidgets, QtGui
+from PyQt5.QtCore import QSettings
+
+from flatcamGUI.GUIElements import FCDoubleSpinner, FCCheckBox, FCComboBox, RadioSet, OptionalInputSection, FCSpinner, \
+ FCEntry
+from flatcamGUI.preferences import settings
+from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
+
+import gettext
+import FlatCAMTranslation as fcTranslate
+import builtins
+
+fcTranslate.apply_language('strings')
+if '_' not in builtins.__dict__:
+ _ = gettext.gettext
+
+settings = QSettings("Open Source", "FlatCAM")
+if settings.contains("machinist"):
+ machinist_setting = settings.value('machinist', type=int)
+else:
+ machinist_setting = 0
+
+
+class GeneralAPPSetGroupUI(OptionsGroupUI):
+ def __init__(self, decimals=4, parent=None):
+ super(GeneralAPPSetGroupUI, self).__init__(self, parent=parent)
+
+ self.setTitle(str(_("App Settings")))
+ self.decimals = decimals
+
+ theme_settings = QtCore.QSettings("Open Source", "FlatCAM")
+ if theme_settings.contains("theme"):
+ theme = theme_settings.value('theme', type=str)
+ else:
+ theme = 'white'
+
+ if theme == 'white':
+ self.resource_loc = 'assets/resources'
+ else:
+ self.resource_loc = 'assets/resources'
+
+ # Create a grid layout for the Application general settings
+ grid0 = QtWidgets.QGridLayout()
+ self.layout.addLayout(grid0)
+ grid0.setColumnStretch(0, 0)
+ grid0.setColumnStretch(1, 1)
+
+ # GRID Settings
+ self.grid_label = QtWidgets.QLabel('%s' % _('Grid Settings'))
+ grid0.addWidget(self.grid_label, 0, 0, 1, 2)
+
+ # Grid X Entry
+ self.gridx_label = QtWidgets.QLabel('%s:' % _('X value'))
+ self.gridx_label.setToolTip(
+ _("This is the Grid snap value on X axis.")
+ )
+ self.gridx_entry = FCDoubleSpinner()
+ self.gridx_entry.set_precision(self.decimals)
+ self.gridx_entry.setSingleStep(0.1)
+
+ grid0.addWidget(self.gridx_label, 1, 0)
+ grid0.addWidget(self.gridx_entry, 1, 1)
+
+ # Grid Y Entry
+ self.gridy_label = QtWidgets.QLabel('%s:' % _('Y value'))
+ self.gridy_label.setToolTip(
+ _("This is the Grid snap value on Y axis.")
+ )
+ self.gridy_entry = FCDoubleSpinner()
+ self.gridy_entry.set_precision(self.decimals)
+ self.gridy_entry.setSingleStep(0.1)
+
+ grid0.addWidget(self.gridy_label, 2, 0)
+ grid0.addWidget(self.gridy_entry, 2, 1)
+
+ # Snap Max Entry
+ self.snap_max_label = QtWidgets.QLabel('%s:' % _('Snap Max'))
+ self.snap_max_label.setToolTip(_("Max. magnet distance"))
+ self.snap_max_dist_entry = FCDoubleSpinner()
+ self.snap_max_dist_entry.set_precision(self.decimals)
+ self.snap_max_dist_entry.setSingleStep(0.1)
+
+ grid0.addWidget(self.snap_max_label, 3, 0)
+ grid0.addWidget(self.snap_max_dist_entry, 3, 1)
+
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid0.addWidget(separator_line, 4, 0, 1, 2)
+
+ # Workspace
+ self.workspace_label = QtWidgets.QLabel('%s' % _('Workspace Settings'))
+ grid0.addWidget(self.workspace_label, 5, 0, 1, 2)
+
+ self.workspace_cb = FCCheckBox('%s' % _('Active'))
+ self.workspace_cb.setToolTip(
+ _("Draw a delimiting rectangle on canvas.\n"
+ "The purpose is to illustrate the limits for our work.")
+ )
+
+ grid0.addWidget(self.workspace_cb, 6, 0, 1, 2)
+
+ self.workspace_type_lbl = QtWidgets.QLabel('%s:' % _('Size'))
+ self.workspace_type_lbl.setToolTip(
+ _("Select the type of rectangle to be used on canvas,\n"
+ "as valid workspace.")
+ )
+ self.wk_cb = FCComboBox()
+
+ grid0.addWidget(self.workspace_type_lbl, 7, 0)
+ grid0.addWidget(self.wk_cb, 7, 1)
+
+ self.pagesize = {}
+ self.pagesize.update(
+ {
+ 'A0': (841, 1189),
+ 'A1': (594, 841),
+ 'A2': (420, 594),
+ 'A3': (297, 420),
+ 'A4': (210, 297),
+ 'A5': (148, 210),
+ 'A6': (105, 148),
+ 'A7': (74, 105),
+ 'A8': (52, 74),
+ 'A9': (37, 52),
+ 'A10': (26, 37),
+
+ 'B0': (1000, 1414),
+ 'B1': (707, 1000),
+ 'B2': (500, 707),
+ 'B3': (353, 500),
+ 'B4': (250, 353),
+ 'B5': (176, 250),
+ 'B6': (125, 176),
+ 'B7': (88, 125),
+ 'B8': (62, 88),
+ 'B9': (44, 62),
+ 'B10': (31, 44),
+
+ 'C0': (917, 1297),
+ 'C1': (648, 917),
+ 'C2': (458, 648),
+ 'C3': (324, 458),
+ 'C4': (229, 324),
+ 'C5': (162, 229),
+ 'C6': (114, 162),
+ 'C7': (81, 114),
+ 'C8': (57, 81),
+ 'C9': (40, 57),
+ 'C10': (28, 40),
+
+ # American paper sizes
+ 'LETTER': (8.5, 11),
+ 'LEGAL': (8.5, 14),
+ 'ELEVENSEVENTEEN': (11, 17),
+
+ # From https://en.wikipedia.org/wiki/Paper_size
+ 'JUNIOR_LEGAL': (5, 8),
+ 'HALF_LETTER': (5.5, 8),
+ 'GOV_LETTER': (8, 10.5),
+ 'GOV_LEGAL': (8.5, 13),
+ 'LEDGER': (17, 11),
+ }
+ )
+
+ page_size_list = list(self.pagesize.keys())
+
+ self.wk_cb.addItems(page_size_list)
+
+ # Page orientation
+ self.wk_orientation_label = QtWidgets.QLabel('%s:' % _("Orientation"))
+ self.wk_orientation_label.setToolTip(_("Can be:\n"
+ "- Portrait\n"
+ "- Landscape"))
+
+ self.wk_orientation_radio = RadioSet([{'label': _('Portrait'), 'value': 'p'},
+ {'label': _('Landscape'), 'value': 'l'},
+ ], stretch=False)
+
+ self.wks = OptionalInputSection(self.workspace_cb,
+ [
+ self.workspace_type_lbl,
+ self.wk_cb,
+ self.wk_orientation_label,
+ self.wk_orientation_radio
+ ])
+
+ grid0.addWidget(self.wk_orientation_label, 8, 0)
+ grid0.addWidget(self.wk_orientation_radio, 8, 1)
+
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid0.addWidget(separator_line, 9, 0, 1, 2)
+
+ # Font Size
+ self.font_size_label = QtWidgets.QLabel('%s' % _('Font Size'))
+ grid0.addWidget(self.font_size_label, 10, 0, 1, 2)
+
+ # Notebook Font Size
+ self.notebook_font_size_label = QtWidgets.QLabel('%s:' % _('Notebook'))
+ self.notebook_font_size_label.setToolTip(
+ _("This sets the font size for the elements found in the Notebook.\n"
+ "The notebook is the collapsible area in the left side of the GUI,\n"
+ "and include the Project, Selected and Tool tabs.")
+ )
+
+ self.notebook_font_size_spinner = FCSpinner()
+ self.notebook_font_size_spinner.set_range(8, 40)
+ self.notebook_font_size_spinner.setWrapping(True)
+
+ qsettings = QSettings("Open Source", "FlatCAM")
+ if qsettings.contains("notebook_font_size"):
+ self.notebook_font_size_spinner.set_value(qsettings.value('notebook_font_size', type=int))
+ else:
+ self.notebook_font_size_spinner.set_value(12)
+
+ grid0.addWidget(self.notebook_font_size_label, 11, 0)
+ grid0.addWidget(self.notebook_font_size_spinner, 11, 1)
+
+ # Axis Font Size
+ self.axis_font_size_label = QtWidgets.QLabel('%s:' % _('Axis'))
+ self.axis_font_size_label.setToolTip(
+ _("This sets the font size for canvas axis.")
+ )
+
+ self.axis_font_size_spinner = FCSpinner()
+ self.axis_font_size_spinner.set_range(0, 40)
+ self.axis_font_size_spinner.setWrapping(True)
+
+ qsettings = QSettings("Open Source", "FlatCAM")
+ if qsettings.contains("axis_font_size"):
+ self.axis_font_size_spinner.set_value(qsettings.value('axis_font_size', type=int))
+ else:
+ self.axis_font_size_spinner.set_value(8)
+
+ grid0.addWidget(self.axis_font_size_label, 12, 0)
+ grid0.addWidget(self.axis_font_size_spinner, 12, 1)
+
+ # TextBox Font Size
+ self.textbox_font_size_label = QtWidgets.QLabel('%s:' % _('Textbox'))
+ self.textbox_font_size_label.setToolTip(
+ _("This sets the font size for the Textbox GUI\n"
+ "elements that are used in FlatCAM.")
+ )
+
+ self.textbox_font_size_spinner = FCSpinner()
+ self.textbox_font_size_spinner.set_range(8, 40)
+ self.textbox_font_size_spinner.setWrapping(True)
+
+ qsettings = QSettings("Open Source", "FlatCAM")
+ if qsettings.contains("textbox_font_size"):
+ self.textbox_font_size_spinner.set_value(settings.value('textbox_font_size', type=int))
+ else:
+ self.textbox_font_size_spinner.set_value(10)
+
+ grid0.addWidget(self.textbox_font_size_label, 13, 0)
+ grid0.addWidget(self.textbox_font_size_spinner, 13, 1)
+
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid0.addWidget(separator_line, 14, 0, 1, 2)
+
+ # -----------------------------------------------------------
+ # -------------- MOUSE SETTINGS -----------------------------
+ # -----------------------------------------------------------
+
+ self.mouse_lbl = QtWidgets.QLabel('%s' % _('Mouse Settings'))
+ grid0.addWidget(self.mouse_lbl, 21, 0, 1, 2)
+
+ # Mouse Cursor Shape
+ self.cursor_lbl = QtWidgets.QLabel('%s:' % _('Cursor Shape'))
+ self.cursor_lbl.setToolTip(
+ _("Choose a mouse cursor shape.\n"
+ "- Small -> with a customizable size.\n"
+ "- Big -> Infinite lines")
+ )
+
+ self.cursor_radio = RadioSet([
+ {"label": _("Small"), "value": "small"},
+ {"label": _("Big"), "value": "big"}
+ ], orientation='horizontal', stretch=False)
+
+ grid0.addWidget(self.cursor_lbl, 22, 0)
+ grid0.addWidget(self.cursor_radio, 22, 1)
+
+ # Mouse Cursor Size
+ self.cursor_size_lbl = QtWidgets.QLabel('%s:' % _('Cursor Size'))
+ self.cursor_size_lbl.setToolTip(
+ _("Set the size of the mouse cursor, in pixels.")
+ )
+
+ self.cursor_size_entry = FCSpinner()
+ self.cursor_size_entry.set_range(10, 70)
+ self.cursor_size_entry.setWrapping(True)
+
+ grid0.addWidget(self.cursor_size_lbl, 23, 0)
+ grid0.addWidget(self.cursor_size_entry, 23, 1)
+
+ # Cursor Width
+ self.cursor_width_lbl = QtWidgets.QLabel('%s:' % _('Cursor Width'))
+ self.cursor_width_lbl.setToolTip(
+ _("Set the line width of the mouse cursor, in pixels.")
+ )
+
+ self.cursor_width_entry = FCSpinner()
+ self.cursor_width_entry.set_range(1, 10)
+ self.cursor_width_entry.setWrapping(True)
+
+ grid0.addWidget(self.cursor_width_lbl, 24, 0)
+ grid0.addWidget(self.cursor_width_entry, 24, 1)
+
+ # Cursor Color Enable
+ self.mouse_cursor_color_cb = FCCheckBox(label='%s' % _('Cursor Color'))
+ self.mouse_cursor_color_cb.setToolTip(
+ _("Check this box to color mouse cursor.")
+ )
+ grid0.addWidget(self.mouse_cursor_color_cb, 25, 0, 1, 2)
+
+ # Cursor Color
+ self.mouse_color_label = QtWidgets.QLabel('%s:' % _('Cursor Color'))
+ self.mouse_color_label.setToolTip(
+ _("Set the color of the mouse cursor.")
+ )
+ self.mouse_cursor_entry = FCEntry()
+ self.mouse_cursor_button = QtWidgets.QPushButton()
+ self.mouse_cursor_button.setFixedSize(15, 15)
+
+ self.form_box_child_1 = QtWidgets.QHBoxLayout()
+ self.form_box_child_1.addWidget(self.mouse_cursor_entry)
+ self.form_box_child_1.addWidget(self.mouse_cursor_button)
+ self.form_box_child_1.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
+
+ grid0.addWidget(self.mouse_color_label, 26, 0)
+ grid0.addLayout(self.form_box_child_1, 26, 1)
+
+ self.mois = OptionalInputSection(
+ self.mouse_cursor_color_cb,
+ [
+ self.mouse_color_label,
+ self.mouse_cursor_entry,
+ self.mouse_cursor_button
+ ]
+ )
+ # Select mouse pan button
+ self.panbuttonlabel = QtWidgets.QLabel('%s:' % _('Pan Button'))
+ self.panbuttonlabel.setToolTip(
+ _("Select the mouse button to use for panning:\n"
+ "- MMB --> Middle Mouse Button\n"
+ "- RMB --> Right Mouse Button")
+ )
+ self.pan_button_radio = RadioSet([{'label': _('MMB'), 'value': '3'},
+ {'label': _('RMB'), 'value': '2'}])
+
+ grid0.addWidget(self.panbuttonlabel, 27, 0)
+ grid0.addWidget(self.pan_button_radio, 27, 1)
+
+ # Multiple Selection Modifier Key
+ self.mselectlabel = QtWidgets.QLabel('%s:' % _('Multiple Selection'))
+ self.mselectlabel.setToolTip(
+ _("Select the key used for multiple selection.")
+ )
+ self.mselect_radio = RadioSet([{'label': _('CTRL'), 'value': 'Control'},
+ {'label': _('SHIFT'), 'value': 'Shift'}])
+
+ grid0.addWidget(self.mselectlabel, 28, 0)
+ grid0.addWidget(self.mselect_radio, 28, 1)
+
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid0.addWidget(separator_line, 29, 0, 1, 2)
+
+ # Delete confirmation
+ self.delete_conf_cb = FCCheckBox(_('Delete object confirmation'))
+ self.delete_conf_cb.setToolTip(
+ _("When checked the application will ask for user confirmation\n"
+ "whenever the Delete object(s) event is triggered, either by\n"
+ "menu shortcut or key shortcut.")
+ )
+ grid0.addWidget(self.delete_conf_cb, 30, 0, 1, 2)
+
+ # Open behavior
+ self.open_style_cb = FCCheckBox('%s' % _('"Open" behavior'))
+ self.open_style_cb.setToolTip(
+ _("When checked the path for the last saved file is used when saving files,\n"
+ "and the path for the last opened file is used when opening files.\n\n"
+ "When unchecked the path for opening files is the one used last: either the\n"
+ "path for saving files or the path for opening files.")
+ )
+
+ grid0.addWidget(self.open_style_cb, 31, 0, 1, 2)
+
+ # Enable/Disable ToolTips globally
+ self.toggle_tooltips_cb = FCCheckBox(label=_('Enable ToolTips'))
+ self.toggle_tooltips_cb.setToolTip(
+ _("Check this box if you want to have toolTips displayed\n"
+ "when hovering with mouse over items throughout the App.")
+ )
+
+ grid0.addWidget(self.toggle_tooltips_cb, 32, 0, 1, 2)
+
+ # Machinist settings that allow unsafe settings
+ self.machinist_cb = FCCheckBox(_("Allow Machinist Unsafe Settings"))
+ self.machinist_cb.setToolTip(
+ _("If checked, some of the application settings will be allowed\n"
+ "to have values that are usually unsafe to use.\n"
+ "Like Z travel negative values or Z Cut positive values.\n"
+ "It will applied at the next application start.\n"
+ "<>: Don't change this unless you know what you are doing !!!")
+ )
+
+ grid0.addWidget(self.machinist_cb, 33, 0, 1, 2)
+
+ # Bookmarks Limit in the Help Menu
+ self.bm_limit_spinner = FCSpinner()
+ self.bm_limit_spinner.set_range(0, 9999)
+ self.bm_limit_label = QtWidgets.QLabel('%s:' % _('Bookmarks limit'))
+ self.bm_limit_label.setToolTip(
+ _("The maximum number of bookmarks that may be installed in the menu.\n"
+ "The number of bookmarks in the bookmark manager may be greater\n"
+ "but the menu will hold only so much.")
+ )
+
+ grid0.addWidget(self.bm_limit_label, 34, 0)
+ grid0.addWidget(self.bm_limit_spinner, 34, 1)
+
+ # Activity monitor icon
+ self.activity_label = QtWidgets.QLabel('%s:' % _("Activity Icon"))
+ self.activity_label.setToolTip(
+ _("Select the GIF that show activity when FlatCAM is active.")
+ )
+ self.activity_combo = FCComboBox()
+ self.activity_combo.addItems(['Ball black', 'Ball green', 'Arrow green', 'Eclipse green'])
+
+ grid0.addWidget(self.activity_label, 35, 0)
+ grid0.addWidget(self.activity_combo, 35, 1)
+
+ self.layout.addStretch()
+
+ self.mouse_cursor_color_cb.stateChanged.connect(self.on_mouse_cursor_color_enable)
+
+ self.mouse_cursor_entry.editingFinished.connect(self.on_mouse_cursor_entry)
+ self.mouse_cursor_button.clicked.connect(self.on_mouse_cursor_button)
+
+ def on_mouse_cursor_color_enable(self, val):
+ if val:
+ self.app.cursor_color_3D = self.app.defaults["global_cursor_color"]
+ else:
+ theme_settings = QtCore.QSettings("Open Source", "FlatCAM")
+ if theme_settings.contains("theme"):
+ theme = theme_settings.value('theme', type=str)
+ else:
+ theme = 'white'
+
+ if theme == 'white':
+ self.app.cursor_color_3D = 'black'
+ else:
+ self.app.cursor_color_3D = 'gray'
+
+ def on_mouse_cursor_entry(self):
+ self.app.defaults['global_cursor_color'] = self.mouse_cursor_entry.get_value()
+ self.mouse_cursor_button.setStyleSheet("background-color:%s" % str(self.app.defaults['global_cursor_color']))
+
+ self.app.cursor_color_3D = self.app.defaults["global_cursor_color"]
+
+ def on_mouse_cursor_button(self):
+ current_color = QtGui.QColor(self.app.defaults['global_cursor_color'])
+
+ c_dialog = QtWidgets.QColorDialog()
+ proj_color = c_dialog.getColor(initial=current_color)
+
+ if proj_color.isValid() is False:
+ return
+
+ self.mouse_cursor_button.setStyleSheet("background-color:%s" % str(proj_color.name()))
+
+ new_val_sel = str(proj_color.name())
+ self.mouse_cursor_entry.set_value(new_val_sel)
+ self.app.defaults['global_cursor_color'] = new_val_sel
+
+ self.app.cursor_color_3D = self.app.defaults["global_cursor_color"]
diff --git a/flatcamGUI/preferences/general/GeneralAppPrefGroupUI.py b/flatcamGUI/preferences/general/GeneralAppPrefGroupUI.py
index 4ab4f105..7f238b5f 100644
--- a/flatcamGUI/preferences/general/GeneralAppPrefGroupUI.py
+++ b/flatcamGUI/preferences/general/GeneralAppPrefGroupUI.py
@@ -1,251 +1,382 @@
import sys
+
+from PyQt5 import QtWidgets
from PyQt5.QtCore import QSettings
-from flatcamGUI.GUIElements import OptionalInputSection
-from flatcamGUI.preferences.OptionUI import *
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI2
+
+from flatcamGUI.GUIElements import RadioSet, FCSpinner, FCCheckBox, FCComboBox, FCButton, OptionalInputSection, \
+ FCDoubleSpinner
+from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
import gettext
import FlatCAMTranslation as fcTranslate
import builtins
+
fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__:
_ = gettext.gettext
+settings = QSettings("Open Source", "FlatCAM")
+if settings.contains("machinist"):
+ machinist_setting = settings.value('machinist', type=int)
+else:
+ machinist_setting = 0
-class GeneralAppPrefGroupUI(OptionsGroupUI2):
- def __init__(self, decimals=4, **kwargs):
+
+class GeneralAppPrefGroupUI(OptionsGroupUI):
+ def __init__(self, decimals=4, parent=None):
+ super(GeneralAppPrefGroupUI, self).__init__(self, parent=parent)
+
+ self.setTitle(_("App Preferences"))
self.decimals = decimals
- super().__init__(**kwargs)
- self.setTitle(str(_("App Preferences")))
- if sys.platform != 'win32':
- self.option_dict()["global_portable"].get_field().hide()
- self.option_dict()["splash_screen"].get_field().stateChanged.connect(self.on_splash_changed)
- self.option_dict()["global_shell_at_startup"].get_field().clicked.connect(self.on_toggle_shell_from_settings)
- self.option_dict()["__apply_language_button"].get_field().clicked.connect(lambda: fcTranslate.on_language_apply_click(app=self.app, restart=True))
+ # Create a form layout for the Application general settings
+ grid0 = QtWidgets.QGridLayout()
+ self.layout.addLayout(grid0)
+ grid0.setColumnStretch(0, 0)
+ grid0.setColumnStretch(1, 1)
+
+ # Units for FlatCAM
+ self.unitslabel = QtWidgets.QLabel('%s:' % _('Units'))
+ self.unitslabel.setToolTip(_("The default value for FlatCAM units.\n"
+ "Whatever is selected here is set every time\n"
+ "FlatCAM is started."))
+ self.units_radio = RadioSet([{'label': _('MM'), 'value': 'MM'},
+ {'label': _('IN'), 'value': 'IN'}])
+
+ grid0.addWidget(self.unitslabel, 0, 0)
+ grid0.addWidget(self.units_radio, 0, 1)
+
+ # Precision Metric
+ self.precision_metric_label = QtWidgets.QLabel('%s:' % _('Precision MM'))
+ self.precision_metric_label.setToolTip(
+ _("The number of decimals used throughout the application\n"
+ "when the set units are in METRIC system.\n"
+ "Any change here require an application restart.")
+ )
+ self.precision_metric_entry = FCSpinner()
+ self.precision_metric_entry.set_range(2, 16)
+ self.precision_metric_entry.setWrapping(True)
+
+ grid0.addWidget(self.precision_metric_label, 1, 0)
+ grid0.addWidget(self.precision_metric_entry, 1, 1)
+
+ # Precision Inch
+ self.precision_inch_label = QtWidgets.QLabel('%s:' % _('Precision INCH'))
+ self.precision_inch_label.setToolTip(
+ _("The number of decimals used throughout the application\n"
+ "when the set units are in INCH system.\n"
+ "Any change here require an application restart.")
+ )
+ self.precision_inch_entry = FCSpinner()
+ self.precision_inch_entry.set_range(2, 16)
+ self.precision_inch_entry.setWrapping(True)
+
+ grid0.addWidget(self.precision_inch_label, 2, 0)
+ grid0.addWidget(self.precision_inch_entry, 2, 1)
+
+ # Graphic Engine for FlatCAM
+ self.ge_label = QtWidgets.QLabel('%s:' % _('Graphic Engine'))
+ self.ge_label.setToolTip(_("Choose what graphic engine to use in FlatCAM.\n"
+ "Legacy(2D) -> reduced functionality, slow performance but enhanced compatibility.\n"
+ "OpenGL(3D) -> full functionality, high performance\n"
+ "Some graphic cards are too old and do not work in OpenGL(3D) mode, like:\n"
+ "Intel HD3000 or older. In this case the plot area will be black therefore\n"
+ "use the Legacy(2D) mode."))
+ self.ge_radio = RadioSet([{'label': _('Legacy(2D)'), 'value': '2D'},
+ {'label': _('OpenGL(3D)'), 'value': '3D'}],
+ orientation='vertical')
+
+ grid0.addWidget(self.ge_label, 3, 0)
+ grid0.addWidget(self.ge_radio, 3, 1)
+
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid0.addWidget(separator_line, 4, 0, 1, 2)
+
+ # Application Level for FlatCAM
+ self.app_level_label = QtWidgets.QLabel('%s:' % _('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'}])
+
+ grid0.addWidget(self.app_level_label, 5, 0)
+ grid0.addWidget(self.app_level_radio, 5, 1)
+
+ # Portability for FlatCAM
+ self.portability_cb = FCCheckBox('%s' % _('Portable app'))
+ self.portability_cb.setToolTip(_("Choose if the application should run as portable.\n\n"
+ "If Checked the application will run portable,\n"
+ "which means that the preferences files will be saved\n"
+ "in the application folder, in the lib\\config subfolder."))
+
+ grid0.addWidget(self.portability_cb, 6, 0, 1, 2)
+
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid0.addWidget(separator_line, 7, 0, 1, 2)
+
+ # Languages for FlatCAM
+ self.languagelabel = QtWidgets.QLabel('%s' % _('Languages'))
+ self.languagelabel.setToolTip(_("Set the language used throughout FlatCAM."))
+ self.language_cb = FCComboBox()
+
+ grid0.addWidget(self.languagelabel, 8, 0, 1, 2)
+ grid0.addWidget(self.language_cb, 9, 0, 1, 2)
+
+ self.language_apply_btn = FCButton(_("Apply Language"))
+ self.language_apply_btn.setToolTip(_("Set the language used throughout FlatCAM.\n"
+ "The app will restart after click."))
+
+ grid0.addWidget(self.language_apply_btn, 15, 0, 1, 2)
+
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid0.addWidget(separator_line, 16, 0, 1, 2)
+
+ # -----------------------------------------------------------
+ # ----------- APPLICATION STARTUP SETTINGS ------------------
+ # -----------------------------------------------------------
+
+ self.startup_label = QtWidgets.QLabel('%s' % _('Startup Settings'))
+ grid0.addWidget(self.startup_label, 17, 0, 1, 2)
+
+ # Splash Screen
+ self.splash_cb = FCCheckBox('%s' % _('Splash Screen'))
+ self.splash_cb.setToolTip(
+ _("Enable display of the splash screen at application startup.")
+ )
qsettings = QSettings("Open Source", "FlatCAM")
if qsettings.value("splash_screen"):
- self.option_dict()["splash_screen"].get_field().set_value(True)
+ self.splash_cb.set_value(True)
else:
- self.option_dict()["splash_screen"].get_field().set_value(False)
+ self.splash_cb.set_value(False)
- self.version_check_field = self.option_dict()["global_version_check"].get_field()
- self.send_stats_field = self.option_dict()["global_send_stats"].get_field()
- self.ois_version_check = OptionalInputSection(self.version_check_field, [self.send_stats_field])
+ grid0.addWidget(self.splash_cb, 18, 0, 1, 2)
+
+ # Sys Tray Icon
+ self.systray_cb = FCCheckBox('%s' % _('Sys Tray Icon'))
+ self.systray_cb.setToolTip(
+ _("Enable display of FlatCAM icon in Sys Tray.")
+ )
+ grid0.addWidget(self.systray_cb, 19, 0, 1, 2)
+
+ # Shell StartUp CB
+ self.shell_startup_cb = FCCheckBox(label='%s' % _('Show Shell'))
+ self.shell_startup_cb.setToolTip(
+ _("Check this box if you want the shell to\n"
+ "start automatically at startup.")
+ )
+
+ grid0.addWidget(self.shell_startup_cb, 20, 0, 1, 2)
+
+ # Project at StartUp CB
+ self.project_startup_cb = FCCheckBox(label='%s' % _('Show Project'))
+ self.project_startup_cb.setToolTip(
+ _("Check this box if you want the project/selected/tool tab area to\n"
+ "to be shown automatically at startup.")
+ )
+ grid0.addWidget(self.project_startup_cb, 21, 0, 1, 2)
+
+ # Version Check CB
+ self.version_check_cb = FCCheckBox(label='%s' % _('Version Check'))
+ self.version_check_cb.setToolTip(
+ _("Check this box if you want to check\n"
+ "for a new version automatically at startup.")
+ )
+
+ grid0.addWidget(self.version_check_cb, 22, 0, 1, 2)
+
+ # Send Stats CB
+ self.send_stats_cb = FCCheckBox(label='%s' % _('Send Statistics'))
+ self.send_stats_cb.setToolTip(
+ _("Check this box if you agree to send anonymous\n"
+ "stats automatically at startup, to help improve FlatCAM.")
+ )
+
+ grid0.addWidget(self.send_stats_cb, 23, 0, 1, 2)
+
+ self.ois_version_check = OptionalInputSection(self.version_check_cb, [self.send_stats_cb])
+
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid0.addWidget(separator_line, 24, 0, 1, 2)
+
+ # Worker Numbers
+ self.worker_number_label = QtWidgets.QLabel('%s:' % _('Workers number'))
+ self.worker_number_label.setToolTip(
+ _("The number of Qthreads made available to the App.\n"
+ "A bigger number may finish the jobs more quickly but\n"
+ "depending on your computer speed, may make the App\n"
+ "unresponsive. Can have a value between 2 and 16.\n"
+ "Default value is 2.\n"
+ "After change, it will be applied at next App start.")
+ )
+ self.worker_number_sb = FCSpinner()
+ self.worker_number_sb.set_range(2, 16)
+
+ grid0.addWidget(self.worker_number_label, 25, 0)
+ grid0.addWidget(self.worker_number_sb, 25, 1)
+
+ # Geometric tolerance
+ tol_label = QtWidgets.QLabel('%s:' % _("Geo Tolerance"))
+ tol_label.setToolTip(_(
+ "This value can counter the effect of the Circle Steps\n"
+ "parameter. Default value is 0.005.\n"
+ "A lower value will increase the detail both in image\n"
+ "and in Gcode for the circles, with a higher cost in\n"
+ "performance. Higher value will provide more\n"
+ "performance at the expense of level of detail."
+ ))
+ self.tol_entry = FCDoubleSpinner()
+ self.tol_entry.setSingleStep(0.001)
+ self.tol_entry.set_precision(6)
+
+ grid0.addWidget(tol_label, 26, 0)
+ grid0.addWidget(self.tol_entry, 26, 1)
+
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid0.addWidget(separator_line, 27, 0, 1, 2)
+
+ # Save Settings
+ self.save_label = QtWidgets.QLabel('%s' % _("Save Settings"))
+ grid0.addWidget(self.save_label, 28, 0, 1, 2)
+
+ # Save compressed project CB
+ self.save_type_cb = FCCheckBox(_('Save Compressed Project'))
+ self.save_type_cb.setToolTip(
+ _("Whether to save a compressed or uncompressed project.\n"
+ "When checked it will save a compressed FlatCAM project.")
+ )
+
+ grid0.addWidget(self.save_type_cb, 29, 0, 1, 2)
+
+ # Project LZMA Comppression Level
+ self.compress_spinner = FCSpinner()
+ self.compress_spinner.set_range(0, 9)
+ self.compress_label = QtWidgets.QLabel('%s:' % _('Compression'))
+ self.compress_label.setToolTip(
+ _("The level of compression used when saving\n"
+ "a FlatCAM project. Higher value means better compression\n"
+ "but require more RAM usage and more processing time.")
+ )
+
+ grid0.addWidget(self.compress_label, 30, 0)
+ grid0.addWidget(self.compress_spinner, 30, 1)
+
+ self.proj_ois = OptionalInputSection(self.save_type_cb, [self.compress_label, self.compress_spinner], True)
+
+ # Auto save CB
+ self.autosave_cb = FCCheckBox(_('Enable Auto Save'))
+ self.autosave_cb.setToolTip(
+ _("Check to enable the autosave feature.\n"
+ "When enabled, the application will try to save a project\n"
+ "at the set interval.")
+ )
+
+ grid0.addWidget(self.autosave_cb, 31, 0, 1, 2)
+
+ # Auto Save Timeout Interval
+ self.autosave_entry = FCSpinner()
+ self.autosave_entry.set_range(0, 9999999)
+ self.autosave_label = QtWidgets.QLabel('%s:' % _('Interval'))
+ self.autosave_label.setToolTip(
+ _("Time interval for autosaving. In milliseconds.\n"
+ "The application will try to save periodically but only\n"
+ "if the project was saved manually at least once.\n"
+ "While active, some operations may block this feature.")
+ )
+
+ grid0.addWidget(self.autosave_label, 32, 0)
+ grid0.addWidget(self.autosave_entry, 32, 1)
- self.save_compressed_field = self.option_dict()["global_save_compressed"].get_field()
- self.compression_label = self.option_dict()["global_compression_level"].label_widget
- self.compression_field = self.option_dict()["global_compression_level"].get_field()
- self.proj_ois = OptionalInputSection(self.save_compressed_field, [self.compression_label, self.compression_field], True)
# self.as_ois = OptionalInputSection(self.autosave_cb, [self.autosave_label, self.autosave_entry], True)
- def build_options(self) -> [OptionUI]:
- return [
- RadioSetOptionUI(
- option="units",
- label_text="Units",
- label_tooltip="The default value for FlatCAM units.\n"
- "Whatever is selected here is set every time\n"
- "FlatCAM is started.",
- label_bold=True,
- label_color="red",
- choices=[{'label': _('MM'), 'value': 'MM'},
- {'label': _('IN'), 'value': 'IN'}]
- ),
- SpinnerOptionUI(
- option="decimals_metric",
- label_text="Precision MM",
- label_tooltip="The number of decimals used throughout the application\n"
- "when the set units are in METRIC system.\n"
- "Any change here require an application restart.",
- min_value=2, max_value=16, step=1
- ),
- SpinnerOptionUI(
- option="decimals_metric",
- label_text="Precision INCH",
- label_tooltip="The number of decimals used throughout the application\n"
- "when the set units are in INCH system.\n"
- "Any change here require an application restart.",
- min_value=2, max_value=16, step=1
- ),
- RadioSetOptionUI(
- option="global_graphic_engine",
- label_text='Graphic Engine',
- label_tooltip="Choose what graphic engine to use in FlatCAM.\n"
- "Legacy(2D) -> reduced functionality, slow performance but enhanced compatibility.\n"
- "OpenGL(3D) -> full functionality, high performance\n"
- "Some graphic cards are too old and do not work in OpenGL(3D) mode, like:\n"
- "Intel HD3000 or older. In this case the plot area will be black therefore\n"
- "use the Legacy(2D) mode.",
- label_bold=True,
- choices=[{'label': _('Legacy(2D)'), 'value': '2D'},
- {'label': _('OpenGL(3D)'), 'value': '3D'}],
- orientation="vertical"
- ),
- SeparatorOptionUI(),
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid0.addWidget(separator_line, 33, 0, 1, 2)
- RadioSetOptionUI(
- option="global_app_level",
- label_text="APP. LEVEL",
- label_tooltip="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.",
- label_bold=True,
- label_color="red",
- choices=[{'label': _('Basic'), 'value': 'b'},
- {'label': _('Advanced'), 'value': 'a'}]
- ),
- CheckboxOptionUI(
- option="global_portable",
- label_text="Portable app",
- label_tooltip="Choose if the application should run as portable.\n\n"
- "If Checked the application will run portable,\n"
- "which means that the preferences files will be saved\n"
- "in the application folder, in the lib\\config subfolder."
- ),
- SeparatorOptionUI(),
+ self.pdf_param_label = QtWidgets.QLabel('%s:' % _("Text to PDF parameters"))
+ self.pdf_param_label.setToolTip(
+ _("Used when saving text in Code Editor or in FlatCAM Document objects.")
+ )
+ grid0.addWidget(self.pdf_param_label, 34, 0, 1, 2)
- HeadingOptionUI(label_text="Languages", label_tooltip="Set the language used throughout FlatCAM."),
- ComboboxOptionUI(
- option="global_language",
- label_text="Language",
- label_tooltip="Set the language used throughout FlatCAM.",
- choices=[] # FIXME: choices should be added here instead of in App
- ),
- FullWidthButtonOptionUI(
- option="__apply_language_button",
- label_text="Apply Language",
- label_tooltip="Set the language used throughout FlatCAM.\n"
- "The app will restart after click."
- ),
- SeparatorOptionUI(),
+ # Top Margin value
+ self.tmargin_entry = FCDoubleSpinner()
+ self.tmargin_entry.set_precision(self.decimals)
+ self.tmargin_entry.set_range(0.0000, 9999.9999)
- HeadingOptionUI("Startup Settings", label_tooltip=None),
- CheckboxOptionUI(
- option="splash_screen",
- label_text="Splash Screen",
- label_tooltip="Enable display of the splash screen at application startup."
- ),
- CheckboxOptionUI(
- option="global_systray_icon",
- label_text="Sys Tray Icon",
- label_tooltip="Enable display of FlatCAM icon in Sys Tray."
- ),
- CheckboxOptionUI(
- option="global_shell_at_startup",
- label_text="Show Shell",
- label_tooltip="Check this box if you want the shell to\n"
- "start automatically at startup."
- ),
- CheckboxOptionUI(
- option="global_project_at_startup",
- label_text="Show Project",
- label_tooltip="Check this box if you want the project/selected/tool tab area to\n"
- "to be shown automatically at startup."
- ),
- CheckboxOptionUI(
- option="global_version_check",
- label_text="Version Check",
- label_tooltip="Check this box if you want to check\n"
- "for a new version automatically at startup."
- ),
- CheckboxOptionUI(
- option="global_send_stats",
- label_text="Send Statistics",
- label_tooltip="Check this box if you agree to send anonymous\n"
- "stats automatically at startup, to help improve FlatCAM."
- ),
- SeparatorOptionUI(),
+ self.tmargin_label = QtWidgets.QLabel('%s:' % _("Top Margin"))
+ self.tmargin_label.setToolTip(
+ _("Distance between text body and the top of the PDF file.")
+ )
- SpinnerOptionUI(
- option="global_worker_number",
- label_text="Workers number",
- label_tooltip="The number of Qthreads made available to the App.\n"
- "A bigger number may finish the jobs more quickly but\n"
- "depending on your computer speed, may make the App\n"
- "unresponsive. Can have a value between 2 and 16.\n"
- "Default value is 2.\n"
- "After change, it will be applied at next App start.",
- min_value=2, max_value=16, step=1
- ),
- DoubleSpinnerOptionUI(
- option="global_tolerance",
- label_text="Geo Tolerance",
- label_tooltip="This value can counter the effect of the Circle Steps\n"
- "parameter. Default value is 0.005.\n"
- "A lower value will increase the detail both in image\n"
- "and in Gcode for the circles, with a higher cost in\n"
- "performance. Higher value will provide more\n"
- "performance at the expense of level of detail.",
- min_value=0.0, max_value=100.0, step=0.001, decimals=6
- ),
- SeparatorOptionUI(),
+ grid0.addWidget(self.tmargin_label, 35, 0)
+ grid0.addWidget(self.tmargin_entry, 35, 1)
- HeadingOptionUI(label_text="Save Settings"),
- CheckboxOptionUI(
- option="global_save_compressed",
- label_text="Save Compressed Project",
- label_tooltip="Whether to save a compressed or uncompressed project.\n"
- "When checked it will save a compressed FlatCAM project."
- ),
- SpinnerOptionUI(
- option="global_compression_level",
- label_text="Compression",
- label_tooltip="The level of compression used when saving\n"
- "a FlatCAM project. Higher value means better compression\n"
- "but require more RAM usage and more processing time.",
- min_value=0, max_value=9, step=1
- ),
- CheckboxOptionUI(
- option="global_autosave",
- label_text="Enable Auto Save",
- label_tooltip="Check to enable the autosave feature.\n"
- "When enabled, the application will try to save a project\n"
- "at the set interval."
- ),
- SpinnerOptionUI(
- option="global_autosave_timeout",
- label_text="Interval",
- label_tooltip="Time interval for autosaving. In milliseconds.\n"
- "The application will try to save periodically but only\n"
- "if the project was saved manually at least once.\n"
- "While active, some operations may block this feature.",
- min_value=500, max_value=9999999, step=60000
- ),
- SeparatorOptionUI(),
+ # Bottom Margin value
+ self.bmargin_entry = FCDoubleSpinner()
+ self.bmargin_entry.set_precision(self.decimals)
+ self.bmargin_entry.set_range(0.0000, 9999.9999)
- HeadingOptionUI(
- label_text="Text to PDF parameters",
- label_tooltip="Used when saving text in Code Editor or in FlatCAM Document objects."
- ),
- DoubleSpinnerOptionUI(
- option="global_tpdf_tmargin",
- label_text="Top Margin",
- label_tooltip="Distance between text body and the top of the PDF file.",
- min_value=0.0, max_value=9999.9999, step=1, decimals=2
- ),
- DoubleSpinnerOptionUI(
- option="global_tpdf_bmargin",
- label_text="Bottom Margin",
- label_tooltip="Distance between text body and the bottom of the PDF file.",
- min_value=0.0, max_value=9999.9999, step=1, decimals=2
- ),
- DoubleSpinnerOptionUI(
- option="global_tpdf_lmargin",
- label_text="Left Margin",
- label_tooltip="Distance between text body and the left of the PDF file.",
- min_value=0.0, max_value=9999.9999, step=1, decimals=2
- ),
- DoubleSpinnerOptionUI(
- option="global_tpdf_rmargin",
- label_text="Right Margin",
- label_tooltip="Distance between text body and the right of the PDF file.",
- min_value=0.0, max_value=9999.9999, step=1, decimals=2
- )
- ]
+ self.bmargin_label = QtWidgets.QLabel('%s:' % _("Bottom Margin"))
+ self.bmargin_label.setToolTip(
+ _("Distance between text body and the bottom of the PDF file.")
+ )
+
+ grid0.addWidget(self.bmargin_label, 36, 0)
+ grid0.addWidget(self.bmargin_entry, 36, 1)
+
+ # Left Margin value
+ self.lmargin_entry = FCDoubleSpinner()
+ self.lmargin_entry.set_precision(self.decimals)
+ self.lmargin_entry.set_range(0.0000, 9999.9999)
+
+ self.lmargin_label = QtWidgets.QLabel('%s:' % _("Left Margin"))
+ self.lmargin_label.setToolTip(
+ _("Distance between text body and the left of the PDF file.")
+ )
+
+ grid0.addWidget(self.lmargin_label, 37, 0)
+ grid0.addWidget(self.lmargin_entry, 37, 1)
+
+ # Right Margin value
+ self.rmargin_entry = FCDoubleSpinner()
+ self.rmargin_entry.set_precision(self.decimals)
+ self.rmargin_entry.set_range(0.0000, 9999.9999)
+
+ self.rmargin_label = QtWidgets.QLabel('%s:' % _("Right Margin"))
+ self.rmargin_label.setToolTip(
+ _("Distance between text body and the right of the PDF file.")
+ )
+
+ grid0.addWidget(self.rmargin_label, 38, 0)
+ grid0.addWidget(self.rmargin_entry, 38, 1)
+
+ self.layout.addStretch()
+
+ if sys.platform != 'win32':
+ self.portability_cb.hide()
+
+ # splash screen button signal
+ self.splash_cb.stateChanged.connect(self.on_splash_changed)
+
+ # Monitor the checkbox from the Application Defaults Tab and show the TCL shell or not depending on it's value
+ self.shell_startup_cb.clicked.connect(self.on_toggle_shell_from_settings)
+
+ self.language_apply_btn.clicked.connect(lambda: fcTranslate.on_language_apply_click(app=self.app, restart=True))
def on_toggle_shell_from_settings(self, state):
"""
@@ -268,4 +399,4 @@ class GeneralAppPrefGroupUI(OptionsGroupUI2):
qsettings.setValue('splash_screen', 1) if state else qsettings.setValue('splash_screen', 0)
# This will write the setting to the platform specific storage.
- del qsettings
\ No newline at end of file
+ del qsettings
diff --git a/flatcamGUI/preferences/general/GeneralAppSettingsGroupUI.py b/flatcamGUI/preferences/general/GeneralAppSettingsGroupUI.py
deleted file mode 100644
index 1978bd6d..00000000
--- a/flatcamGUI/preferences/general/GeneralAppSettingsGroupUI.py
+++ /dev/null
@@ -1,301 +0,0 @@
-from PyQt5 import QtCore
-from PyQt5.QtCore import QSettings
-from flatcamGUI.GUIElements import OptionalInputSection
-from flatcamGUI.preferences import settings
-from flatcamGUI.preferences.OptionUI import *
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI2
-
-import gettext
-import FlatCAMTranslation as fcTranslate
-import builtins
-fcTranslate.apply_language('strings')
-if '_' not in builtins.__dict__:
- _ = gettext.gettext
-
-
-class GeneralAppSettingsGroupUI(OptionsGroupUI2):
- def __init__(self, decimals=4, **kwargs):
- self.decimals = decimals
- self.pagesize = {}
- self.pagesize.update(
- {
- 'A0': (841, 1189),
- 'A1': (594, 841),
- 'A2': (420, 594),
- 'A3': (297, 420),
- 'A4': (210, 297),
- 'A5': (148, 210),
- 'A6': (105, 148),
- 'A7': (74, 105),
- 'A8': (52, 74),
- 'A9': (37, 52),
- 'A10': (26, 37),
-
- 'B0': (1000, 1414),
- 'B1': (707, 1000),
- 'B2': (500, 707),
- 'B3': (353, 500),
- 'B4': (250, 353),
- 'B5': (176, 250),
- 'B6': (125, 176),
- 'B7': (88, 125),
- 'B8': (62, 88),
- 'B9': (44, 62),
- 'B10': (31, 44),
-
- 'C0': (917, 1297),
- 'C1': (648, 917),
- 'C2': (458, 648),
- 'C3': (324, 458),
- 'C4': (229, 324),
- 'C5': (162, 229),
- 'C6': (114, 162),
- 'C7': (81, 114),
- 'C8': (57, 81),
- 'C9': (40, 57),
- 'C10': (28, 40),
-
- # American paper sizes
- 'LETTER': (8.5, 11),
- 'LEGAL': (8.5, 14),
- 'ELEVENSEVENTEEN': (11, 17),
-
- # From https://en.wikipedia.org/wiki/Paper_size
- 'JUNIOR_LEGAL': (5, 8),
- 'HALF_LETTER': (5.5, 8),
- 'GOV_LETTER': (8, 10.5),
- 'GOV_LEGAL': (8.5, 13),
- 'LEDGER': (17, 11),
- }
- )
- super().__init__(**kwargs)
-
- self.setTitle(str(_("App Settings")))
-
- qsettings = QSettings("Open Source", "FlatCAM")
-
- self.notebook_font_size_field = self.option_dict()["notebook_font_size"].get_field()
- if qsettings.contains("notebook_font_size"):
- self.notebook_font_size_field.set_value(qsettings.value('notebook_font_size', type=int))
- else:
- self.notebook_font_size_field.set_value(12)
-
- self.axis_font_size_field = self.option_dict()["axis_font_size"].get_field()
- if qsettings.contains("axis_font_size"):
- self.axis_font_size_field.set_value(qsettings.value('axis_font_size', type=int))
- else:
- self.axis_font_size_field.set_value(8)
-
- self.textbox_font_size_field = self.option_dict()["textbox_font_size"].get_field()
- if qsettings.contains("textbox_font_size"):
- self.textbox_font_size_field.set_value(settings.value('textbox_font_size', type=int))
- else:
- self.textbox_font_size_field.set_value(10)
-
- self.workspace_enabled_field = self.option_dict()["global_workspace"].get_field()
- self.workspace_type_field = self.option_dict()["global_workspaceT"].get_field()
- self.workspace_type_label = self.option_dict()["global_workspaceT"].label_widget
- self.workspace_orientation_field = self.option_dict()["global_workspace_orientation"].get_field()
- self.workspace_orientation_label = self.option_dict()["global_workspace_orientation"].label_widget
- self.wks = OptionalInputSection(self.workspace_enabled_field, [self.workspace_type_label, self.workspace_type_field, self.workspace_orientation_label, self.workspace_orientation_field])
-
- self.mouse_cursor_color_enabled_field = self.option_dict()["global_cursor_color_enabled"].get_field()
- self.mouse_cursor_color_field = self.option_dict()["global_cursor_color"].get_field()
- self.mouse_cursor_color_label = self.option_dict()["global_cursor_color"].label_widget
- self.mois = OptionalInputSection(self.mouse_cursor_color_enabled_field, [self.mouse_cursor_color_label, self.mouse_cursor_color_field])
- self.mouse_cursor_color_enabled_field.stateChanged.connect(self.on_mouse_cursor_color_enable)
- self.mouse_cursor_color_field.entry.editingFinished.connect(self.on_mouse_cursor_entry)
-
- def build_options(self) -> [OptionUI]:
- return [
- HeadingOptionUI(label_text="Grid Settings", label_tooltip=None),
- DoubleSpinnerOptionUI(
- option="global_gridx",
- label_text="X value",
- label_tooltip="This is the Grid snap value on X axis.",
- step=0.1,
- decimals=self.decimals
- ),
- DoubleSpinnerOptionUI(
- option="global_gridy",
- label_text='Y value',
- label_tooltip="This is the Grid snap value on Y axis.",
- step=0.1,
- decimals=self.decimals
- ),
- DoubleSpinnerOptionUI(
- option="global_snap_max",
- label_text="Snap Max",
- label_tooltip="Max. magnet distance",
- step=0.1,
- decimals=self.decimals
- ),
- SeparatorOptionUI(),
-
- HeadingOptionUI(label_text="Workspace Settings", label_tooltip=None),
- CheckboxOptionUI(
- option="global_workspace",
- label_text="Active",
- label_tooltip="Draw a delimiting rectangle on canvas.\n"
- "The purpose is to illustrate the limits for our work."
- ),
- ComboboxOptionUI(
- option="global_workspaceT",
- label_text="Size",
- label_tooltip="Select the type of rectangle to be used on canvas,\nas valid workspace.",
- choices=list(self.pagesize.keys())
- ),
- RadioSetOptionUI(
- option="global_workspace_orientation",
- label_text="Orientation",
- label_tooltip="Can be:\n- Portrait\n- Landscape",
- choices=[
- {'label': _('Portrait'), 'value': 'p'},
- {'label': _('Landscape'), 'value': 'l'},
- ]
- ),
- # FIXME enabling OptionalInputSection ??
- SeparatorOptionUI(),
-
- HeadingOptionUI(label_text="Font Size", label_tooltip=None),
- SpinnerOptionUI(
- option="notebook_font_size",
- label_text="Notebook",
- label_tooltip="This sets the font size for the elements found in the Notebook.\n"
- "The notebook is the collapsible area in the left side of the GUI,\n"
- "and include the Project, Selected and Tool tabs.",
- min_value=8, max_value=40, step=1
- ),
- SpinnerOptionUI(
- option="axis_font_size",
- label_text="Axis",
- label_tooltip="This sets the font size for canvas axis.",
- min_value=8, max_value=40, step=1
- ),
- SpinnerOptionUI(
- option="textbox_font_size",
- label_text="Textbox",
- label_tooltip="This sets the font size for the Textbox GUI\n"
- "elements that are used in FlatCAM.",
- min_value=8, max_value=40, step=1
- ),
- SeparatorOptionUI(),
-
- HeadingOptionUI(label_text="Mouse Settings", label_tooltip=None),
- RadioSetOptionUI(
- option="global_cursor_type",
- label_text="Cursor Shape",
- label_tooltip="Choose a mouse cursor shape.\n"
- "- Small -> with a customizable size.\n"
- "- Big -> Infinite lines",
- choices=[
- {"label": _("Small"), "value": "small"},
- {"label": _("Big"), "value": "big"}
- ]
- ),
- SpinnerOptionUI(
- option="global_cursor_size",
- label_text="Cursor Size",
- label_tooltip="Set the size of the mouse cursor, in pixels.",
- min_value=10, max_value=70, step=1
- ),
- SpinnerOptionUI(
- option="global_cursor_width",
- label_text="Cursor Width",
- label_tooltip="Set the line width of the mouse cursor, in pixels.",
- min_value=1, max_value=10, step=1
- ),
- CheckboxOptionUI(
- option="global_cursor_color_enabled",
- label_text="Cursor Color",
- label_tooltip="Check this box to color mouse cursor."
- ),
- ColorOptionUI(
- option="global_cursor_color",
- label_text="Cursor Color",
- label_tooltip="Set the color of the mouse cursor."
- ),
- # FIXME enabling of cursor color
- RadioSetOptionUI(
- option="global_pan_button",
- label_text="Pan Button",
- label_tooltip="Select the mouse button to use for panning:\n"
- "- MMB --> Middle Mouse Button\n"
- "- RMB --> Right Mouse Button",
- choices=[{'label': _('MMB'), 'value': '3'},
- {'label': _('RMB'), 'value': '2'}]
- ),
- RadioSetOptionUI(
- option="global_mselect_key",
- label_text="Multiple Selection",
- label_tooltip="Select the key used for multiple selection.",
- choices=[{'label': _('CTRL'), 'value': 'Control'},
- {'label': _('SHIFT'), 'value': 'Shift'}]
- ),
- SeparatorOptionUI(),
-
- CheckboxOptionUI(
- option="global_delete_confirmation",
- label_text="Delete object confirmation",
- label_tooltip="When checked the application will ask for user confirmation\n"
- "whenever the Delete object(s) event is triggered, either by\n"
- "menu shortcut or key shortcut."
- ),
- CheckboxOptionUI(
- option="global_open_style",
- label_text='"Open" behavior',
- label_tooltip="When checked the path for the last saved file is used when saving files,\n"
- "and the path for the last opened file is used when opening files.\n\n"
- "When unchecked the path for opening files is the one used last: either the\n"
- "path for saving files or the path for opening files."
- ),
- CheckboxOptionUI(
- option="global_toggle_tooltips",
- label_text="Enable ToolTips",
- label_tooltip="Check this box if you want to have toolTips displayed\n"
- "when hovering with mouse over items throughout the App."
- ),
- CheckboxOptionUI(
- option="global_machinist_setting",
- label_text="Allow Machinist Unsafe Settings",
- label_tooltip="If checked, some of the application settings will be allowed\n"
- "to have values that are usually unsafe to use.\n"
- "Like Z travel negative values or Z Cut positive values.\n"
- "It will applied at the next application start.\n"
- "<>: Don't change this unless you know what you are doing !!!"
- ),
- SpinnerOptionUI(
- option="global_bookmarks_limit",
- label_text="Bookmarks limit",
- label_tooltip="The maximum number of bookmarks that may be installed in the menu.\n"
- "The number of bookmarks in the bookmark manager may be greater\n"
- "but the menu will hold only so much.",
- min_value=0, max_value=9999, step=1
- ),
- ComboboxOptionUI(
- option="global_activity_icon",
- label_text="Activity Icon",
- label_tooltip="Select the GIF that show activity when FlatCAM is active.",
- choices=['Ball black', 'Ball green', 'Arrow green', 'Eclipse green']
- )
-
- ]
-
- def on_mouse_cursor_color_enable(self, val):
- if val:
- self.app.cursor_color_3D = self.app.defaults["global_cursor_color"]
- else:
- theme_settings = QtCore.QSettings("Open Source", "FlatCAM")
- if theme_settings.contains("theme"):
- theme = theme_settings.value('theme', type=str)
- else:
- theme = 'white'
-
- if theme == 'white':
- self.app.cursor_color_3D = 'black'
- else:
- self.app.cursor_color_3D = 'gray'
-
- def on_mouse_cursor_entry(self):
- self.app.defaults['global_cursor_color'] = self.mouse_cursor_color_field.get_value()
- self.app.cursor_color_3D = self.app.defaults["global_cursor_color"]
diff --git a/flatcamGUI/preferences/general/GeneralGUIPrefGroupUI.py b/flatcamGUI/preferences/general/GeneralGUIPrefGroupUI.py
index 44172641..baedacc7 100644
--- a/flatcamGUI/preferences/general/GeneralGUIPrefGroupUI.py
+++ b/flatcamGUI/preferences/general/GeneralGUIPrefGroupUI.py
@@ -1,187 +1,423 @@
-from PyQt5 import QtWidgets, QtCore
-from PyQt5.QtCore import QSettings
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI2
+from PyQt5 import QtWidgets, QtCore, QtGui
+from PyQt5.QtCore import QSettings, Qt
+
+from flatcamGUI.GUIElements import RadioSet, FCCheckBox, FCButton, FCComboBox, FCEntry, FCSpinner
+from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
import gettext
import FlatCAMTranslation as fcTranslate
import builtins
+
fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__:
_ = gettext.gettext
-from flatcamGUI.preferences.OptionUI import OptionUI, CheckboxOptionUI, RadioSetOptionUI, \
- SeparatorOptionUI, HeadingOptionUI, ComboboxOptionUI, ColorOptionUI, FullWidthButtonOptionUI, \
- SliderWithSpinnerOptionUI, ColorAlphaSliderOptionUI
+settings = QSettings("Open Source", "FlatCAM")
+if settings.contains("machinist"):
+ machinist_setting = settings.value('machinist', type=int)
+else:
+ machinist_setting = 0
-class GeneralGUIPrefGroupUI(OptionsGroupUI2):
+class GeneralGUIPrefGroupUI(OptionsGroupUI):
+ def __init__(self, decimals=4, parent=None):
+ super(GeneralGUIPrefGroupUI, self).__init__(self, parent=parent)
- def __init__(self, decimals=4, **kwargs):
- self.decimals = decimals
- super().__init__(**kwargs)
self.setTitle(str(_("GUI Preferences")))
+ self.decimals = decimals
- self.layout_field = self.option_dict()["layout"].get_field()
- self.layout_field.activated.connect(self.on_layout)
+ # Create a grid layout for the Application general settings
+ grid0 = QtWidgets.QGridLayout()
+ self.layout.addLayout(grid0)
+ grid0.setColumnStretch(0, 0)
+ grid0.setColumnStretch(1, 1)
- self.theme_field = self.option_dict()["global_theme"].get_field()
+ # Theme selection
+ self.theme_label = QtWidgets.QLabel('%s:' % _('Theme'))
+ self.theme_label.setToolTip(
+ _("Select a theme for FlatCAM.\n"
+ "It will theme the plot area.")
+ )
- self.style_field = self.option_dict()["style"].get_field()
- current_style_index = self.style_field.findText(QtWidgets.qApp.style().objectName(), QtCore.Qt.MatchFixedString)
- self.style_field.setCurrentIndex(current_style_index)
- self.style_field.activated[str].connect(self.handle_style)
+ self.theme_radio = RadioSet([
+ {"label": _("Light"), "value": "white"},
+ {"label": _("Dark"), "value": "black"}
+ ], orientation='vertical')
+
+ grid0.addWidget(self.theme_label, 0, 0)
+ grid0.addWidget(self.theme_radio, 0, 1)
+
+ # Enable Gray Icons
+ self.gray_icons_cb = FCCheckBox('%s' % _('Use Gray Icons'))
+ self.gray_icons_cb.setToolTip(
+ _("Check this box to use a set of icons with\n"
+ "a lighter (gray) color. To be used when a\n"
+ "full dark theme is applied.")
+ )
+ grid0.addWidget(self.gray_icons_cb, 1, 0, 1, 3)
+
+ # self.theme_button = FCButton(_("Apply Theme"))
+ # self.theme_button.setToolTip(
+ # _("Select a theme for FlatCAM.\n"
+ # "It will theme the plot area.\n"
+ # "The application will restart after change.")
+ # )
+ # grid0.addWidget(self.theme_button, 2, 0, 1, 3)
+
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid0.addWidget(separator_line, 3, 0, 1, 2)
+
+ # Layout selection
+ self.layout_label = QtWidgets.QLabel('%s:' % _('Layout'))
+ self.layout_label.setToolTip(
+ _("Select an layout for FlatCAM.\n"
+ "It is applied immediately.")
+ )
+ self.layout_combo = FCComboBox()
+ # don't translate the QCombo items as they are used in QSettings and identified by name
+ self.layout_combo.addItem("standard")
+ self.layout_combo.addItem("compact")
+ self.layout_combo.addItem("minimal")
+
+ grid0.addWidget(self.layout_label, 4, 0)
+ grid0.addWidget(self.layout_combo, 4, 1)
+
+ # Set the current index for layout_combo
+ qsettings = QSettings("Open Source", "FlatCAM")
+ if qsettings.contains("layout"):
+ layout = qsettings.value('layout', type=str)
+ idx = self.layout_combo.findText(layout.capitalize())
+ self.layout_combo.setCurrentIndex(idx)
+
+ # Style selection
+ self.style_label = QtWidgets.QLabel('%s:' % _('Style'))
+ self.style_label.setToolTip(
+ _("Select an style for FlatCAM.\n"
+ "It will be applied at the next app start.")
+ )
+ self.style_combo = FCComboBox()
+ self.style_combo.addItems(QtWidgets.QStyleFactory.keys())
+ # find current style
+ index = self.style_combo.findText(QtWidgets.qApp.style().objectName(), QtCore.Qt.MatchFixedString)
+ self.style_combo.setCurrentIndex(index)
+ self.style_combo.activated[str].connect(self.handle_style)
+
+ grid0.addWidget(self.style_label, 5, 0)
+ grid0.addWidget(self.style_combo, 5, 1)
+
+ # Enable High DPI Support
+ self.hdpi_cb = FCCheckBox('%s' % _('Activate HDPI Support'))
+ self.hdpi_cb.setToolTip(
+ _("Enable High DPI support for FlatCAM.\n"
+ "It will be applied at the next app start.")
+ )
- self.hdpi_field = self.option_dict()["hdpi"].get_field()
qsettings = QSettings("Open Source", "FlatCAM")
if qsettings.contains("hdpi"):
- self.hdpi_field.set_value(qsettings.value('hdpi', type=int))
+ self.hdpi_cb.set_value(qsettings.value('hdpi', type=int))
else:
- self.hdpi_field.set_value(False)
- self.hdpi_field.stateChanged.connect(self.handle_hdpi)
+ self.hdpi_cb.set_value(False)
+ self.hdpi_cb.stateChanged.connect(self.handle_hdpi)
- def build_options(self) -> [OptionUI]:
- return [
- RadioSetOptionUI(
- option="global_theme",
- label_text="Theme",
- label_tooltip="Select a theme for FlatCAM.\nIt will theme the plot area.",
- choices=[
- {"label": _("Light"), "value": "white"},
- {"label": _("Dark"), "value": "black"}
- ],
- orientation='vertical'
- ),
- CheckboxOptionUI(
- option="global_gray_icons",
- label_text="Use Gray Icons",
- label_tooltip="Check this box to use a set of icons with\na lighter (gray) color. To be used when a\nfull dark theme is applied."
- ),
- SeparatorOptionUI(),
+ grid0.addWidget(self.hdpi_cb, 6, 0, 1, 3)
- ComboboxOptionUI(
- option="layout",
- label_text="Layout",
- label_tooltip="Select an layout for FlatCAM.\nIt is applied immediately.",
- choices=[
- "standard",
- "compact",
- "minimal"
- ]
- ),
- ComboboxOptionUI(
- option="style",
- label_text="Style",
- label_tooltip="Select an style for FlatCAM.\nIt will be applied at the next app start.",
- choices=QtWidgets.QStyleFactory.keys()
- ),
- CheckboxOptionUI(
- option="hdpi",
- label_text='Activate HDPI Support',
- label_tooltip="Enable High DPI support for FlatCAM.\nIt will be applied at the next app start.",
- ),
- CheckboxOptionUI(
- option="global_hover",
- label_text='Display Hover Shape',
- label_tooltip="Enable display of a hover shape for FlatCAM objects.\nIt is displayed whenever the mouse cursor is hovering\nover any kind of not-selected object.",
- ),
- CheckboxOptionUI(
- option="global_selection_shape",
- label_text='Display Selection Shape',
- label_tooltip="Enable the display of a selection shape for FlatCAM objects.\n"
- "It is displayed whenever the mouse selects an object\n"
- "either by clicking or dragging mouse from left to right or\n"
- "right to left."
- ),
- SeparatorOptionUI(),
+ # Enable Hover box
+ self.hover_cb = FCCheckBox('%s' % _('Display Hover Shape'))
+ self.hover_cb.setToolTip(
+ _("Enable display of a hover shape for FlatCAM objects.\n"
+ "It is displayed whenever the mouse cursor is hovering\n"
+ "over any kind of not-selected object.")
+ )
+ grid0.addWidget(self.hover_cb, 8, 0, 1, 3)
- HeadingOptionUI(label_text="Left-Right Selection Color", label_tooltip=None),
- ColorOptionUI(
- option="global_sel_line",
- label_text="Outline",
- label_tooltip="Set the line color for the 'left to right' selection box."
- ),
- ColorOptionUI(
- option="global_sel_fill",
- label_text="Fill",
- label_tooltip="Set the fill color for the selection box\n"
- "in case that the selection is done from left to right.\n"
- "First 6 digits are the color and the last 2\n"
- "digits are for alpha (transparency) level."
- ),
- ColorAlphaSliderOptionUI(
- applies_to=["global_sel_line", "global_sel_fill"],
- group=self,
- label_text="Alpha",
- label_tooltip="Set the fill transparency for the 'left to right' selection box."
- ),
- SeparatorOptionUI(),
+ # Enable Selection box
+ self.selection_cb = FCCheckBox('%s' % _('Display Selection Shape'))
+ self.selection_cb.setToolTip(
+ _("Enable the display of a selection shape for FlatCAM objects.\n"
+ "It is displayed whenever the mouse selects an object\n"
+ "either by clicking or dragging mouse from left to right or\n"
+ "right to left.")
+ )
+ grid0.addWidget(self.selection_cb, 9, 0, 1, 3)
- HeadingOptionUI(label_text="Right-Left Selection Color", label_tooltip=None),
- ColorOptionUI(
- option="global_alt_sel_line",
- label_text="Outline",
- label_tooltip="Set the line color for the 'right to left' selection box."
- ),
- ColorOptionUI(
- option="global_alt_sel_fill",
- label_text="Fill",
- label_tooltip="Set the fill color for the selection box\n"
- "in case that the selection is done from right to left.\n"
- "First 6 digits are the color and the last 2\n"
- "digits are for alpha (transparency) level."
- ),
- ColorAlphaSliderOptionUI(
- applies_to=["global_alt_sel_line", "global_alt_sel_fill"],
- group=self,
- label_text="Alpha",
- label_tooltip="Set the fill transparency for the 'right to left' selection box."
- ),
- SeparatorOptionUI(),
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid0.addWidget(separator_line, 14, 0, 1, 2)
- HeadingOptionUI(label_text='Editor Color', label_tooltip=None),
- ColorOptionUI(
- option="global_draw_color",
- label_text="Drawing",
- label_tooltip="Set the color for the shape."
- ),
- ColorOptionUI(
- option="global_sel_draw_color",
- label_text="Selection",
- label_tooltip="Set the color of the shape when selected."
- ),
- SeparatorOptionUI(),
+ # Plot Selection (left - right) Color
+ self.sel_lr_label = QtWidgets.QLabel('%s' % _('Left-Right Selection Color'))
+ grid0.addWidget(self.sel_lr_label, 15, 0, 1, 2)
- HeadingOptionUI(label_text='Project Items Color', label_tooltip=None),
- ColorOptionUI(
- option="global_proj_item_color",
- label_text="Enabled",
- label_tooltip="Set the color of the items in Project Tab Tree."
- ),
- ColorOptionUI(
- option="global_proj_item_dis_color",
- label_text="Disabled",
- label_tooltip="Set the color of the items in Project Tab Tree,\n"
- "for the case when the items are disabled."
- ),
- CheckboxOptionUI(
- option="global_project_autohide",
- label_text="Project AutoHide",
- label_tooltip="Check this box if you want the project/selected/tool tab area to\n"
- "hide automatically when there are no objects loaded and\n"
- "to show whenever a new object is created."
- ),
- ]
+ self.sl_color_label = QtWidgets.QLabel('%s:' % _('Outline'))
+ self.sl_color_label.setToolTip(
+ _("Set the line color for the 'left to right' selection box.")
+ )
+ self.sl_color_entry = FCEntry()
+ self.sl_color_button = QtWidgets.QPushButton()
+ self.sl_color_button.setFixedSize(15, 15)
- def on_layout(self, index=None, lay=None):
- if lay:
- current_layout = lay
- else:
- current_layout = self.layout_field.get_value()
- self.app.ui.set_layout(current_layout)
+ self.form_box_child_4 = QtWidgets.QHBoxLayout()
+ self.form_box_child_4.addWidget(self.sl_color_entry)
+ self.form_box_child_4.addWidget(self.sl_color_button)
+ self.form_box_child_4.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
+
+ grid0.addWidget(self.sl_color_label, 16, 0)
+ grid0.addLayout(self.form_box_child_4, 16, 1)
+
+ self.sf_color_label = QtWidgets.QLabel('%s:' % _('Fill'))
+ self.sf_color_label.setToolTip(
+ _("Set the fill color for the selection box\n"
+ "in case that the selection is done from left to right.\n"
+ "First 6 digits are the color and the last 2\n"
+ "digits are for alpha (transparency) level.")
+ )
+ self.sf_color_entry = FCEntry()
+ self.sf_color_button = QtWidgets.QPushButton()
+ self.sf_color_button.setFixedSize(15, 15)
+
+ self.form_box_child_5 = QtWidgets.QHBoxLayout()
+ self.form_box_child_5.addWidget(self.sf_color_entry)
+ self.form_box_child_5.addWidget(self.sf_color_button)
+ self.form_box_child_5.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
+
+ grid0.addWidget(self.sf_color_label, 17, 0)
+ grid0.addLayout(self.form_box_child_5, 17, 1)
+
+ # Plot Selection (left - right) Fill Transparency Level
+ self.sf_alpha_label = QtWidgets.QLabel('%s:' % _('Alpha'))
+ self.sf_alpha_label.setToolTip(
+ _("Set the fill transparency for the 'left to right' selection box.")
+ )
+ self.sf_color_alpha_slider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
+ self.sf_color_alpha_slider.setMinimum(0)
+ self.sf_color_alpha_slider.setMaximum(255)
+ self.sf_color_alpha_slider.setSingleStep(1)
+
+ self.sf_color_alpha_spinner = FCSpinner()
+ self.sf_color_alpha_spinner.setMinimumWidth(70)
+ self.sf_color_alpha_spinner.set_range(0, 255)
+
+ self.form_box_child_6 = QtWidgets.QHBoxLayout()
+ self.form_box_child_6.addWidget(self.sf_color_alpha_slider)
+ self.form_box_child_6.addWidget(self.sf_color_alpha_spinner)
+
+ grid0.addWidget(self.sf_alpha_label, 18, 0)
+ grid0.addLayout(self.form_box_child_6, 18, 1)
+
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid0.addWidget(separator_line, 19, 0, 1, 2)
+
+ # Plot Selection (left - right) Color
+ self.sel_rl_label = QtWidgets.QLabel('%s' % _('Right-Left Selection Color'))
+ grid0.addWidget(self.sel_rl_label, 20, 0, 1, 2)
+
+ # Plot Selection (right - left) Line Color
+ self.alt_sl_color_label = QtWidgets.QLabel('%s:' % _('Outline'))
+ self.alt_sl_color_label.setToolTip(
+ _("Set the line color for the 'right to left' selection box.")
+ )
+ self.alt_sl_color_entry = FCEntry()
+ self.alt_sl_color_button = QtWidgets.QPushButton()
+ self.alt_sl_color_button.setFixedSize(15, 15)
+
+ self.form_box_child_7 = QtWidgets.QHBoxLayout()
+ self.form_box_child_7.addWidget(self.alt_sl_color_entry)
+ self.form_box_child_7.addWidget(self.alt_sl_color_button)
+ self.form_box_child_7.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
+
+ grid0.addWidget(self.alt_sl_color_label, 21, 0)
+ grid0.addLayout(self.form_box_child_7, 21, 1)
+
+ # Plot Selection (right - left) Fill Color
+ self.alt_sf_color_label = QtWidgets.QLabel('%s:' % _('Fill'))
+ self.alt_sf_color_label.setToolTip(
+ _("Set the fill color for the selection box\n"
+ "in case that the selection is done from right to left.\n"
+ "First 6 digits are the color and the last 2\n"
+ "digits are for alpha (transparency) level.")
+ )
+ self.alt_sf_color_entry = FCEntry()
+ self.alt_sf_color_button = QtWidgets.QPushButton()
+ self.alt_sf_color_button.setFixedSize(15, 15)
+
+ self.form_box_child_8 = QtWidgets.QHBoxLayout()
+ self.form_box_child_8.addWidget(self.alt_sf_color_entry)
+ self.form_box_child_8.addWidget(self.alt_sf_color_button)
+ self.form_box_child_8.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
+
+ grid0.addWidget(self.alt_sf_color_label, 22, 0)
+ grid0.addLayout(self.form_box_child_8, 22, 1)
+
+ # Plot Selection (right - left) Fill Transparency Level
+ self.alt_sf_alpha_label = QtWidgets.QLabel('%s:' % _('Alpha'))
+ self.alt_sf_alpha_label.setToolTip(
+ _("Set the fill transparency for selection 'right to left' box.")
+ )
+ self.alt_sf_color_alpha_slider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
+ self.alt_sf_color_alpha_slider.setMinimum(0)
+ self.alt_sf_color_alpha_slider.setMaximum(255)
+ self.alt_sf_color_alpha_slider.setSingleStep(1)
+
+ self.alt_sf_color_alpha_spinner = FCSpinner()
+ self.alt_sf_color_alpha_spinner.setMinimumWidth(70)
+ self.alt_sf_color_alpha_spinner.set_range(0, 255)
+
+ self.form_box_child_9 = QtWidgets.QHBoxLayout()
+ self.form_box_child_9.addWidget(self.alt_sf_color_alpha_slider)
+ self.form_box_child_9.addWidget(self.alt_sf_color_alpha_spinner)
+
+ grid0.addWidget(self.alt_sf_alpha_label, 23, 0)
+ grid0.addLayout(self.form_box_child_9, 23, 1)
+
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid0.addWidget(separator_line, 24, 0, 1, 2)
+
+ # ------------------------------------------------------------------
+ # ----------------------- Editor Color -----------------------------
+ # ------------------------------------------------------------------
+
+ self.editor_color_label = QtWidgets.QLabel('%s' % _('Editor Color'))
+ grid0.addWidget(self.editor_color_label, 25, 0, 1, 2)
+
+ # Editor Draw Color
+ self.draw_color_label = QtWidgets.QLabel('%s:' % _('Drawing'))
+ self.alt_sf_color_label.setToolTip(
+ _("Set the color for the shape.")
+ )
+ self.draw_color_entry = FCEntry()
+ self.draw_color_button = QtWidgets.QPushButton()
+ self.draw_color_button.setFixedSize(15, 15)
+
+ self.form_box_child_10 = QtWidgets.QHBoxLayout()
+ self.form_box_child_10.addWidget(self.draw_color_entry)
+ self.form_box_child_10.addWidget(self.draw_color_button)
+ self.form_box_child_10.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
+
+ grid0.addWidget(self.draw_color_label, 26, 0)
+ grid0.addLayout(self.form_box_child_10, 26, 1)
+
+ # Editor Draw Selection Color
+ self.sel_draw_color_label = QtWidgets.QLabel('%s:' % _('Selection'))
+ self.sel_draw_color_label.setToolTip(
+ _("Set the color of the shape when selected.")
+ )
+ self.sel_draw_color_entry = FCEntry()
+ self.sel_draw_color_button = QtWidgets.QPushButton()
+ self.sel_draw_color_button.setFixedSize(15, 15)
+
+ self.form_box_child_11 = QtWidgets.QHBoxLayout()
+ self.form_box_child_11.addWidget(self.sel_draw_color_entry)
+ self.form_box_child_11.addWidget(self.sel_draw_color_button)
+ self.form_box_child_11.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
+
+ grid0.addWidget(self.sel_draw_color_label, 27, 0)
+ grid0.addLayout(self.form_box_child_11, 27, 1)
+
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid0.addWidget(separator_line, 28, 0, 1, 2)
+
+ # ------------------------------------------------------------------
+ # ----------------------- Project Settings -----------------------------
+ # ------------------------------------------------------------------
+
+ self.proj_settings_label = QtWidgets.QLabel('%s' % _('Project Items Color'))
+ grid0.addWidget(self.proj_settings_label, 29, 0, 1, 2)
+
+ # Project Tab items color
+ self.proj_color_label = QtWidgets.QLabel('%s:' % _('Enabled'))
+ self.proj_color_label.setToolTip(
+ _("Set the color of the items in Project Tab Tree.")
+ )
+ self.proj_color_entry = FCEntry()
+ self.proj_color_button = QtWidgets.QPushButton()
+ self.proj_color_button.setFixedSize(15, 15)
+
+ self.form_box_child_12 = QtWidgets.QHBoxLayout()
+ self.form_box_child_12.addWidget(self.proj_color_entry)
+ self.form_box_child_12.addWidget(self.proj_color_button)
+ self.form_box_child_12.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
+
+ grid0.addWidget(self.proj_color_label, 30, 0)
+ grid0.addLayout(self.form_box_child_12, 30, 1)
+
+ self.proj_color_dis_label = QtWidgets.QLabel('%s:' % _('Disabled'))
+ self.proj_color_dis_label.setToolTip(
+ _("Set the color of the items in Project Tab Tree,\n"
+ "for the case when the items are disabled.")
+ )
+ self.proj_color_dis_entry = FCEntry()
+ self.proj_color_dis_button = QtWidgets.QPushButton()
+ self.proj_color_dis_button.setFixedSize(15, 15)
+
+ self.form_box_child_13 = QtWidgets.QHBoxLayout()
+ self.form_box_child_13.addWidget(self.proj_color_dis_entry)
+ self.form_box_child_13.addWidget(self.proj_color_dis_button)
+ self.form_box_child_13.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
+
+ grid0.addWidget(self.proj_color_dis_label, 31, 0)
+ grid0.addLayout(self.form_box_child_13, 31, 1)
+
+ # Project autohide CB
+ self.project_autohide_cb = FCCheckBox(label=_('Project AutoHide'))
+ self.project_autohide_cb.setToolTip(
+ _("Check this box if you want the project/selected/tool tab area to\n"
+ "hide automatically when there are no objects loaded and\n"
+ "to show whenever a new object is created.")
+ )
+
+ grid0.addWidget(self.project_autohide_cb, 32, 0, 1, 2)
+
+ # Just to add empty rows
+ grid0.addWidget(QtWidgets.QLabel(''), 33, 0, 1, 2)
+
+ self.layout.addStretch()
+
+ # #############################################################################
+ # ############################# GUI COLORS SIGNALS ############################
+ # #############################################################################
+
+ # Setting selection (left - right) colors signals
+ self.sf_color_entry.editingFinished.connect(self.on_sf_color_entry)
+ self.sf_color_button.clicked.connect(self.on_sf_color_button)
+ self.sf_color_alpha_spinner.valueChanged.connect(self.on_sf_color_spinner)
+ self.sf_color_alpha_slider.valueChanged.connect(self.on_sf_color_slider)
+ self.sl_color_entry.editingFinished.connect(self.on_sl_color_entry)
+ self.sl_color_button.clicked.connect(self.on_sl_color_button)
+
+ # Setting selection (right - left) colors signals
+ self.alt_sf_color_entry.editingFinished.connect(self.on_alt_sf_color_entry)
+ self.alt_sf_color_button.clicked.connect(self.on_alt_sf_color_button)
+ self.alt_sf_color_alpha_spinner.valueChanged.connect(self.on_alt_sf_color_spinner)
+ self.alt_sf_color_alpha_slider.valueChanged.connect(self.on_alt_sf_color_slider)
+ self.alt_sl_color_entry.editingFinished.connect(self.on_alt_sl_color_entry)
+ self.alt_sl_color_button.clicked.connect(self.on_alt_sl_color_button)
+
+ # Setting Editor Draw colors signals
+ self.draw_color_entry.editingFinished.connect(self.on_draw_color_entry)
+ self.draw_color_button.clicked.connect(self.on_draw_color_button)
+
+ self.sel_draw_color_entry.editingFinished.connect(self.on_sel_draw_color_entry)
+ self.sel_draw_color_button.clicked.connect(self.on_sel_draw_color_button)
+
+ self.proj_color_entry.editingFinished.connect(self.on_proj_color_entry)
+ self.proj_color_button.clicked.connect(self.on_proj_color_button)
+
+ self.proj_color_dis_entry.editingFinished.connect(self.on_proj_color_dis_entry)
+ self.proj_color_dis_button.clicked.connect(self.on_proj_color_dis_button)
+
+ self.layout_combo.activated.connect(self.on_layout)
@staticmethod
def handle_style(style):
- # FIXME: this should be moved out to a view model
# set current style
qsettings = QSettings("Open Source", "FlatCAM")
qsettings.setValue('style', style)
@@ -191,10 +427,349 @@ class GeneralGUIPrefGroupUI(OptionsGroupUI2):
@staticmethod
def handle_hdpi(state):
- # FIXME: this should be moved out to a view model
# set current HDPI
qsettings = QSettings("Open Source", "FlatCAM")
qsettings.setValue('hdpi', state)
# This will write the setting to the platform specific storage.
- del qsettings
\ No newline at end of file
+ del qsettings
+
+ # Setting selection colors (left - right) handlers
+ def on_sf_color_entry(self):
+ self.app.defaults['global_sel_fill'] = self.app.defaults['global_sel_fill'][7:9]
+ self.sf_color_button.setStyleSheet("background-color:%s" % str(self.app.defaults['global_sel_fill'])[:7])
+
+ def on_sf_color_button(self):
+ current_color = QtGui.QColor(self.app.defaults['global_sel_fill'][:7])
+
+ c_dialog = QtWidgets.QColorDialog()
+ plot_fill_color = c_dialog.getColor(initial=current_color)
+
+ if plot_fill_color.isValid() is False:
+ return
+
+ self.sf_color_button.setStyleSheet("background-color:%s" % str(plot_fill_color.name()))
+
+ new_val = str(plot_fill_color.name()) + str(self.app.defaults['global_sel_fill'][7:9])
+ self.sf_color_entry.set_value(new_val)
+ self.app.defaults['global_sel_fill'] = new_val
+
+ def on_sf_color_spinner(self):
+ spinner_value = self.sf_color_alpha_spinner.value()
+ self.sf_color_alpha_slider.setValue(spinner_value)
+ self.app.defaults['global_sel_fill'] = self.app.defaults['global_sel_fill'][:7] + \
+ (hex(spinner_value)[2:] if int(hex(spinner_value)[2:], 16) > 0 else '00')
+ self.app.defaults['global_sel_line'] = self.app.defaults['global_sel_line'][:7] + \
+ (hex(spinner_value)[2:] if int(hex(spinner_value)[2:], 16) > 0 else '00')
+
+ def on_sf_color_slider(self):
+ slider_value = self.sf_color_alpha_slider.value()
+ self.sf_color_alpha_spinner.setValue(slider_value)
+
+ def on_sl_color_entry(self):
+ self.app.defaults['global_sel_line'] = self.sl_color_entry.get_value()[:7] + \
+ self.app.defaults['global_sel_line'][7:9]
+ self.sl_color_button.setStyleSheet("background-color:%s" % str(self.app.defaults['global_sel_line'])[:7])
+
+ def on_sl_color_button(self):
+ current_color = QtGui.QColor(self.app.defaults['global_sel_line'][:7])
+
+ c_dialog = QtWidgets.QColorDialog()
+ plot_line_color = c_dialog.getColor(initial=current_color)
+
+ if plot_line_color.isValid() is False:
+ return
+
+ self.sl_color_button.setStyleSheet("background-color:%s" % str(plot_line_color.name()))
+
+ new_val_line = str(plot_line_color.name()) + str(self.app.defaults['global_sel_line'][7:9])
+ self.sl_color_entry.set_value(new_val_line)
+ self.app.defaults['global_sel_line'] = new_val_line
+
+ # Setting selection colors (right - left) handlers
+ def on_alt_sf_color_entry(self):
+ self.app.defaults['global_alt_sel_fill'] = self.alt_sf_color_entry.get_value()[:7] + \
+ self.app.defaults['global_alt_sel_fill'][7:9]
+ self.alt_sf_color_button.setStyleSheet(
+ "background-color:%s" % str(self.app.defaults['global_alt_sel_fill'])[:7]
+ )
+
+ def on_alt_sf_color_button(self):
+ current_color = QtGui.QColor(self.app.defaults['global_alt_sel_fill'][:7])
+
+ c_dialog = QtWidgets.QColorDialog()
+ plot_fill_color = c_dialog.getColor(initial=current_color)
+
+ if plot_fill_color.isValid() is False:
+ return
+
+ self.alt_sf_color_button.setStyleSheet("background-color:%s" % str(plot_fill_color.name()))
+
+ new_val = str(plot_fill_color.name()) + str(self.app.defaults['global_alt_sel_fill'][7:9])
+ self.alt_sf_color_entry.set_value(new_val)
+ self.app.defaults['global_alt_sel_fill'] = new_val
+
+ def on_alt_sf_color_spinner(self):
+ spinner_value = self.alt_sf_color_alpha_spinner.value()
+ self.alt_sf_color_alpha_slider.setValue(spinner_value)
+ self.app.defaults['global_alt_sel_fill'] = self.app.defaults['global_alt_sel_fill'][:7] + \
+ (hex(spinner_value)[2:] if int(hex(spinner_value)[2:], 16) > 0 else '00')
+ self.app.defaults['global_alt_sel_line'] = self.app.defaults['global_alt_sel_line'][:7] + \
+ (hex(spinner_value)[2:] if int(hex(spinner_value)[2:], 16) > 0 else '00')
+
+ def on_alt_sf_color_slider(self):
+ slider_value = self.alt_sf_color_alpha_slider.value()
+ self.alt_sf_color_alpha_spinner.setValue(slider_value)
+
+ def on_alt_sl_color_entry(self):
+ self.app.defaults['global_alt_sel_line'] = self.alt_sl_color_entry.get_value()[:7] + \
+ self.app.defaults['global_alt_sel_line'][7:9]
+ self.alt_sl_color_button.setStyleSheet(
+ "background-color:%s" % str(self.app.defaults['global_alt_sel_line'])[:7]
+ )
+
+ def on_alt_sl_color_button(self):
+ current_color = QtGui.QColor(self.app.defaults['global_alt_sel_line'][:7])
+
+ c_dialog = QtWidgets.QColorDialog()
+ plot_line_color = c_dialog.getColor(initial=current_color)
+
+ if plot_line_color.isValid() is False:
+ return
+
+ self.alt_sl_color_button.setStyleSheet("background-color:%s" % str(plot_line_color.name()))
+
+ new_val_line = str(plot_line_color.name()) + str(self.app.defaults['global_alt_sel_line'][7:9])
+ self.alt_sl_color_entry.set_value(new_val_line)
+ self.app.defaults['global_alt_sel_line'] = new_val_line
+
+ # Setting Editor colors
+ def on_draw_color_entry(self):
+ self.app.defaults['global_draw_color'] = self.draw_color_entry.get_value()
+ self.draw_color_button.setStyleSheet("background-color:%s" % str(self.app.defaults['global_draw_color']))
+
+ def on_draw_color_button(self):
+ current_color = QtGui.QColor(self.app.defaults['global_draw_color'])
+
+ c_dialog = QtWidgets.QColorDialog()
+ draw_color = c_dialog.getColor(initial=current_color)
+
+ if draw_color.isValid() is False:
+ return
+
+ self.draw_color_button.setStyleSheet("background-color:%s" % str(draw_color.name()))
+
+ new_val = str(draw_color.name())
+ self.draw_color_entry.set_value(new_val)
+ self.app.defaults['global_draw_color'] = new_val
+
+ def on_sel_draw_color_entry(self):
+ self.app.defaults['global_sel_draw_color'] = self.sel_draw_color_entry.get_value()
+ self.sel_draw_color_button.setStyleSheet(
+ "background-color:%s" % str(self.app.defaults['global_sel_draw_color']))
+
+ def on_sel_draw_color_button(self):
+ current_color = QtGui.QColor(self.app.defaults['global_sel_draw_color'])
+
+ c_dialog = QtWidgets.QColorDialog()
+ sel_draw_color = c_dialog.getColor(initial=current_color)
+
+ if sel_draw_color.isValid() is False:
+ return
+
+ self.sel_draw_color_button.setStyleSheet("background-color:%s" % str(sel_draw_color.name()))
+
+ new_val_sel = str(sel_draw_color.name())
+ self.sel_draw_color_entry.set_value(new_val_sel)
+ self.app.defaults['global_sel_draw_color'] = new_val_sel
+
+ def on_proj_color_entry(self):
+ self.app.defaults['global_proj_item_color'] = self.proj_color_entry.get_value()
+ self.proj_color_button.setStyleSheet(
+ "background-color:%s" % str(self.app.defaults['global_proj_item_color']))
+
+ def on_proj_color_button(self):
+ current_color = QtGui.QColor(self.app.defaults['global_proj_item_color'])
+
+ c_dialog = QtWidgets.QColorDialog()
+ proj_color = c_dialog.getColor(initial=current_color)
+
+ if proj_color.isValid() is False:
+ return
+
+ self.proj_color_button.setStyleSheet("background-color:%s" % str(proj_color.name()))
+
+ new_val_sel = str(proj_color.name())
+ self.proj_color_entry.set_value(new_val_sel)
+ self.app.defaults['global_proj_item_color'] = new_val_sel
+
+ def on_proj_color_dis_entry(self):
+ self.app.defaults['global_proj_item_dis_color'] = self.proj_color_dis_entry.get_value()
+ self.proj_color_dis_button.setStyleSheet(
+ "background-color:%s" % str(self.app.defaults['global_proj_item_dis_color']))
+
+ def on_proj_color_dis_button(self):
+ current_color = QtGui.QColor(self.app.defaults['global_proj_item_dis_color'])
+
+ c_dialog = QtWidgets.QColorDialog()
+ proj_color = c_dialog.getColor(initial=current_color)
+
+ if proj_color.isValid() is False:
+ return
+
+ self.proj_color_dis_button.setStyleSheet("background-color:%s" % str(proj_color.name()))
+
+ new_val_sel = str(proj_color.name())
+ self.proj_color_dis_entry.set_value(new_val_sel)
+ self.app.defaults['global_proj_item_dis_color'] = new_val_sel
+
+ def on_layout(self, index=None, lay=None):
+ """
+ Set the toolbars layout (location)
+
+ :param index:
+ :param lay: Type of layout to be set on the toolbard
+ :return: None
+ """
+
+ self.app.defaults.report_usage("on_layout()")
+ if lay:
+ current_layout = lay
+ else:
+ current_layout = self.layout_combo.get_value()
+
+ lay_settings = QSettings("Open Source", "FlatCAM")
+ lay_settings.setValue('layout', current_layout)
+
+ # This will write the setting to the platform specific storage.
+ del lay_settings
+
+ # first remove the toolbars:
+ try:
+ self.app.ui.removeToolBar(self.app.ui.toolbarfile)
+ self.app.ui.removeToolBar(self.app.ui.toolbargeo)
+ self.app.ui.removeToolBar(self.app.ui.toolbarview)
+ self.app.ui.removeToolBar(self.app.ui.toolbarshell)
+ self.app.ui.removeToolBar(self.app.ui.toolbartools)
+ self.app.ui.removeToolBar(self.app.ui.exc_edit_toolbar)
+ self.app.ui.removeToolBar(self.app.ui.geo_edit_toolbar)
+ self.app.ui.removeToolBar(self.app.ui.grb_edit_toolbar)
+ self.app.ui.removeToolBar(self.app.ui.snap_toolbar)
+ self.app.ui.removeToolBar(self.app.ui.toolbarshell)
+ except Exception:
+ pass
+
+ if current_layout == 'compact':
+ # ## TOOLBAR INSTALLATION # ##
+ self.app.ui.toolbarfile = QtWidgets.QToolBar('File Toolbar')
+ self.app.ui.toolbarfile.setObjectName('File_TB')
+ self.app.ui.addToolBar(Qt.LeftToolBarArea, self.app.ui.toolbarfile)
+
+ self.app.ui.toolbargeo = QtWidgets.QToolBar('Edit Toolbar')
+ self.app.ui.toolbargeo.setObjectName('Edit_TB')
+ self.app.ui.addToolBar(Qt.LeftToolBarArea, self.app.ui.toolbargeo)
+
+ self.app.ui.toolbarshell = QtWidgets.QToolBar('Shell Toolbar')
+ self.app.ui.toolbarshell.setObjectName('Shell_TB')
+ self.app.ui.addToolBar(Qt.LeftToolBarArea, self.app.ui.toolbarshell)
+
+ self.app.ui.toolbartools = QtWidgets.QToolBar('Tools Toolbar')
+ self.app.ui.toolbartools.setObjectName('Tools_TB')
+ self.app.ui.addToolBar(Qt.LeftToolBarArea, self.app.ui.toolbartools)
+
+ self.app.ui.geo_edit_toolbar = QtWidgets.QToolBar('Geometry Editor Toolbar')
+ # self.app.ui.geo_edit_toolbar.setVisible(False)
+ self.app.ui.geo_edit_toolbar.setObjectName('GeoEditor_TB')
+ self.app.ui.addToolBar(Qt.RightToolBarArea, self.app.ui.geo_edit_toolbar)
+
+ self.app.ui.toolbarview = QtWidgets.QToolBar('View Toolbar')
+ self.app.ui.toolbarview.setObjectName('View_TB')
+ self.app.ui.addToolBar(Qt.RightToolBarArea, self.app.ui.toolbarview)
+
+ self.app.ui.addToolBarBreak(area=Qt.RightToolBarArea)
+
+ self.app.ui.grb_edit_toolbar = QtWidgets.QToolBar('Gerber Editor Toolbar')
+ # self.app.ui.grb_edit_toolbar.setVisible(False)
+ self.app.ui.grb_edit_toolbar.setObjectName('GrbEditor_TB')
+ self.app.ui.addToolBar(Qt.RightToolBarArea, self.app.ui.grb_edit_toolbar)
+
+ self.app.ui.exc_edit_toolbar = QtWidgets.QToolBar('Excellon Editor Toolbar')
+ self.app.ui.exc_edit_toolbar.setObjectName('ExcEditor_TB')
+ self.app.ui.addToolBar(Qt.RightToolBarArea, self.app.ui.exc_edit_toolbar)
+
+ self.app.ui.snap_toolbar = QtWidgets.QToolBar('Grid Toolbar')
+ self.app.ui.snap_toolbar.setObjectName('Snap_TB')
+ self.app.ui.snap_toolbar.setMaximumHeight(30)
+ self.app.ui.splitter_left.addWidget(self.app.ui.snap_toolbar)
+
+ self.app.ui.corner_snap_btn.setVisible(True)
+ self.app.ui.snap_magnet.setVisible(True)
+ else:
+ # ## TOOLBAR INSTALLATION # ##
+ self.app.ui.toolbarfile = QtWidgets.QToolBar('File Toolbar')
+ self.app.ui.toolbarfile.setObjectName('File_TB')
+ self.app.ui.addToolBar(self.app.ui.toolbarfile)
+
+ self.app.ui.toolbargeo = QtWidgets.QToolBar('Edit Toolbar')
+ self.app.ui.toolbargeo.setObjectName('Edit_TB')
+ self.app.ui.addToolBar(self.app.ui.toolbargeo)
+
+ self.app.ui.toolbarview = QtWidgets.QToolBar('View Toolbar')
+ self.app.ui.toolbarview.setObjectName('View_TB')
+ self.app.ui.addToolBar(self.app.ui.toolbarview)
+
+ self.app.ui.toolbarshell = QtWidgets.QToolBar('Shell Toolbar')
+ self.app.ui.toolbarshell.setObjectName('Shell_TB')
+ self.app.ui.addToolBar(self.app.ui.toolbarshell)
+
+ self.app.ui.toolbartools = QtWidgets.QToolBar('Tools Toolbar')
+ self.app.ui.toolbartools.setObjectName('Tools_TB')
+ self.app.ui.addToolBar(self.app.ui.toolbartools)
+
+ self.app.ui.exc_edit_toolbar = QtWidgets.QToolBar('Excellon Editor Toolbar')
+ # self.app.ui.exc_edit_toolbar.setVisible(False)
+ self.app.ui.exc_edit_toolbar.setObjectName('ExcEditor_TB')
+ self.app.ui.addToolBar(self.app.ui.exc_edit_toolbar)
+
+ self.app.ui.addToolBarBreak()
+
+ self.app.ui.geo_edit_toolbar = QtWidgets.QToolBar('Geometry Editor Toolbar')
+ # self.app.ui.geo_edit_toolbar.setVisible(False)
+ self.app.ui.geo_edit_toolbar.setObjectName('GeoEditor_TB')
+ self.app.ui.addToolBar(self.app.ui.geo_edit_toolbar)
+
+ self.app.ui.grb_edit_toolbar = QtWidgets.QToolBar('Gerber Editor Toolbar')
+ # self.app.ui.grb_edit_toolbar.setVisible(False)
+ self.app.ui.grb_edit_toolbar.setObjectName('GrbEditor_TB')
+ self.app.ui.addToolBar(self.app.ui.grb_edit_toolbar)
+
+ self.app.ui.snap_toolbar = QtWidgets.QToolBar('Grid Toolbar')
+ self.app.ui.snap_toolbar.setObjectName('Snap_TB')
+ # self.app.ui.snap_toolbar.setMaximumHeight(30)
+ self.app.ui.addToolBar(self.app.ui.snap_toolbar)
+
+ self.app.ui.corner_snap_btn.setVisible(False)
+ self.app.ui.snap_magnet.setVisible(False)
+
+ if current_layout == 'minimal':
+ self.app.ui.toolbarview.setVisible(False)
+ self.app.ui.toolbarshell.setVisible(False)
+ self.app.ui.snap_toolbar.setVisible(False)
+ self.app.ui.geo_edit_toolbar.setVisible(False)
+ self.app.ui.grb_edit_toolbar.setVisible(False)
+ self.app.ui.exc_edit_toolbar.setVisible(False)
+ self.app.ui.lock_toolbar(lock=True)
+
+ # add all the actions to the toolbars
+ self.app.ui.populate_toolbars()
+
+ # reconnect all the signals to the toolbar actions
+ self.app.connect_toolbar_signals()
+
+ self.app.ui.grid_snap_btn.setChecked(True)
+ self.app.ui.on_grid_snap_triggered(state=True)
+
+ self.app.ui.grid_gap_x_entry.setText(str(self.app.defaults["global_gridx"]))
+ self.app.ui.grid_gap_y_entry.setText(str(self.app.defaults["global_gridy"]))
+ self.app.ui.snap_max_dist_entry.setText(str(self.app.defaults["global_snap_max"]))
+ self.app.ui.grid_gap_link_cb.setChecked(True)
diff --git a/flatcamGUI/preferences/general/GeneralPreferencesUI.py b/flatcamGUI/preferences/general/GeneralPreferencesUI.py
index c88d7362..46636438 100644
--- a/flatcamGUI/preferences/general/GeneralPreferencesUI.py
+++ b/flatcamGUI/preferences/general/GeneralPreferencesUI.py
@@ -1,25 +1,43 @@
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
-from flatcamGUI.preferences.PreferencesSectionUI import PreferencesSectionUI
+from PyQt5 import QtWidgets
+from PyQt5.QtCore import QSettings
+
from flatcamGUI.preferences.general.GeneralAppPrefGroupUI import GeneralAppPrefGroupUI
-from flatcamGUI.preferences.general.GeneralAppSettingsGroupUI import GeneralAppSettingsGroupUI
+from flatcamGUI.preferences.general.GeneralAPPSetGroupUI import GeneralAPPSetGroupUI
from flatcamGUI.preferences.general.GeneralGUIPrefGroupUI import GeneralGUIPrefGroupUI
+import gettext
+import FlatCAMTranslation as fcTranslate
+import builtins
-class GeneralPreferencesUI(PreferencesSectionUI):
+fcTranslate.apply_language('strings')
+if '_' not in builtins.__dict__:
+ _ = gettext.gettext
- def __init__(self, decimals, **kwargs):
+settings = QSettings("Open Source", "FlatCAM")
+if settings.contains("machinist"):
+ machinist_setting = settings.value('machinist', type=int)
+else:
+ machinist_setting = 0
+
+
+class GeneralPreferencesUI(QtWidgets.QWidget):
+ def __init__(self, decimals, parent=None):
+ QtWidgets.QWidget.__init__(self, parent=parent)
+ self.layout = QtWidgets.QHBoxLayout()
+ self.setLayout(self.layout)
self.decimals = decimals
- super().__init__(**kwargs)
- def build_groups(self) -> [OptionsGroupUI]:
- return [
- GeneralAppPrefGroupUI(decimals=self.decimals),
- GeneralGUIPrefGroupUI(decimals=self.decimals),
- GeneralAppSettingsGroupUI(decimals=self.decimals)
- ]
+ self.general_app_group = GeneralAppPrefGroupUI(decimals=self.decimals)
+ self.general_app_group.setMinimumWidth(250)
- def get_tab_id(self):
- return "general_tab"
+ self.general_gui_group = GeneralGUIPrefGroupUI(decimals=self.decimals)
+ self.general_gui_group.setMinimumWidth(250)
- def get_tab_label(self):
- return _("General")
+ self.general_app_set_group = GeneralAPPSetGroupUI(decimals=self.decimals)
+ self.general_app_set_group.setMinimumWidth(250)
+
+ self.layout.addWidget(self.general_app_group)
+ self.layout.addWidget(self.general_gui_group)
+ self.layout.addWidget(self.general_app_set_group)
+
+ self.layout.addStretch()
diff --git a/flatcamGUI/preferences/geometry/GeometryAdvOptPrefGroupUI.py b/flatcamGUI/preferences/geometry/GeometryAdvOptPrefGroupUI.py
index 57993400..7ade9b90 100644
--- a/flatcamGUI/preferences/geometry/GeometryAdvOptPrefGroupUI.py
+++ b/flatcamGUI/preferences/geometry/GeometryAdvOptPrefGroupUI.py
@@ -1,150 +1,246 @@
-from flatcamGUI.preferences.OptionUI import *
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI2
+from PyQt5 import QtWidgets
+from PyQt5.QtCore import QSettings
+
+from flatcamGUI.GUIElements import FCEntry, FloatEntry, FCDoubleSpinner, FCCheckBox, RadioSet, FCLabel
+from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
import gettext
import FlatCAMTranslation as fcTranslate
import builtins
+
fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__:
_ = gettext.gettext
+settings = QSettings("Open Source", "FlatCAM")
+if settings.contains("machinist"):
+ machinist_setting = settings.value('machinist', type=int)
+else:
+ machinist_setting = 0
-class GeometryAdvOptPrefGroupUI(OptionsGroupUI2):
- def __init__(self, decimals=4, **kwargs):
- self.decimals = decimals
- super().__init__(**kwargs)
+class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
+ def __init__(self, decimals=4, parent=None):
+ # OptionsGroupUI.__init__(self, "Geometry Advanced Options Preferences", parent=parent)
+ super(GeometryAdvOptPrefGroupUI, self).__init__(self, parent=parent)
+
self.setTitle(str(_("Geometry Adv. Options")))
+ self.decimals = decimals
- def build_options(self) -> [OptionUI]:
- return [
- HeadingOptionUI(
- label_text="Advanced Options",
- label_tooltip="A list of Geometry advanced parameters.\n"
- "Those parameters are available only for\n"
- "Advanced App. Level."
- ),
- LineEntryOptionUI(
- option="geometry_toolchangexy",
- label_text="Toolchange X-Y",
- label_tooltip="Toolchange X,Y position."
- ),
- FloatEntryOptionUI(
- option="geometry_startz",
- label_text="Start Z",
- label_tooltip="Height of the tool just after starting the work.\n"
- "Delete the value if you don't need this feature."
- ),
- DoubleSpinnerOptionUI(
- option="geometry_feedrate_rapid",
- label_text="Feedrate Rapids",
- label_tooltip="Cutting speed in the XY plane\n"
- "(in units per minute).\n"
- "This is for the rapid move G00.\n"
- "It is useful only for Marlin,\n"
- "ignore for any other cases.",
- min_value=0, max_value=99999.9999, step=10, decimals=self.decimals
- ),
- CheckboxOptionUI(
- option="geometry_extracut",
- label_text="Re-cut",
- label_tooltip="In order to remove possible\n"
- "copper leftovers where first cut\n"
- "meet with last cut, we generate an\n"
- "extended cut over the first cut section."
- ),
- DoubleSpinnerOptionUI(
- option="geometry_extracut_length",
- label_text="Re-cut length",
- label_tooltip="In order to remove possible\n"
- "copper leftovers where first cut\n"
- "meet with last cut, we generate an\n"
- "extended cut over the first cut section.",
- min_value=0, max_value=99999, step=0.1, decimals=self.decimals
- ),
- DoubleSpinnerOptionUI(
- option="geometry_z_pdepth",
- label_text="Probe Z depth",
- label_tooltip="The maximum depth that the probe is allowed\n"
- "to probe. Negative value, in current units.",
- min_value=-99999, max_value=0.0, step=0.1, decimals=self.decimals
- ),
- DoubleSpinnerOptionUI(
- option="geometry_feedrate_probe",
- label_text="Feedrate Probe",
- label_tooltip="The feedrate used while the probe is probing.",
- min_value=0, max_value=99999.9999, step=0.1, decimals=self.decimals
- ),
- RadioSetOptionUI(
- option="geometry_spindledir",
- label_text="Spindle direction",
- label_tooltip="This sets the direction that the spindle is rotating.\n"
- "It can be either:\n"
- "- CW = clockwise or\n"
- "- CCW = counter clockwise",
- choices=[{'label': _('CW'), 'value': 'CW'},
- {'label': _('CCW'), 'value': 'CCW'}]
- ),
- CheckboxOptionUI(
- option="geometry_f_plunge",
- label_text="Fast Plunge",
- label_tooltip="By checking this, the vertical move from\n"
- "Z_Toolchange to Z_move is done with G0,\n"
- "meaning the fastest speed available.\n"
- "WARNING: the move is done at Toolchange X,Y coords."
- ),
- DoubleSpinnerOptionUI(
- option="geometry_segx",
- label_text="Segment X size",
- label_tooltip="The size of the trace segment on the X axis.\n"
- "Useful for auto-leveling.\n"
- "A value of 0 means no segmentation on the X axis.",
- min_value=0, max_value=99999, step=0.1, decimals=self.decimals
- ),
- DoubleSpinnerOptionUI(
- option="geometry_segy",
- label_text="Segment Y size",
- label_tooltip="The size of the trace segment on the Y axis.\n"
- "Useful for auto-leveling.\n"
- "A value of 0 means no segmentation on the Y axis.",
- min_value=0, max_value=99999, step=0.1, decimals=self.decimals
- ),
+ # ------------------------------
+ # ## Advanced Options
+ # ------------------------------
+ self.geo_label = QtWidgets.QLabel('%s:' % _('Advanced Options'))
+ self.geo_label.setToolTip(
+ _("A list of Geometry advanced parameters.\n"
+ "Those parameters are available only for\n"
+ "Advanced App. Level.")
+ )
+ self.layout.addWidget(self.geo_label)
- HeadingOptionUI(
- label_text="Area Exclusion",
- label_tooltip="Area exclusion parameters.\n"
- "Those parameters are available only for\n"
- "Advanced App. Level."
- ),
- CheckboxOptionUI(
- option="geometry_area_exclusion",
- label_text="Exclusion areas",
- label_tooltip="Include exclusion areas.\n"
- "In those areas the travel of the tools\n"
- "is forbidden."
- ),
- RadioSetOptionUI(
- option="geometry_area_shape",
- label_text="Shape",
- label_tooltip="The kind of selection shape used for area selection.",
- choices=[{'label': _("Square"), 'value': 'square'},
- {'label': _("Polygon"), 'value': 'polygon'}]
- ),
- RadioSetOptionUI(
- option="geometry_area_strategy",
- label_text="Strategy",
- label_tooltip="The strategy followed when encountering an exclusion area.\n"
- "Can be:\n"
- "- Over -> when encountering the area, the tool will go to a set height\n"
- "- Around -> will avoid the exclusion area by going around the area",
- choices=[{'label': _('Over'), 'value': 'over'},
- {'label': _('Around'), 'value': 'around'}]
- ),
- DoubleSpinnerOptionUI(
- option="geometry_area_overz",
- label_text="Over Z",
- label_tooltip="The height Z to which the tool will rise in order to avoid\n"
- "an interdiction area.",
- min_value=0.0, max_value=9999.9999, step=0.5, decimals=self.decimals
+ grid1 = QtWidgets.QGridLayout()
+ self.layout.addLayout(grid1)
+
+ # Toolchange X,Y
+ toolchange_xy_label = QtWidgets.QLabel('%s:' % _('Toolchange X-Y'))
+ toolchange_xy_label.setToolTip(
+ _("Toolchange X,Y position.")
+ )
+ grid1.addWidget(toolchange_xy_label, 1, 0)
+ self.toolchangexy_entry = FCEntry()
+ grid1.addWidget(self.toolchangexy_entry, 1, 1)
+
+ # Start move Z
+ startzlabel = QtWidgets.QLabel('%s:' % _('Start Z'))
+ startzlabel.setToolTip(
+ _("Height of the tool just after starting the work.\n"
+ "Delete the value if you don't need this feature.")
+ )
+ grid1.addWidget(startzlabel, 2, 0)
+ self.gstartz_entry = FloatEntry()
+ grid1.addWidget(self.gstartz_entry, 2, 1)
+
+ # Feedrate rapids
+ fr_rapid_label = QtWidgets.QLabel('%s:' % _('Feedrate Rapids'))
+ fr_rapid_label.setToolTip(
+ _("Cutting speed in the XY plane\n"
+ "(in units per minute).\n"
+ "This is for the rapid move G00.\n"
+ "It is useful only for Marlin,\n"
+ "ignore for any other cases.")
+ )
+ self.feedrate_rapid_entry = FCDoubleSpinner()
+ self.feedrate_rapid_entry.set_range(0, 99999.9999)
+ self.feedrate_rapid_entry.set_precision(self.decimals)
+ self.feedrate_rapid_entry.setSingleStep(0.1)
+ self.feedrate_rapid_entry.setWrapping(True)
+
+ grid1.addWidget(fr_rapid_label, 4, 0)
+ grid1.addWidget(self.feedrate_rapid_entry, 4, 1)
+
+ # End move extra cut
+ self.extracut_cb = FCCheckBox('%s' % _('Re-cut'))
+ self.extracut_cb.setToolTip(
+ _("In order to remove possible\n"
+ "copper leftovers where first cut\n"
+ "meet with last cut, we generate an\n"
+ "extended cut over the first cut section.")
+ )
+
+ self.e_cut_entry = FCDoubleSpinner()
+ self.e_cut_entry.set_range(0, 99999)
+ self.e_cut_entry.set_precision(self.decimals)
+ self.e_cut_entry.setSingleStep(0.1)
+ self.e_cut_entry.setWrapping(True)
+ self.e_cut_entry.setToolTip(
+ _("In order to remove possible\n"
+ "copper leftovers where first cut\n"
+ "meet with last cut, we generate an\n"
+ "extended cut over the first cut section.")
+ )
+ grid1.addWidget(self.extracut_cb, 5, 0)
+ grid1.addWidget(self.e_cut_entry, 5, 1)
+
+ # Probe depth
+ self.pdepth_label = QtWidgets.QLabel('%s:' % _("Probe Z depth"))
+ self.pdepth_label.setToolTip(
+ _("The maximum depth that the probe is allowed\n"
+ "to probe. Negative value, in current units.")
+ )
+ self.pdepth_entry = FCDoubleSpinner()
+ self.pdepth_entry.set_range(-99999, 0.0000)
+ self.pdepth_entry.set_precision(self.decimals)
+ self.pdepth_entry.setSingleStep(0.1)
+ self.pdepth_entry.setWrapping(True)
+
+ grid1.addWidget(self.pdepth_label, 6, 0)
+ grid1.addWidget(self.pdepth_entry, 6, 1)
+
+ # Probe feedrate
+ self.feedrate_probe_label = QtWidgets.QLabel('%s:' % _("Feedrate Probe"))
+ self.feedrate_probe_label.setToolTip(
+ _("The feedrate used while the probe is probing.")
+ )
+ self.feedrate_probe_entry = FCDoubleSpinner()
+ self.feedrate_probe_entry.set_range(0, 99999.9999)
+ self.feedrate_probe_entry.set_precision(self.decimals)
+ self.feedrate_probe_entry.setSingleStep(0.1)
+ self.feedrate_probe_entry.setWrapping(True)
+
+ grid1.addWidget(self.feedrate_probe_label, 7, 0)
+ grid1.addWidget(self.feedrate_probe_entry, 7, 1)
+
+ # Spindle direction
+ spindle_dir_label = QtWidgets.QLabel('%s:' % _('Spindle direction'))
+ spindle_dir_label.setToolTip(
+ _("This sets the direction that the spindle is rotating.\n"
+ "It can be either:\n"
+ "- CW = clockwise or\n"
+ "- CCW = counter clockwise")
+ )
+
+ self.spindledir_radio = RadioSet([{'label': _('CW'), 'value': 'CW'},
+ {'label': _('CCW'), 'value': 'CCW'}])
+ grid1.addWidget(spindle_dir_label, 8, 0)
+ grid1.addWidget(self.spindledir_radio, 8, 1)
+
+ # Fast Move from Z Toolchange
+ self.fplunge_cb = FCCheckBox('%s' % _('Fast Plunge'))
+ self.fplunge_cb.setToolTip(
+ _("By checking this, the vertical move from\n"
+ "Z_Toolchange to Z_move is done with G0,\n"
+ "meaning the fastest speed available.\n"
+ "WARNING: the move is done at Toolchange X,Y coords.")
+ )
+ grid1.addWidget(self.fplunge_cb, 9, 0, 1, 2)
+
+ # Size of trace segment on X axis
+ segx_label = QtWidgets.QLabel('%s:' % _("Segment X size"))
+ segx_label.setToolTip(
+ _("The size of the trace segment on the X axis.\n"
+ "Useful for auto-leveling.\n"
+ "A value of 0 means no segmentation on the X axis.")
+ )
+ self.segx_entry = FCDoubleSpinner()
+ self.segx_entry.set_range(0, 99999)
+ self.segx_entry.set_precision(self.decimals)
+ self.segx_entry.setSingleStep(0.1)
+ self.segx_entry.setWrapping(True)
+
+ grid1.addWidget(segx_label, 10, 0)
+ grid1.addWidget(self.segx_entry, 10, 1)
+
+ # Size of trace segment on Y axis
+ segy_label = QtWidgets.QLabel('%s:' % _("Segment Y size"))
+ segy_label.setToolTip(
+ _("The size of the trace segment on the Y axis.\n"
+ "Useful for auto-leveling.\n"
+ "A value of 0 means no segmentation on the Y axis.")
+ )
+ self.segy_entry = FCDoubleSpinner()
+ self.segy_entry.set_range(0, 99999)
+ self.segy_entry.set_precision(self.decimals)
+ self.segy_entry.setSingleStep(0.1)
+ self.segy_entry.setWrapping(True)
+
+ grid1.addWidget(segy_label, 11, 0)
+ grid1.addWidget(self.segy_entry, 11, 1)
+
+ # -----------------------------
+ # --- Area Exclusion ----------
+ # -----------------------------
+ self.adv_label = QtWidgets.QLabel('%s:' % _('Area Exclusion'))
+ self.adv_label.setToolTip(
+ _("Area exclusion parameters.\n"
+ "Those parameters are available only for\n"
+ "Advanced App. Level.")
+ )
+ grid1.addWidget(self.adv_label, 12, 0, 1, 2)
+
+ # Exclusion Area CB
+ self.exclusion_cb = FCCheckBox('%s:' % _("Exclusion areas"))
+ self.exclusion_cb.setToolTip(
+ _(
+ "Include exclusion areas.\n"
+ "In those areas the travel of the tools\n"
+ "is forbidden."
)
- ]
+ )
+ grid1.addWidget(self.exclusion_cb, 13, 0, 1, 2)
+
+ # Area Selection shape
+ self.area_shape_label = QtWidgets.QLabel('%s:' % _("Shape"))
+ self.area_shape_label.setToolTip(
+ _("The kind of selection shape used for area selection.")
+ )
+
+ self.area_shape_radio = RadioSet([{'label': _("Square"), 'value': 'square'},
+ {'label': _("Polygon"), 'value': 'polygon'}])
+
+ grid1.addWidget(self.area_shape_label, 14, 0)
+ grid1.addWidget(self.area_shape_radio, 14, 1)
+
+ # Chose Strategy
+ self.strategy_label = FCLabel('%s:' % _("Strategy"))
+ self.strategy_label.setToolTip(_("The strategy followed when encountering an exclusion area.\n"
+ "Can be:\n"
+ "- Over -> when encountering the area, the tool will go to a set height\n"
+ "- Around -> will avoid the exclusion area by going around the area"))
+ self.strategy_radio = RadioSet([{'label': _('Over'), 'value': 'over'},
+ {'label': _('Around'), 'value': 'around'}])
+
+ grid1.addWidget(self.strategy_label, 15, 0)
+ grid1.addWidget(self.strategy_radio, 15, 1)
+
+ # Over Z
+ self.over_z_label = FCLabel('%s:' % _("Over Z"))
+ self.over_z_label.setToolTip(_("The height Z to which the tool will rise in order to avoid\n"
+ "an interdiction area."))
+ self.over_z_entry = FCDoubleSpinner()
+ self.over_z_entry.set_range(0.000, 9999.9999)
+ self.over_z_entry.set_precision(self.decimals)
+
+ grid1.addWidget(self.over_z_label, 18, 0)
+ grid1.addWidget(self.over_z_entry, 18, 1)
+
+ self.layout.addStretch()
diff --git a/flatcamGUI/preferences/geometry/GeometryEditorPrefGroupUI.py b/flatcamGUI/preferences/geometry/GeometryEditorPrefGroupUI.py
index fe861c34..9c5204ab 100644
--- a/flatcamGUI/preferences/geometry/GeometryEditorPrefGroupUI.py
+++ b/flatcamGUI/preferences/geometry/GeometryEditorPrefGroupUI.py
@@ -1,41 +1,67 @@
-from flatcamGUI.preferences.OptionUI import *
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI2
+from PyQt5 import QtWidgets
+from PyQt5.QtCore import QSettings
+
+from flatcamGUI.GUIElements import FCSpinner, RadioSet
+from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
import gettext
import FlatCAMTranslation as fcTranslate
import builtins
+
fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__:
_ = gettext.gettext
+settings = QSettings("Open Source", "FlatCAM")
+if settings.contains("machinist"):
+ machinist_setting = settings.value('machinist', type=int)
+else:
+ machinist_setting = 0
-class GeometryEditorPrefGroupUI(OptionsGroupUI2):
- def __init__(self, decimals=4, **kwargs):
- self.decimals = decimals
- super().__init__(**kwargs)
+class GeometryEditorPrefGroupUI(OptionsGroupUI):
+ def __init__(self, decimals=4, parent=None):
+ # OptionsGroupUI.__init__(self, "Gerber Adv. Options Preferences", parent=parent)
+ super(GeometryEditorPrefGroupUI, self).__init__(self, parent=parent)
+
self.setTitle(str(_("Geometry Editor")))
+ self.decimals = decimals
- def build_options(self) -> [OptionUI]:
- return [
- HeadingOptionUI(label_text="Parameters"),
- SpinnerOptionUI(
- option="geometry_editor_sel_limit",
- label_text="Selection limit",
- label_tooltip="Set the number of selected geometry\n"
- "items above which the utility geometry\n"
- "becomes just a selection rectangle.\n"
- "Increases the performance when moving a\n"
- "large number of geometric elements.",
- min_value=0, max_value=9999, step=1
- ),
- RadioSetOptionUI(
- option="geometry_editor_milling_type",
- label_text="Milling Type",
- label_tooltip="Milling type:\n"
- "- climb / best for precision milling and to reduce tool usage\n"
- "- conventional / useful when there is no backlash compensation",
- choices=[{'label': _('Climb'), 'value': 'cl'},
- {'label': _('Conventional'), 'value': 'cv'}]
- )
- ]
\ No newline at end of file
+ # Advanced Geometry Parameters
+ self.param_label = QtWidgets.QLabel("%s:" % _("Parameters"))
+ self.param_label.setToolTip(
+ _("A list of Geometry Editor parameters.")
+ )
+ self.layout.addWidget(self.param_label)
+
+ grid0 = QtWidgets.QGridLayout()
+ self.layout.addLayout(grid0)
+
+ # Selection Limit
+ self.sel_limit_label = QtWidgets.QLabel('%s:' % _("Selection limit"))
+ self.sel_limit_label.setToolTip(
+ _("Set the number of selected geometry\n"
+ "items above which the utility geometry\n"
+ "becomes just a selection rectangle.\n"
+ "Increases the performance when moving a\n"
+ "large number of geometric elements.")
+ )
+ self.sel_limit_entry = FCSpinner()
+ self.sel_limit_entry.set_range(0, 9999)
+
+ grid0.addWidget(self.sel_limit_label, 0, 0)
+ grid0.addWidget(self.sel_limit_entry, 0, 1)
+
+ # Milling Type
+ milling_type_label = QtWidgets.QLabel('%s:' % _('Milling Type'))
+ milling_type_label.setToolTip(
+ _("Milling type:\n"
+ "- climb / best for precision milling and to reduce tool usage\n"
+ "- conventional / useful when there is no backlash compensation")
+ )
+ self.milling_type_radio = RadioSet([{'label': _('Climb'), 'value': 'cl'},
+ {'label': _('Conventional'), 'value': 'cv'}])
+ grid0.addWidget(milling_type_label, 1, 0)
+ grid0.addWidget(self.milling_type_radio, 1, 1)
+
+ self.layout.addStretch()
diff --git a/flatcamGUI/preferences/geometry/GeometryGenPrefGroupUI.py b/flatcamGUI/preferences/geometry/GeometryGenPrefGroupUI.py
index 1e800702..60479236 100644
--- a/flatcamGUI/preferences/geometry/GeometryGenPrefGroupUI.py
+++ b/flatcamGUI/preferences/geometry/GeometryGenPrefGroupUI.py
@@ -1,5 +1,8 @@
-from flatcamGUI.preferences.OptionUI import *
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI2
+from PyQt5 import QtWidgets, QtCore, QtGui
+from PyQt5.QtCore import QSettings
+
+from flatcamGUI.GUIElements import FCCheckBox, FCSpinner, FCEntry
+from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
import gettext
import FlatCAMTranslation as fcTranslate
@@ -9,46 +12,112 @@ fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__:
_ = gettext.gettext
+settings = QSettings("Open Source", "FlatCAM")
+if settings.contains("machinist"):
+ machinist_setting = settings.value('machinist', type=int)
+else:
+ machinist_setting = 0
-class GeometryGenPrefGroupUI(OptionsGroupUI2):
- def __init__(self, decimals=4, **kwargs):
- self.decimals = decimals
- super().__init__(**kwargs)
+class GeometryGenPrefGroupUI(OptionsGroupUI):
+ def __init__(self, decimals=4, parent=None):
+ # OptionsGroupUI.__init__(self, "Geometry General Preferences", parent=parent)
+ super(GeometryGenPrefGroupUI, self).__init__(self, parent=parent)
+
self.setTitle(str(_("Geometry General")))
+ self.decimals = decimals
- def build_options(self) -> [OptionUI]:
- return [
- HeadingOptionUI(label_text="Plot Options"),
- CheckboxOptionUI(
- option="geometry_plot",
- label_text="Plot",
- label_tooltip="Plot (show) this object."
- ),
- SpinnerOptionUI(
- option="geometry_circle_steps",
- label_text="Circle Steps",
- label_tooltip="The number of circle steps for Geometry \n"
- "circle and arc shapes linear approximation.",
- min_value=0, max_value=9999, step=1
- ),
- HeadingOptionUI(label_text="Tools"),
- LineEntryOptionUI(
- option="geometry_cnctooldia",
- label_text="Tools Dia",
- label_color="green",
- label_bold=True,
- label_tooltip="Diameters of the tools, separated by comma.\n"
- "The value of the diameter has to use the dot decimals separator.\n"
- "Valid values: 0.3, 1.0"
- ),
- SeparatorOptionUI(),
+ # ## Plot options
+ self.plot_options_label = QtWidgets.QLabel("%s:" % _("Plot Options"))
+ self.layout.addWidget(self.plot_options_label)
- HeadingOptionUI(label_text="Geometry Object Color"),
- ColorOptionUI(
- option="geometry_plot_line",
- label_text="Outline",
+ # Plot CB
+ self.plot_cb = FCCheckBox(label=_('Plot'))
+ self.plot_cb.setToolTip(
+ _("Plot (show) this object.")
+ )
+ self.layout.addWidget(self.plot_cb)
- label_tooltip="Set the line color for plotted objects.",
- ),
- ]
+ grid0 = QtWidgets.QGridLayout()
+ self.layout.addLayout(grid0)
+ grid0.setColumnStretch(0, 0)
+ grid0.setColumnStretch(1, 1)
+
+ # Number of circle steps for circular aperture linear approximation
+ self.circle_steps_label = QtWidgets.QLabel('%s:' % _("Circle Steps"))
+ self.circle_steps_label.setToolTip(
+ _("The number of circle steps for Geometry \n"
+ "circle and arc shapes linear approximation.")
+ )
+ self.circle_steps_entry = FCSpinner()
+ self.circle_steps_entry.set_range(0, 999)
+
+ grid0.addWidget(self.circle_steps_label, 1, 0)
+ grid0.addWidget(self.circle_steps_entry, 1, 1)
+
+ # Tools
+ self.tools_label = QtWidgets.QLabel("%s:" % _("Tools"))
+ grid0.addWidget(self.tools_label, 2, 0, 1, 2)
+
+ # Tooldia
+ tdlabel = QtWidgets.QLabel('%s:' % _('Tools Dia'))
+ tdlabel.setToolTip(
+ _("Diameters of the tools, separated by comma.\n"
+ "The value of the diameter has to use the dot decimals separator.\n"
+ "Valid values: 0.3, 1.0")
+ )
+ self.cnctooldia_entry = FCEntry()
+
+ grid0.addWidget(tdlabel, 3, 0)
+ grid0.addWidget(self.cnctooldia_entry, 3, 1)
+
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid0.addWidget(separator_line, 9, 0, 1, 2)
+
+ # Geometry Object Color
+ self.gerber_color_label = QtWidgets.QLabel('%s' % _('Geometry Object Color'))
+ grid0.addWidget(self.gerber_color_label, 10, 0, 1, 2)
+
+ # Plot Line Color
+ self.line_color_label = QtWidgets.QLabel('%s:' % _('Outline'))
+ self.line_color_label.setToolTip(
+ _("Set the line color for plotted objects.")
+ )
+ self.line_color_entry = FCEntry()
+ self.line_color_button = QtWidgets.QPushButton()
+ self.line_color_button.setFixedSize(15, 15)
+
+ self.form_box_child_2 = QtWidgets.QHBoxLayout()
+ self.form_box_child_2.addWidget(self.line_color_entry)
+ self.form_box_child_2.addWidget(self.line_color_button)
+ self.form_box_child_2.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
+
+ grid0.addWidget(self.line_color_label, 11, 0)
+ grid0.addLayout(self.form_box_child_2, 11, 1)
+
+ self.layout.addStretch()
+
+ # Setting plot colors signals
+ self.line_color_entry.editingFinished.connect(self.on_line_color_entry)
+ self.line_color_button.clicked.connect(self.on_line_color_button)
+
+ def on_line_color_entry(self):
+ self.app.defaults['geometry_plot_line'] = self.line_color_entry.get_value()[:7] + 'FF'
+ self.line_color_button.setStyleSheet("background-color:%s" % str(self.app.defaults['geometry_plot_line'])[:7])
+
+ def on_line_color_button(self):
+ current_color = QtGui.QColor(self.app.defaults['geometry_plot_line'][:7])
+ # print(current_color)
+
+ c_dialog = QtWidgets.QColorDialog()
+ plot_line_color = c_dialog.getColor(initial=current_color)
+
+ if plot_line_color.isValid() is False:
+ return
+
+ self.line_color_button.setStyleSheet("background-color:%s" % str(plot_line_color.name()))
+
+ new_val_line = str(plot_line_color.name()) + str(self.app.defaults['geometry_plot_line'][7:9])
+ self.line_color_entry.set_value(new_val_line)
diff --git a/flatcamGUI/preferences/geometry/GeometryOptPrefGroupUI.py b/flatcamGUI/preferences/geometry/GeometryOptPrefGroupUI.py
index 102a9273..c2e0f6e2 100644
--- a/flatcamGUI/preferences/geometry/GeometryOptPrefGroupUI.py
+++ b/flatcamGUI/preferences/geometry/GeometryOptPrefGroupUI.py
@@ -1,13 +1,14 @@
-from PyQt5.QtCore import QSettings
+from PyQt5 import QtWidgets
+from PyQt5.QtCore import Qt, QSettings
-from flatcamGUI.GUIElements import OptionalInputSection
+from flatcamGUI.GUIElements import FCDoubleSpinner, FCCheckBox, OptionalInputSection, FCEntry, FCSpinner, FCComboBox
from flatcamGUI.preferences import machinist_setting
-from flatcamGUI.preferences.OptionUI import *
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI2
+from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
import gettext
import FlatCAMTranslation as fcTranslate
import builtins
+
fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__:
_ = gettext.gettext
@@ -19,135 +20,246 @@ else:
machinist_setting = 0
-class GeometryOptPrefGroupUI(OptionsGroupUI2):
+class GeometryOptPrefGroupUI(OptionsGroupUI):
+ def __init__(self, decimals=4, parent=None):
+ # OptionsGroupUI.__init__(self, "Geometry Options Preferences", parent=parent)
+ super(GeometryOptPrefGroupUI, self).__init__(self, parent=parent)
- def __init__(self, decimals=4, **kwargs):
- self.decimals = decimals
- super().__init__(**kwargs)
self.setTitle(str(_("Geometry Options")))
- self.pp_geometry_name_cb = self.option_dict()["geometry_ppname_g"].get_field()
+ self.decimals = decimals
+
+ # ------------------------------
+ # ## Create CNC Job
+ # ------------------------------
+ self.cncjob_label = QtWidgets.QLabel('%s:' % _('Create CNC Job'))
+ self.cncjob_label.setToolTip(
+ _("Create a CNC Job object\n"
+ "tracing the contours of this\n"
+ "Geometry object.")
+ )
+ self.layout.addWidget(self.cncjob_label)
+
+ grid1 = QtWidgets.QGridLayout()
+ self.layout.addLayout(grid1)
+ grid1.setColumnStretch(0, 0)
+ grid1.setColumnStretch(1, 1)
+
+ # Cut Z
+ cutzlabel = QtWidgets.QLabel('%s:' % _('Cut Z'))
+ cutzlabel.setToolTip(
+ _("Cutting depth (negative)\n"
+ "below the copper surface.")
+ )
+ self.cutz_entry = FCDoubleSpinner()
+
+ if machinist_setting == 0:
+ self.cutz_entry.set_range(-9999.9999, 0.0000)
+ else:
+ self.cutz_entry.set_range(-9999.9999, 9999.9999)
+
+ self.cutz_entry.set_precision(self.decimals)
+ self.cutz_entry.setSingleStep(0.1)
+ self.cutz_entry.setWrapping(True)
+
+ grid1.addWidget(cutzlabel, 0, 0)
+ grid1.addWidget(self.cutz_entry, 0, 1)
+
+ # Multidepth CheckBox
+ self.multidepth_cb = FCCheckBox(label=_('Multi-Depth'))
+ self.multidepth_cb.setToolTip(
+ _(
+ "Use multiple passes to limit\n"
+ "the cut depth in each pass. Will\n"
+ "cut multiple times until Cut Z is\n"
+ "reached."
+ )
+ )
+ grid1.addWidget(self.multidepth_cb, 1, 0)
+
+ # Depth/pass
+ dplabel = QtWidgets.QLabel('%s:' % _('Depth/Pass'))
+ dplabel.setToolTip(
+ _("The depth to cut on each pass,\n"
+ "when multidepth is enabled.\n"
+ "It has positive value although\n"
+ "it is a fraction from the depth\n"
+ "which has negative value.")
+ )
+
+ self.depthperpass_entry = FCDoubleSpinner()
+ self.depthperpass_entry.set_range(0, 99999)
+ self.depthperpass_entry.set_precision(self.decimals)
+ self.depthperpass_entry.setSingleStep(0.1)
+ self.depthperpass_entry.setWrapping(True)
+
+ grid1.addWidget(dplabel, 2, 0)
+ grid1.addWidget(self.depthperpass_entry, 2, 1)
- self.multidepth_cb = self.option_dict()["geometry_multidepth"].get_field()
- self.depthperpass_entry = self.option_dict()["geometry_depthperpass"].get_field()
self.ois_multidepth = OptionalInputSection(self.multidepth_cb, [self.depthperpass_entry])
- self.dwell_cb = self.option_dict()["geometry_dwell"].get_field()
- self.dwelltime_entry = self.option_dict()["geometry_dwelltime"].get_field()
+ # Travel Z
+ travelzlabel = QtWidgets.QLabel('%s:' % _('Travel Z'))
+ travelzlabel.setToolTip(
+ _("Height of the tool when\n"
+ "moving without cutting.")
+ )
+ self.travelz_entry = FCDoubleSpinner()
+
+ if machinist_setting == 0:
+ self.travelz_entry.set_range(0.0001, 9999.9999)
+ else:
+ self.travelz_entry.set_range(-9999.9999, 9999.9999)
+
+ self.travelz_entry.set_precision(self.decimals)
+ self.travelz_entry.setSingleStep(0.1)
+ self.travelz_entry.setWrapping(True)
+
+ grid1.addWidget(travelzlabel, 3, 0)
+ grid1.addWidget(self.travelz_entry, 3, 1)
+
+ # Tool change:
+ self.toolchange_cb = FCCheckBox('%s' % _("Tool change"))
+ self.toolchange_cb.setToolTip(
+ _(
+ "Include tool-change sequence\n"
+ "in the Machine Code (Pause for tool change)."
+ )
+ )
+ grid1.addWidget(self.toolchange_cb, 4, 0, 1, 2)
+
+ # Toolchange Z
+ toolchangezlabel = QtWidgets.QLabel('%s:' % _('Toolchange Z'))
+ toolchangezlabel.setToolTip(
+ _(
+ "Z-axis position (height) for\n"
+ "tool change."
+ )
+ )
+ self.toolchangez_entry = FCDoubleSpinner()
+
+ if machinist_setting == 0:
+ self.toolchangez_entry.set_range(0.000, 9999.9999)
+ else:
+ self.toolchangez_entry.set_range(-9999.9999, 9999.9999)
+
+ self.toolchangez_entry.set_precision(self.decimals)
+ self.toolchangez_entry.setSingleStep(0.1)
+ self.toolchangez_entry.setWrapping(True)
+
+ grid1.addWidget(toolchangezlabel, 5, 0)
+ grid1.addWidget(self.toolchangez_entry, 5, 1)
+
+ # End move Z
+ endz_label = QtWidgets.QLabel('%s:' % _('End move Z'))
+ endz_label.setToolTip(
+ _("Height of the tool after\n"
+ "the last move at the end of the job.")
+ )
+ self.endz_entry = FCDoubleSpinner()
+
+ if machinist_setting == 0:
+ self.endz_entry.set_range(0.000, 9999.9999)
+ else:
+ self.endz_entry.set_range(-9999.9999, 9999.9999)
+
+ self.endz_entry.set_precision(self.decimals)
+ self.endz_entry.setSingleStep(0.1)
+ self.endz_entry.setWrapping(True)
+
+ grid1.addWidget(endz_label, 6, 0)
+ grid1.addWidget(self.endz_entry, 6, 1)
+
+ # End Move X,Y
+ endmove_xy_label = QtWidgets.QLabel('%s:' % _('End move X,Y'))
+ endmove_xy_label.setToolTip(
+ _("End move X,Y position. In format (x,y).\n"
+ "If no value is entered then there is no move\n"
+ "on X,Y plane at the end of the job.")
+ )
+ self.endxy_entry = FCEntry()
+
+ grid1.addWidget(endmove_xy_label, 7, 0)
+ grid1.addWidget(self.endxy_entry, 7, 1)
+
+ # Feedrate X-Y
+ frlabel = QtWidgets.QLabel('%s:' % _('Feedrate X-Y'))
+ frlabel.setToolTip(
+ _("Cutting speed in the XY\n"
+ "plane in units per minute")
+ )
+ self.cncfeedrate_entry = FCDoubleSpinner()
+ self.cncfeedrate_entry.set_range(0, 99999.9999)
+ self.cncfeedrate_entry.set_precision(self.decimals)
+ self.cncfeedrate_entry.setSingleStep(0.1)
+ self.cncfeedrate_entry.setWrapping(True)
+
+ grid1.addWidget(frlabel, 8, 0)
+ grid1.addWidget(self.cncfeedrate_entry, 8, 1)
+
+ # Feedrate Z (Plunge)
+ frz_label = QtWidgets.QLabel('%s:' % _('Feedrate Z'))
+ frz_label.setToolTip(
+ _("Cutting speed in the XY\n"
+ "plane in units per minute.\n"
+ "It is called also Plunge.")
+ )
+ self.feedrate_z_entry = FCDoubleSpinner()
+ self.feedrate_z_entry.set_range(0, 99999.9999)
+ self.feedrate_z_entry.set_precision(self.decimals)
+ self.feedrate_z_entry.setSingleStep(0.1)
+ self.feedrate_z_entry.setWrapping(True)
+
+ grid1.addWidget(frz_label, 9, 0)
+ grid1.addWidget(self.feedrate_z_entry, 9, 1)
+
+ # Spindle Speed
+ spdlabel = QtWidgets.QLabel('%s:' % _('Spindle speed'))
+ spdlabel.setToolTip(
+ _(
+ "Speed of the spindle in RPM (optional).\n"
+ "If LASER preprocessor is used,\n"
+ "this value is the power of laser."
+ )
+ )
+ self.cncspindlespeed_entry = FCSpinner()
+ self.cncspindlespeed_entry.set_range(0, 1000000)
+ self.cncspindlespeed_entry.set_step(100)
+
+ grid1.addWidget(spdlabel, 10, 0)
+ grid1.addWidget(self.cncspindlespeed_entry, 10, 1)
+
+ # Dwell
+ self.dwell_cb = FCCheckBox(label='%s' % _('Enable Dwell'))
+ self.dwell_cb.setToolTip(
+ _("Pause to allow the spindle to reach its\n"
+ "speed before cutting.")
+ )
+ dwelltime = QtWidgets.QLabel('%s:' % _('Duration'))
+ dwelltime.setToolTip(
+ _("Number of time units for spindle to dwell.")
+ )
+ self.dwelltime_entry = FCDoubleSpinner()
+ self.dwelltime_entry.set_range(0, 99999)
+ self.dwelltime_entry.set_precision(self.decimals)
+ self.dwelltime_entry.setSingleStep(0.1)
+ self.dwelltime_entry.setWrapping(True)
+
+ grid1.addWidget(self.dwell_cb, 11, 0)
+ grid1.addWidget(dwelltime, 12, 0)
+ grid1.addWidget(self.dwelltime_entry, 12, 1)
+
self.ois_dwell = OptionalInputSection(self.dwell_cb, [self.dwelltime_entry])
- def build_options(self) -> [OptionUI]:
- return [
- HeadingOptionUI(
- label_text="Create CNC Job",
- label_tooltip="Create a CNC Job object\n"
- "tracing the contours of this\n"
- "Geometry object."
- ),
- DoubleSpinnerOptionUI(
- option="geometry_cutz",
- label_text="Cut Z",
- label_tooltip="Cutting depth (negative)\n"
- "below the copper surface.",
- min_value=-9999.9999, max_value=(9999.999 if machinist_setting else 0.0),
- decimals=self.decimals, step=0.1
- ),
- CheckboxOptionUI(
- option="geometry_multidepth",
- label_text="Multi-Depth",
- label_tooltip="Use multiple passes to limit\n"
- "the cut depth in each pass. Will\n"
- "cut multiple times until Cut Z is\n"
- "reached."
- ),
- DoubleSpinnerOptionUI(
- option="geometry_depthperpass",
- label_text="Depth/Pass",
- label_tooltip="The depth to cut on each pass,\n"
- "when multidepth is enabled.\n"
- "It has positive value although\n"
- "it is a fraction from the depth\n"
- "which has negative value.",
- min_value=0, max_value=99999, step=0.1, decimals=self.decimals
+ # preprocessor selection
+ pp_label = QtWidgets.QLabel('%s:' % _("Preprocessor"))
+ pp_label.setToolTip(
+ _("The Preprocessor file that dictates\n"
+ "the Machine Code (like GCode, RML, HPGL) output.")
+ )
+ self.pp_geometry_name_cb = FCComboBox()
+ self.pp_geometry_name_cb.setFocusPolicy(Qt.StrongFocus)
- ),
- DoubleSpinnerOptionUI(
- option="geometry_travelz",
- label_text="Travel Z",
- label_tooltip="Height of the tool when\n"
- "moving without cutting.",
- min_value=(-9999.9999 if machinist_setting else 0.0001), max_value=9999.9999,
- step=0.1, decimals=self.decimals
- ),
- CheckboxOptionUI(
- option="geometry_toolchange",
- label_text="Tool change",
- label_tooltip="Include tool-change sequence\n"
- "in the Machine Code (Pause for tool change)."
- ),
- DoubleSpinnerOptionUI(
- option="geometry_toolchangez",
- label_text="Toolchange Z",
- label_tooltip="Z-axis position (height) for\n"
- "tool change.",
- min_value=(-9999.9999 if machinist_setting else 0.0), max_value=9999.9999,
- step=0.1, decimals=self.decimals
- ),
- DoubleSpinnerOptionUI(
- option="geometry_endz",
- label_text="End move Z",
- label_tooltip="Height of the tool after\n"
- "the last move at the end of the job.",
- min_value=(-9999.9999 if machinist_setting else 0.0), max_value=9999.9999,
- step=0.1, decimals=self.decimals
- ),
- LineEntryOptionUI(
- option="geometry_endxy",
- label_text="End move X,Y",
- label_tooltip="End move X,Y position. In format (x,y).\n"
- "If no value is entered then there is no move\n"
- "on X,Y plane at the end of the job."
- ),
- DoubleSpinnerOptionUI(
- option="geometry_feedrate",
- label_text="Feedrate X-Y",
- label_tooltip="Cutting speed in the XY\n"
- "plane in units per minute",
- min_value=0, max_value=99999.9999, step=0.1, decimals=self.decimals
- ),
- DoubleSpinnerOptionUI(
- option="geometry_feedrate_z",
- label_text="Feedrate Z",
- label_tooltip="Cutting speed in the XY\n"
- "plane in units per minute.\n"
- "It is called also Plunge.",
- min_value=0, max_value=99999.9999, step=0.1, decimals=self.decimals
- ),
- SpinnerOptionUI(
- option="geometry_spindlespeed",
- label_text="Spindle speed",
- label_tooltip="Speed of the spindle in RPM (optional).\n"
- "If LASER preprocessor is used,\n"
- "this value is the power of laser.",
- min_value=0, max_value=1000000, step=100
- ),
- CheckboxOptionUI(
- option="geometry_dwell",
- label_text="Enable Dwell",
- label_tooltip="Pause to allow the spindle to reach its\n"
- "speed before cutting."
- ),
- DoubleSpinnerOptionUI(
- option="geometry_dwelltime",
- label_text="Duration",
- label_tooltip="Number of time units for spindle to dwell.",
- min_value=0, max_value=999999, step=0.5, decimals=self.decimals
- ),
- ComboboxOptionUI(
- option="geometry_ppname_g",
- label_text="Preprocessor",
- label_tooltip="The Preprocessor file that dictates\n"
- "the Machine Code (like GCode, RML, HPGL) output.",
- choices=[] # Populated in App (FIXME)
- )
- ]
+ grid1.addWidget(pp_label, 13, 0)
+ grid1.addWidget(self.pp_geometry_name_cb, 13, 1)
+ self.layout.addStretch()
diff --git a/flatcamGUI/preferences/geometry/GeometryPreferencesUI.py b/flatcamGUI/preferences/geometry/GeometryPreferencesUI.py
index 643b606d..cf906d61 100644
--- a/flatcamGUI/preferences/geometry/GeometryPreferencesUI.py
+++ b/flatcamGUI/preferences/geometry/GeometryPreferencesUI.py
@@ -1,5 +1,6 @@
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
-from flatcamGUI.preferences.PreferencesSectionUI import PreferencesSectionUI
+from PyQt5 import QtWidgets
+from PyQt5.QtCore import QSettings
+
from flatcamGUI.preferences.geometry.GeometryEditorPrefGroupUI import GeometryEditorPrefGroupUI
from flatcamGUI.preferences.geometry.GeometryAdvOptPrefGroupUI import GeometryAdvOptPrefGroupUI
from flatcamGUI.preferences.geometry.GeometryOptPrefGroupUI import GeometryOptPrefGroupUI
@@ -8,30 +9,38 @@ from flatcamGUI.preferences.geometry.GeometryGenPrefGroupUI import GeometryGenPr
import gettext
import FlatCAMTranslation as fcTranslate
import builtins
+
fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__:
_ = gettext.gettext
+settings = QSettings("Open Source", "FlatCAM")
+if settings.contains("machinist"):
+ machinist_setting = settings.value('machinist', type=int)
+else:
+ machinist_setting = 0
-class GeometryPreferencesUI(PreferencesSectionUI):
- def __init__(self, decimals, **kwargs):
+class GeometryPreferencesUI(QtWidgets.QWidget):
+
+ def __init__(self, decimals, parent=None):
+ QtWidgets.QWidget.__init__(self, parent=parent)
+ self.layout = QtWidgets.QHBoxLayout()
+ self.setLayout(self.layout)
self.decimals = decimals
- # FIXME: remove the need for external access to geometry_opt_group
+
+ self.geometry_gen_group = GeometryGenPrefGroupUI(decimals=self.decimals)
+ self.geometry_gen_group.setMinimumWidth(220)
self.geometry_opt_group = GeometryOptPrefGroupUI(decimals=self.decimals)
- super().__init__(**kwargs)
+ self.geometry_opt_group.setMinimumWidth(300)
+ self.geometry_adv_opt_group = GeometryAdvOptPrefGroupUI(decimals=self.decimals)
+ self.geometry_adv_opt_group.setMinimumWidth(270)
+ self.geometry_editor_group = GeometryEditorPrefGroupUI(decimals=self.decimals)
+ self.geometry_editor_group.setMinimumWidth(250)
- def build_groups(self) -> [OptionsGroupUI]:
- return [
- GeometryGenPrefGroupUI(decimals=self.decimals),
- self.geometry_opt_group,
- GeometryAdvOptPrefGroupUI(decimals=self.decimals),
- GeometryEditorPrefGroupUI(decimals=self.decimals)
- ]
-
- def get_tab_id(self):
- return "geometry_tab"
-
- def get_tab_label(self):
- return _("GEOMETRY")
+ self.layout.addWidget(self.geometry_gen_group)
+ self.layout.addWidget(self.geometry_opt_group)
+ self.layout.addWidget(self.geometry_adv_opt_group)
+ self.layout.addWidget(self.geometry_editor_group)
+ self.layout.addStretch()
diff --git a/flatcamGUI/preferences/gerber/GerberAdvOptPrefGroupUI.py b/flatcamGUI/preferences/gerber/GerberAdvOptPrefGroupUI.py
index af9f28c8..20376bfd 100644
--- a/flatcamGUI/preferences/gerber/GerberAdvOptPrefGroupUI.py
+++ b/flatcamGUI/preferences/gerber/GerberAdvOptPrefGroupUI.py
@@ -1,6 +1,8 @@
-from flatcamGUI.GUIElements import OptionalInputSection
-from flatcamGUI.preferences.OptionUI import *
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI2
+from PyQt5 import QtWidgets
+from PyQt5.QtCore import QSettings
+
+from flatcamGUI.GUIElements import FCCheckBox, RadioSet, FCDoubleSpinner, FCSpinner, OptionalInputSection
+from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
import gettext
import FlatCAMTranslation as fcTranslate
@@ -10,113 +12,175 @@ fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__:
_ = gettext.gettext
+settings = QSettings("Open Source", "FlatCAM")
+if settings.contains("machinist"):
+ machinist_setting = settings.value('machinist', type=int)
+else:
+ machinist_setting = 0
-class GerberAdvOptPrefGroupUI(OptionsGroupUI2):
- def __init__(self, decimals=4, **kwargs):
- self.decimals = decimals
- super().__init__(**kwargs)
+class GerberAdvOptPrefGroupUI(OptionsGroupUI):
+ def __init__(self, decimals=4, parent=None):
+ # OptionsGroupUI.__init__(self, "Gerber Adv. Options Preferences", parent=parent)
+ super(GerberAdvOptPrefGroupUI, self).__init__(self, parent=parent)
+
self.setTitle(str(_("Gerber Adv. Options")))
+ self.decimals = decimals
- self.simplify_cb = self.option_dict()["gerber_simplification"].get_field()
- self.simplification_tol_label = self.option_dict()["gerber_simp_tolerance"].label_widget
- self.simplification_tol_spinner = self.option_dict()["gerber_simp_tolerance"].get_field()
- self.ois_simplif = OptionalInputSection(self.simplify_cb, [self.simplification_tol_label, self.simplification_tol_spinner], logic=True)
+ # ## Advanced Gerber Parameters
+ self.adv_param_label = QtWidgets.QLabel('%s:' % _('Advanced Options'))
+ self.adv_param_label.setToolTip(
+ _("A list of Gerber advanced parameters.\n"
+ "Those parameters are available only for\n"
+ "Advanced App. Level.")
+ )
+ self.layout.addWidget(self.adv_param_label)
- def build_options(self) -> [OptionUI]:
- return [
- HeadingOptionUI(
- label_text="Advanced Options",
- label_tooltip="A list of Gerber advanced parameters.\n"
- "Those parameters are available only for\n"
- "Advanced App. Level."
- ),
- CheckboxOptionUI(
- option="gerber_follow",
- label_text='"Follow"',
- label_tooltip="Generate a 'Follow' geometry.\n"
- "This means that it will cut through\n"
- "the middle of the trace."
- ),
- CheckboxOptionUI(
- option="gerber_aperture_display",
- label_text="Table Show/Hide",
- label_tooltip="Toggle the display of the Gerber Apertures Table.\n"
- "Also, on hide, it will delete all mark shapes\n"
- "that are drawn on canvas."
- ),
- SeparatorOptionUI(),
+ grid0 = QtWidgets.QGridLayout()
+ self.layout.addLayout(grid0)
- RadioSetOptionUI(
- option="gerber_tool_type",
- label_text="Tool Type",
- label_bold=True,
- label_tooltip="Choose which tool to use for Gerber isolation:\n"
- "'Circular' or 'V-shape'.\n"
- "When the 'V-shape' is selected then the tool\n"
- "diameter will depend on the chosen cut depth.",
- choices=[{'label': 'Circular', 'value': 'circular'},
- {'label': 'V-Shape', 'value': 'v'}]
- ),
- DoubleSpinnerOptionUI(
- option="gerber_vtipdia",
- label_text="V-Tip Dia",
- label_tooltip="The tip diameter for V-Shape Tool",
- min_value=-99.9999, max_value=99.9999, step=0.1, decimals=self.decimals
- ),
- SpinnerOptionUI(
- option="gerber_vtipangle",
- label_text="V-Tip Angle",
- label_tooltip="The tip angle for V-Shape Tool.\n"
- "In degrees.",
- min_value=1, max_value=180, step=5
- ),
- DoubleSpinnerOptionUI(
- option="gerber_vcutz",
- label_text="Cut Z",
- label_tooltip="Cutting depth (negative)\n"
- "below the copper surface.",
- min_value=-99.9999, max_value=0.0000, step=0.1, decimals=self.decimals
- ),
+ # Follow Attribute
+ self.follow_cb = FCCheckBox(label=_('"Follow"'))
+ self.follow_cb.setToolTip(
+ _("Generate a 'Follow' geometry.\n"
+ "This means that it will cut through\n"
+ "the middle of the trace.")
+ )
+ grid0.addWidget(self.follow_cb, 0, 0, 1, 2)
- RadioSetOptionUI(
- option="gerber_iso_type",
- label_text="Isolation Type",
- label_tooltip="Choose how the isolation will be executed:\n"
- "- 'Full' -> complete isolation of polygons\n"
- "- 'Ext' -> will isolate only on the outside\n"
- "- 'Int' -> will isolate only on the inside\n"
- "'Exterior' isolation is almost always possible\n"
- "(with the right tool) but 'Interior'\n"
- "isolation can be done only when there is an opening\n"
- "inside of the polygon (e.g polygon is a 'doughnut' shape).",
- choices=[{'label': _('Full'), 'value': 'full'},
- {'label': _('Exterior'), 'value': 'ext'},
- {'label': _('Interior'), 'value': 'int'}]
- ),
- SeparatorOptionUI(),
+ # Aperture Table Visibility CB
+ self.aperture_table_visibility_cb = FCCheckBox(label=_('Table Show/Hide'))
+ self.aperture_table_visibility_cb.setToolTip(
+ _("Toggle the display of the Gerber Apertures Table.\n"
+ "Also, on hide, it will delete all mark shapes\n"
+ "that are drawn on canvas.")
- RadioSetOptionUI(
- option="gerber_buffering",
- label_text="Buffering",
- label_tooltip="Buffering type:\n"
- "- None --> best performance, fast file loading but no so good display\n"
- "- Full --> slow file loading but good visuals. This is the default.\n"
- "<>: Don't change this unless you know what you are doing !!!",
- choices=[{'label': _('None'), 'value': 'no'},
- {'label': _('Full'), 'value': 'full'}]
- ),
- CheckboxOptionUI(
- option="gerber_simplification",
- label_text="Simplify",
- label_tooltip="When checked all the Gerber polygons will be\n"
- "loaded with simplification having a set tolerance.\n"
- "<>: Don't change this unless you know what you are doing !!!"
- ),
- DoubleSpinnerOptionUI(
- option="gerber_simp_tolerance",
- label_text="Tolerance",
- label_tooltip="Tolerance for polygon simplification.",
- min_value=0.0, max_value=0.01, step=0.0001, decimals=self.decimals+1
- )
- ]
\ No newline at end of file
+ )
+ grid0.addWidget(self.aperture_table_visibility_cb, 1, 0, 1, 2)
+
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid0.addWidget(separator_line, 2, 0, 1, 2)
+
+ # Tool Type
+ self.tool_type_label = QtWidgets.QLabel('%s' % _('Tool Type'))
+ self.tool_type_label.setToolTip(
+ _("Choose which tool to use for Gerber isolation:\n"
+ "'Circular' or 'V-shape'.\n"
+ "When the 'V-shape' is selected then the tool\n"
+ "diameter will depend on the chosen cut depth.")
+ )
+ self.tool_type_radio = RadioSet([{'label': 'Circular', 'value': 'circular'},
+ {'label': 'V-Shape', 'value': 'v'}])
+
+ grid0.addWidget(self.tool_type_label, 3, 0)
+ grid0.addWidget(self.tool_type_radio, 3, 1, 1, 2)
+
+ # Tip Dia
+ self.tipdialabel = QtWidgets.QLabel('%s:' % _('V-Tip Dia'))
+ self.tipdialabel.setToolTip(
+ _("The tip diameter for V-Shape Tool")
+ )
+ self.tipdia_spinner = FCDoubleSpinner()
+ self.tipdia_spinner.set_precision(self.decimals)
+ self.tipdia_spinner.set_range(-99.9999, 99.9999)
+ self.tipdia_spinner.setSingleStep(0.1)
+ self.tipdia_spinner.setWrapping(True)
+ grid0.addWidget(self.tipdialabel, 4, 0)
+ grid0.addWidget(self.tipdia_spinner, 4, 1, 1, 2)
+
+ # Tip Angle
+ self.tipanglelabel = QtWidgets.QLabel('%s:' % _('V-Tip Angle'))
+ self.tipanglelabel.setToolTip(
+ _("The tip angle for V-Shape Tool.\n"
+ "In degree.")
+ )
+ self.tipangle_spinner = FCSpinner()
+ self.tipangle_spinner.set_range(1, 180)
+ self.tipangle_spinner.set_step(5)
+ self.tipangle_spinner.setWrapping(True)
+ grid0.addWidget(self.tipanglelabel, 5, 0)
+ grid0.addWidget(self.tipangle_spinner, 5, 1, 1, 2)
+
+ # Cut Z
+ self.cutzlabel = QtWidgets.QLabel('%s:' % _('Cut Z'))
+ self.cutzlabel.setToolTip(
+ _("Cutting depth (negative)\n"
+ "below the copper surface.")
+ )
+ self.cutz_spinner = FCDoubleSpinner()
+ self.cutz_spinner.set_precision(self.decimals)
+ self.cutz_spinner.set_range(-99.9999, 0.0000)
+ self.cutz_spinner.setSingleStep(0.1)
+ self.cutz_spinner.setWrapping(True)
+
+ grid0.addWidget(self.cutzlabel, 6, 0)
+ grid0.addWidget(self.cutz_spinner, 6, 1, 1, 2)
+
+ # Isolation Type
+ self.iso_type_label = QtWidgets.QLabel('%s:' % _('Isolation Type'))
+ self.iso_type_label.setToolTip(
+ _("Choose how the isolation will be executed:\n"
+ "- 'Full' -> complete isolation of polygons\n"
+ "- 'Ext' -> will isolate only on the outside\n"
+ "- 'Int' -> will isolate only on the inside\n"
+ "'Exterior' isolation is almost always possible\n"
+ "(with the right tool) but 'Interior'\n"
+ "isolation can be done only when there is an opening\n"
+ "inside of the polygon (e.g polygon is a 'doughnut' shape).")
+ )
+ self.iso_type_radio = RadioSet([{'label': _('Full'), 'value': 'full'},
+ {'label': _('Exterior'), 'value': 'ext'},
+ {'label': _('Interior'), 'value': 'int'}])
+
+ grid0.addWidget(self.iso_type_label, 7, 0,)
+ grid0.addWidget(self.iso_type_radio, 7, 1, 1, 2)
+
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid0.addWidget(separator_line, 8, 0, 1, 2)
+
+ # Buffering Type
+ buffering_label = QtWidgets.QLabel('%s:' % _('Buffering'))
+ buffering_label.setToolTip(
+ _("Buffering type:\n"
+ "- None --> best performance, fast file loading but no so good display\n"
+ "- Full --> slow file loading but good visuals. This is the default.\n"
+ "<>: Don't change this unless you know what you are doing !!!")
+ )
+ self.buffering_radio = RadioSet([{'label': _('None'), 'value': 'no'},
+ {'label': _('Full'), 'value': 'full'}])
+ grid0.addWidget(buffering_label, 9, 0)
+ grid0.addWidget(self.buffering_radio, 9, 1)
+
+ # Simplification
+ self.simplify_cb = FCCheckBox(label=_('Simplify'))
+ self.simplify_cb.setToolTip(
+ _("When checked all the Gerber polygons will be\n"
+ "loaded with simplification having a set tolerance.\n"
+ "<>: Don't change this unless you know what you are doing !!!")
+ )
+ grid0.addWidget(self.simplify_cb, 10, 0, 1, 2)
+
+ # Simplification tolerance
+ self.simplification_tol_label = QtWidgets.QLabel(_('Tolerance'))
+ self.simplification_tol_label.setToolTip(_("Tolerance for polygon simplification."))
+
+ self.simplification_tol_spinner = FCDoubleSpinner()
+ self.simplification_tol_spinner.set_precision(self.decimals + 1)
+ self.simplification_tol_spinner.setWrapping(True)
+ self.simplification_tol_spinner.setRange(0.00000, 0.01000)
+ self.simplification_tol_spinner.setSingleStep(0.0001)
+
+ grid0.addWidget(self.simplification_tol_label, 11, 0)
+ grid0.addWidget(self.simplification_tol_spinner, 11, 1)
+ self.ois_simplif = OptionalInputSection(
+ self.simplify_cb,
+ [
+ self.simplification_tol_label, self.simplification_tol_spinner
+ ],
+ logic=True)
+
+ self.layout.addStretch()
diff --git a/flatcamGUI/preferences/gerber/GerberEditorPrefGroupUI.py b/flatcamGUI/preferences/gerber/GerberEditorPrefGroupUI.py
index 2b9bd49e..3ba0da99 100644
--- a/flatcamGUI/preferences/gerber/GerberEditorPrefGroupUI.py
+++ b/flatcamGUI/preferences/gerber/GerberEditorPrefGroupUI.py
@@ -1,138 +1,247 @@
-from flatcamGUI.preferences.OptionUI import *
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI2
+from PyQt5 import QtWidgets
+from PyQt5.QtCore import QSettings
+
+from flatcamGUI.GUIElements import FCSpinner, FCDoubleSpinner, FCComboBox, FCEntry, RadioSet
+from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
import gettext
import FlatCAMTranslation as fcTranslate
import builtins
+
fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__:
_ = gettext.gettext
+settings = QSettings("Open Source", "FlatCAM")
+if settings.contains("machinist"):
+ machinist_setting = settings.value('machinist', type=int)
+else:
+ machinist_setting = 0
-class GerberEditorPrefGroupUI(OptionsGroupUI2):
- def __init__(self, decimals=4, **kwargs):
- self.decimals = decimals
- super().__init__(**kwargs)
+class GerberEditorPrefGroupUI(OptionsGroupUI):
+ def __init__(self, decimals=4, parent=None):
+ # OptionsGroupUI.__init__(self, "Gerber Adv. Options Preferences", parent=parent)
+ super(GerberEditorPrefGroupUI, self).__init__(self, parent=parent)
+
self.setTitle(str(_("Gerber Editor")))
+ self.decimals = decimals
- def build_options(self) -> [OptionUI]:
- return [
- HeadingOptionUI(
- label_text="Parameters",
- label_tooltip="A list of Gerber Editor parameters."
- ),
- SpinnerOptionUI(
- option="gerber_editor_sel_limit",
- label_text="Selection limit",
- label_tooltip="Set the number of selected Gerber geometry\n"
- "items above which the utility geometry\n"
- "becomes just a selection rectangle.\n"
- "Increases the performance when moving a\n"
- "large number of geometric elements.",
- min_value=0, max_value=9999, step=1
- ),
- SpinnerOptionUI(
- option="gerber_editor_newcode",
- label_text="New Aperture code",
- label_tooltip="Code for the new aperture",
- min_value=10, max_value=99, step=1
- ),
- DoubleSpinnerOptionUI(
- option="gerber_editor_newsize",
- label_text="New Aperture size",
- label_tooltip="Size for the new aperture",
- min_value=0.0, max_value=100.0, step=0.1, decimals=self.decimals
- ),
- ComboboxOptionUI(
- option="gerber_editor_newtype",
- label_text="New Aperture type",
- label_tooltip="Type for the new aperture.\n"
- "Can be 'C', 'R' or 'O'.",
- choices=['C', 'R', 'O']
- ),
- SpinnerOptionUI(
- option="gerber_editor_array_size",
- label_text="Nr of pads",
- label_tooltip="Specify how many pads to be in the array.",
- min_value=0, max_value=9999, step=1
- ),
- LineEntryOptionUI(
- option="gerber_editor_newdim",
- label_text="Aperture Dimensions",
- label_tooltip="Diameters of the tools, separated by comma.\n"
- "The value of the diameter has to use the dot decimals separator.\n"
- "Valid values: 0.3, 1.0"
- ),
+ # Advanced Gerber Parameters
+ self.param_label = QtWidgets.QLabel("%s:" % _("Parameters"))
+ self.param_label.setToolTip(
+ _("A list of Gerber Editor parameters.")
+ )
+ self.layout.addWidget(self.param_label)
- HeadingOptionUI(label_text="Linear Pad Array"),
- RadioSetOptionUI(
- option="gerber_editor_lin_axis",
- label_text="Linear Direction",
- label_tooltip="Direction on which the linear array is oriented:\n"
- "- 'X' - horizontal axis \n"
- "- 'Y' - vertical axis or \n"
- "- 'Angle' - a custom angle for the array inclination",
- choices=[{'label': _('X'), 'value': 'X'},
- {'label': _('Y'), 'value': 'Y'},
- {'label': _('Angle'), 'value': 'A'}]
- ),
- DoubleSpinnerOptionUI(
- option="gerber_editor_lin_pitch",
- label_text="Pitch",
- label_tooltip="Pitch = Distance between elements of the array.",
- min_value=-9999.99, max_value=9999.99, step=0.1, decimals=self.decimals
- ),
- DoubleSpinnerOptionUI(
- option="gerber_editor_lin_angle",
- label_text="Angle",
- label_tooltip="Angle at which each element in circular array is placed.", # FIXME: this seems wrong
- min_value=-360, max_value=360, step=5, decimals=self.decimals
- ),
+ grid0 = QtWidgets.QGridLayout()
+ self.layout.addLayout(grid0)
- HeadingOptionUI(label_text="Circular Pad Array"),
- RadioSetOptionUI(
- option="gerber_editor_circ_dir",
- label_text="Circular Direction",
- label_tooltip="Direction for circular array.\n"
- "Can be CW = clockwise or CCW = counter clockwise.",
- choices=[{'label': _('CW'), 'value': 'CW'},
- {'label': _('CCW'), 'value': 'CCW'}]
- ),
- DoubleSpinnerOptionUI(
- option="gerber_editor_circ_angle",
- label_text="Circular Angle",
- label_tooltip="Angle at which each element in circular array is placed.",
- min_value=-360, max_value=360, step=5, decimals=self.decimals
- ),
+ # Selection Limit
+ self.sel_limit_label = QtWidgets.QLabel('%s:' % _("Selection limit"))
+ self.sel_limit_label.setToolTip(
+ _("Set the number of selected Gerber geometry\n"
+ "items above which the utility geometry\n"
+ "becomes just a selection rectangle.\n"
+ "Increases the performance when moving a\n"
+ "large number of geometric elements.")
+ )
+ self.sel_limit_entry = FCSpinner()
+ self.sel_limit_entry.set_range(0, 9999)
- HeadingOptionUI(label_text="Buffer Tool"),
- DoubleSpinnerOptionUI(
- option="gerber_editor_buff_f",
- label_text="Buffer distance",
- label_tooltip="Distance at which to buffer the Gerber element.",
- min_value=-9999, max_value=9999, step=0.1, decimals=self.decimals
- ),
+ grid0.addWidget(self.sel_limit_label, 0, 0)
+ grid0.addWidget(self.sel_limit_entry, 0, 1)
- HeadingOptionUI(label_text="Scale Tool"),
- DoubleSpinnerOptionUI(
- option="gerber_editor_scale_f",
- label_text="Scale factor",
- label_tooltip="Factor to scale the Gerber element.",
- min_value=0, max_value=9999, step=0.1, decimals=self.decimals
- ),
+ # New aperture code
+ self.addcode_entry_lbl = QtWidgets.QLabel('%s:' % _('New Aperture code'))
+ self.addcode_entry_lbl.setToolTip(
+ _("Code for the new aperture")
+ )
- HeadingOptionUI(label_text="Mark Area Tool"),
- DoubleSpinnerOptionUI(
- option="gerber_editor_ma_low",
- label_text="Threshold low",
- label_tooltip="Threshold value under which the apertures are not marked.",
- min_value=0, max_value=9999, step=0.1, decimals=self.decimals
- ),
- DoubleSpinnerOptionUI(
- option="gerber_editor_ma_high",
- label_text="Threshold high",
- label_tooltip="Threshold value over which the apertures are not marked.",
- min_value=0, max_value=9999, step=0.1, decimals=self.decimals
- )
- ]
+ self.addcode_entry = FCSpinner()
+ self.addcode_entry.set_range(10, 99)
+ self.addcode_entry.setWrapping(True)
+
+ grid0.addWidget(self.addcode_entry_lbl, 1, 0)
+ grid0.addWidget(self.addcode_entry, 1, 1)
+
+ # New aperture size
+ self.addsize_entry_lbl = QtWidgets.QLabel('%s:' % _('New Aperture size'))
+ self.addsize_entry_lbl.setToolTip(
+ _("Size for the new aperture")
+ )
+
+ self.addsize_entry = FCDoubleSpinner()
+ self.addsize_entry.set_range(0, 100)
+ self.addsize_entry.set_precision(self.decimals)
+
+ grid0.addWidget(self.addsize_entry_lbl, 2, 0)
+ grid0.addWidget(self.addsize_entry, 2, 1)
+
+ # New aperture type
+ self.addtype_combo_lbl = QtWidgets.QLabel('%s:' % _('New Aperture type'))
+ self.addtype_combo_lbl.setToolTip(
+ _("Type for the new aperture.\n"
+ "Can be 'C', 'R' or 'O'.")
+ )
+
+ self.addtype_combo = FCComboBox()
+ self.addtype_combo.addItems(['C', 'R', 'O'])
+
+ grid0.addWidget(self.addtype_combo_lbl, 3, 0)
+ grid0.addWidget(self.addtype_combo, 3, 1)
+
+ # Number of pads in a pad array
+ self.grb_array_size_label = QtWidgets.QLabel('%s:' % _('Nr of pads'))
+ self.grb_array_size_label.setToolTip(
+ _("Specify how many pads to be in the array.")
+ )
+
+ self.grb_array_size_entry = FCSpinner()
+ self.grb_array_size_entry.set_range(0, 9999)
+
+ grid0.addWidget(self.grb_array_size_label, 4, 0)
+ grid0.addWidget(self.grb_array_size_entry, 4, 1)
+
+ self.adddim_label = QtWidgets.QLabel('%s:' % _('Aperture Dimensions'))
+ self.adddim_label.setToolTip(
+ _("Diameters of the tools, separated by comma.\n"
+ "The value of the diameter has to use the dot decimals separator.\n"
+ "Valid values: 0.3, 1.0")
+ )
+ grid0.addWidget(self.adddim_label, 5, 0)
+ self.adddim_entry = FCEntry()
+ grid0.addWidget(self.adddim_entry, 5, 1)
+
+ self.grb_array_linear_label = QtWidgets.QLabel('%s:' % _('Linear Pad Array'))
+ grid0.addWidget(self.grb_array_linear_label, 6, 0, 1, 2)
+
+ # Linear Pad Array direction
+ self.grb_axis_label = QtWidgets.QLabel('%s:' % _('Linear Direction'))
+ self.grb_axis_label.setToolTip(
+ _("Direction on which the linear array is oriented:\n"
+ "- 'X' - horizontal axis \n"
+ "- 'Y' - vertical axis or \n"
+ "- 'Angle' - a custom angle for the array inclination")
+ )
+
+ self.grb_axis_radio = RadioSet([{'label': _('X'), 'value': 'X'},
+ {'label': _('Y'), 'value': 'Y'},
+ {'label': _('Angle'), 'value': 'A'}])
+
+ grid0.addWidget(self.grb_axis_label, 7, 0)
+ grid0.addWidget(self.grb_axis_radio, 7, 1)
+
+ # Linear Pad Array pitch distance
+ self.grb_pitch_label = QtWidgets.QLabel('%s:' % _('Pitch'))
+ self.grb_pitch_label.setToolTip(
+ _("Pitch = Distance between elements of the array.")
+ )
+ # self.drill_pitch_label.setMinimumWidth(100)
+ self.grb_pitch_entry = FCDoubleSpinner()
+ self.grb_pitch_entry.set_precision(self.decimals)
+
+ grid0.addWidget(self.grb_pitch_label, 8, 0)
+ grid0.addWidget(self.grb_pitch_entry, 8, 1)
+
+ # Linear Pad Array custom angle
+ self.grb_angle_label = QtWidgets.QLabel('%s:' % _('Angle'))
+ self.grb_angle_label.setToolTip(
+ _("Angle at which each element in circular array is placed.")
+ )
+ self.grb_angle_entry = FCDoubleSpinner()
+ self.grb_angle_entry.set_precision(self.decimals)
+ self.grb_angle_entry.set_range(-360, 360)
+ self.grb_angle_entry.setSingleStep(5)
+
+ grid0.addWidget(self.grb_angle_label, 9, 0)
+ grid0.addWidget(self.grb_angle_entry, 9, 1)
+
+ self.grb_array_circ_label = QtWidgets.QLabel('%s:' % _('Circular Pad Array'))
+ grid0.addWidget(self.grb_array_circ_label, 10, 0, 1, 2)
+
+ # Circular Pad Array direction
+ self.grb_circular_direction_label = QtWidgets.QLabel('%s:' % _('Circular Direction'))
+ self.grb_circular_direction_label.setToolTip(
+ _("Direction for circular array.\n"
+ "Can be CW = clockwise or CCW = counter clockwise.")
+ )
+
+ self.grb_circular_dir_radio = RadioSet([{'label': _('CW'), 'value': 'CW'},
+ {'label': _('CCW'), 'value': 'CCW'}])
+
+ grid0.addWidget(self.grb_circular_direction_label, 11, 0)
+ grid0.addWidget(self.grb_circular_dir_radio, 11, 1)
+
+ # Circular Pad Array Angle
+ self.grb_circular_angle_label = QtWidgets.QLabel('%s:' % _('Circular Angle'))
+ self.grb_circular_angle_label.setToolTip(
+ _("Angle at which each element in circular array is placed.")
+ )
+ self.grb_circular_angle_entry = FCDoubleSpinner()
+ self.grb_circular_angle_entry.set_precision(self.decimals)
+ self.grb_circular_angle_entry.set_range(-360, 360)
+
+ self.grb_circular_angle_entry.setSingleStep(5)
+
+ grid0.addWidget(self.grb_circular_angle_label, 12, 0)
+ grid0.addWidget(self.grb_circular_angle_entry, 12, 1)
+
+ self.grb_array_tools_b_label = QtWidgets.QLabel('%s:' % _('Buffer Tool'))
+ grid0.addWidget(self.grb_array_tools_b_label, 13, 0, 1, 2)
+
+ # Buffer Distance
+ self.grb_buff_label = QtWidgets.QLabel('%s:' % _('Buffer distance'))
+ self.grb_buff_label.setToolTip(
+ _("Distance at which to buffer the Gerber element.")
+ )
+ self.grb_buff_entry = FCDoubleSpinner()
+ self.grb_buff_entry.set_precision(self.decimals)
+ self.grb_buff_entry.set_range(-9999, 9999)
+
+ grid0.addWidget(self.grb_buff_label, 14, 0)
+ grid0.addWidget(self.grb_buff_entry, 14, 1)
+
+ self.grb_array_tools_s_label = QtWidgets.QLabel('%s:' % _('Scale Tool'))
+ grid0.addWidget(self.grb_array_tools_s_label, 15, 0, 1, 2)
+
+ # Scale Factor
+ self.grb_scale_label = QtWidgets.QLabel('%s:' % _('Scale factor'))
+ self.grb_scale_label.setToolTip(
+ _("Factor to scale the Gerber element.")
+ )
+ self.grb_scale_entry = FCDoubleSpinner()
+ self.grb_scale_entry.set_precision(self.decimals)
+ self.grb_scale_entry.set_range(0, 9999)
+
+ grid0.addWidget(self.grb_scale_label, 16, 0)
+ grid0.addWidget(self.grb_scale_entry, 16, 1)
+
+ self.grb_array_tools_ma_label = QtWidgets.QLabel('%s:' % _('Mark Area Tool'))
+ grid0.addWidget(self.grb_array_tools_ma_label, 17, 0, 1, 2)
+
+ # Mark area Tool low threshold
+ self.grb_ma_low_label = QtWidgets.QLabel('%s:' % _('Threshold low'))
+ self.grb_ma_low_label.setToolTip(
+ _("Threshold value under which the apertures are not marked.")
+ )
+ self.grb_ma_low_entry = FCDoubleSpinner()
+ self.grb_ma_low_entry.set_precision(self.decimals)
+ self.grb_ma_low_entry.set_range(0, 9999)
+
+ grid0.addWidget(self.grb_ma_low_label, 18, 0)
+ grid0.addWidget(self.grb_ma_low_entry, 18, 1)
+
+ # Mark area Tool high threshold
+ self.grb_ma_high_label = QtWidgets.QLabel('%s:' % _('Threshold high'))
+ self.grb_ma_high_label.setToolTip(
+ _("Threshold value over which the apertures are not marked.")
+ )
+ self.grb_ma_high_entry = FCDoubleSpinner()
+ self.grb_ma_high_entry.set_precision(self.decimals)
+ self.grb_ma_high_entry.set_range(0, 9999)
+
+ grid0.addWidget(self.grb_ma_high_label, 19, 0)
+ grid0.addWidget(self.grb_ma_high_entry, 19, 1)
+
+ self.layout.addStretch()
diff --git a/flatcamGUI/preferences/gerber/GerberExpPrefGroupUI.py b/flatcamGUI/preferences/gerber/GerberExpPrefGroupUI.py
index e6e85fb6..01729dc5 100644
--- a/flatcamGUI/preferences/gerber/GerberExpPrefGroupUI.py
+++ b/flatcamGUI/preferences/gerber/GerberExpPrefGroupUI.py
@@ -1,5 +1,8 @@
-from flatcamGUI.preferences.OptionUI import *
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI2
+from PyQt5 import QtWidgets, QtCore
+from PyQt5.QtCore import QSettings
+
+from flatcamGUI.GUIElements import RadioSet, FCSpinner
+from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
import gettext
import FlatCAMTranslation as fcTranslate
@@ -9,49 +12,107 @@ fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__:
_ = gettext.gettext
+settings = QSettings("Open Source", "FlatCAM")
+if settings.contains("machinist"):
+ machinist_setting = settings.value('machinist', type=int)
+else:
+ machinist_setting = 0
-class GerberExpPrefGroupUI(OptionsGroupUI2):
- def __init__(self, decimals=4, **kwargs):
- self.decimals = decimals
- super().__init__(**kwargs)
+class GerberExpPrefGroupUI(OptionsGroupUI):
+
+ def __init__(self, decimals=4, parent=None):
+ super(GerberExpPrefGroupUI, self).__init__(self, parent=parent)
+
self.setTitle(str(_("Gerber Export")))
+ self.decimals = decimals
- def build_options(self) -> [OptionUI]:
- return [
- HeadingOptionUI(
- label_text="Export Options",
- label_tooltip="The parameters set here are used in the file exported\n"
- "when using the File -> Export -> Export Gerber menu entry."
- ),
- RadioSetOptionUI(
- option="gerber_exp_units",
- label_text="Units",
- label_tooltip="The units used in the Gerber file.",
- choices=[{'label': _('INCH'), 'value': 'IN'},
- {'label': _('MM'), 'value': 'MM'}]
- ),
- SpinnerOptionUI(
- option="gerber_exp_integer",
- label_text="Int",
- label_tooltip="The number of digits in the whole part of Gerber coordinates",
- min_value=0, max_value=9, step=1
- ),
- SpinnerOptionUI(
- option="gerber_exp_decimals",
- label_text="Decimals",
- label_tooltip="The number of digits in the decimal part of Gerber coordinates",
- min_value=0, max_value=9, step=1
- ),
- RadioSetOptionUI(
- option="gerber_exp_zeros",
- label_text="Zeros",
- label_tooltip="This sets the type of Gerber zeros.\n"
- "If LZ then Leading Zeros are removed and\n"
- "Trailing Zeros are kept.\n"
- "If TZ is checked then Trailing Zeros are removed\n"
- "and Leading Zeros are kept.",
- choices=[{'label': _('LZ'), 'value': 'L'},
- {'label': _('TZ'), 'value': 'T'}]
- )
- ]
\ No newline at end of file
+ # Plot options
+ self.export_options_label = QtWidgets.QLabel("%s:" % _("Export Options"))
+ self.export_options_label.setToolTip(
+ _("The parameters set here are used in the file exported\n"
+ "when using the File -> Export -> Export Gerber menu entry.")
+ )
+ self.layout.addWidget(self.export_options_label)
+
+ form = QtWidgets.QFormLayout()
+ self.layout.addLayout(form)
+
+ # Gerber Units
+ self.gerber_units_label = QtWidgets.QLabel('%s:' % _('Units'))
+ self.gerber_units_label.setToolTip(
+ _("The units used in the Gerber file.")
+ )
+
+ self.gerber_units_radio = RadioSet([{'label': _('INCH'), 'value': 'IN'},
+ {'label': _('MM'), 'value': 'MM'}])
+ self.gerber_units_radio.setToolTip(
+ _("The units used in the Gerber file.")
+ )
+
+ form.addRow(self.gerber_units_label, self.gerber_units_radio)
+
+ # Gerber format
+ self.digits_label = QtWidgets.QLabel("%s:" % _("Int/Decimals"))
+ self.digits_label.setToolTip(
+ _("The number of digits in the whole part of the number\n"
+ "and in the fractional part of the number.")
+ )
+
+ hlay1 = QtWidgets.QHBoxLayout()
+
+ self.format_whole_entry = FCSpinner()
+ self.format_whole_entry.set_range(0, 9)
+ self.format_whole_entry.set_step(1)
+ self.format_whole_entry.setWrapping(True)
+
+ self.format_whole_entry.setMinimumWidth(30)
+ self.format_whole_entry.setToolTip(
+ _("This numbers signify the number of digits in\n"
+ "the whole part of Gerber coordinates.")
+ )
+ hlay1.addWidget(self.format_whole_entry, QtCore.Qt.AlignLeft)
+
+ gerber_separator_label = QtWidgets.QLabel(':')
+ gerber_separator_label.setFixedWidth(5)
+ hlay1.addWidget(gerber_separator_label, QtCore.Qt.AlignLeft)
+
+ self.format_dec_entry = FCSpinner()
+ self.format_dec_entry.set_range(0, 9)
+ self.format_dec_entry.set_step(1)
+ self.format_dec_entry.setWrapping(True)
+
+ self.format_dec_entry.setMinimumWidth(30)
+ self.format_dec_entry.setToolTip(
+ _("This numbers signify the number of digits in\n"
+ "the decimal part of Gerber coordinates.")
+ )
+ hlay1.addWidget(self.format_dec_entry, QtCore.Qt.AlignLeft)
+ hlay1.addStretch()
+
+ form.addRow(self.digits_label, hlay1)
+
+ # Gerber Zeros
+ self.zeros_label = QtWidgets.QLabel('%s:' % _('Zeros'))
+ self.zeros_label.setAlignment(QtCore.Qt.AlignLeft)
+ self.zeros_label.setToolTip(
+ _("This sets the type of Gerber zeros.\n"
+ "If LZ then Leading Zeros are removed and\n"
+ "Trailing Zeros are kept.\n"
+ "If TZ is checked then Trailing Zeros are removed\n"
+ "and Leading Zeros are kept.")
+ )
+
+ self.zeros_radio = RadioSet([{'label': _('LZ'), 'value': 'L'},
+ {'label': _('TZ'), 'value': 'T'}])
+ self.zeros_radio.setToolTip(
+ _("This sets the type of Gerber zeros.\n"
+ "If LZ then Leading Zeros are removed and\n"
+ "Trailing Zeros are kept.\n"
+ "If TZ is checked then Trailing Zeros are removed\n"
+ "and Leading Zeros are kept.")
+ )
+
+ form.addRow(self.zeros_label, self.zeros_radio)
+
+ self.layout.addStretch()
diff --git a/flatcamGUI/preferences/gerber/GerberGenPrefGroupUI.py b/flatcamGUI/preferences/gerber/GerberGenPrefGroupUI.py
index 33acdfcc..6f52fe45 100644
--- a/flatcamGUI/preferences/gerber/GerberGenPrefGroupUI.py
+++ b/flatcamGUI/preferences/gerber/GerberGenPrefGroupUI.py
@@ -1,106 +1,273 @@
-from flatcamGUI.preferences.OptionUI import *
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI2
+from PyQt5 import QtWidgets, QtCore, QtGui
+from PyQt5.QtCore import QSettings
+
+from flatcamGUI.GUIElements import FCCheckBox, FCSpinner, RadioSet, FCEntry
+from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
import gettext
import FlatCAMTranslation as fcTranslate
import builtins
+
fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__:
_ = gettext.gettext
+settings = QSettings("Open Source", "FlatCAM")
+if settings.contains("machinist"):
+ machinist_setting = settings.value('machinist', type=int)
+else:
+ machinist_setting = 0
+
+
+class GerberGenPrefGroupUI(OptionsGroupUI):
+ def __init__(self, decimals=4, parent=None):
+ # OptionsGroupUI.__init__(self, "Gerber General Preferences", parent=parent)
+ super(GerberGenPrefGroupUI, self).__init__(self, parent=parent)
-class GerberGenPrefGroupUI(OptionsGroupUI2):
- def __init__(self, decimals=4, **kwargs):
- self.decimals = decimals
- super().__init__(**kwargs)
self.setTitle(str(_("Gerber General")))
+ self.decimals = decimals
- def build_options(self) -> [OptionUI]:
- return [
- HeadingOptionUI(label_text="Plot Options"),
- CheckboxOptionUI(
- option="gerber_solid",
- label_text="Solid",
- label_tooltip="Solid color polygons."
- ),
- CheckboxOptionUI(
- option="gerber_multicolored",
- label_text="M-Color",
- label_tooltip="Draw polygons in different colors."
- ),
- CheckboxOptionUI(
- option="gerber_plot",
- label_text="Plot",
- label_tooltip="Plot (show) this object."
- ),
- SpinnerOptionUI(
- option="gerber_circle_steps",
- label_text="Circle Steps",
- label_tooltip="The number of circle steps for Gerber \n"
- "circular aperture linear approximation.",
- min_value=0, max_value=9999, step=1
- ),
- SeparatorOptionUI(),
+ # ## Plot options
+ self.plot_options_label = QtWidgets.QLabel("%s:" % _("Plot Options"))
+ self.layout.addWidget(self.plot_options_label)
- HeadingOptionUI(
- label_text="Default Values",
- label_tooltip="Those values will be used as fallback values\n"
- "in case that they are not found in the Gerber file."
- ),
- RadioSetOptionUI(
- option="gerber_def_units",
- label_text="Units",
- label_tooltip="The units used in the Gerber file.",
- choices=[{'label': _('INCH'), 'value': 'IN'},
- {'label': _('MM'), 'value': 'MM'}]
- ),
- RadioSetOptionUI(
- option="gerber_def_zeros",
- label_text="Zeros",
- label_tooltip="This sets the type of Gerber zeros.\n"
- "If LZ then Leading Zeros are removed and\n"
- "Trailing Zeros are kept.\n"
- "If TZ is checked then Trailing Zeros are removed\n"
- "and Leading Zeros are kept.",
- choices=[{'label': _('LZ'), 'value': 'L'},
- {'label': _('TZ'), 'value': 'T'}]
- ),
- SeparatorOptionUI(),
+ grid0 = QtWidgets.QGridLayout()
+ self.layout.addLayout(grid0)
- CheckboxOptionUI(
- option="gerber_clean_apertures",
- label_text="Clean Apertures",
- label_tooltip="Will remove apertures that do not have geometry\n"
- "thus lowering the number of apertures in the Gerber object."
- ),
- CheckboxOptionUI(
- option="gerber_extra_buffering",
- label_text="Polarity change buffer",
- label_tooltip="Will apply extra buffering for the\n"
- "solid geometry when we have polarity changes.\n"
- "May help loading Gerber files that otherwise\n"
- "do not load correctly."
- ),
- SeparatorOptionUI(),
+ # Solid CB
+ self.solid_cb = FCCheckBox(label='%s' % _('Solid'))
+ self.solid_cb.setToolTip(
+ _("Solid color polygons.")
+ )
+ grid0.addWidget(self.solid_cb, 0, 0)
- HeadingOptionUI(label_text="Gerber Object Color"),
- ColorOptionUI(
- option="gerber_plot_line",
- label_text="Outline",
- label_tooltip="Set the line color for plotted objects.",
- ),
- ColorOptionUI(
- option="gerber_plot_fill",
- label_text="Fill",
- label_tooltip="Set the fill color for plotted objects.\n"
- "First 6 digits are the color and the last 2\n"
- "digits are for alpha (transparency) level."
- ),
- ColorAlphaSliderOptionUI(
- applies_to=["gerber_plot_line", "gerber_plot_fill"],
- group=self,
- label_text="Alpha",
- label_tooltip="Set the transparency for plotted objects."
- )
- ]
+ # Multicolored CB
+ self.multicolored_cb = FCCheckBox(label='%s' % _('M-Color'))
+ self.multicolored_cb.setToolTip(
+ _("Draw polygons in different colors.")
+ )
+ grid0.addWidget(self.multicolored_cb, 0, 1)
+ # Plot CB
+ self.plot_cb = FCCheckBox(label='%s' % _('Plot'))
+ self.plot_options_label.setToolTip(
+ _("Plot (show) this object.")
+ )
+ grid0.addWidget(self.plot_cb, 0, 2)
+
+ # Number of circle steps for circular aperture linear approximation
+ self.circle_steps_label = QtWidgets.QLabel('%s:' % _("Circle Steps"))
+ self.circle_steps_label.setToolTip(
+ _("The number of circle steps for Gerber \n"
+ "circular aperture linear approximation.")
+ )
+ self.circle_steps_entry = FCSpinner()
+ self.circle_steps_entry.set_range(0, 9999)
+
+ grid0.addWidget(self.circle_steps_label, 1, 0)
+ grid0.addWidget(self.circle_steps_entry, 1, 1, 1, 2)
+
+ grid0.addWidget(QtWidgets.QLabel(''), 2, 0, 1, 3)
+
+ # Default format for Gerber
+ self.gerber_default_label = QtWidgets.QLabel('%s:' % _('Default Values'))
+ self.gerber_default_label.setToolTip(
+ _("Those values will be used as fallback values\n"
+ "in case that they are not found in the Gerber file.")
+ )
+
+ grid0.addWidget(self.gerber_default_label, 3, 0, 1, 3)
+
+ # Gerber Units
+ self.gerber_units_label = QtWidgets.QLabel('%s:' % _('Units'))
+ self.gerber_units_label.setToolTip(
+ _("The units used in the Gerber file.")
+ )
+
+ self.gerber_units_radio = RadioSet([{'label': _('INCH'), 'value': 'IN'},
+ {'label': _('MM'), 'value': 'MM'}])
+ self.gerber_units_radio.setToolTip(
+ _("The units used in the Gerber file.")
+ )
+
+ grid0.addWidget(self.gerber_units_label, 4, 0)
+ grid0.addWidget(self.gerber_units_radio, 4, 1, 1, 2)
+
+ # Gerber Zeros
+ self.gerber_zeros_label = QtWidgets.QLabel('%s:' % _('Zeros'))
+ self.gerber_zeros_label.setAlignment(QtCore.Qt.AlignLeft)
+ self.gerber_zeros_label.setToolTip(
+ _("This sets the type of Gerber zeros.\n"
+ "If LZ then Leading Zeros are removed and\n"
+ "Trailing Zeros are kept.\n"
+ "If TZ is checked then Trailing Zeros are removed\n"
+ "and Leading Zeros are kept.")
+ )
+
+ self.gerber_zeros_radio = RadioSet([{'label': _('LZ'), 'value': 'L'},
+ {'label': _('TZ'), 'value': 'T'}])
+ self.gerber_zeros_radio.setToolTip(
+ _("This sets the type of Gerber zeros.\n"
+ "If LZ then Leading Zeros are removed and\n"
+ "Trailing Zeros are kept.\n"
+ "If TZ is checked then Trailing Zeros are removed\n"
+ "and Leading Zeros are kept.")
+ )
+
+ grid0.addWidget(self.gerber_zeros_label, 5, 0)
+ grid0.addWidget(self.gerber_zeros_radio, 5, 1, 1, 2)
+
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid0.addWidget(separator_line, 6, 0, 1, 3)
+
+ # Apertures Cleaning
+ self.gerber_clean_cb = FCCheckBox(label='%s' % _('Clean Apertures'))
+ self.gerber_clean_cb.setToolTip(
+ _("Will remove apertures that do not have geometry\n"
+ "thus lowering the number of apertures in the Gerber object.")
+ )
+ grid0.addWidget(self.gerber_clean_cb, 7, 0, 1, 3)
+
+ # Apply Extra Buffering
+ self.gerber_extra_buffering = FCCheckBox(label='%s' % _('Polarity change buffer'))
+ self.gerber_extra_buffering.setToolTip(
+ _("Will apply extra buffering for the\n"
+ "solid geometry when we have polarity changes.\n"
+ "May help loading Gerber files that otherwise\n"
+ "do not load correctly.")
+ )
+ grid0.addWidget(self.gerber_extra_buffering, 8, 0, 1, 3)
+
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid0.addWidget(separator_line, 9, 0, 1, 3)
+
+ # Gerber Object Color
+ self.gerber_color_label = QtWidgets.QLabel('%s' % _('Gerber Object Color'))
+ grid0.addWidget(self.gerber_color_label, 10, 0, 1, 3)
+
+ # Plot Line Color
+ self.pl_color_label = QtWidgets.QLabel('%s:' % _('Outline'))
+ self.pl_color_label.setToolTip(
+ _("Set the line color for plotted objects.")
+ )
+ self.pl_color_entry = FCEntry()
+ self.pl_color_button = QtWidgets.QPushButton()
+ self.pl_color_button.setFixedSize(15, 15)
+
+ self.form_box_child_2 = QtWidgets.QHBoxLayout()
+ self.form_box_child_2.addWidget(self.pl_color_entry)
+ self.form_box_child_2.addWidget(self.pl_color_button)
+ self.form_box_child_2.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
+
+ grid0.addWidget(self.pl_color_label, 11, 0)
+ grid0.addLayout(self.form_box_child_2, 11, 1, 1, 2)
+
+ # Plot Fill Color
+ self.pf_color_label = QtWidgets.QLabel('%s:' % _('Fill'))
+ self.pf_color_label.setToolTip(
+ _("Set the fill color for plotted objects.\n"
+ "First 6 digits are the color and the last 2\n"
+ "digits are for alpha (transparency) level.")
+ )
+ self.pf_color_entry = FCEntry()
+ self.pf_color_button = QtWidgets.QPushButton()
+ self.pf_color_button.setFixedSize(15, 15)
+
+ self.form_box_child_1 = QtWidgets.QHBoxLayout()
+ self.form_box_child_1.addWidget(self.pf_color_entry)
+ self.form_box_child_1.addWidget(self.pf_color_button)
+ self.form_box_child_1.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
+
+ grid0.addWidget(self.pf_color_label, 12, 0)
+ grid0.addLayout(self.form_box_child_1, 12, 1, 1, 2)
+
+ # Plot Fill Transparency Level
+ self.pf_alpha_label = QtWidgets.QLabel('%s:' % _('Alpha'))
+ self.pf_alpha_label.setToolTip(
+ _("Set the fill transparency for plotted objects.")
+ )
+ self.pf_color_alpha_slider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
+ self.pf_color_alpha_slider.setMinimum(0)
+ self.pf_color_alpha_slider.setMaximum(255)
+ self.pf_color_alpha_slider.setSingleStep(1)
+
+ self.pf_color_alpha_spinner = FCSpinner()
+ self.pf_color_alpha_spinner.setMinimumWidth(70)
+ self.pf_color_alpha_spinner.set_range(0, 255)
+
+ self.form_box_child_3 = QtWidgets.QHBoxLayout()
+ self.form_box_child_3.addWidget(self.pf_color_alpha_slider)
+ self.form_box_child_3.addWidget(self.pf_color_alpha_spinner)
+
+ grid0.addWidget(self.pf_alpha_label, 13, 0)
+ grid0.addLayout(self.form_box_child_3, 13, 1, 1, 2)
+
+ self.layout.addStretch()
+
+ # Setting plot colors signals
+ self.pl_color_entry.editingFinished.connect(self.on_pl_color_entry)
+ self.pl_color_button.clicked.connect(self.on_pl_color_button)
+ self.pf_color_entry.editingFinished.connect(self.on_pf_color_entry)
+ self.pf_color_button.clicked.connect(self.on_pf_color_button)
+ self.pf_color_alpha_spinner.valueChanged.connect(self.on_pf_color_spinner)
+ self.pf_color_alpha_slider.valueChanged.connect(self.on_pf_color_slider)
+
+ # Setting plot colors handlers
+ def on_pf_color_entry(self):
+ self.app.defaults['gerber_plot_fill'] = self.pf_color_entry.get_value()[:7] + \
+ self.app.defaults['gerber_plot_fill'][7:9]
+ self.pf_color_button.setStyleSheet("background-color:%s" % str(self.app.defaults['gerber_plot_fill'])[:7])
+
+ def on_pf_color_button(self):
+ current_color = QtGui.QColor(self.app.defaults['gerber_plot_fill'][:7])
+
+ c_dialog = QtWidgets.QColorDialog()
+ plot_fill_color = c_dialog.getColor(initial=current_color)
+
+ if plot_fill_color.isValid() is False:
+ return
+
+ self.pf_color_button.setStyleSheet("background-color:%s" % str(plot_fill_color.name()))
+
+ new_val = str(plot_fill_color.name()) + str(self.app.defaults['gerber_plot_fill'][7:9])
+ self.pf_color_entry.set_value(new_val)
+ self.app.defaults['gerber_plot_fill'] = new_val
+
+ def on_pf_color_spinner(self):
+ spinner_value = self.pf_color_alpha_spinner.value()
+ self.pf_color_alpha_slider.setValue(spinner_value)
+ self.app.defaults['gerber_plot_fill'] = \
+ self.app.defaults['gerber_plot_fill'][:7] + \
+ (hex(spinner_value)[2:] if int(hex(spinner_value)[2:], 16) > 0 else '00')
+ self.app.defaults['gerber_plot_line'] = \
+ self.app.defaults['gerber_plot_line'][:7] + \
+ (hex(spinner_value)[2:] if int(hex(spinner_value)[2:], 16) > 0 else '00')
+
+ def on_pf_color_slider(self):
+ slider_value = self.pf_color_alpha_slider.value()
+ self.pf_color_alpha_spinner.setValue(slider_value)
+
+ def on_pl_color_entry(self):
+ self.app.defaults['gerber_plot_line'] = self.pl_color_entry.get_value()[:7] + \
+ self.app.defaults['gerber_plot_line'][7:9]
+ self.pl_color_button.setStyleSheet("background-color:%s" % str(self.app.defaults['gerber_plot_line'])[:7])
+
+ def on_pl_color_button(self):
+ current_color = QtGui.QColor(self.app.defaults['gerber_plot_line'][:7])
+ # print(current_color)
+
+ c_dialog = QtWidgets.QColorDialog()
+ plot_line_color = c_dialog.getColor(initial=current_color)
+
+ if plot_line_color.isValid() is False:
+ return
+
+ self.pl_color_button.setStyleSheet("background-color:%s" % str(plot_line_color.name()))
+
+ new_val_line = str(plot_line_color.name()) + str(self.app.defaults['gerber_plot_line'][7:9])
+ self.pl_color_entry.set_value(new_val_line)
+ self.app.defaults['gerber_plot_line'] = new_val_line
diff --git a/flatcamGUI/preferences/gerber/GerberOptPrefGroupUI.py b/flatcamGUI/preferences/gerber/GerberOptPrefGroupUI.py
index 231c6528..404f17ba 100644
--- a/flatcamGUI/preferences/gerber/GerberOptPrefGroupUI.py
+++ b/flatcamGUI/preferences/gerber/GerberOptPrefGroupUI.py
@@ -1,5 +1,8 @@
-from flatcamGUI.preferences.OptionUI import *
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI2
+from PyQt5 import QtWidgets
+from PyQt5.QtCore import QSettings
+
+from flatcamGUI.GUIElements import FCDoubleSpinner, FCSpinner, RadioSet, FCCheckBox
+from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
import gettext
import FlatCAMTranslation as fcTranslate
@@ -9,103 +12,176 @@ fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__:
_ = gettext.gettext
+settings = QSettings("Open Source", "FlatCAM")
+if settings.contains("machinist"):
+ machinist_setting = settings.value('machinist', type=int)
+else:
+ machinist_setting = 0
-class GerberOptPrefGroupUI(OptionsGroupUI2):
- def __init__(self, decimals=4, **kwargs):
+class GerberOptPrefGroupUI(OptionsGroupUI):
+ def __init__(self, decimals=4, parent=None):
+ # OptionsGroupUI.__init__(self, "Gerber Options Preferences", parent=parent)
+ super(GerberOptPrefGroupUI, self).__init__(self, parent=parent)
+
self.decimals = decimals
- super().__init__(**kwargs)
+
self.setTitle(str(_("Gerber Options")))
- def build_options(self) -> [OptionUI]:
- return [
- HeadingOptionUI(
- label_text="Isolation Routing",
- label_tooltip="Create a Geometry object with\n"
- "toolpaths to cut outside polygons."
- ),
- DoubleSpinnerOptionUI(
- option="gerber_isotooldia",
- label_text="Tool dia",
- label_tooltip="Diameter of the cutting tool.",
- min_value=0.0, max_value=9999.9, step=0.1, decimals=self.decimals
- ),
- SpinnerOptionUI(
- option="gerber_isopasses",
- label_text="# Passes",
- label_tooltip="Width of the isolation gap in\n"
- "number (integer) of tool widths.",
- min_value=1, max_value=999, step=1
- ),
- DoubleSpinnerOptionUI(
- option="gerber_isooverlap",
- label_text="Pass overlap",
- label_tooltip="How much (percentage) of the tool width to overlap each tool pass.",
- min_value=0.0, max_value=99.9999, step=0.1, decimals=self.decimals, suffix="%"
- ),
- RadioSetOptionUI(
- option="gerber_iso_scope",
- label_text="Scope",
- label_tooltip="Isolation scope. Choose what to isolate:\n"
- "- 'All' -> Isolate all the polygons in the object\n"
- "- 'Selection' -> Isolate a selection of polygons.",
- choices=[{'label': _('All'), 'value': 'all'},
- {'label': _('Selection'), 'value': 'single'}]
- ),
- RadioSetOptionUI(
- option="gerber_milling_type",
- label_text="Milling Type",
- label_tooltip="Milling type:\n"
- "- climb / best for precision milling and to reduce tool usage\n"
- "- conventional / useful when there is no backlash compensation",
- choices=[{'label': _('Climb'), 'value': 'cl'},
- {'label': _('Conventional'), 'value': 'cv'}]
- ),
- CheckboxOptionUI(
- option="gerber_combine_passes",
- label_text="Combine Passes",
- label_tooltip="Combine all passes into one object"
- ),
- SeparatorOptionUI(),
+ # ## Isolation Routing
+ self.isolation_routing_label = QtWidgets.QLabel("%s:" % _("Isolation Routing"))
+ self.isolation_routing_label.setToolTip(
+ _("Create a Geometry object with\n"
+ "toolpaths to cut outside polygons.")
+ )
+ self.layout.addWidget(self.isolation_routing_label)
- HeadingOptionUI(
- label_text="Non-copper regions",
- label_tooltip="Create polygons covering the\n"
- "areas without copper on the PCB.\n"
- "Equivalent to the inverse of this\n"
- "object. Can be used to remove all\n"
- "copper from a specified region."
- ),
- DoubleSpinnerOptionUI(
- option="gerber_noncoppermargin",
- label_text="Boundary Margin",
- label_tooltip="Specify the edge of the PCB\n"
- "by drawing a box around all\n"
- "objects with this minimum\n"
- "distance.",
- min_value=-9999, max_value=9999, step=0.1, decimals=self.decimals
- ),
- CheckboxOptionUI(
- option="gerber_noncopperrounded",
- label_text="Rounded Geo",
- label_tooltip="Resulting geometry will have rounded corners."
- ),
- SeparatorOptionUI(),
+ # Cutting Tool Diameter
+ grid0 = QtWidgets.QGridLayout()
+ self.layout.addLayout(grid0)
- HeadingOptionUI(label_text="Bounding Box"),
- DoubleSpinnerOptionUI(
- option="gerber_bboxmargin",
- label_text="Boundary Margin",
- label_tooltip="Distance of the edges of the box\n"
- "to the nearest polygon.",
- min_value=-9999, max_value=9999, step=0.1, decimals=self.decimals
- ),
- CheckboxOptionUI(
- option="gerber_bboxrounded",
- label_text="Rounded Geo",
- label_tooltip="If the bounding box is \n"
- "to have rounded corners\n"
- "their radius is equal to\n"
- "the margin."
- ),
- ]
\ No newline at end of file
+ tdlabel = QtWidgets.QLabel('%s:' % _('Tool dia'))
+ tdlabel.setToolTip(
+ _("Diameter of the cutting tool.")
+ )
+ grid0.addWidget(tdlabel, 0, 0)
+ self.iso_tool_dia_entry = FCDoubleSpinner()
+ self.iso_tool_dia_entry.set_precision(self.decimals)
+ self.iso_tool_dia_entry.setSingleStep(0.1)
+ self.iso_tool_dia_entry.set_range(-9999, 9999)
+
+ grid0.addWidget(self.iso_tool_dia_entry, 0, 1)
+
+ # Nr of passes
+ passlabel = QtWidgets.QLabel('%s:' % _('# Passes'))
+ passlabel.setToolTip(
+ _("Width of the isolation gap in\n"
+ "number (integer) of tool widths.")
+ )
+ self.iso_width_entry = FCSpinner()
+ self.iso_width_entry.set_range(1, 999)
+
+ grid0.addWidget(passlabel, 1, 0)
+ grid0.addWidget(self.iso_width_entry, 1, 1)
+
+ # Pass overlap
+ overlabel = QtWidgets.QLabel('%s:' % _('Pass overlap'))
+ overlabel.setToolTip(
+ _("How much (percentage) of the tool width to overlap each tool pass.")
+ )
+ self.iso_overlap_entry = FCDoubleSpinner(suffix='%')
+ self.iso_overlap_entry.set_precision(self.decimals)
+ self.iso_overlap_entry.setWrapping(True)
+ self.iso_overlap_entry.setRange(0.0000, 99.9999)
+ self.iso_overlap_entry.setSingleStep(0.1)
+
+ grid0.addWidget(overlabel, 2, 0)
+ grid0.addWidget(self.iso_overlap_entry, 2, 1)
+
+ # Isolation Scope
+ self.iso_scope_label = QtWidgets.QLabel('%s:' % _('Scope'))
+ self.iso_scope_label.setToolTip(
+ _("Isolation scope. Choose what to isolate:\n"
+ "- 'All' -> Isolate all the polygons in the object\n"
+ "- 'Selection' -> Isolate a selection of polygons.")
+ )
+ self.iso_scope_radio = RadioSet([{'label': _('All'), 'value': 'all'},
+ {'label': _('Selection'), 'value': 'single'}])
+
+ grid0.addWidget(self.iso_scope_label, 3, 0)
+ grid0.addWidget(self.iso_scope_radio, 3, 1, 1, 2)
+
+ # Milling Type
+ milling_type_label = QtWidgets.QLabel('%s:' % _('Milling Type'))
+ milling_type_label.setToolTip(
+ _("Milling type:\n"
+ "- climb / best for precision milling and to reduce tool usage\n"
+ "- conventional / useful when there is no backlash compensation")
+ )
+ grid0.addWidget(milling_type_label, 4, 0)
+ self.milling_type_radio = RadioSet([{'label': _('Climb'), 'value': 'cl'},
+ {'label': _('Conventional'), 'value': 'cv'}])
+ grid0.addWidget(self.milling_type_radio, 4, 1)
+
+ # Combine passes
+ self.combine_passes_cb = FCCheckBox(label=_('Combine Passes'))
+ self.combine_passes_cb.setToolTip(
+ _("Combine all passes into one object")
+ )
+ grid0.addWidget(self.combine_passes_cb, 5, 0, 1, 2)
+
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid0.addWidget(separator_line, 6, 0, 1, 2)
+
+ # ## Clear non-copper regions
+ self.clearcopper_label = QtWidgets.QLabel("%s:" % _("Non-copper regions"))
+ self.clearcopper_label.setToolTip(
+ _("Create polygons covering the\n"
+ "areas without copper on the PCB.\n"
+ "Equivalent to the inverse of this\n"
+ "object. Can be used to remove all\n"
+ "copper from a specified region.")
+ )
+ self.layout.addWidget(self.clearcopper_label)
+
+ grid1 = QtWidgets.QGridLayout()
+ self.layout.addLayout(grid1)
+
+ # Margin
+ bmlabel = QtWidgets.QLabel('%s:' % _('Boundary Margin'))
+ bmlabel.setToolTip(
+ _("Specify the edge of the PCB\n"
+ "by drawing a box around all\n"
+ "objects with this minimum\n"
+ "distance.")
+ )
+ grid1.addWidget(bmlabel, 0, 0)
+ self.noncopper_margin_entry = FCDoubleSpinner()
+ self.noncopper_margin_entry.set_precision(self.decimals)
+ self.noncopper_margin_entry.setSingleStep(0.1)
+ self.noncopper_margin_entry.set_range(-9999, 9999)
+ grid1.addWidget(self.noncopper_margin_entry, 0, 1)
+
+ # Rounded corners
+ self.noncopper_rounded_cb = FCCheckBox(label=_("Rounded Geo"))
+ self.noncopper_rounded_cb.setToolTip(
+ _("Resulting geometry will have rounded corners.")
+ )
+ grid1.addWidget(self.noncopper_rounded_cb, 1, 0, 1, 2)
+
+ separator_line = QtWidgets.QFrame()
+ separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+ separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ grid1.addWidget(separator_line, 2, 0, 1, 2)
+
+ # ## Bounding box
+ self.boundingbox_label = QtWidgets.QLabel('%s:' % _('Bounding Box'))
+ self.layout.addWidget(self.boundingbox_label)
+
+ grid2 = QtWidgets.QGridLayout()
+ self.layout.addLayout(grid2)
+
+ bbmargin = QtWidgets.QLabel('%s:' % _('Boundary Margin'))
+ bbmargin.setToolTip(
+ _("Distance of the edges of the box\n"
+ "to the nearest polygon.")
+ )
+ self.bbmargin_entry = FCDoubleSpinner()
+ self.bbmargin_entry.set_precision(self.decimals)
+ self.bbmargin_entry.setSingleStep(0.1)
+ self.bbmargin_entry.set_range(-9999, 9999)
+
+ grid2.addWidget(bbmargin, 0, 0)
+ grid2.addWidget(self.bbmargin_entry, 0, 1)
+
+ self.bbrounded_cb = FCCheckBox(label='%s' % _("Rounded Geo"))
+ self.bbrounded_cb.setToolTip(
+ _("If the bounding box is \n"
+ "to have rounded corners\n"
+ "their radius is equal to\n"
+ "the margin.")
+ )
+ grid2.addWidget(self.bbrounded_cb, 1, 0, 1, 2)
+ self.layout.addStretch()
diff --git a/flatcamGUI/preferences/gerber/GerberPreferencesUI.py b/flatcamGUI/preferences/gerber/GerberPreferencesUI.py
index 8d3b3e90..f9d9f8aa 100644
--- a/flatcamGUI/preferences/gerber/GerberPreferencesUI.py
+++ b/flatcamGUI/preferences/gerber/GerberPreferencesUI.py
@@ -1,5 +1,6 @@
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
-from flatcamGUI.preferences.PreferencesSectionUI import PreferencesSectionUI
+from PyQt5 import QtWidgets
+from PyQt5.QtCore import QSettings
+
from flatcamGUI.preferences.gerber.GerberEditorPrefGroupUI import GerberEditorPrefGroupUI
from flatcamGUI.preferences.gerber.GerberExpPrefGroupUI import GerberExpPrefGroupUI
from flatcamGUI.preferences.gerber.GerberAdvOptPrefGroupUI import GerberAdvOptPrefGroupUI
@@ -9,30 +10,44 @@ from flatcamGUI.preferences.gerber.GerberGenPrefGroupUI import GerberGenPrefGrou
import gettext
import FlatCAMTranslation as fcTranslate
import builtins
+
fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__:
_ = gettext.gettext
+settings = QSettings("Open Source", "FlatCAM")
+if settings.contains("machinist"):
+ machinist_setting = settings.value('machinist', type=int)
+else:
+ machinist_setting = 0
-class GerberPreferencesUI(PreferencesSectionUI):
- def __init__(self, decimals, **kwargs):
+class GerberPreferencesUI(QtWidgets.QWidget):
+
+ def __init__(self, decimals, parent=None):
+ QtWidgets.QWidget.__init__(self, parent=parent)
+ self.layout = QtWidgets.QHBoxLayout()
+ self.setLayout(self.layout)
self.decimals = decimals
- super().__init__(**kwargs)
- def build_groups(self) -> [OptionsGroupUI]:
- return [
- GerberGenPrefGroupUI(decimals=self.decimals),
+ self.gerber_gen_group = GerberGenPrefGroupUI(decimals=self.decimals)
+ self.gerber_gen_group.setMinimumWidth(250)
+ self.gerber_opt_group = GerberOptPrefGroupUI(decimals=self.decimals)
+ self.gerber_opt_group.setMinimumWidth(250)
+ self.gerber_exp_group = GerberExpPrefGroupUI(decimals=self.decimals)
+ self.gerber_exp_group.setMinimumWidth(230)
+ self.gerber_adv_opt_group = GerberAdvOptPrefGroupUI(decimals=self.decimals)
+ self.gerber_adv_opt_group.setMinimumWidth(200)
+ self.gerber_editor_group = GerberEditorPrefGroupUI(decimals=self.decimals)
+ self.gerber_editor_group.setMinimumWidth(200)
- GerberOptPrefGroupUI(decimals=self.decimals), # FIXME vertical layout with opt and exp
- GerberExpPrefGroupUI(decimals=self.decimals),
+ self.vlay = QtWidgets.QVBoxLayout()
+ self.vlay.addWidget(self.gerber_opt_group)
+ self.vlay.addWidget(self.gerber_exp_group)
- GerberAdvOptPrefGroupUI(decimals=self.decimals),
- GerberEditorPrefGroupUI(decimals=self.decimals)
- ]
+ self.layout.addWidget(self.gerber_gen_group)
+ self.layout.addLayout(self.vlay)
+ self.layout.addWidget(self.gerber_adv_opt_group)
+ self.layout.addWidget(self.gerber_editor_group)
- def get_tab_id(self):
- return "gerber_tab"
-
- def get_tab_label(self):
- return _("GERBER")
+ self.layout.addStretch()
diff --git a/flatcamGUI/preferences/tools/Tools2PreferencesUI.py b/flatcamGUI/preferences/tools/Tools2PreferencesUI.py
index 168940a0..01ed4def 100644
--- a/flatcamGUI/preferences/tools/Tools2PreferencesUI.py
+++ b/flatcamGUI/preferences/tools/Tools2PreferencesUI.py
@@ -1,5 +1,6 @@
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
-from flatcamGUI.preferences.PreferencesSectionUI import PreferencesSectionUI
+from PyQt5 import QtWidgets
+from PyQt5.QtCore import QSettings
+
from flatcamGUI.preferences.tools.Tools2InvertPrefGroupUI import Tools2InvertPrefGroupUI
from flatcamGUI.preferences.tools.Tools2PunchGerberPrefGroupUI import Tools2PunchGerberPrefGroupUI
from flatcamGUI.preferences.tools.Tools2EDrillsPrefGroupUI import Tools2EDrillsPrefGroupUI
@@ -10,46 +11,79 @@ from flatcamGUI.preferences.tools.Tools2QRCodePrefGroupUI import Tools2QRCodePre
from flatcamGUI.preferences.tools.Tools2OptimalPrefGroupUI import Tools2OptimalPrefGroupUI
from flatcamGUI.preferences.tools.Tools2RulesCheckPrefGroupUI import Tools2RulesCheckPrefGroupUI
+import gettext
+import FlatCAMTranslation as fcTranslate
+import builtins
-class Tools2PreferencesUI(PreferencesSectionUI):
+fcTranslate.apply_language('strings')
+if '_' not in builtins.__dict__:
+ _ = gettext.gettext
- def __init__(self, decimals, **kwargs):
+settings = QSettings("Open Source", "FlatCAM")
+if settings.contains("machinist"):
+ machinist_setting = settings.value('machinist', type=int)
+else:
+ machinist_setting = 0
+
+
+class Tools2PreferencesUI(QtWidgets.QWidget):
+
+ def __init__(self, decimals, parent=None):
+ QtWidgets.QWidget.__init__(self, parent=parent)
+ self.layout = QtWidgets.QHBoxLayout()
+ self.setLayout(self.layout)
self.decimals = decimals
+
self.tools2_checkrules_group = Tools2RulesCheckPrefGroupUI(decimals=self.decimals)
+ self.tools2_checkrules_group.setMinimumWidth(220)
+
self.tools2_optimal_group = Tools2OptimalPrefGroupUI(decimals=self.decimals)
+ self.tools2_optimal_group.setMinimumWidth(220)
+
self.tools2_qrcode_group = Tools2QRCodePrefGroupUI(decimals=self.decimals)
+ self.tools2_qrcode_group.setMinimumWidth(220)
+
self.tools2_cfill_group = Tools2CThievingPrefGroupUI(decimals=self.decimals)
+ self.tools2_cfill_group.setMinimumWidth(220)
+
self.tools2_fiducials_group = Tools2FiducialsPrefGroupUI(decimals=self.decimals)
+ self.tools2_fiducials_group.setMinimumWidth(220)
+
self.tools2_cal_group = Tools2CalPrefGroupUI(decimals=self.decimals)
+ self.tools2_cal_group.setMinimumWidth(220)
+
self.tools2_edrills_group = Tools2EDrillsPrefGroupUI(decimals=self.decimals)
+ self.tools2_edrills_group.setMinimumWidth(220)
+
self.tools2_punch_group = Tools2PunchGerberPrefGroupUI(decimals=self.decimals)
+ self.tools2_punch_group.setMinimumWidth(220)
+
self.tools2_invert_group = Tools2InvertPrefGroupUI(decimals=self.decimals)
- super().__init__(**kwargs)
+ self.tools2_invert_group.setMinimumWidth(220)
- def build_groups(self) -> [OptionsGroupUI]:
- return [
- # fixme column 1
- self.tools2_checkrules_group,
- self.tools2_optimal_group,
+ self.vlay = QtWidgets.QVBoxLayout()
+ self.vlay.addWidget(self.tools2_checkrules_group)
+ self.vlay.addWidget(self.tools2_optimal_group)
- # fixme column 2
- self.tools2_qrcode_group,
- self.tools2_fiducials_group,
+ self.vlay1 = QtWidgets.QVBoxLayout()
+ self.vlay1.addWidget(self.tools2_qrcode_group)
+ self.vlay1.addWidget(self.tools2_fiducials_group)
- # fixme column 3
- self.tools2_cfill_group,
+ self.vlay2 = QtWidgets.QVBoxLayout()
+ self.vlay2.addWidget(self.tools2_cfill_group)
- # fixme column 4
- self.tools2_cal_group,
- self.tools2_edrills_group,
+ self.vlay3 = QtWidgets.QVBoxLayout()
+ self.vlay3.addWidget(self.tools2_cal_group)
+ self.vlay3.addWidget(self.tools2_edrills_group)
- # fixme column 5
- self.tools2_punch_group,
- self.tools2_invert_group,
- ]
+ self.vlay4 = QtWidgets.QVBoxLayout()
+ self.vlay4.addWidget(self.tools2_punch_group)
+ self.vlay4.addWidget(self.tools2_invert_group)
- def get_tab_id(self):
- return "tools2_tab"
+ self.layout.addLayout(self.vlay)
+ self.layout.addLayout(self.vlay1)
+ self.layout.addLayout(self.vlay2)
+ self.layout.addLayout(self.vlay3)
+ self.layout.addLayout(self.vlay4)
- def get_tab_label(self):
- return _("TOOLS 2")
\ No newline at end of file
+ self.layout.addStretch()
diff --git a/flatcamGUI/preferences/tools/ToolsPreferencesUI.py b/flatcamGUI/preferences/tools/ToolsPreferencesUI.py
index 0c4ffd70..dc3061a8 100644
--- a/flatcamGUI/preferences/tools/ToolsPreferencesUI.py
+++ b/flatcamGUI/preferences/tools/ToolsPreferencesUI.py
@@ -1,5 +1,6 @@
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
-from flatcamGUI.preferences.PreferencesSectionUI import PreferencesSectionUI
+from PyQt5 import QtWidgets
+from PyQt5.QtCore import QSettings
+
from flatcamGUI.preferences.tools.ToolsSubPrefGroupUI import ToolsSubPrefGroupUI
from flatcamGUI.preferences.tools.ToolsSolderpastePrefGroupUI import ToolsSolderpastePrefGroupUI
from flatcamGUI.preferences.tools.ToolsTransformPrefGroupUI import ToolsTransformPrefGroupUI
@@ -11,48 +12,83 @@ from flatcamGUI.preferences.tools.Tools2sidedPrefGroupUI import Tools2sidedPrefG
from flatcamGUI.preferences.tools.ToolsCutoutPrefGroupUI import ToolsCutoutPrefGroupUI
from flatcamGUI.preferences.tools.ToolsNCCPrefGroupUI import ToolsNCCPrefGroupUI
+import gettext
+import FlatCAMTranslation as fcTranslate
+import builtins
-class ToolsPreferencesUI(PreferencesSectionUI):
+fcTranslate.apply_language('strings')
+if '_' not in builtins.__dict__:
+ _ = gettext.gettext
- def __init__(self, decimals, **kwargs):
+settings = QSettings("Open Source", "FlatCAM")
+if settings.contains("machinist"):
+ machinist_setting = settings.value('machinist', type=int)
+else:
+ machinist_setting = 0
+
+
+class ToolsPreferencesUI(QtWidgets.QWidget):
+
+ def __init__(self, decimals, parent=None):
+ QtWidgets.QWidget.__init__(self, parent=parent)
+ self.layout = QtWidgets.QHBoxLayout()
+ self.setLayout(self.layout)
self.decimals = decimals
+
self.tools_ncc_group = ToolsNCCPrefGroupUI(decimals=self.decimals)
+ self.tools_ncc_group.setMinimumWidth(220)
+
self.tools_paint_group = ToolsPaintPrefGroupUI(decimals=self.decimals)
+ self.tools_paint_group.setMinimumWidth(220)
+
self.tools_cutout_group = ToolsCutoutPrefGroupUI(decimals=self.decimals)
+ self.tools_cutout_group.setMinimumWidth(220)
+
self.tools_2sided_group = Tools2sidedPrefGroupUI(decimals=self.decimals)
+ self.tools_2sided_group.setMinimumWidth(220)
+
self.tools_film_group = ToolsFilmPrefGroupUI(decimals=self.decimals)
+ self.tools_film_group.setMinimumWidth(220)
+
self.tools_panelize_group = ToolsPanelizePrefGroupUI(decimals=self.decimals)
+ self.tools_panelize_group.setMinimumWidth(220)
+
self.tools_calculators_group = ToolsCalculatorsPrefGroupUI(decimals=self.decimals)
+ self.tools_calculators_group.setMinimumWidth(220)
+
self.tools_transform_group = ToolsTransformPrefGroupUI(decimals=self.decimals)
+ self.tools_transform_group.setMinimumWidth(200)
+
self.tools_solderpaste_group = ToolsSolderpastePrefGroupUI(decimals=self.decimals)
+ self.tools_solderpaste_group.setMinimumWidth(200)
+
self.tools_sub_group = ToolsSubPrefGroupUI(decimals=self.decimals)
- super().__init__(**kwargs)
+ self.tools_sub_group.setMinimumWidth(200)
- def build_groups(self) -> [OptionsGroupUI]:
- return [
- # fixme column 1
- self.tools_ncc_group,
- self.tools_cutout_group,
+ self.vlay = QtWidgets.QVBoxLayout()
+ self.vlay.addWidget(self.tools_ncc_group)
+ self.vlay.addWidget(self.tools_cutout_group)
- # fixme column 2
- self.tools_paint_group,
- self.tools_panelize_group,
+ self.vlay1 = QtWidgets.QVBoxLayout()
+ self.vlay1.addWidget(self.tools_paint_group)
+ self.vlay1.addWidget(self.tools_panelize_group)
- # fixme column 3
- self.tools_transform_group,
- self.tools_2sided_group,
- self.tools_sub_group,
+ self.vlay2 = QtWidgets.QVBoxLayout()
+ self.vlay2.addWidget(self.tools_transform_group)
+ self.vlay2.addWidget(self.tools_2sided_group)
+ self.vlay2.addWidget(self.tools_sub_group)
- # fixme column 4
- self.tools_film_group,
- self.tools_calculators_group,
+ self.vlay3 = QtWidgets.QVBoxLayout()
+ self.vlay3.addWidget(self.tools_film_group)
+ self.vlay3.addWidget(self.tools_calculators_group)
- # fixme column 5
- self.tools_solderpaste_group,
- ]
+ self.vlay4 = QtWidgets.QVBoxLayout()
+ self.vlay4.addWidget(self.tools_solderpaste_group)
- def get_tab_id(self):
- return "tools_tab"
+ self.layout.addLayout(self.vlay)
+ self.layout.addLayout(self.vlay1)
+ self.layout.addLayout(self.vlay2)
+ self.layout.addLayout(self.vlay3)
+ self.layout.addLayout(self.vlay4)
- def get_tab_label(self):
- return _("TOOLS")
+ self.layout.addStretch()
diff --git a/flatcamGUI/preferences/utilities/UtilPreferencesUI.py b/flatcamGUI/preferences/utilities/UtilPreferencesUI.py
index 9e2f40b1..ae9e2110 100644
--- a/flatcamGUI/preferences/utilities/UtilPreferencesUI.py
+++ b/flatcamGUI/preferences/utilities/UtilPreferencesUI.py
@@ -1,31 +1,37 @@
-from flatcamGUI.preferences.OptionsGroupUI import OptionsGroupUI
-from flatcamGUI.preferences.PreferencesSectionUI import PreferencesSectionUI
+from PyQt5 import QtWidgets
+
from flatcamGUI.preferences.utilities.AutoCompletePrefGroupUI import AutoCompletePrefGroupUI
from flatcamGUI.preferences.utilities.FAGrbPrefGroupUI import FAGrbPrefGroupUI
from flatcamGUI.preferences.utilities.FAGcoPrefGroupUI import FAGcoPrefGroupUI
from flatcamGUI.preferences.utilities.FAExcPrefGroupUI import FAExcPrefGroupUI
-class UtilPreferencesUI(PreferencesSectionUI):
+class UtilPreferencesUI(QtWidgets.QWidget):
- def __init__(self, decimals, **kwargs):
+ def __init__(self, decimals, parent=None):
+ QtWidgets.QWidget.__init__(self, parent=parent)
+ self.layout = QtWidgets.QHBoxLayout()
+ self.setLayout(self.layout)
self.decimals = decimals
+
+ self.vlay = QtWidgets.QVBoxLayout()
self.fa_excellon_group = FAExcPrefGroupUI(decimals=self.decimals)
+ self.fa_excellon_group.setMinimumWidth(260)
+
self.fa_gcode_group = FAGcoPrefGroupUI(decimals=self.decimals)
+ self.fa_gcode_group.setMinimumWidth(260)
+
+ self.vlay.addWidget(self.fa_excellon_group)
+ self.vlay.addWidget(self.fa_gcode_group)
+
self.fa_gerber_group = FAGrbPrefGroupUI(decimals=self.decimals)
+ self.fa_gerber_group.setMinimumWidth(260)
+
self.kw_group = AutoCompletePrefGroupUI(decimals=self.decimals)
- super().__init__(**kwargs)
+ self.kw_group.setMinimumWidth(260)
- def build_groups(self) -> [OptionsGroupUI]:
- return [
- self.fa_excellon_group, # fixme column with fa_excellon and fa_gcode
- self.fa_gcode_group,
- self.fa_gerber_group,
- self.kw_group,
- ]
+ self.layout.addLayout(self.vlay)
+ self.layout.addWidget(self.fa_gerber_group)
+ self.layout.addWidget(self.kw_group)
- def get_tab_id(self):
- return "fa_tab"
-
- def get_tab_label(self):
- return _("UTILITIES")
\ No newline at end of file
+ self.layout.addStretch()
diff --git a/flatcamTools/ToolCopperThieving.py b/flatcamTools/ToolCopperThieving.py
index f6c85731..d6fd310a 100644
--- a/flatcamTools/ToolCopperThieving.py
+++ b/flatcamTools/ToolCopperThieving.py
@@ -910,22 +910,16 @@ class ToolCopperThieving(FlatCAMTool):
edge_width=self.app.defaults["global_cursor_width"],
size=self.app.defaults["global_cursor_size"])
+ # update the positions on status bar
+ self.app.ui.position_label.setText(" X: %.4f "
+ "Y: %.4f" % (curr_pos[0], curr_pos[1]))
if self.cursor_pos is None:
self.cursor_pos = (0, 0)
self.app.dx = curr_pos[0] - float(self.cursor_pos[0])
self.app.dy = curr_pos[1] - float(self.cursor_pos[1])
-
- # # update the positions on status bar
- # self.app.ui.position_label.setText(" X: %.4f "
- # "Y: %.4f" % (curr_pos[0], curr_pos[1]))
- # self.app.ui.rel_position_label.setText("Dx: %.4f Dy: "
- # "%.4f " % (self.app.dx, self.app.dy))
-
- units = self.app.defaults["units"].lower()
- self.plotcanvas.text_hud.text = \
- 'Dx:\t{:<.4f} [{:s}]\nDy:\t{:<.4f} [{:s}]\nX: \t{:<.4f} [{:s}]\nY: \t{:<.4f} [{:s}]'.format(
- self.app.dx, units, self.app.dy, units, curr_pos[0], units, curr_pos[1], units)
+ self.app.ui.rel_position_label.setText("Dx: %.4f Dy: "
+ "%.4f " % (self.app.dx, self.app.dy))
# draw the utility geometry
if self.first_click:
diff --git a/flatcamTools/ToolDistance.py b/flatcamTools/ToolDistance.py
index bcc506fb..ea62c64e 100644
--- a/flatcamTools/ToolDistance.py
+++ b/flatcamTools/ToolDistance.py
@@ -544,16 +544,11 @@ class Distance(FlatCAMTool):
else:
pos = (pos_canvas[0], pos_canvas[1])
- # self.app.ui.position_label.setText(
- # " X: {} Y: {}".format(
- # '%.*f' % (self.decimals, pos[0]), '%.*f' % (self.decimals, pos[1])
- # )
- # )
-
- units = self.app.defaults["units"].lower()
- self.plotcanvas.text_hud.text = \
- 'Dx:\t{:<.4f} [{:s}]\nDy:\t{:<.4f} [{:s}]\nX: \t{:<.4f} [{:s}]\nY: \t{:<.4f} [{:s}]'.format(
- 0.0000, units, 0.0000, units, pos[0], units, pos[1], units)
+ self.app.ui.position_label.setText(
+ " X: {} Y: {}".format(
+ '%.*f' % (self.decimals, pos[0]), '%.*f' % (self.decimals, pos[1])
+ )
+ )
if self.rel_point1 is not None:
dx = pos[0] - float(self.rel_point1[0])
diff --git a/flatcamTools/ToolNCC.py b/flatcamTools/ToolNCC.py
index d01f02de..0b80c735 100644
--- a/flatcamTools/ToolNCC.py
+++ b/flatcamTools/ToolNCC.py
@@ -1825,22 +1825,16 @@ class NonCopperClear(FlatCAMTool, Gerber):
edge_width=self.app.defaults["global_cursor_width"],
size=self.app.defaults["global_cursor_size"])
+ # update the positions on status bar
+ self.app.ui.position_label.setText(" X: %.4f "
+ "Y: %.4f" % (curr_pos[0], curr_pos[1]))
if self.cursor_pos is None:
self.cursor_pos = (0, 0)
self.app.dx = curr_pos[0] - float(self.cursor_pos[0])
self.app.dy = curr_pos[1] - float(self.cursor_pos[1])
-
- # # update the positions on status bar
- # self.app.ui.position_label.setText(" X: %.4f "
- # "Y: %.4f" % (curr_pos[0], curr_pos[1]))
- # self.app.ui.rel_position_label.setText("Dx: %.4f Dy: "
- # "%.4f " % (self.app.dx, self.app.dy))
-
- units = self.app.defaults["units"].lower()
- self.plotcanvas.text_hud.text = \
- 'Dx:\t{:<.4f} [{:s}]\nDy:\t{:<.4f} [{:s}]\nX: \t{:<.4f} [{:s}]\nY: \t{:<.4f} [{:s}]'.format(
- self.app.dx, units, self.app.dy, units, curr_pos[0], units, curr_pos[1], units)
+ self.app.ui.rel_position_label.setText("Dx: %.4f Dy: "
+ "%.4f " % (self.app.dx, self.app.dy))
# draw the utility geometry
if shape_type == "square":
diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py
index ae1b23cc..4dda2d36 100644
--- a/flatcamTools/ToolPaint.py
+++ b/flatcamTools/ToolPaint.py
@@ -1724,22 +1724,16 @@ class ToolPaint(FlatCAMTool, Gerber):
edge_width=self.app.defaults["global_cursor_width"],
size=self.app.defaults["global_cursor_size"])
+ # update the positions on status bar
+ self.app.ui.position_label.setText(" X: %.4f "
+ "Y: %.4f" % (curr_pos[0], curr_pos[1]))
if self.cursor_pos is None:
self.cursor_pos = (0, 0)
self.app.dx = curr_pos[0] - float(self.cursor_pos[0])
self.app.dy = curr_pos[1] - float(self.cursor_pos[1])
-
- # # update the positions on status bar
- # self.app.ui.position_label.setText(" X: %.4f "
- # "Y: %.4f" % (curr_pos[0], curr_pos[1]))
- # self.app.ui.rel_position_label.setText("Dx: %.4f Dy: "
- # "%.4f " % (self.app.dx, self.app.dy))
-
- units = self.app.defaults["units"].lower()
- self.plotcanvas.text_hud.text = \
- 'Dx:\t{:<.4f} [{:s}]\nDy:\t{:<.4f} [{:s}]\nX: \t{:<.4f} [{:s}]\nY: \t{:<.4f} [{:s}]'.format(
- self.app.dx, units, self.app.dy, units, curr_pos[0], units, curr_pos[1], units)
+ self.app.ui.rel_position_label.setText("Dx: %.4f Dy: "
+ "%.4f " % (self.app.dx, self.app.dy))
# draw the utility geometry
if shape_type == "square":