17
17
#include " qgsvectorlayer.h"
18
18
#include " qgsvectordataprovider.h"
19
19
#include " qgsfields.h"
20
+ #include " qgsvectorlayerutils.h"
20
21
21
22
#include < QTableView>
22
23
@@ -108,14 +109,19 @@ void QgsEditorWidgetWrapper::updateConstraintWidgetStatus( bool constraintValid
108
109
void QgsEditorWidgetWrapper::updateConstraint ( const QgsFeature &ft )
109
110
{
110
111
bool toEmit ( false );
111
- QString errStr ( tr ( " predicate is True" ) );
112
112
QString expression = layer ()->editFormConfig ().constraintExpression ( mFieldIdx );
113
- QString description ;
113
+ QStringList expressions, descriptions ;
114
114
QVariant value = ft.attribute ( mFieldIdx );
115
+ QString fieldName = ft.fields ().count () > mFieldIdx ? ft.fields ().field ( mFieldIdx ).name () : QString ();
116
+
117
+ mConstraintFailureReason .clear ();
118
+
119
+ QStringList errors;
115
120
116
121
if ( ! expression.isEmpty () )
117
122
{
118
- description = layer ()->editFormConfig ().constraintDescription ( mFieldIdx );
123
+ expressions << expression;
124
+ descriptions << layer ()->editFormConfig ().constraintDescription ( mFieldIdx );
119
125
120
126
QgsExpressionContext context = layer ()->createExpressionContext ();
121
127
context.setFeature ( ft );
@@ -125,11 +131,17 @@ void QgsEditorWidgetWrapper::updateConstraint( const QgsFeature &ft )
125
131
mValidConstraint = expr.evaluate ( &context ).toBool ();
126
132
127
133
if ( expr.hasParserError () )
128
- errStr = expr.parserErrorString ();
134
+ {
135
+ errors << tr ( " Parser error: %1" ).arg ( expr.parserErrorString () );
136
+ }
129
137
else if ( expr.hasEvalError () )
130
- errStr = expr.evalErrorString ();
138
+ {
139
+ errors << tr ( " Evaluation error: %1" ).arg ( expr.evalErrorString () );
140
+ }
131
141
else if ( ! mValidConstraint )
132
- errStr = tr ( " predicate is False" );
142
+ {
143
+ errors << tr ( " %1 check failed" ).arg ( layer ()->editFormConfig ().constraintDescription ( mFieldIdx ) );
144
+ }
133
145
134
146
toEmit = true ;
135
147
}
@@ -138,30 +150,66 @@ void QgsEditorWidgetWrapper::updateConstraint( const QgsFeature &ft )
138
150
139
151
if ( layer ()->fieldConstraints ( mFieldIdx ) & QgsField::ConstraintNotNull )
140
152
{
153
+ descriptions << QStringLiteral ( " NotNull" );
141
154
if ( !expression.isEmpty () )
142
155
{
143
- QString fieldName = ft.fields ().field ( mFieldIdx ).name ();
144
- expression = " ( " + expression + " ) AND ( " + fieldName + " IS NOT NULL)" ;
145
- description = " ( " + description + " ) AND NotNull" ;
156
+ expressions << fieldName + " IS NOT NULL" ;
146
157
}
147
158
else
148
159
{
149
- description = QStringLiteral ( " NotNull" );
150
- expression = QStringLiteral ( " NotNull" );
160
+ expressions << QStringLiteral ( " NotNull" );
151
161
}
152
162
153
163
mValidConstraint = mValidConstraint && !value.isNull ();
154
164
155
165
if ( value.isNull () )
156
- errStr = tr ( " predicate is False" );
166
+ {
167
+ errors << tr ( " Value is NULL" );
168
+ }
169
+
170
+ toEmit = true ;
171
+ }
172
+
173
+ if ( layer ()->fieldConstraints ( mFieldIdx ) & QgsField::ConstraintUnique )
174
+ {
175
+ descriptions << QStringLiteral ( " Unique" );
176
+ if ( !expression.isEmpty () )
177
+ {
178
+ expressions << fieldName + " IS UNIQUE" ;
179
+ }
180
+ else
181
+ {
182
+ expression = QStringLiteral ( " Unique" );
183
+ }
184
+
185
+ bool alreadyExists = QgsVectorLayerUtils::valueExists ( layer (), mFieldIdx , value, QgsFeatureIds () << ft.id () );
186
+ mValidConstraint = mValidConstraint && !alreadyExists;
187
+
188
+ if ( alreadyExists )
189
+ {
190
+ errors << tr ( " Value is not unique" );
191
+ }
157
192
158
193
toEmit = true ;
159
194
}
160
195
161
196
if ( toEmit )
162
197
{
198
+ QString errStr = errors.isEmpty () ? tr ( " Constraint checks passed" ) : errors.join ( ' \n ' );
199
+ mConstraintFailureReason = errors.join ( " , " );
200
+ QString description;
201
+ if ( descriptions.size () > 1 )
202
+ description = " ( " + descriptions.join ( " ) AND ( " ) + " )" ;
203
+ else if ( !descriptions.isEmpty () )
204
+ description = descriptions.at ( 0 );
205
+ QString expressionDesc;
206
+ if ( expressions.size () > 1 )
207
+ expressionDesc = " ( " + expressions.join ( " ) AND ( " ) + " )" ;
208
+ else if ( !expressions.isEmpty () )
209
+ expressionDesc = expressions.at ( 0 );
210
+
163
211
updateConstraintWidgetStatus ( mValidConstraint );
164
- emit constraintStatusChanged ( expression , description, errStr, mValidConstraint );
212
+ emit constraintStatusChanged ( expressionDesc , description, errStr, mValidConstraint );
165
213
}
166
214
}
167
215
@@ -170,6 +218,11 @@ bool QgsEditorWidgetWrapper::isValidConstraint() const
170
218
return mValidConstraint ;
171
219
}
172
220
221
+ QString QgsEditorWidgetWrapper::constraintFailureReason () const
222
+ {
223
+ return mConstraintFailureReason ;
224
+ }
225
+
173
226
bool QgsEditorWidgetWrapper::isInTable ( const QWidget* parent )
174
227
{
175
228
if ( !parent ) return false ;
0 commit comments