Basic property editor framework
This commit is contained in:
@@ -15,7 +15,17 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTableView" name="prop"/>
|
||||
<widget class="QTableView" name="table">
|
||||
<attribute name="horizontalHeaderCascadingSectionResizes">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderStretchLastSection">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
||||
@@ -222,3 +222,7 @@ class _RegisteredOp(object):
|
||||
def RegisterOperation(name, objFactory, setupProperties):
|
||||
global _RegisteredOps
|
||||
_RegisteredOps[name] = _RegisteredOp(objFactory, setupProperties)
|
||||
|
||||
def OpNamePrefix(name):
|
||||
return name.replace('Path', '').replace(' ', '').replace('_', '')
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import PathScripts.PathGui as PathGui
|
||||
import PathScripts.PathIconViewProvider as PathIconViewProvider
|
||||
import PathScripts.PathLog as PathLog
|
||||
import PathScripts.PathSetupSheet as PathSetupSheet
|
||||
import PathScripts.PathSetupSheetOpPrototype as PathSetupSheetOpPrototype
|
||||
import PathScripts.PathUtil as PathUtil
|
||||
|
||||
from PySide import QtCore, QtGui
|
||||
@@ -93,17 +94,97 @@ class ViewProvider:
|
||||
def doubleClicked(self, vobj):
|
||||
self.setEdit(vobj)
|
||||
|
||||
class PropertyEditorDelegate(QtGui.QStyledItemDelegate):
|
||||
|
||||
def paint(self, painter, option, index):
|
||||
#PathLog.track(index.column(), type(option))
|
||||
if False and 2 == index.column():
|
||||
PathLog.track(index.row(), index.data().toString())
|
||||
painter.drawText(option.rect, index.data().toString())
|
||||
else:
|
||||
QtGui.QStyledItemDelegate.paint(self, painter, option, index)
|
||||
|
||||
def createEditor(self, parent, option, index):
|
||||
PathLog.track(index.row(), index.column())
|
||||
if 0 == index.column():
|
||||
return QtGui.QStyledItemDelegate.createEditor(self, parent, option, index)
|
||||
return None
|
||||
|
||||
def setEditorData(self, widget, index):
|
||||
PathLog.track(index.row(), index.column())
|
||||
if 0 == index.column():
|
||||
QtGui.QStyledItemDelegate.setEditorData(self, widget, index)
|
||||
isset = widget.isChecked()
|
||||
index.model().item(index.row(), 1).setEnabled(isset)
|
||||
index.model().item(index.row(), 2).setEnabled(isset)
|
||||
print("setEditorData(%s)" % widget)
|
||||
|
||||
def setModelData(self, widget, model, index):
|
||||
PathLog.track(index.row(), index.column())
|
||||
if 0 == index.column():
|
||||
return QtGui.QStyledItemDelegate.setModelData(self, widget, model, index)
|
||||
print("setModelData(%s)" % widget)
|
||||
|
||||
def updateEditorGeometry(self, widget, option, index):
|
||||
#print("is this even called")
|
||||
if widget:
|
||||
widget.setGeometry(option.rect)
|
||||
else:
|
||||
print("so sad")
|
||||
|
||||
class OpTaskPanel:
|
||||
|
||||
def __init__(self, obj, name, op):
|
||||
self.name = name
|
||||
self.prefix = PathSetupSheet.OpNamePrefix(name)
|
||||
self.obj = obj
|
||||
self.op = op
|
||||
self.form = FreeCADGui.PySideUic.loadUi(":/panels/SetupOp.ui")
|
||||
self.form.setWindowTitle(self.name)
|
||||
self.props = sorted(op.properties())
|
||||
self.prototype = PathSetupSheetOpPrototype.OpPrototype()
|
||||
op.factory("OpPrototype.%s" % name, self.prototype)
|
||||
|
||||
def updateData(self, topLeft, bottomRight):
|
||||
if 0 == topLeft.column():
|
||||
isset = self.model.item(topLeft.row(), 0).checkState() == QtCore.Qt.Checked
|
||||
self.model.item(topLeft.row(), 1).setEnabled(isset)
|
||||
self.model.item(topLeft.row(), 2).setEnabled(isset)
|
||||
|
||||
|
||||
def setupUi(self):
|
||||
PathLog.track()
|
||||
|
||||
self.delegate = PropertyEditorDelegate(self.form)
|
||||
self.model = QtGui.QStandardItemModel(len(self.props), 3, self.form)
|
||||
self.model.setHorizontalHeaderLabels(['Set', 'Property', 'Value'])
|
||||
|
||||
for i,name in enumerate(self.props):
|
||||
prop = self.prototype.getProperty(name)
|
||||
isset = hasattr(self.obj, self.propertyName(name))
|
||||
if isset:
|
||||
prop.setValue(getattr(self.obj, self.propertyName(name)))
|
||||
|
||||
self.model.setData(self.model.index(i, 0), isset, QtCore.Qt.EditRole)
|
||||
self.model.setData(self.model.index(i, 1), name, QtCore.Qt.EditRole)
|
||||
self.model.setData(self.model.index(i, 2), prop, QtCore.Qt.EditRole)
|
||||
self.model.setData(self.model.index(i, 2), prop.toString(), QtCore.Qt.DisplayRole)
|
||||
|
||||
self.model.item(i, 0).setCheckable(True)
|
||||
self.model.item(i, 0).setText('')
|
||||
self.model.item(i, 1).setEditable(False)
|
||||
if not isset:
|
||||
self.model.item(i, 1).setEnabled(False)
|
||||
self.model.item(i, 2).setEnabled(False)
|
||||
|
||||
self.form.table.setModel(self.model)
|
||||
self.form.table.setItemDelegate(self.delegate)
|
||||
self.form.table.resizeColumnsToContents()
|
||||
|
||||
self.model.dataChanged.connect(self.updateData)
|
||||
|
||||
def propertyName(self, prop):
|
||||
return "%{}_%{}".format(self.prefix, prop)
|
||||
|
||||
class TaskPanel:
|
||||
DataIds = QtCore.Qt.ItemDataRole.UserRole
|
||||
|
||||
@@ -39,6 +39,7 @@ class Property(object):
|
||||
self.category = category
|
||||
self.info = info
|
||||
self.editorMode = 0
|
||||
self.value = ''
|
||||
|
||||
def setValue(self, value):
|
||||
self.value = value
|
||||
@@ -48,7 +49,20 @@ class Property(object):
|
||||
def setEditorMode(self, mode):
|
||||
self.editorMode = mode
|
||||
|
||||
def toString(self):
|
||||
if self.value:
|
||||
return str(self.value)
|
||||
t = self.typeString()
|
||||
p = 'an' if t[0] in ['A', 'E', 'I', 'O', 'U'] else 'a'
|
||||
return "%s %s" % (p, t)
|
||||
|
||||
def typeString(self):
|
||||
return "Property"
|
||||
|
||||
class PropertyEnumeration(Property):
|
||||
def typeString(self):
|
||||
return "Enumeration"
|
||||
|
||||
def setValue(self, value):
|
||||
if list == type(value):
|
||||
self.enums = value
|
||||
@@ -59,19 +73,24 @@ class PropertyEnumeration(Property):
|
||||
return self.enums
|
||||
|
||||
class PropertyDistance(Property):
|
||||
pass
|
||||
def typeString(self):
|
||||
return "Distance"
|
||||
|
||||
class PropertyPercent(Property):
|
||||
pass
|
||||
def typeString(self):
|
||||
return "Percent"
|
||||
|
||||
class PropertyFloat(Property):
|
||||
pass
|
||||
def typeString(self):
|
||||
return "Float"
|
||||
|
||||
class PropertyBool(Property):
|
||||
pass
|
||||
def typeString(self):
|
||||
return "Bool"
|
||||
|
||||
class PropertyString(Property):
|
||||
pass
|
||||
def typeString(self):
|
||||
return "String"
|
||||
|
||||
class OpPrototype(object):
|
||||
|
||||
@@ -99,6 +118,8 @@ class OpPrototype(object):
|
||||
def setEditorMode(self, name, mode):
|
||||
self.properties[name].setEditorMode(mode)
|
||||
|
||||
def getProperty(self, name):
|
||||
return self.properties[name]
|
||||
|
||||
def setupProperties(self, setup):
|
||||
return [p for p in self.properties if p.name in setup]
|
||||
|
||||
Reference in New Issue
Block a user