File size: 5,136 Bytes
985c397 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | # SPDX-License-Identifier: LGPL-2.1-or-later
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::PropertyFloat",
"App::PropertyInteger",
"App::PropertyLength",
"App::PropertyPercent",
]
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():
val = get_field()
if isinstance(getattr(self.obj, prop_name), int):
val = int(val)
setattr(self.obj, prop_name, val)
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
|