diff --git a/AppGUI/preferences/PreferencesUIManager.py b/AppGUI/preferences/PreferencesUIManager.py index db1d738b..33a3cec4 100644 --- a/AppGUI/preferences/PreferencesUIManager.py +++ b/AppGUI/preferences/PreferencesUIManager.py @@ -131,7 +131,7 @@ class PreferencesUIManager: "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_iso_scope": self.ui.gerber_defaults_form.gerber_opt_group.select_combo, "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, diff --git a/AppGUI/preferences/gerber/GerberOptPrefGroupUI.py b/AppGUI/preferences/gerber/GerberOptPrefGroupUI.py index e3269322..2a57a640 100644 --- a/AppGUI/preferences/gerber/GerberOptPrefGroupUI.py +++ b/AppGUI/preferences/gerber/GerberOptPrefGroupUI.py @@ -1,7 +1,7 @@ from PyQt5 import QtWidgets from PyQt5.QtCore import QSettings -from AppGUI.GUIElements import FCDoubleSpinner, FCSpinner, RadioSet, FCCheckBox +from AppGUI.GUIElements import FCDoubleSpinner, FCSpinner, RadioSet, FCCheckBox, FCComboBox from AppGUI.preferences.OptionsGroupUI import OptionsGroupUI import gettext @@ -79,17 +79,20 @@ class GerberOptPrefGroupUI(OptionsGroupUI): grid0.addWidget(self.iso_overlap_entry, 2, 1) # Isolation Scope - self.iso_scope_label = QtWidgets.QLabel('%s:' % _('Scope')) - self.iso_scope_label.setToolTip( + self.select_label = QtWidgets.QLabel('%s:' % _('Selection')) + self.select_label.setToolTip( _("Isolation scope. Choose what to isolate:\n" "- 'All' -> Isolate all the polygons in the object\n" - "- 'Selection' -> Isolate a selection of polygons.") + "- 'Selection' -> Isolate a selection of polygons.\n" + "- 'Reference Object' - will process the area specified by another object.") + ) + self.select_combo = FCComboBox() + self.select_combo.addItems( + [_("All"), _("Area Selection"), _("Reference Object")] ) - 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) + grid0.addWidget(self.select_label, 3, 0) + grid0.addWidget(self.select_combo, 3, 1, 1, 2) # Milling Type milling_type_label = QtWidgets.QLabel('%s:' % _('Milling Type')) diff --git a/AppTools/ToolIsolation.py b/AppTools/ToolIsolation.py index adbbba79..d12a3e9f 100644 --- a/AppTools/ToolIsolation.py +++ b/AppTools/ToolIsolation.py @@ -370,22 +370,21 @@ class ToolIsolation(AppTool, Gerber): self.grid3.addWidget(self.milling_type_label, 15, 0) self.grid3.addWidget(self.milling_type_radio, 15, 1) - # Combine All Passes - self.combine_passes_cb = FCCheckBox(label=_('Combine')) - self.combine_passes_cb.setToolTip( - _("Combine all passes into one object") - ) - self.combine_passes_cb.setObjectName("i_combine") - - self.grid3.addWidget(self.combine_passes_cb, 16, 0) - # Follow - self.follow_cb = FCCheckBox(label=_('"Follow"')) + self.follow_label = QtWidgets.QLabel('%s:' % _('Follow')) + self.follow_label.setToolTip( + _("Generate a 'Follow' geometry.\n" + "This means that it will cut through\n" + "the middle of the trace.") + ) + + self.follow_cb = FCCheckBox() self.follow_cb.setToolTip(_("Generate a 'Follow' geometry.\n" "This means that it will cut through\n" "the middle of the trace.")) self.follow_cb.setObjectName("i_follow") + self.grid3.addWidget(self.follow_label, 16, 0) self.grid3.addWidget(self.follow_cb, 16, 1) # Isolation Type @@ -435,7 +434,6 @@ class ToolIsolation(AppTool, Gerber): # Rest Machining self.rest_cb = FCCheckBox('%s' % _("Rest Machining")) self.rest_cb.setObjectName("i_rest_machining") - self.rest_cb.setToolTip( _("If checked, use 'rest machining'.\n" "Basically it will clear copper outside PCB features,\n" @@ -448,6 +446,57 @@ class ToolIsolation(AppTool, Gerber): self.grid3.addWidget(self.rest_cb, 25, 0, 1, 2) + # Combine All Passes + self.combine_passes_cb = FCCheckBox(label=_('Combine')) + self.combine_passes_cb.setToolTip( + _("Combine all passes into one object") + ) + self.combine_passes_cb.setObjectName("i_combine") + + self.grid3.addWidget(self.combine_passes_cb, 26, 0, 1, 2) + + # Exception Areas + self.except_cb = FCCheckBox(label=_('Except')) + self.except_cb.setToolTip(_("When the isolation geometry is generated,\n" + "by checking this, the area of the object below\n" + "will be subtracted from the isolation geometry.")) + self.except_cb.setObjectName("i_except") + self.grid3.addWidget(self.except_cb, 27, 0, 1, 2) + + # Type of object to be excepted + self.type_excobj_combo_label = QtWidgets.QLabel('%s:' % _("Obj Type")) + self.type_excobj_combo_label.setToolTip( + _("Specify the type of object to be excepted from isolation.\n" + "It can be of type: Gerber or Geometry.\n" + "What is selected here will dictate the kind\n" + "of objects that will populate the 'Object' combobox.") + ) + + self.type_excobj_radio = RadioSet([{'label': _("Geometry"), 'value': 'geometry'}, + {'label': _("Gerber"), 'value': 'gerber'}]) + + self.grid3.addWidget(self.type_excobj_combo_label, 28, 0) + self.grid3.addWidget(self.type_excobj_radio, 28, 1) + + # The object to be excepted + self.exc_obj_combo = FCComboBox() + self.exc_obj_combo.setToolTip(_("Object whose area will be removed from isolation geometry.")) + + # set the model for the Area Exception comboboxes + self.exc_obj_combo.setModel(self.app.collection) + self.exc_obj_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) + self.exc_obj_combo.is_last = True + self.exc_obj_combo.obj_type = self.type_excobj_radio.get_value() + + self.grid3.addWidget(self.exc_obj_combo, 29, 0, 1, 2) + + self.e_ois = OptionalHideInputSection(self.except_cb, + [ + self.type_excobj_combo_label, + self.type_excobj_radio, + self.exc_obj_combo + ]) + # Isolation Scope self.select_label = QtWidgets.QLabel('%s:' % _("Selection")) self.select_label.setToolTip( @@ -462,8 +511,8 @@ class ToolIsolation(AppTool, Gerber): ) self.select_combo.setObjectName("i_selection") - self.grid3.addWidget(self.select_label, 26, 0) - self.grid3.addWidget(self.select_combo, 26, 1) + self.grid3.addWidget(self.select_label, 30, 0) + self.grid3.addWidget(self.select_combo, 30, 1) self.reference_combo_type_label = QtWidgets.QLabel('%s:' % _("Ref. Type")) self.reference_combo_type_label.setToolTip( @@ -473,8 +522,8 @@ class ToolIsolation(AppTool, Gerber): self.reference_combo_type = FCComboBox() self.reference_combo_type.addItems([_("Gerber"), _("Excellon"), _("Geometry")]) - self.grid3.addWidget(self.reference_combo_type_label, 27, 0) - self.grid3.addWidget(self.reference_combo_type, 27, 1) + self.grid3.addWidget(self.reference_combo_type_label, 31, 0) + self.grid3.addWidget(self.reference_combo_type, 31, 1) self.reference_combo_label = QtWidgets.QLabel('%s:' % _("Ref. Object")) self.reference_combo_label.setToolTip( @@ -485,8 +534,8 @@ class ToolIsolation(AppTool, Gerber): self.reference_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) self.reference_combo.is_last = True - self.grid3.addWidget(self.reference_combo_label, 28, 0) - self.grid3.addWidget(self.reference_combo, 28, 1) + self.grid3.addWidget(self.reference_combo_label, 32, 0) + self.grid3.addWidget(self.reference_combo, 32, 1) self.reference_combo.hide() self.reference_combo_label.hide() @@ -502,58 +551,16 @@ class ToolIsolation(AppTool, Gerber): self.area_shape_radio = RadioSet([{'label': _("Square"), 'value': 'square'}, {'label': _("Polygon"), 'value': 'polygon'}]) - self.grid3.addWidget(self.area_shape_label, 29, 0) - self.grid3.addWidget(self.area_shape_radio, 29, 1) + self.grid3.addWidget(self.area_shape_label, 33, 0) + self.grid3.addWidget(self.area_shape_radio, 33, 1) self.area_shape_label.hide() self.area_shape_radio.hide() - # Exception Areas - self.except_cb = FCCheckBox(label=_('Except')) - self.except_cb.setToolTip(_("When the isolation geometry is generated,\n" - "by checking this, the area of the object below\n" - "will be subtracted from the isolation geometry.")) - self.except_cb.setObjectName("i_except") - self.grid3.addWidget(self.except_cb, 30, 0) - - # Type of object to be excepted - self.type_excobj_combo_label = QtWidgets.QLabel('%s:' % _("Obj Type")) - self.type_excobj_combo_label.setToolTip( - _("Specify the type of object to be excepted from isolation.\n" - "It can be of type: Gerber or Geometry.\n" - "What is selected here will dictate the kind\n" - "of objects that will populate the 'Object' combobox.") - ) - - self.type_excobj_radio = RadioSet([{'label': _("Geometry"), 'value': 'geometry'}, - {'label': _("Gerber"), 'value': 'gerber'}]) - - self.grid3.addWidget(self.type_excobj_combo_label, 31, 0) - self.grid3.addWidget(self.type_excobj_radio, 31, 1) - - # The object to be excepted - self.exc_obj_combo = FCComboBox() - self.exc_obj_combo.setToolTip(_("Object whose area will be removed from isolation geometry.")) - - # set the model for the Area Exception comboboxes - self.exc_obj_combo.setModel(self.app.collection) - self.exc_obj_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) - self.exc_obj_combo.is_last = True - self.exc_obj_combo.obj_type = self.type_excobj_radio.get_value() - - self.grid3.addWidget(self.exc_obj_combo, 32, 0, 1, 2) - - self.e_ois = OptionalHideInputSection(self.except_cb, - [ - self.type_excobj_combo_label, - self.type_excobj_radio, - self.exc_obj_combo - ]) - separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - self.grid3.addWidget(separator_line, 33, 0, 1, 2) + self.grid3.addWidget(separator_line, 34, 0, 1, 2) self.generate_iso_button = QtWidgets.QPushButton("%s" % _("Generate Isolation Geometry")) self.generate_iso_button.setStyleSheet(""" @@ -947,6 +954,13 @@ class ToolIsolation(AppTool, Gerber): self.units = self.app.defaults['units'].upper() self.old_tool_dia = self.app.defaults["tools_nccnewdia"] + # try to select in the Gerber combobox the active object + try: + current_name = self.app.collection.get_active().options['name'] + self.object_combo.set_value(current_name) + except Exception: + pass + app_mode = self.app.defaults["global_app_level"] # Show/Hide Advanced Options @@ -954,7 +968,7 @@ class ToolIsolation(AppTool, Gerber): self.level.setText('%s' % _('Basic')) # override the Preferences Value; in Basic mode the Tool Type is always Circular ('C1') - self.tool_type_radio.set_value('circular') + self.tool_type_radio.set_value('C1') self.tool_type_label.hide() self.tool_type_radio.hide() @@ -967,11 +981,40 @@ class ToolIsolation(AppTool, Gerber): self.follow_cb.setChecked(False) self.follow_cb.hide() + self.follow_label.hide() + self.rest_cb.setChecked(False) + self.rest_cb.hide() self.except_cb.setChecked(False) self.except_cb.hide() + self.select_combo.setCurrentIndex(0) + self.select_combo.hide() + self.select_label.hide() else: self.level.setText('%s' % _('Advanced')) + # TODO remember to set the GUI elements to values from app.defaults dict + self.tool_type_radio.set_value(self.app.defaults["gerber_tool_type"]) + self.tool_type_label.show() + self.tool_type_radio.show() + + self.milling_type_label.show() + self.milling_type_radio.show() + + self.iso_type_label.show() + self.iso_type_radio.set_value(self.app.defaults["gerber_iso_type"]) + self.iso_type_radio.show() + + self.follow_cb.setChecked(False) + self.follow_cb.show() + self.follow_label.show() + self.rest_cb.setChecked(False) + self.rest_cb.show() + self.except_cb.setChecked(False) + self.except_cb.show() + self.select_combo.setCurrentIndex(0) + self.select_combo.show() + self.select_label.show() + if self.app.defaults["gerber_buffering"] == 'no': self.create_buffer_button.show() try: @@ -992,15 +1035,15 @@ class ToolIsolation(AppTool, Gerber): self.on_reference_combo_changed() self.order_radio.set_value(self.app.defaults["tools_nccorder"]) - self.passes_entry.set_value(1) - self.iso_overlap_entry.set_value(10) - self.milling_type_radio.set_value(self.app.defaults["tools_nccmilling_type"]) - self.combine_passes_cb.set_value(True) - self.follow_cb.set_value(False) + self.passes_entry.set_value(self.app.defaults["gerber_isopasses"]) + self.iso_overlap_entry.set_value(self.app.defaults["gerber_isooverlap"]) + self.milling_type_radio.set_value(self.app.defaults["gerber_milling_type"]) + self.combine_passes_cb.set_value(self.app.defaults["gerber_combine_passes"]) + self.follow_cb.set_value(self.app.defaults["gerber_follow"]) self.except_cb.set_value(False) - self.iso_type_radio.set_value('full') + self.iso_type_radio.set_value(self.app.defaults["gerber_iso_type"]) self.rest_cb.set_value(False) - self.select_combo.set_value(_("All")) + self.select_combo.set_value(self.app.defaults["gerber_iso_scope"]) self.area_shape_radio.set_value('square') self.cutz_entry.set_value(self.app.defaults["tools_ncccutz"]) @@ -1046,23 +1089,24 @@ class ToolIsolation(AppTool, Gerber): "area_strategy": self.app.defaults["geometry_area_strategy"], "area_overz": float(self.app.defaults["geometry_area_overz"]), - "tools_nccoperation": self.app.defaults["tools_nccoperation"], - "tools_nccmargin": self.app.defaults["tools_nccmargin"], - "tools_nccmethod": self.app.defaults["tools_nccmethod"], - "tools_nccconnect": self.app.defaults["tools_nccconnect"], - "tools_ncccontour": self.app.defaults["tools_ncccontour"], - "tools_nccoverlap": self.app.defaults["tools_nccoverlap"], + "tools_iso_passes": self.app.defaults["gerber_isopasses"], + "tools_iso_overlap": self.app.defaults["gerber_isooverlap"], + "tools_iso_milling_type": self.app.defaults["gerber_milling_type"], + "tools_iso_combine": self.app.defaults["gerber_combine_passes"], + "tools_iso_follow": self.app.defaults["gerber_follow"], + "tools_iso_type": self.app.defaults["gerber_iso_type"], + "nccrest": self.app.defaults["tools_nccrest"], - "nccref": self.app.defaults["tools_nccref"], - "tools_ncc_offset_choice": self.app.defaults["tools_ncc_offset_choice"], - "tools_ncc_offset_value": self.app.defaults["tools_ncc_offset_value"], - "tools_nccmilling_type": self.app.defaults["tools_nccmilling_type"], + "nccref": self.app.defaults["gerber_iso_scope"], + + "tools_iso_exclusion": True, + } try: - dias = [float(self.app.defaults["tools_ncctools"])] + dias = [float(self.app.defaults["gerber_isotooldia"])] except (ValueError, TypeError): - dias = [float(eval(dia)) for dia in self.app.defaults["tools_ncctools"].split(",") if dia != ''] + dias = [float(eval(dia)) for dia in self.app.defaults["gerber_isotooldia"].split(",") if dia != ''] if not dias: log.error("At least one tool diameter needed. Verify in Edit -> Preferences -> TOOLS -> Isolation Tools.") @@ -1219,7 +1263,7 @@ class ToolIsolation(AppTool, Gerber): current_widget.stateChanged.connect(self.form_to_storage) if isinstance(current_widget, RadioSet): current_widget.activated_custom.connect(self.form_to_storage) - elif isinstance(current_widget, FCDoubleSpinner): + elif isinstance(current_widget, FCDoubleSpinner) or isinstance(current_widget, FCSpinner): current_widget.returnPressed.connect(self.form_to_storage) elif isinstance(current_widget, FCComboBox): current_widget.currentIndexChanged.connect(self.form_to_storage) @@ -1260,7 +1304,7 @@ class ToolIsolation(AppTool, Gerber): current_widget.activated_custom.disconnect(self.form_to_storage) except (TypeError, ValueError): pass - elif isinstance(current_widget, FCDoubleSpinner): + elif isinstance(current_widget, FCDoubleSpinner) or isinstance(current_widget, FCSpinner): try: current_widget.returnPressed.disconnect(self.form_to_storage) except (TypeError, ValueError): diff --git a/AppTools/ToolPDF.py b/AppTools/ToolPDF.py index 4b4e88ad..59f4f7a6 100644 --- a/AppTools/ToolPDF.py +++ b/AppTools/ToolPDF.py @@ -130,7 +130,7 @@ class ToolPDF(AppTool): raise grace stream_nr += 1 - log.debug(" PDF STREAM: %d\n" % stream_nr) + log.debug("PDF STREAM: %d\n" % stream_nr) s = s.strip(b'\r\n') try: self.pdf_decompressed[short_name] += (zlib.decompress(s).decode('UTF-8') + '\r\n') diff --git a/App_Main.py b/App_Main.py index 4d7ea3da..d5b129f0 100644 --- a/App_Main.py +++ b/App_Main.py @@ -2939,7 +2939,7 @@ class App(QtCore.QObject): self.resize(720, 330) logo = QtWidgets.QLabel() - logo.setPixmap(QtGui.QPixmap(self.app.resource_location + '/flatcam_icon256.png')) + logo.setPixmap(QtGui.QPixmap(self.app.resource_location + '/contribute256.png')) content = QtWidgets.QLabel( "This program is %s and free in a very wide meaning of the word.
" diff --git a/CHANGELOG.md b/CHANGELOG.md index b296e4c3..0bee5dcb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ CHANGELOG for FlatCAM beta ================================================= +26.05.2020 + +- working on Isolation Tool: made to work the tool parameters data to GUI and GUI to data +- Isolation Tool: reworked the GUI +- if there is a Gerber object selected then in Isolation Tool the Gerber object combobox will show that object name as current + 25.05.2020 - updated the GUI fields for the Scale and Offset in the Object UI to allow only numeric values and operators in the list [/,*,+,-], spaces, dots and comma diff --git a/assets/resources/contribute256.png b/assets/resources/contribute256.png new file mode 100644 index 00000000..dd1bc479 Binary files /dev/null and b/assets/resources/contribute256.png differ diff --git a/assets/resources/dark_resources/contribute256.png b/assets/resources/dark_resources/contribute256.png new file mode 100644 index 00000000..ab1739dd Binary files /dev/null and b/assets/resources/dark_resources/contribute256.png differ diff --git a/defaults.py b/defaults.py index e2db25b4..5f6178fd 100644 --- a/defaults.py +++ b/defaults.py @@ -177,7 +177,7 @@ class FlatCAMDefaults: "gerber_isooverlap": 10, "gerber_milling_type": "cl", "gerber_combine_passes": False, - "gerber_iso_scope": 'all', + "gerber_iso_scope": _("All"), "gerber_noncoppermargin": 0.1, "gerber_noncopperrounded": False, "gerber_bboxmargin": 0.1, @@ -188,7 +188,7 @@ class FlatCAMDefaults: "gerber_aperture_scale_factor": 1.0, "gerber_aperture_buffer_factor": 0.0, "gerber_follow": False, - "gerber_tool_type": 'circular', + "gerber_tool_type": 'C1', "gerber_vtipdia": 0.1, "gerber_vtipangle": 30, "gerber_vcutz": -0.05,