freecad-cam/Mod/CAM/PathPythonGui/simple_edit_panel.py
2026-02-01 01:59:24 +01:00

130 lines
4.8 KiB
Python

import FreeCAD
import FreeCADGui
from PySide import QtGui
translate = FreeCAD.Qt.translate
PROP_TYPE_QTYES = ["App::PropertyDistance", "App::PropertyAngle"]
PROP_TYPE_NUMERIC = PROP_TYPE_QTYES + ["App::PropertyPercent", "App:PropertyFloat"]
class SimpleEditPanel:
"""A simple property edit panel for a FreeCAD object
Attributes:
_transaction_name: Name to use for the undo transaction used in this panel.
_ui_file: Path to the Qt UI file to use when creating this panel. Must be
overridden by the subclass.
"""
_transaction_name = "Property Edit"
_ui_file = ""
def __init__(self, obj, view):
self.obj = obj
self.viewProvider = view
FreeCAD.ActiveDocument.openTransaction(self._transaction_name)
self.form = FreeCADGui.PySideUic.loadUi(self._ui_file)
self._fc = {}
self.setupUi()
def getFields(self):
for prop_name, (get_field, set_field) in self._fc.items():
setattr(self.obj, prop_name, get_field())
def setFields(self):
for prop_name, (get_field, set_field) in self._fc.items():
set_field(getattr(self.obj, prop_name))
def connectWidget(self, prop_name, widget, custom_lbls=None):
"""Connect a widget to a proxy object property
This registers a connection between a UI widget and an object property,
performing a series of convenience functions in the process, namely:
* It copies the tooltip from the object property, with proper handling
of translation.
* If it is an enum property, it loads the translated choices from the
property into the widget. Optionally the caller can override some or
all of these labels using the `custom_lbls` dictionary.
* It registers type conversion functions so when the form is applied or
accepted the data is converted and stored/retrieved without manual
intervention.
"""
if custom_lbls is None:
custom_lbls = {}
prop_type = self.obj.getTypeIdOfProperty(prop_name)
widget_type = type(widget).__name__
if prop_type == "App::PropertyEnumeration" and widget_type == "QComboBox":
enum = self.obj.getEnumerationsOfProperty(prop_name)
# Populate the combo box with the enumeration elements, use the form context for translation
elements = [
translate(self.form.objectName(), custom_lbls.get(itm, itm)) for itm in enum
]
widget.clear()
widget.addItems(elements)
def _getter():
return enum[widget.currentIndex()]
def _setter(val):
widget.setCurrentIndex(enum.index(val))
self._fc[prop_name] = _getter, _setter
elif prop_type == "App::PropertyBool" and widget_type == "QCheckBox":
self._fc[prop_name] = widget.isChecked, widget.setChecked
elif prop_type in PROP_TYPE_NUMERIC and widget_type == "QDoubleSpinBox":
self._fc[prop_name] = widget.value, widget.setValue
elif prop_type in PROP_TYPE_QTYES and widget_type == "QLineEdit":
self._fc[prop_name] = widget.text, lambda v: widget.setText(v.UserString)
else:
raise ValueError(
f"Unsupported connection between '{prop_type}' property and '{widget_type}' widget"
)
# Set the tooltip to the one corresponding to the property.
widget.setToolTip(
translate("App::Property", self.obj.getDocumentationOfProperty(prop_name))
)
def getStandardButtons(self):
return (
QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Apply | QtGui.QDialogButtonBox.Cancel
)
def clicked(self, button):
# callback for standard buttons
if button == QtGui.QDialogButtonBox.Apply:
self.updateModel()
FreeCAD.ActiveDocument.recompute()
if button == QtGui.QDialogButtonBox.Cancel:
self.abort()
def abort(self):
FreeCAD.ActiveDocument.abortTransaction()
self.cleanup(True)
def reject(self):
FreeCAD.ActiveDocument.abortTransaction()
FreeCADGui.Control.closeDialog()
FreeCAD.ActiveDocument.recompute()
def accept(self):
self.getFields()
FreeCAD.ActiveDocument.commitTransaction()
FreeCADGui.ActiveDocument.resetEdit()
FreeCADGui.Control.closeDialog()
FreeCAD.ActiveDocument.recompute()
def cleanup(self, gui):
self.viewProvider.clearTaskPanel()
if gui:
FreeCADGui.Control.closeDialog()
FreeCAD.ActiveDocument.recompute()
def updateModel(self):
self.getFields()
self.obj.Proxy.execute(self.obj)
FreeCAD.ActiveDocument.recompute()
def open(self):
pass