From 2b83e18773895486205ce654a57f1e666c86c841 Mon Sep 17 00:00:00 2001 From: dismine Date: Fri, 29 Aug 2014 12:19:11 +0300 Subject: [PATCH] New property formula. --HG-- branch : feature --- src/app/container/container.pri | 6 +- src/app/container/vformula.cpp | 238 ++++++++++++++++++ src/app/container/vformula.h | 80 ++++++ src/app/dialogs/tools/dialogarc.ui | 3 + .../dialogs/tools/dialogeditwrongformula.cpp | 29 ++- .../dialogs/tools/dialogeditwrongformula.h | 6 + src/app/widgets/vformulaproperty.cpp | 207 +++++++++++++++ src/app/widgets/vformulaproperty.h | 88 +++++++ src/app/widgets/vformulapropertyeditor.cpp | 127 ++++++++++ src/app/widgets/vformulapropertyeditor.h | 78 ++++++ .../widgets/vtooloptionspropertybrowser.cpp | 27 +- src/app/widgets/widgets.pri | 8 +- .../plugins/vcolorproperty.cpp | 16 +- .../plugins/vcolorproperty.h | 4 +- .../plugins/venumproperty.cpp | 2 +- .../vpropertyexplorer/plugins/venumproperty.h | 2 +- .../plugins/vnumberproperty.cpp | 4 +- .../plugins/vnumberproperty.h | 2 +- .../plugins/vobjectproperty.cpp | 2 +- .../plugins/vobjectproperty.h | 2 +- .../plugins/vstringproperty.cpp | 36 ++- .../plugins/vstringproperty.h | 6 + src/libs/vpropertyexplorer/vproperty.cpp | 17 +- src/libs/vpropertyexplorer/vproperty.h | 12 +- src/libs/vpropertyexplorer/vproperty_p.h | 4 +- .../vpropertyexplorer/vpropertyformwidget.cpp | 103 ++++++-- .../vpropertyexplorer/vpropertyformwidget.h | 4 + .../vstandardpropertyfactory.cpp | 2 +- 28 files changed, 1051 insertions(+), 64 deletions(-) create mode 100644 src/app/container/vformula.cpp create mode 100644 src/app/container/vformula.h create mode 100644 src/app/widgets/vformulaproperty.cpp create mode 100644 src/app/widgets/vformulaproperty.h create mode 100644 src/app/widgets/vformulapropertyeditor.cpp create mode 100644 src/app/widgets/vformulapropertyeditor.h diff --git a/src/app/container/container.pri b/src/app/container/container.pri index 758aaf921..2c1e50367 100644 --- a/src/app/container/container.pri +++ b/src/app/container/container.pri @@ -9,7 +9,8 @@ SOURCES += \ container/varclength.cpp \ container/vcurvelength.cpp \ container/vlinelength.cpp \ - container/vsplinelength.cpp + container/vsplinelength.cpp \ + container/vformula.cpp HEADERS += \ container/vcontainer.h \ @@ -30,4 +31,5 @@ HEADERS += \ container/vcurvelength_p.h \ container/vlineangle_p.h \ container/vlinelength_p.h \ - container/vmeasurement_p.h + container/vmeasurement_p.h \ + container/vformula.h diff --git a/src/app/container/vformula.cpp b/src/app/container/vformula.cpp new file mode 100644 index 000000000..eb3cf4d0d --- /dev/null +++ b/src/app/container/vformula.cpp @@ -0,0 +1,238 @@ +/************************************************************************ + ** + ** @file vformula.cpp + ** @author Roman Telezhynskyi + ** @date 28 8, 2014 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2014 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#include "vformula.h" +#include "../container/calculator.h" +#include "../container/vcontainer.h" +#include "../widgets/vapplication.h" + +//VFormula +//--------------------------------------------------------------------------------------------------------------------- +VFormula::VFormula() + :formula(QString()), value(QString(tr("Error"))), checkZero(true), data(nullptr), toolId(NULL_ID), + postfix(QStringLiteral("")), _error(true) +{} + +//--------------------------------------------------------------------------------------------------------------------- +VFormula::VFormula(const QString &formula, const VContainer *container) + :formula(formula), value(QString(tr("Error"))), checkZero(true), data(container), toolId(NULL_ID), + postfix(QStringLiteral("")), _error(true) +{ + this->formula.replace("\n", " ");// Replace line return with spaces for calc if exist + Eval(); +} + +//--------------------------------------------------------------------------------------------------------------------- +VFormula &VFormula::operator=(const VFormula &formula) +{ + if ( &formula == this ) + { + return *this; + } + this->formula = formula.getFormula(); + this->value = formula.getValue(); + this->checkZero = formula.getCheckZero(); + this->data = formula.getData(); + this->toolId = formula.getToolId(); + this->postfix = formula.getPostfix(); + this->_error = formula.error(); + return *this; +} + +//--------------------------------------------------------------------------------------------------------------------- +VFormula::VFormula(const VFormula &formula) + :formula(formula.getFormula()), value(formula.getValue()), checkZero(formula.getCheckZero()), + data(formula.getData()), toolId(formula.getToolId()), postfix(formula.getPostfix()), _error(formula.error()) +{} + +//--------------------------------------------------------------------------------------------------------------------- +bool VFormula::operator==(const VFormula &formula) const +{ + bool isEqual = false; + if (this->formula == formula.getFormula() && this->value == formula.getValue() && + this->checkZero == formula.getCheckZero() && this->data == formula.getData() && + this->toolId == formula.getToolId() && this->postfix == formula.getPostfix() && + this->_error == formula.error()) + { + isEqual = true; + } + return isEqual; +} + +bool VFormula::operator!=(const VFormula &formula) const +{ + return !VFormula::operator==(formula); +} + +//--------------------------------------------------------------------------------------------------------------------- +QString VFormula::getFormula() const +{ + return formula; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VFormula::setFormula(const QString &value) +{ + if (formula != value) + { + formula = value; + Eval(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +QString VFormula::getValue() const +{ + return value; +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VFormula::getCheckZero() const +{ + return checkZero; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VFormula::setCheckZero(bool value) +{ + if (checkZero != value) + { + checkZero = value; + Eval(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +const VContainer *VFormula::getData() const +{ + return data; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VFormula::setData(const VContainer *value) +{ + if (data != value && value != nullptr) + { + data = value; + Eval(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 VFormula::getToolId() const +{ + return toolId; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VFormula::setToolId(const quint32 &value) +{ + toolId = value; +} + +//--------------------------------------------------------------------------------------------------------------------- +QString VFormula::getPostfix() const +{ + return postfix; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VFormula::setPostfix(const QString &value) +{ + if (postfix != value) + { + postfix = value; + Eval(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VFormula::error() const +{ + return _error; +} + +//--------------------------------------------------------------------------------------------------------------------- +int VFormula::FormulaTypeId() +{ + return qMetaTypeId(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VFormula::Eval() +{ + if (data == nullptr) + { + return; + } + if (formula.isEmpty()) + { + value = QString(tr("Error")); + _error = true; + } + else + { + try + { + Calculator *cal = new Calculator(data); + const qreal result = cal->EvalFormula(formula); + delete cal; + + //if result equal 0 + if (checkZero && qFuzzyCompare(1 + result, 1 + 0)) + { + value = QString("0"); + _error = true; + } + else + { + QLocale loc; + if (qApp->getSettings()->value("configuration/osSeparator", 1).toBool()) + { + loc = QLocale::system(); + } + else + { + loc = QLocale(QLocale::C); + } + value = QString(loc.toString(result) + " " + postfix); + _error = false; + } + } + catch (qmu::QmuParserError &e) + { + value = QString(tr("Error")); + _error = true; + qDebug() << "\nMath parser error:\n" + << "--------------------------------------\n" + << "Message: " << e.GetMsg() << "\n" + << "Expression: " << e.GetExpr() << "\n" + << "--------------------------------------"; + } + } +} diff --git a/src/app/container/vformula.h b/src/app/container/vformula.h new file mode 100644 index 000000000..c624ed829 --- /dev/null +++ b/src/app/container/vformula.h @@ -0,0 +1,80 @@ +/************************************************************************ + ** + ** @file vformula.h + ** @author Roman Telezhynskyi + ** @date 28 8, 2014 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2014 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef VFORMULA_H +#define VFORMULA_H + +#include + +class VContainer; + +class VFormula +{ + Q_DECLARE_TR_FUNCTIONS(VFormula) +public: + VFormula(); + VFormula(const QString &formula, const VContainer *container); + VFormula &operator=(const VFormula &formula); + VFormula(const VFormula &formula); + bool operator==(const VFormula &formula) const; + bool operator!=(const VFormula &formula) const; + + QString getFormula() const; + void setFormula(const QString &value); + + QString getValue() const; + + bool getCheckZero() const; + void setCheckZero(bool value); + + const VContainer *getData() const; + void setData(const VContainer *value); + + quint32 getToolId() const; + void setToolId(const quint32 &value); + + QString getPostfix() const; + void setPostfix(const QString &value); + + bool error() const; + + static int FormulaTypeId(); +private: + QString formula; + QString value; + bool checkZero; + const VContainer *data; + quint32 toolId; + QString postfix; + bool _error; + + void Eval(); +}; +Q_DECLARE_METATYPE(VFormula) + +#endif // VFORMULA_H diff --git a/src/app/dialogs/tools/dialogarc.ui b/src/app/dialogs/tools/dialogarc.ui index 8689df614..9e751d4ee 100644 --- a/src/app/dialogs/tools/dialogarc.ui +++ b/src/app/dialogs/tools/dialogarc.ui @@ -522,6 +522,9 @@ + + 9 + diff --git a/src/app/dialogs/tools/dialogeditwrongformula.cpp b/src/app/dialogs/tools/dialogeditwrongformula.cpp index 34b7e8c6a..3c2797d95 100644 --- a/src/app/dialogs/tools/dialogeditwrongformula.cpp +++ b/src/app/dialogs/tools/dialogeditwrongformula.cpp @@ -31,7 +31,8 @@ //--------------------------------------------------------------------------------------------------------------------- DialogEditWrongFormula::DialogEditWrongFormula(const VContainer *data, const quint32 &toolId, QWidget *parent) - :DialogTool(data, toolId, parent), ui(new Ui::DialogEditWrongFormula), formula(QString()), formulaBaseHeight(0) + :DialogTool(data, toolId, parent), ui(new Ui::DialogEditWrongFormula), formula(QString()), formulaBaseHeight(0), + checkZero(false), postfix(QStringLiteral("")), restoreCursor(false) { ui->setupUi(this); InitVariables(ui); @@ -51,7 +52,11 @@ DialogEditWrongFormula::DialogEditWrongFormula(const VContainer *data, const qui //Disable Qt::WaitCursor #ifndef QT_NO_CURSOR - QApplication::restoreOverrideCursor(); + if (QApplication::overrideCursor()->shape() == Qt::WaitCursor) + { + restoreCursor = true; + QApplication::restoreOverrideCursor(); + } #endif } @@ -59,7 +64,10 @@ DialogEditWrongFormula::DialogEditWrongFormula(const VContainer *data, const qui DialogEditWrongFormula::~DialogEditWrongFormula() { #ifndef QT_NO_CURSOR - QApplication::setOverrideCursor(Qt::WaitCursor); + if (restoreCursor) + { + QApplication::setOverrideCursor(Qt::WaitCursor); + } #endif delete ui; } @@ -91,8 +99,7 @@ void DialogEditWrongFormula::EvalFormula() { SCASSERT(plainTextEditFormula != nullptr); SCASSERT(labelResultCalculation != nullptr); - const QString postfix = QStringLiteral(""); - Eval(plainTextEditFormula->toPlainText(), flagFormula, timerFormula, labelResultCalculation, postfix); + Eval(plainTextEditFormula->toPlainText(), flagFormula, timerFormula, labelResultCalculation, postfix, checkZero); } //--------------------------------------------------------------------------------------------------------------------- @@ -115,6 +122,18 @@ void DialogEditWrongFormula::setFormula(const QString &value) ui->plainTextEditFormula->setPlainText(formula); } +//--------------------------------------------------------------------------------------------------------------------- +void DialogEditWrongFormula::setCheckZero(bool value) +{ + checkZero = value; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogEditWrongFormula::setPostfix(const QString &value) +{ + postfix = value; +} + //--------------------------------------------------------------------------------------------------------------------- QString DialogEditWrongFormula::getFormula() const { diff --git a/src/app/dialogs/tools/dialogeditwrongformula.h b/src/app/dialogs/tools/dialogeditwrongformula.h index 5e070c2b0..8a6de06e9 100644 --- a/src/app/dialogs/tools/dialogeditwrongformula.h +++ b/src/app/dialogs/tools/dialogeditwrongformula.h @@ -53,6 +53,8 @@ public: QString getFormula() const; void setFormula(const QString &value); + void setCheckZero(bool value); + void setPostfix(const QString &value); public slots: virtual void DialogAccepted(); virtual void DialogRejected(); @@ -72,6 +74,10 @@ private: /** @brief formulaBaseHeight base height defined by dialogui */ int formulaBaseHeight; + + bool checkZero; + QString postfix; + bool restoreCursor; }; diff --git a/src/app/widgets/vformulaproperty.cpp b/src/app/widgets/vformulaproperty.cpp new file mode 100644 index 000000000..752a8103b --- /dev/null +++ b/src/app/widgets/vformulaproperty.cpp @@ -0,0 +1,207 @@ +/************************************************************************ + ** + ** @file vformulaproperty.cpp + ** @author Roman Telezhynskyi + ** @date 28 8, 2014 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2014 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#include "vformulaproperty.h" +#include "vformulapropertyeditor.h" + +#include "../libs/vpropertyexplorer/vproperty_p.h" +#include "vformulapropertyeditor.h" +#include "../libs/vpropertyexplorer/vproperties.h" +#include "../container/vformula.h" + +enum class ChildType : char {Invalid = 0, Value = 1, Formula = 2}; + +using namespace VPE; + +//--------------------------------------------------------------------------------------------------------------------- +VFormulaProperty::VFormulaProperty(const QString &name) : + VProperty(name, static_cast(VFormula::FormulaTypeId())) +{ + d_ptr->type = Property::Complex; + + VStringProperty* tmpValue = new VStringProperty(QStringLiteral("Value")); + addChild(tmpValue); + tmpValue->setUpdateBehaviour(true, false); + tmpValue->setReadOnly(true); + tmpValue->setTypeForParent(static_cast(ChildType::Value)); + + VStringProperty* tmpFormula = new VStringProperty(QStringLiteral("Formula")); + addChild(tmpFormula); + tmpFormula->setUpdateBehaviour(true, false); + tmpFormula->setTypeForParent(static_cast(ChildType::Formula)); + + setValue(0); +} + +//--------------------------------------------------------------------------------------------------------------------- +//! Get the data how it should be displayed +QVariant VFormulaProperty::data (int column, int role) const +{ + if(column == DPC_Data && (Qt::DisplayRole == role || Qt::EditRole == role)) + return getValue(); + else + return VProperty::data(column, role); +} + +Qt::ItemFlags VFormulaProperty::flags(int column) const +{ + if(column == DPC_Name || column == DPC_Data) + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + else + return Qt::NoItemFlags; +} + +//--------------------------------------------------------------------------------------------------------------------- +//! Returns an editor widget, or NULL if it doesn't supply one +QWidget* VFormulaProperty::createEditor(QWidget* parent, const QStyleOptionViewItem& options, + const QAbstractItemDelegate* delegate) +{ + Q_UNUSED(options); + Q_UNUSED(delegate); + + VFormula formula = VProperty::d_ptr->VariantValue.value(); + VFormulaPropertyEditor* tmpEditor = new VFormulaPropertyEditor(parent); + + tmpEditor->setFormula(formula); + VProperty::d_ptr->editor = tmpEditor; + return VProperty::d_ptr->editor; +} + +//--------------------------------------------------------------------------------------------------------------------- +//! Sets the property's data to the editor (returns false, if the standard delegate should do that) +bool VFormulaProperty::setEditorData(QWidget* editor) +{ + VFormulaPropertyEditor* tmpWidget = qobject_cast(editor); + if(tmpWidget) + { + VFormula formula = VProperty::d_ptr->VariantValue.value(); + tmpWidget->setFormula(formula); + } + else + return false; + + return true; +} + +//--------------------------------------------------------------------------------------------------------------------- +//! Gets the data from the widget +QVariant VFormulaProperty::getEditorData(QWidget* editor) const +{ + VFormulaPropertyEditor* tmpWidget = qobject_cast(editor); + if(tmpWidget) + { + QVariant value; + value.setValue(tmpWidget->getFormula()); + return value; + } + + return QVariant(); +} + +//--------------------------------------------------------------------------------------------------------------------- +QString VFormulaProperty::type() const +{ + return "formula"; +} + +//--------------------------------------------------------------------------------------------------------------------- +VProperty *VFormulaProperty::clone(bool include_children, VProperty *container) const +{ + if(!container) { + container = new VFormulaProperty(getName()); + + if(!include_children) { + QList tmpChildren = container->getChildren(); + foreach(VProperty* tmpChild, tmpChildren) { + container->removeChild(tmpChild); + delete tmpChild; + } + } + } + + return VProperty::clone(false, container); // Child + +} + +//--------------------------------------------------------------------------------------------------------------------- +void VFormulaProperty::setValue(const QVariant &value) +{ + VFormula tmpFormula = value.value(); + setFormula(tmpFormula); +} + +//--------------------------------------------------------------------------------------------------------------------- +QVariant VFormulaProperty::getValue() const +{ + VFormula tmpFormula = getFormula(); + QVariant value; + value.setValue(tmpFormula); + return value; +} + +//--------------------------------------------------------------------------------------------------------------------- +VFormula VFormulaProperty::getFormula() const +{ + return VProperty::d_ptr->VariantValue.value(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VFormulaProperty::setFormula(const VFormula &formula) +{ + if(d_ptr->Children.count() < 2) + return; + + QVariant value; + value.setValue(formula); + value.convert(VFormula::FormulaTypeId()); + VProperty::d_ptr->VariantValue = value; + + QVariant tmpValue(formula.getValue()); + tmpValue.convert(QVariant::String); + + QVariant tmpFormula(formula.getFormula()); + tmpFormula.convert(QVariant::String); + + VProperty::d_ptr->Children.at(0)->setValue(tmpValue); + VProperty::d_ptr->Children.at(1)->setValue(tmpFormula); + + if (VProperty::d_ptr->editor != nullptr) + { + setEditorData(VProperty::d_ptr->editor); + } +} + +void VFormulaProperty::ValueChildChanged(const QVariant &value, int typeForParent) +{ + if (typeForParent == static_cast(ChildType::Formula)) + { + VFormula newFormula = getFormula(); + newFormula.setFormula(value.toString()); + setFormula(newFormula); + } +} diff --git a/src/app/widgets/vformulaproperty.h b/src/app/widgets/vformulaproperty.h new file mode 100644 index 000000000..848e698b8 --- /dev/null +++ b/src/app/widgets/vformulaproperty.h @@ -0,0 +1,88 @@ +/************************************************************************ + ** + ** @file vformulaproperty.h + ** @author Roman Telezhynskyi + ** @date 28 8, 2014 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2014 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef VFORMULAPROPERTY_H +#define VFORMULAPROPERTY_H + +#include "../libs/vpropertyexplorer/vproperty.h" + +class VFormula; + +using namespace VPE; + +class VFormulaProperty : public VProperty +{ + +public: + VFormulaProperty(const QString &name); + + //! Get the data how it should be displayed + virtual QVariant data (int column = DPC_Name, int role = Qt::DisplayRole) const; + + //! Returns item flags + Qt::ItemFlags flags(int column = DPC_Name) const; + + //! Returns an editor widget, or NULL if it doesn't supply one + //! \param parent The widget to which the editor will be added as a child + //! \options Render options + //! \delegate A pointer to the QAbstractItemDelegate requesting the editor. This can be used to connect signals and slots. + virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& options, const QAbstractItemDelegate* delegate); + + //! Sets the property's data to the editor (returns false, if the standard delegate should do that) + virtual bool setEditorData(QWidget* editor); + + //! Gets the data from the widget + virtual QVariant getEditorData(QWidget* editor) const; + + //! Returns a string containing the type of the property + virtual QString type() const; + + //! Clones this property + //! \param include_children Indicates whether to also clone the children + //! \param container If a property is being passed here, no new VProperty is being created but instead it is tried to fill all the data into container. This can also be used when subclassing this function. + //! \return Returns the newly created property (or container, if it was not NULL) + virtual VProperty* clone(bool include_children = true, VProperty* container = NULL) const; + + //! Sets the value of the property + virtual void setValue(const QVariant& value); + + //! Returns the value of the property as a QVariant + virtual QVariant getValue() const; + + //! Returns the formula + virtual VFormula getFormula() const; + + //! Sets the formula + virtual void setFormula(const VFormula &formula); + +public slots: + virtual void ValueChildChanged(const QVariant &value, int typeForParent); + +}; + +#endif // VFORMULAPROPERTY_H diff --git a/src/app/widgets/vformulapropertyeditor.cpp b/src/app/widgets/vformulapropertyeditor.cpp new file mode 100644 index 000000000..baa7de4b6 --- /dev/null +++ b/src/app/widgets/vformulapropertyeditor.cpp @@ -0,0 +1,127 @@ +/************************************************************************ + ** + ** @file vformulapropertyeditor.cpp + ** @author Roman Telezhynskyi + ** @date 28 8, 2014 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2014 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#include "vformulapropertyeditor.h" + +#include +#include +#include +#include +#include + +#include "../libs/vpropertyexplorer/vproperty.h" +#include "../dialogs/tools/dialogeditwrongformula.h" + +using namespace VPE; + +// VFormulaPropertyEditor +//--------------------------------------------------------------------------------------------------------------------- +VFormulaPropertyEditor::VFormulaPropertyEditor(QWidget *parent) : + QWidget(parent) +{ + setAutoFillBackground(true); + + // Create the tool button + ToolButton = new QToolButton(this); + ToolButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); + ToolButton->setText(tr("...")); + ToolButton->setFixedWidth(20); + ToolButton->installEventFilter(this); + setFocusProxy(ToolButton); // Make the ToolButton the focus proxy + setFocusPolicy(ToolButton->focusPolicy()); + connect(ToolButton, SIGNAL(clicked()), this, SLOT(onToolButtonClicked())); + + // Create the text label + TextLabel = new QLabel(this); + TextLabel->setText(formula.getValue()); + + // Spacer (this is needed for proper display of the label and button) + Spacer = new QSpacerItem(1, 0, QSizePolicy::Expanding, QSizePolicy::Ignored); + + // The layout (a horizontal layout) + QHBoxLayout* layout = new QHBoxLayout(this); + layout->setSpacing(3); + layout->setMargin(0); + layout->addWidget(TextLabel); + layout->addItem(Spacer); + layout->addWidget(ToolButton); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VFormulaPropertyEditor::setFormula(const VFormula& formula) +{ + if (this->formula != formula) + { + this->formula = formula; + TextLabel->setText(this->formula.getValue()); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VFormulaPropertyEditor::onToolButtonClicked() +{ + DialogEditWrongFormula* tmpWidget = new DialogEditWrongFormula(formula.getData(), formula.getToolId()); + tmpWidget->setCheckZero(formula.getCheckZero()); + tmpWidget->setPostfix(formula.getPostfix()); + tmpWidget->setFormula(formula.getFormula()); + + if (tmpWidget->exec() == QDialog::Accepted) + { + formula.setFormula(tmpWidget->getFormula()); + TextLabel->setText(formula.getValue()); + delete tmpWidget; + emit dataChangedByUser(formula, this); + UserChangeEvent *event = new UserChangeEvent(); + QCoreApplication::postEvent ( this, event ); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VFormulaPropertyEditor::eventFilter(QObject *obj, QEvent *ev) +{ + if(obj == ToolButton && (ev->type() == QEvent::KeyPress || ev->type() == QEvent::KeyPress)) + { + // Ignore the event, so that eventually the delegate gets the event. + ev->ignore(); + return true; + } + + return QWidget::eventFilter(obj, ev); +} + +//--------------------------------------------------------------------------------------------------------------------- +VFormulaPropertyEditor::~VFormulaPropertyEditor() +{ + // +} + +//--------------------------------------------------------------------------------------------------------------------- +VFormula VFormulaPropertyEditor::getFormula() +{ + return formula; +} diff --git a/src/app/widgets/vformulapropertyeditor.h b/src/app/widgets/vformulapropertyeditor.h new file mode 100644 index 000000000..622facc76 --- /dev/null +++ b/src/app/widgets/vformulapropertyeditor.h @@ -0,0 +1,78 @@ +/************************************************************************ + ** + ** @file vformulapropertyeditor.h + ** @author Roman Telezhynskyi + ** @date 28 8, 2014 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2014 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef VFORMULAPROPERTYEDITOR_H +#define VFORMULAPROPERTYEDITOR_H + +#include +#include +#include +#include +#include + +#include "../container/vformula.h" + +class VFormulaPropertyEditor : public QWidget +{ + Q_OBJECT + +public: + //! Constructor taking a widget as parent + VFormulaPropertyEditor(QWidget *parent); + + //! Destructor + virtual ~VFormulaPropertyEditor(); + + //! Returns the formula currently set + VFormula getFormula(); + + //! Needed for proper event handling + bool eventFilter(QObject *obj, QEvent *ev); + +signals: + //! This is emitted, when the user changes the color + void dataChangedByUser(const VFormula &getFormula, VFormulaPropertyEditor* editor); + + void dataChanged(); + +public slots: + //! Sets the color of the widget + void setFormula(const VFormula &formula); + +private slots: + void onToolButtonClicked(); + +private: + VFormula formula; + QToolButton* ToolButton; + QLabel* TextLabel; + QSpacerItem* Spacer; +}; + + +#endif // VFORMULAPROPERTYEDITOR_H diff --git a/src/app/widgets/vtooloptionspropertybrowser.cpp b/src/app/widgets/vtooloptionspropertybrowser.cpp index 787821ded..5fdae5e54 100644 --- a/src/app/widgets/vtooloptionspropertybrowser.cpp +++ b/src/app/widgets/vtooloptionspropertybrowser.cpp @@ -33,6 +33,8 @@ #include "visualization/vgraphicssimpletextitem.h" #include "visualization/vcontrolpointspline.h" #include "../libs/vpropertyexplorer/vproperties.h" +#include "vformulaproperty.h" +#include "../container/vformula.h" #include #include @@ -139,9 +141,16 @@ void VToolOptionsPropertyBrowser::userChangedData(VProperty *property) } else if (id == QLatin1String("lineType")) { - i->setTypeLine(variant.toString()); } + else if (id == QLatin1String("formulaLength")) + { + VFormula formula = variant.value(); + if (formula.error() == false) + { + i->setFormulaLength(variant.value().getFormula()); + } + } break; } default: @@ -203,6 +212,14 @@ void VToolOptionsPropertyBrowser::UpdateOptions() qint32 index = styles.indexOf(i->getLineType()); idToProperty[QLatin1String("lineType")]->setValue(index); + VFormula formula(i->getFormulaLength(), i->getData()); + formula.setCheckZero(true); + formula.setToolId(i->getId()); + formula.setPostfix(VDomDocument::UnitsToStr(qApp->patternUnit())); + QVariant value; + value.setValue(formula); + idToProperty[QLatin1String("formulaLength")]->setValue(value); + break; } case VGraphicsSimpleTextItem::Type: @@ -267,6 +284,14 @@ void VToolOptionsPropertyBrowser::ShowItemOptions(QGraphicsItem *item) qint32 index = styles.indexOf(i->getLineType()); lineTypeProperty->setValue(index); AddProperty(lineTypeProperty, QLatin1String("lineType")); + + VFormulaProperty* itemLength = new VFormulaProperty(tr("Length")); + VFormula formula(i->getFormulaLength(), i->getData()); + formula.setCheckZero(true); + formula.setToolId(i->getId()); + formula.setPostfix(VDomDocument::UnitsToStr(qApp->patternUnit())); + itemLength->setFormula(formula); + AddProperty(itemLength, QLatin1String("formulaLength")); break; } case VGraphicsSimpleTextItem::Type: diff --git a/src/app/widgets/widgets.pri b/src/app/widgets/widgets.pri index 8def2ed00..4c2ac1298 100644 --- a/src/app/widgets/widgets.pri +++ b/src/app/widgets/widgets.pri @@ -8,7 +8,9 @@ HEADERS += \ widgets/textdelegate.h \ widgets/vtranslation.h \ widgets/undoevent.h \ - widgets/vtooloptionspropertybrowser.h + widgets/vtooloptionspropertybrowser.h \ + widgets/vformulapropertyeditor.h \ + widgets/vformulaproperty.h SOURCES += \ widgets/vtablegraphicsview.cpp \ @@ -20,4 +22,6 @@ SOURCES += \ widgets/textdelegate.cpp \ widgets/vtranslation.cpp \ widgets/undoevent.cpp \ - widgets/vtooloptionspropertybrowser.cpp + widgets/vtooloptionspropertybrowser.cpp \ + widgets/vformulapropertyeditor.cpp \ + widgets/vformulaproperty.cpp diff --git a/src/libs/vpropertyexplorer/plugins/vcolorproperty.cpp b/src/libs/vpropertyexplorer/plugins/vcolorproperty.cpp index 7d3152eda..dbf2a1838 100644 --- a/src/libs/vpropertyexplorer/plugins/vcolorproperty.cpp +++ b/src/libs/vpropertyexplorer/plugins/vcolorproperty.cpp @@ -5,14 +5,14 @@ using namespace VPE; -QColorProperty::QColorProperty(const QString &name) : +VColorProperty::VColorProperty(const QString &name) : VProperty(name, QVariant::Color) { } //! Get the data how it should be displayed -QVariant QColorProperty::data (int column, int role) const +QVariant VColorProperty::data (int column, int role) const { if(column == DPC_Data && (Qt::DisplayRole == role)) return VColorPropertyEditor::getColorString(d_ptr->VariantValue.value()); @@ -25,7 +25,7 @@ QVariant QColorProperty::data (int column, int role) const } //! Returns an editor widget, or NULL if it doesn't supply one -QWidget* QColorProperty::createEditor(QWidget* parent, const QStyleOptionViewItem& options, const QAbstractItemDelegate* delegate) +QWidget* VColorProperty::createEditor(QWidget* parent, const QStyleOptionViewItem& options, const QAbstractItemDelegate* delegate) { Q_UNUSED(options); Q_UNUSED(delegate); @@ -36,7 +36,7 @@ QWidget* QColorProperty::createEditor(QWidget* parent, const QStyleOptionViewIte } //! Sets the property's data to the editor (returns false, if the standard delegate should do that) -bool QColorProperty::setEditorData(QWidget* editor) +bool VColorProperty::setEditorData(QWidget* editor) { VColorPropertyEditor* tmpWidget = qobject_cast(editor); if(tmpWidget) @@ -48,7 +48,7 @@ bool QColorProperty::setEditorData(QWidget* editor) } //! Gets the data from the widget -QVariant QColorProperty::getEditorData(QWidget* editor) const +QVariant VColorProperty::getEditorData(QWidget* editor) const { VColorPropertyEditor* tmpWidget = qobject_cast(editor); if(tmpWidget) @@ -57,12 +57,12 @@ QVariant QColorProperty::getEditorData(QWidget* editor) const return QVariant(); } -QString QColorProperty::type() const +QString VColorProperty::type() const { return "color"; } -VProperty *QColorProperty::clone(bool include_children, VProperty *container) const +VProperty *VColorProperty::clone(bool include_children, VProperty *container) const { - return VProperty::clone(include_children, container ? container : new QColorProperty(getName())); + return VProperty::clone(include_children, container ? container : new VColorProperty(getName())); } diff --git a/src/libs/vpropertyexplorer/plugins/vcolorproperty.h b/src/libs/vpropertyexplorer/plugins/vcolorproperty.h index d61802f1f..cad37a0e7 100644 --- a/src/libs/vpropertyexplorer/plugins/vcolorproperty.h +++ b/src/libs/vpropertyexplorer/plugins/vcolorproperty.h @@ -7,11 +7,11 @@ namespace VPE { -class VPROPERTYEXPLORERSHARED_EXPORT QColorProperty : public VProperty +class VPROPERTYEXPLORERSHARED_EXPORT VColorProperty : public VProperty { public: - QColorProperty(const QString &name); + VColorProperty(const QString &name); //! Get the data how it should be displayed virtual QVariant data (int column = DPC_Name, int role = Qt::DisplayRole) const; diff --git a/src/libs/vpropertyexplorer/plugins/venumproperty.cpp b/src/libs/vpropertyexplorer/plugins/venumproperty.cpp index e03504bbb..8e8d69902 100644 --- a/src/libs/vpropertyexplorer/plugins/venumproperty.cpp +++ b/src/libs/vpropertyexplorer/plugins/venumproperty.cpp @@ -7,7 +7,7 @@ using namespace VPE; VEnumProperty::VEnumProperty(const QString& name) - : QObject(), VProperty(name, QVariant::Int) + : VProperty(name, QVariant::Int) { VProperty::d_ptr->VariantValue = 0; VProperty::d_ptr->VariantValue.convert(QVariant::Int); diff --git a/src/libs/vpropertyexplorer/plugins/venumproperty.h b/src/libs/vpropertyexplorer/plugins/venumproperty.h index c43761bf2..07be616b5 100644 --- a/src/libs/vpropertyexplorer/plugins/venumproperty.h +++ b/src/libs/vpropertyexplorer/plugins/venumproperty.h @@ -7,7 +7,7 @@ namespace VPE{ -class VPROPERTYEXPLORERSHARED_EXPORT VEnumProperty : public QObject, public VProperty +class VPROPERTYEXPLORERSHARED_EXPORT VEnumProperty : public VProperty { Q_OBJECT public: diff --git a/src/libs/vpropertyexplorer/plugins/vnumberproperty.cpp b/src/libs/vpropertyexplorer/plugins/vnumberproperty.cpp index 07fb5cf65..f82c510aa 100644 --- a/src/libs/vpropertyexplorer/plugins/vnumberproperty.cpp +++ b/src/libs/vpropertyexplorer/plugins/vnumberproperty.cpp @@ -14,7 +14,7 @@ const int VIntegerProperty::StandardMin = -1000000; const int VIntegerProperty::StandardMax = 1000000; VIntegerProperty::VIntegerProperty(const QString& name, const QMap& settings) - : QObject(), VProperty(name, QVariant::Int), Min(StandardMin), Max(StandardMax) + : VProperty(name, QVariant::Int), Min(StandardMin), Max(StandardMax) { VProperty::setSettings(settings); VProperty::d_ptr->VariantValue.setValue(0); @@ -22,7 +22,7 @@ VIntegerProperty::VIntegerProperty(const QString& name, const QMapVariantValue.setValue(0); VProperty::d_ptr->VariantValue.convert(QVariant::Int); diff --git a/src/libs/vpropertyexplorer/plugins/vnumberproperty.h b/src/libs/vpropertyexplorer/plugins/vnumberproperty.h index 155357933..b1fdbcafb 100644 --- a/src/libs/vpropertyexplorer/plugins/vnumberproperty.h +++ b/src/libs/vpropertyexplorer/plugins/vnumberproperty.h @@ -8,7 +8,7 @@ namespace VPE { //! Class for holding an integer property -class VPROPERTYEXPLORERSHARED_EXPORT VIntegerProperty : public QObject, public VProperty +class VPROPERTYEXPLORERSHARED_EXPORT VIntegerProperty : public VProperty { Q_OBJECT public: diff --git a/src/libs/vpropertyexplorer/plugins/vobjectproperty.cpp b/src/libs/vpropertyexplorer/plugins/vobjectproperty.cpp index 321c09231..1687dc2cf 100644 --- a/src/libs/vpropertyexplorer/plugins/vobjectproperty.cpp +++ b/src/libs/vpropertyexplorer/plugins/vobjectproperty.cpp @@ -28,7 +28,7 @@ using namespace VPE; VObjectProperty::VObjectProperty(const QString& name) - : QObject(), VProperty(name, QVariant::Int) + : VProperty(name, QVariant::Int) { VProperty::d_ptr->VariantValue = 0; VProperty::d_ptr->VariantValue.convert(QVariant::UInt); diff --git a/src/libs/vpropertyexplorer/plugins/vobjectproperty.h b/src/libs/vpropertyexplorer/plugins/vobjectproperty.h index a3e7b49d4..7ea6246bd 100644 --- a/src/libs/vpropertyexplorer/plugins/vobjectproperty.h +++ b/src/libs/vpropertyexplorer/plugins/vobjectproperty.h @@ -29,7 +29,7 @@ class QComboBox; namespace VPE{ -class VPROPERTYEXPLORERSHARED_EXPORT VObjectProperty : public QObject, public VProperty +class VPROPERTYEXPLORERSHARED_EXPORT VObjectProperty : public VProperty { Q_OBJECT public: diff --git a/src/libs/vpropertyexplorer/plugins/vstringproperty.cpp b/src/libs/vpropertyexplorer/plugins/vstringproperty.cpp index 00cd08061..89ad53579 100644 --- a/src/libs/vpropertyexplorer/plugins/vstringproperty.cpp +++ b/src/libs/vpropertyexplorer/plugins/vstringproperty.cpp @@ -29,7 +29,7 @@ using namespace VPE; VPE::VStringProperty::VStringProperty(const QString &name, const QMap &settings) - : VProperty(name, QVariant::String), readOnly(false) + : VProperty(name, QVariant::String), readOnly(false), typeForParent(0) { VProperty::setSettings(settings); d_ptr->VariantValue.setValue(QStringLiteral("")); @@ -37,7 +37,7 @@ VPE::VStringProperty::VStringProperty(const QString &name, const QMapVariantValue.setValue(QStringLiteral("")); d_ptr->VariantValue.convert(QVariant::String); @@ -74,29 +74,51 @@ void VPE::VStringProperty::setReadOnly(bool readOnly) void VPE::VStringProperty::setSetting(const QString &key, const QVariant &value) { - if(key == "ReadOnly") + if(key == QLatin1String("ReadOnly")) setReadOnly(value.toBool()); + if(key == QLatin1String("TypeForParent")) + setTypeForParent(value.toInt()); } QVariant VPE::VStringProperty::getSetting(const QString &key) const { - if(key == "ReadOnly") + if(key == QLatin1String("ReadOnly")) return readOnly; + else if (key == QLatin1String("TypeForParent")) + return typeForParent; else return VProperty::getSetting(key); } QStringList VPE::VStringProperty::getSettingKeys() const { - return QStringList("ReadOnly"); + QStringList settings; + settings << QStringLiteral("ReadOnly") << QStringLiteral("TypeForParent"); + return settings; } QString VPE::VStringProperty::type() const { - return "string"; + return QStringLiteral("string"); } VPE::VProperty *VPE::VStringProperty::clone(bool include_children, VPE::VProperty *container) const { - return VProperty::clone(include_children, container ? container : new VStringProperty(getName())); + return VProperty::clone(include_children, container ? container : new VStringProperty(getName(), getSettings())); } + +void VStringProperty::UpdateParent(const QVariant &value) +{ + emit childChanged(value, typeForParent); +} + +int VStringProperty::getTypeForParent() const +{ + return typeForParent; +} + +void VStringProperty::setTypeForParent(int value) +{ + typeForParent = value; +} + diff --git a/src/libs/vpropertyexplorer/plugins/vstringproperty.h b/src/libs/vpropertyexplorer/plugins/vstringproperty.h index 5182e8e69..105fa7deb 100644 --- a/src/libs/vpropertyexplorer/plugins/vstringproperty.h +++ b/src/libs/vpropertyexplorer/plugins/vstringproperty.h @@ -64,8 +64,14 @@ public: //! \return Returns the newly created property (or container, if it was not NULL) virtual VProperty* clone(bool include_children = true, VProperty* container = nullptr) const; + virtual void UpdateParent(const QVariant &value); + + int getTypeForParent() const; + void setTypeForParent(int value); + protected: bool readOnly; + int typeForParent; }; } diff --git a/src/libs/vpropertyexplorer/vproperty.cpp b/src/libs/vpropertyexplorer/vproperty.cpp index 59f96238e..30be44c00 100644 --- a/src/libs/vpropertyexplorer/vproperty.cpp +++ b/src/libs/vpropertyexplorer/vproperty.cpp @@ -10,7 +10,7 @@ using namespace VPE; //! Standard constructor, takes a name and a parent property as argument VProperty::VProperty(const QString& name, QVariant::Type type) - : d_ptr(new VPropertyPrivate(name, type)) + : QObject(), d_ptr(new VPropertyPrivate(name, type)) { } @@ -342,3 +342,18 @@ VProperty* VProperty::clone(bool include_children, VProperty* container) const return container; } + +Property VProperty::propertyType() const +{ + return d_ptr->type; +} + +void VProperty::UpdateParent(const QVariant &value) +{ + Q_UNUSED(value); +} + +void VProperty::ValueChildChanged(const QVariant &value, int typeForParent) +{ + +} diff --git a/src/libs/vpropertyexplorer/vproperty.h b/src/libs/vpropertyexplorer/vproperty.h index 26e80f60b..2a433a9fd 100644 --- a/src/libs/vpropertyexplorer/vproperty.h +++ b/src/libs/vpropertyexplorer/vproperty.h @@ -12,6 +12,8 @@ namespace VPE { +enum class Property : char{Simple, Complex}; + static const int MyCustomEventType = 1099; class UserChangeEvent : public QEvent @@ -22,8 +24,9 @@ public: class VPropertyPrivate; -class VPROPERTYEXPLORERSHARED_EXPORT VProperty +class VPROPERTYEXPLORERSHARED_EXPORT VProperty : public QObject { + Q_OBJECT public: enum DPC_DisplayColumn { DPC_Name = 0, @@ -158,6 +161,13 @@ public: //! \return Returns the newly created property (or container, if it was not NULL) virtual VProperty* clone(bool include_children = true, VProperty* container = nullptr) const; + Property propertyType() const; + + virtual void UpdateParent(const QVariant &value); +public slots: + virtual void ValueChildChanged(const QVariant &value, int typeForParent); +signals: + void childChanged(const QVariant &value, int typeForParent); protected: //! Protected constructor diff --git a/src/libs/vpropertyexplorer/vproperty_p.h b/src/libs/vpropertyexplorer/vproperty_p.h index deaecdfed..6937e32c7 100644 --- a/src/libs/vpropertyexplorer/vproperty_p.h +++ b/src/libs/vpropertyexplorer/vproperty_p.h @@ -40,13 +40,15 @@ public: QWidget* editor; + Property type; + //! List of child properties QList Children; //! Constructor passing name and type VPropertyPrivate(const QString& name, QVariant::Type type) : VariantValue(type), Name(name), PropertyVariantType(type), UpdateParent(false), UpdateChildren(false), - Parent(nullptr), editor(nullptr) + Parent(nullptr), editor(nullptr), type(Property::Simple) {} //! Constructor diff --git a/src/libs/vpropertyexplorer/vpropertyformwidget.cpp b/src/libs/vpropertyexplorer/vpropertyformwidget.cpp index ef0f17937..9dcef9d9d 100644 --- a/src/libs/vpropertyexplorer/vpropertyformwidget.cpp +++ b/src/libs/vpropertyexplorer/vpropertyformwidget.cpp @@ -71,39 +71,79 @@ void VPropertyFormWidget::build() if(!tmpProperty) continue; if(tmpProperty->getRowCount() > 0) { - // Child properties, the property itself is not being added - VPropertyFormWidget* tmpNewFormWidget = new VPropertyFormWidget(tmpProperty, this); - tmpFormLayout->addRow(tmpNewFormWidget); - d_ptr->EditorWidgets.append(VPropertyFormWidgetPrivate::SEditorWidget(tmpNewFormWidget)); - tmpNewFormWidget->setCommitBehaviour(d_ptr->UpdateEditors); + if (tmpProperty->propertyType() == Property::Complex) + { + buildEditor(tmpProperty, tmpFormLayout, Property::Complex); + QWidget *group = new QWidget(this); + tmpFormLayout->addRow(group); + + QFormLayout* subFormLayout = new QFormLayout(group); + QMargins margins = subFormLayout->contentsMargins(); + margins.setTop(0); + margins.setLeft(14); + subFormLayout->setContentsMargins(margins); + + group->setLayout(subFormLayout); + QList children = tmpProperty->getChildren(); + for (int j = 0; j < children.size(); ++j) + { + buildEditor(children[j], subFormLayout); + connect(children[j], &VProperty::childChanged, tmpProperty, &VProperty::ValueChildChanged, + Qt::UniqueConnection); + ++i; + d_ptr->Properties.insert(i, children[j]); + } + } + else + { + // Child properties, the property itself is not being added + VPropertyFormWidget* tmpNewFormWidget = new VPropertyFormWidget(tmpProperty, this); + tmpFormLayout->addRow(tmpNewFormWidget); + d_ptr->EditorWidgets.append(VPropertyFormWidgetPrivate::SEditorWidget(tmpNewFormWidget)); + tmpNewFormWidget->setCommitBehaviour(d_ptr->UpdateEditors); + } } else if(tmpProperty->type() == "widget") { VWidgetProperty* tmpWidgetProperty = static_cast(tmpProperty); tmpFormLayout->addRow(tmpWidgetProperty->getWidget()); d_ptr->EditorWidgets.append(VPropertyFormWidgetPrivate::SEditorWidget(tmpWidgetProperty->getWidget())); } else { - // Add property (no child properties) - // Create the editor (if it doesn't work, create empty widget) - QWidget* tmpEditor = tmpProperty->createEditor(this, QStyleOptionViewItem(), nullptr); - if(!tmpEditor) - tmpEditor = new QWidget(this); - - // set tooltip and whats this - tmpEditor->setToolTip(tmpProperty->getDescription()); - tmpEditor->setWhatsThis(tmpProperty->getDescription()); - - // Install event filter - tmpEditor->installEventFilter(this); - - // Set the editor data - tmpProperty->setEditorData(tmpEditor); - - // add new row - tmpFormLayout->addRow(tmpProperty->getName(), tmpEditor); - d_ptr->EditorWidgets.append(VPropertyFormWidgetPrivate::SEditorWidget(tmpEditor)); + buildEditor(tmpProperty, tmpFormLayout); } } } +void VPropertyFormWidget::buildEditor(VProperty* property, QFormLayout* formLayout, Property type) +{ + // Add property (no child properties) + // Create the editor (if it doesn't work, create empty widget) + QWidget* tmpEditor = property->createEditor(this, QStyleOptionViewItem(), nullptr); + if(!tmpEditor) + tmpEditor = new QWidget(this); + + // set tooltip and whats this + tmpEditor->setToolTip(property->getDescription()); + tmpEditor->setWhatsThis(property->getDescription()); + + // Install event filter + tmpEditor->installEventFilter(this); + + // Set the editor data + property->setEditorData(tmpEditor); + + // add new row + if (type == Property::Complex) + { + QString name = ""+property->getName()+""; + formLayout->addRow(name, tmpEditor); + } + else + { + formLayout->addRow(property->getName(), tmpEditor); + } + + d_ptr->EditorWidgets.append(VPropertyFormWidgetPrivate::SEditorWidget(tmpEditor)); +} + void VPropertyFormWidget::commitData() { for(int i = 0; i < d_ptr->Properties.count(); ++i) @@ -129,8 +169,19 @@ void VPropertyFormWidget::commitData(int row) QVariant oldValue = tmpProperty->data(VProperty::DPC_Data, Qt::EditRole); if (oldValue != newValue) { - tmpProperty->setValue(newValue); - emit propertyDataSubmitted(tmpProperty); + if (VProperty *parent = tmpProperty->getParent()) + { + if (parent->propertyType() == Property::Complex) + { + tmpProperty->UpdateParent(newValue); + emit propertyDataSubmitted(parent); + } + } + else + { + tmpProperty->setValue(newValue); + emit propertyDataSubmitted(tmpProperty); + } } } } diff --git a/src/libs/vpropertyexplorer/vpropertyformwidget.h b/src/libs/vpropertyexplorer/vpropertyformwidget.h index 4cc3f0ad9..c407bc603 100644 --- a/src/libs/vpropertyexplorer/vpropertyformwidget.h +++ b/src/libs/vpropertyexplorer/vpropertyformwidget.h @@ -5,6 +5,8 @@ #include #include "vproperty.h" +class QFormLayout; + namespace VPE { class VPropertyFormWidgetPrivate; @@ -32,6 +34,8 @@ public slots: //! Rebuilds the whole form virtual void build(); + void buildEditor(VProperty *property, QFormLayout *formLayout, Property type = Property::Simple); + //! Reads the data from the editors and commits it to the properties void commitData(); diff --git a/src/libs/vpropertyexplorer/vstandardpropertyfactory.cpp b/src/libs/vpropertyexplorer/vstandardpropertyfactory.cpp index a9a05ea46..8b175764c 100644 --- a/src/libs/vpropertyexplorer/vstandardpropertyfactory.cpp +++ b/src/libs/vpropertyexplorer/vstandardpropertyfactory.cpp @@ -45,7 +45,7 @@ VProperty *VStandardPropertyFactory::createProperty(const QString &type, const Q } else if(type == QString("bool")) { return new VBoolProperty(name); } else if(type == QString("color")) { - return new QColorProperty(name); + return new VColorProperty(name); } else if(type == QString("empty")) { return new VEmptyProperty(name); } else if(type == QString("enum")) {