QGIS API Documentation  2.99.0-Master (6c64c5a)
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  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  mFeature = feature;
72  setValue( feature.attribute( mFieldIdx ) );
73 }
74 
76 {
77  emit valueChanged( value() );
78 }
79 
81 {
82  if ( !mConstraintResultVisible )
83  {
84  widget()->setStyleSheet( QString() );
85  }
86  else
87  {
88  switch ( mConstraintResult )
89  {
91  widget()->setStyleSheet( QString() );
92  break;
93 
95  widget()->setStyleSheet( QStringLiteral( "background-color: #FFE0B2;" ) );
96  break;
97 
99  widget()->setStyleSheet( QStringLiteral( "background-color: #FFECB3;" ) );
100  break;
101  }
102  }
103 }
104 
106 {
107  return mConstraintResult;
108 }
109 
111 {
112  return mConstraintResultVisible;
113 }
114 
116 {
117  if ( mConstraintResultVisible == constraintResultVisible )
118  return;
119 
120  mConstraintResultVisible = constraintResultVisible;
121 
123 
124  emit constraintResultVisibleChanged( mConstraintResultVisible );
125 }
126 
128 {
129  updateConstraint( layer(), mFieldIdx, ft, constraintOrigin );
130 }
131 
133 {
134  QStringList errors;
135  QStringList softErrors;
136  QStringList expressions;
137  QStringList descriptions;
138  bool toEmit( false );
139  bool hardConstraintsOk( true );
140  bool softConstraintsOk( true );
141 
142  QgsField field = layer->fields().at( index );
143  QString expression = field.constraints().constraintExpression();
144 
145  if ( ft.isValid() )
146  {
147  if ( ! expression.isEmpty() )
148  {
149  expressions << expression;
150  descriptions << field.constraints().constraintDescription();
151  toEmit = true;
152  }
153 
155  {
156  descriptions << tr( "Not NULL" );
157  if ( !expression.isEmpty() )
158  {
159  expressions << field.name() + QStringLiteral( " IS NOT NULL" );
160  }
161  else
162  {
163  expressions << QStringLiteral( "IS NOT NULL" );
164  }
165  toEmit = true;
166  }
167 
169  {
170  descriptions << tr( "Unique" );
171  if ( !expression.isEmpty() )
172  {
173  expressions << field.name() + QStringLiteral( " IS UNIQUE" );
174  }
175  else
176  {
177  expressions << QStringLiteral( "IS UNIQUE" );
178  }
179  toEmit = true;
180  }
181 
182  hardConstraintsOk = QgsVectorLayerUtils::validateAttribute( layer, ft, index, errors, QgsFieldConstraints::ConstraintStrengthHard, constraintOrigin );
183 
184  softConstraintsOk = QgsVectorLayerUtils::validateAttribute( layer, ft, index, softErrors, QgsFieldConstraints::ConstraintStrengthSoft, constraintOrigin );
185  errors << softErrors;
186  }
187  else // invalid feature
188  {
189  if ( ! expression.isEmpty() )
190  {
191  hardConstraintsOk = true;
192  softConstraintsOk = false;
193 
194  errors << QStringLiteral( "Invalid feature" );
195 
196  toEmit = true;
197  }
198  }
199 
200  mValidConstraint = hardConstraintsOk && softConstraintsOk;
201  mIsBlockingCommit = !hardConstraintsOk;
202 
203  mConstraintFailureReason = errors.join( QStringLiteral( ", " ) );
204 
205  if ( toEmit )
206  {
207  QString errStr = errors.isEmpty() ? tr( "Constraint checks passed" ) : mConstraintFailureReason;
208 
209  QString description = descriptions.join( QStringLiteral( ", " ) );
210  QString expressionDesc;
211  if ( expressions.size() > 1 )
212  expressionDesc = "( " + expressions.join( QStringLiteral( " ) AND ( " ) ) + " )";
213  else if ( !expressions.isEmpty() )
214  expressionDesc = expressions.at( 0 );
215 
216  ConstraintResult result = !hardConstraintsOk ? ConstraintResultFailHard
217  : ( !softConstraintsOk ? ConstraintResultFailSoft : ConstraintResultPass );
218  //set the constraint result
219  mConstraintResult = result;
221  emit constraintStatusChanged( expressionDesc, description, errStr, result );
222  }
223 }
224 
226 {
227  return mValidConstraint;
228 }
229 
231 {
232  return mIsBlockingCommit;
233 }
234 
236 {
237  return mConstraintFailureReason;
238 }
239 
240 bool QgsEditorWidgetWrapper::isInTable( const QWidget *parent )
241 {
242  if ( !parent ) return false;
243  if ( qobject_cast<const QTableView *>( parent ) ) return true;
244  return isInTable( parent->parentWidget() );
245 }
246 
247 void QgsEditorWidgetWrapper::setHint( const QString &hintText )
248 {
249  widget()->setToolTip( hintText );
250 }
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:176
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:57
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 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.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:62
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
Getter of constraintResultVisible Defines if the constraint result should be visualized on the widget...
QgsField at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:145
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.
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:48
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:60
ConstraintResult
Result of constraint checks.
virtual void setHint(const QString &hintText)
Add a hint text on the widget.
QgsEditorWidgetWrapper(QgsVectorLayer *vl, int fieldIdx, QWidget *editor=nullptr, QWidget *parent=nullptr)
Create a new widget wrapper.
void valueChanged(const QVariant &value)
Emit this signal, whenever the value 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.
ConstraintResult constraintResult() const
Getter of constraintResult It&#39;s the current result of the constraint on the widget influencing it&#39;s v...
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
void setConstraintResultVisible(bool constraintResultVisible)
Setter of constraintResultVisible Defines if the constraint result should be visualized on the widget...
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.