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:
@@ -82,11 +82,9 @@ Enumeration::~Enumeration()
|
||||
void Enumeration::tearDown(void)
|
||||
{
|
||||
// Ugly...
|
||||
char **plEnums = (char **)_EnumArray;
|
||||
|
||||
// Delete C Strings first
|
||||
while (*plEnums != NULL) {
|
||||
free(*(plEnums++));
|
||||
for(char **plEnums = (char **)_EnumArray; *plEnums != NULL; ++plEnums) {
|
||||
// Delete C Strings first
|
||||
free(*plEnums);
|
||||
}
|
||||
|
||||
delete [] _EnumArray;
|
||||
@@ -98,6 +96,9 @@ void Enumeration::tearDown(void)
|
||||
|
||||
void Enumeration::setEnums(const char **plEnums)
|
||||
{
|
||||
if(plEnums == _EnumArray)
|
||||
return;
|
||||
|
||||
std::string oldValue;
|
||||
bool preserve = (isValid() && plEnums != NULL);
|
||||
if (preserve) {
|
||||
@@ -118,7 +119,11 @@ void Enumeration::setEnums(const char **plEnums)
|
||||
findMaxVal();
|
||||
|
||||
// set _index
|
||||
_index = 0;
|
||||
if (_index < 0)
|
||||
_index = 0;
|
||||
else if (_index > _maxVal)
|
||||
_index = _maxVal;
|
||||
|
||||
if (preserve) {
|
||||
setValue(oldValue);
|
||||
}
|
||||
@@ -311,6 +316,10 @@ Enumeration & Enumeration::operator=(const Enumeration &other)
|
||||
|
||||
bool Enumeration::operator==(const Enumeration &other) const
|
||||
{
|
||||
if(_index != other._index)
|
||||
return false;
|
||||
if (getCStr() == other.getCStr())
|
||||
return true;
|
||||
if (getCStr() == NULL || other.getCStr() == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -71,6 +71,8 @@ std::string Property::getFullName() const {
|
||||
if(myName) {
|
||||
if(father)
|
||||
name = father->getFullName() + ".";
|
||||
else
|
||||
name = "?.";
|
||||
name += myName;
|
||||
}else
|
||||
return "?";
|
||||
|
||||
@@ -304,18 +304,22 @@ PropertyEnumeration::~PropertyEnumeration()
|
||||
|
||||
void PropertyEnumeration::setEnums(const char **plEnums)
|
||||
{
|
||||
// Setting the enum is done only once inside the constructor
|
||||
// but before the current index is already set. So, this needs
|
||||
// to be preserved.
|
||||
int index = _enum._index;
|
||||
// For backward compatibility, if the property container is not attached to
|
||||
// any document (i.e. its full name starts with '?'), do not notify, or
|
||||
// else existing code may crash.
|
||||
bool notify = !boost::starts_with(getFullName(), "?");
|
||||
if (notify)
|
||||
aboutToSetValue();
|
||||
_enum.setEnums(plEnums);
|
||||
// Make sure not to set an index out of range
|
||||
int max = _enum.maxValue();
|
||||
_enum._index = std::min<int>(index, max);
|
||||
if (notify)
|
||||
hasSetValue();
|
||||
}
|
||||
|
||||
void PropertyEnumeration::setEnums(const std::vector<std::string> &Enums)
|
||||
{
|
||||
// _enum.setEnums() will preserve old value possible, so no need to do it
|
||||
// here
|
||||
#if 0
|
||||
if (_enum.isValid()) {
|
||||
const std::string &index = getValueAsString();
|
||||
_enum.setEnums(Enums);
|
||||
@@ -323,6 +327,9 @@ void PropertyEnumeration::setEnums(const std::vector<std::string> &Enums)
|
||||
} else {
|
||||
_enum.setEnums(Enums);
|
||||
}
|
||||
#else
|
||||
setEnumVector(Enums);
|
||||
#endif
|
||||
}
|
||||
|
||||
void PropertyEnumeration::setValue(const char *value)
|
||||
@@ -378,6 +385,19 @@ std::vector<std::string> PropertyEnumeration::getEnumVector() const
|
||||
return _enum.getEnumVector();
|
||||
}
|
||||
|
||||
void PropertyEnumeration::setEnumVector(const std::vector<std::string> &values)
|
||||
{
|
||||
// For backward compatibility, if the property container is not attached to
|
||||
// any document (i.e. its full name starts with '?'), do not notify, or
|
||||
// else existing code may crash.
|
||||
bool notify = !boost::starts_with(getFullName(), "?");
|
||||
if (notify)
|
||||
aboutToSetValue();
|
||||
_enum.setEnums(values);
|
||||
if (notify)
|
||||
hasSetValue();
|
||||
}
|
||||
|
||||
const char ** PropertyEnumeration::getEnums() const
|
||||
{
|
||||
return _enum.getEnums();
|
||||
@@ -414,6 +434,8 @@ void PropertyEnumeration::Restore(Base::XMLReader &reader)
|
||||
// get the value of my Attribute
|
||||
long val = reader.getAttributeAsInteger("value");
|
||||
|
||||
aboutToSetValue();
|
||||
|
||||
if (reader.hasAttribute("CustomEnum")) {
|
||||
reader.readElement("CustomEnumList");
|
||||
int count = reader.getAttributeAsInteger("count");
|
||||
@@ -436,14 +458,21 @@ void PropertyEnumeration::Restore(Base::XMLReader &reader)
|
||||
val = getValue();
|
||||
}
|
||||
|
||||
setValue(val);
|
||||
_enum.setValue(val);
|
||||
hasSetValue();
|
||||
}
|
||||
|
||||
PyObject * PropertyEnumeration::getPyObject()
|
||||
{
|
||||
if (!_enum.isValid()) {
|
||||
PyErr_SetString(PyExc_AssertionError, "The enum is empty");
|
||||
return nullptr;
|
||||
// There is legimate use case of having an empty PropertyEnumeration and
|
||||
// set its enumeration items later. Returning error here cause hasattr()
|
||||
// to return False even though the property exists.
|
||||
//
|
||||
// PyErr_SetString(PyExc_AssertionError, "The enum is empty");
|
||||
// return 0;
|
||||
//
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
return Py_BuildValue("s", getValueAsString());
|
||||
@@ -458,6 +487,7 @@ void PropertyEnumeration::setPyObject(PyObject *value)
|
||||
_enum.setValue(val, true);
|
||||
hasSetValue();
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (PyUnicode_Check(value)) {
|
||||
std::string str = PyUnicode_AsUTF8(value);
|
||||
@@ -467,34 +497,47 @@ void PropertyEnumeration::setPyObject(PyObject *value)
|
||||
hasSetValue();
|
||||
}
|
||||
else {
|
||||
std::stringstream out;
|
||||
out << "'" << str << "' is not part of the enumeration";
|
||||
throw Base::ValueError(out.str());
|
||||
FC_THROWM(Base::ValueError, "'" << str
|
||||
<< "' is not part of the enumeration in "
|
||||
<< getFullName());
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (PySequence_Check(value)) {
|
||||
Py_ssize_t nSize = PySequence_Size(value);
|
||||
std::vector<std::string> values;
|
||||
values.resize(nSize);
|
||||
|
||||
for (Py_ssize_t i = 0; i < nSize; ++i) {
|
||||
PyObject *item = PySequence_GetItem(value, i);
|
||||
try {
|
||||
std::vector<std::string> values;
|
||||
|
||||
if (PyUnicode_Check(item)) {
|
||||
values[i] = PyUnicode_AsUTF8(item);
|
||||
}
|
||||
else {
|
||||
std::string error = std::string("type in list must be str or unicode, not ");
|
||||
throw Base::TypeError(error + item->ob_type->tp_name);
|
||||
int idx = -1;
|
||||
Py::Sequence seq(value);
|
||||
|
||||
if(seq.size() == 2) {
|
||||
Py::Object v(seq[0].ptr());
|
||||
if(!v.isString() && v.isSequence()) {
|
||||
idx = Py::Int(seq[1].ptr());
|
||||
seq = v;
|
||||
}
|
||||
}
|
||||
|
||||
values.resize(seq.size());
|
||||
|
||||
for (int i = 0; i < seq.size(); ++i)
|
||||
values[i] = Py::Object(seq[i].ptr()).as_string();
|
||||
|
||||
aboutToSetValue();
|
||||
_enum.setEnums(values);
|
||||
if (idx>=0)
|
||||
_enum.setValue(idx,true);
|
||||
hasSetValue();
|
||||
return;
|
||||
} catch (Py::Exception &) {
|
||||
Base::PyException e;
|
||||
e.ReportException();
|
||||
}
|
||||
_enum.setEnums(values);
|
||||
setValue((long)0);
|
||||
}
|
||||
else {
|
||||
std::string error = std::string("type must be int, str or unicode not ");
|
||||
throw Base::TypeError(error + value->ob_type->tp_name);
|
||||
}
|
||||
|
||||
FC_THROWM(Base::TypeError, "PropertyEnumeration " << getFullName()
|
||||
<< " expects type to be int, string, or list(string), or list(list, int)");
|
||||
}
|
||||
|
||||
Property * PropertyEnumeration::Copy() const
|
||||
@@ -504,22 +547,20 @@ Property * PropertyEnumeration::Copy() const
|
||||
|
||||
void PropertyEnumeration::Paste(const Property &from)
|
||||
{
|
||||
aboutToSetValue();
|
||||
|
||||
const PropertyEnumeration& prop = dynamic_cast<const PropertyEnumeration&>(from);
|
||||
_enum = prop._enum;
|
||||
|
||||
hasSetValue();
|
||||
setValue(prop._enum);
|
||||
}
|
||||
|
||||
void PropertyEnumeration::setPathValue(const ObjectIdentifier &path, const boost::any &value)
|
||||
void PropertyEnumeration::setPathValue(const ObjectIdentifier &, const boost::any &value)
|
||||
{
|
||||
verifyPath(path);
|
||||
|
||||
if (value.type() == typeid(int))
|
||||
setValue(boost::any_cast<int>(value));
|
||||
else if (value.type() == typeid(long))
|
||||
setValue(boost::any_cast<long>(value));
|
||||
else if (value.type() == typeid(double))
|
||||
setValue(boost::any_cast<double>(value));
|
||||
else if (value.type() == typeid(float))
|
||||
setValue(boost::any_cast<float>(value));
|
||||
else if (value.type() == typeid(short))
|
||||
setValue(boost::any_cast<short>(value));
|
||||
else if (value.type() == typeid(std::string))
|
||||
@@ -528,8 +569,61 @@ void PropertyEnumeration::setPathValue(const ObjectIdentifier &path, const boost
|
||||
setValue(boost::any_cast<char*>(value));
|
||||
else if (value.type() == typeid(const char*))
|
||||
setValue(boost::any_cast<const char*>(value));
|
||||
else
|
||||
throw bad_cast();
|
||||
else {
|
||||
Base::PyGILStateLocker lock;
|
||||
Py::Object pyValue = pyObjectFromAny(value);
|
||||
setPyObject(pyValue.ptr());
|
||||
}
|
||||
}
|
||||
|
||||
bool PropertyEnumeration::setPyPathValue(const ObjectIdentifier &, const Py::Object &value)
|
||||
{
|
||||
setPyObject(value.ptr());
|
||||
return true;
|
||||
}
|
||||
|
||||
const boost::any PropertyEnumeration::getPathValue(const ObjectIdentifier &path) const
|
||||
{
|
||||
std::string p = path.getSubPathStr();
|
||||
if (p == ".Enum" || p == ".All") {
|
||||
Base::PyGILStateLocker lock;
|
||||
Py::Object res;
|
||||
getPyPathValue(path, res);
|
||||
return pyObjectToAny(res,false);
|
||||
}
|
||||
else if (p == ".String") {
|
||||
auto v = getValueAsString();
|
||||
return std::string(v?v:"");
|
||||
} else
|
||||
return getValue();
|
||||
}
|
||||
|
||||
bool PropertyEnumeration::getPyPathValue(const ObjectIdentifier &path, Py::Object &r) const
|
||||
{
|
||||
std::string p = path.getSubPathStr();
|
||||
if (p == ".Enum" || p == ".All") {
|
||||
Base::PyGILStateLocker lock;
|
||||
Py::Tuple res(_enum.maxValue()+1);
|
||||
const char **enums = _enum.getEnums();
|
||||
PropertyString tmp;
|
||||
for(int i=0;i<=_enum.maxValue();++i) {
|
||||
tmp.setValue(enums[i]);
|
||||
res.setItem(i,Py::asObject(tmp.getPyObject()));
|
||||
}
|
||||
if(p == ".Enum")
|
||||
r = res;
|
||||
else {
|
||||
Py::Tuple tuple(2);
|
||||
tuple.setItem(0, res);
|
||||
tuple.setItem(1, Py::Int(getValue()));
|
||||
r = tuple;
|
||||
}
|
||||
} else if (p == ".String") {
|
||||
auto v = getValueAsString();
|
||||
r = Py::String(v?v:"");
|
||||
} else
|
||||
r = Py::Int(getValue());
|
||||
return true;
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
|
||||
@@ -186,11 +186,13 @@ public:
|
||||
const char * getValueAsString(void) const;
|
||||
|
||||
/// Returns Enumeration object
|
||||
Enumeration getEnum(void) const;
|
||||
const Enumeration &getEnum(void) const;
|
||||
|
||||
/// get all possible enum values as vector of strings
|
||||
std::vector<std::string> getEnumVector(void) const;
|
||||
|
||||
/// set enum values as vector of strings
|
||||
void setEnumVector(const std::vector<std::string> &);
|
||||
/// get the pointer to the enum list
|
||||
const char ** getEnums(void) const;
|
||||
|
||||
@@ -211,7 +213,9 @@ public:
|
||||
virtual void Paste(const Property &from);
|
||||
|
||||
virtual void setPathValue(const App::ObjectIdentifier & path, const boost::any & value);
|
||||
virtual const boost::any getPathValue(const App::ObjectIdentifier & /*path*/) const { return _enum; }
|
||||
virtual bool setPyPathValue(const App::ObjectIdentifier & path, const Py::Object &value);
|
||||
virtual const boost::any getPathValue(const App::ObjectIdentifier & /*path*/) const;
|
||||
virtual bool getPyPathValue(const ObjectIdentifier &path, Py::Object &r) const;
|
||||
|
||||
private:
|
||||
Enumeration _enum;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user