diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ff06c8f..e3488a26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ CHANGELOG for FlatCAM beta ================================================= +28.08.2020 + +- Paint Tool - upgraded the UI and added the functionality that now adding a new tool is done by first searching the Tools DB for a suitable tool and if fails then it adds an default tool +- Paint Tool - on start will attempt to search in the Tools DB for the default tools and if found will load them from the DB + + 27.08.2020 - fixed the Tcl commands AddCircle, AddPolygon, AddPolyline and AddRectangle to have stored bounds therefore making them movable/selectable on canvas diff --git a/appTools/ToolIsolation.py b/appTools/ToolIsolation.py index e7502f01..cc88f39b 100644 --- a/appTools/ToolIsolation.py +++ b/appTools/ToolIsolation.py @@ -50,23 +50,23 @@ class ToolIsolation(AppTool, Gerber): # ############################################################################# # ######################### Tool GUI ########################################## # ############################################################################# - self.t_ui = IsoUI(layout=self.layout, app=self.app) - self.toolName = self.t_ui.toolName + self.ui = IsoUI(layout=self.layout, app=self.app) + self.toolName = self.ui.toolName # ############################################################################# # ###################### Setup CONTEXT MENU ################################### # ############################################################################# - self.t_ui.tools_table.setupContextMenu() - self.t_ui.tools_table.addContextMenu( + self.ui.tools_table.setupContextMenu() + self.ui.tools_table.addContextMenu( _("Search and Add"), self.on_add_tool_by_key, icon=QtGui.QIcon(self.app.resource_location + "/plus16.png") ) - self.t_ui.tools_table.addContextMenu( + self.ui.tools_table.addContextMenu( _("Pick from DB"), self.on_add_tool_by_key, icon=QtGui.QIcon(self.app.resource_location + "/search_db32.png") ) - self.t_ui.tools_table.addContextMenu( + self.ui.tools_table.addContextMenu( _("Delete"), lambda: self.on_tool_delete(rows_to_delete=None, all_tools=None), icon=QtGui.QIcon(self.app.resource_location + "/trash16.png") @@ -129,12 +129,12 @@ class ToolIsolation(AppTool, Gerber): self.poly_sel_disconnect_flag = False self.form_fields = { - "tools_iso_passes": self.t_ui.passes_entry, - "tools_iso_overlap": self.t_ui.iso_overlap_entry, - "tools_iso_milling_type": self.t_ui.milling_type_radio, - "tools_iso_combine": self.t_ui.combine_passes_cb, - "tools_iso_follow": self.t_ui.follow_cb, - "tools_iso_isotype": self.t_ui.iso_type_radio + "tools_iso_passes": self.ui.passes_entry, + "tools_iso_overlap": self.ui.iso_overlap_entry, + "tools_iso_milling_type": self.ui.milling_type_radio, + "tools_iso_combine": self.ui.combine_passes_cb, + "tools_iso_follow": self.ui.follow_cb, + "tools_iso_isotype": self.ui.iso_type_radio } self.name2option = { @@ -184,7 +184,7 @@ class ToolIsolation(AppTool, Gerber): self.build_ui() # all the tools are selected by default - self.t_ui.tools_table.selectAll() + self.ui.tools_table.selectAll() self.app.ui.notebook.setTabText(2, _("Isolation Tool")) @@ -192,34 +192,34 @@ class ToolIsolation(AppTool, Gerber): # ############################################################################# # ############################ SIGNALS ######################################## # ############################################################################# - self.t_ui.deltool_btn.clicked.connect(self.on_tool_delete) + self.ui.deltool_btn.clicked.connect(self.on_tool_delete) - self.t_ui.find_optimal_button.clicked.connect(self.on_find_optimal_tooldia) - self.optimal_found_sig.connect(lambda val: self.t_ui.new_tooldia_entry.set_value(float(val))) + self.ui.find_optimal_button.clicked.connect(self.on_find_optimal_tooldia) + self.optimal_found_sig.connect(lambda val: self.ui.new_tooldia_entry.set_value(float(val))) - self.t_ui.reference_combo_type.currentIndexChanged.connect(self.on_reference_combo_changed) - self.t_ui.select_combo.currentIndexChanged.connect(self.on_toggle_reference) + self.ui.reference_combo_type.currentIndexChanged.connect(self.on_reference_combo_changed) + self.ui.select_combo.currentIndexChanged.connect(self.on_toggle_reference) - self.t_ui.type_excobj_radio.activated_custom.connect(self.on_type_excobj_index_changed) - self.t_ui.apply_param_to_all.clicked.connect(self.on_apply_param_to_all_clicked) + self.ui.type_excobj_radio.activated_custom.connect(self.on_type_excobj_index_changed) + self.ui.apply_param_to_all.clicked.connect(self.on_apply_param_to_all_clicked) # adding Tools - self.t_ui.add_newtool_button.clicked.connect(lambda: self.on_tool_add()) - self.t_ui.addtool_from_db_btn.clicked.connect(self.on_tool_add_from_db_clicked) + self.ui.add_newtool_button.clicked.connect(lambda: self.on_tool_add()) + self.ui.addtool_from_db_btn.clicked.connect(self.on_tool_add_from_db_clicked) - self.t_ui.generate_iso_button.clicked.connect(self.on_iso_button_click) - self.t_ui.reset_button.clicked.connect(self.set_tool_ui) + self.ui.generate_iso_button.clicked.connect(self.on_iso_button_click) + self.ui.reset_button.clicked.connect(self.set_tool_ui) # Cleanup on Graceful exit (CTRL+ALT+X combo key) self.app.cleanup.connect(self.set_tool_ui) def on_type_excobj_index_changed(self, val): obj_type = 0 if val == 'gerber' else 2 - self.t_ui.exc_obj_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) - self.t_ui.exc_obj_combo.setCurrentIndex(0) - self.t_ui.exc_obj_combo.obj_type = { + self.ui.exc_obj_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) + self.ui.exc_obj_combo.setCurrentIndex(0) + self.ui.exc_obj_combo.obj_type = { "gerber": "Gerber", "geometry": "Geometry" - }[self.t_ui.type_excobj_radio.get_value()] + }[self.ui.type_excobj_radio.get_value()] def set_tool_ui(self): self.units = self.app.defaults['units'].upper() @@ -229,7 +229,7 @@ class ToolIsolation(AppTool, Gerber): selected_obj = self.app.collection.get_active() if selected_obj.kind == 'gerber': current_name = selected_obj.options['name'] - self.t_ui.object_combo.set_value(current_name) + self.ui.object_combo.set_value(current_name) except Exception: pass @@ -237,88 +237,88 @@ class ToolIsolation(AppTool, Gerber): # Show/Hide Advanced Options if app_mode == 'b': - self.t_ui.level.setText('%s' % _('Basic')) + self.ui.level.setText('%s' % _('Basic')) - self.t_ui.milling_type_label.hide() - self.t_ui.milling_type_radio.hide() + self.ui.milling_type_label.hide() + self.ui.milling_type_radio.hide() - self.t_ui.iso_type_label.hide() - self.t_ui.iso_type_radio.set_value('full') - self.t_ui.iso_type_radio.hide() + self.ui.iso_type_label.hide() + self.ui.iso_type_radio.set_value('full') + self.ui.iso_type_radio.hide() - self.t_ui.follow_cb.set_value(False) - self.t_ui.follow_cb.hide() - self.t_ui.follow_label.hide() + self.ui.follow_cb.set_value(False) + self.ui.follow_cb.hide() + self.ui.follow_label.hide() - self.t_ui.rest_cb.set_value(False) - self.t_ui.rest_cb.hide() - self.t_ui.forced_rest_iso_cb.hide() + self.ui.rest_cb.set_value(False) + self.ui.rest_cb.hide() + self.ui.forced_rest_iso_cb.hide() - self.t_ui.except_cb.set_value(False) - self.t_ui.except_cb.hide() + self.ui.except_cb.set_value(False) + self.ui.except_cb.hide() - self.t_ui.type_excobj_radio.hide() - self.t_ui.exc_obj_combo.hide() + self.ui.type_excobj_radio.hide() + self.ui.exc_obj_combo.hide() - self.t_ui.select_combo.setCurrentIndex(0) - self.t_ui.select_combo.hide() - self.t_ui.select_label.hide() + self.ui.select_combo.setCurrentIndex(0) + self.ui.select_combo.hide() + self.ui.select_label.hide() else: - self.t_ui.level.setText('%s' % _('Advanced')) + self.ui.level.setText('%s' % _('Advanced')) - self.t_ui.milling_type_label.show() - self.t_ui.milling_type_radio.show() + self.ui.milling_type_label.show() + self.ui.milling_type_radio.show() - self.t_ui.iso_type_label.show() - self.t_ui.iso_type_radio.set_value(self.app.defaults["tools_iso_isotype"]) - self.t_ui.iso_type_radio.show() + self.ui.iso_type_label.show() + self.ui.iso_type_radio.set_value(self.app.defaults["tools_iso_isotype"]) + self.ui.iso_type_radio.show() - self.t_ui.follow_cb.set_value(self.app.defaults["tools_iso_follow"]) - self.t_ui.follow_cb.show() - self.t_ui.follow_label.show() + self.ui.follow_cb.set_value(self.app.defaults["tools_iso_follow"]) + self.ui.follow_cb.show() + self.ui.follow_label.show() - self.t_ui.rest_cb.set_value(self.app.defaults["tools_iso_rest"]) - self.t_ui.rest_cb.show() - self.t_ui.forced_rest_iso_cb.show() + self.ui.rest_cb.set_value(self.app.defaults["tools_iso_rest"]) + self.ui.rest_cb.show() + self.ui.forced_rest_iso_cb.show() - self.t_ui.except_cb.set_value(self.app.defaults["tools_iso_isoexcept"]) - self.t_ui.except_cb.show() + self.ui.except_cb.set_value(self.app.defaults["tools_iso_isoexcept"]) + self.ui.except_cb.show() - self.t_ui.select_combo.set_value(self.app.defaults["tools_iso_selection"]) - self.t_ui.select_combo.show() - self.t_ui.select_label.show() + self.ui.select_combo.set_value(self.app.defaults["tools_iso_selection"]) + self.ui.select_combo.show() + self.ui.select_label.show() if self.app.defaults["gerber_buffering"] == 'no': - self.t_ui.create_buffer_button.show() + self.ui.create_buffer_button.show() try: - self.t_ui.create_buffer_button.clicked.disconnect(self.on_generate_buffer) + self.ui.create_buffer_button.clicked.disconnect(self.on_generate_buffer) except TypeError: pass - self.t_ui.create_buffer_button.clicked.connect(self.on_generate_buffer) + self.ui.create_buffer_button.clicked.connect(self.on_generate_buffer) else: - self.t_ui.create_buffer_button.hide() + self.ui.create_buffer_button.hide() - self.t_ui.tools_frame.show() + self.ui.tools_frame.show() - self.t_ui.type_excobj_radio.set_value('gerber') + self.ui.type_excobj_radio.set_value('gerber') # run those once so the obj_type attribute is updated for the FCComboboxes # so the last loaded object is displayed self.on_type_excobj_index_changed(val="gerber") self.on_reference_combo_changed() - self.t_ui.order_radio.set_value(self.app.defaults["tools_iso_order"]) - self.t_ui.passes_entry.set_value(self.app.defaults["tools_iso_passes"]) - self.t_ui.iso_overlap_entry.set_value(self.app.defaults["tools_iso_overlap"]) - self.t_ui.milling_type_radio.set_value(self.app.defaults["tools_iso_milling_type"]) - self.t_ui.combine_passes_cb.set_value(self.app.defaults["tools_iso_combine_passes"]) - self.t_ui.area_shape_radio.set_value(self.app.defaults["tools_iso_area_shape"]) - self.t_ui.poly_int_cb.set_value(self.app.defaults["tools_iso_poly_ints"]) - self.t_ui.forced_rest_iso_cb.set_value(self.app.defaults["tools_iso_force"]) + self.ui.order_radio.set_value(self.app.defaults["tools_iso_order"]) + self.ui.passes_entry.set_value(self.app.defaults["tools_iso_passes"]) + self.ui.iso_overlap_entry.set_value(self.app.defaults["tools_iso_overlap"]) + self.ui.milling_type_radio.set_value(self.app.defaults["tools_iso_milling_type"]) + self.ui.combine_passes_cb.set_value(self.app.defaults["tools_iso_combine_passes"]) + self.ui.area_shape_radio.set_value(self.app.defaults["tools_iso_area_shape"]) + self.ui.poly_int_cb.set_value(self.app.defaults["tools_iso_poly_ints"]) + self.ui.forced_rest_iso_cb.set_value(self.app.defaults["tools_iso_force"]) - self.t_ui.new_tooldia_entry.set_value(self.app.defaults["tools_iso_newdia"]) + self.ui.new_tooldia_entry.set_value(self.app.defaults["tools_iso_newdia"]) - loaded_obj = self.app.collection.get_by_name(self.t_ui.object_combo.get_value()) + loaded_obj = self.app.collection.get_by_name(self.ui.object_combo.get_value()) if loaded_obj: outname = loaded_obj.options['name'] else: @@ -391,21 +391,8 @@ class ToolIsolation(AppTool, Gerber): self.tooluid = 0 - # adding tools from Preferences: FIXME should search in Tools Database self.iso_tools.clear() for tool_dia in dias: - # self.tooluid += 1 - # self.iso_tools.update({ - # int(self.tooluid): { - # 'tooldia': float('%.*f' % (self.decimals, tool_dia)), - # 'offset': 'Path', - # 'offset_value': 0.0, - # 'type': 'Iso', - # 'tool_type': 'V', - # 'data': deepcopy(self.default_data), - # 'solid_geometry': [] - # } - # }) self.on_tool_add(custom_dia=tool_dia) self.obj_name = "" @@ -422,24 +409,23 @@ class ToolIsolation(AppTool, Gerber): self.sel_rect = [] self.tool_type_item_options = ["C1", "C2", "C3", "C4", "B", "V"] - self.units = self.app.defaults['units'].upper() self.on_rest_machining_check(state=self.app.defaults["tools_iso_rest"]) - self.t_ui.tools_table.drag_drop_sig.connect(self.rebuild_ui) + self.ui.tools_table.drag_drop_sig.connect(self.rebuild_ui) def rebuild_ui(self): # read the table tools uid - current_uid_list = [] - for row in range(self.t_ui.tools_table.rowCount()): - uid = int(self.t_ui.tools_table.item(row, 3).text()) - current_uid_list.append(uid) + currenuid_list = [] + for row in range(self.ui.tools_table.rowCount()): + uid = int(self.ui.tools_table.item(row, 3).text()) + currenuid_list.append(uid) new_tools = {} new_uid = 1 - for current_uid in current_uid_list: - new_tools[new_uid] = deepcopy(self.iso_tools[current_uid]) + for currenuid in currenuid_list: + new_tools[new_uid] = deepcopy(self.iso_tools[currenuid]) new_uid += 1 self.iso_tools = new_tools @@ -457,7 +443,7 @@ class ToolIsolation(AppTool, Gerber): for k, v in self.iso_tools.items(): sorted_tools.append(self.app.dec_format(float(v['tooldia']), self.decimals)) - order = self.t_ui.order_radio.get_value() + order = self.ui.order_radio.get_value() if order == 'fwd': sorted_tools.sort(reverse=False) elif order == 'rev': @@ -466,7 +452,7 @@ class ToolIsolation(AppTool, Gerber): pass n = len(sorted_tools) - self.t_ui.tools_table.setRowCount(n) + self.ui.tools_table.setRowCount(n) tool_id = 0 for tool_sorted in sorted_tools: @@ -479,76 +465,76 @@ class ToolIsolation(AppTool, Gerber): id_ = QtWidgets.QTableWidgetItem('%d' % int(tool_id)) id_.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) row_no = tool_id - 1 - self.t_ui.tools_table.setItem(row_no, 0, id_) + self.ui.tools_table.setItem(row_no, 0, id_) # Diameter dia = QtWidgets.QTableWidgetItem(str(truncated_dia)) dia.setFlags(QtCore.Qt.ItemIsEnabled) - self.t_ui.tools_table.setItem(row_no, 1, dia) + self.ui.tools_table.setItem(row_no, 1, dia) # Tool Type tool_type_item = FCComboBox() tool_type_item.addItems(self.tool_type_item_options) idx = tool_type_item.findText(tooluid_value['tool_type']) tool_type_item.setCurrentIndex(idx) - self.t_ui.tools_table.setCellWidget(row_no, 2, tool_type_item) + self.ui.tools_table.setCellWidget(row_no, 2, tool_type_item) # Tool unique ID # REMEMBER: THIS COLUMN IS HIDDEN tool_uid_item = QtWidgets.QTableWidgetItem(str(int(tooluid_key))) - self.t_ui.tools_table.setItem(row_no, 3, tool_uid_item) + self.ui.tools_table.setItem(row_no, 3, tool_uid_item) # make the diameter column editable for row in range(tool_id): - self.t_ui.tools_table.item(row, 1).setFlags( + self.ui.tools_table.item(row, 1).setFlags( QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) # all the tools are selected by default - self.t_ui.tools_table.selectColumn(0) + self.ui.tools_table.selectColumn(0) # - self.t_ui.tools_table.resizeColumnsToContents() - self.t_ui.tools_table.resizeRowsToContents() + self.ui.tools_table.resizeColumnsToContents() + self.ui.tools_table.resizeRowsToContents() - vertical_header = self.t_ui.tools_table.verticalHeader() + vertical_header = self.ui.tools_table.verticalHeader() vertical_header.hide() - self.t_ui.tools_table.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) + self.ui.tools_table.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) - horizontal_header = self.t_ui.tools_table.horizontalHeader() + horizontal_header = self.ui.tools_table.horizontalHeader() horizontal_header.setMinimumSectionSize(10) horizontal_header.setSectionResizeMode(0, QtWidgets.QHeaderView.Fixed) horizontal_header.resizeSection(0, 20) horizontal_header.setSectionResizeMode(1, QtWidgets.QHeaderView.Stretch) - # self.t_ui.tools_table.setSortingEnabled(True) + # self.ui.tools_table.setSortingEnabled(True) # sort by tool diameter - # self.t_ui.tools_table.sortItems(1) + # self.ui.tools_table.sortItems(1) - self.t_ui.tools_table.setMinimumHeight(self.t_ui.tools_table.getHeight()) - self.t_ui.tools_table.setMaximumHeight(self.t_ui.tools_table.getHeight()) + self.ui.tools_table.setMinimumHeight(self.ui.tools_table.getHeight()) + self.ui.tools_table.setMaximumHeight(self.ui.tools_table.getHeight()) self.ui_connect() # set the text on tool_data_label after loading the object sel_rows = set() - sel_items = self.t_ui.tools_table.selectedItems() + sel_items = self.ui.tools_table.selectedItems() for it in sel_items: sel_rows.add(it.row()) if len(sel_rows) > 1: - self.t_ui.tool_data_label.setText( + self.ui.tool_data_label.setText( "%s: %s" % (_('Parameters for'), _("Multiple Tools")) ) def ui_connect(self): - self.t_ui.tools_table.itemChanged.connect(self.on_tool_edit) + self.ui.tools_table.itemChanged.connect(self.on_tool_edit) # rows selected - self.t_ui.tools_table.clicked.connect(self.on_row_selection_change) - self.t_ui.tools_table.horizontalHeader().sectionClicked.connect(self.on_toggle_all_rows) + self.ui.tools_table.clicked.connect(self.on_row_selection_change) + self.ui.tools_table.horizontalHeader().sectionClicked.connect(self.on_toggle_all_rows) # tool table widgets - for row in range(self.t_ui.tools_table.rowCount()): + for row in range(self.ui.tools_table.rowCount()): try: - self.t_ui.tools_table.cellWidget(row, 2).currentIndexChanged.connect(self.on_tooltable_cellwidget_change) + self.ui.tools_table.cellWidget(row, 2).currentIndexChanged.connect(self.on_tooltable_cellwidget_change) except AttributeError: pass @@ -564,32 +550,32 @@ class ToolIsolation(AppTool, Gerber): elif isinstance(current_widget, FCComboBox): current_widget.currentIndexChanged.connect(self.form_to_storage) - self.t_ui.rest_cb.stateChanged.connect(self.on_rest_machining_check) - self.t_ui.order_radio.activated_custom[str].connect(self.on_order_changed) + self.ui.rest_cb.stateChanged.connect(self.on_rest_machining_check) + self.ui.order_radio.activated_custom[str].connect(self.on_order_changed) def ui_disconnect(self): try: # if connected, disconnect the signal from the slot on item_changed as it creates issues - self.t_ui.tools_table.itemChanged.disconnect() + self.ui.tools_table.itemChanged.disconnect() except (TypeError, AttributeError): pass # rows selected try: - self.t_ui.tools_table.clicked.disconnect() + self.ui.tools_table.clicked.disconnect() except (TypeError, AttributeError): pass try: - self.t_ui.tools_table.horizontalHeader().sectionClicked.disconnect() + self.ui.tools_table.horizontalHeader().sectionClicked.disconnect() except (TypeError, AttributeError): pass # tool table widgets - for row in range(self.t_ui.tools_table.rowCount()): + for row in range(self.ui.tools_table.rowCount()): try: - self.t_ui.tools_table.cellWidget(row, 2).currentIndexChanged.disconnect() + self.ui.tools_table.cellWidget(row, 2).currentIndexChanged.disconnect() except (TypeError, AttributeError): pass @@ -618,11 +604,11 @@ class ToolIsolation(AppTool, Gerber): pass try: - self.t_ui.rest_cb.stateChanged.disconnect() + self.ui.rest_cb.stateChanged.disconnect() except (TypeError, ValueError): pass try: - self.t_ui.order_radio.activated_custom[str].disconnect() + self.ui.order_radio.activated_custom[str].disconnect() except (TypeError, ValueError): pass @@ -632,7 +618,7 @@ class ToolIsolation(AppTool, Gerber): :return: """ - sel_model = self.t_ui.tools_table.selectionModel() + sel_model = self.ui.tools_table.selectionModel() sel_indexes = sel_model.selectedIndexes() # it will iterate over all indexes which means all items in all columns too but I'm interested only on rows @@ -640,19 +626,19 @@ class ToolIsolation(AppTool, Gerber): for idx in sel_indexes: sel_rows.add(idx.row()) - if len(sel_rows) == self.t_ui.tools_table.rowCount(): - self.t_ui.tools_table.clearSelection() - self.t_ui.tool_data_label.setText( + if len(sel_rows) == self.ui.tools_table.rowCount(): + self.ui.tools_table.clearSelection() + self.ui.tool_data_label.setText( "%s: %s" % (_('Parameters for'), _("No Tool Selected")) ) else: - self.t_ui.tools_table.selectAll() - self.t_ui.tool_data_label.setText( + self.ui.tools_table.selectAll() + self.ui.tool_data_label.setText( "%s: %s" % (_('Parameters for'), _("Multiple Tools")) ) def on_row_selection_change(self): - sel_model = self.t_ui.tools_table.selectionModel() + sel_model = self.ui.tools_table.selectionModel() sel_indexes = sel_model.selectedIndexes() # it will iterate over all indexes which means all items in all columns too but I'm interested only on rows @@ -669,26 +655,26 @@ class ToolIsolation(AppTool, Gerber): self.blockSignals(True) sel_rows = set() - table_items = self.t_ui.tools_table.selectedItems() + table_items = self.ui.tools_table.selectedItems() if table_items: for it in table_items: sel_rows.add(it.row()) - # sel_rows = sorted(set(index.row() for index in self.t_ui.tools_table.selectedIndexes())) + # sel_rows = sorted(set(index.row() for index in self.ui.tools_table.selectedIndexes())) if not sel_rows or len(sel_rows) == 0: - self.t_ui.generate_iso_button.setDisabled(True) - self.t_ui.tool_data_label.setText( + self.ui.generate_iso_button.setDisabled(True) + self.ui.tool_data_label.setText( "%s: %s" % (_('Parameters for'), _("No Tool Selected")) ) self.blockSignals(False) return else: - self.t_ui.generate_iso_button.setDisabled(False) + self.ui.generate_iso_button.setDisabled(False) for current_row in sel_rows: # populate the form with the data from the tool associated with the row parameter try: - item = self.t_ui.tools_table.item(current_row, 3) + item = self.ui.tools_table.item(current_row, 3) if item is not None: tooluid = int(item.text()) else: @@ -700,7 +686,7 @@ class ToolIsolation(AppTool, Gerber): # update the QLabel that shows for which Tool we have the parameters in the UI form if len(sel_rows) == 1: cr = current_row + 1 - self.t_ui.tool_data_label.setText( + self.ui.tool_data_label.setText( "%s: %s %d" % (_('Parameters for'), _("Tool"), cr) ) try: @@ -713,7 +699,7 @@ class ToolIsolation(AppTool, Gerber): except Exception as e: log.debug("ToolIsolation ---> update_ui() " + str(e)) else: - self.t_ui.tool_data_label.setText( + self.ui.tool_data_label.setText( "%s: %s" % (_('Parameters for'), _("Multiple Tools")) ) @@ -730,7 +716,7 @@ class ToolIsolation(AppTool, Gerber): pass def form_to_storage(self): - if self.t_ui.tools_table.rowCount() == 0: + if self.ui.tools_table.rowCount() == 0: # there is no tool in tool table so we can't save the GUI elements values to storage return @@ -740,12 +726,12 @@ class ToolIsolation(AppTool, Gerber): wdg_objname = widget_changed.objectName() option_changed = self.name2option[wdg_objname] - # row = self.t_ui.tools_table.currentRow() - rows = sorted(set(index.row() for index in self.t_ui.tools_table.selectedIndexes())) + # row = self.ui.tools_table.currentRow() + rows = sorted(set(index.row() for index in self.ui.tools_table.selectedIndexes())) for row in rows: if row < 0: row = 0 - tooluid_item = int(self.t_ui.tools_table.item(row, 3).text()) + tooluid_item = int(self.ui.tools_table.item(row, 3).text()) for tooluid_key, tooluid_val in self.iso_tools.items(): if int(tooluid_key) == tooluid_item: @@ -758,18 +744,18 @@ class ToolIsolation(AppTool, Gerber): self.blockSignals(False) def on_apply_param_to_all_clicked(self): - if self.t_ui.tools_table.rowCount() == 0: + if self.ui.tools_table.rowCount() == 0: # there is no tool in tool table so we can't save the GUI elements values to storage log.debug("ToolIsolation.on_apply_param_to_all_clicked() --> no tool in Tools Table, aborting.") return self.blockSignals(True) - row = self.t_ui.tools_table.currentRow() + row = self.ui.tools_table.currentRow() if row < 0: row = 0 - tooluid_item = int(self.t_ui.tools_table.item(row, 3).text()) + tooluid_item = int(self.ui.tools_table.item(row, 3).text()) temp_tool_data = {} for tooluid_key, tooluid_val in self.iso_tools.items(): @@ -802,58 +788,58 @@ class ToolIsolation(AppTool, Gerber): self.app.inform.emit('[WARNING_NOTCL] %s...' % _("Adding Tool cancelled")) def on_reference_combo_changed(self): - obj_type = self.t_ui.reference_combo_type.currentIndex() - self.t_ui.reference_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) - self.t_ui.reference_combo.setCurrentIndex(0) - self.t_ui.reference_combo.obj_type = { + obj_type = self.ui.reference_combo_type.currentIndex() + self.ui.reference_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex())) + self.ui.reference_combo.setCurrentIndex(0) + self.ui.reference_combo.obj_type = { _("Gerber"): "Gerber", _("Excellon"): "Excellon", _("Geometry"): "Geometry" - }[self.t_ui.reference_combo_type.get_value()] + }[self.ui.reference_combo_type.get_value()] def on_toggle_reference(self): - val = self.t_ui.select_combo.get_value() + val = self.ui.select_combo.get_value() if val == _("All"): - self.t_ui.reference_combo.hide() - self.t_ui.reference_combo_label.hide() - self.t_ui.reference_combo_type.hide() - self.t_ui.reference_combo_type_label.hide() - self.t_ui.area_shape_label.hide() - self.t_ui.area_shape_radio.hide() - self.t_ui.poly_int_cb.hide() + self.ui.reference_combo.hide() + self.ui.reference_combo_label.hide() + self.ui.reference_combo_type.hide() + self.ui.reference_combo_type_label.hide() + self.ui.area_shape_label.hide() + self.ui.area_shape_radio.hide() + self.ui.poly_int_cb.hide() # disable rest-machining for area painting - self.t_ui.rest_cb.setDisabled(False) + self.ui.rest_cb.setDisabled(False) elif val == _("Area Selection"): - self.t_ui.reference_combo.hide() - self.t_ui.reference_combo_label.hide() - self.t_ui.reference_combo_type.hide() - self.t_ui.reference_combo_type_label.hide() - self.t_ui.area_shape_label.show() - self.t_ui.area_shape_radio.show() - self.t_ui.poly_int_cb.hide() + self.ui.reference_combo.hide() + self.ui.reference_combo_label.hide() + self.ui.reference_combo_type.hide() + self.ui.reference_combo_type_label.hide() + self.ui.area_shape_label.show() + self.ui.area_shape_radio.show() + self.ui.poly_int_cb.hide() # disable rest-machining for area isolation - self.t_ui.rest_cb.set_value(False) - self.t_ui.rest_cb.setDisabled(True) + self.ui.rest_cb.set_value(False) + self.ui.rest_cb.setDisabled(True) elif val == _("Polygon Selection"): - self.t_ui.reference_combo.hide() - self.t_ui.reference_combo_label.hide() - self.t_ui.reference_combo_type.hide() - self.t_ui.reference_combo_type_label.hide() - self.t_ui.area_shape_label.hide() - self.t_ui.area_shape_radio.hide() - self.t_ui.poly_int_cb.show() + self.ui.reference_combo.hide() + self.ui.reference_combo_label.hide() + self.ui.reference_combo_type.hide() + self.ui.reference_combo_type_label.hide() + self.ui.area_shape_label.hide() + self.ui.area_shape_radio.hide() + self.ui.poly_int_cb.show() else: - self.t_ui.reference_combo.show() - self.t_ui.reference_combo_label.show() - self.t_ui.reference_combo_type.show() - self.t_ui.reference_combo_type_label.show() - self.t_ui.area_shape_label.hide() - self.t_ui.area_shape_radio.hide() - self.t_ui.poly_int_cb.hide() + self.ui.reference_combo.show() + self.ui.reference_combo_label.show() + self.ui.reference_combo_type.show() + self.ui.reference_combo_type_label.show() + self.ui.area_shape_label.hide() + self.ui.area_shape_radio.hide() + self.ui.poly_int_cb.hide() # disable rest-machining for area painting - self.t_ui.rest_cb.setDisabled(False) + self.ui.rest_cb.setDisabled(False) def on_order_changed(self, order): if order != 'no': @@ -861,41 +847,41 @@ class ToolIsolation(AppTool, Gerber): def on_rest_machining_check(self, state): if state: - self.t_ui.order_radio.set_value('rev') - self.t_ui.order_label.setDisabled(True) - self.t_ui.order_radio.setDisabled(True) + self.ui.order_radio.set_value('rev') + self.ui.order_label.setDisabled(True) + self.ui.order_radio.setDisabled(True) - self.old_combine_state = self.t_ui.combine_passes_cb.get_value() - self.t_ui.combine_passes_cb.set_value(True) - self.t_ui.combine_passes_cb.setDisabled(True) + self.old_combine_state = self.ui.combine_passes_cb.get_value() + self.ui.combine_passes_cb.set_value(True) + self.ui.combine_passes_cb.setDisabled(True) - self.t_ui.forced_rest_iso_cb.setDisabled(False) + self.ui.forced_rest_iso_cb.setDisabled(False) else: - self.t_ui.order_label.setDisabled(False) - self.t_ui.order_radio.setDisabled(False) + self.ui.order_label.setDisabled(False) + self.ui.order_radio.setDisabled(False) - self.t_ui.combine_passes_cb.set_value(self.old_combine_state) - self.t_ui.combine_passes_cb.setDisabled(False) + self.ui.combine_passes_cb.set_value(self.old_combine_state) + self.ui.combine_passes_cb.setDisabled(False) - self.t_ui.forced_rest_iso_cb.setDisabled(True) + self.ui.forced_rest_iso_cb.setDisabled(True) def on_tooltable_cellwidget_change(self): cw = self.sender() assert isinstance(cw, QtWidgets.QComboBox), \ "Expected a QtWidgets.QComboBox, got %s" % isinstance(cw, QtWidgets.QComboBox) - cw_index = self.t_ui.tools_table.indexAt(cw.pos()) + cw_index = self.ui.tools_table.indexAt(cw.pos()) cw_row = cw_index.row() cw_col = cw_index.column() - current_uid = int(self.t_ui.tools_table.item(cw_row, 3).text()) + currenuid = int(self.ui.tools_table.item(cw_row, 3).text()) # if the sender is in the column with index 2 then we update the tool_type key if cw_col == 2: tt = cw.currentText() typ = 'Iso' if tt == 'V' else "Rough" - self.iso_tools[current_uid].update({ + self.iso_tools[currenuid].update({ 'type': typ, 'tool_type': tt, }) @@ -903,7 +889,7 @@ class ToolIsolation(AppTool, Gerber): def on_find_optimal_tooldia(self): self.units = self.app.defaults['units'].upper() - obj_name = self.t_ui.object_combo.currentText() + obj_name = self.ui.object_combo.currentText() # Get source object. try: @@ -1019,7 +1005,7 @@ class ToolIsolation(AppTool, Gerber): # determine the new tool diameter if custom_dia is None: - tool_dia = self.t_ui.new_tooldia_entry.get_value() + tool_dia = self.ui.new_tooldia_entry.get_value() else: tool_dia = custom_dia if tool_dia is None or tool_dia == 0: @@ -1139,9 +1125,9 @@ class ToolIsolation(AppTool, Gerber): self.build_ui() # select the tool just added - for row in range(self.t_ui.tools_table.rowCount()): - if int(self.t_ui.tools_table.item(row, 3).text()) == tooluid: - self.t_ui.tools_table.selectRow(row) + for row in range(self.ui.tools_table.rowCount()): + if int(self.ui.tools_table.item(row, 3).text()) == tooluid: + self.ui.tools_table.selectRow(row) break # update the UI form @@ -1151,13 +1137,12 @@ class ToolIsolation(AppTool, Gerber): def on_tool_default_add(self, dia=None, muted=None): self.blockSignals(True) - self.units = self.app.defaults['units'].upper() if dia: tool_dia = dia else: - tool_dia = self.t_ui.new_tooldia_entry.get_value() + tool_dia = self.ui.new_tooldia_entry.get_value() if tool_dia is None or tool_dia == 0: self.build_ui() @@ -1166,8 +1151,6 @@ class ToolIsolation(AppTool, Gerber): self.blockSignals(False) return - tool_dia = self.app.dec_format(tool_dia, self.decimals) - # construct a list of all 'tooluid' in the self.iso_tools tool_uid_list = [int(tooluid_key) for tooluid_key in self.iso_tools] @@ -1185,7 +1168,7 @@ class ToolIsolation(AppTool, Gerber): if truncated_tooldia in tool_dias: if muted is None: self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. Tool already in Tool Table.")) - # self.t_ui.tools_table.itemChanged.connect(self.on_tool_edit) + # self.ui.tools_table.itemChanged.connect(self.on_tool_edit) self.blockSignals(False) return @@ -1205,9 +1188,9 @@ class ToolIsolation(AppTool, Gerber): self.build_ui() # select the tool just added - for row in range(self.t_ui.tools_table.rowCount()): - if int(self.t_ui.tools_table.item(row, 3).text()) == self.tooluid: - self.t_ui.tools_table.selectRow(row) + for row in range(self.ui.tools_table.rowCount()): + if int(self.ui.tools_table.item(row, 3).text()) == self.tooluid: + self.ui.tools_table.selectRow(row) break # update the UI form @@ -1220,15 +1203,15 @@ class ToolIsolation(AppTool, Gerber): self.blockSignals(True) edited_row = item.row() - editeduid = int(self.t_ui.tools_table.item(edited_row, 3).text()) + editeduid = int(self.ui.tools_table.item(edited_row, 3).text()) tool_dias = [] try: - new_tool_dia = float(self.t_ui.tools_table.item(edited_row, 1).text()) + new_tool_dia = float(self.ui.tools_table.item(edited_row, 1).text()) except ValueError: # try to convert comma to decimal point. if it's still not working error message and return try: - new_tool_dia = float(self.t_ui.tools_table.item(edited_row, 1).text().replace(',', '.')) + new_tool_dia = float(self.ui.tools_table.item(edited_row, 1).text().replace(',', '.')) except ValueError: self.app.inform.emit('[ERROR_NOTCL] %s' % _("Wrong value format entered, use a number.")) self.blockSignals(False) @@ -1249,7 +1232,7 @@ class ToolIsolation(AppTool, Gerber): for k, v in self.iso_tools.items(): if k == editeduid: old_tool_dia = v['tooldia'] - restore_dia_item = self.t_ui.tools_table.item(edited_row, 1) + restore_dia_item = self.ui.tools_table.item(edited_row, 1) restore_dia_item.setText(str(old_tool_dia)) break @@ -1278,10 +1261,10 @@ class ToolIsolation(AppTool, Gerber): if rows_to_delete: try: for row in rows_to_delete: - tooluid_del = int(self.t_ui.tools_table.item(row, 3).text()) + tooluid_del = int(self.ui.tools_table.item(row, 3).text()) deleted_tools_list.append(tooluid_del) except TypeError: - tooluid_del = int(self.t_ui.tools_table.item(rows_to_delete, 3).text()) + tooluid_del = int(self.ui.tools_table.item(rows_to_delete, 3).text()) deleted_tools_list.append(tooluid_del) for t in deleted_tools_list: @@ -1292,12 +1275,12 @@ class ToolIsolation(AppTool, Gerber): return try: - if self.t_ui.tools_table.selectedItems(): - for row_sel in self.t_ui.tools_table.selectedItems(): + if self.ui.tools_table.selectedItems(): + for row_sel in self.ui.tools_table.selectedItems(): row = row_sel.row() if row < 0: continue - tooluid_del = int(self.t_ui.tools_table.item(row, 3).text()) + tooluid_del = int(self.ui.tools_table.item(row, 3).text()) deleted_tools_list.append(tooluid_del) for t in deleted_tools_list: @@ -1317,7 +1300,7 @@ class ToolIsolation(AppTool, Gerber): def on_generate_buffer(self): self.app.inform.emit('[WARNING_NOTCL] %s...' % _("Buffering solid geometry")) - self.obj_name = self.t_ui.object_combo.currentText() + self.obj_name = self.ui.object_combo.currentText() # Get source object. try: @@ -1344,7 +1327,7 @@ class ToolIsolation(AppTool, Gerber): def on_iso_button_click(self): - self.obj_name = self.t_ui.object_combo.currentText() + self.obj_name = self.ui.object_combo.currentText() # Get source object. try: @@ -1406,7 +1389,7 @@ class ToolIsolation(AppTool, Gerber): :type isolated_obj: AppObjects.FlatCAMGerber.GerberObject :return: None """ - selection = self.t_ui.select_combo.get_value() + selection = self.ui.select_combo.get_value() if selection == _("All"): self.isolate(isolated_obj=isolated_obj) @@ -1451,7 +1434,7 @@ class ToolIsolation(AppTool, Gerber): self.poly_sel_disconnect_flag = True elif selection == _("Reference Object"): - ref_obj = self.app.collection.get_by_name(self.t_ui.reference_combo.get_value()) + ref_obj = self.app.collection.get_by_name(self.ui.reference_combo.get_value()) ref_geo = cascaded_union(ref_obj.solid_geometry) use_geo = cascaded_union(isolated_obj.solid_geometry).difference(ref_geo) self.isolate(isolated_obj=isolated_obj, geometry=use_geo) @@ -1473,14 +1456,14 @@ class ToolIsolation(AppTool, Gerber): :return: None """ - combine = self.t_ui.combine_passes_cb.get_value() + combine = self.ui.combine_passes_cb.get_value() tools_storage = self.iso_tools sorted_tools = [] - table_items = self.t_ui.tools_table.selectedItems() + table_items = self.ui.tools_table.selectedItems() sel_rows = {t.row() for t in table_items} for row in sel_rows: - tid = int(self.t_ui.tools_table.item(row, 3).text()) + tid = int(self.ui.tools_table.item(row, 3).text()) sorted_tools.append(tid) if not sorted_tools: self.app.inform.emit('[ERROR_NOTCL] %s' % _("No selected tools in Tool Table.")) @@ -1490,14 +1473,14 @@ class ToolIsolation(AppTool, Gerber): for tool_iso in self.iso_tools: for key in self.iso_tools[tool_iso]: if key == 'data': - self.iso_tools[tool_iso][key]["tools_iso_rest"] = self.t_ui.rest_cb.get_value() + self.iso_tools[tool_iso][key]["tools_iso_rest"] = self.ui.rest_cb.get_value() self.iso_tools[tool_iso][key]["tools_iso_combine_passes"] = combine - self.iso_tools[tool_iso][key]["tools_iso_isoexcept"] = self.t_ui.except_cb.get_value() - self.iso_tools[tool_iso][key]["tools_iso_selection"] = self.t_ui.select_combo.get_value() - self.iso_tools[tool_iso][key]["tools_iso_area_shape"] = self.t_ui.area_shape_radio.get_value() + self.iso_tools[tool_iso][key]["tools_iso_isoexcept"] = self.ui.except_cb.get_value() + self.iso_tools[tool_iso][key]["tools_iso_selection"] = self.ui.select_combo.get_value() + self.iso_tools[tool_iso][key]["tools_iso_area_shape"] = self.ui.area_shape_radio.get_value() if combine: - if self.t_ui.rest_cb.get_value(): + if self.ui.rest_cb.get_value(): self.combined_rest(iso_obj=isolated_obj, iso2geo=geometry, tools_storage=tools_storage, lim_area=limited_area, negative_dia=negative_dia, plot=plot) else: @@ -1527,7 +1510,7 @@ class ToolIsolation(AppTool, Gerber): milling_type = tool_data['tools_iso_milling_type'] - iso_except = self.t_ui.except_cb.get_value() + iso_except = self.ui.except_cb.get_value() for i in range(passes): tool_dia = tools_storage[tool]['tooldia'] @@ -1587,7 +1570,7 @@ class ToolIsolation(AppTool, Gerber): # ############################################################ # ########## AREA SUBTRACTION ################################ # ############################################################ - if self.t_ui.except_cb.get_value(): + if self.ui.except_cb.get_value(): self.app.proc_container.update_view_text(' %s' % _("Subtracting Geo")) geo_obj.solid_geometry = self.area_subtraction(geo_obj.solid_geometry) @@ -1670,15 +1653,15 @@ class ToolIsolation(AppTool, Gerber): # sorted_tools.append(float('%.*f' % (self.decimals, float(v['tooldia'])))) sorted_tools = [] - table_items = self.t_ui.tools_table.selectedItems() + table_items = self.ui.tools_table.selectedItems() sel_rows = {t.row() for t in table_items} for row in sel_rows: try: - tdia = float(self.t_ui.tools_table.item(row, 1).text()) + tdia = float(self.ui.tools_table.item(row, 1).text()) except ValueError: # try to convert comma to decimal point. if it's still not working error message and return try: - tdia = float(self.t_ui.tools_table.item(row, 1).text().replace(',', '.')) + tdia = float(self.ui.tools_table.item(row, 1).text().replace(',', '.')) except ValueError: self.app.inform.emit('[ERROR_NOTCL] %s' % _("Wrong value format entered, use a number.")) continue @@ -1688,7 +1671,7 @@ class ToolIsolation(AppTool, Gerber): self.app.inform.emit('[ERROR_NOTCL] %s' % _("No selected tools in Tool Table.")) return 'fail' - order = self.t_ui.order_radio.get_value() + order = self.ui.order_radio.get_value() if order == 'fwd': sorted_tools.sort(reverse=False) elif order == 'rev': @@ -1720,8 +1703,8 @@ class ToolIsolation(AppTool, Gerber): 'full': 2 }[tool_data['tools_iso_isotype']] - forced_rest = self.t_ui.forced_rest_iso_cb.get_value() - iso_except = self.t_ui.except_cb.get_value() + forced_rest = self.ui.forced_rest_iso_cb.get_value() + iso_except = self.ui.except_cb.get_value() outname = "%s_%.*f" % (iso_obj.options["name"], self.decimals, float(tool_dia)) internal_name = outname + "_iso" @@ -1866,10 +1849,10 @@ class ToolIsolation(AppTool, Gerber): prog_plot = self.app.defaults["tools_iso_plotting"] sorted_tools = [] - table_items = self.t_ui.tools_table.selectedItems() + table_items = self.ui.tools_table.selectedItems() sel_rows = {t.row() for t in table_items} for row in sel_rows: - tid = int(self.t_ui.tools_table.item(row, 3).text()) + tid = int(self.ui.tools_table.item(row, 3).text()) sorted_tools.append(tid) if not sorted_tools: self.app.inform.emit('[ERROR_NOTCL] %s' % _("No selected tools in Tool Table.")) @@ -1900,7 +1883,7 @@ class ToolIsolation(AppTool, Gerber): milling_type = tool_data['tools_iso_milling_type'] - iso_except = self.t_ui.except_cb.get_value() + iso_except = self.ui.except_cb.get_value() outname = "%s_%.*f" % (iso_obj.options["name"], self.decimals, float(tool_dia)) @@ -2028,7 +2011,7 @@ class ToolIsolation(AppTool, Gerber): if subtraction_geo: sub_union = cascaded_union(subtraction_geo) else: - name = self.t_ui.exc_obj_combo.currentText() + name = self.ui.exc_obj_combo.currentText() subtractor_obj = self.app.collection.get_by_name(name) sub_union = cascaded_union(subtractor_obj.solid_geometry) @@ -2151,7 +2134,7 @@ class ToolIsolation(AppTool, Gerber): curr_pos = (curr_pos[0], curr_pos[1]) if event.button == 1: - if self.t_ui.poly_int_cb.get_value() is True: + if self.ui.poly_int_cb.get_value() is True: clicked_poly = self.find_polygon_ignore_interiors(point=(curr_pos[0], curr_pos[1]), geoset=self.grb_obj.solid_geometry) @@ -2213,7 +2196,7 @@ class ToolIsolation(AppTool, Gerber): if self.poly_dict: poly_list = deepcopy(list(self.poly_dict.values())) - if self.t_ui.poly_int_cb.get_value() is True: + if self.ui.poly_int_cb.get_value() is True: # isolate the interior polygons with a negative tool self.isolate(isolated_obj=self.grb_obj, geometry=poly_list, negative_dia=True) else: @@ -2351,7 +2334,7 @@ class ToolIsolation(AppTool, Gerber): return "" elif event.button == right_button and self.mouse_is_dragging is False: - shape_type = self.t_ui.area_shape_radio.get_value() + shape_type = self.ui.area_shape_radio.get_value() if shape_type == "square": self.first_click = False @@ -2411,7 +2394,7 @@ class ToolIsolation(AppTool, Gerber): # called on mouse move def on_mouse_move(self, event): - shape_type = self.t_ui.area_shape_radio.get_value() + shape_type = self.ui.area_shape_radio.get_value() if self.app.is_legacy is False: event_pos = event.pos @@ -2569,9 +2552,9 @@ class ToolIsolation(AppTool, Gerber): # select last tool added toolid = res - for row in range(self.t_ui.tools_table.rowCount()): - if int(self.t_ui.tools_table.item(row, 3).text()) == toolid: - self.t_ui.tools_table.selectRow(row) + for row in range(self.ui.tools_table.rowCount()): + if int(self.ui.tools_table.item(row, 3).text()) == toolid: + self.ui.tools_table.selectRow(row) self.on_row_selection_change() def on_tool_from_db_inserted(self, tool): @@ -2587,38 +2570,31 @@ class ToolIsolation(AppTool, Gerber): tooldia = float(tool['tooldia']) # construct a list of all 'tooluid' in the self.tools - tool_uid_list = [] - for tooluid_key in self.iso_tools: - tool_uid_item = int(tooluid_key) - tool_uid_list.append(tool_uid_item) + tool_uid_list = [int(tooluid_key) for tooluid_key in self.iso_tools] # find maximum from the temp_uid, add 1 and this is the new 'tooluid' - if not tool_uid_list: - max_uid = 0 - else: - max_uid = max(tool_uid_list) + max_uid = 0 if not tool_uid_list else max(tool_uid_list) tooluid = max_uid + 1 - tooldia = float('%.*f' % (self.decimals, tooldia)) - tool_dias = [] for k, v in self.iso_tools.items(): for tool_v in v.keys(): if tool_v == 'tooldia': - tool_dias.append(float('%.*f' % (self.decimals, (v[tool_v])))) + tool_dias.append(self.app.dec_format(v[tool_v], self.decimals)) - if float('%.*f' % (self.decimals, tooldia)) in tool_dias: + truncated_tooldia = self.app.dec_format(tooldia, self.decimals) + if truncated_tooldia in tool_dias: self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. Tool already in Tool Table.")) self.ui_connect() return 'fail' self.iso_tools.update({ tooluid: { - 'tooldia': float('%.*f' % (self.decimals, tooldia)), - 'offset': tool['offset'], - 'offset_value': tool['offset_value'], - 'type': tool['type'], - 'tool_type': tool['tool_type'], + 'tooldia': truncated_tooldia, + 'offset': deepcopy(tool['offset']), + 'offset_value': deepcopy(tool['offset_value']), + 'type': deepcopy(tool['type']), + 'tool_type': deepcopy(tool['tool_type']), 'data': deepcopy(tool['data']), 'solid_geometry': [] } @@ -2632,12 +2608,12 @@ class ToolIsolation(AppTool, Gerber): self.build_ui() # select the tool just added - for row in range(self.t_ui.tools_table.rowCount()): - if int(self.t_ui.tools_table.item(row, 3).text()) == self.tooluid: - self.t_ui.tools_table.selectRow(row) + for row in range(self.ui.tools_table.rowCount()): + if int(self.ui.tools_table.item(row, 3).text()) == self.tooluid: + self.ui.tools_table.selectRow(row) break - # if self.t_ui.tools_table.rowCount() != 0: + # if self.ui.tools_table.rowCount() != 0: # self.param_frame.setDisabled(False) def on_tool_add_from_db_clicked(self): @@ -3116,7 +3092,6 @@ class IsoUI: "from the Tool Database.\n" "Tool database administration in Menu: Options -> Tools Database") ) - bhlay.addWidget(self.addtool_from_db_btn) self.grid3.addLayout(bhlay, 7, 0, 1, 2) diff --git a/appTools/ToolPaint.py b/appTools/ToolPaint.py index 5f420bce..e5b93664 100644 --- a/appTools/ToolPaint.py +++ b/appTools/ToolPaint.py @@ -10,10 +10,11 @@ from PyQt5.QtCore import Qt from appTool import AppTool from copy import deepcopy -# from ObjectCollection import * + from appParsers.ParseGerber import Gerber from camlib import Geometry, FlatCAMRTreeStorage, grace -from appGUI.GUIElements import FCTable, FCDoubleSpinner, FCCheckBox, FCInputDialog, RadioSet, FCButton, FCComboBox +from appGUI.GUIElements import FCTable, FCDoubleSpinner, FCCheckBox, FCInputDialog, RadioSet, FCButton, FCComboBox, \ + FCLabel from shapely.geometry import base, Polygon, MultiPolygon, LinearRing, Point from shapely.ops import cascaded_union, unary_union, linemerge @@ -21,10 +22,11 @@ from shapely.ops import cascaded_union, unary_union, linemerge from matplotlib.backend_bases import KeyEvent as mpl_key_event import numpy as np -import math from numpy import Inf import traceback +import sys import logging +import simplejson as json import gettext import appTranslation as fcTranslate @@ -119,8 +121,6 @@ class ToolPaint(AppTool, Gerber): 'p_contour': "tools_paintcontour", } - self.old_tool_dia = None - # store here the points for the "Polygon" area selection shape self.points = [] # set this as True when in middle of drawing a "Polygon" area selection shape @@ -171,21 +171,19 @@ class ToolPaint(AppTool, Gerber): # ############################################################################# # ################################# Signals ################################### # ############################################################################# - self.ui.addtool_btn.clicked.connect(self.on_tool_add) - self.ui.addtool_entry.returnPressed.connect(self.on_tool_add) + self.ui.new_tooldia_entry.returnPressed.connect(self.on_tool_add) self.ui.deltool_btn.clicked.connect(self.on_tool_delete) - self.ui.tipdia_entry.returnPressed.connect(self.on_calculate_tooldia) - self.ui.tipangle_entry.returnPressed.connect(self.on_calculate_tooldia) - self.ui.cutz_entry.returnPressed.connect(self.on_calculate_tooldia) - self.ui.generate_paint_button.clicked.connect(self.on_paint_button_click) - self.ui.selectmethod_combo.currentIndexChanged.connect(self.on_selection) + self.ui.selectmethod_combo.currentIndexChanged.connect(self.ui.on_selection) self.ui.reference_type_combo.currentIndexChanged.connect(self.on_reference_combo_changed) self.ui.type_obj_radio.activated_custom.connect(self.on_type_obj_changed) self.ui.apply_param_to_all.clicked.connect(self.on_apply_param_to_all_clicked) + + # adding tools + self.ui.add_newtool_button.clicked.connect(lambda: self.on_tool_add()) self.ui.addtool_from_db_btn.clicked.connect(self.on_paint_tool_add_from_db_clicked) self.ui.reset_button.clicked.connect(self.set_tool_ui) @@ -422,113 +420,14 @@ class ToolPaint(AppTool, Gerber): 'tool_type': tt, }) - def on_tool_type(self, val): - if val == 'V': - self.ui.addtool_entry_lbl.setDisabled(True) - self.ui.addtool_entry.setDisabled(True) - self.ui.tipdialabel.show() - self.ui.tipdia_entry.show() - self.ui.tipanglelabel.show() - self.ui.tipangle_entry.show() - - self.on_calculate_tooldia() - else: - self.ui.addtool_entry_lbl.setDisabled(False) - self.ui.addtool_entry.setDisabled(False) - self.ui.tipdialabel.hide() - self.ui.tipdia_entry.hide() - self.ui.tipanglelabel.hide() - self.ui.tipangle_entry.hide() - - self.ui.addtool_entry.set_value(self.old_tool_dia) - - def on_calculate_tooldia(self): - if self.ui.tool_type_radio.get_value() == 'V': - tip_dia = float(self.ui.tipdia_entry.get_value()) - tip_angle = float(self.ui.tipangle_entry.get_value()) / 2.0 - cut_z = float(self.ui.cutz_entry.get_value()) - cut_z = -cut_z if cut_z < 0 else cut_z - - # calculated tool diameter so the cut_z parameter is obeyed - tool_dia = tip_dia + (2 * cut_z * math.tan(math.radians(tip_angle))) - - # update the default_data so it is used in the ncc_tools dict - self.default_data.update({ - "vtipdia": tip_dia, - "vtipangle": (tip_angle * 2), - }) - - self.ui.addtool_entry.set_value(tool_dia) - - return tool_dia - else: - return float(self.ui.addtool_entry.get_value()) - - def on_selection(self): - sel_combo = self.ui.selectmethod_combo.get_value() - - if sel_combo == _("Reference Object"): - self.ui.reference_combo.show() - self.ui.reference_combo_label.show() - self.ui.reference_type_combo.show() - self.ui.reference_type_label.show() - else: - self.ui.reference_combo.hide() - self.ui.reference_combo_label.hide() - self.ui.reference_type_combo.hide() - self.ui.reference_type_label.hide() - - if sel_combo == _("Polygon Selection"): - # disable rest-machining for single polygon painting - # self.ui.rest_cb.set_value(False) - # self.ui.rest_cb.setDisabled(True) - pass - - if sel_combo == _("Area Selection"): - # disable rest-machining for area painting - # self.ui.rest_cb.set_value(False) - # self.ui.rest_cb.setDisabled(True) - - self.ui.area_shape_label.show() - self.ui.area_shape_radio.show() - else: - self.ui.addtool_entry.setDisabled(False) - self.ui.addtool_btn.setDisabled(False) - self.ui.deltool_btn.setDisabled(False) - self.ui.tools_table.setContextMenuPolicy(Qt.ActionsContextMenu) - - self.ui.area_shape_label.hide() - self.ui.area_shape_radio.hide() - def on_order_changed(self, order): if order != 'no': self.build_ui() - def on_rest_machining_check(self, state): - if state: - self.ui.order_radio.set_value('rev') - self.ui.order_label.setDisabled(True) - self.ui.order_radio.setDisabled(True) - - self.ui.offset_label.hide() - self.ui.offset_entry.hide() - self.ui.rest_offset_label.show() - self.ui.rest_offset_entry.show() - else: - self.ui.order_label.setDisabled(False) - self.ui.order_radio.setDisabled(False) - - self.ui.offset_label.show() - self.ui.offset_entry.show() - self.ui.rest_offset_label.hide() - self.ui.rest_offset_entry.hide() - def set_tool_ui(self): self.ui.tools_frame.show() self.reset_fields() - self.old_tool_dia = self.app.defaults["tools_paintnewdia"] - # updated units self.units = self.app.defaults['units'].upper() @@ -588,15 +487,9 @@ class ToolPaint(AppTool, Gerber): self.ui.paintcontour_cb.set_value(self.app.defaults["tools_paintcontour"]) self.ui.paintoverlap_entry.set_value(self.app.defaults["tools_paintoverlap"]) - self.ui.cutz_entry.set_value(self.app.defaults["tools_paintcutz"]) - self.ui.tool_type_radio.set_value(self.app.defaults["tools_painttool_type"]) - self.ui.tipdia_entry.set_value(self.app.defaults["tools_painttipdia"]) - self.ui.tipangle_entry.set_value(self.app.defaults["tools_painttipangle"]) - self.ui.addtool_entry.set_value(self.app.defaults["tools_paintnewdia"]) + self.ui.new_tooldia_entry.set_value(self.app.defaults["tools_paintnewdia"]) self.ui.rest_cb.set_value(self.app.defaults["tools_paintrest"]) - self.on_tool_type(val=self.ui.tool_type_radio.get_value()) - # # make the default object type, "Geometry" # self.type_obj_radio.set_value("geometry") @@ -629,22 +522,24 @@ class ToolPaint(AppTool, Gerber): try: diameters = [float(self.app.defaults["tools_painttooldia"])] except (ValueError, TypeError): - diameters = [eval(x) for x in self.app.defaults["tools_painttooldia"].split(",") if x != ''] + if isinstance(self.app.defaults["tools_painttooldia"], str): + diameters = [eval(x) for x in self.app.defaults["tools_painttooldia"].split(",") if x != ''] + else: + diameters = self.app.defaults["tools_painttooldia"] if not diameters: log.error("At least one tool diameter needed. Verify in Edit -> Preferences -> TOOLS -> NCC Tools.") self.build_ui() + # if the Paint Method is "Single" disable the tool table context menu if self.default_data["tools_selectmethod"] == "single": self.ui.tools_table.setContextMenuPolicy(Qt.NoContextMenu) return - # call on self.on_tool_add() counts as an call to self.build_ui() - # through this, we add a initial row / tool in the tool_table for dia in diameters: - self.on_tool_add(dia, muted=True) + self.on_tool_add(custom_dia=dia) - self.on_rest_machining_check(state=self.app.defaults["tools_paintrest"]) + self.ui.on_rest_machining_check(state=self.app.defaults["tools_paintrest"]) # if the Paint Method is "Single" disable the tool table context menu if self.default_data["tools_selectmethod"] == "single": @@ -759,57 +654,206 @@ class ToolPaint(AppTool, Gerber): "%s: %s" % (_('Parameters for'), _("Multiple Tools")) ) - def on_tool_add(self, dia=None, muted=None): + def on_tool_add(self, custom_dia=None): self.blockSignals(True) + filename = self.app.data_path + '\\tools_db.FlatDB' + + new_tools_dict = deepcopy(self.default_data) + updated_tooldia = None + + # construct a list of all 'tooluid' in the self.iso_tools + tool_uid_list = [int(tooluid_key) for tooluid_key in self.paint_tools] + + # find maximum from the temp_uid, add 1 and this is the new 'tooluid' + max_uid = 0 if not tool_uid_list else max(tool_uid_list) + tooluid = int(max_uid + 1) + + tool_dias = [] + for k, v in self.paint_tools.items(): + for tool_v in v.keys(): + if tool_v == 'tooldia': + tool_dias.append(self.app.dec_format(v[tool_v], self.decimals)) + + # determine the new tool diameter + if custom_dia is None: + tool_dia = self.ui.new_tooldia_entry.get_value() + else: + tool_dia = custom_dia + if tool_dia is None or tool_dia == 0: + self.build_ui() + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Please enter a tool diameter with non-zero value, " + "in Float format.")) + self.blockSignals(False) + return + truncated_tooldia = self.app.dec_format(tool_dia, self.decimals) + + # if new tool diameter already in the Tool List then abort + if truncated_tooldia in tool_dias: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. Tool already in Tool Table.")) + self.blockSignals(False) + return + + # load the database tools from the file + try: + with open(filename) as f: + tools = f.read() + except IOError: + self.app.log.error("Could not load tools DB file.") + self.app.inform.emit('[ERROR] %s' % _("Could not load Tools DB file.")) + self.blockSignals(False) + self.on_tool_default_add() + return + + try: + # store here the tools from Tools Database when searching in Tools Database + tools_db_dict = json.loads(tools) + except Exception: + e = sys.exc_info()[0] + self.app.log.error(str(e)) + self.app.inform.emit('[ERROR] %s' % _("Failed to parse Tools DB file.")) + self.blockSignals(False) + self.on_tool_default_add() + return + + tool_found = 0 + + offset = 'Path' + offset_val = 0.0 + typ = "Rough" + tool_type = 'V' + # look in database tools + for db_tool, db_tool_val in tools_db_dict.items(): + offset = db_tool_val['offset'] + offset_val = db_tool_val['offset_value'] + typ = db_tool_val['type'] + tool_type = db_tool_val['tool_type'] + + db_tooldia = db_tool_val['tooldia'] + low_limit = float(db_tool_val['data']['tol_min']) + high_limit = float(db_tool_val['data']['tol_max']) + + # we need only tool marked for Paint Tool + if db_tool_val['data']['tool_target'] != _('Paint'): + continue + + # if we find a tool with the same diameter in the Tools DB just update it's data + if truncated_tooldia == db_tooldia: + tool_found += 1 + for d in db_tool_val['data']: + if d.find('tools_paint') == 0: + new_tools_dict[d] = db_tool_val['data'][d] + elif d.find('tools_') == 0: + # don't need data for other App Tools; this tests after 'tools_drill_' + continue + else: + new_tools_dict[d] = db_tool_val['data'][d] + # search for a tool that has a tolerance that the tool fits in + elif high_limit >= truncated_tooldia >= low_limit: + tool_found += 1 + updated_tooldia = db_tooldia + for d in db_tool_val['data']: + if d.find('tools_paint') == 0: + new_tools_dict[d] = db_tool_val['data'][d] + elif d.find('tools_') == 0: + # don't need data for other App Tools; this tests after 'tools_drill_' + continue + else: + new_tools_dict[d] = db_tool_val['data'][d] + + # test we found a suitable tool in Tools Database or if multiple ones + if tool_found == 0: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Tool not in Tools Database. Adding a default tool.")) + self.on_tool_default_add() + self.blockSignals(False) + return + + if tool_found > 1: + self.app.inform.emit( + '[WARNING_NOTCL] %s' % _("Cancelled.\n" + "Multiple tools for one tool diameter found in Tools Database.")) + self.blockSignals(False) + return + + # if new tool diameter found in Tools Database already in the Tool List then abort + if updated_tooldia is not None and updated_tooldia in tool_dias: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. Tool already in Tool Table.")) + self.blockSignals(False) + return + + new_tdia = deepcopy(updated_tooldia) if updated_tooldia is not None else deepcopy(truncated_tooldia) + self.paint_tools.update({ + tooluid: { + 'tooldia': new_tdia, + 'offset': deepcopy(offset), + 'offset_value': deepcopy(offset_val), + 'type': deepcopy(typ), + 'tool_type': deepcopy(tool_type), + 'data': deepcopy(new_tools_dict), + 'solid_geometry': [] + } + }) + self.blockSignals(False) + self.build_ui() + + # select the tool just added + for row in range(self.ui.tools_table.rowCount()): + if int(self.ui.tools_table.item(row, 3).text()) == tooluid: + self.ui.tools_table.selectRow(row) + break + + # update the UI form + self.update_ui() + + self.app.inform.emit('[success] %s' % _("New tool added to Tool Table from Tools Database.")) + + def on_tool_default_add(self, dia=None, muted=None): + self.blockSignals(True) + self.units = self.app.defaults['units'].upper() + if dia: tool_dia = dia else: - tool_dia = self.on_calculate_tooldia() + tool_dia = self.ui.new_tooldia_entry.get_value() - if tool_dia is None: - self.build_ui() - self.app.inform.emit('[WARNING_NOTCL] %s' % _("Please enter a tool diameter to add, in Float format.")) - return + if tool_dia is None or tool_dia == 0: + self.build_ui() + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Please enter a tool diameter with non-zero value, " + "in Float format.")) + self.blockSignals(False) + return # construct a list of all 'tooluid' in the self.tools - tool_uid_list = [] - for tooluid_key in self.paint_tools: - tool_uid_item = int(tooluid_key) - tool_uid_list.append(tool_uid_item) + tool_uid_list = [int(tooluid_key) for tooluid_key in self.paint_tools] # find maximum from the temp_uid, add 1 and this is the new 'tooluid' - if not tool_uid_list: - max_uid = 0 - else: - max_uid = max(tool_uid_list) + max_uid = 0 if not tool_uid_list else max(tool_uid_list) self.tooluid = int(max_uid + 1) tool_dias = [] for k, v in self.paint_tools.items(): for tool_v in v.keys(): if tool_v == 'tooldia': - tool_dias.append(float('%.*f' % (self.decimals, v[tool_v]))) + tool_dias.append(self.app.dec_format(v[tool_v], self.decimals)) - if float('%.*f' % (self.decimals, tool_dia)) in tool_dias: + truncated_tooldia = self.app.dec_format(tool_dia, self.decimals) + if truncated_tooldia in tool_dias: if muted is None: self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled. Tool already in Tool Table.")) self.blockSignals(False) return - else: - if muted is None: - self.app.inform.emit('[success] %s' % _("New tool added to Tool Table.")) - self.paint_tools.update({ - int(self.tooluid): { - 'tooldia': float('%.*f' % (self.decimals, tool_dia)), - 'offset': 'Path', - 'offset_value': 0.0, - 'type': 'Iso', - 'tool_type': self.ui.tool_type_radio.get_value(), - 'data': dict(self.default_data), - 'solid_geometry': [] - } - }) + + self.paint_tools.update({ + int(self.tooluid): { + 'tooldia': truncated_tooldia, + 'offset': 'Path', + 'offset_value': 0.0, + 'type': 'Iso', + 'tool_type': 'V', + 'data': deepcopy(self.default_data), + 'solid_geometry': [] + } + }) self.blockSignals(False) self.build_ui() @@ -820,6 +864,12 @@ class ToolPaint(AppTool, Gerber): self.ui.tools_table.selectRow(row) break + # update the UI form + self.update_ui() + + if muted is None: + self.app.inform.emit('[success] %s' % _("New tool added to Tool Table.")) + def on_tool_edit(self, item): self.blockSignals(True) @@ -860,61 +910,6 @@ class ToolPaint(AppTool, Gerber): self.blockSignals(False) self.build_ui() - # def on_tool_copy(self, all=None): - # try: - # self.ui.tools_table.itemChanged.disconnect() - # except: - # pass - # - # # find the tool_uid maximum value in the self.tools - # uid_list = [] - # for key in self.paint_tools: - # uid_list.append(int(key)) - # try: - # max_uid = max(uid_list, key=int) - # except ValueError: - # max_uid = 0 - # - # if all is None: - # if self.ui.tools_table.selectedItems(): - # for current_row in self.ui.tools_table.selectedItems(): - # # sometime the header get selected and it has row number -1 - # # we don't want to do anything with the header :) - # if current_row.row() < 0: - # continue - # try: - # tooluid_copy = int(self.ui.tools_table.item(current_row.row(), 3).text()) - # max_uid += 1 - # self.paint_tools[int(max_uid)] = dict(self.paint_tools[tooluid_copy]) - # for td in self.paint_tools: - # print("COPIED", self.paint_tools[td]) - # self.build_ui() - # except AttributeError: - # self.app.inform.emit("[WARNING_NOTCL] Failed. Select a tool to copy.") - # self.build_ui() - # return - # except Exception as e: - # log.debug("on_tool_copy() --> " + str(e)) - # # deselect the table - # # self.ui.geo_tools_table.clearSelection() - # else: - # self.app.inform.emit("[WARNING_NOTCL] Failed. Select a tool to copy.") - # self.build_ui() - # return - # else: - # # we copy all tools in geo_tools_table - # try: - # temp_tools = dict(self.paint_tools) - # max_uid += 1 - # for tooluid in temp_tools: - # self.paint_tools[int(max_uid)] = dict(temp_tools[tooluid]) - # temp_tools.clear() - # self.build_ui() - # except Exception as e: - # log.debug("on_tool_copy() --> " + str(e)) - # - # self.app.inform.emit("[success] Tool was copied in the Tool Table.") - def on_tool_delete(self, rows_to_delete=None, all_tools=None): """ Will delete a tool in the tool table @@ -1694,11 +1689,12 @@ class ToolPaint(AppTool, Gerber): return None def paint_geo(self, obj, geometry, tooldia=None, order=None, method=None, outname=None, - tools_storage=None, plot=True, run_threaded=True): + tools_storage=None, plot=True, run_threaded=True): """ Paints a given geometry. :param obj: painted object + :param geometry: geometry to Paint :param tooldia: Diameter of the painting tool :param order: if the tools are ordered and how :param outname: Name of the resulting Geometry Object. @@ -1711,7 +1707,6 @@ class ToolPaint(AppTool, Gerber): :return: None """ - paint_method = method if method is not None else self.ui.paintmethod_combo.get_value() # determine if to use the progressive plotting prog_plot = True if self.app.defaults["tools_paint_plotting"] == 'progressive' else False @@ -1967,7 +1962,7 @@ class ToolPaint(AppTool, Gerber): return "fail" # store here the cleared geometry - cleared_geo = [] + # cleared_geo = [] # determine the tool parameters to use over = float(tools_storage[current_uid]['data']['tools_paintoverlap']) / 100.0 @@ -2131,10 +2126,12 @@ class ToolPaint(AppTool, Gerber): has_solid_geo += 1 if has_solid_geo == 0: - app_obj.inform.emit('[ERROR] %s' % - _("There is no Painting Geometry in the file.\n" - "Usually it means that the tool diameter is too big for the painted geometry.\n" - "Change the painting parameters and try again.")) + app_obj.inform.emit( + '[ERROR] %s' % + _("There is no Painting Geometry in the file.\n" + "Usually it means that the tool diameter is too big for the painted geometry.\n" + "Change the painting parameters and try again.") + ) return "fail" geo_obj.solid_geometry = cascaded_union(final_solid_geometry) else: @@ -2519,8 +2516,7 @@ class ToolPaint(AppTool, Gerber): elif isinstance(current_widget, FCComboBox): current_widget.currentIndexChanged.connect(self.form_to_storage) - self.ui.tool_type_radio.activated_custom.connect(self.on_tool_type) - self.ui.rest_cb.stateChanged.connect(self.on_rest_machining_check) + self.ui.rest_cb.stateChanged.connect(self.ui.on_rest_machining_check) self.ui.order_radio.activated_custom[str].connect(self.on_order_changed) def ui_disconnect(self): @@ -2572,13 +2568,6 @@ class ToolPaint(AppTool, Gerber): except (TypeError, ValueError): pass - - try: - # if connected, disconnect the signal from the slot on item_changed as it creates issues - self.ui.tool_type_radio.activated_custom.disconnect() - except (TypeError, AttributeError): - pass - try: # if connected, disconnect the signal from the slot on item_changed as it creates issues self.ui.rest_cb.stateChanged.disconnect() @@ -2625,6 +2614,10 @@ class ToolPaint(AppTool, Gerber): """ tool_from_db = deepcopy(tool) + if tool['data']['tool_target'] != _("Paint"): + self.app.inform.emit('[ERROR_NOTCL] %s' % _("Selected tool can't be used here. Pick another.")) + return + res = self.on_paint_tool_from_db_inserted(tool=tool_from_db) for idx in range(self.app.ui.plot_tab_area.count()): @@ -2740,7 +2733,7 @@ class PaintUI: self.layout = layout # ## Title - title_label = QtWidgets.QLabel("%s" % self.toolName) + title_label = FCLabel("%s" % self.toolName) title_label.setStyleSheet(""" QLabel { @@ -2767,7 +2760,7 @@ class PaintUI: # ##### Type of object to be painted ############# # ################################################ - self.type_obj_combo_label = QtWidgets.QLabel('%s:' % _("Obj Type")) + self.type_obj_combo_label = FCLabel('%s:' % _("Obj Type")) self.type_obj_combo_label.setToolTip( _("Specify the type of object to be painted.\n" "It can be of type: Gerber or Geometry.\n" @@ -2790,7 +2783,7 @@ class PaintUI: self.obj_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) self.obj_combo.is_last = True - self.object_label = QtWidgets.QLabel('%s:' % _("Object")) + self.object_label = FCLabel('%s:' % _("Object")) self.object_label.setToolTip(_("Object to be painted.")) grid0.addWidget(self.object_label, 2, 0) @@ -2802,7 +2795,7 @@ class PaintUI: grid0.addWidget(separator_line, 5, 0, 1, 2) # ### Tools ## ## - self.tools_table_label = QtWidgets.QLabel('%s' % _('Tools Table')) + self.tools_table_label = FCLabel('%s' % _('Tools Table')) self.tools_table_label.setToolTip( _("Tools pool from which the algorithm\n" "will pick the ones used for painting.") @@ -2845,7 +2838,7 @@ class PaintUI: "Choosing the 'V-Shape' Tool Type automatically will select the Operation Type\n" "in the resulting geometry as Isolation.")) - self.order_label = QtWidgets.QLabel('%s:' % _('Tool order')) + self.order_label = FCLabel('%s:' % _('Tool order')) self.order_label.setToolTip(_("This set the way that the tools in the tools table are used.\n" "'No' --> means that the used order is the one in the tool table\n" "'Forward' --> means that the tools will be ordered from small to big\n" @@ -2871,113 +2864,53 @@ class PaintUI: separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) grid0.addWidget(separator_line, 10, 0, 1, 2) - self.grid3 = QtWidgets.QGridLayout() - self.tools_box.addLayout(self.grid3) - self.grid3.setColumnStretch(0, 0) - self.grid3.setColumnStretch(1, 1) - # ############################################################################## # ###################### ADD A NEW TOOL ######################################## # ############################################################################## - self.tool_sel_label = QtWidgets.QLabel('%s' % _("New Tool")) - self.grid3.addWidget(self.tool_sel_label, 1, 0, 1, 2) - - # Tool Type Radio Button - self.tool_type_label = QtWidgets.QLabel('%s:' % _('Tool Type')) - self.tool_type_label.setToolTip( - _("Default tool type:\n" - "- 'V-shape'\n" - "- Circular") - ) - - self.tool_type_radio = RadioSet([{'label': _('V-shape'), 'value': 'V'}, - {'label': _('Circular'), 'value': 'C1'}]) - self.tool_type_radio.setToolTip( - _("Default tool type:\n" - "- 'V-shape'\n" - "- Circular") - ) - self.tool_type_radio.setObjectName('p_tool_type') - - self.grid3.addWidget(self.tool_type_label, 2, 0) - self.grid3.addWidget(self.tool_type_radio, 2, 1) - - # Tip Dia - self.tipdialabel = QtWidgets.QLabel('%s:' % _('V-Tip Dia')) - self.tipdialabel.setToolTip( - _("The tip diameter for V-Shape Tool")) - self.tipdia_entry = FCDoubleSpinner(callback=self.confirmation_message) - self.tipdia_entry.set_precision(self.decimals) - self.tipdia_entry.set_range(0.0000, 9999.9999) - self.tipdia_entry.setSingleStep(0.1) - self.tipdia_entry.setObjectName('p_vtip_dia') - - self.grid3.addWidget(self.tipdialabel, 3, 0) - self.grid3.addWidget(self.tipdia_entry, 3, 1) - - # 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_entry = FCDoubleSpinner(callback=self.confirmation_message) - self.tipangle_entry.set_precision(self.decimals) - self.tipangle_entry.set_range(0.0000, 180.0000) - self.tipangle_entry.setSingleStep(5) - self.tipangle_entry.setObjectName('p_vtip_angle') - - self.grid3.addWidget(self.tipanglelabel, 4, 0) - self.grid3.addWidget(self.tipangle_entry, 4, 1) - - # Cut Z entry - cutzlabel = QtWidgets.QLabel('%s:' % _('Cut Z')) - cutzlabel.setToolTip( - _("Depth of cut into material. Negative value.\n" - "In FlatCAM units.") - ) - self.cutz_entry = FCDoubleSpinner(callback=self.confirmation_message) - self.cutz_entry.set_precision(self.decimals) - self.cutz_entry.set_range(-99999.9999, 0.0000) - self.cutz_entry.setObjectName('p_cutz') - - self.cutz_entry.setToolTip( - _("Depth of cut into material. Negative value.\n" - "In FlatCAM units.") - ) - self.grid3.addWidget(cutzlabel, 5, 0) - self.grid3.addWidget(self.cutz_entry, 5, 1) + + self.grid3 = QtWidgets.QGridLayout() + self.grid3.setColumnStretch(0, 0) + self.grid3.setColumnStretch(1, 1) + self.tools_box.addLayout(self.grid3) + + self.tool_sel_label = FCLabel('%s' % _('Add from DB')) + self.grid3.addWidget(self.tool_sel_label, 0, 0, 1, 2) # ### Tool Diameter #### - self.addtool_entry_lbl = QtWidgets.QLabel('%s:' % _('Tool Dia')) - self.addtool_entry_lbl.setToolTip( + self.new_tooldia_lbl = FCLabel('%s:' % _('Tool Dia')) + self.new_tooldia_lbl.setToolTip( _("Diameter for the new tool to add in the Tool Table.\n" "If the tool is V-shape type then this value is automatically\n" "calculated from the other parameters.") ) - self.addtool_entry = FCDoubleSpinner(callback=self.confirmation_message) - self.addtool_entry.set_precision(self.decimals) - self.addtool_entry.set_range(0.000, 9999.9999) - self.addtool_entry.setObjectName('p_tool_dia') + self.new_tooldia_entry = FCDoubleSpinner(callback=self.confirmation_message) + self.new_tooldia_entry.set_precision(self.decimals) + self.new_tooldia_entry.set_range(0.000, 9999.9999) + self.new_tooldia_entry.setObjectName('p_tool_dia') - self.grid3.addWidget(self.addtool_entry_lbl, 6, 0) - self.grid3.addWidget(self.addtool_entry, 6, 1) + self.grid3.addWidget(self.new_tooldia_lbl, 2, 0) + self.grid3.addWidget(self.new_tooldia_entry, 2, 1) hlay = QtWidgets.QHBoxLayout() - self.addtool_btn = QtWidgets.QPushButton(_('Add')) - self.addtool_btn.setToolTip( + self.add_newtool_button = FCButton(_('Search and Add')) + self.add_newtool_button.setIcon(QtGui.QIcon(self.app.resource_location + '/plus16.png')) + self.add_newtool_button.setToolTip( _("Add a new tool to the Tool Table\n" - "with the diameter specified above.") + "with the diameter specified above.\n" + "This is done by a background search\n" + "in the Tools Database. If nothing is found\n" + "in the Tools DB then a default tool is added.") ) + hlay.addWidget(self.add_newtool_button) - self.addtool_from_db_btn = QtWidgets.QPushButton(_('Add from DB')) + self.addtool_from_db_btn = FCButton(_('Pick from DB')) + self.addtool_from_db_btn.setIcon(QtGui.QIcon(self.app.resource_location + '/search_db32.png')) self.addtool_from_db_btn.setToolTip( _("Add a new tool to the Tool Table\n" "from the Tool Database.\n" "Tool database administration in Menu: Options -> Tools Database") ) - - hlay.addWidget(self.addtool_btn) hlay.addWidget(self.addtool_from_db_btn) self.grid3.addLayout(hlay, 7, 0, 1, 2) @@ -2987,21 +2920,20 @@ class PaintUI: separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) self.grid3.addWidget(separator_line, 8, 0, 1, 2) - self.deltool_btn = QtWidgets.QPushButton(_('Delete')) + self.deltool_btn = FCButton(_('Delete')) + self.deltool_btn.setIcon(QtGui.QIcon(self.app.resource_location + '/trash16.png')) self.deltool_btn.setToolTip( _("Delete a selection of tools in the Tool Table\n" "by first selecting a row(s) in the Tool Table.") ) self.grid3.addWidget(self.deltool_btn, 9, 0, 1, 2) - self.grid3.addWidget(QtWidgets.QLabel(''), 10, 0, 1, 2) - separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) self.grid3.addWidget(separator_line, 11, 0, 1, 2) - self.tool_data_label = QtWidgets.QLabel( + self.tool_data_label = FCLabel( "%s: %s %d" % (_('Parameters for'), _("Tool"), int(1))) self.tool_data_label.setToolTip( _( @@ -3017,7 +2949,7 @@ class PaintUI: self.tools_box.addLayout(grid4) # Overlap - ovlabel = QtWidgets.QLabel('%s:' % _('Overlap')) + ovlabel = FCLabel('%s:' % _('Overlap')) ovlabel.setToolTip( _("How much (percentage) of the tool width to overlap each tool pass.\n" "Adjust the value starting with lower values\n" @@ -3038,7 +2970,7 @@ class PaintUI: grid4.addWidget(self.paintoverlap_entry, 1, 1) # Offset - self.offset_label = QtWidgets.QLabel('%s:' % _('Offset')) + self.offset_label = FCLabel('%s:' % _('Offset')) self.offset_label.setToolTip( _("Distance by which to avoid\n" "the edges of the polygon to\n" @@ -3053,7 +2985,7 @@ class PaintUI: grid4.addWidget(self.offset_entry, 2, 1) # Method - methodlabel = QtWidgets.QLabel('%s:' % _('Method')) + methodlabel = FCLabel('%s:' % _('Method')) methodlabel.setToolTip( _("Algorithm for painting:\n" "- Standard: Fixed step inwards.\n" @@ -3125,7 +3057,7 @@ class PaintUI: grid4.addWidget(separator_line, 13, 0, 1, 2) # General Parameters - self.gen_param_label = QtWidgets.QLabel('%s' % _("Common Parameters")) + self.gen_param_label = FCLabel('%s' % _("Common Parameters")) self.gen_param_label.setToolTip( _("Parameters that are common for all tools.") ) @@ -3145,7 +3077,7 @@ class PaintUI: grid4.addWidget(self.rest_cb, 16, 0, 1, 2) # Rest Offset - self.rest_offset_label = QtWidgets.QLabel('%s:' % _('Offset')) + self.rest_offset_label = FCLabel('%s:' % _('Offset')) self.rest_offset_label.setToolTip( _("Distance by which to avoid\n" "the edges of the polygon to\n" @@ -3159,7 +3091,7 @@ class PaintUI: grid4.addWidget(self.rest_offset_entry, 17, 1) # Polygon selection - selectlabel = QtWidgets.QLabel('%s:' % _('Selection')) + selectlabel = FCLabel('%s:' % _('Selection')) selectlabel.setToolTip( _("Selection of area to be processed.\n" "- 'Polygon Selection' - left mouse click to add/remove polygons to be processed.\n" @@ -3199,7 +3131,7 @@ class PaintUI: form1 = QtWidgets.QFormLayout() grid4.addLayout(form1, 20, 0, 1, 2) - self.reference_type_label = QtWidgets.QLabel('%s:' % _("Ref. Type")) + self.reference_type_label = FCLabel('%s:' % _("Ref. Type")) self.reference_type_label.setToolTip( _("The type of FlatCAM object to be used as paint reference.\n" "It can be Gerber, Excellon or Geometry.") @@ -3209,7 +3141,7 @@ class PaintUI: form1.addRow(self.reference_type_label, self.reference_type_combo) - self.reference_combo_label = QtWidgets.QLabel('%s:' % _("Ref. Object")) + self.reference_combo_label = FCLabel('%s:' % _("Ref. Object")) self.reference_combo_label.setToolTip( _("The FlatCAM object to be used as non copper clearing reference.") ) @@ -3225,7 +3157,7 @@ class PaintUI: self.reference_type_label.hide() # Area Selection shape - self.area_shape_label = QtWidgets.QLabel('%s:' % _("Shape")) + self.area_shape_label = FCLabel('%s:' % _("Shape")) self.area_shape_label.setToolTip( _("The kind of selection shape used for area selection.") ) @@ -3240,7 +3172,7 @@ class PaintUI: self.area_shape_radio.hide() # GO Button - self.generate_paint_button = QtWidgets.QPushButton(_('Generate Geometry')) + self.generate_paint_button = FCButton(_('Generate Geometry')) self.generate_paint_button.setIcon(QtGui.QIcon(self.app.resource_location + '/geometry32.png')) self.generate_paint_button.setToolTip( _("Create a Geometry Object which paints the polygons.") @@ -3256,7 +3188,7 @@ class PaintUI: self.tools_box.addStretch() # ## Reset Tool - self.reset_button = QtWidgets.QPushButton(_("Reset Tool")) + self.reset_button = FCButton(_("Reset Tool")) self.reset_button.setIcon(QtGui.QIcon(self.app.resource_location + '/reset32.png')) self.reset_button.setToolTip( _("Will reset the tool parameters.") @@ -3272,6 +3204,61 @@ class PaintUI: # #################################### FINSIHED GUI ########################### # ############################################################################# + def on_rest_machining_check(self, state): + if state: + self.order_radio.set_value('rev') + self.order_label.setDisabled(True) + self.order_radio.setDisabled(True) + + self.offset_label.hide() + self.offset_entry.hide() + self.rest_offset_label.show() + self.rest_offset_entry.show() + else: + self.order_label.setDisabled(False) + self.order_radio.setDisabled(False) + + self.offset_label.show() + self.offset_entry.show() + self.rest_offset_label.hide() + self.rest_offset_entry.hide() + + def on_selection(self): + sel_combo = self.selectmethod_combo.get_value() + + if sel_combo == _("Reference Object"): + self.reference_combo.show() + self.reference_combo_label.show() + self.reference_type_combo.show() + self.reference_type_label.show() + else: + self.reference_combo.hide() + self.reference_combo_label.hide() + self.reference_type_combo.hide() + self.reference_type_label.hide() + + if sel_combo == _("Polygon Selection"): + # disable rest-machining for single polygon painting + # self.ui.rest_cb.set_value(False) + # self.ui.rest_cb.setDisabled(True) + pass + + if sel_combo == _("Area Selection"): + # disable rest-machining for area painting + # self.ui.rest_cb.set_value(False) + # self.ui.rest_cb.setDisabled(True) + + self.area_shape_label.show() + self.area_shape_radio.show() + else: + self.new_tooldia_entry.setDisabled(False) + self.add_newtool_button.setDisabled(False) + self.deltool_btn.setDisabled(False) + self.tools_table.setContextMenuPolicy(Qt.ActionsContextMenu) + + self.area_shape_label.hide() + self.area_shape_radio.hide() + def confirmation_message(self, accepted, minval, maxval): if accepted is False: self.app.inform[str, bool].emit('[WARNING_NOTCL] %s: [%.*f, %.*f]' % (_("Edited value is out of range"),