App/Gui: improve expression binding of PropertyEnumeration

The enumeration items are exposed through sub path '.Enum'. When
'ShowAll' is enabled in property view, this sub path is exposed as a
sub property item named 'Enum', and can be either manually edited or
bound with an expression.
This commit is contained in:
Zheng, Lei
2019-12-23 11:48:03 +08:00
committed by Chris Hennes
parent 3cc2b49ee9
commit 72ae26dfee
7 changed files with 241 additions and 77 deletions

View File

@@ -100,6 +100,7 @@ ViewProviderDocumentObject::ViewProviderDocumentObject()
ViewProviderDocumentObject::~ViewProviderDocumentObject()
{
// Make sure that the property class does not destruct our string list
DisplayMode.setContainer(nullptr);
DisplayMode.setEnums(0);
}
@@ -687,7 +688,7 @@ ViewProviderDocumentObject *ViewProviderDocumentObject::getLinkedViewProvider(
std::string ViewProviderDocumentObject::getFullName() const {
if(pcObject)
return pcObject->getFullName() + ".ViewObject";
return std::string();
return std::string("?");
}
bool ViewProviderDocumentObject::allowTreeOrderSwap(const App::DocumentObject *child1, const App::DocumentObject *child2) const

View File

@@ -770,7 +770,7 @@ QVariant PropertyFontItem::value(const App::Property* prop) const
void PropertyFontItem::setValue(const QVariant& value)
{
if (!value.canConvert(QVariant::String))
if (hasExpression() || !value.canConvert(QVariant::String))
return;
QString val = value.toString();
QString data = QString::fromLatin1("\"%1\"").arg(val);
@@ -1270,7 +1270,7 @@ QVariant PropertyBoolItem::value(const App::Property* prop) const
void PropertyBoolItem::setValue(const QVariant& value)
{
if (!value.canConvert(QVariant::Bool))
if (hasExpression() || !value.canConvert(QVariant::Bool))
return;
bool val = value.toBool();
QString data = (val ? QLatin1String("True") : QLatin1String("False"));
@@ -1377,7 +1377,7 @@ QVariant PropertyVectorItem::value(const App::Property* prop) const
void PropertyVectorItem::setValue(const QVariant& value)
{
if (!value.canConvert<Base::Vector3d>())
if (hasExpression() || !value.canConvert<Base::Vector3d>())
return;
const Base::Vector3d& val = value.value<Base::Vector3d>();
QString data = QString::fromLatin1("(%1, %2, %3)")
@@ -1652,7 +1652,7 @@ QVariant PropertyVectorDistanceItem::value(const App::Property* prop) const
void PropertyVectorDistanceItem::setValue(const QVariant& variant)
{
if (!variant.canConvert<Base::Vector3d>())
if (hasExpression() || !variant.canConvert<Base::Vector3d>())
return;
const Base::Vector3d& value = variant.value<Base::Vector3d>();
@@ -1869,7 +1869,7 @@ QVariant PropertyMatrixItem::toolTip(const App::Property* prop) const
void PropertyMatrixItem::setValue(const QVariant& value)
{
if (!value.canConvert<Base::Matrix4D>())
if (hasExpression() || !value.canConvert<Base::Matrix4D>())
return;
const Base::Matrix4D& val = value.value<Base::Matrix4D>();
const int decimals=16;
@@ -2644,7 +2644,7 @@ QVariant PropertyPlacementItem::toString(const QVariant& prop) const
void PropertyPlacementItem::setValue(const QVariant& value)
{
if (!value.canConvert<Base::Placement>())
if (hasExpression() || !value.canConvert<Base::Placement>())
return;
// Accept this only if the user changed the axis, angle or position but
// not if >this< item loses focus
@@ -2711,7 +2711,37 @@ void PropertyPlacementItem::propertyBound()
PROPERTYITEM_SOURCE(Gui::PropertyEditor::PropertyEnumItem)
PropertyEnumItem::PropertyEnumItem()
:m_enum(0)
{
if(PropertyView::showAll()) {
m_enum = static_cast<PropertyStringListItem*>(PropertyStringListItem::create());
m_enum->setParent(this);
m_enum->setPropertyName(QLatin1String(QT_TRANSLATE_NOOP("App::Property", "Enum")));
this->appendChild(m_enum);
}
}
void PropertyEnumItem::propertyBound()
{
if (m_enum && isBound())
m_enum->bind(App::ObjectIdentifier(getPath())<<App::ObjectIdentifier::String("Enum"));
}
void PropertyEnumItem::setEnum(QStringList values)
{
setData(values);
}
QStringList PropertyEnumItem::getEnum() const
{
QStringList res;
auto prop = getFirstProperty();
if (prop && prop->getTypeId().isDerivedFrom(App::PropertyEnumeration::getClassTypeId())) {
const App::PropertyEnumeration* prop_enum = static_cast<const App::PropertyEnumeration*>(prop);
for(int i=0,last=prop_enum->getEnum().maxValue();i<=last;++i)
res.push_back(QString::fromUtf8(prop_enum->getEnums()[i]));
}
return res;
}
QVariant PropertyEnumItem::value(const App::Property* prop) const
@@ -2719,25 +2749,40 @@ QVariant PropertyEnumItem::value(const App::Property* prop) const
assert(prop && prop->getTypeId().isDerivedFrom(App::PropertyEnumeration::getClassTypeId()));
const App::PropertyEnumeration* prop_enum = static_cast<const App::PropertyEnumeration*>(prop);
const std::vector<std::string>& value = prop_enum->getEnumVector();
long currentItem = prop_enum->getValue();
if (currentItem < 0 || currentItem >= static_cast<long>(value.size()))
if(!prop_enum->isValid())
return QVariant(QString());
return QVariant(QString::fromUtf8(value[currentItem].c_str()));
return QVariant(QString::fromUtf8(prop_enum->getValueAsString()));
}
void PropertyEnumItem::setValue(const QVariant& value)
{
if (!value.canConvert(QVariant::StringList))
if (hasExpression())
return;
QStringList items = value.toStringList();
if (!items.isEmpty()) {
QByteArray val = items.front().toUtf8();
std::string str = Base::Tools::escapedUnicodeFromUtf8(val);
QString data = QString::fromLatin1("u\"%1\"").arg(QString::fromStdString(str));
setPropertyValue(data);
QString data;
if (value.type() == QVariant::StringList) {
QStringList values = value.toStringList();
QTextStream str(&data);
str << "[";
for (QStringList::Iterator it = values.begin(); it != values.end(); ++it) {
QString text(*it);
text.replace(QString::fromUtf8("'"),QString::fromUtf8("\\'"));
std::string pystr = Base::Tools::escapedUnicodeFromUtf8(text.toUtf8());
pystr = Base::Interpreter().strToPython(pystr.c_str());
str << "u\"" << pystr.c_str() << "\", ";
}
str << "]";
}
else if (value.canConvert(QVariant::String)) {
QByteArray val = value.toString().toUtf8();
std::string str = Base::Tools::escapedUnicodeFromUtf8(val);
data = QString::fromLatin1("u\"%1\"").arg(QString::fromStdString(str));
}
else
return;
setPropertyValue(data);
}
QWidget* PropertyEnumItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const
@@ -2851,7 +2896,7 @@ QVariant PropertyStringListItem::value(const App::Property* prop) const
void PropertyStringListItem::setValue(const QVariant& value)
{
if (!value.canConvert(QVariant::StringList))
if (hasExpression() || !value.canConvert(QVariant::StringList))
return;
QStringList values = value.toStringList();
QString data;
@@ -2928,7 +2973,7 @@ QVariant PropertyFloatListItem::value(const App::Property* prop) const
void PropertyFloatListItem::setValue(const QVariant& value)
{
if (!value.canConvert(QVariant::StringList))
if (hasExpression() || !value.canConvert(QVariant::StringList))
return;
QStringList values = value.toStringList();
QString data;
@@ -3003,7 +3048,7 @@ QVariant PropertyIntegerListItem::value(const App::Property* prop) const
void PropertyIntegerListItem::setValue(const QVariant& value)
{
if (!value.canConvert(QVariant::StringList))
if (hasExpression() || !value.canConvert(QVariant::StringList))
return;
QStringList values = value.toStringList();
QString data;
@@ -3055,7 +3100,7 @@ QVariant PropertyColorItem::value(const App::Property* prop) const
void PropertyColorItem::setValue(const QVariant& value)
{
if (!value.canConvert<QColor>())
if (hasExpression() || !value.canConvert<QColor>())
return;
QColor col = value.value<QColor>();
App::Color val; val.setValue<QColor>(col);
@@ -3347,7 +3392,7 @@ QVariant PropertyMaterialItem::value(const App::Property* prop) const
void PropertyMaterialItem::setValue(const QVariant& value)
{
if (!value.canConvert<Material>())
if (hasExpression() || !value.canConvert<Material>())
return;
Material mat = value.value<Material>();
@@ -3779,7 +3824,7 @@ QVariant PropertyMaterialListItem::value(const App::Property* prop) const
void PropertyMaterialListItem::setValue(const QVariant& value)
{
if (!value.canConvert<QVariantList>())
if (hasExpression() || !value.canConvert<QVariantList>())
return;
QVariantList list = value.toList();
@@ -3900,7 +3945,7 @@ QVariant PropertyFileItem::value(const App::Property* prop) const
void PropertyFileItem::setValue(const QVariant& value)
{
if (!value.canConvert(QVariant::String))
if (hasExpression() || !value.canConvert(QVariant::String))
return;
QString val = value.toString();
QString data = QString::fromLatin1("\"%1\"").arg(val);
@@ -3957,7 +4002,7 @@ QVariant PropertyPathItem::value(const App::Property* prop) const
void PropertyPathItem::setValue(const QVariant& value)
{
if (!value.canConvert(QVariant::String))
if (hasExpression() || !value.canConvert(QVariant::String))
return;
QString val = value.toString();
QString data = QString::fromLatin1("\"%1\"").arg(val);
@@ -4009,7 +4054,7 @@ QVariant PropertyTransientFileItem::value(const App::Property* prop) const
void PropertyTransientFileItem::setValue(const QVariant& value)
{
if (!value.canConvert(QVariant::String))
if (hasExpression() || !value.canConvert(QVariant::String))
return;
QString val = value.toString();
QString data = QString::fromLatin1("\"%1\"").arg(val);
@@ -4267,7 +4312,6 @@ PropertyLinkListItem::PropertyLinkListItem()
{
}
// --------------------------------------------------------------------
PropertyItemEditorFactory::PropertyItemEditorFactory()
{

View File

@@ -778,6 +778,8 @@ private:
PropertyVectorDistanceItem* m_p;
};
class PropertyStringListItem;
/**
* Edit properties of enum type.
* \author Werner Mayer
@@ -785,18 +787,26 @@ private:
class GuiExport PropertyEnumItem: public PropertyItem
{
Q_OBJECT
Q_PROPERTY(QStringList Enum READ getEnum WRITE setEnum DESIGNABLE true USER true)
PROPERTYITEM_HEADER
virtual QWidget* createEditor(QWidget* parent, const QObject* receiver, const char* method) const;
virtual void setEditorData(QWidget *editor, const QVariant& data) const;
virtual QVariant editorData(QWidget *editor) const;
QStringList getEnum() const;
void setEnum(QStringList);
protected:
virtual QVariant value(const App::Property*) const;
virtual void setValue(const QVariant&);
virtual void propertyBound();
protected:
PropertyEnumItem();
private:
PropertyStringListItem* m_enum;
};
/**