QGIS API Documentation  2.99.0-Master (b058df7)
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( QVariant( value ) );
78 }
79 
81 {
82  emit valueChanged( QVariant( value ) );
83 }
84 
86 {
87  emit valueChanged( QVariant( value ) );
88 }
89 
91 {
92  emit valueChanged( QVariant( value ) );
93 }
94 
96 {
97  emit valueChanged( QVariant( value ) );
98 }
99 
101 {
102  emit valueChanged( 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 
131 {
132  return mConstraintResult;
133 }
134 
136 {
137  return mConstraintResultVisible;
138 }
139 
141 {
142  if ( mConstraintResultVisible == constraintResultVisible )
143  return;
144 
145  mConstraintResultVisible = constraintResultVisible;
146 
148 
149  emit constraintResultVisibleChanged( mConstraintResultVisible );
150 }
151 
153 {
154  updateConstraint( layer(), mFieldIdx, ft, constraintOrigin );
155 }
156 
158 {
159  QStringList errors;
160  QStringList softErrors;
161  QStringList expressions;
162  QStringList descriptions;
163  bool toEmit( false );
164  bool hardConstraintsOk( true );
165  bool softConstraintsOk( true );
166 
167  QgsField field = layer->fields().at( index );
168  QString expression = field.constraints().constraintExpression();
169 
170  if ( ft.isValid() )
171  {
172  if ( ! expression.isEmpty() )
173  {
174  expressions << expression;
175  descriptions << field.constraints().constraintDescription();
176  toEmit = true;
177  }
178 
180  {
181  descriptions << tr( "Not NULL" );
182  if ( !expression.isEmpty() )
183  {
184  expressions << field.name() + QStringLiteral( " IS NOT NULL" );
185  }
186  else
187  {
188  expressions << QStringLiteral( "IS NOT NULL" );
189  }
190  toEmit = true;
191  }
192 
194  {
195  descriptions << tr( "Unique" );
196  if ( !expression.isEmpty() )
197  {
198  expressions << field.name() + QStringLiteral( " IS UNIQUE" );
199  }
200  else
201  {
202  expressions << QStringLiteral( "IS UNIQUE" );
203  }
204  toEmit = true;
205  }
206 
207  hardConstraintsOk = QgsVectorLayerUtils::validateAttribute( layer, ft, index, errors, QgsFieldConstraints::ConstraintStrengthHard, constraintOrigin );
208 
209  softConstraintsOk = QgsVectorLayerUtils::validateAttribute( layer, ft, index, softErrors, QgsFieldConstraints::ConstraintStrengthSoft, constraintOrigin );
210  errors << softErrors;
211  }
212  else // invalid feature
213  {
214  if ( ! expression.isEmpty() )
215  {
216  hardConstraintsOk = true;
217  softConstraintsOk = false;
218 
219  errors << QStringLiteral( "Invalid feature" );
220 
221  toEmit = true;
222  }
223  }
224 
225  mValidConstraint = hardConstraintsOk && softConstraintsOk;
226  mIsBlockingCommit = !hardConstraintsOk;
227 
228  mConstraintFailureReason = errors.join( QStringLiteral( ", " ) );
229 
230  if ( toEmit )
231  {
232  QString errStr = errors.isEmpty() ? tr( "Constraint checks passed" ) : mConstraintFailureReason;
233 
234  QString description = descriptions.join( QStringLiteral( ", " ) );
235  QString expressionDesc;
236  if ( expressions.size() > 1 )
237  expressionDesc = "( " + expressions.join( QStringLiteral( " ) AND ( " ) ) + " )";
238  else if ( !expressions.isEmpty() )
239  expressionDesc = expressions.at( 0 );
240 
241  ConstraintResult result = !hardConstraintsOk ? ConstraintResultFailHard
242  : ( !softConstraintsOk ? ConstraintResultFailSoft : ConstraintResultPass );
243  //set the constraint result
244  mConstraintResult = result;
246  emit constraintStatusChanged( expressionDesc, description, errStr, result );
247  }
248 }
249 
251 {
252  return mValidConstraint;
253 }
254 
256 {
257  return mIsBlockingCommit;
258 }
259 
261 {
262  return mConstraintFailureReason;
263 }
264 
265 bool QgsEditorWidgetWrapper::isInTable( const QWidget *parent )
266 {
267  if ( !parent ) return false;
268  if ( qobject_cast<const QTableView *>( parent ) ) return true;
269  return isInTable( parent->parentWidget() );
270 }
271 
272 void QgsEditorWidgetWrapper::setHint( const QString &hintText )
273 {
274  widget()->setToolTip( hintText );
275 }
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:56
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 updateConstraintWidgetStatus()
This should update the widget with a visual cue if a constraint status changed.
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: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.
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: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:59
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 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.
QgsEditorWidgetWrapper(QgsVectorLayer *vl, int fieldIdx, QWidget *editor=nullptr, QWidget *parent=0)
Create a new widget wrapper.
void constraintResultVisibleChanged(bool visible)
Emit this signal when the constraint result visibility changed.
Field must have a unique value.