QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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 <QPushButton>
19#include <QSettings>
20#include <QLabel>
21
22#include "qgsproject.h"
24#include "qgsfilterlineedit.h"
25#include "qgsapplication.h"
28
29
30QgsExternalResourceWidgetWrapper::QgsExternalResourceWidgetWrapper( QgsVectorLayer *layer, int fieldIdx, QWidget *editor, QgsMessageBar *messageBar, QWidget *parent )
31 : QgsEditorWidgetWrapper( layer, fieldIdx, editor, parent )
32 , mMessageBar( messageBar )
33{
34}
35
37{
38 if ( mQgsWidget )
39 {
40 return mQgsWidget->documentPath( field().type() );
41 }
42
43 if ( mLineEdit )
44 {
45 if ( mLineEdit->text().isEmpty() || mLineEdit->text() == QgsApplication::nullRepresentation() )
46 {
47 return QVariant( field().type() );
48 }
49 else
50 {
51 return mLineEdit->text();
52 }
53 }
54
55 return QVariant( field().type() );
56}
57
59{
60 if ( mLineEdit )
61 {
62 whileBlocking( mLineEdit )->clear();
63 }
64
65 if ( mLabel )
66 {
67 mLabel->clear();
68 }
69
70 if ( mQgsWidget )
71 {
72 whileBlocking( mQgsWidget )->setDocumentPath( QString() );
73 }
74}
75
77{
78 return mLineEdit || mLabel || mQgsWidget;
79}
80
81void QgsExternalResourceWidgetWrapper::updateProperties( const QgsFeature &feature )
82{
83 if ( mQgsWidget && mPropertyCollection.hasActiveProperties() )
84 {
86 expressionContext.setFeature( feature );
87 bool ok = false;
88
90 {
91 const QString path = mPropertyCollection.valueAsString( QgsEditorWidgetWrapper::Property::RootPath, expressionContext, QString(), &ok );
92 if ( ok )
93 {
94 mQgsWidget->setDefaultRoot( path );
95 }
96 }
98 {
99 const QString dvcString = mPropertyCollection.valueAsString( QgsEditorWidgetWrapper::Property::DocumentViewerContent, expressionContext, QStringLiteral( "NoContent" ), &ok );
100 if ( ok )
101 {
103 if ( dvcString.compare( QLatin1String( "image" ), Qt::CaseInsensitive ) == 0 )
104 {
106 }
107 else if ( dvcString.compare( QLatin1String( "audio" ), Qt::CaseInsensitive ) == 0 )
108 {
110 }
111 else if ( dvcString.compare( QLatin1String( "video" ), Qt::CaseInsensitive ) == 0 )
112 {
114 }
115 else if ( dvcString.compare( QLatin1String( "web" ), Qt::CaseInsensitive ) == 0 )
116 {
118 }
119 else
120 {
122 }
123 mQgsWidget->setDocumentViewerContent( dvc );
124 }
125 }
126 }
127}
128
130{
131 updateProperties( feature );
133
134 if ( mQgsWidget )
135 {
137 }
138}
139
141{
142 mForm = qobject_cast<QgsAttributeForm *>( parent );
143
144 if ( mForm )
146
147 return new QgsExternalResourceWidget( parent );
148}
149
151{
152 mLineEdit = qobject_cast<QLineEdit *>( editor );
153 mLabel = qobject_cast<QLabel *>( editor );
154 mQgsWidget = qobject_cast<QgsExternalResourceWidget *>( editor );
155
156 if ( mLineEdit )
157 {
158 QgsFilterLineEdit *fle = qobject_cast<QgsFilterLineEdit *>( editor );
159 if ( fle )
160 {
162 }
163 }
164 else
165 mLineEdit = editor->findChild<QLineEdit *>();
166
167 if ( mQgsWidget )
168 {
169 mQgsWidget->setMessageBar( mMessageBar );
170
172
173 const QVariantMap cfg = config();
174 mPropertyCollection.loadVariant( cfg.value( QStringLiteral( "PropertyCollection" ) ), propertyDefinitions() );
175
176 mQgsWidget->setStorageType( cfg.value( QStringLiteral( "StorageType" ) ).toString() );
177 mQgsWidget->setStorageAuthConfigId( cfg.value( QStringLiteral( "StorageAuthConfigId" ) ).toString() );
178
181 QgsExpression::quotedValue( cfg.value( QStringLiteral( "StorageUrl" ) ).toString() ) );
182
184
185 if ( cfg.contains( QStringLiteral( "UseLink" ) ) )
186 {
187 mQgsWidget->fileWidget()->setUseLink( cfg.value( QStringLiteral( "UseLink" ) ).toBool() );
188 }
189 if ( cfg.contains( QStringLiteral( "FullUrl" ) ) )
190 {
191 mQgsWidget->fileWidget()->setFullUrl( cfg.value( QStringLiteral( "FullUrl" ) ).toBool() );
192 }
193
195 {
196 mQgsWidget->setDefaultRoot( cfg.value( QStringLiteral( "DefaultRoot" ) ).toString() );
197 }
198 if ( cfg.contains( QStringLiteral( "StorageMode" ) ) )
199 {
200 mQgsWidget->fileWidget()->setStorageMode( ( QgsFileWidget::StorageMode )cfg.value( QStringLiteral( "StorageMode" ) ).toInt() );
201 }
202 if ( cfg.contains( QStringLiteral( "RelativeStorage" ) ) )
203 {
204 mQgsWidget->setRelativeStorage( ( QgsFileWidget::RelativeStorage )cfg.value( QStringLiteral( "RelativeStorage" ) ).toInt() );
205 }
206 if ( cfg.contains( QStringLiteral( "FileWidget" ) ) )
207 {
208 mQgsWidget->setFileWidgetVisible( cfg.value( QStringLiteral( "FileWidget" ) ).toBool() );
209 }
210 if ( cfg.contains( QStringLiteral( "FileWidgetButton" ) ) )
211 {
212 mQgsWidget->fileWidget()->setFileWidgetButtonVisible( cfg.value( QStringLiteral( "FileWidgetButton" ) ).toBool() );
213 }
214 if ( cfg.contains( QStringLiteral( "DocumentViewer" ) ) )
215 {
216 mQgsWidget->setDocumentViewerContent( ( QgsExternalResourceWidget::DocumentViewerContent )cfg.value( QStringLiteral( "DocumentViewer" ) ).toInt() );
217 }
218 if ( cfg.contains( QStringLiteral( "FileWidgetFilter" ) ) )
219 {
220 mQgsWidget->fileWidget()->setFilter( cfg.value( QStringLiteral( "FileWidgetFilter" ) ).toString() );
221 }
222 if ( cfg.contains( QStringLiteral( "DocumentViewerHeight" ) ) )
223 {
224 mQgsWidget->setDocumentViewerHeight( cfg.value( QStringLiteral( "DocumentViewerHeight" ) ).toInt( ) );
225 }
226 if ( cfg.contains( QStringLiteral( "DocumentViewerWidth" ) ) )
227 {
228 mQgsWidget->setDocumentViewerWidth( cfg.value( QStringLiteral( "DocumentViewerWidth" ) ).toInt( ) );
229 }
230 }
231
232 if ( mLineEdit )
233 connect( mLineEdit, &QLineEdit::textChanged, this, [ = ]( const QString & value )
234 {
236 emit valueChanged( value );
238 emit valuesChanged( value );
239 } );
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 {
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 {
295
296 if ( documentViewerContentExp.referencedColumns().contains( attribute ) ||
297 rootPathExp.referencedColumns().contains( attribute ) )
298 {
299 const QgsFeature feature = mForm->currentFormFeature();
300 updateProperties( feature );
301 }
302 }
303}
304
305void QgsExternalResourceWidgetWrapper::updateConstraintWidgetStatus()
306{
307 if ( mLineEdit )
308 {
310 {
311 widget()->setStyleSheet( QString() );
312 }
313 else
314 {
315 switch ( constraintResult() )
316 {
318 mLineEdit->setStyleSheet( QString() );
319 break;
320
322 mLineEdit->setStyleSheet( QStringLiteral( "QgsFilterLineEdit { background-color: #dd7777; }" ) );
323 break;
324
326 mLineEdit->setStyleSheet( QStringLiteral( "QgsFilterLineEdit { background-color: #ffd85d; }" ) );
327 break;
328 }
329 }
330 }
331}
332
334{
335 if ( !mQgsWidget || !layer() )
336 return;
337
338 QgsExpressionContext expressionContext( layer()->createExpressionContext() );
339 expressionContext.setFeature( formFeature() );
341 if ( context().parentFormFeature().isValid() )
342 {
343 expressionContext.appendScope( QgsExpressionContextUtils::parentFormScope( context().parentFormFeature() ) );
344 }
345
346 mQgsWidget->fileWidget()->setExpressionContext( expressionContext );
347}
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()
This string is used to represent the value NULL throughout QGIS.
void widgetValueChanged(const QString &attribute, const QVariant &value, bool attributeChanged)
Notifies about changes of attributes.
QgsFeature currentFormFeature() const
Returns the feature that is currently displayed in the form with all the changes received on editing ...
Manages an editor widget Widget and wrapper share the same parent.
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.
void setFeature(const QgsFeature &feature) override
Will be called when the feature changes.
ConstraintResult constraintResult
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.
Class for 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 setDocumentPath(const QVariant &documentPath)
void setMessageBar(QgsMessageBar *messageBar)
Set messageBar to report messages.
void setStorageAuthConfigId(const QString &authCfg)
Sets the authentication configuration ID to be used for the current external storage (if defined)
QVariant documentPath(QVariant::Type type=QVariant::String) const
documentPath returns the path of the current document in the widget
QgsExternalStorageFileWidget * fileWidget()
Returns file widget to allow its configuration.
void setStorageType(const QString &storageType)
Set storageType storage type unique identifier as defined in QgsExternalStorageRegistry or null QStri...
void setRelativeStorage(QgsFileWidget::RelativeStorage relativeStorage)
Configures if paths are handled absolute or relative and if relative, which should be the base path.
void setDocumentViewerHeight(int height)
setDocumentViewerWidth set the height of the document viewer.
void setDocumentViewerContent(QgsExternalResourceWidget::DocumentViewerContent content)
setDocumentViewerContent defines the type of content to be shown. Widget will be adapted accordingly
void setDefaultRoot(const QString &defaultRoot)
Configures the base path which should be used if the relativeStorage property is set to QgsFileWidget...
void setDocumentViewerWidth(int width)
setDocumentViewerWidth set the width of the document viewer.
void setFileWidgetVisible(bool visible)
Sets the visibility of the file widget in the layout.
void setReadOnly(bool readOnly)
defines if the widget is readonly
void setExpressionContext(const QgsExpressionContext &context)
Set expression context to be used when for storage URL expression evaluation.
void setStorageUrlExpression(const QString &urlExpression)
Set urlExpression expression, which once evaluated, provide the URL used to store selected documents.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
StorageMode
The StorageMode enum determines if the file picker should pick files or directories.
Definition: qgsfilewidget.h:67
@ GetFile
Select a single file.
Definition: qgsfilewidget.h:68
void setFullUrl(bool fullUrl)
Sets whether links shown use the full path.
RelativeStorage
The RelativeStorage enum determines if path is absolute, relative to the current project path or rela...
Definition: qgsfilewidget.h:79
void setStorageMode(QgsFileWidget::StorageMode storageMode)
Sets the widget's storage mode (i.e.
void setUseLink(bool useLink)
Sets whether the file path will be shown as a link.
void setFileWidgetButtonVisible(bool visible)
Sets whether the tool button is visible.
void setFilter(const QString &filter)
setFilter sets the filter used by the model to filters.
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.
Definition: qgsmessagebar.h:61
bool isActive(int key) const final
Returns true if the collection contains an active property with the specified key.
bool loadVariant(const QVariant &configuration, const QgsPropertiesDefinition &definitions) final
Loads this property collection from a QVariantMap, wrapped in a QVariant.
bool hasActiveProperties() const final
Returns true if the collection has any active properties, or false if all properties within the colle...
QgsProperty property(int key) const final
Returns a matching property from the collection, if one exists.
QString asExpression() const
Returns an expression string representing the state of the property, or an empty string if the proper...
QString expressionString() const
Returns the expression used for the property value.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
Represents a vector layer which manages a vector based data sets.
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:5776
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:5775
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:5111