QGIS API Documentation  3.9.0-Master (224899f119)
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 
100 {
101  if ( !mConstraintResultVisible )
102  {
103  widget()->setStyleSheet( QString() );
104  }
105  else
106  {
107  switch ( mConstraintResult )
108  {
110  widget()->setStyleSheet( QString() );
111  break;
112 
114  widget()->setStyleSheet( QStringLiteral( "background-color: #FFE0B2;" ) );
115  break;
116 
118  widget()->setStyleSheet( QStringLiteral( "background-color: #FFECB3;" ) );
119  break;
120  }
121  }
122 }
123 
124 bool QgsEditorWidgetWrapper::setFormFeatureAttribute( const QString &attributeName, const QVariant &attributeValue )
125 {
126  return mFormFeature.setAttribute( attributeName, attributeValue );
127 }
128 
129 void QgsEditorWidgetWrapper::updateValues( const QVariant &value, const QVariantList &additionalValues )
130 {
131  // this method should be made pure virtual in QGIS 4
132  Q_UNUSED( additionalValues );
134  // avoid infinte recursive loop
135  if ( !isRunningDeprecatedSetValue )
136  setValue( value );
138 }
139 
141 {
142  return mConstraintResult;
143 }
144 
146 {
147  return mConstraintResultVisible;
148 }
149 
151 {
152  if ( mConstraintResultVisible == constraintResultVisible )
153  return;
154 
155  mConstraintResultVisible = constraintResultVisible;
156 
158 
159  emit constraintResultVisibleChanged( mConstraintResultVisible );
160 }
161 
163 {
164  updateConstraint( layer(), mFieldIdx, ft, constraintOrigin );
165 }
166 
168 {
169  QStringList errors;
170  QStringList softErrors;
171  QStringList expressions;
172  QStringList descriptions;
173  bool toEmit( false );
174  bool hardConstraintsOk( true );
175  bool softConstraintsOk( true );
176 
177  QgsField field = layer->fields().at( index );
178  QString expression = field.constraints().constraintExpression();
179 
180  if ( ft.isValid() )
181  {
182  if ( ! expression.isEmpty() )
183  {
184  expressions << expression;
185  descriptions << field.constraints().constraintDescription();
186  toEmit = true;
187  }
188 
190  {
191  descriptions << tr( "Not NULL" );
192  if ( !expression.isEmpty() )
193  {
194  expressions << field.name() + QStringLiteral( " IS NOT NULL" );
195  }
196  else
197  {
198  expressions << QStringLiteral( "IS NOT NULL" );
199  }
200  toEmit = true;
201  }
202 
204  {
205  descriptions << tr( "Unique" );
206  if ( !expression.isEmpty() )
207  {
208  expressions << field.name() + QStringLiteral( " IS UNIQUE" );
209  }
210  else
211  {
212  expressions << QStringLiteral( "IS UNIQUE" );
213  }
214  toEmit = true;
215  }
216 
217  hardConstraintsOk = QgsVectorLayerUtils::validateAttribute( layer, ft, index, errors, QgsFieldConstraints::ConstraintStrengthHard, constraintOrigin );
218 
219  softConstraintsOk = QgsVectorLayerUtils::validateAttribute( layer, ft, index, softErrors, QgsFieldConstraints::ConstraintStrengthSoft, constraintOrigin );
220  errors << softErrors;
221  }
222  else // invalid feature
223  {
224  if ( ! expression.isEmpty() )
225  {
226  hardConstraintsOk = true;
227  softConstraintsOk = false;
228 
229  errors << QStringLiteral( "Invalid feature" );
230 
231  toEmit = true;
232  }
233  }
234 
235  mValidConstraint = hardConstraintsOk && softConstraintsOk;
236  mIsBlockingCommit = !hardConstraintsOk;
237 
238  mConstraintFailureReason = errors.join( QStringLiteral( ", " ) );
239 
240  if ( toEmit )
241  {
242  QString errStr = errors.isEmpty() ? tr( "Constraint checks passed" ) : mConstraintFailureReason;
243 
244  QString description = descriptions.join( QStringLiteral( ", " ) );
245  QString expressionDesc;
246  if ( expressions.size() > 1 )
247  expressionDesc = "( " + expressions.join( QStringLiteral( " ) AND ( " ) ) + " )";
248  else if ( !expressions.isEmpty() )
249  expressionDesc = expressions.at( 0 );
250 
251  ConstraintResult result = !hardConstraintsOk ? ConstraintResultFailHard
252  : ( !softConstraintsOk ? ConstraintResultFailSoft : ConstraintResultPass );
253  //set the constraint result
254  mConstraintResult = result;
256  emit constraintStatusChanged( expressionDesc, description, errStr, result );
257  }
258 }
259 
261 {
262  return mValidConstraint;
263 }
264 
266 {
267  return mIsBlockingCommit;
268 }
269 
271 {
272  return mConstraintFailureReason;
273 }
274 
275 bool QgsEditorWidgetWrapper::isInTable( const QWidget *parent )
276 {
277  if ( !parent ) return false;
278  if ( qobject_cast<const QTableView *>( parent ) ) return true;
279  return isInTable( parent->parentWidget() );
280 }
281 
282 void QgsEditorWidgetWrapper::setHint( const QString &hintText )
283 {
284  widget()->setToolTip( hintText );
285 }
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:183
void emitValueChanged()
Will call the value() method to determine the emitted value.
Widget failed at least one soft (non-enforced) constraint.
QString constraintFailureReason() const
Returns the reason why a constraint check has failed (or an empty string if constraint check was succ...
QString name
Definition: qgsfield.h:58
QgsField field() const
Access the field.
Manages an editor widget Widget and wrapper share the same parent.
ConstraintOrigin
Origin of constraints.
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:634
void setFormFeature(const QgsFeature &feature)
Set the feature currently being edited to feature.
Widget failed at least one hard (enforced) constraint.
bool setAttribute(int field, const QVariant &attr)
Set an attribute&#39;s value by field index.
Definition: qgsfeature.cpp:211
virtual void updateConstraintWidgetStatus()
This should update the widget with a visual cue if a constraint status changed.
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.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
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...
bool constraintResultVisible() const
Returns whether the constraint result is visible.
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:163
void updateConstraint(const QgsFeature &featureContext, QgsFieldConstraints::ConstraintOrigin constraintOrigin=QgsFieldConstraints::ConstraintOriginNotSet)
Update constraint.
QVariant defaultValue() const
Access the default value of the field.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
static bool isInTable(const QWidget *parent)
Check if the given widget or one of its parent is a QTableView.
bool isBlockingCommit() const
Returns true if the widget is preventing the feature from being committed.
void setFeature(const QgsFeature &feature) override
Will be called when the feature changes.
QString constraintDescription() const
Returns the descriptive name for the constraint expression.
static QgsEditorWidgetWrapper * fromWidget(QWidget *widget)
Will return a wrapper for a given widget.
virtual QString defaultValueClause(int fieldIndex) const
Returns any default value clauses which are present at the provider for a specified field index...
bool setFormFeatureAttribute(const QString &attributeName, const QVariant &attributeValue)
Update the feature currently being edited by changing its attribute attributeName to attributeValue...
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:48
User is warned if constraint is violated but feature can still be accepted.
virtual void setValue(const QVariant &value)
Is called, when the value of the widget needs to be changed.
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 isValidConstraint() const
Gets the current constraint status.
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:635
Widget passed constraints successfully.
QgsFieldConstraints constraints
Definition: qgsfield.h:61
ConstraintResult
Result of constraint checks.
virtual void setHint(const QString &hintText)
Add a hint text on the widget.
virtual QVariantList additionalFieldValues() const
Will be used to access the widget&#39;s values for potential additional fields handled by the widget...
virtual QStringList additionalFields() const
Returns the list of additional fields which the editor handles.
QgsEditorWidgetWrapper(QgsVectorLayer *vl, int fieldIdx, QWidget *editor=nullptr, QWidget *parent=nullptr)
Create a new widget wrapper.
virtual QVariant value() const =0
Will be used to access the widget&#39;s value.
ConstraintResult constraintResult() const
Returns the constraint result, which is the current result of the constraint on the widget influencin...
QWidget * widget()
Access the widget managed by this wrapper.
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer&#39;s data provider, it may be nullptr.
int fieldIdx() const
Access the field index.
QString constraintExpression() const
Returns the constraint expression for the field, if set.
QgsVectorLayer * layer() const
Returns the vector layer associated with the widget.
Represents a vector layer which manages a vector based data sets.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:262
Q_DECL_DEPRECATED void valueChanged(const QVariant &value)
Emit this signal, whenever the value changed.
void setConstraintResultVisible(bool constraintResultVisible)
Sets whether the constraint result is visible.
Manages an editor widget Widget and wrapper share the same parent.
Constraint must be honored before feature can be accepted.
void constraintResultVisibleChanged(bool visible)
Emit this signal when the constraint result visibility changed.
Field must have a unique value.
void constraintStatusChanged(const QString &constraint, const QString &desc, const QString &err, QgsEditorWidgetWrapper::ConstraintResult status)
Emit this signal when the constraint status changed.