Skip to content

Commit

Permalink
Merge pull request #3673 from nyalldawson/constraints
Browse files Browse the repository at this point in the history
[FEATURE] Improved constraint handling, pt 1
  • Loading branch information
nyalldawson committed Nov 4, 2016
2 parents 100667a + 9b9a002 commit 9a2ca1c
Show file tree
Hide file tree
Showing 65 changed files with 2,416 additions and 438 deletions.
14 changes: 10 additions & 4 deletions doc/api_break.dox
Expand Up @@ -736,10 +736,16 @@ QgsEditFormConfig {#qgis_api_break_3_0_QgsEditFormConfig}
- widgetType() and widgetConfig() now reflect only the user configured values.
QgsEditorWidgetRegistry::instance()->findBest() must be used instead.
- widgetType(), widgetConfig(), setWidgetType(), setWidgetConfig() and removeWidgetConfig() now only take a string as first parameter. Access by index has been removed.
- expression() has been renamed to constraintExpression()
- setExpression() has been renamed to setConstraintExpression()
- expressionDescription() has been renamed to constraintDescription()
- setExpressionDesctiption() has been renamed to setConstraintDescription()
- expression(), setExpression(), expressionDescription() and setExpressionDescription()
have been removed. Use QgsVectorLayer.setConstraintExpression()/constraintExpression(),
or QgsField.constraintExpression()/QgsField.constraintDescription() instead.
- notNull() and setNotNull() have been removed. Use QgsVectorLayer.setFieldConstraint()/fieldConstraints(), or QgsField.constraints() instead.

QgsEditorWidgetWrapper {#qgis_api_break_3_0_QgsEditorWidgetWrapper}
----------------------

- constraintStatusChanged now reports a QgsEditorWidgetWrapper::ConstraintResult instead of the previous boolean value for the constraint status
- The boolean constraintValid argument for updateConstraintWidgetStatus has been changed to a QgsEditorWidgetWrapper::ConstraintResult value


QgsExpression {#qgis_api_break_3_0_QgsExpression}
Expand Down
2 changes: 2 additions & 0 deletions python/core/core.sip
Expand Up @@ -56,6 +56,7 @@
%Include qgsfeaturerequest.sip
%Include qgsfeedback.sip
%Include qgsfield.sip
%Include qgsfieldconstraints.sip
%Include qgsfields.sip
%Include qgsgeometrysimplifier.sip
%Include qgsgeometryvalidator.sip
Expand Down Expand Up @@ -148,6 +149,7 @@
%Include qgsvectorlayerimport.sip
%Include qgsvectorlayerjoinbuffer.sip
%Include qgsvectorlayerundocommand.sip
%Include qgsvectorlayerutils.sip
%Include qgsvectorsimplifymethod.sip

%Include qgscachedfeatureiterator.sip
Expand Down
55 changes: 0 additions & 55 deletions python/core/qgseditformconfig.sip
Expand Up @@ -197,61 +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 );

/**
* Returns if the field at fieldidx should be treated as NOT NULL value
*/
bool notNull( int fieldidx ) const;
/**
* Set if the field at fieldidx should be treated as NOT NULL value
*/
void setNotNull( int idx, bool notnull = true );

/**
* 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.
Expand Down
16 changes: 16 additions & 0 deletions python/core/qgsfield.sip
Expand Up @@ -14,6 +14,7 @@ class QgsField
%End

public:

/** Constructor. Constructs a new QgsField object.
* @param name Field name
* @param type Field variant type, currently supported: String / Int / Double
Expand Down Expand Up @@ -162,6 +163,20 @@ class QgsField
*/
void setDefaultValueExpression( const QString& expression );

/**
* Returns constraints which are present for the field.
* @note added in QGIS 3.0
* @see setConstraints()
*/
const QgsFieldConstraints& constraints() const;

/**
* Sets constraints which are present for the field.
* @note added in QGIS 3.0
* @see constraints()
*/
void setConstraints( const QgsFieldConstraints& constraints );

/** Returns the alias for the field (the friendly displayed name of the field ),
* or an empty string if there is no alias.
* @see setAlias()
Expand Down Expand Up @@ -254,3 +269,4 @@ class QgsField
*/
const QgsEditorWidgetSetup& editorWidgetSetup() const;
}; // class QgsField

127 changes: 127 additions & 0 deletions python/core/qgsfieldconstraints.sip
@@ -0,0 +1,127 @@
/**
* \class QgsFieldConstraints
* \ingroup core
* Stores information about constraints which may be present on a field.
* \note added in QGIS 3.0
*/


class QgsFieldConstraints
{

%TypeHeaderCode
#include <qgsfieldconstraints.h>
%End

public:

/**
* Constraints which may be present on a field.
*/
enum Constraint
{
ConstraintNotNull, //!< Field may not be null
ConstraintUnique, //!< Field must have a unique value
ConstraintExpression, //!< Field has an expression constraint set. See constraintExpression().
};
typedef QFlags<QgsFieldConstraints::Constraint> Constraints;

/**
* Origin of constraints.
*/
enum ConstraintOrigin
{
ConstraintOriginNotSet, //!< Constraint is not set
ConstraintOriginProvider, //!< Constraint was set at data provider
ConstraintOriginLayer, //!< Constraint was set by layer
};

/**
* Strength of constraints.
*/
enum ConstraintStrength
{
ConstraintStrengthNotSet, //!< Constraint is not set
ConstraintStrengthHard, //!< Constraint must be honored before feature can be accepted
ConstraintStrengthSoft, //!< User is warned if constraint is violated but feature can still be accepted
};

/**
* Constructor for QgsFieldConstraints.
*/
QgsFieldConstraints();

/**
* Returns any constraints which are present for the field.
* @see setConstraints()
* @see constraintOrigin()
*/
Constraints constraints() const;

/**
* Returns the origin of a field constraint, or ConstraintOriginNotSet if the constraint
* is not present on this field.
* @see constraints()
*/
ConstraintOrigin constraintOrigin( Constraint constraint ) const;

/**
* Returns the strength of a field constraint, or ConstraintStrengthNotSet if the constraint
* is not present on this field.
* @see constraints()
* @see setConstraintStrength()
*/
ConstraintStrength constraintStrength( Constraint constraint ) const;

/**
* Sets the strength of a constraint. Note that the strength of constraints which originate
* from a provider cannot be changed. Constraints default to ConstraintStrengthHard unless
* explicitly changed.
* @see constraintStrength()
*/
void setConstraintStrength( Constraint constraint, ConstraintStrength strength );

/**
* Sets a constraint on the field.
* @see constraints()
* @see removeConstraint()
*/
void setConstraint( Constraint constraint, ConstraintOrigin origin = ConstraintOriginLayer );

/**
* Removes a constraint from the field.
* @see setConstraint()
* @see constraints()
*/
void removeConstraint( Constraint constraint );

/**
* Returns the constraint expression for the field, if set.
* @see constraints()
* @see constraintDescription()
* @see setConstraintExpression()
*/
QString constraintExpression() const;

/**
* Returns the descriptive name for the constraint expression.
* @see constraints()
* @see constraintExpression()
* @see setConstraintExpression()
*/
QString constraintDescription() const;

/**
* Set the constraint expression for the field. An optional descriptive name for the constraint
* can also be set. Setting an empty expression will clear any existing expression constraint.
* @see constraintExpression()
* @see constraintDescription()
* @see constraints()
*/
void setConstraintExpression( const QString& expression, const QString& description = QString() );

bool operator==( const QgsFieldConstraints& other ) const;

};

QFlags<QgsFieldConstraints::Constraint> operator|(QgsFieldConstraints::Constraint f1, QFlags<QgsFieldConstraints::Constraint> f2);
7 changes: 7 additions & 0 deletions python/core/qgsvectordataprovider.sip
Expand Up @@ -230,6 +230,13 @@ class QgsVectorDataProvider : QgsDataProvider
*/
virtual QVariant defaultValue( int fieldId ) const;

/**
* Returns any constraints which are present at the provider for a specified
* field index.
* @note added in QGIS 3.0
*/
QgsFieldConstraints::Constraints fieldConstraints( int fieldIndex ) const;

/**
* Changes geometries of existing features
* @param geometry_map A QgsGeometryMap whose index contains the feature IDs
Expand Down
56 changes: 56 additions & 0 deletions python/core/qgsvectorlayer.sip
Expand Up @@ -1257,6 +1257,62 @@ class QgsVectorLayer : QgsMapLayer
*/
QString defaultValueExpression( int index ) const;

/**
* Returns any constraints which are present for a specified
* field index. These constraints may be inherited from the layer's data provider
* or may be set manually on the vector layer from within QGIS.
* @note added in QGIS 3.0
* @see setFieldConstraint()
*/
QgsFieldConstraints::Constraints fieldConstraints( int fieldIndex ) const;

/**
* Sets a constraint for a specified field index. Any constraints inherited from the layer's
* data provider will be kept intact and cannot be modified. Ie, calling this method only allows for new
* constraints to be added on top of the existing provider constraints.
* @note added in QGIS 3.0
* @see fieldConstraints()
* @see removeFieldConstraint()
*/
void setFieldConstraint( int index, QgsFieldConstraints::Constraint constraint, QgsFieldConstraints::ConstraintStrength strength = QgsFieldConstraints::ConstraintStrengthHard );

/**
* Removes a constraint for a specified field index. Any constraints inherited from the layer's
* data provider will be kept intact and cannot be removed.
* @note added in QGIS 3.0
* @see fieldConstraints()
* @see setFieldConstraint()
*/
void removeFieldConstraint( int index, QgsFieldConstraints::Constraint constraint );

/**
* 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
Expand Down
31 changes: 31 additions & 0 deletions python/core/qgsvectorlayerutils.sip
@@ -0,0 +1,31 @@

/** \ingroup core
* \class QgsVectorLayerUtils
* \brief Contains utility methods for working with QgsVectorLayers.
*
* \note Added in version 3.0
*/
class QgsVectorLayerUtils
{
%TypeHeaderCode
#include <qgsvectorlayerutils.h>
%End
public:

/**
* Returns true if the specified value already exists within a field. This method can be used to test for uniqueness
* of values inside a layer's attributes. An optional list of ignored feature IDs can be provided, if so, any features
* with IDs within this list are ignored when testing for existance of the value.
*/
static bool valueExists( const QgsVectorLayer* layer, int fieldIndex, const QVariant& value, const QgsFeatureIds& ignoreIds = QgsFeatureIds() );

/**
* Tests an attribute value to check whether it passes all constraints which are present on the corresponding field.
* Returns true if the attribute value is valid for the field. Any constraint failures will be reported in the errors argument.
* If the strength or origin parameter is set then only constraints with a matching strength/origin will be checked.
*/
static bool validateAttribute( const QgsVectorLayer* layer, const QgsFeature& feature, int attributeIndex, QStringList& errors /Out/,
QgsFieldConstraints::ConstraintStrength strength = QgsFieldConstraints::ConstraintStrengthNotSet,
QgsFieldConstraints::ConstraintOrigin origin = QgsFieldConstraints::ConstraintOriginNotSet );

};

0 comments on commit 9a2ca1c

Please sign in to comment.