Skip to content

Commit

Permalink
Add "apply on update" option to default values
Browse files Browse the repository at this point in the history
  • Loading branch information
m-kuhn committed Sep 29, 2017
1 parent cb8ae89 commit d6eb7ba
Show file tree
Hide file tree
Showing 10 changed files with 131 additions and 28 deletions.
6 changes: 3 additions & 3 deletions python/core/qgsfield.sip
Original file line number Diff line number Diff line change
Expand Up @@ -178,17 +178,17 @@ Gets variant type of the field as it will be retrieved from data source
Set the field comment
%End

QString defaultValueExpression() const;
QgsDefaultValue defaultValue() const;
%Docstring
Returns the expression used when calculating the default value for the field.
:return: expression evaluated when calculating default values for field, or an
empty string if no default is set
.. versionadded:: 3.0
.. seealso:: setDefaultValueExpression()
:rtype: str
:rtype: QgsDefaultValue
%End

void setDefaultValueExpression( const QString &expression );
void setDefaultValue( const QgsDefaultValue &defaultValue );
%Docstring
Sets an expression to use when calculating the default value for the field.
\param expression expression to evaluate when calculating default values for field. Pass
Expand Down
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ SET(QGIS_CORE_SRCS
qgsdatetimestatisticalsummary.cpp
qgsdatumtransformstore.cpp
qgsdbfilterproxymodel.cpp
qgsdefaultvalue.cpp
qgsdiagramrenderer.cpp
qgsdistancearea.cpp
qgseditformconfig.cpp
Expand Down Expand Up @@ -805,6 +806,7 @@ SET(QGIS_CORE_HDRS
qgsdatetimestatisticalsummary.h
qgsdatumtransformstore.h
qgsdbfilterproxymodel.h
qgsdefaultvalue.h
qgsdiagramrenderer.h
qgsdistancearea.h
qgseditformconfig.h
Expand Down
49 changes: 49 additions & 0 deletions src/core/qgsdefaultvalue.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/***************************************************************************
qgsdefaultvalue.cpp
---------------------
begin : 19.9.2017
copyright : (C) 2017 by Matthias Kuhn
email : matthias@opengis.ch
***************************************************************************
* *
* This program 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 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsdefaultvalue.h"

QgsDefaultValue::QgsDefaultValue( const QString &expression, bool applyOnUpdate )
: mExpression( expression )
, mApplyOnUpdate( applyOnUpdate )
{

}

bool QgsDefaultValue::operator==( const QgsDefaultValue &other ) const
{
return mExpression == other.mExpression
&& mApplyOnUpdate == other.mApplyOnUpdate;
}

QString QgsDefaultValue::expression() const
{
return mExpression;
}

void QgsDefaultValue::setExpression( const QString &expression )
{
mExpression = expression;
}

bool QgsDefaultValue::applyOnUpdate() const
{
return mApplyOnUpdate;
}

void QgsDefaultValue::setApplyOnUpdate( bool applyOnUpdate )
{
mApplyOnUpdate = applyOnUpdate;
}
46 changes: 46 additions & 0 deletions src/core/qgsdefaultvalue.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/***************************************************************************
qgsdefaultvalue.h
---------------------
begin : 19.9.2017
copyright : (C) 2017 by Matthias Kuhn
email : matthias@opengis.ch
***************************************************************************
* *
* This program 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 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSDEFAULTVALUE_H
#define QGSDEFAULTVALUE_H

#include "qgis_core.h"

#include <QString>
#include <QObject>

class CORE_EXPORT QgsDefaultValue
{
Q_GADGET

Q_PROPERTY( QString expression READ expression WRITE setExpression )
Q_PROPERTY( bool applyOnUpdate READ applyOnUpdate WRITE setApplyOnUpdate )

public:
QgsDefaultValue( const QString &expression = QString(), bool applyOnUpdate = false );
bool operator==( const QgsDefaultValue &other ) const;

QString expression() const;
void setExpression( const QString &expression );

bool applyOnUpdate() const;
void setApplyOnUpdate( bool applyOnUpdate );

private:
QString mExpression;
bool mApplyOnUpdate = false;
};

#endif // QGSDEFAULTVALUE_H
13 changes: 7 additions & 6 deletions src/core/qgsfield.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,14 +165,14 @@ void QgsField::setComment( const QString &comment )
d->comment = comment;
}

QString QgsField::defaultValueExpression() const
QgsDefaultValue QgsField::defaultValue() const
{
return d->defaultValueExpression;
return d->defaultValue;
}

void QgsField::setDefaultValueExpression( const QString &expression )
void QgsField::setDefaultValue( const QgsDefaultValue &defaultValue )
{
d->defaultValueExpression = expression;
d->defaultValue = defaultValue;
}

void QgsField::setConstraints( const QgsFieldConstraints &constraints )
Expand Down Expand Up @@ -307,7 +307,8 @@ QDataStream &operator<<( QDataStream &out, const QgsField &field )
out << field.precision();
out << field.comment();
out << field.alias();
out << field.defaultValueExpression();
out << field.defaultValue().expression();
out << field.defaultValue().applyOnUpdate();
out << field.constraints().constraints();
out << static_cast< quint32 >( field.constraints().constraintOrigin( QgsFieldConstraints::ConstraintNotNull ) );
out << static_cast< quint32 >( field.constraints().constraintOrigin( QgsFieldConstraints::ConstraintUnique ) );
Expand Down Expand Up @@ -335,7 +336,7 @@ QDataStream &operator>>( QDataStream &in, QgsField &field )
field.setPrecision( static_cast< int >( precision ) );
field.setComment( comment );
field.setAlias( alias );
field.setDefaultValueExpression( defaultValueExpression );
field.setDefaultValue( defaultValueExpression );
QgsFieldConstraints fieldConstraints;
if ( constraints & QgsFieldConstraints::ConstraintNotNull )
{
Expand Down
7 changes: 4 additions & 3 deletions src/core/qgsfield.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ typedef QList<int> QgsAttributeList SIP_SKIP;

#include "qgseditorwidgetsetup.h"
#include "qgsfieldconstraints.h"
#include "qgsdefaultvalue.h"

/** \class QgsField
* \ingroup core
Expand All @@ -53,7 +54,7 @@ class CORE_EXPORT QgsField
Q_PROPERTY( QString comment READ comment WRITE setComment )
Q_PROPERTY( QString name READ name WRITE setName )
Q_PROPERTY( QString alias READ alias WRITE setAlias )
Q_PROPERTY( QString defaultValueExpression READ defaultValueExpression WRITE setDefaultValueExpression )
Q_PROPERTY( QgsDefaultValue defaultValue READ defaultValue WRITE setDefaultValue )
Q_PROPERTY( QgsFieldConstraints constraints READ constraints WRITE setConstraints )

public:
Expand Down Expand Up @@ -199,15 +200,15 @@ class CORE_EXPORT QgsField
* \since QGIS 3.0
* \see setDefaultValueExpression()
*/
QString defaultValueExpression() const;
QgsDefaultValue defaultValue() const;

/** Sets an expression to use when calculating the default value for the field.
* \param expression expression to evaluate when calculating default values for field. Pass
* an empty expression to clear the default.
* \since QGIS 3.0
* \see defaultValueExpression()
*/
void setDefaultValueExpression( const QString &expression );
void setDefaultValue( const QgsDefaultValue &defaultValue );

/**
* Returns constraints which are present for the field.
Expand Down
9 changes: 5 additions & 4 deletions src/core/qgsfield_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

#include "qgsfieldconstraints.h"
#include "qgseditorwidgetsetup.h"
#include "qgsdefaultvalue.h"
#include <QString>
#include <QVariant>
#include <QSharedData>
Expand Down Expand Up @@ -72,7 +73,7 @@ class QgsFieldPrivate : public QSharedData
, precision( other.precision )
, comment( other.comment )
, alias( other.alias )
, defaultValueExpression( other.defaultValueExpression )
, defaultValue( other.defaultValue )
, constraints( other.constraints )
{
}
Expand All @@ -83,7 +84,7 @@ class QgsFieldPrivate : public QSharedData
{
return ( ( name == other.name ) && ( type == other.type ) && ( subType == other.subType )
&& ( length == other.length ) && ( precision == other.precision )
&& ( alias == other.alias ) && ( defaultValueExpression == other.defaultValueExpression )
&& ( alias == other.alias ) && ( defaultValue == other.defaultValue )
&& ( constraints == other.constraints ) );
}

Expand Down Expand Up @@ -111,8 +112,8 @@ class QgsFieldPrivate : public QSharedData
//! Alias for field name (friendly name shown to users)
QString alias;

//! Default value expression
QString defaultValueExpression;
//! Default value
QgsDefaultValue defaultValue;

//! Field constraints
QgsFieldConstraints constraints;
Expand Down
15 changes: 9 additions & 6 deletions src/core/qgsvectorlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1725,10 +1725,11 @@ bool QgsVectorLayer::readSymbology( const QDomNode &layerNode, QString &errorMes

QString field = defaultElem.attribute( QStringLiteral( "field" ), QString() );
QString expression = defaultElem.attribute( QStringLiteral( "expression" ), QString() );
bool applyOnUpdate = defaultElem.attribute( QStringLiteral( "applyOnUpdate" ), QStringLiteral( "0" ) ) == QLatin1String( "1" );
if ( field.isEmpty() || expression.isEmpty() )
continue;

mDefaultExpressionMap.insert( field, expression );
mDefaultExpressionMap.insert( field, QgsDefaultValue( expression, applyOnUpdate ) );
}
}

Expand Down Expand Up @@ -2074,7 +2075,8 @@ bool QgsVectorLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QString
{
QDomElement defaultElem = doc.createElement( QStringLiteral( "default" ) );
defaultElem.setAttribute( QStringLiteral( "field" ), field.name() );
defaultElem.setAttribute( QStringLiteral( "expression" ), field.defaultValueExpression() );
defaultElem.setAttribute( QStringLiteral( "expression" ), field.defaultValue().expression() );
defaultElem.setAttribute( QStringLiteral( "applyOnUpdate" ), field.defaultValue().applyOnUpdate() ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
defaultsElem.appendChild( defaultElem );
}
node.appendChild( defaultsElem );
Expand Down Expand Up @@ -2918,14 +2920,14 @@ void QgsVectorLayer::updateFields()

mFields[ index ].setAlias( aliasIt.value() );
}
QMap< QString, QString >::const_iterator defaultIt = mDefaultExpressionMap.constBegin();
QMap< QString, QgsDefaultValue >::const_iterator defaultIt = mDefaultExpressionMap.constBegin();
for ( ; defaultIt != mDefaultExpressionMap.constEnd(); ++defaultIt )
{
int index = mFields.lookupField( defaultIt.key() );
if ( index < 0 )
continue;

mFields[ index ].setDefaultValueExpression( defaultIt.value() );
mFields[ index ].setDefaultValue( defaultIt.value() );
}

QMap< QString, QgsFieldConstraints::Constraints >::const_iterator constraintIt = mFieldConstraints.constBegin();
Expand Down Expand Up @@ -3004,7 +3006,7 @@ QVariant QgsVectorLayer::defaultValue( int index, const QgsFeature &feature, Qgs
if ( index < 0 || index >= mFields.count() )
return QVariant();

QString expression = mFields.at( index ).defaultValueExpression();
QString expression = mFields.at( index ).defaultValue().expression();
if ( expression.isEmpty() )
return mDataProvider->defaultValue( index );

Expand Down Expand Up @@ -3061,12 +3063,13 @@ void QgsVectorLayer::setDefaultValueExpression( int index, const QString &expres
updateFields();
}

// TODO to QgsDefaultValue defaultValueDenfinition( int index )
QString QgsVectorLayer::defaultValueExpression( int index ) const
{
if ( index < 0 || index >= mFields.count() )
return QString();
else
return mFields.at( index ).defaultValueExpression();
return mFields.at( index ).defaultValue().expression();
}

QSet<QVariant> QgsVectorLayer::uniqueValues( int index, int limit ) const
Expand Down
2 changes: 1 addition & 1 deletion src/core/qgsvectorlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -1999,7 +1999,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
QgsStringMap mAttributeAliasMap;

//! Map which stores default value expressions for fields
QgsStringMap mDefaultExpressionMap;
QMap<QString, QgsDefaultValue> mDefaultExpressionMap;

//! Map which stores constraints for fields
QMap< QString, QgsFieldConstraints::Constraints > mFieldConstraints;
Expand Down
10 changes: 5 additions & 5 deletions tests/src/core/testqgsfield.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ void TestQgsField::gettersSetters()
QCOMPARE( field.comment(), QString( "comment" ) );
field.setAlias( QStringLiteral( "alias" ) );
QCOMPARE( field.alias(), QString( "alias" ) );
field.setDefaultValueExpression( QStringLiteral( "1+2" ) );
QCOMPARE( field.defaultValueExpression(), QString( "1+2" ) );
field.setDefaultValue( QStringLiteral( "1+2" ) );
QCOMPARE( field.defaultValue(), QString( "1+2" ) );
QgsFieldConstraints constraints;
constraints.setConstraint( QgsFieldConstraints::ConstraintNotNull, QgsFieldConstraints::ConstraintOriginProvider );
field.setConstraints( constraints );
Expand Down Expand Up @@ -244,10 +244,10 @@ void TestQgsField::equality()
QVERIFY( !( field1 == field2 ) );
QVERIFY( field1 != field2 );
field2.setAlias( QString() );
field2.setDefaultValueExpression( QStringLiteral( "1+2" ) );
field2.setDefaultValue( QStringLiteral( "1+2" ) );
QVERIFY( !( field1 == field2 ) );
QVERIFY( field1 != field2 );
field2.setDefaultValueExpression( QString() );
field2.setDefaultValue( QString() );
constraints = field2.constraints();
constraints.removeConstraint( QgsFieldConstraints::ConstraintNotNull );
field2.setConstraints( constraints );
Expand Down Expand Up @@ -461,7 +461,7 @@ void TestQgsField::dataStream()
original.setTypeName( QStringLiteral( "typename1" ) );
original.setComment( QStringLiteral( "comment1" ) );
original.setAlias( QStringLiteral( "alias" ) );
original.setDefaultValueExpression( QStringLiteral( "default" ) );
original.setDefaultValue( QStringLiteral( "default" ) );
QgsFieldConstraints constraints;
constraints.setConstraint( QgsFieldConstraints::ConstraintNotNull, QgsFieldConstraints::ConstraintOriginProvider );
constraints.setConstraint( QgsFieldConstraints::ConstraintUnique, QgsFieldConstraints::ConstraintOriginLayer );
Expand Down

0 comments on commit d6eb7ba

Please sign in to comment.