QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
qgsexternalresourcewidgetwrapper.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsexternalresourcewidgetwrapper.cpp
3 --------------------------------------
4 begin : 16.12.2015
5 copyright : (C) 2015 by Denis Rouzaud
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 "qgsapplication.h"
22#include "qgsfilterlineedit.h"
23#include "qgsproject.h"
24
25#include <QLabel>
26#include <QPushButton>
27#include <QSettings>
28#include <QString>
29
30#include "moc_qgsexternalresourcewidgetwrapper.cpp"
31
32using namespace Qt::StringLiterals;
33
35 : QgsEditorWidgetWrapper( layer, fieldIdx, editor, parent )
36 , mMessageBar( messageBar )
37{
38}
39
41{
42 if ( mQgsWidget )
43 {
44 return mQgsWidget->documentPath( field().type() );
45 }
46
47 if ( mLineEdit )
48 {
49 if ( mLineEdit->text().isEmpty() || mLineEdit->text() == QgsApplication::nullRepresentation() )
50 {
52 }
53 else
54 {
55 return mLineEdit->text();
56 }
57 }
58
60}
61
63{
64 if ( mLineEdit )
65 {
66 whileBlocking( mLineEdit )->clear();
67 }
68
69 if ( mLabel )
70 {
71 mLabel->clear();
72 }
73
74 if ( mQgsWidget )
75 {
76 whileBlocking( mQgsWidget )->setDocumentPath( QString() );
77 }
78}
79
81{
82 return mLineEdit || mLabel || mQgsWidget;
83}
84
85void QgsExternalResourceWidgetWrapper::updateProperties( const QgsFeature &feature )
86{
87 if ( mQgsWidget && mPropertyCollection.hasActiveProperties() )
88 {
90 expressionContext.setFeature( feature );
91 bool ok = false;
92
94 {
95 const QString path = mPropertyCollection.valueAsString( QgsEditorWidgetWrapper::Property::RootPath, expressionContext, QString(), &ok );
96 if ( ok )
97 {
98 mQgsWidget->setDefaultRoot( path );
99 }
100 }
102 {
103 const QString dvcString = mPropertyCollection.valueAsString( QgsEditorWidgetWrapper::Property::DocumentViewerContent, expressionContext, u"NoContent"_s, &ok );
104 if ( ok )
105 {
107 if ( dvcString.compare( "image"_L1, Qt::CaseInsensitive ) == 0 )
108 {
110 }
111 else if ( dvcString.compare( "audio"_L1, Qt::CaseInsensitive ) == 0 )
112 {
114 }
115 else if ( dvcString.compare( "video"_L1, Qt::CaseInsensitive ) == 0 )
116 {
118 }
119 else if ( dvcString.compare( "web"_L1, Qt::CaseInsensitive ) == 0 )
120 {
122 }
123 else
124 {
126 }
127 mQgsWidget->setDocumentViewerContent( dvc );
128 }
129 }
130 }
131}
132
134{
135 updateProperties( feature );
137
138 if ( mQgsWidget )
139 {
141 }
142}
143
145{
146 mForm = qobject_cast<QgsAttributeForm *>( parent );
147
148 if ( mForm )
150
151 return new QgsExternalResourceWidget( parent );
152}
153
155{
156 mLineEdit = qobject_cast<QLineEdit *>( editor );
157 mLabel = qobject_cast<QLabel *>( editor );
158 mQgsWidget = qobject_cast<QgsExternalResourceWidget *>( editor );
159
160 if ( mLineEdit )
161 {
162 QgsFilterLineEdit *fle = qobject_cast<QgsFilterLineEdit *>( editor );
163 if ( fle )
164 {
166 }
167 }
168 else
169 mLineEdit = editor->findChild<QLineEdit *>();
170
171 if ( mQgsWidget )
172 {
173 mQgsWidget->setMessageBar( mMessageBar );
174
175 mQgsWidget->fileWidget()->setStorageMode( QgsFileWidget::GetFile );
176
177 const QVariantMap cfg = config();
178 mPropertyCollection.loadVariant( cfg.value( u"PropertyCollection"_s ), propertyDefinitions() );
179
180 mQgsWidget->setStorageType( cfg.value( u"StorageType"_s ).toString() );
181 mQgsWidget->setStorageAuthConfigId( cfg.value( u"StorageAuthConfigId"_s ).toString() );
182
183 mQgsWidget->fileWidget()->setStorageUrlExpression( mPropertyCollection.isActive( QgsWidgetWrapper::Property::StorageUrl ) ? mPropertyCollection.property( QgsWidgetWrapper::Property::StorageUrl ).asExpression() : QgsExpression::quotedValue( cfg.value( u"StorageUrl"_s ).toString() ) );
184
186
187 if ( cfg.contains( u"UseLink"_s ) )
188 {
189 mQgsWidget->fileWidget()->setUseLink( cfg.value( u"UseLink"_s ).toBool() );
190 }
191 if ( cfg.contains( u"FullUrl"_s ) )
192 {
193 mQgsWidget->fileWidget()->setFullUrl( cfg.value( u"FullUrl"_s ).toBool() );
194 }
195
197 {
198 mQgsWidget->setDefaultRoot( cfg.value( u"DefaultRoot"_s ).toString() );
199 }
200 if ( cfg.contains( u"StorageMode"_s ) )
201 {
202 mQgsWidget->fileWidget()->setStorageMode( ( QgsFileWidget::StorageMode ) cfg.value( u"StorageMode"_s ).toInt() );
203 }
204 if ( cfg.contains( u"RelativeStorage"_s ) )
205 {
206 mQgsWidget->setRelativeStorage( ( QgsFileWidget::RelativeStorage ) cfg.value( u"RelativeStorage"_s ).toInt() );
207 }
208 if ( cfg.contains( u"FileWidget"_s ) )
209 {
210 mQgsWidget->setFileWidgetVisible( cfg.value( u"FileWidget"_s ).toBool() );
211 }
212 if ( cfg.contains( u"FileWidgetButton"_s ) )
213 {
214 mQgsWidget->fileWidget()->setFileWidgetButtonVisible( cfg.value( u"FileWidgetButton"_s ).toBool() );
215 }
216 if ( cfg.contains( u"DocumentViewer"_s ) )
217 {
218 mQgsWidget->setDocumentViewerContent( ( QgsExternalResourceWidget::DocumentViewerContent ) cfg.value( u"DocumentViewer"_s ).toInt() );
219 }
220 if ( cfg.contains( u"FileWidgetFilter"_s ) )
221 {
222 mQgsWidget->fileWidget()->setFilter( cfg.value( u"FileWidgetFilter"_s ).toString() );
223 }
224 if ( cfg.contains( u"DocumentViewerHeight"_s ) )
225 {
226 mQgsWidget->setDocumentViewerHeight( cfg.value( u"DocumentViewerHeight"_s ).toInt() );
227 }
228 if ( cfg.contains( u"DocumentViewerWidth"_s ) )
229 {
230 mQgsWidget->setDocumentViewerWidth( cfg.value( u"DocumentViewerWidth"_s ).toInt() );
231 }
232 }
233
234 if ( mLineEdit )
235 connect( mLineEdit, &QLineEdit::textChanged, this, [this]( const QString &value ) {
237 emit valueChanged( value );
239 emit valuesChanged( value );
240 } );
241}
242
243void QgsExternalResourceWidgetWrapper::updateValues( const QVariant &value, const QVariantList & )
244{
245 if ( mLineEdit )
246 {
248 {
249 mLineEdit->setText( QgsApplication::nullRepresentation() );
250 }
251 else
252 {
253 mLineEdit->setText( value.toString() );
254 }
255 }
256
257 if ( mLabel )
258 {
259 mLabel->setText( value.toString() );
261 emit valueChanged( value.toString() );
263 emit valuesChanged( value.toString() ); // emit signal that value has changed, do not do it for other widgets
264 }
265
266 if ( mQgsWidget )
267 {
269 {
270 mQgsWidget->setDocumentPath( QgsApplication::nullRepresentation() );
271 }
272 else
273 {
274 mQgsWidget->setDocumentPath( value.toString() );
275 }
276 }
277}
278
280{
281 if ( mLineEdit )
282 mLineEdit->setReadOnly( !enabled );
283
284 if ( mQgsWidget )
285 mQgsWidget->setReadOnly( !enabled );
286}
287
288void QgsExternalResourceWidgetWrapper::widgetValueChanged( const QString &attribute, const QVariant &newValue, bool attributeChanged )
289{
290 Q_UNUSED( newValue );
291 if ( attributeChanged )
292 {
293 const QgsExpression documentViewerContentExp = QgsExpression( mPropertyCollection.property( QgsEditorWidgetWrapper::Property::DocumentViewerContent ).expressionString() );
294 const QgsExpression rootPathExp = QgsExpression( mPropertyCollection.property( QgsEditorWidgetWrapper::Property::RootPath ).expressionString() );
295
296 if ( documentViewerContentExp.referencedColumns().contains( attribute ) || rootPathExp.referencedColumns().contains( attribute ) )
297 {
298 const QgsFeature feature = mForm->currentFormFeature();
299 updateProperties( feature );
300 }
301 }
302}
303
305{
306 if ( mLineEdit )
307 {
309 {
310 widget()->setStyleSheet( QString() );
311 }
312 else
313 {
314 switch ( constraintResult() )
315 {
317 mLineEdit->setStyleSheet( QString() );
318 break;
319
321 mLineEdit->setStyleSheet( u"QgsFilterLineEdit { background-color: #dd7777; }"_s );
322 break;
323
325 mLineEdit->setStyleSheet( u"QgsFilterLineEdit { background-color: #ffd85d; }"_s );
326 break;
327 }
328 }
329 }
330}
331
333{
334 if ( !mQgsWidget || !layer() )
335 return;
336
337 QgsExpressionContext expressionContext( layer()->createExpressionContext() );
338 expressionContext.setFeature( formFeature() );
340 if ( context().parentFormFeature().isValid() )
341 {
342 expressionContext.appendScope( QgsExpressionContextUtils::parentFormScope( context().parentFormFeature() ) );
343 }
344
345 mQgsWidget->fileWidget()->setExpressionContext( expressionContext );
346}
QString valueAsString(int key, const QgsExpressionContext &context, const QString &defaultString=QString(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a string.
static QString nullRepresentation()
Returns the string used to represent the value NULL throughout QGIS.
void widgetValueChanged(const QString &attribute, const QVariant &value, bool attributeChanged)
Notifies about changes of attributes.
QgsFeature formFeature() const
The feature currently being edited, in its current state.
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.
int fieldIdx() const
Access the field index.
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.
void valuesChanged(const QVariant &value, const QVariantList &additionalFieldValues=QVariantList())
Emit this signal, whenever the value changed.
QgsField field() const
Access the field.
@ ConstraintResultFailSoft
Widget failed at least one soft (non-enforced) constraint.
@ ConstraintResultPass
Widget passed constraints successfully.
@ ConstraintResultFailHard
Widget failed at least one hard (enforced) constraint.
static QgsExpressionContextScope * parentFormScope(const QgsFeature &formFeature=QgsFeature(), const QString &formMode=QString())
Creates a new scope which contains functions and variables from the current parent attribute form/tab...
static QgsExpressionContextScope * formScope(const QgsFeature &formFeature=QgsFeature(), const QString &formMode=QString())
Creates a new scope which contains functions and variables from the current attribute form/table form...
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Handles parsing and evaluation of expressions (formerly called "search strings").
static QString quotedValue(const QVariant &value)
Returns a string representation of a literal value, including appropriate quotations where required.
QSet< QString > referencedColumns() const
Gets list of columns referenced by the expression.
void updateFileWidgetExpressionContext()
Update file widget current expression context according to layer, feature, and parent feature.
void setFeature(const QgsFeature &feature) override
bool valid() const override
Returns true if the widget has been properly initialized.
QVariant value() const override
Will be used to access the widget's value.
QWidget * createWidget(QWidget *parent) override
This method should create a new widget with the provided parent.
void showIndeterminateState() override
Sets the widget to display in an indeterminate "mixed value" state.
void widgetValueChanged(const QString &attribute, const QVariant &newValue, bool attributeChanged)
Will be called when a value in the current edited form or table row changes.
void initWidget(QWidget *editor) override
This method should initialize the editor widget with runtime data.
QgsExternalResourceWidgetWrapper(QgsVectorLayer *layer, int fieldIdx, QWidget *editor=nullptr, QgsMessageBar *messageBar=nullptr, QWidget *parent=nullptr)
Constructor for QgsExternalResourceWidgetWrapper.
Widget to display file path with a push button for an "open file" dialog It can also be used to displ...
void setDefaultRoot(const QString &defaultRoot)
Configures the base path which should be used if the relativeStorage property is set to QgsFileWidget...
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:60
StorageMode
The StorageMode enum determines if the file picker should pick files or directories.
@ GetFile
Select a single file.
RelativeStorage
The RelativeStorage enum determines if path is absolute, relative to the current project path or rela...
QLineEdit subclass with built in support for clearing the widget's value and handling custom null val...
void setNullValue(const QString &nullValue)
Sets the string representation for null values in the widget.
A bar for displaying non-blocking messages to the user.
bool isActive(int key) const final
Returns true if the collection contains an active property with the specified key.
bool hasActiveProperties() const final
Returns true if the collection has any active properties, or false if all properties within the colle...
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
static QVariant createNullVariant(QMetaType::Type metaType)
Helper method to properly create a null QVariant from a metaType Returns the created QVariant.
Represents a vector layer which manages a vector based dataset.
QWidget * widget()
Access the widget managed by this wrapper.
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the editor widget property definitions.
const QgsAttributeEditorContext & context() const
Returns information about the context in which this widget is shown.
QgsVectorLayer * layer() const
Returns the vector layer associated with the widget.
QgsPropertyCollection mPropertyCollection
Data defined property collection.
QVariantMap config() const
Returns the whole config.
@ DocumentViewerContent
Document type for external resource.
@ StorageUrl
Storage URL for external resource.
@ RootPath
Root path for external resource.
#define Q_NOWARN_DEPRECATED_POP
Definition qgis.h:7451
#define Q_NOWARN_DEPRECATED_PUSH
Definition qgis.h:7450
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition qgis.h:6804