New property formula.

--HG--
branch : feature
This commit is contained in:
dismine 2014-08-29 12:19:11 +03:00
parent 37ec49065a
commit 2b83e18773
28 changed files with 1051 additions and 64 deletions

View File

@ -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

View File

@ -0,0 +1,238 @@
/************************************************************************
**
** @file vformula.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @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
** <https://bitbucket.org/dismine/valentina> 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 <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#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<VFormula>();
}
//---------------------------------------------------------------------------------------------------------------------
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"
<< "--------------------------------------";
}
}
}

View File

@ -0,0 +1,80 @@
/************************************************************************
**
** @file vformula.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @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
** <https://bitbucket.org/dismine/valentina> 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 <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef VFORMULA_H
#define VFORMULA_H
#include <QCoreApplication>
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

View File

@ -522,6 +522,9 @@
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<property name="leftMargin">
<number>9</number>
</property>
<item>
<widget class="QPlainTextEdit" name="plainTextEditF2">
<property name="sizePolicy">

View File

@ -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
{

View File

@ -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;
};

View File

@ -0,0 +1,207 @@
/************************************************************************
**
** @file vformulaproperty.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @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
** <https://bitbucket.org/dismine/valentina> 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 <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#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<QVariant::Type>(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<int>(ChildType::Value));
VStringProperty* tmpFormula = new VStringProperty(QStringLiteral("Formula"));
addChild(tmpFormula);
tmpFormula->setUpdateBehaviour(true, false);
tmpFormula->setTypeForParent(static_cast<int>(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<VFormula>();
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<VFormulaPropertyEditor*>(editor);
if(tmpWidget)
{
VFormula formula = VProperty::d_ptr->VariantValue.value<VFormula>();
tmpWidget->setFormula(formula);
}
else
return false;
return true;
}
//---------------------------------------------------------------------------------------------------------------------
//! Gets the data from the widget
QVariant VFormulaProperty::getEditorData(QWidget* editor) const
{
VFormulaPropertyEditor* tmpWidget = qobject_cast<VFormulaPropertyEditor*>(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<VProperty*> 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<VFormula>();
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<VFormula>();
}
//---------------------------------------------------------------------------------------------------------------------
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<int>(ChildType::Formula))
{
VFormula newFormula = getFormula();
newFormula.setFormula(value.toString());
setFormula(newFormula);
}
}

View File

@ -0,0 +1,88 @@
/************************************************************************
**
** @file vformulaproperty.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @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
** <https://bitbucket.org/dismine/valentina> 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 <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#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

View File

@ -0,0 +1,127 @@
/************************************************************************
**
** @file vformulapropertyeditor.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @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
** <https://bitbucket.org/dismine/valentina> 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 <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#include "vformulapropertyeditor.h"
#include <QHBoxLayout>
#include <QFileDialog>
#include <QKeyEvent>
#include <QApplication>
#include <QColorDialog>
#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;
}

View File

@ -0,0 +1,78 @@
/************************************************************************
**
** @file vformulapropertyeditor.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @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
** <https://bitbucket.org/dismine/valentina> 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 <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef VFORMULAPROPERTYEDITOR_H
#define VFORMULAPROPERTYEDITOR_H
#include <QWidget>
#include <QToolButton>
#include <QLineEdit>
#include <QLabel>
#include <QSpacerItem>
#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

View File

@ -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 <QDockWidget>
#include <QHBoxLayout>
@ -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<VFormula>();
if (formula.error() == false)
{
i->setFormulaLength(variant.value<VFormula>().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:

View File

@ -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

View File

@ -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<QColor>());
@ -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<VColorPropertyEditor*>(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<VColorPropertyEditor*>(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()));
}

View File

@ -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;

View File

@ -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);

View File

@ -7,7 +7,7 @@
namespace VPE{
class VPROPERTYEXPLORERSHARED_EXPORT VEnumProperty : public QObject, public VProperty
class VPROPERTYEXPLORERSHARED_EXPORT VEnumProperty : public VProperty
{
Q_OBJECT
public:

View File

@ -14,7 +14,7 @@ const int VIntegerProperty::StandardMin = -1000000;
const int VIntegerProperty::StandardMax = 1000000;
VIntegerProperty::VIntegerProperty(const QString& name, const QMap<QString, QVariant>& 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 QMap<QString, QVar
}
VIntegerProperty::VIntegerProperty(const QString &name)
: QObject(), VProperty(name), Min(StandardMin), Max(StandardMax)
: VProperty(name), Min(StandardMin), Max(StandardMax)
{
VProperty::d_ptr->VariantValue.setValue(0);
VProperty::d_ptr->VariantValue.convert(QVariant::Int);

View File

@ -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:

View File

@ -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);

View File

@ -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:

View File

@ -29,7 +29,7 @@ using namespace VPE;
VPE::VStringProperty::VStringProperty(const QString &name, const QMap<QString, QVariant> &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 QMap<QString, Q
}
VPE::VStringProperty::VStringProperty(const QString &name)
: VProperty(name), readOnly(false)
: VProperty(name), readOnly(false), typeForParent(0)
{
d_ptr->VariantValue.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;
}

View File

@ -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;
};
}

View File

@ -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)
{
}

View File

@ -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

View File

@ -40,13 +40,15 @@ public:
QWidget* editor;
Property type;
//! List of child properties
QList<VProperty*> 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

View File

@ -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<VProperty*> 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<VWidgetProperty*>(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 = "<b>"+property->getName()+"</b>";
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);
}
}
}
}

View File

@ -5,6 +5,8 @@
#include <QLabel>
#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();

View File

@ -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")) {