QGIS API Documentation  2.99.0-Master (53aba61)
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  , mValidConstraint( true )
29  , mIsBlockingCommit( false )
30  , mFieldIdx( fieldIdx )
31 {
32 }
33 
35 {
36  return mFieldIdx;
37 }
38 
40 {
41  if ( mFieldIdx < layer()->fields().count() )
42  return layer()->fields().at( mFieldIdx );
43  else
44  return QgsField();
45 }
46 
48 {
49  mDefaultValue = layer()->dataProvider()->defaultValueClause( mFieldIdx );
50 
51  return mDefaultValue;
52 }
53 
55 {
56  return qobject_cast<QgsEditorWidgetWrapper *>( widget->property( "EWV2Wrapper" ).value<QgsWidgetWrapper *>() );
57 }
58 
60 {
61  QWidget *wdg = widget();
62  if ( wdg )
63  {
64  wdg->setEnabled( enabled );
65  }
66 }
67 
69 {
70  mFeature = feature;
71  setValue( feature.attribute( mFieldIdx ) );
72 }
73 
75 {
76  emit valueChanged( QVariant( value ) );
77 }
78 
80 {
81  emit valueChanged( QVariant( value ) );
82 }
83 
85 {
86  emit valueChanged( QVariant( value ) );
87 }
88 
90 {
91  emit valueChanged( QVariant( value ) );
92 }
93 
95 {
96  emit valueChanged( QVariant( value ) );
97 }
98 
100 {
101  emit valueChanged( value() );
102 }
103 
105 {
106  switch ( constraintResult )
107  {
109  widget()->setStyleSheet( QString() );
110  break;
111 
113  widget()->setStyleSheet( QStringLiteral( "background-color: #dd7777;" ) );
114  break;
115 
117  widget()->setStyleSheet( QStringLiteral( "background-color: #ffd85d;" ) );
118  break;
119  }
120 }
121 
123 {
124  updateConstraint( layer(), mFieldIdx, ft, constraintOrigin );
125 }
126 
128 {
129  QStringList errors;
130  QStringList softErrors;
131  QStringList expressions;
132  QStringList descriptions;
133  bool toEmit( false );
134  bool hardConstraintsOk( true );
135  bool softConstraintsOk( true );
136 
137  QgsField field = layer->fields().at( index );
138  QString expression = field.constraints().constraintExpression();
139 
140  if ( ft.isValid() )
141  {
142  if ( ! expression.isEmpty() )
143  {
144  expressions << expression;
145  descriptions << field.constraints().constraintDescription();
146  toEmit = true;
147  }
148 
150  {
151  descriptions << tr( "Not NULL" );
152  if ( !expression.isEmpty() )
153  {
154  expressions << field.name() + QStringLiteral( " IS NOT NULL" );
155  }
156  else
157  {
158  expressions << QStringLiteral( "IS NOT NULL" );
159  }
160  toEmit = true;
161  }
162 
164  {
165  descriptions << tr( "Unique" );
166  if ( !expression.isEmpty() )
167  {
168  expressions << field.name() + QStringLiteral( " IS UNIQUE" );
169  }
170  else
171  {
172  expressions << QStringLiteral( "IS UNIQUE" );
173  }
174  toEmit = true;
175  }
176 
177  hardConstraintsOk = QgsVectorLayerUtils::validateAttribute( layer, ft, index, errors, QgsFieldConstraints::ConstraintStrengthHard, constraintOrigin );
178 
179  softConstraintsOk = QgsVectorLayerUtils::validateAttribute( layer, ft, index, softErrors, QgsFieldConstraints::ConstraintStrengthSoft, constraintOrigin );
180  errors << softErrors;
181  }
182  else // invalid feature
183  {
184  if ( ! expression.isEmpty() )
185  {
186  hardConstraintsOk = true;
187  softConstraintsOk = false;
188 
189  errors << "Invalid feature";
190 
191  toEmit = true;
192  }
193  }
194 
195  mValidConstraint = hardConstraintsOk && softConstraintsOk;
196  mIsBlockingCommit = !hardConstraintsOk;
197 
198  mConstraintFailureReason = errors.join( ", " );
199 
200  if ( toEmit )
201  {
202  QString errStr = errors.isEmpty() ? tr( "Constraint checks passed" ) : mConstraintFailureReason;
203 
204  QString description = descriptions.join( ", " );
205  QString expressionDesc;
206  if ( expressions.size() > 1 )
207  expressionDesc = "( " + expressions.join( " ) AND ( " ) + " )";
208  else if ( !expressions.isEmpty() )
209  expressionDesc = expressions.at( 0 );
210 
211  ConstraintResult result = !hardConstraintsOk ? ConstraintResultFailHard
212  : ( !softConstraintsOk ? ConstraintResultFailSoft : ConstraintResultPass );
214  emit constraintStatusChanged( expressionDesc, description, errStr, result );
215  }
216 }
217 
219 {
220  return mValidConstraint;
221 }
222 
224 {
225  return mIsBlockingCommit;
226 }
227 
229 {
230  return mConstraintFailureReason;
231 }
232 
233 bool QgsEditorWidgetWrapper::isInTable( const QWidget *parent )
234 {
235  if ( !parent ) return false;
236  if ( qobject_cast<const QTableView *>( parent ) ) return true;
237  return isInTable( parent->parentWidget() );
238 }
239 
240 void QgsEditorWidgetWrapper::setHint( const QString &hintText )
241 {
242  widget()->setToolTip( hintText );
243 }
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:176
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:54
void valueChanged()
Will call the value() method to determine the emitted value.
QgsField field() const
Access the field.
Manages an editor widget Widget and wrapper share the same parent.
ConstraintOrigin
Origin of constraints.
Widget failed at least one hard (enforced) constraint.
virtual void setEnabled(bool enabled) override
Is used to enable or disable the edit functionality of the managed widget.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:61
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...
QgsField at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:135
void updateConstraint(const QgsFeature &featureContext, QgsFieldConstraints::ConstraintOrigin constraintOrigin=QgsFieldConstraints::ConstraintOriginNotSet)
Update constraint.
QVariant defaultValue() const
Access the default value of the field.
static bool isInTable(const QWidget *parent)
Check if the given widget or one of its parent is a QTableView.
QgsFields fields() const override
Returns the list of fields of this layer.
bool isBlockingCommit() const
Returns true if the widget is preventing the feature from being committed.
virtual 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...
virtual void setValue(const QVariant &value)=0
Is called, when the value of the widget needs to be changed.
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:46
User is warned if constraint is violated but feature can still be accepted.
bool isValidConstraint() const
Get the current constraint status.
Widget passed constraints successfully.
QgsFieldConstraints constraints
Definition: qgsfield.h:57
ConstraintResult
Result of constraint checks.
virtual void setHint(const QString &hintText)
Add a hint text on the widget.
void constraintStatusChanged(const QString &constraint, const QString &desc, const QString &err, ConstraintResult status)
Emit this signal when the constraint status changed.
virtual void updateConstraintWidgetStatus(ConstraintResult status)
This should update the widget with a visual cue if a constraint status changed.
virtual QVariant value() const =0
Will be used to access the widget&#39;s value.
QgsVectorDataProvider * dataProvider() override
Returns the layer&#39;s data provider.
QWidget * widget()
Access the widget managed by this wrapper.
int fieldIdx() const
Access the field index.
QString constraintExpression() const
Returns the constraint expression for the field, if set.
QgsVectorLayer * layer() const
Access the QgsVectorLayer, you are working on.
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:255
Manages an editor widget Widget and wrapper share the same parent.
Constraint must be honored before feature can be accepted.
QgsEditorWidgetWrapper(QgsVectorLayer *vl, int fieldIdx, QWidget *editor=nullptr, QWidget *parent=0)
Create a new widget wrapper.
Field must have a unique value.