mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
Move responsibility for storage of constraint expressions to QgsVectorLayer
This commit is contained in:
parent
f99ea26bdf
commit
2500d75f5e
@ -197,52 +197,6 @@ class QgsEditFormConfig
|
||||
*/
|
||||
void setReadOnly( int idx, bool readOnly = true );
|
||||
|
||||
/**
|
||||
* Returns the constraint expression of a specific field
|
||||
*
|
||||
* @param idx The index of the field
|
||||
* @return the expression
|
||||
*
|
||||
* @note added in QGIS 2.16
|
||||
* @note renamed in QGIS 3.0
|
||||
*/
|
||||
QString constraintExpression( int idx ) const;
|
||||
|
||||
/**
|
||||
* Set the constraint expression for a specific field
|
||||
*
|
||||
* @param idx the field index
|
||||
* @param expression the constraint expression
|
||||
*
|
||||
* @note added in QGIS 2.16
|
||||
* @note renamed in QGIS 3.0
|
||||
*/
|
||||
void setConstraintExpression( int idx, const QString& expression );
|
||||
|
||||
/**
|
||||
* Returns the constraint expression description of a specific field.
|
||||
*
|
||||
* @param idx The index of the field
|
||||
* @return The expression description. Will be presented
|
||||
* to the user in case the constraint fails.
|
||||
*
|
||||
* @note added in QGIS 2.16
|
||||
* @note renamed in QGIS 3.0
|
||||
*/
|
||||
QString constraintDescription( int idx ) const;
|
||||
|
||||
/**
|
||||
* Set the constraint expression description for a specific field.
|
||||
*
|
||||
* @param idx The index of the field
|
||||
* @param description The description of the expression. Will be presented
|
||||
* to the user in case the constraint fails.
|
||||
*
|
||||
* @note added in QGIS 2.16
|
||||
* @note renamed in QGIS 3.0
|
||||
*/
|
||||
void setContraintDescription( int idx, const QString& description );
|
||||
|
||||
/**
|
||||
* If this returns true, the widget at the given index will receive its label on the previous line
|
||||
* while if it returns false, the widget will receive its label on the left hand side.
|
||||
|
@ -23,6 +23,7 @@ class QgsField
|
||||
{
|
||||
ConstraintNotNull, //!< Field may not be null
|
||||
ConstraintUnique, //!< Field must have a unique value
|
||||
ConstraintExpression, //!< Field has an expression constraint set. See constraintExpression().
|
||||
};
|
||||
typedef QFlags<QgsField::Constraint> Constraints;
|
||||
|
||||
|
@ -1275,6 +1275,34 @@ class QgsVectorLayer : QgsMapLayer
|
||||
*/
|
||||
void setFieldConstraints( int index, QgsField::Constraints constraints );
|
||||
|
||||
/**
|
||||
* Returns the constraint expression for for a specified field index, if set.
|
||||
* @note added in QGIS 3.0
|
||||
* @see fieldConstraints()
|
||||
* @see constraintDescription()
|
||||
* @see setConstraintExpression()
|
||||
*/
|
||||
QString constraintExpression( int index ) const;
|
||||
|
||||
/**
|
||||
* Returns the descriptive name for the constraint expression for a specified field index.
|
||||
* @note added in QGIS 3.0
|
||||
* @see constraints()
|
||||
* @see constraintExpression()
|
||||
* @see setConstraintExpression()
|
||||
*/
|
||||
QString constraintDescription( int index ) const;
|
||||
|
||||
/**
|
||||
* Set the constraint expression for the specified field index. An optional descriptive name for the constraint
|
||||
* can also be set. Setting an empty expression will clear any existing expression constraint.
|
||||
* @note added in QGIS 3.0
|
||||
* @see constraintExpression()
|
||||
* @see constraintDescription()
|
||||
* @see constraints()
|
||||
*/
|
||||
void setConstraintExpression( int index, const QString& expression, const QString& description = QString() );
|
||||
|
||||
/** Calculates a list of unique values contained within an attribute in the layer. Note that
|
||||
* in some circumstances when unsaved changes are present for the layer then the returned list
|
||||
* may contain outdated values (for instance when the attribute value in a saved feature has
|
||||
|
@ -977,8 +977,7 @@ void QgsFieldsProperties::apply()
|
||||
|
||||
editFormConfig.setReadOnly( i, !cfg.mEditable );
|
||||
editFormConfig.setLabelOnTop( i, cfg.mLabelOnTop );
|
||||
editFormConfig.setContraintDescription( i, cfg.mConstraintDescription );
|
||||
editFormConfig.setConstraintExpression( i, cfg.mConstraint );
|
||||
mLayer->setConstraintExpression( i, cfg.mConstraint, cfg.mConstraintDescription );
|
||||
|
||||
editFormConfig.setWidgetType( name, cfg.mEditorWidgetType );
|
||||
editFormConfig.setWidgetConfig( name, cfg.mEditorWidgetConfig );
|
||||
@ -1062,8 +1061,8 @@ QgsFieldsProperties::FieldConfig::FieldConfig( QgsVectorLayer* layer, int idx )
|
||||
&& layer->fields().fieldOrigin( idx ) != QgsFields::OriginExpression;
|
||||
mLabelOnTop = layer->editFormConfig().labelOnTop( idx );
|
||||
mConstraints = layer->fields().at( idx ).constraints();
|
||||
mConstraint = layer->editFormConfig().constraintExpression( idx );
|
||||
mConstraintDescription = layer->editFormConfig().constraintDescription( idx );
|
||||
mConstraint = layer->fields().at( idx ).constraintExpression();
|
||||
mConstraintDescription = layer->fields().at( idx ).constraintDescription();
|
||||
const QgsEditorWidgetSetup setup = QgsEditorWidgetRegistry::instance()->findBest( layer, layer->fields().field( idx ).name() );
|
||||
mEditorWidgetType = setup.type();
|
||||
mEditorWidgetConfig = setup.config();
|
||||
|
@ -182,44 +182,6 @@ bool QgsEditFormConfig::labelOnTop( int idx ) const
|
||||
return false;
|
||||
}
|
||||
|
||||
QString QgsEditFormConfig::constraintExpression( int idx ) const
|
||||
{
|
||||
QString expr;
|
||||
|
||||
if ( idx >= 0 && idx < d->mFields.count() )
|
||||
expr = d->mConstraints.value( d->mFields.at( idx ).name(), QString() );
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
||||
void QgsEditFormConfig::setConstraintExpression( int idx, const QString& expression )
|
||||
{
|
||||
if ( idx >= 0 && idx < d->mFields.count() )
|
||||
{
|
||||
d.detach();
|
||||
d->mConstraints[ d->mFields.at( idx ).name()] = expression;
|
||||
}
|
||||
}
|
||||
|
||||
QString QgsEditFormConfig::constraintDescription( int idx ) const
|
||||
{
|
||||
QString description;
|
||||
|
||||
if ( idx >= 0 && idx < d->mFields.count() )
|
||||
description = d->mConstraintsDescription[ d->mFields.at( idx ).name()];
|
||||
|
||||
return description;
|
||||
}
|
||||
|
||||
void QgsEditFormConfig::setContraintDescription( int idx, const QString &descr )
|
||||
{
|
||||
if ( idx >= 0 && idx < d->mFields.count() )
|
||||
{
|
||||
d.detach();
|
||||
d->mConstraintsDescription[ d->mFields.at( idx ).name()] = descr;
|
||||
}
|
||||
}
|
||||
|
||||
void QgsEditFormConfig::setReadOnly( int idx, bool readOnly )
|
||||
{
|
||||
if ( idx >= 0 && idx < d->mFields.count() )
|
||||
|
@ -232,52 +232,6 @@ class CORE_EXPORT QgsEditFormConfig
|
||||
*/
|
||||
void setReadOnly( int idx, bool readOnly = true );
|
||||
|
||||
/**
|
||||
* Returns the constraint expression of a specific field
|
||||
*
|
||||
* @param idx The index of the field
|
||||
* @return the expression
|
||||
*
|
||||
* @note added in QGIS 2.16
|
||||
* @note renamed in QGIS 3.0
|
||||
*/
|
||||
QString constraintExpression( int idx ) const;
|
||||
|
||||
/**
|
||||
* Set the constraint expression for a specific field
|
||||
*
|
||||
* @param idx the field index
|
||||
* @param expression the constraint expression
|
||||
*
|
||||
* @note added in QGIS 2.16
|
||||
* @note renamed in QGIS 3.0
|
||||
*/
|
||||
void setConstraintExpression( int idx, const QString& expression );
|
||||
|
||||
/**
|
||||
* Returns the constraint expression description of a specific field.
|
||||
*
|
||||
* @param idx The index of the field
|
||||
* @return The expression description. Will be presented
|
||||
* to the user in case the constraint fails.
|
||||
*
|
||||
* @note added in QGIS 2.16
|
||||
* @note renamed in QGIS 3.0
|
||||
*/
|
||||
QString constraintDescription( int idx ) const;
|
||||
|
||||
/**
|
||||
* Set the constraint expression description for a specific field.
|
||||
*
|
||||
* @param idx The index of the field
|
||||
* @param description The description of the expression. Will be presented
|
||||
* to the user in case the constraint fails.
|
||||
*
|
||||
* @note added in QGIS 2.16
|
||||
* @note renamed in QGIS 3.0
|
||||
*/
|
||||
void setContraintDescription( int idx, const QString& description );
|
||||
|
||||
/**
|
||||
* If this returns true, the widget at the given index will receive its label on the previous line
|
||||
* while if it returns false, the widget will receive its label on the left hand side.
|
||||
|
@ -38,8 +38,6 @@ class QgsEditFormConfigPrivate : public QSharedData
|
||||
: QSharedData( o )
|
||||
, mInvisibleRootContainer( static_cast<QgsAttributeEditorContainer*>( o.mInvisibleRootContainer->clone( nullptr ) ) )
|
||||
, mConfiguredRootContainer( o.mConfiguredRootContainer )
|
||||
, mConstraints( o.mConstraints )
|
||||
, mConstraintsDescription( o.mConstraintsDescription )
|
||||
, mFieldEditables( o.mFieldEditables )
|
||||
, mLabelOnTop( o.mLabelOnTop )
|
||||
, mEditorWidgetTypes( o.mEditorWidgetTypes )
|
||||
@ -64,8 +62,6 @@ class QgsEditFormConfigPrivate : public QSharedData
|
||||
//! This flag is set if the root container was configured by the user
|
||||
bool mConfiguredRootContainer;
|
||||
|
||||
QMap< QString, QString> mConstraints;
|
||||
QMap< QString, QString> mConstraintsDescription;
|
||||
QMap< QString, bool> mFieldEditables;
|
||||
QMap< QString, bool> mLabelOnTop;
|
||||
|
||||
|
@ -1459,6 +1459,24 @@ bool QgsVectorLayer::readXml( const QDomNode& layer_node )
|
||||
mFieldConstraints.insert( field, static_cast< QgsField::Constraints >( constraints ) );
|
||||
}
|
||||
}
|
||||
mFieldConstraintExpressions.clear();
|
||||
QDomNode constraintExpressionsNode = layer_node.namedItem( "constraintExpressions" );
|
||||
if ( !constraintExpressionsNode.isNull() )
|
||||
{
|
||||
QDomNodeList constraintNodeList = constraintExpressionsNode.toElement().elementsByTagName( "constraint" );
|
||||
for ( int i = 0; i < constraintNodeList.size(); ++i )
|
||||
{
|
||||
QDomElement constraintElem = constraintNodeList.at( i ).toElement();
|
||||
|
||||
QString field = constraintElem.attribute( "field", QString() );
|
||||
QString exp = constraintElem.attribute( "exp", QString() );
|
||||
QString desc = constraintElem.attribute( "desc", QString() );
|
||||
if ( field.isEmpty() || exp.isEmpty() )
|
||||
continue;
|
||||
|
||||
mFieldConstraintExpressions.insert( field, qMakePair( exp, desc ) );
|
||||
}
|
||||
}
|
||||
|
||||
updateFields();
|
||||
|
||||
@ -1677,6 +1695,19 @@ bool QgsVectorLayer::writeXml( QDomNode & layer_node,
|
||||
}
|
||||
layer_node.appendChild( constraintsElem );
|
||||
|
||||
// constraint expressions
|
||||
QDomElement constraintExpressionsElem = document.createElement( "constraintExpressions" );
|
||||
Q_FOREACH ( const QgsField& field, mFields )
|
||||
{
|
||||
QDomElement constraintExpressionElem = document.createElement( "constraint" );
|
||||
constraintExpressionElem.setAttribute( "field", field.name() );
|
||||
constraintExpressionElem.setAttribute( "exp", field.constraintExpression() );
|
||||
constraintExpressionElem.setAttribute( "desc", field.constraintDescription() );
|
||||
constraintExpressionsElem.appendChild( constraintExpressionElem );
|
||||
}
|
||||
layer_node.appendChild( constraintExpressionsElem );
|
||||
|
||||
|
||||
// change dependencies
|
||||
QDomElement dataDependenciesElement = document.createElement( QStringLiteral( "dataDependencies" ) );
|
||||
Q_FOREACH ( const QgsMapLayerDependency& dep, dependencies() )
|
||||
@ -2948,6 +2979,20 @@ void QgsVectorLayer::updateFields()
|
||||
mFields[ index ].setConstraint( QgsField::ConstraintExpression, QgsField::ConstraintOriginLayer );
|
||||
}
|
||||
|
||||
QMap< QString, QPair< QString, QString > >::const_iterator constraintExpIt = mFieldConstraintExpressions.constBegin();
|
||||
for ( ; constraintExpIt != mFieldConstraintExpressions.constEnd(); ++constraintExpIt )
|
||||
{
|
||||
int index = mFields.lookupField( constraintExpIt.key() );
|
||||
if ( index < 0 )
|
||||
continue;
|
||||
|
||||
// always keep provider constraints intact
|
||||
if ( mFields.at( index ).constraintOrigin( QgsField::ConstraintExpression ) == QgsField::ConstraintOriginProvider )
|
||||
continue;
|
||||
|
||||
mFields[ index ].setConstraintExpression( constraintExpIt.value().first, constraintExpIt.value().second );
|
||||
}
|
||||
|
||||
if ( oldFields != mFields )
|
||||
{
|
||||
emit updatedFields();
|
||||
@ -4268,3 +4313,35 @@ void QgsVectorLayer::setFieldConstraints( int index, QgsField::Constraints const
|
||||
}
|
||||
updateFields();
|
||||
}
|
||||
|
||||
QString QgsVectorLayer::constraintExpression( int index ) const
|
||||
{
|
||||
if ( index < 0 || index >= mFields.count() )
|
||||
return QString();
|
||||
|
||||
return mFields.at( index ).constraintExpression();
|
||||
}
|
||||
|
||||
QString QgsVectorLayer::constraintDescription( int index ) const
|
||||
{
|
||||
if ( index < 0 || index >= mFields.count() )
|
||||
return QString();
|
||||
|
||||
return mFields.at( index ).constraintDescription();
|
||||
}
|
||||
|
||||
void QgsVectorLayer::setConstraintExpression( int index, const QString& expression, const QString& description )
|
||||
{
|
||||
if ( index < 0 || index >= mFields.count() )
|
||||
return;
|
||||
|
||||
if ( expression.isEmpty() )
|
||||
{
|
||||
mFieldConstraintExpressions.remove( mFields.at( index ).name() );
|
||||
}
|
||||
else
|
||||
{
|
||||
mFieldConstraintExpressions.insert( mFields.at( index ).name(), qMakePair( expression, description ) );
|
||||
}
|
||||
updateFields();
|
||||
}
|
||||
|
@ -1415,6 +1415,34 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
|
||||
*/
|
||||
void setFieldConstraints( int index, QgsField::Constraints constraints );
|
||||
|
||||
/**
|
||||
* Returns the constraint expression for for a specified field index, if set.
|
||||
* @note added in QGIS 3.0
|
||||
* @see fieldConstraints()
|
||||
* @see constraintDescription()
|
||||
* @see setConstraintExpression()
|
||||
*/
|
||||
QString constraintExpression( int index ) const;
|
||||
|
||||
/**
|
||||
* Returns the descriptive name for the constraint expression for a specified field index.
|
||||
* @note added in QGIS 3.0
|
||||
* @see constraints()
|
||||
* @see constraintExpression()
|
||||
* @see setConstraintExpression()
|
||||
*/
|
||||
QString constraintDescription( int index ) const;
|
||||
|
||||
/**
|
||||
* Set the constraint expression for the specified field index. An optional descriptive name for the constraint
|
||||
* can also be set. Setting an empty expression will clear any existing expression constraint.
|
||||
* @note added in QGIS 3.0
|
||||
* @see constraintExpression()
|
||||
* @see constraintDescription()
|
||||
* @see constraints()
|
||||
*/
|
||||
void setConstraintExpression( int index, const QString& expression, const QString& description = QString() );
|
||||
|
||||
/** Calculates a list of unique values contained within an attribute in the layer. Note that
|
||||
* in some circumstances when unsaved changes are present for the layer then the returned list
|
||||
* may contain outdated values (for instance when the attribute value in a saved feature has
|
||||
@ -1955,6 +1983,9 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
|
||||
//! Map which stores constraints for fields
|
||||
QMap< QString, QgsField::Constraints > mFieldConstraints;
|
||||
|
||||
//! Map which stores expression constraints for fields. Value is a pair of expression/description.
|
||||
QMap< QString, QPair< QString, QString > > mFieldConstraintExpressions;
|
||||
|
||||
//! Holds the configuration for the edit form
|
||||
QgsEditFormConfig mEditFormConfig;
|
||||
|
||||
|
@ -268,8 +268,12 @@ void QgsEditorWidgetRegistry::readMapLayer( QgsMapLayer* mapLayer, const QDomEle
|
||||
// upgrade from older config
|
||||
vectorLayer->setFieldConstraints( idx, vectorLayer->fieldConstraints( idx ) | QgsField::ConstraintNotNull );
|
||||
}
|
||||
formConfig.setConstraintExpression( idx, ewv2CfgElem.attribute( QStringLiteral( "constraint" ), QString() ) );
|
||||
formConfig.setContraintDescription( idx, ewv2CfgElem.attribute( QStringLiteral( "constraintDescription" ), QString() ) );
|
||||
if ( !ewv2CfgElem.attribute( QStringLiteral( "constraint" ), QString() ).isEmpty() )
|
||||
{
|
||||
// upgrade from older config
|
||||
vectorLayer->setConstraintExpression( idx, ewv2CfgElem.attribute( QStringLiteral( "constraint" ), QString() ),
|
||||
ewv2CfgElem.attribute( QStringLiteral( "constraintDescription" ), QString() ) );
|
||||
}
|
||||
|
||||
formConfig.setWidgetConfig( name, cfg );
|
||||
}
|
||||
@ -323,8 +327,6 @@ void QgsEditorWidgetRegistry::writeMapLayer( QgsMapLayer* mapLayer, QDomElement&
|
||||
QDomElement ewv2CfgElem = doc.createElement( QStringLiteral( "widgetv2config" ) );
|
||||
ewv2CfgElem.setAttribute( QStringLiteral( "fieldEditable" ), !vectorLayer->editFormConfig().readOnly( idx ) );
|
||||
ewv2CfgElem.setAttribute( QStringLiteral( "labelOnTop" ), vectorLayer->editFormConfig().labelOnTop( idx ) );
|
||||
ewv2CfgElem.setAttribute( QStringLiteral( "constraint" ), vectorLayer->editFormConfig().constraintExpression( idx ) );
|
||||
ewv2CfgElem.setAttribute( QStringLiteral( "constraintDescription" ), vectorLayer->editFormConfig().constraintDescription( idx ) );
|
||||
|
||||
mWidgetFactories[widgetType]->writeConfig( vectorLayer->editFormConfig().widgetConfig( field.name() ), ewv2CfgElem, doc, vectorLayer, idx );
|
||||
|
||||
|
@ -109,10 +109,11 @@ void QgsEditorWidgetWrapper::updateConstraintWidgetStatus( bool constraintValid
|
||||
void QgsEditorWidgetWrapper::updateConstraint( const QgsFeature &ft )
|
||||
{
|
||||
bool toEmit( false );
|
||||
QString expression = layer()->editFormConfig().constraintExpression( mFieldIdx );
|
||||
QgsField field = layer()->fields().at( mFieldIdx );
|
||||
|
||||
QString expression = field.constraintExpression();
|
||||
QStringList expressions, descriptions;
|
||||
QVariant value = ft.attribute( mFieldIdx );
|
||||
QString fieldName = ft.fields().count() > mFieldIdx ? ft.fields().field( mFieldIdx ).name() : QString();
|
||||
|
||||
mConstraintFailureReason.clear();
|
||||
|
||||
@ -121,7 +122,7 @@ void QgsEditorWidgetWrapper::updateConstraint( const QgsFeature &ft )
|
||||
if ( ! expression.isEmpty() )
|
||||
{
|
||||
expressions << expression;
|
||||
descriptions << layer()->editFormConfig().constraintDescription( mFieldIdx );
|
||||
descriptions << field.constraintDescription();
|
||||
|
||||
QgsExpressionContext context = layer()->createExpressionContext();
|
||||
context.setFeature( ft );
|
||||
@ -140,7 +141,7 @@ void QgsEditorWidgetWrapper::updateConstraint( const QgsFeature &ft )
|
||||
}
|
||||
else if ( ! mValidConstraint )
|
||||
{
|
||||
errors << tr( "%1 check failed" ).arg( layer()->editFormConfig().constraintDescription( mFieldIdx ) );
|
||||
errors << tr( "%1 check failed" ).arg( field.constraintDescription() );
|
||||
}
|
||||
|
||||
toEmit = true;
|
||||
@ -148,12 +149,12 @@ void QgsEditorWidgetWrapper::updateConstraint( const QgsFeature &ft )
|
||||
else
|
||||
mValidConstraint = true;
|
||||
|
||||
if ( layer()->fields().at( mFieldIdx ).constraints() & QgsField::ConstraintNotNull )
|
||||
if ( field.constraints() & QgsField::ConstraintNotNull )
|
||||
{
|
||||
descriptions << QStringLiteral( "NotNull" );
|
||||
if ( !expression.isEmpty() )
|
||||
{
|
||||
expressions << fieldName + " IS NOT NULL";
|
||||
expressions << field.name() + " IS NOT NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -170,12 +171,12 @@ void QgsEditorWidgetWrapper::updateConstraint( const QgsFeature &ft )
|
||||
toEmit = true;
|
||||
}
|
||||
|
||||
if ( layer()->fields().at( mFieldIdx ).constraints() & QgsField::ConstraintUnique )
|
||||
if ( field.constraints() & QgsField::ConstraintUnique )
|
||||
{
|
||||
descriptions << QStringLiteral( "Unique" );
|
||||
if ( !expression.isEmpty() )
|
||||
{
|
||||
expressions << fieldName + " IS UNIQUE";
|
||||
expressions << field.name() + " IS UNIQUE";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -940,7 +940,7 @@ QList<QgsEditorWidgetWrapper*> QgsAttributeForm::constraintDependencies( QgsEdit
|
||||
if ( name != ewwName )
|
||||
{
|
||||
// get expression and referencedColumns
|
||||
QgsExpression expr = eww->layer()->editFormConfig().constraintExpression( eww->fieldIdx() );
|
||||
QgsExpression expr = eww->layer()->fields().at( eww->fieldIdx() ).constraintExpression();
|
||||
|
||||
Q_FOREACH ( const QString& colName, expr.referencedColumns() )
|
||||
{
|
||||
|
@ -78,14 +78,11 @@ void TestQgsAttributeForm::testFieldConstraint()
|
||||
form.setFeature( ft );
|
||||
|
||||
// testing stuff
|
||||
QSignalSpy spy( &form, SIGNAL( attributeChanged( QString, QVariant ) ) );
|
||||
QString validLabel = QStringLiteral( "col0<font color=\"green\">*</font>" );
|
||||
QString invalidLabel = QStringLiteral( "col0<font color=\"red\">*</font>" );
|
||||
|
||||
// set constraint
|
||||
QgsEditFormConfig config = layer->editFormConfig();
|
||||
config.setConstraintExpression( 0, QString() );
|
||||
layer->setEditFormConfig( config );
|
||||
layer->setConstraintExpression( 0, QString() );
|
||||
|
||||
// get wrapper
|
||||
QgsEditorWidgetWrapper *ww;
|
||||
@ -96,8 +93,13 @@ void TestQgsAttributeForm::testFieldConstraint()
|
||||
QCOMPARE( label->text(), QString( "col0" ) );
|
||||
|
||||
// set a not null constraint
|
||||
config.setConstraintExpression( 0, QStringLiteral( "col0 is not null" ) );
|
||||
layer->setEditFormConfig( config );
|
||||
layer->setConstraintExpression( 0, QStringLiteral( "col0 is not null" ) );
|
||||
// build a form for this feature
|
||||
QgsAttributeForm form2( layer );
|
||||
form2.setFeature( ft );
|
||||
QSignalSpy spy( &form2, SIGNAL( attributeChanged( QString, QVariant ) ) );
|
||||
ww = qobject_cast<QgsEditorWidgetWrapper*>( form2.mWidgets[0] );
|
||||
label = form2.mBuddyMap.value( ww->widget() );
|
||||
|
||||
// set value to 1
|
||||
ww->setValue( 1 );
|
||||
@ -131,12 +133,10 @@ void TestQgsAttributeForm::testFieldMultiConstraints()
|
||||
ft.setAttribute( QStringLiteral( "col3" ), 3 );
|
||||
|
||||
// set constraints for each field
|
||||
QgsEditFormConfig config = layer->editFormConfig();
|
||||
config.setConstraintExpression( 0, QString() );
|
||||
config.setConstraintExpression( 1, QString() );
|
||||
config.setConstraintExpression( 2, QString() );
|
||||
config.setConstraintExpression( 3, QString() );
|
||||
layer->setEditFormConfig( config );
|
||||
layer->setConstraintExpression( 0, QString() );
|
||||
layer->setConstraintExpression( 1, QString() );
|
||||
layer->setConstraintExpression( 2, QString() );
|
||||
layer->setConstraintExpression( 3, QString() );
|
||||
|
||||
// build a form for this feature
|
||||
QgsAttributeForm form( layer );
|
||||
@ -167,15 +167,26 @@ void TestQgsAttributeForm::testFieldMultiConstraints()
|
||||
QCOMPARE( label3->text(), QString( "col3" ) );
|
||||
|
||||
// update constraint
|
||||
config.setConstraintExpression( 0, QStringLiteral( "col0 < (col1 * col2)" ) );
|
||||
config.setConstraintExpression( 1, QString() );
|
||||
config.setConstraintExpression( 2, QString() );
|
||||
config.setConstraintExpression( 3, QStringLiteral( "col0 = 2" ) );
|
||||
layer->setEditFormConfig( config );
|
||||
layer->setConstraintExpression( 0, QStringLiteral( "col0 < (col1 * col2)" ) );
|
||||
layer->setConstraintExpression( 1, QString() );
|
||||
layer->setConstraintExpression( 2, QString() );
|
||||
layer->setConstraintExpression( 3, QStringLiteral( "col0 = 2" ) );
|
||||
|
||||
QgsAttributeForm form2( layer );
|
||||
form2.setFeature( ft );
|
||||
ww0 = qobject_cast<QgsEditorWidgetWrapper*>( form2.mWidgets[0] );
|
||||
ww1 = qobject_cast<QgsEditorWidgetWrapper*>( form2.mWidgets[1] );
|
||||
ww2 = qobject_cast<QgsEditorWidgetWrapper*>( form2.mWidgets[2] );
|
||||
ww3 = qobject_cast<QgsEditorWidgetWrapper*>( form2.mWidgets[3] );
|
||||
label0 = form2.mBuddyMap.value( ww0->widget() );
|
||||
label1 = form2.mBuddyMap.value( ww1->widget() );
|
||||
label2 = form2.mBuddyMap.value( ww2->widget() );
|
||||
label3 = form2.mBuddyMap.value( ww3->widget() );
|
||||
QSignalSpy spy2( &form2, SIGNAL( attributeChanged( QString, QVariant ) ) );
|
||||
|
||||
// change value
|
||||
ww0->setValue( 2 ); // update col0
|
||||
QCOMPARE( spy.count(), 2 );
|
||||
QCOMPARE( spy2.count(), 2 );
|
||||
|
||||
QCOMPARE( label0->text(), QString( "col0" + inv ) ); // 2 < ( 1 + 2 )
|
||||
QCOMPARE( label1->text(), QString( "col1" ) );
|
||||
@ -183,9 +194,9 @@ void TestQgsAttributeForm::testFieldMultiConstraints()
|
||||
QCOMPARE( label3->text(), QString( "col3" + val ) ); // 2 = 2
|
||||
|
||||
// change value
|
||||
spy.clear();
|
||||
spy2.clear();
|
||||
ww0->setValue( 1 ); // update col0
|
||||
QCOMPARE( spy.count(), 2 );
|
||||
QCOMPARE( spy2.count(), 2 );
|
||||
|
||||
QCOMPARE( label0->text(), QString( "col0" + val ) ); // 1 < ( 1 + 2 )
|
||||
QCOMPARE( label1->text(), QString( "col1" ) );
|
||||
@ -205,9 +216,7 @@ void TestQgsAttributeForm::testOKButtonStatus()
|
||||
ft.setValid( true );
|
||||
|
||||
// set constraint
|
||||
QgsEditFormConfig config = layer->editFormConfig();
|
||||
config.setConstraintExpression( 0, QString() );
|
||||
layer->setEditFormConfig( config );
|
||||
layer->setConstraintExpression( 0, QString() );
|
||||
|
||||
// build a form for this feature
|
||||
QgsAttributeForm form( layer );
|
||||
@ -235,14 +244,21 @@ void TestQgsAttributeForm::testOKButtonStatus()
|
||||
QCOMPARE( okButton->isEnabled(), true );
|
||||
|
||||
// invalid constraint and editable layer : OK button disabled
|
||||
config.setConstraintExpression( 0, QStringLiteral( "col0 = 0" ) );
|
||||
layer->setEditFormConfig( config );
|
||||
layer->setConstraintExpression( 0, QStringLiteral( "col0 = 0" ) );
|
||||
QgsAttributeForm form2( layer );
|
||||
form2.setFeature( ft );
|
||||
ww = qobject_cast<QgsEditorWidgetWrapper*>( form2.mWidgets[0] );
|
||||
okButton = form2.mButtonBox->button( QDialogButtonBox::Ok );
|
||||
ww->setValue( 1 );
|
||||
QCOMPARE( okButton->isEnabled(), false );
|
||||
|
||||
// valid constraint and editable layer : OK button enabled
|
||||
config.setConstraintExpression( 0, QStringLiteral( "col0 = 2" ) );
|
||||
layer->setEditFormConfig( config );
|
||||
layer->setConstraintExpression( 0, QStringLiteral( "col0 = 2" ) );
|
||||
QgsAttributeForm form3( layer );
|
||||
form3.setFeature( ft );
|
||||
ww = qobject_cast<QgsEditorWidgetWrapper*>( form3.mWidgets[0] );
|
||||
okButton = form3.mButtonBox->button( QDialogButtonBox::Ok );
|
||||
|
||||
ww->setValue( 2 );
|
||||
QCOMPARE( okButton->isEnabled(), true );
|
||||
|
||||
|
@ -1840,12 +1840,79 @@ class TestQgsVectorLayer(unittest.TestCase):
|
||||
self.assertEqual(layer3.fieldConstraints(0), QgsField.ConstraintNotNull)
|
||||
self.assertEqual(layer3.fieldConstraints(1), QgsField.ConstraintNotNull | QgsField.ConstraintUnique)
|
||||
self.assertEqual(layer3.fields().at(0).constraints(), QgsField.ConstraintNotNull)
|
||||
self.assertEqual(layer.fields().at(0).constraintOrigin(QgsField.ConstraintNotNull),
|
||||
self.assertEqual(layer3.fields().at(0).constraintOrigin(QgsField.ConstraintNotNull),
|
||||
QgsField.ConstraintOriginLayer)
|
||||
self.assertEqual(layer3.fields().at(1).constraints(), QgsField.ConstraintNotNull | QgsField.ConstraintUnique)
|
||||
self.assertEqual(layer.fields().at(1).constraintOrigin(QgsField.ConstraintNotNull),
|
||||
self.assertEqual(layer3.fields().at(1).constraintOrigin(QgsField.ConstraintNotNull),
|
||||
QgsField.ConstraintOriginLayer)
|
||||
self.assertEqual(layer.fields().at(1).constraintOrigin(QgsField.ConstraintUnique),
|
||||
self.assertEqual(layer3.fields().at(1).constraintOrigin(QgsField.ConstraintUnique),
|
||||
QgsField.ConstraintOriginLayer)
|
||||
|
||||
def testGetSetConstraintExpressions(self):
|
||||
""" test getting and setting field constraint expressions """
|
||||
layer = createLayerWithOnePoint()
|
||||
|
||||
self.assertFalse(layer.constraintExpression(0))
|
||||
self.assertFalse(layer.constraintExpression(1))
|
||||
self.assertFalse(layer.constraintExpression(2))
|
||||
|
||||
layer.setConstraintExpression(0, '1+2')
|
||||
self.assertEqual(layer.constraintExpression(0), '1+2')
|
||||
self.assertFalse(layer.constraintExpression(1))
|
||||
self.assertFalse(layer.constraintExpression(2))
|
||||
self.assertEqual(layer.fields().at(0).constraintExpression(), '1+2')
|
||||
|
||||
layer.setConstraintExpression(1, '3+4', 'desc')
|
||||
self.assertEqual(layer.constraintExpression(0), '1+2')
|
||||
self.assertEqual(layer.constraintExpression(1), '3+4')
|
||||
self.assertEqual(layer.constraintDescription(1), 'desc')
|
||||
self.assertFalse(layer.constraintExpression(2))
|
||||
self.assertEqual(layer.fields().at(0).constraintExpression(), '1+2')
|
||||
self.assertEqual(layer.fields().at(1).constraintExpression(), '3+4')
|
||||
self.assertEqual(layer.fields().at(1).constraintDescription(), 'desc')
|
||||
|
||||
layer.setConstraintExpression(1, None)
|
||||
self.assertEqual(layer.constraintExpression(0), '1+2')
|
||||
self.assertFalse(layer.constraintExpression(1))
|
||||
self.assertFalse(layer.constraintExpression(2))
|
||||
self.assertEqual(layer.fields().at(0).constraintExpression(), '1+2')
|
||||
self.assertFalse(layer.fields().at(1).constraintExpression())
|
||||
|
||||
def testSaveRestoreConstraintExpressions(self):
|
||||
""" test saving and restoring constraint expressions from xml"""
|
||||
layer = createLayerWithOnePoint()
|
||||
|
||||
# no constraints
|
||||
doc = QDomDocument("testdoc")
|
||||
elem = doc.createElement("maplayer")
|
||||
self.assertTrue(layer.writeXml(elem, doc))
|
||||
|
||||
layer2 = createLayerWithOnePoint()
|
||||
self.assertTrue(layer2.readXml(elem))
|
||||
self.assertFalse(layer2.constraintExpression(0))
|
||||
self.assertFalse(layer2.constraintExpression(1))
|
||||
|
||||
# set some constraints
|
||||
layer.setConstraintExpression(0, '1+2')
|
||||
layer.setConstraintExpression(1, '3+4', 'desc')
|
||||
|
||||
doc = QDomDocument("testdoc")
|
||||
elem = doc.createElement("maplayer")
|
||||
self.assertTrue(layer.writeXml(elem, doc))
|
||||
|
||||
layer3 = createLayerWithOnePoint()
|
||||
self.assertTrue(layer3.readXml(elem))
|
||||
self.assertEqual(layer3.constraintExpression(0), '1+2')
|
||||
self.assertEqual(layer3.constraintExpression(1), '3+4')
|
||||
self.assertEqual(layer3.constraintDescription(1), 'desc')
|
||||
self.assertEqual(layer3.fields().at(0).constraintExpression(), '1+2')
|
||||
self.assertEqual(layer3.fields().at(1).constraintExpression(), '3+4')
|
||||
self.assertEqual(layer3.fields().at(1).constraintDescription(), 'desc')
|
||||
self.assertEqual(layer3.fields().at(0).constraints(), QgsField.ConstraintExpression)
|
||||
self.assertEqual(layer3.fields().at(1).constraints(), QgsField.ConstraintExpression)
|
||||
self.assertEqual(layer3.fields().at(0).constraintOrigin(QgsField.ConstraintExpression),
|
||||
QgsField.ConstraintOriginLayer)
|
||||
self.assertEqual(layer3.fields().at(1).constraintOrigin(QgsField.ConstraintExpression),
|
||||
QgsField.ConstraintOriginLayer)
|
||||
|
||||
def testGetFeatureLimitWithEdits(self):
|
||||
|
Loading…
x
Reference in New Issue
Block a user