Skip to content

Commit 020d20a

Browse files
committed
[FEATURE] constraints on widgets
1 parent 4ae1b55 commit 020d20a

29 files changed

+782
-41
lines changed

python/core/qgseditformconfig.sip

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,22 @@ class QgsEditFormConfig : QObject
476476
*/
477477
void setReadOnly( int idx, bool readOnly = true );
478478

479+
/**
480+
* Returns the constraint expression of a specific field
481+
* @param idx The index of the field
482+
* @return the expression
483+
* @note added in QGIS 2.16
484+
*/
485+
QString constraint( int idx ) const;
486+
487+
/**
488+
* Set the constraint expression for a specific field
489+
* @param idx the field index
490+
* @param str the constraint expression
491+
* @note added in QGIS 2.16
492+
*/
493+
void setConstraint( int idx, const QString& str );
494+
479495
/**
480496
* Returns if the field at fieldidx should be treated as NOT NULL value
481497
*/

python/gui/editorwidgets/core/qgseditorwidgetwrapper.sip

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,21 @@ class QgsEditorWidgetWrapper : QgsWidgetWrapper
8888
*/
8989
virtual void showIndeterminateState();
9090

91+
/**
92+
* Update constraint.
93+
* @param featureContext the feature to use to evaluate the constraint
94+
* @note added in QGIS 2.16
95+
*/
96+
void updateConstraint( const QgsFeature &featureContext );
97+
98+
/**
99+
* Get the current constraint status.
100+
* @return true if the constraint is valid or if there's not constraint,
101+
* false otherwise
102+
* @note added in QGIS 2.16
103+
*/
104+
bool isValidConstraint() const;
105+
91106
signals:
92107
/**
93108
* Emit this signal, whenever the value changed.
@@ -96,6 +111,13 @@ class QgsEditorWidgetWrapper : QgsWidgetWrapper
96111
*/
97112
void valueChanged( const QVariant& value );
98113

114+
/**
115+
* @brief constraintStatusChanged
116+
* @param constraint
117+
* @param status
118+
*/
119+
void constraintStatusChanged( const QString& constraint, const QString& err, bool status );
120+
99121
public slots:
100122
/**
101123
* Will be called when the feature changes
@@ -162,4 +184,17 @@ class QgsEditorWidgetWrapper : QgsWidgetWrapper
162184
* Will call the value() method to determine the emitted value
163185
*/
164186
void valueChanged();
187+
188+
protected:
189+
/**
190+
* This should update the widget with a visual cue if a constraint status
191+
* changed.
192+
*
193+
* By default a stylesheet will be applied on the widget that changes the
194+
* background color to red.
195+
*
196+
* This can be overwritten in subclasses to allow individual widgets to
197+
* change the visual cue.
198+
*/
199+
virtual void updateConstraintWidgetStatus();
165200
};

python/gui/editorwidgets/qgsrelationreferencewidgetwrapper.sip

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,18 @@ class QgsRelationReferenceWidgetWrapper : QgsEditorWidgetWrapper
2121
public slots:
2222
virtual void setValue( const QVariant& value );
2323
virtual void setEnabled( bool enabled );
24+
25+
protected:
26+
/**
27+
* This should update the widget with a visual cue if a constraint status
28+
* changed.
29+
*
30+
* By default a stylesheet will be applied on the widget that changes the
31+
* background color to red.
32+
*
33+
* This can be overwritten in subclasses to allow individual widgets to
34+
* change the visual cue.
35+
* @note added in QGIS 2.16
36+
*/
37+
void updateConstraintWidgetStatus();
2438
};

src/app/qgsattributetypedialog.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ QgsAttributeTypeDialog::QgsAttributeTypeDialog( QgsVectorLayer *vl, int fieldIdx
7171

7272
QSettings settings;
7373
restoreGeometry( settings.value( "/Windows/QgsAttributeTypeDialog/geometry" ).toByteArray() );
74+
75+
constraintExpression->setLayer( vl );
7476
}
7577

