QGIS API Documentation 4.1.0-Master (60fea48833c)
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
38{
39 return mFieldIdx;
40}
41
43{
44 QgsVectorLayer *vl = layer();
45 if ( vl && mFieldIdx < vl->fields().count() )
46 return vl->fields().at( mFieldIdx );
47 else
48 return QgsField();
49}
50
52{
53 mDefaultValue = layer()->dataProvider()->defaultValueClause( mFieldIdx );
54
55 return mDefaultValue;
56}
57
58QgsEditorWidgetWrapper *QgsEditorWidgetWrapper::fromWidget( QWidget *widget ) // cppcheck-suppress duplInheritedMember
59{
60 if ( !widget )
61 return nullptr;
62
63 return qobject_cast<QgsEditorWidgetWrapper *>( widget->property( "EWV2Wrapper" ).value<QgsWidgetWrapper *>() );
64}
65
67{
68 QWidget *wdg = widget();
69 if ( wdg )
70 {
71 wdg->setEnabled( enabled );
72 }
73}
74
76{
77 setFormFeature( feature );
78 QVariantList newAdditionalFieldValues;
79 const QStringList constAdditionalFields = additionalFields();
80 for ( const QString &fieldName : constAdditionalFields )
81 newAdditionalFieldValues << feature.attribute( fieldName );
82 setValues( feature.attribute( mFieldIdx ), newAdditionalFieldValues );
83}
84
86{
87 isRunningDeprecatedSetValue = true;
88 updateValues( value, QVariantList() );
89 isRunningDeprecatedSetValue = false;
90}
91
92void QgsEditorWidgetWrapper::setValues( const QVariant &value, const QVariantList &additionalValues )
93{
94 updateValues( value, additionalValues );
95}
96
104
105void QgsEditorWidgetWrapper::parentFormValueChanged( const QString &attribute, const QVariant &value )
106{
107 Q_UNUSED( attribute )
108 Q_UNUSED( value )
109}
110
112{
113 if ( !mConstraintResultVisible )
114 {
115 widget()->setStyleSheet( QString() );
116 }
117 else
118 {
119 switch ( mConstraintResult )
120 {
122 widget()->setStyleSheet( QString() );
123 break;
124
126 widget()->setStyleSheet(
127 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 );
129 break;
130
132 widget()->setStyleSheet(
133 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
134 );
135 break;
136 }
137 }
138#if QT_VERSION >= QT_VERSION_CHECK( 6, 9, 0 ) && QT_VERSION < QT_VERSION_CHECK( 6, 10, 0 )
139 widget()->style()->unpolish( widget() );
140 widget()->style()->polish( widget() );
141#endif
142}
143
144bool QgsEditorWidgetWrapper::setFormFeatureAttribute( const QString &attributeName, const QVariant &attributeValue )
145{
146 return mFormFeature.setAttribute( attributeName, attributeValue );
147}
148
149void QgsEditorWidgetWrapper::updateValues( const QVariant &value, const QVariantList &additionalValues )
150{
151 // this method should be made pure virtual in QGIS 5
152 Q_UNUSED( additionalValues );
154 // avoid infinite recursive loop
155 if ( !isRunningDeprecatedSetValue )
156 setValue( value );
158}
159
164
166{
167 return mConstraintResultVisible;
168}
169
171{
172 if ( mConstraintResultVisible == constraintResultVisible )
173 return;
174
175 mConstraintResultVisible = constraintResultVisible;
176
178
179 emit constraintResultVisibleChanged( mConstraintResultVisible );
180}
181
183{
184 updateConstraint( layer(), mFieldIdx, ft, constraintOrigin );
185}
186
188{
189 QStringList errors;
190 QStringList softErrors;
191 QStringList expressions;
192 QStringList descriptions;
193 bool toEmit( false );
194 bool hardConstraintsOk( true );
195 bool softConstraintsOk( true );
196
197 const QgsField field = layer->fields().at( index );
198 const QString expression = field.constraints().constraintExpression();
199
200 if ( ft.isValid() )
201 {
202 if ( !expression.isEmpty() )
203 {
204 expressions << expression;
205 descriptions << field.constraints().constraintDescription();
206 toEmit = true;
207 }
208
209 if ( field.constraints().constraints() & QgsFieldConstraints::ConstraintNotNull )
210 {
211 descriptions << tr( "Not NULL" );
212 if ( !expression.isEmpty() )
213 {
214 expressions << field.name() + u" IS NOT NULL"_s;
215 }
216 else
217 {
218 expressions << u"IS NOT NULL"_s;
219 }
220 toEmit = true;
221 }
222
223 if ( field.constraints().constraints() & QgsFieldConstraints::ConstraintUnique )
224 {
225 descriptions << tr( "Unique" );
226 if ( !expression.isEmpty() )
227 {
228 expressions << field.name() + u" IS UNIQUE"_s;
229 }
230 else
231 {
232 expressions << u"IS UNIQUE"_s;
233 }
234 toEmit = true;
235 }
236
237 hardConstraintsOk = QgsVectorLayerUtils::validateAttribute( layer, ft, index, errors, QgsFieldConstraints::ConstraintStrengthHard, constraintOrigin );
238
239 softConstraintsOk = QgsVectorLayerUtils::validateAttribute( layer, ft, index, softErrors, QgsFieldConstraints::ConstraintStrengthSoft, constraintOrigin );
240 errors << softErrors;
241 }
242 else // invalid feature
243 {
244 if ( !expression.isEmpty() )
245 {
246 hardConstraintsOk = true;
247 softConstraintsOk = false;
248
249 errors << u"Invalid feature"_s;
250
251 toEmit = true;
252 }
253 }
254
255 mValidConstraint = hardConstraintsOk && softConstraintsOk;
256 mIsBlockingCommit = !hardConstraintsOk;
257
258 mConstraintFailureReason = errors.join( ", "_L1 );
259
260 if ( toEmit )
261 {
262 const QString errStr = errors.isEmpty() ? tr( "Constraint checks passed" ) : mConstraintFailureReason;
263
264 const QString description = descriptions.join( ", "_L1 );
265 QString expressionDesc;
266 if ( expressions.size() > 1 )
267 expressionDesc = "( " + expressions.join( " ) AND ( "_L1 ) + " )";
268 else if ( !expressions.isEmpty() )
269 expressionDesc = expressions.at( 0 );
270
271 const ConstraintResult result = !hardConstraintsOk ? ConstraintResultFailHard : ( !softConstraintsOk ? ConstraintResultFailSoft : ConstraintResultPass );
272 //set the constraint result
273 mConstraintResult = result;
275 emit constraintStatusChanged( expressionDesc, description, errStr, result );
276 }
277}
278
287
289{
290 return mValidConstraint;
291}
292
294{
295 return mIsBlockingCommit;
296}
297
298
300{
301 return mConstraintFailureReason;
302}
303
304bool QgsEditorWidgetWrapper::isInTable( const QWidget *parent )
305{
306 if ( !parent )
307 return false;
308 if ( qobject_cast<const QTableView *>( parent ) )
309 return true;
310 return isInTable( parent->parentWidget() );
311}
312
313void QgsEditorWidgetWrapper::setHint( const QString &hintText )
314{
315 if ( QWidget *w = widget() )
316 w->setToolTip( hintText );
317}
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:7504
#define Q_NOWARN_DEPRECATED_PUSH
Definition qgis.h:7503