QGIS API Documentation  3.4.15-Madeira (e83d02e274)
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  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 
105 bool QgsEditorWidgetWrapper::setFormFeatureAttribute( const QString &attributeName, const QVariant &attributeValue )
106 {
107  return mFormFeature.setAttribute( attributeName, attributeValue );
108 }
109 
111 {
112  return mConstraintResult;
113 }
114 
116 {
117  return mConstraintResultVisible;
118 }
119 
121 {
122  if ( mConstraintResultVisible == constraintResultVisible )
123  return;
124 
125  mConstraintResultVisible = constraintResultVisible;
126 
128 
129  emit constraintResultVisibleChanged( mConstraintResultVisible );
130 }
131 
133 {
134  updateConstraint( layer(), mFieldIdx, ft, constraintOrigin );
135 }
136 
138 {
139  QStringList errors;
140  QStringList softErrors;
141  QStringList expressions;
142  QStringList descriptions;
143  bool toEmit( false );
144  bool hardConstraintsOk( true );
145  bool softConstraintsOk( true );
146 
147  QgsField field = layer->fields().at( index );
148  QString expression = field.constraints().constraintExpression();
149 
150  if ( ft.isValid() )
151  {
152  if ( ! expression.isEmpty() )
153  {
154  expressions << expression;
155  descriptions << field.constraints().constraintDescription();
156  toEmit = true;
157  }
158 
160  {
161  descriptions << tr( "Not NULL" );
162  if ( !expression.isEmpty() )
163  {
164  expressions << field.name() + QStringLiteral( " IS NOT NULL" );
165  }
166  else
167  {
168  expressions << QStringLiteral( "IS NOT NULL" );
169  }
170  toEmit = true;
171  }
172 
174  {
175  descriptions << tr( "Unique" );
176  if ( !expression.isEmpty() )
177  {
178  expressions << field.name() + QStringLiteral( " IS UNIQUE" );
179  }
180  else
181  {
182  expressions << QStringLiteral( "IS UNIQUE" );
183  }
184  toEmit = true;
185  }
186 
187  hardConstraintsOk = QgsVectorLayerUtils::validateAttribute( layer, ft, index, errors, QgsFieldConstraints::ConstraintStrengthHard, constraintOrigin );
188 
189  softConstraintsOk = QgsVectorLayerUtils::validateAttribute( layer, ft, index, softErrors, QgsFieldConstraints::ConstraintStrengthSoft, constraintOrigin );
190  errors << softErrors;
191  }
192  else // invalid feature
193  {
194  if ( ! expression.isEmpty() )
195  {
196  hardConstraintsOk = true;
197  softConstraintsOk = false;
198 
199  errors << QStringLiteral( "Invalid feature" );
200 
201  toEmit = true;
202  }
203  }
204 
205  mValidConstraint = hardConstraintsOk && softConstraintsOk;
206  mIsBlockingCommit = !hardConstraintsOk;
207 
208  mConstraintFailureReason = errors.join( QStringLiteral( ", " ) );
209 
210  if ( toEmit )
211  {
212  QString errStr = errors.isEmpty() ? tr( "Constraint checks passed" ) : mConstraintFailureReason;
213 
214  QString description = descriptions.join( QStringLiteral( ", " ) );
215  QString expressionDesc;
216  if ( expressions.size() > 1 )
217  expressionDesc = "( " + expressions.join( QStringLiteral( " ) AND ( " ) ) + " )";
218  else if ( !expressions.isEmpty() )
219  expressionDesc = expressions.at( 0 );
220 
221  ConstraintResult result = !hardConstraintsOk ? ConstraintResultFailHard
222  : ( !softConstraintsOk ? ConstraintResultFailSoft : ConstraintResultPass );
223  //set the constraint result
224  mConstraintResult = result;
226  emit constraintStatusChanged( expressionDesc, description, errStr, result );
227  }
228 }
229 
231 {
232  return mValidConstraint;
233 }
234 
236 {
237  return mIsBlockingCommit;
238 }
239 
241 {
242  return mConstraintFailureReason;
243 }
244 
245 bool QgsEditorWidgetWrapper::isInTable( const QWidget *parent )
246 {
247  if ( !parent ) return false;
248  if ( qobject_cast<const QTableView *>( parent ) ) return true;
249  return isInTable( parent->parentWidget() );
250 }
251 
252 void QgsEditorWidgetWrapper::setHint( const QString &hintText )
253 {
254  widget()->setToolTip( hintText );
255 }
ConstraintResult constraintResult() const
Returns the constraint result, which is the current result of the constraint on the widget influencin...
void emitValueChanged()
Will call the value() method to determine the emitted value.
Widget failed at least one soft (non-enforced) constraint.
int fieldIdx() const
Access the field index.
bool isValidConstraint() const
Gets the current constraint status.
QString name
Definition: qgsfield.h:57
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:183
Manages an editor widget Widget and wrapper share the same parent.
ConstraintOrigin
Origin of constraints.
QgsField field() const
Access the field.
void setFormFeature(const QgsFeature &feature)
Set the feature currently being edited to feature.
Widget failed at least one hard (enforced) constraint.
QString constraintDescription() const
Returns the descriptive name for the constraint expression.
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.
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...
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.
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.
void setFeature(const QgsFeature &feature) override
Will be called when the feature changes.
static QgsEditorWidgetWrapper * fromWidget(QWidget *widget)
Will return a wrapper for a given widget.
virtual void setValue(const QVariant &value)=0
Is called, when the value of the widget needs to be changed.
QString constraintExpression() const
Returns the constraint expression for the field, if set.
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.
QVariant defaultValue() const
Access the default value of the field.
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.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:262
void valueChanged(const QVariant &value)
Emit this signal, whenever the value changed.
QgsVectorLayer * layer() const
Returns the vector layer associated with the widget.
bool constraintResultVisible() const
Returns whether the constraint result is visible.
virtual QVariant value() const =0
Will be used to access the widget&#39;s value.
QString constraintFailureReason() const
Returns the reason why a constraint check has failed (or an empty string if constraint check was succ...
QWidget * widget()
Access the widget managed by this wrapper.
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer&#39;s data provider.
virtual QString defaultValueClause(int fieldIndex) const
Returns any default value clauses which are present at the provider for a specified field index...
Represents a vector layer which manages a vector based data sets.
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.
bool isBlockingCommit() const
Returns true if the widget is preventing the feature from being committed.
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.