QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
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 
16 #include "qgseditorwidgetwrapper.h"
17 #include "qgsvectorlayer.h"
18 #include "qgsvectordataprovider.h"
19 #include "qgsfields.h"
20 #include "qgsvectorlayerutils.h"
22 #include "qgsvectorlayerjoininfo.h"
23 
24 #include <QTableView>
25 
26 QgsEditorWidgetWrapper::QgsEditorWidgetWrapper( QgsVectorLayer *vl, int fieldIdx, QWidget *editor, QWidget *parent )
27  : QgsWidgetWrapper( vl, editor, parent )
28  , mFieldIdx( fieldIdx )
29  , mValidConstraint( true )
30  , mIsBlockingCommit( false )
31 {
32 }
33 
35 {
36  return mFieldIdx;
37 }
38 
40 {
41  QgsVectorLayer *vl = layer();
42  if ( vl && mFieldIdx < vl->fields().count() )
43  return vl->fields().at( mFieldIdx );
44  else
45  return QgsField();
46 }
47 
49 {
50  mDefaultValue = layer()->dataProvider()->defaultValueClause( mFieldIdx );
51 
52  return mDefaultValue;
53 }
54 
56 {
57  return qobject_cast<QgsEditorWidgetWrapper *>( widget->property( "EWV2Wrapper" ).value<QgsWidgetWrapper *>() );
58 }
59 
61 {
62  QWidget *wdg = widget();
63  if ( wdg )
64  {
65  wdg->setEnabled( enabled );
66  }
67 }
68 
70 {
71  setFormFeature( feature );
72  QVariantList newAdditionalFieldValues;
73  const QStringList constAdditionalFields = additionalFields();
74  for ( const QString &fieldName : constAdditionalFields )
75  newAdditionalFieldValues << feature.attribute( fieldName );
76  setValues( feature.attribute( mFieldIdx ), newAdditionalFieldValues );
77 }
78 
79 void QgsEditorWidgetWrapper::setValue( const QVariant &value )
80 {
81  isRunningDeprecatedSetValue = true;
82  updateValues( value, QVariantList() );
83  isRunningDeprecatedSetValue = false;
84 }
85 
86 void QgsEditorWidgetWrapper::setValues( const QVariant &value, const QVariantList &additionalValues )
87 {
88  updateValues( value, additionalValues );
89 }
90 
92 {
94  emit valueChanged( value() );
97 }
98 
99 void QgsEditorWidgetWrapper::parentFormValueChanged( const QString &attribute, const QVariant &value )
100 {
101  Q_UNUSED( attribute )
102  Q_UNUSED( value )
103 }
104 
106 {
107  if ( !mConstraintResultVisible )
108  {
109  widget()->setStyleSheet( QString() );
110  }
111  else
112  {
113  switch ( mConstraintResult )
114  {
116  widget()->setStyleSheet( QString() );
117  break;
118 
120  widget()->setStyleSheet( QStringLiteral( "background-color: #FFE0B2;" ) );
121  break;
122 
124  widget()->setStyleSheet( QStringLiteral( "background-color: #FFECB3;" ) );
125  break;
126  }
127  }
128 }
129 
130 bool QgsEditorWidgetWrapper::setFormFeatureAttribute( const QString &attributeName, const QVariant &attributeValue )
131 {
132  return mFormFeature.setAttribute( attributeName, attributeValue );
133 }
134 
135 void QgsEditorWidgetWrapper::updateValues( const QVariant &value, const QVariantList &additionalValues )
136 {
137  // this method should be made pure virtual in QGIS 4
138  Q_UNUSED( additionalValues );
140  // avoid infinite recursive loop
141  if ( !isRunningDeprecatedSetValue )
142  setValue( value );
144 }
145 
147 {
148  return mConstraintResult;
149 }
150 
152 {
153  return mConstraintResultVisible;
154 }
155 
156 void QgsEditorWidgetWrapper::setConstraintResultVisible( bool constraintResultVisible )
157 {
158  if ( mConstraintResultVisible == constraintResultVisible )
159  return;
160 
161  mConstraintResultVisible = constraintResultVisible;
162 
164 
165  emit constraintResultVisibleChanged( mConstraintResultVisible );
166 }
167 
169 {
170  updateConstraint( layer(), mFieldIdx, ft, constraintOrigin );
171 }
172 
174 {
175  QStringList errors;
176  QStringList softErrors;
177  QStringList expressions;
178  QStringList descriptions;
179  bool toEmit( false );
180  bool hardConstraintsOk( true );
181  bool softConstraintsOk( true );
182 
183  QgsField field = layer->fields().at( index );
184  QString expression = field.constraints().constraintExpression();
185 
186  if ( ft.isValid() )
187  {
188  if ( ! expression.isEmpty() )
189  {
190  expressions << expression;
191  descriptions << field.constraints().constraintDescription();
192  toEmit = true;
193  }
194 
196  {
197  descriptions << tr( "Not NULL" );
198  if ( !expression.isEmpty() )
199  {
200  expressions << field.name() + QStringLiteral( " IS NOT NULL" );
201  }
202  else
203  {
204  expressions << QStringLiteral( "IS NOT NULL" );
205  }
206  toEmit = true;
207  }
208 
210  {
211  descriptions << tr( "Unique" );
212  if ( !expression.isEmpty() )
213  {
214  expressions << field.name() + QStringLiteral( " IS UNIQUE" );
215  }
216  else
217  {
218  expressions << QStringLiteral( "IS UNIQUE" );
219  }
220  toEmit = true;
221  }
222 
223  hardConstraintsOk = QgsVectorLayerUtils::validateAttribute( layer, ft, index, errors, QgsFieldConstraints::ConstraintStrengthHard, constraintOrigin );
224 
225  softConstraintsOk = QgsVectorLayerUtils::validateAttribute( layer, ft, index, softErrors, QgsFieldConstraints::ConstraintStrengthSoft, constraintOrigin );
226  errors << softErrors;
227  }
228  else // invalid feature
229  {
230  if ( ! expression.isEmpty() )
231  {
232  hardConstraintsOk = true;
233  softConstraintsOk = false;
234 
235  errors << QStringLiteral( "Invalid feature" );
236 
237  toEmit = true;
238  }
239  }
240 
241  mValidConstraint = hardConstraintsOk && softConstraintsOk;
242  mIsBlockingCommit = !hardConstraintsOk;
243 
244  mConstraintFailureReason = errors.join( QLatin1String( ", " ) );
245 
246  if ( toEmit )
247  {
248  QString errStr = errors.isEmpty() ? tr( "Constraint checks passed" ) : mConstraintFailureReason;
249 
250  QString description = descriptions.join( QLatin1String( ", " ) );
251  QString expressionDesc;
252  if ( expressions.size() > 1 )
253  expressionDesc = "( " + expressions.join( QLatin1String( " ) AND ( " ) ) + " )";
254  else if ( !expressions.isEmpty() )
255  expressionDesc = expressions.at( 0 );
256 
257  ConstraintResult result = !hardConstraintsOk ? ConstraintResultFailHard
258  : ( !softConstraintsOk ? ConstraintResultFailSoft : ConstraintResultPass );
259  //set the constraint result
260  mConstraintResult = result;
262  emit constraintStatusChanged( expressionDesc, description, errStr, result );
263  }
264 }
265 
267 {
268  return mValidConstraint;
269 }
270 
272 {
273  return mIsBlockingCommit;
274 }
275 
276 
278 {
279  return mConstraintFailureReason;
280 }
281 
282 bool QgsEditorWidgetWrapper::isInTable( const QWidget *parent )
283 {
284  if ( !parent ) return false;
285  if ( qobject_cast<const QTableView *>( parent ) ) return true;
286  return isInTable( parent->parentWidget() );
287 }
288 
289 void QgsEditorWidgetWrapper::setHint( const QString &hintText )
290 {
291  widget()->setToolTip( hintText );
292 }
qgsfields.h
qgseditorwidgetwrapper.h
QgsEditorWidgetWrapper::setValues
void setValues(const QVariant &value, const QVariantList &additionalValues)
Is called when the value of the widget or additional field values needs to be changed.
Definition: qgseditorwidgetwrapper.cpp:86
QgsWidgetWrapper
Manages an editor widget Widget and wrapper share the same parent.
Definition: qgswidgetwrapper.h:53
QgsEditorWidgetWrapper::isValidConstraint
bool isValidConstraint() const
Gets the current constraint status.
Definition: qgseditorwidgetwrapper.cpp:266
QgsEditorWidgetWrapper::setFormFeatureAttribute
bool setFormFeatureAttribute(const QString &attributeName, const QVariant &attributeValue)
Update the feature currently being edited by changing its attribute attributeName to attributeValue.
Definition: qgseditorwidgetwrapper.cpp:130
QgsEditorWidgetWrapper::ConstraintResultFailHard
@ ConstraintResultFailHard
Widget failed at least one hard (enforced) constraint.
Definition: qgseditorwidgetwrapper.h:63
QgsEditorWidgetWrapper::setValue
virtual void setValue(const QVariant &value)
Is called when the value of the widget needs to be changed.
Definition: qgseditorwidgetwrapper.cpp:79
QgsEditorWidgetWrapper::setHint
virtual void setHint(const QString &hintText)
Add a hint text on the widget.
Definition: qgseditorwidgetwrapper.cpp:289
QgsEditorWidgetWrapper::additionalFieldValues
virtual QVariantList additionalFieldValues() const
Will be used to access the widget's values for potential additional fields handled by the widget.
Definition: qgseditorwidgetwrapper.h:100
QgsEditorWidgetWrapper::constraintResult
ConstraintResult constraintResult
Definition: qgseditorwidgetwrapper.h:52
QgsFieldConstraints::ConstraintStrengthSoft
@ ConstraintStrengthSoft
User is warned if constraint is violated but feature can still be accepted.
Definition: qgsfieldconstraints.h:68
QgsFieldConstraints::constraintExpression
QString constraintExpression() const
Returns the constraint expression for the field, if set.
Definition: qgsfieldconstraints.cpp:67
QgsEditorWidgetWrapper::value
virtual QVariant value() const =0
Will be used to access the widget's value.
QgsEditorWidgetWrapper::ConstraintResult
ConstraintResult
Result of constraint checks.
Definition: qgseditorwidgetwrapper.h:61
QgsEditorWidgetWrapper::additionalFields
virtual QStringList additionalFields() const
Returns the list of additional fields which the editor handles.
Definition: qgseditorwidgetwrapper.h:92
QgsEditorWidgetWrapper::QgsEditorWidgetWrapper
QgsEditorWidgetWrapper(QgsVectorLayer *vl, int fieldIdx, QWidget *editor=nullptr, QWidget *parent=nullptr)
Create a new widget wrapper.
Definition: qgseditorwidgetwrapper.cpp:26
QgsEditorWidgetWrapper::constraintResultVisible
bool constraintResultVisible
Definition: qgseditorwidgetwrapper.h:51
QgsField::name
QString name
Definition: qgsfield.h:59
QgsFieldConstraints::ConstraintNotNull
@ ConstraintNotNull
Field may not be null.
Definition: qgsfieldconstraints.h:45
QgsWidgetWrapper::widget
QWidget * widget()
Access the widget managed by this wrapper.
Definition: qgswidgetwrapper.cpp:46
QgsEditorWidgetWrapper
Manages an editor widget Widget and wrapper share the same parent.
Definition: qgseditorwidgetwrapper.h:48
qgsvectorlayerjoininfo.h
QgsEditorWidgetWrapper::fieldIdx
int fieldIdx() const
Access the field index.
Definition: qgseditorwidgetwrapper.cpp:34
QgsEditorWidgetWrapper::valueChanged
Q_DECL_DEPRECATED void valueChanged(const QVariant &value)
Emit this signal, whenever the value changed.
QgsVectorLayer::fields
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Definition: qgsvectorlayer.cpp:3283
Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:797
QgsEditorWidgetWrapper::ConstraintResultPass
@ ConstraintResultPass
Widget passed constraints successfully.
Definition: qgseditorwidgetwrapper.h:62
QgsWidgetWrapper::layer
QgsVectorLayer * layer() const
Returns the vector layer associated with the widget.
Definition: qgswidgetwrapper.cpp:91
qgsvectorlayerjoinbuffer.h
QgsFeature::isValid
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:185
QgsFieldConstraints::ConstraintOrigin
ConstraintOrigin
Origin of constraints.
Definition: qgsfieldconstraints.h:55
QgsEditorWidgetWrapper::setConstraintResultVisible
void setConstraintResultVisible(bool constraintResultVisible)
Sets whether the constraint result is visible.
Definition: qgseditorwidgetwrapper.cpp:156
qgsvectordataprovider.h
QgsEditorWidgetWrapper::constraintStatusChanged
void constraintStatusChanged(const QString &constraint, const QString &desc, const QString &err, QgsEditorWidgetWrapper::ConstraintResult status)
Emit this signal when the constraint status changed.
QgsEditorWidgetWrapper::constraintResultVisibleChanged
void constraintResultVisibleChanged(bool visible)
Emit this signal when the constraint result visibility changed.
QgsFieldConstraints::ConstraintUnique
@ ConstraintUnique
Field must have a unique value.
Definition: qgsfieldconstraints.h:46
qgsvectorlayerutils.h
QgsEditorWidgetWrapper::field
QgsField field() const
Access the field.
Definition: qgseditorwidgetwrapper.cpp:39
QgsFeature::attribute
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:264
QgsEditorWidgetWrapper::emitValueChanged
void emitValueChanged()
Will call the value() method to determine the emitted value.
Definition: qgseditorwidgetwrapper.cpp:91
QgsFieldConstraints::ConstraintStrengthHard
@ ConstraintStrengthHard
Constraint must be honored before feature can be accepted.
Definition: qgsfieldconstraints.h:67
QgsFieldConstraints::constraintDescription
QString constraintDescription() const
Returns the descriptive name for the constraint expression.
Definition: qgsfieldconstraints.h:133
QgsEditorWidgetWrapper::constraintFailureReason
QString constraintFailureReason() const
Returns the reason why a constraint check has failed (or an empty string if constraint check was succ...
Definition: qgseditorwidgetwrapper.cpp:277
qgsvectorlayer.h
QgsEditorWidgetWrapper::setFormFeature
void setFormFeature(const QgsFeature &feature)
Set the feature currently being edited to feature.
Definition: qgseditorwidgetwrapper.h:353
QgsFeature::setAttribute
bool setAttribute(int field, const QVariant &attr)
Set an attribute's value by field index.
Definition: qgsfeature.cpp:213
QgsEditorWidgetWrapper::valuesChanged
void valuesChanged(const QVariant &value, const QVariantList &additionalFieldValues=QVariantList())
Emit this signal, whenever the value changed.
QgsEditorWidgetWrapper::parentFormValueChanged
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.
Definition: qgseditorwidgetwrapper.cpp:99
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:387
QgsEditorWidgetWrapper::ConstraintResultFailSoft
@ ConstraintResultFailSoft
Widget failed at least one soft (non-enforced) constraint.
Definition: qgseditorwidgetwrapper.h:64
QgsVectorLayerUtils::validateAttribute
static bool validateAttribute(const QgsVectorLayer *layer, const QgsFeature &feature, int attributeIndex, QStringList &errors, QgsFieldConstraints::ConstraintStrength strength=QgsFieldConstraints::ConstraintStrengthNotSet, QgsFieldConstraints::ConstraintOrigin origin=QgsFieldConstraints::ConstraintOriginNotSet)
Tests an attribute value to check whether it passes all constraints which are present on the correspo...
Definition: qgsvectorlayerutils.cpp:375
QgsEditorWidgetWrapper::updateConstraintWidgetStatus
virtual void updateConstraintWidgetStatus()
This should update the widget with a visual cue if a constraint status changed.
Definition: qgseditorwidgetwrapper.cpp:105
QgsEditorWidgetWrapper::setEnabled
void setEnabled(bool enabled) override
Is used to enable or disable the edit functionality of the managed widget.
Definition: qgseditorwidgetwrapper.cpp:60
QgsVectorLayer::dataProvider
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
Definition: qgsvectorlayer.cpp:627
QgsField::constraints
QgsFieldConstraints constraints
Definition: qgsfield.h:62
QgsVectorDataProvider::defaultValueClause
virtual QString defaultValueClause(int fieldIndex) const
Returns any default value clauses which are present at the provider for a specified field index.
Definition: qgsvectordataprovider.cpp:149
QgsEditorWidgetWrapper::defaultValue
QVariant defaultValue() const
Access the default value of the field.
Definition: qgseditorwidgetwrapper.cpp:48
QgsFeature
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:56
QgsFieldConstraints::constraints
Q_GADGET Constraints constraints
Definition: qgsfieldconstraints.h:36
QgsEditorWidgetWrapper::updateConstraint
void updateConstraint(const QgsFeature &featureContext, QgsFieldConstraints::ConstraintOrigin constraintOrigin=QgsFieldConstraints::ConstraintOriginNotSet)
Update constraint.
Definition: qgseditorwidgetwrapper.cpp:168
QgsFields::at
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:163
QgsEditorWidgetWrapper::setFeature
void setFeature(const QgsFeature &feature) override
Will be called when the feature changes.
Definition: qgseditorwidgetwrapper.cpp:69
Q_NOWARN_DEPRECATED_PUSH
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:796
QgsEditorWidgetWrapper::fromWidget
static QgsEditorWidgetWrapper * fromWidget(QWidget *widget)
Will return a wrapper for a given widget.
Definition: qgseditorwidgetwrapper.cpp:55
QgsEditorWidgetWrapper::isInTable
static bool isInTable(const QWidget *parent)
Check if the given widget or one of its parent is a QTableView.
Definition: qgseditorwidgetwrapper.cpp:282
QgsEditorWidgetWrapper::isBlockingCommit
bool isBlockingCommit() const
Returns true if the widget is preventing the feature from being committed.
Definition: qgseditorwidgetwrapper.cpp:271
QgsField
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:50