From dcad13135770aff0930fafd0128a953c07e054b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Tr=C3=B6ger?= Date: Tue, 13 Oct 2015 08:32:23 +0200 Subject: [PATCH] Expressions: Fix property editor behavior - change responsibility of python code emition - Correct python code handling for expressions - handle constraints expressions handling --- src/App/PropertyExpressionEngine.cpp | 3 +- src/Gui/ExpressionBinding.cpp | 2 +- src/Gui/ExpressionBinding.h | 2 +- src/Gui/QuantitySpinBox.cpp | 3 - src/Gui/propertyeditor/PropertyItem.cpp | 128 ++++++++++-------- .../Gui/PropertyConstraintListItem.cpp | 2 +- 6 files changed, 77 insertions(+), 63 deletions(-) diff --git a/src/App/PropertyExpressionEngine.cpp b/src/App/PropertyExpressionEngine.cpp index ddcbed548..0a7f0acb6 100644 --- a/src/App/PropertyExpressionEngine.cpp +++ b/src/App/PropertyExpressionEngine.cpp @@ -317,7 +317,8 @@ void PropertyExpressionEngine::setValue(const ObjectIdentifier & path, boost::sh prop->getPathValue(usePath); // Check if the current expression equals the new one and do nothing if so to reduce unneeded computations - if(expressions.find(usePath) != expressions.end() && expr == expressions[usePath].expression) + ExpressionMap::iterator it = expressions.find(usePath); + if(it != expressions.end() && expr == it->second.expression) return; if (expr) { diff --git a/src/Gui/ExpressionBinding.cpp b/src/Gui/ExpressionBinding.cpp index e560f4960..f4ec86ef0 100644 --- a/src/Gui/ExpressionBinding.cpp +++ b/src/Gui/ExpressionBinding.cpp @@ -180,7 +180,7 @@ bool ExpressionBinding::apply() std::string name = docObj->getNameInDocument(); - return apply("App.ActiveDocument." + name + "." + std::string(prop->getName())); + return apply("App.ActiveDocument." + name + "." + getPath().toEscapedString()); } void ExpressionBinding::expressionChange(const ObjectIdentifier& id) { diff --git a/src/Gui/ExpressionBinding.h b/src/Gui/ExpressionBinding.h index f89438ab5..b794447aa 100644 --- a/src/Gui/ExpressionBinding.h +++ b/src/Gui/ExpressionBinding.h @@ -52,7 +52,7 @@ public: //auto apply means that the python code is issues not only on aplly() but //also on setExpression - bool autoApply() {return m_autoApply;}; + bool autoApply() const {return m_autoApply;}; void setAutoApply(bool value) {m_autoApply = value;}; protected: diff --git a/src/Gui/QuantitySpinBox.cpp b/src/Gui/QuantitySpinBox.cpp index 0cf4806a7..6b6a92ef1 100644 --- a/src/Gui/QuantitySpinBox.cpp +++ b/src/Gui/QuantitySpinBox.cpp @@ -317,10 +317,7 @@ void Gui::QuantitySpinBox::onChange() { QPalette p(lineEdit()->palette()); p.setColor(QPalette::Active, QPalette::Text, defaultPalette.color(QPalette::Text)); lineEdit()->setPalette(p); -<<<<<<< 175351b02ea3a586e1dbe0dc5e993966714ea236 -======= iconLabel->setToolTip(QString()); ->>>>>>> further expression integration for property editor } iconLabel->setToolTip(QString()); } diff --git a/src/Gui/propertyeditor/PropertyItem.cpp b/src/Gui/propertyeditor/PropertyItem.cpp index 19c83851b..5e9590fb6 100644 --- a/src/Gui/propertyeditor/PropertyItem.cpp +++ b/src/Gui/propertyeditor/PropertyItem.cpp @@ -62,6 +62,7 @@ TYPESYSTEM_SOURCE(Gui::PropertyEditor::PropertyItem, Base::BaseClass); PropertyItem::PropertyItem() : parentItem(0), readonly(false), cleared(false) { precision = Base::UnitsApi::getDecimals(); + setAutoApply(true); } PropertyItem::~PropertyItem() @@ -86,19 +87,21 @@ void PropertyItem::setPropertyData(const std::vector& items) const App::Property& p = *items.front(); - if(!(p.getContainer()->getPropertyType(&p) & App::Prop_ReadOnly)) { - - App::ObjectIdentifier id(p); - std::vector paths; - p.getPaths(paths); - - //there may be no paths available in this property (for example an empty constraint list) - if(id.getProperty() && !paths.empty()) - bind(id); - + try { + if(!(p.getContainer()->isReadOnly(&p))) { + + App::ObjectIdentifier id(p); + std::vector paths; + p.getPaths(paths); + + //there may be no paths available in this property (for example an empty constraint list) + if(id.getProperty() && !paths.empty()) + bind(id); + + } } - else - setReadOnly(true); + //it may happen that setting properties is not possible + catch(...) {}; } propertyItems = items; @@ -247,26 +250,26 @@ QString PropertyItem::pythonIdentifier(const App::Property* prop) const if (parent->getTypeId() == App::Document::getClassTypeId()) { App::Document* doc = static_cast(parent); QString docName = QString::fromAscii(App::GetApplication().getDocumentName(doc)); - QString propName = QString::fromAscii(parent->getPropertyName(prop)); - return QString::fromAscii("FreeCAD.getDocument(\"%1\").%2").arg(docName).arg(propName); + QString propName = QString::fromAscii(parent->getPropertyName(prop)); + return QString::fromAscii("FreeCAD.getDocument(\"%1\").%2").arg(docName).arg(propName); } if (parent->getTypeId().isDerivedFrom(App::DocumentObject::getClassTypeId())) { App::DocumentObject* obj = static_cast(parent); App::Document* doc = obj->getDocument(); QString docName = QString::fromAscii(App::GetApplication().getDocumentName(doc)); QString objName = QString::fromAscii(obj->getNameInDocument()); - QString propName = QString::fromAscii(parent->getPropertyName(prop)); + QString propName = QString::fromAscii(parent->getPropertyName(prop)); return QString::fromAscii("FreeCAD.getDocument(\"%1\").getObject(\"%2\").%3") - .arg(docName).arg(objName).arg(propName); + .arg(docName).arg(objName).arg(propName); } if (parent->getTypeId().isDerivedFrom(Gui::ViewProviderDocumentObject::getClassTypeId())) { App::DocumentObject* obj = static_cast(parent)->getObject(); App::Document* doc = obj->getDocument(); QString docName = QString::fromAscii(App::GetApplication().getDocumentName(doc)); QString objName = QString::fromAscii(obj->getNameInDocument()); - QString propName = QString::fromAscii(parent->getPropertyName(prop)); + QString propName = QString::fromAscii(parent->getPropertyName(prop)); return QString::fromAscii("FreeCADGui.getDocument(\"%1\").getObject(\"%2\").%3") - .arg(docName).arg(objName).arg(propName); + .arg(docName).arg(objName).arg(propName); } return QString(); } @@ -366,12 +369,7 @@ QVariant PropertyItem::data(int column, int role) const } bool PropertyItem::setData (const QVariant& value) -{ - //check if we have an expression set. If so we do nothing, as than the editor is responsible - //for issuing the relevant python code - if(hasExpression()) - return true; - +{ cleared = false; // This is the basic mechanism to set the value to @@ -545,11 +543,14 @@ QVariant PropertyIntegerItem::value(const App::Property* prop) const void PropertyIntegerItem::setValue(const QVariant& value) { - if (!value.canConvert(QVariant::Int)) - return; - int val = value.toInt(); - QString data = QString::fromAscii("%1").arg(val); - setPropertyValue(data); + //if the item has an expression it issues the python code + if(!hasExpression()) { + if (!value.canConvert(QVariant::Int)) + return; + int val = value.toInt(); + QString data = QString::fromAscii("%1").arg(val); + setPropertyValue(data); + } } QWidget* PropertyIntegerItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const @@ -561,8 +562,9 @@ QWidget* PropertyIntegerItem::createEditor(QWidget* parent, const QObject* recei if(isBound()) { sb->bind(getPath()); - sb->setAutoApply(true); + sb->setAutoApply(autoApply()); } + return sb; } @@ -608,11 +610,14 @@ QVariant PropertyIntegerConstraintItem::value(const App::Property* prop) const void PropertyIntegerConstraintItem::setValue(const QVariant& value) { - if (!value.canConvert(QVariant::Int)) - return; - int val = value.toInt(); - QString data = QString::fromAscii("%1").arg(val); - setPropertyValue(data); + //if the item has an expression it issues the python code + if(!hasExpression()) { + if (!value.canConvert(QVariant::Int)) + return; + int val = value.toInt(); + QString data = QString::fromAscii("%1").arg(val); + setPropertyValue(data); + } } QWidget* PropertyIntegerConstraintItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const @@ -624,8 +629,8 @@ QWidget* PropertyIntegerConstraintItem::createEditor(QWidget* parent, const QObj if(isBound()) { sb->bind(getPath()); - sb->setAutoApply(true); - } + sb->setAutoApply(autoApply()); + } return sb; } @@ -695,11 +700,14 @@ QVariant PropertyFloatItem::value(const App::Property* prop) const void PropertyFloatItem::setValue(const QVariant& value) { - if (!value.canConvert(QVariant::Double)) - return; - double val = value.toDouble(); - QString data = QString::fromAscii("%1").arg(val,0,'f',decimals()); - setPropertyValue(data); + //if the item has an expression it issues the python code + if(!hasExpression()) { + if (!value.canConvert(QVariant::Double)) + return; + double val = value.toDouble(); + QString data = QString::fromAscii("%1").arg(val,0,'f',decimals()); + setPropertyValue(data); + } } QWidget* PropertyFloatItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const @@ -712,7 +720,7 @@ QWidget* PropertyFloatItem::createEditor(QWidget* parent, const QObject* receive if(isBound()) { sb->bind(getPath()); - sb->setAutoApply(true); + sb->setAutoApply(autoApply()); } return sb; @@ -760,12 +768,15 @@ QVariant PropertyUnitItem::value(const App::Property* prop) const void PropertyUnitItem::setValue(const QVariant& value) { - if (!value.canConvert()) - return; - const Base::Quantity& val = value.value(); + //if the item has an expression it handles the python code + if(!hasExpression()) { + if (!value.canConvert()) + return; + const Base::Quantity& val = value.value(); - QString unit = QString::fromLatin1("'%1 %2'").arg(val.getValue()).arg(val.getUnit().getString()); - setPropertyValue(unit); + QString unit = QString::fromLatin1("'%1 %2'").arg(val.getValue()).arg(val.getUnit().getString()); + setPropertyValue(unit); + } } QWidget* PropertyUnitItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const @@ -778,8 +789,9 @@ QWidget* PropertyUnitItem::createEditor(QWidget* parent, const QObject* receiver //if we are bound to an expression we need to bind it to the input field if(isBound()) { infield->bind(getPath()); - infield->setAutoApply(true); + infield->setAutoApply(autoApply()); } + QObject::connect(infield, SIGNAL(valueChanged(double)), receiver, method); return infield; @@ -860,11 +872,14 @@ QVariant PropertyFloatConstraintItem::value(const App::Property* prop) const void PropertyFloatConstraintItem::setValue(const QVariant& value) { - if (!value.canConvert(QVariant::Double)) - return; - double val = value.toDouble(); - QString data = QString::fromAscii("%1").arg(val,0,'f',decimals()); - setPropertyValue(data); + //if the item has an expression it issues the python code + if(!hasExpression()) { + if (!value.canConvert(QVariant::Double)) + return; + double val = value.toDouble(); + QString data = QString::fromAscii("%1").arg(val,0,'f',decimals()); + setPropertyValue(data); + } } QWidget* PropertyFloatConstraintItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const @@ -877,8 +892,9 @@ QWidget* PropertyFloatConstraintItem::createEditor(QWidget* parent, const QObjec if(isBound()) { sb->bind(getPath()); - sb->setAutoApply(true); + sb->setAutoApply(autoApply()); } + return sb; } @@ -2317,7 +2333,7 @@ QVariant PropertyPathItem::toolTip(const App::Property* prop) const QWidget* PropertyPathItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const { Gui::FileChooser *fc = new Gui::FileChooser(parent); - fc->setMode(FileChooser::Directory); + fc->setMode(FileChooser::Directory); fc->setAutoFillBackground(true); fc->setDisabled(isReadOnly()); QObject::connect(fc, SIGNAL(fileNameSelected(const QString&)), receiver, method); diff --git a/src/Mod/Sketcher/Gui/PropertyConstraintListItem.cpp b/src/Mod/Sketcher/Gui/PropertyConstraintListItem.cpp index 1c848d53d..61a52c573 100644 --- a/src/Mod/Sketcher/Gui/PropertyConstraintListItem.cpp +++ b/src/Mod/Sketcher/Gui/PropertyConstraintListItem.cpp @@ -103,7 +103,7 @@ void PropertyConstraintListItem::initialize() } item->bind(list->createPath(id-1)); - item->setAutoApply(true); + item->setAutoApply(false); } }