QGIS API Documentation 3.41.0-Master (45a0abf3bec)
Loading...
Searching...
No Matches
qgseditorwidgetwrapper.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgseditorwidgetwrapper.cpp
3 --------------------------------------
4 Date : 20.4.2013
5 Copyright : (C) 2013 Matthias Kuhn
6 Email : matthias at opengis dot ch
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17#include "moc_qgseditorwidgetwrapper.cpp"
18#include "qgsvectorlayer.h"
20#include "qgsfields.h"
21#include "qgsvectorlayerutils.h"
24
25#include <QTableView>
26
27QgsEditorWidgetWrapper::QgsEditorWidgetWrapper( QgsVectorLayer *vl, int fieldIdx, QWidget *editor, QWidget *parent )
28 : QgsWidgetWrapper( vl, editor, parent )
29 , mFieldIdx( fieldIdx )
30 , mValidConstraint( true )
31 , mIsBlockingCommit( false )
32{
33}
34
36{
37 return mFieldIdx;
38}
39
41{
42 QgsVectorLayer *vl = layer();
43 if ( vl && mFieldIdx < vl->fields().count() )
44 return vl->fields().at( mFieldIdx );
45 else
46 return QgsField();
47}
48
50{
51 mDefaultValue = layer()->dataProvider()->defaultValueClause( mFieldIdx );
52
53 return mDefaultValue;
54}
55
56QgsEditorWidgetWrapper *QgsEditorWidgetWrapper::fromWidget( QWidget *widget ) // cppcheck-suppress duplInheritedMember
57{
58 if ( !widget )
59 return nullptr;
60
61 return qobject_cast<QgsEditorWidgetWrapper *>( widget->property( "EWV2Wrapper" ).value<QgsWidgetWrapper *>() );
62}
63
65{
66 QWidget *wdg = widget();
67 if ( wdg )
68 {
69 wdg->setEnabled( enabled );
70 }
71}
72
74{
75 setFormFeature( feature );
76 QVariantList newAdditionalFieldValues;
77 const QStringList constAdditionalFields = additionalFields();
78 for ( const QString &fieldName : constAdditionalFields )
79 newAdditionalFieldValues << feature.attribute( fieldName );
80 setValues( feature.attribute( mFieldIdx ), newAdditionalFieldValues );
81}
82
83void QgsEditorWidgetWrapper::setValue( const QVariant &value )
84{
85 isRunningDeprecatedSetValue = true;
86 updateValues( value, QVariantList() );
87 isRunningDeprecatedSetValue = false;
88}
89
90void QgsEditorWidgetWrapper::setValues( const QVariant &value, const QVariantList &additionalValues )
91{
92 updateValues( value, additionalValues );
93}
94
102
103void QgsEditorWidgetWrapper::parentFormValueChanged( const QString &attribute, const QVariant &value )
104{
105 Q_UNUSED( attribute )
106 Q_UNUSED( value )
107}
108
110{
111 if ( !mConstraintResultVisible )
112 {
113 widget()->setStyleSheet( QString() );
114 }
115 else
116 {
117 switch ( mConstraintResult )
118 {
120 widget()->setStyleSheet( QString() );
121 break;
122
124 widget()->setStyleSheet( QStringLiteral( "background-color: rgba(255, 150, 0, 0.3);" ) );
125 break;
126
128 widget()->setStyleSheet( QStringLiteral( "background-color: rgba(255, 200, 45, 0.3);" ) );
129 break;
130 }
131 }
132}
133
134bool QgsEditorWidgetWrapper::setFormFeatureAttribute( const QString &attributeName, const QVariant &attributeValue )
135{
136 return mFormFeature.setAttribute( attributeName, attributeValue );
137}
138
139void QgsEditorWidgetWrapper::updateValues( const QVariant &value, const QVariantList &additionalValues )
140{
141 // this method should be made pure virtual in QGIS 4
142 Q_UNUSED( additionalValues );
144 // avoid infinite recursive loop
145 if ( !isRunningDeprecatedSetValue )
146 setValue( value );
148}
149
154
156{
157 return mConstraintResultVisible;
158}
159
160void QgsEditorWidgetWrapper::setConstraintResultVisible( bool constraintResultVisible )
161{
162 if ( mConstraintResultVisible == constraintResultVisible )
163 return;
164
165 mConstraintResultVisible = constraintResultVisible;
166
168
169 emit constraintResultVisibleChanged( mConstraintResultVisible );
170}
171
173{
174 updateConstraint( layer(), mFieldIdx, ft, constraintOrigin );
175}
176
178{
179 QStringList errors;
180 QStringList softErrors;
181 QStringList expressions;
182 QStringList descriptions;
183 bool toEmit( false );
184 bool hardConstraintsOk( true );
185 bool softConstraintsOk( true );
186
187 const QgsField field = layer->fields().at( index );
188 const QString expression = field.constraints().constraintExpression();
189
190 if ( ft.isValid() )
191 {
192 if ( ! expression.isEmpty() )
193 {
194 expressions << expression;
195 descriptions << field.constraints().constraintDescription();
196 toEmit = true;
197 }
198
200 {
201 descriptions << tr( "Not NULL" );
202 if ( !expression.isEmpty() )
203 {
204 expressions << field.name() + QStringLiteral( " IS NOT NULL" );
205 }
206 else
207 {
208 expressions << QStringLiteral( "IS NOT NULL" );
209 }
210 toEmit = true;
211 }
212
214 {
215 descriptions << tr( "Unique" );
216 if ( !expression.isEmpty() )
217 {
218 expressions << field.name() + QStringLiteral( " IS UNIQUE" );
219 }
220 else
221 {
222 expressions << QStringLiteral( "IS UNIQUE" );
223 }
224 toEmit = true;
225 }
226
227 hardConstraintsOk = QgsVectorLayerUtils::validateAttribute( layer, ft, index, errors, QgsFieldConstraints::ConstraintStrengthHard, constraintOrigin );
228
229 softConstraintsOk = QgsVectorLayerUtils::validateAttribute( layer, ft, index, softErrors, QgsFieldConstraints::ConstraintStrengthSoft, constraintOrigin );
230 errors << softErrors;
231 }
232 else // invalid feature
233 {
234 if ( ! expression.isEmpty() )
235 {
236 hardConstraintsOk = true;
237 softConstraintsOk = false;
238
239 errors << QStringLiteral( "Invalid feature" );
240
241 toEmit = true;
242 }
243 }
244
245 mValidConstraint = hardConstraintsOk && softConstraintsOk;
246 mIsBlockingCommit = !hardConstraintsOk;
247
248 mConstraintFailureReason = errors.join( QLatin1String( ", " ) );
249
250 if ( toEmit )
251 {
252 const QString errStr = errors.isEmpty() ? tr( "Constraint checks passed" ) : mConstraintFailureReason;
253
254 const QString description = descriptions.join( QLatin1String( ", " ) );
255 QString expressionDesc;
256 if ( expressions.size() > 1 )
257 expressionDesc = "( " + expressions.join( QLatin1String( " ) AND ( " ) ) + " )";
258 else if ( !expressions.isEmpty() )
259 expressionDesc = expressions.at( 0 );
260
261 const ConstraintResult result = !hardConstraintsOk ? ConstraintResultFailHard
262 : ( !softConstraintsOk ? ConstraintResultFailSoft : ConstraintResultPass );
263 //set the constraint result
264 mConstraintResult = result;
266 emit constraintStatusChanged( expressionDesc, description, errStr, result );
267 }
268}
269
270void QgsEditorWidgetWrapper::updateConstraint( QgsEditorWidgetWrapper::ConstraintResult constraintResult, const QString &constraintFailureReason )
271{
272 mValidConstraint = constraintResult == ConstraintResultPass;
273 mIsBlockingCommit = constraintResult == ConstraintResultFailHard;
274 mConstraintFailureReason = constraintResult != ConstraintResultPass ? constraintFailureReason : QString();
275 mConstraintResult = constraintResult;
277}
278
280{
281 return mValidConstraint;
282}
283
285{
286 return mIsBlockingCommit;
287}
288
289
291{
292 return mConstraintFailureReason;
293}
294
295bool QgsEditorWidgetWrapper::isInTable( const QWidget *parent )
296{
297 if ( !parent ) return false;
298 if ( qobject_cast<const QTableView *>( parent ) ) return true;
299 return isInTable( parent->parentWidget() );
300}
301
302void QgsEditorWidgetWrapper::setHint( const QString &hintText )
303{
304 if ( QWidget *w = widget() )
305 w->setToolTip( hintText );
306}
Manages an editor widget Widget and wrapper share the same parent.
Q_DECL_DEPRECATED void valueChanged(const QVariant &value)
Emit this signal, whenever the value changed.
virtual void updateConstraintWidgetStatus()
This should update the widget with a visual cue if a constraint status changed.
void setFormFeature(const QgsFeature &feature)
Set the feature currently being edited to feature.
virtual QVariant value() const =0
Will be used to access the widget's value.
virtual QVariantList additionalFieldValues() const
Will be used to access the widget's values for potential additional fields handled by the widget.
int fieldIdx() const
Access the field index.
virtual void parentFormValueChanged(const QString &attribute, const QVariant &value)
Is called in embedded form widgets when an attribute value in the parent form has changed.
QgsEditorWidgetWrapper(QgsVectorLayer *vl, int fieldIdx, QWidget *editor=nullptr, QWidget *parent=nullptr)
Create a new widget wrapper.
void setFeature(const QgsFeature &feature) override
Will be called when the feature changes.
virtual QStringList additionalFields() const
Returns the list of additional fields which the editor handles.
void constraintResultVisibleChanged(bool visible)
Emit this signal when the constraint result visibility changed.
QString constraintFailureReason() const
Returns the reason why a constraint check has failed (or an empty string if constraint check was succ...
QVariant defaultValue() const
Access the default value of the field.
void setEnabled(bool enabled) override
Is used to enable or disable the edit functionality of the managed widget.
void valuesChanged(const QVariant &value, const QVariantList &additionalFieldValues=QVariantList())
Emit this signal, whenever the value changed.
bool isValidConstraint() const
Gets the current constraint status.
void updateConstraint(const QgsFeature &featureContext, QgsFieldConstraints::ConstraintOrigin constraintOrigin=QgsFieldConstraints::ConstraintOriginNotSet)
Update constraint.
static bool isInTable(const QWidget *parent)
Check if the given widget or one of its parent is a QTableView.
void setValues(const QVariant &value, const QVariantList &additionalValues)
Is called when the value of the widget or additional field values needs to be changed.
bool setFormFeatureAttribute(const QString &attributeName, const QVariant &attributeValue)
Update the feature currently being edited by changing its attribute attributeName to attributeValue.
void emitValueChanged()
Will call the value() method to determine the emitted value.
virtual void setHint(const QString &hintText)
Add a hint text on the widget.
QgsField field() const
Access the field.
ConstraintResult
Result of constraint checks.
@ ConstraintResultFailSoft
Widget failed at least one soft (non-enforced) constraint.
@ ConstraintResultPass
Widget passed constraints successfully.
@ ConstraintResultFailHard
Widget failed at least one hard (enforced) constraint.
void constraintStatusChanged(const QString &constraint, const QString &desc, const QString &err, QgsEditorWidgetWrapper::ConstraintResult status)
Emit this signal when the constraint status changed.
virtual void setValue(const QVariant &value)
Is called when the value of the widget needs to be changed.
bool isBlockingCommit() const
Returns true if the widget is preventing the feature from being committed.
void setConstraintResultVisible(bool constraintResultVisible)
Sets whether the constraint result is visible.
static QgsEditorWidgetWrapper * fromWidget(QWidget *widget)
Will return a wrapper for a given widget.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:58
Q_INVOKABLE bool setAttribute(int field, const QVariant &attr)
Sets an attribute's value by field index.
bool isValid() const
Returns the validity of this feature.
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
@ ConstraintStrengthSoft
User is warned if constraint is violated but feature can still be accepted.
@ ConstraintStrengthHard
Constraint must be honored before feature can be accepted.
ConstraintOrigin
Origin of constraints.
QString constraintExpression() const
Returns the constraint expression for the field, if set.
@ ConstraintNotNull
Field may not be null.
@ ConstraintUnique
Field must have a unique value.
QString constraintDescription() const
Returns the descriptive name for the constraint expression.
Encapsulate a field in an attribute table or data source.
Definition qgsfield.h:53
QString name
Definition qgsfield.h:62
QgsFieldConstraints constraints
Definition qgsfield.h:65
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
virtual QString defaultValueClause(int fieldIndex) const
Returns any default value clauses which are present at the provider for a specified field index.
static bool validateAttribute(const QgsVectorLayer *layer, const QgsFeature &feature, int attributeIndex, QStringList &errors, QgsFieldConstraints::ConstraintStrength strength=QgsFieldConstraints::ConstraintStrengthNotSet, QgsFieldConstraints::ConstraintOrigin origin=QgsFieldConstraints::ConstraintOriginNotSet)
Tests a feature attribute value to check whether it passes all constraints which are present on the c...
Represents a vector layer which manages a vector based data sets.
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
Manages an editor widget Widget and wrapper share the same parent.
QWidget * widget()
Access the widget managed by this wrapper.
QgsVectorLayer * layer() const
Returns the vector layer associated with the widget.
#define Q_NOWARN_DEPRECATED_POP
Definition qgis.h:6535
#define Q_NOWARN_DEPRECATED_PUSH
Definition qgis.h:6534