7678
QgsAttributeTypeDialog::~QgsAttributeTypeDialog()
@@ -183,6 +185,16 @@ bool QgsAttributeTypeDialog::notNull() const
183185
return notNullCheckBox->isChecked();
184186
}
185187

188+
void QgsAttributeTypeDialog::setConstraint( const QString &str )
189+
{
190+
constraintExpression->setField( str );
191+
}
192+
193+
QString QgsAttributeTypeDialog::constraint() const
194+
{
195+
return constraintExpression->asExpression();
196+
}
197+
186198
void QgsAttributeTypeDialog::setFieldEditable( bool editable )
187199
{
188200
isFieldEditableCheckBox->setChecked( editable );

src/app/qgsattributetypedialog.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,18 @@ class APP_EXPORT QgsAttributeTypeDialog: public QDialog, private Ui::QgsAttribut
9494
*/
9595
bool notNull() const;
9696

97+
/**
98+
* Getter for the constraint expression
99+
* @note added in QGIS 2.16
100+
*/
101+
QString constraint() const;
102+
103+
/**
104+
* Setter for the constraint expression
105+
* @note added in QGIS 2.16
106+
*/
107+
void setConstraint( const QString &str );
108+
97109
private slots:
98110
/**
99111
* Slot to handle change of index in combobox to select correct page

src/app/qgsfieldsproperties.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,7 @@ void QgsFieldsProperties::attributeTypeDialog()
528528
attributeTypeDialog.setFieldEditable( cfg.mEditable );
529529
attributeTypeDialog.setLabelOnTop( cfg.mLabelOnTop );
530530
attributeTypeDialog.setNotNull( cfg.mNotNull );
531+
attributeTypeDialog.setConstraint( cfg.mConstraint );
531532

532533
attributeTypeDialog.setWidgetV2Config( cfg.mEditorWidgetV2Config );
533534
attributeTypeDialog.setWidgetV2Type( cfg.mEditorWidgetV2Type );
@@ -538,6 +539,7 @@ void QgsFieldsProperties::attributeTypeDialog()
538539
cfg.mEditable = attributeTypeDialog.fieldEditable();
539540
cfg.mLabelOnTop = attributeTypeDialog.labelOnTop();
540541
cfg.mNotNull = attributeTypeDialog.notNull();
542+
cfg.mConstraint = attributeTypeDialog.constraint();
541543

542544
cfg.mEditorWidgetV2Type = attributeTypeDialog.editorWidgetV2Type();
543545
cfg.mEditorWidgetV2Config = attributeTypeDialog.editorWidgetV2Config();
@@ -911,6 +913,7 @@ void QgsFieldsProperties::apply()
911913
mLayer->editFormConfig()->setReadOnly( i, !cfg.mEditable );
912914
mLayer->editFormConfig()->setLabelOnTop( i, cfg.mLabelOnTop );
913915
mLayer->editFormConfig()->setNotNull( i, cfg.mNotNull );
916+
mLayer->editFormConfig()->setConstraint( i, cfg.mConstraint );
914917

915918
mLayer->editFormConfig()->setWidgetType( idx, cfg.mEditorWidgetV2Type );
916919
mLayer->editFormConfig()->setWidgetConfig( idx, cfg.mEditorWidgetV2Config );
@@ -990,6 +993,7 @@ QgsFieldsProperties::FieldConfig::FieldConfig( QgsVectorLayer* layer, int idx )
990993
&& layer->fields().fieldOrigin( idx ) != QgsFields::OriginExpression;
991994
mLabelOnTop = layer->editFormConfig()->labelOnTop( idx );
992995
mNotNull = layer->editFormConfig()->notNull( idx );
996+
mConstraint = layer->editFormConfig()->constraint( idx );
993997
mEditorWidgetV2Type = layer->editFormConfig()->widgetType( idx );
994998
mEditorWidgetV2Config = layer->editFormConfig()->widgetConfig( idx );
995999

src/app/qgsfieldsproperties.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ class APP_EXPORT QgsFieldsProperties : public QWidget, private Ui_QgsFieldsPrope
9393
bool mEditableEnabled;
9494
bool mLabelOnTop;
9595
bool mNotNull;
96+
QString mConstraint;
9697
QPushButton* mButton;
9798
QString mEditorWidgetV2Type;
9899
QMap<QString, QVariant> mEditorWidgetV2Config;

src/core/qgseditformconfig.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,22 @@ bool QgsEditFormConfig::labelOnTop( int idx ) const
119119
return false;
120120
}
121121

122+
QString QgsEditFormConfig::constraint( int idx ) const
123+
{
124+
QString expr = "";
125+
126+
if ( idx >= 0 && idx < mFields.count() )
127+
expr = mConstraints.value( mFields.at( idx ).name(), "" );
128+
129+
return expr;
130+
}
131+
132+
void QgsEditFormConfig::setConstraint( int idx, const QString& str )
133+
{
134+
if ( idx >= 0 && idx < mFields.count() )
135+
mConstraints[ mFields.at( idx ).name()] = str;
136+
}
137+
122138
bool QgsEditFormConfig::notNull( int idx ) const
123139
{
124140
if ( idx >= 0 && idx < mFields.count() )

src/core/qgseditformconfig.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,22 @@ class CORE_EXPORT QgsEditFormConfig : public QObject
512512
*/
513513
void setReadOnly( int idx, bool readOnly = true );
514514

515+
/**
516+
* Returns the constraint expression of a specific field
517+
* @param idx The index of the field
518+
* @return the expression
519+
* @note added in QGIS 2.16
520+
*/
521+
QString constraint( int idx ) const;
522+
523+
/**
524+
* Set the constraint expression for a specific field
525+
* @param idx the field index
526+
* @param str the constraint expression
527+
* @note added in QGIS 2.16
528+
*/
529+
void setConstraint( int idx, const QString& str );
530+
515531
/**
516532
* Returns if the field at fieldidx should be treated as NOT NULL value
517533
*/
@@ -640,6 +656,7 @@ class CORE_EXPORT QgsEditFormConfig : public QObject
640656
/** Map that stores the tab for attributes in the edit form. Key is the tab order and value the tab name*/
641657
QList< TabData > mTabs;
642658

659+
QMap< QString, QString> mConstraints;
643660
QMap< QString, bool> mFieldEditables;
644661
QMap< QString, bool> mLabelOnTop;
645662
QMap< QString, bool> mNotNull;

src/gui/editorwidgets/core/qgseditorwidgetregistry.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,8 @@ void QgsEditorWidgetRegistry::readMapLayer( QgsMapLayer* mapLayer, const QDomEle
252252
vectorLayer->editFormConfig()->setReadOnly( idx, ewv2CfgElem.attribute( "fieldEditable", "1" ) != "1" );
253253
vectorLayer->editFormConfig()->setLabelOnTop( idx, ewv2CfgElem.attribute( "labelOnTop", "0" ) == "1" );
254254
vectorLayer->editFormConfig()->setNotNull( idx, ewv2CfgElem.attribute( "notNull", "0" ) == "1" );
255+
vectorLayer->editFormConfig()->setConstraint( idx, ewv2CfgElem.attribute( "constraint", "" ) );
256+
255257
vectorLayer->editFormConfig()->setWidgetConfig( idx, cfg );
256258
}
257259
else
@@ -309,6 +311,7 @@ void QgsEditorWidgetRegistry::writeMapLayer( QgsMapLayer* mapLayer, QDomElement&
309311
ewv2CfgElem.setAttribute( "fieldEditable", !vectorLayer->editFormConfig()->readOnly( idx ) );
310312
ewv2CfgElem.setAttribute( "labelOnTop", vectorLayer->editFormConfig()->labelOnTop( idx ) );
311313
ewv2CfgElem.setAttribute( "notNull", vectorLayer->editFormConfig()->notNull( idx ) );
314+
ewv2CfgElem.setAttribute( "constraint", vectorLayer->editFormConfig()->constraint( idx ) );
312315

313316
mWidgetFactories[widgetType]->writeConfig( vectorLayer->editFormConfig()->widgetConfig( idx ), ewv2CfgElem, doc, vectorLayer, idx );
314317

0 commit comments

Comments
 (0)