QGIS API Documentation 3.99.0-Master (8e76e220402)
Loading...
Searching...
No Matches
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
17
18#include "qgsfields.h"
20#include "qgsvectorlayer.h"
23#include "qgsvectorlayerutils.h"
24
25#include <QString>
26#include <QTableView>
27
28#include "moc_qgseditorwidgetwrapper.cpp"
29
30using namespace Qt::StringLiterals;
31
32QgsEditorWidgetWrapper::QgsEditorWidgetWrapper( QgsVectorLayer *vl, int fieldIdx, QWidget *editor, QWidget *parent )
33 : QgsWidgetWrapper( vl, editor, parent )
34 , mFieldIdx( fieldIdx )
35{
36}
37
39{
40 return mFieldIdx;
41}
42
44{
45 QgsVectorLayer *vl = layer();
46 if ( vl && mFieldIdx < vl->fields().count() )
47 return vl->fields().at( mFieldIdx );
48 else
49 return QgsField();
50}
51
53{
54 mDefaultValue = layer()->dataProvider()->defaultValueClause( mFieldIdx );
55
56 return mDefaultValue;
57}
58
59QgsEditorWidgetWrapper *QgsEditorWidgetWrapper::fromWidget( QWidget *widget ) // cppcheck-suppress duplInheritedMember
60{
61 if ( !widget )
62 return nullptr;
63
64 return qobject_cast<QgsEditorWidgetWrapper *>( widget->property( "EWV2Wrapper" ).value<QgsWidgetWrapper *>() );
65}
66
68{
69 QWidget *wdg = widget();
70 if ( wdg )
71 {
72 wdg->setEnabled( enabled );
73 }
74}
75
77{
78 setFormFeature( feature );
79 QVariantList newAdditionalFieldValues;
80 const QStringList constAdditionalFields = additionalFields();
81 for ( const QString &fieldName : constAdditionalFields )
82 newAdditionalFieldValues << feature.attribute( fieldName );
83 setValues( feature.attribute( mFieldIdx ), newAdditionalFieldValues );
84}
85
87{
88 isRunningDeprecatedSetValue = true;
89 updateValues( value, QVariantList() );
90 isRunningDeprecatedSetValue = false;
91}
92
93void QgsEditorWidgetWrapper::setValues( const QVariant &value, const QVariantList &additionalValues )
94{
95 updateValues( value, additionalValues );
96}
97
105
106void QgsEditorWidgetWrapper::parentFormValueChanged( const QString &attribute, const QVariant &value )
107{
108 Q_UNUSED( attribute )
109 Q_UNUSED( value )
110}
111
113{
114 if ( !mConstraintResultVisible )
115 {
116 widget()->setStyleSheet( QString() );
117 }
118 else
119 {
120 switch ( mConstraintResult )
121 {
123 widget()->setStyleSheet( QString() );
124 break;
125
127 widget()->setStyleSheet( u"QWidget { background-color: rgba(255, 150, 0, 0.3); } QCalendarWidget QWidget#qt_calendar_calendarview, QCalendarWidget QWidget#qt_calendar_navigationbar QWidget { color: rgb(0, 0, 0); background-color: rgba(255, 150, 0, 1); }"_s );
128 break;
129
131 widget()->setStyleSheet( u"QWidget { background-color: rgba(255, 200, 45, 0.3); } QCalendarWidget QWidget#qt_calendar_calendarview, QCalendarWidget QWidget#qt_calendar_navigationbar QWidget { color: rgb(0, 0, 0); background-color: rgba(255, 200, 45, 1); }"_s );
132 break;
133 }
134 }
135#if QT_VERSION >= QT_VERSION_CHECK( 6, 9, 0 ) && QT_VERSION < QT_VERSION_CHECK( 6, 10, 0 )
136 widget()->style()->unpolish( widget() );
137 widget()->style()->polish( widget() );
138#endif
139}
140
141bool QgsEditorWidgetWrapper::setFormFeatureAttribute( const QString &attributeName, const QVariant &attributeValue )
142{
143 return mFormFeature.setAttribute( attributeName, attributeValue );
144}
145
146void QgsEditorWidgetWrapper::updateValues( const QVariant &value, const QVariantList &additionalValues )
147{
148 // this method should be made pure virtual in QGIS 5
149 Q_UNUSED( additionalValues );
151 // avoid infinite recursive loop
152 if ( !isRunningDeprecatedSetValue )
153 setValue( value );
155}
156
161
163{
164 return mConstraintResultVisible;
165}
166
168{
169 if ( mConstraintResultVisible == constraintResultVisible )
170 return;
171
172 mConstraintResultVisible = constraintResultVisible;
173
175
176 emit constraintResultVisibleChanged( mConstraintResultVisible );
177}
178
180{
181 updateConstraint( layer(), mFieldIdx, ft, constraintOrigin );
182}
183
185{
186 QStringList errors;
187 QStringList softErrors;
188 QStringList expressions;
189 QStringList descriptions;
190 bool toEmit( false );
191 bool hardConstraintsOk( true );
192 bool softConstraintsOk( true );
193
194 const QgsField field = layer->fields().at( index );
195 const QString expression = field.constraints().constraintExpression();
196
197 if ( ft.isValid() )
198 {
199 if ( !expression.isEmpty() )
200 {
201 expressions << expression;
202 descriptions << field.constraints().constraintDescription();
203 toEmit = true;
204 }
205
206 if ( field.constraints().constraints() & QgsFieldConstraints::ConstraintNotNull )
207 {
208 descriptions << tr( "Not NULL" );
209 if ( !expression.isEmpty() )
210 {
211 expressions << field.name() + u" IS NOT NULL"_s;
212 }
213 else
214 {
215 expressions << u"IS NOT NULL"_s;
216 }
217 toEmit = true;
218 }
219
220 if ( field.constraints().constraints() & QgsFieldConstraints::ConstraintUnique )
221 {
222 descriptions << tr( "Unique" );
223 if ( !expression.isEmpty() )
224 {
225 expressions << field.name() + u" IS UNIQUE"_s;
226 }
227 else
228 {
229 expressions << u"IS UNIQUE"_s;
230 }
231 toEmit = true;
232 }
233
234 hardConstraintsOk = QgsVectorLayerUtils::validateAttribute( layer, ft, index, errors, QgsFieldConstraints::ConstraintStrengthHard, constraintOrigin );
235
236 softConstraintsOk = QgsVectorLayerUtils::validateAttribute( layer, ft, index, softErrors, QgsFieldConstraints::ConstraintStrengthSoft, constraintOrigin );
237 errors << softErrors;
238 }
239 else // invalid feature
240 {
241 if ( !expression.isEmpty() )
242 {
243 hardConstraintsOk = true;
244 softConstraintsOk = false;
245
246 errors << u"Invalid feature"_s;
247
248 toEmit = true;
249 }
250 }
251
252 mValidConstraint = hardConstraintsOk && softConstraintsOk;
253 mIsBlockingCommit = !hardConstraintsOk;
254
255 mConstraintFailureReason = errors.join( ", "_L1 );
256
257 if ( toEmit )
258 {
259 const QString errStr = errors.isEmpty() ? tr( "Constraint checks passed" ) : mConstraintFailureReason;
260
261 const QString description = descriptions.join( ", "_L1 );
262 QString expressionDesc;
263 if ( expressions.size() > 1 )
264 expressionDesc = "( " + expressions.join( " ) AND ( "_L1 ) + " )";
265 else if ( !expressions.isEmpty() )
266 expressionDesc = expressions.at( 0 );
267
268 const ConstraintResult result = !hardConstraintsOk ? ConstraintResultFailHard
269 : ( !softConstraintsOk ? ConstraintResultFailSoft : ConstraintResultPass );
270 //set the constraint result
271 mConstraintResult = result;
273 emit constraintStatusChanged( expressionDesc, description, errStr, result );
274 }
275}
276
285
287{
288 return mValidConstraint;
289}
290
292{
293 return mIsBlockingCommit;
294}
295
296
298{
299 return mConstraintFailureReason;
300}
301
302bool QgsEditorWidgetWrapper::isInTable( const QWidget *parent )
303{
304 if ( !parent )
305 return false;
306 if ( qobject_cast<const QTableView *>( parent ) )
307 return true;
308 return isInTable( parent->parentWidget() );
309}
310
311void QgsEditorWidgetWrapper::setHint( const QString &hintText )
312{
313 if ( QWidget *w = widget() )
314 w->setToolTip( hintText );
315}
Q_DECL_DEPRECATED void valueChanged(const QVariant &value)
Emit this signal, whenever the value changed.
virtual void updateConstraintWidgetStatus()
This should update the widget with a visual cue if a constraint status changed.
void setFormFeature(const QgsFeature &feature)
Set the feature currently being edited to feature.
virtual QVariant value() const =0
Will be used to access the widget's value.
virtual QVariantList additionalFieldValues() const
Will be used to access the widget's values for potential additional fields handled by the widget.
int fieldIdx() const
Access the field index.
virtual void parentFormValueChanged(const QString &attribute, const QVariant &value)
Is called in embedded form widgets when an attribute value in the parent form has changed.
QgsEditorWidgetWrapper(QgsVectorLayer *vl, int fieldIdx, QWidget *editor=nullptr, QWidget *parent=nullptr)
Create a new widget wrapper.
void setFeature(const QgsFeature &feature) override
Will be called when the feature changes.
virtual QStringList additionalFields() const
Returns the list of additional fields which the editor handles.
void constraintResultVisibleChanged(bool visible)
Emit this signal when the constraint result visibility changed.
QString constraintFailureReason() const
Returns the reason why a constraint check has failed (or an empty string if constraint check was succ...
QVariant defaultValue() const
Access the default value of the field.
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.
bool isValidConstraint() const
Gets the current constraint status.
void updateConstraint(const QgsFeature &featureContext, QgsFieldConstraints::ConstraintOrigin constraintOrigin=QgsFieldConstraints::ConstraintOriginNotSet)
Update constraint.
static bool isInTable(const QWidget *parent)
Check if the given widget or one of its parent is a QTableView.
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 setFormFeatureAttribute(const QString &attributeName, const QVariant &attributeValue)
Update the feature currently being edited by changing its attribute attributeName to attributeValue.
void emitValueChanged()
Will call the value() method to determine the emitted value.
virtual void setHint(const QString &hintText)
Add a hint text on the widget.
QgsField field() const
Access the field.
ConstraintResult
Result of constraint checks.
@ ConstraintResultFailSoft
Widget failed at least one soft (non-enforced) constraint.
@ ConstraintResultPass
Widget passed constraints successfully.
@ ConstraintResultFailHard
Widget failed at least one hard (enforced) constraint.
void constraintStatusChanged(const QString &constraint, const QString &desc, const QString &err, QgsEditorWidgetWrapper::ConstraintResult status)
Emit this signal when the constraint status changed.
virtual void setValue(const QVariant &value)
Is called when the value of the widget needs to be changed.
bool isBlockingCommit() const
Returns true if the widget is preventing the feature from being committed.
void setConstraintResultVisible(bool constraintResultVisible)
Sets whether the constraint result is visible.
static QgsEditorWidgetWrapper * fromWidget(QWidget *widget)
Will return a wrapper for a given widget.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:60
bool isValid() const
Returns the validity of this feature.
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
@ ConstraintStrengthSoft
User is warned if constraint is violated but feature can still be accepted.
@ ConstraintStrengthHard
Constraint must be honored before feature can be accepted.
ConstraintOrigin
Origin of constraints.
@ ConstraintNotNull
Field may not be null.
@ ConstraintUnique
Field must have a unique value.
Encapsulate a field in an attribute table or data source.
Definition qgsfield.h:56
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
virtual QString defaultValueClause(int fieldIndex) const
Returns any default value clauses which are present at the provider for a specified field index.
static bool validateAttribute(const QgsVectorLayer *layer, const QgsFeature &feature, int attributeIndex, QStringList &errors, QgsFieldConstraints::ConstraintStrength strength=QgsFieldConstraints::ConstraintStrengthNotSet, QgsFieldConstraints::ConstraintOrigin origin=QgsFieldConstraints::ConstraintOriginNotSet)
Tests a feature attribute value to check whether it passes all constraints which are present on the c...
Represents a vector layer which manages a vector based dataset.
QgsVectorDataProvider * dataProvider() final
Returns the layer's data provider, it may be nullptr.
QWidget * widget()
Access the widget managed by this wrapper.
QgsWidgetWrapper(QgsVectorLayer *vl, QWidget *editor=nullptr, QWidget *parent=nullptr)
Create a new widget wrapper.
QgsVectorLayer * layer() const
Returns the vector layer associated with the widget.
#define Q_NOWARN_DEPRECATED_POP
Definition qgis.h:7486
#define Q_NOWARN_DEPRECATED_PUSH
Definition qgis.h:7485