| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | """Widget for editing a ToolBit object.""" |
| |
|
| | from typing import Optional |
| | from PySide import QtGui, QtCore |
| | import FreeCAD |
| | import FreeCADGui |
| | from ...shape.ui.shapewidget import ShapeWidget |
| | from ...docobject.ui import DocumentObjectEditorWidget |
| | from ..models.base import ToolBit |
| | from ..util import setToolBitSchema |
| |
|
| | translate = FreeCAD.Qt.translate |
| |
|
| |
|
| | class ToolBitPropertiesWidget(QtGui.QWidget): |
| | """ |
| | A composite widget for editing the properties and shape of a ToolBit. |
| | """ |
| |
|
| | |
| | toolBitChanged = QtCore.Signal() |
| | toolNoChanged = QtCore.Signal(int) |
| |
|
| | def __init__( |
| | self, |
| | toolbit: Optional[ToolBit] = None, |
| | tool_no: Optional[int] = None, |
| | parent=None, |
| | icon: bool = True, |
| | ): |
| | super().__init__(parent) |
| | self._toolbit = None |
| | self._show_shape = icon |
| | self._tool_no = tool_no |
| | setToolBitSchema() |
| |
|
| | |
| | self._label_edit = QtGui.QLineEdit() |
| | self._id_label = QtGui.QLabel() |
| | self._id_label.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse) |
| |
|
| | theicon = toolbit.get_icon() if toolbit else None |
| | abbr = theicon.abbreviations if theicon else {} |
| | self._property_editor = DocumentObjectEditorWidget(property_suffixes=abbr) |
| | self._property_editor.setSizePolicy( |
| | QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding |
| | ) |
| | self._shape_widget = None |
| |
|
| | |
| | toolbit_group_box = QtGui.QGroupBox(translate("CAM", "Toolbit")) |
| | form_layout = QtGui.QFormLayout(toolbit_group_box) |
| | form_layout.addRow(translate("CAM", "Label:"), self._label_edit) |
| | |
| |
|
| | |
| | self._tool_no_edit = QtGui.QSpinBox() |
| | self._tool_no_edit.setMinimum(1) |
| | self._tool_no_edit.setMaximum(99999999) |
| | if tool_no is not None: |
| | form_layout.addRow(translate("CAM", "Tool Number:"), self._tool_no_edit) |
| |
|
| | main_layout = QtGui.QVBoxLayout(self) |
| | main_layout.addWidget(toolbit_group_box) |
| |
|
| | properties_group_box = QtGui.QGroupBox(FreeCAD.Qt.translate("CAM", "Properties")) |
| | properties_group_box.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) |
| | properties_layout = QtGui.QVBoxLayout(properties_group_box) |
| | properties_layout.setSpacing(5) |
| | properties_layout.addWidget(self._property_editor) |
| |
|
| | |
| | properties_layout.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) |
| |
|
| | |
| | properties_layout.setStretchFactor(self._property_editor, 1) |
| |
|
| | main_layout.addWidget(properties_group_box) |
| |
|
| | |
| | main_layout.addStretch(1) |
| |
|
| | |
| | self._shape_display_layout = QtGui.QHBoxLayout() |
| | self._shape_display_layout.addStretch(1) |
| |
|
| | |
| | self._shape_display_layout.addStretch(1) |
| | main_layout.addLayout(self._shape_display_layout) |
| |
|
| | |
| | self._label_edit.editingFinished.connect(self._on_label_changed) |
| | self._tool_no_edit.valueChanged.connect(self._on_tool_no_changed) |
| | self._property_editor.propertyChanged.connect(self.toolBitChanged) |
| |
|
| | if toolbit: |
| | self.load_toolbit(toolbit) |
| |
|
| | def _on_label_changed(self): |
| | """Update the toolbit's label when the line edit changes.""" |
| | if self._toolbit and self._toolbit.obj: |
| | new_label = self._label_edit.text() |
| | if self._toolbit.obj.Label != new_label: |
| | self._toolbit.obj.Label = new_label |
| | self.toolBitChanged.emit() |
| |
|
| | def _on_tool_no_changed(self, value): |
| | """Update the tool number when the line edit changes.""" |
| | if self._tool_no != value: |
| | self._tool_no = value |
| | self.toolNoChanged.emit(value) |
| |
|
| | def load_toolbit(self, toolbit: ToolBit): |
| | """Load a ToolBit object into the editor.""" |
| | |
| | toolbit_units = None |
| | if toolbit and hasattr(toolbit.obj, "Units"): |
| | toolbit_units = getattr(toolbit.obj, "Units", None) |
| | |
| | if isinstance(toolbit_units, (list, tuple)) and len(toolbit_units) > 0: |
| | toolbit_units = toolbit_units[0] |
| | if toolbit_units in ("Metric", "Imperial"): |
| | setToolBitSchema(toolbit_units) |
| | elif FreeCAD.ActiveDocument is None: |
| | setToolBitSchema() |
| |
|
| | self._toolbit = toolbit |
| | if not self._toolbit or not self._toolbit.obj: |
| | |
| | self._label_edit.clear() |
| | self._label_edit.setEnabled(False) |
| | self._id_label.clear() |
| | self._tool_no_edit.clear() |
| | self._property_editor.setObject(None) |
| | |
| | if self._shape_widget: |
| | self._shape_display_layout.removeWidget(self._shape_widget) |
| | self._shape_widget.deleteLater() |
| | self._shape_widget = None |
| | self._tool_no_edit.setValue(1) |
| | self.setEnabled(False) |
| | return |
| |
|
| | self.setEnabled(True) |
| | self._label_edit.setEnabled(True) |
| | self._label_edit.setText(self._toolbit.obj.Label) |
| | self._id_label.setText(self._toolbit.get_id()) |
| | self._tool_no_edit.setValue(int(self._tool_no or 1)) |
| |
|
| | |
| | props_to_show = self._toolbit._get_props(("Shape", "Attributes")) |
| | icon = self._toolbit._tool_bit_shape.get_icon() |
| | suffixes = icon.abbreviations if icon else {} |
| | self._property_editor.setObject(self._toolbit.obj) |
| | self._property_editor.setPropertiesToShow(props_to_show, suffixes) |
| |
|
| | |
| | if self._shape_widget: |
| | self._shape_display_layout.removeWidget(self._shape_widget) |
| | self._shape_widget.deleteLater() |
| | self._shape_widget = None |
| |
|
| | if self._show_shape and self._toolbit._tool_bit_shape: |
| | self._shape_widget = ShapeWidget(shape=self._toolbit._tool_bit_shape, parent=self) |
| | self._shape_widget.setMinimumSize(200, 150) |
| | |
| | self._shape_display_layout.insertWidget(1, self._shape_widget) |
| |
|
| | def save_toolbit(self): |
| | """ |
| | Applies changes from the editor widgets back to the ToolBit object. |
| | Note: Most changes are applied via signals, but this can be called |
| | for explicit save actions. |
| | """ |
| | |
| | self._on_label_changed() |
| |
|
| | |
| | |
| |
|
| |
|
| | class ToolBitEditorPanel(QtGui.QWidget): |
| | """ |
| | A widget for editing a ToolBit object, wrapping ToolBitEditorWidget |
| | and providing standard dialog buttons. |
| | """ |
| |
|
| | |
| | accepted = QtCore.Signal(ToolBit) |
| | rejected = QtCore.Signal() |
| | toolBitChanged = QtCore.Signal() |
| |
|
| | def __init__(self, toolbit: ToolBit | None = None, parent=None): |
| | super().__init__(parent) |
| |
|
| | |
| | self._editor_widget = ToolBitPropertiesWidget(toolbit, self) |
| |
|
| | |
| | buttons = QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel |
| | self._button_box = QtGui.QDialogButtonBox(buttons) |
| |
|
| | |
| | self._button_box.accepted.connect(self._accepted) |
| | self._button_box.rejected.connect(self.rejected.emit) |
| |
|
| | |
| | main_layout = QtGui.QVBoxLayout(self) |
| | main_layout.addWidget(self._editor_widget) |
| | main_layout.addWidget(self._button_box) |
| |
|
| | |
| | self._editor_widget.toolBitChanged.connect(self.toolBitChanged) |
| |
|
| | def _accepted(self): |
| | self.accepted.emit(self._editor_widget._toolbit) |
| |
|
| | def load_toolbit(self, toolbit: ToolBit): |
| | """Load a ToolBit object into the editor.""" |
| | self._editor_widget.load_toolbit(toolbit) |
| |
|
| | def save_toolbit(self): |
| | """Applies changes from the editor widgets back to the ToolBit object.""" |
| | self._editor_widget.save_toolbit() |
| |
|
| |
|
| | class ToolBitEditor(QtGui.QWidget): |
| | """ |
| | A widget for editing a ToolBit object, wrapping ToolBitEditorWidget |
| | and providing standard dialog buttons. |
| | """ |
| |
|
| | |
| | toolBitChanged = QtCore.Signal() |
| |
|
| | def __init__( |
| | self, |
| | toolbit: ToolBit, |
| | tool_no: Optional[int] = None, |
| | parent=None, |
| | icon: bool = False, |
| | ): |
| | super().__init__(parent) |
| | self.form = FreeCADGui.PySideUic.loadUi(":/panels/ToolBitEditor.ui") |
| |
|
| | self.toolbit = toolbit |
| | self.tool_no = tool_no |
| | self.default_title = self.form.windowTitle() |
| |
|
| | |
| | self._original_schema = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Units").GetInt( |
| | "UserSchema", 6 |
| | ) |
| | self._tab_closed = False |
| |
|
| | |
| | tool_tab_layout = self.form.toolTabLayout |
| | widget = ShapeWidget(toolbit._tool_bit_shape) |
| | tool_tab_layout.addWidget(widget) |
| |
|
| | |
| | self._props = ToolBitPropertiesWidget(toolbit, tool_no, self, icon=icon) |
| | self._last_units_value = self._get_units_value(self._props) |
| | self._props.toolBitChanged.connect(self._on_toolbit_changed) |
| | self._props.toolBitChanged.connect(self._update) |
| | self._props.toolNoChanged.connect(self._on_tool_no_changed) |
| | tool_tab_layout.addWidget(self._props) |
| |
|
| | self.form.tabWidget.setCurrentIndex(0) |
| | self.form.tabWidget.currentChanged.connect(self._on_tab_switched) |
| |
|
| | |
| | self.form.tabWidget.setTabVisible(1, False) |
| |
|
| | |
| | self.feeds_tab_idx = None |
| | """ |
| | TODO: disabled for now. |
| | if tool.supports_feeds_and_speeds(): |
| | label = translate('CAM', 'Feeds && Speeds') |
| | self.feeds = FeedsAndSpeedsWidget(db, serializer, tool, parent=self) |
| | self.feeds_tab_idx = self.form.tabWidget.insertTab(1, self.feeds, label) |
| | else: |
| | self.feeds = None |
| | self.feeds_tab_idx = None |
| | |
| | self.form.lineEditCoating.setText(toolbit.get_coating()) |
| | self.form.lineEditCoating.textChanged.connect(toolbit.set_coating) |
| | self.form.lineEditHardness.setText(toolbit.get_hardness()) |
| | self.form.lineEditHardness.textChanged.connect(toolbit.set_hardness) |
| | self.form.lineEditMaterials.setText(toolbit.get_materials()) |
| | self.form.lineEditMaterials.textChanged.connect(toolbit.set_materials) |
| | self.form.lineEditSupplier.setText(toolbit.get_supplier()) |
| | self.form.lineEditSupplier.textChanged.connect(toolbit.set_supplier) |
| | self.form.plainTextEditNotes.setPlainText(tool.get_notes()) |
| | self.form.plainTextEditNotes.textChanged.connect(self._on_notes_changed) |
| | """ |
| |
|
| | self._update() |
| |
|
| | def _get_units_value(self, props): |
| | """ |
| | Helper to extract the Units value from the toolbit properties. |
| | """ |
| | if props and hasattr(props._toolbit.obj, "Units"): |
| | units_value = getattr(props._toolbit.obj, "Units", None) |
| | if isinstance(units_value, (list, tuple)) and len(units_value) > 0: |
| | units_value = units_value[0] |
| | return units_value |
| | return None |
| |
|
| | def _on_toolbit_changed(self): |
| | """ |
| | Slot called when the toolbit is changed. If the Units value has changed, |
| | refreshes the property editor widget to update the schema and UI. |
| | """ |
| | units_value = self._get_units_value(self._props) |
| | if units_value in ("Metric", "Imperial") and units_value != self._last_units_value: |
| | self._refresh_property_editor() |
| | self._last_units_value = units_value |
| |
|
| | def _refresh_property_editor(self): |
| | """ |
| | Refreshes the property editor widget in the tab. |
| | Removes the current ToolBitPropertiesWidget, restores the original units schema, |
| | recreates the widget, and reconnects all signals. This ensures the UI and schema |
| | are in sync with the current toolbit's units, and user changes are preserved |
| | because the ToolBit object is always up to date. |
| | """ |
| | |
| | tool_tab_layout = self.form.toolTabLayout |
| | tool_tab_layout.removeWidget(self._props) |
| | self._props.deleteLater() |
| | |
| | FreeCAD.Units.setSchema(self._original_schema) |
| | |
| | self._props = ToolBitPropertiesWidget(self.toolbit, self.tool_no, self, icon=False) |
| | self._last_units_value = self._get_units_value(self._props) |
| | self._props.toolBitChanged.connect(self._on_toolbit_changed) |
| | self._props.toolBitChanged.connect(self._update) |
| | self._props.toolNoChanged.connect(self._on_tool_no_changed) |
| | tool_tab_layout.addWidget(self._props) |
| | self.form.tabWidget.setCurrentIndex(0) |
| |
|
| | def _restore_original_schema(self): |
| | """ |
| | Restores the original units schema that was active before the ToolBit editor was opened. |
| | """ |
| | FreeCAD.Units.setSchema(self._original_schema) |
| |
|
| | def _update(self): |
| | title = self.default_title |
| | tool_name = self.toolbit.label |
| | if tool_name: |
| | title = "{} - {}".format(tool_name, title) |
| | self.form.setWindowTitle(title) |
| |
|
| | def _on_tab_switched(self, index): |
| | if index == self.feeds_tab_idx: |
| | self.feeds.update() |
| |
|
| | def _on_notes_changed(self): |
| | self.toolbit.set_notes(self.form.plainTextEditNotes.toPlainText()) |
| |
|
| | def _on_tool_no_changed(self, value): |
| | self.tool_no = value |
| |
|
| | def get_tool_no(self): |
| | return self.tool_no |
| |
|
| | def show(self): |
| | return self.form.exec_() |
| |
|