QGIS API Documentation  3.9.0-Master (224899f119)
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
6  email : denis.rouzaud@gmail.com
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"
27 
28 
29 QgsExternalResourceWidgetWrapper::QgsExternalResourceWidgetWrapper( QgsVectorLayer *layer, int fieldIdx, QWidget *editor, QWidget *parent )
30  : QgsEditorWidgetWrapper( layer, fieldIdx, editor, parent )
31 
32 {
33 }
34 
36 {
37  if ( mQgsWidget )
38  {
39  return mQgsWidget->documentPath( field().type() );
40  }
41 
42  if ( mLineEdit )
43  {
44  if ( mLineEdit->text().isEmpty() || mLineEdit->text() == QgsApplication::nullRepresentation() )
45  {
46  return QVariant( field().type() );
47  }
48  else
49  {
50  return mLineEdit->text();
51  }
52  }
53 
54  return QVariant( field().type() );
55 }
56 
58 {
59  if ( mLineEdit )
60  {
61  whileBlocking( mLineEdit )->clear();
62  }
63 
64  if ( mLabel )
65  {
66  mLabel->clear();
67  }
68 
69  if ( mQgsWidget )
70  {
71  whileBlocking( mQgsWidget )->setDocumentPath( QString() );
72  }
73 }
74 
76 {
77  return mLineEdit || mLabel || mQgsWidget;
78 }
79 
81 {
82  if ( mQgsWidget && mPropertyCollection.hasActiveProperties() )
83  {
85  expressionContext.setFeature( feature );
86  bool ok = false;
87 
89  {
90  QString path = mPropertyCollection.valueAsString( QgsEditorWidgetWrapper::RootPath, expressionContext, QString(), &ok );
91  if ( ok )
92  {
93  mQgsWidget->setDefaultRoot( path );
94  }
95  }
97  {
98  QString dvcString = mPropertyCollection.valueAsString( QgsEditorWidgetWrapper::DocumentViewerContent, expressionContext, QStringLiteral( "NoContent" ), &ok );
99  if ( ok )
100  {
102  if ( dvcString.compare( QLatin1String( "image" ), Qt::CaseInsensitive ) == 0 )
103  {
105  }
106  else if ( dvcString.compare( QLatin1String( "web" ), Qt::CaseInsensitive ) == 0 )
107  {
109  }
110  else
111  {
113  }
114  mQgsWidget->setDocumentViewerContent( dvc );
115  }
116  }
117  }
118 
120 }
121 
123 {
124  return new QgsExternalResourceWidget( parent );
125 }
126 
128 {
129  mLineEdit = qobject_cast<QLineEdit *>( editor );
130  mLabel = qobject_cast<QLabel *>( editor );
131  mQgsWidget = qobject_cast<QgsExternalResourceWidget *>( editor );
132 
133  if ( mLineEdit )
134  {
135  QgsFilterLineEdit *fle = qobject_cast<QgsFilterLineEdit *>( editor );
136  if ( fle )
137  {
139  }
140  }
141  else
142  mLineEdit = editor->findChild<QLineEdit *>();
143 
144  if ( mQgsWidget )
145  {
146  mQgsWidget->fileWidget()->setStorageMode( QgsFileWidget::GetFile );
147 
148  QVariantMap cfg = config();
149 
150  if ( cfg.contains( QStringLiteral( "UseLink" ) ) )
151  {
152  mQgsWidget->fileWidget()->setUseLink( cfg.value( QStringLiteral( "UseLink" ) ).toBool() );
153  }
154  if ( cfg.contains( QStringLiteral( "FullUrl" ) ) )
155  {
156  mQgsWidget->fileWidget()->setFullUrl( cfg.value( QStringLiteral( "FullUrl" ) ).toBool() );
157  }
158 
159  mPropertyCollection.loadVariant( cfg.value( QStringLiteral( "PropertyCollection" ) ), propertyDefinitions() );
161  {
162  mQgsWidget->setDefaultRoot( cfg.value( QStringLiteral( "DefaultRoot" ) ).toString() );
163  }
164  if ( cfg.contains( QStringLiteral( "StorageMode" ) ) )
165  {
166  mQgsWidget->fileWidget()->setStorageMode( ( QgsFileWidget::StorageMode )cfg.value( QStringLiteral( "StorageMode" ) ).toInt() );
167  }
168  if ( cfg.contains( QStringLiteral( "RelativeStorage" ) ) )
169  {
170  mQgsWidget->setRelativeStorage( ( QgsFileWidget::RelativeStorage )cfg.value( QStringLiteral( "RelativeStorage" ) ).toInt() );
171  }
172  if ( cfg.contains( QStringLiteral( "FileWidget" ) ) )
173  {
174  mQgsWidget->setFileWidgetVisible( cfg.value( QStringLiteral( "FileWidget" ) ).toBool() );
175  }
176  if ( cfg.contains( QStringLiteral( "FileWidgetButton" ) ) )
177  {
178  // Prevent from showing the button in the attribute table, see https://github.com/qgis/QGIS/issues/26948
179  mQgsWidget->fileWidget()->setFileWidgetButtonVisible( cfg.value( QStringLiteral( "FileWidgetButton" ) ).toBool() && context().formMode() != QgsAttributeEditorContext::Popup );
180  }
181  if ( cfg.contains( QStringLiteral( "DocumentViewer" ) ) )
182  {
183  mQgsWidget->setDocumentViewerContent( ( QgsExternalResourceWidget::DocumentViewerContent )cfg.value( QStringLiteral( "DocumentViewer" ) ).toInt() );
184  }
185  if ( cfg.contains( QStringLiteral( "FileWidgetFilter" ) ) )
186  {
187  mQgsWidget->fileWidget()->setFilter( cfg.value( QStringLiteral( "FileWidgetFilter" ) ).toString() );
188  }
189  }
190 
191  if ( mLineEdit )
192  connect( mLineEdit, &QLineEdit::textChanged, this, [ = ]( const QString & value )
193  {
195  emit valueChanged( value );
197  emit valuesChanged( value );
198  } );
199 
200 }
201 
202 void QgsExternalResourceWidgetWrapper::updateValues( const QVariant &value, const QVariantList & )
203 {
204  if ( mLineEdit )
205  {
206  if ( value.isNull() )
207  {
208  mLineEdit->setText( QgsApplication::nullRepresentation() );
209  }
210  else
211  {
212  mLineEdit->setText( value.toString() );
213  }
214  }
215 
216  if ( mLabel )
217  {
218  mLabel->setText( value.toString() );
220  emit valueChanged( value.toString() );
222  emit valuesChanged( value.toString() ); // emit signal that value has changed, do not do it for other widgets
223  }
224 
225  if ( mQgsWidget )
226  {
227  if ( value.isNull() )
228  {
230  }
231  else
232  {
233  mQgsWidget->setDocumentPath( value.toString() );
234  }
235  }
236 
237 }
238 
240 {
241  if ( mLineEdit )
242  mLineEdit->setReadOnly( !enabled );
243 
244  if ( mQgsWidget )
245  mQgsWidget->setReadOnly( !enabled );
246 }
247 
248 void QgsExternalResourceWidgetWrapper::updateConstraintWidgetStatus()
249 {
250  if ( mLineEdit )
251  {
252  if ( !constraintResultVisible() )
253  {
254  widget()->setStyleSheet( QString() );
255  }
256  else
257  {
258  switch ( constraintResult() )
259  {
261  mLineEdit->setStyleSheet( QString() );
262  break;
263 
265  mLineEdit->setStyleSheet( QStringLiteral( "QgsFilterLineEdit { background-color: #dd7777; }" ) );
266  break;
267 
269  mLineEdit->setStyleSheet( QStringLiteral( "QgsFilterLineEdit { background-color: #ffd85d; }" ) );
270  break;
271  }
272  }
273  }
274 }
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the editor widget property definitions.
void initWidget(QWidget *editor) override
This method should initialize the editor widget with runtime data.
QgsExternalResourceWidgetWrapper(QgsVectorLayer *layer, int fieldIdx, QWidget *editor=nullptr, QWidget *parent=nullptr)
Constructor for QgsExternalResourceWidgetWrapper.
Widget failed at least one soft (non-enforced) constraint.
QVariant documentPath(QVariant::Type type=QVariant::String) const
documentPath returns the path of the current document in the widget
QgsField field() const
Access the field.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Manages an editor widget Widget and wrapper share the same parent.
bool valid() const override
Returns true if the widget has been properly initialized.
void setDocumentViewerContent(QgsExternalResourceWidget::DocumentViewerContent content)
setDocumentViewerContent defines the type of content to be shown. Widget will be adapted accordingly ...
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:634
Widget failed at least one hard (enforced) constraint.
void valuesChanged(const QVariant &value, const QVariantList &additionalFieldValues=QVariantList())
Emit this signal, whenever the value changed.
QVariantMap config() const
Returns the whole config.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
void setDocumentPath(const QVariant &documentPath)
bool constraintResultVisible() const
Returns whether the constraint result is visible.
Root path for external resource.
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key.
QVariant value() const override
Will be used to access the widget&#39;s value.
A widget was opened as a popup (e.g. attribute table editor widget)
QgsPropertyCollection mPropertyCollection
Data defined property collection.
Select a single file.
Definition: qgsfilewidget.h:65
void setFeature(const QgsFeature &feature) override
Will be called when the feature changes.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
bool loadVariant(const QVariant &configuration, const QgsPropertiesDefinition &definitions) override
Loads this property collection from a QVariantMap, wrapped in a QVariant.
void setDefaultRoot(const QString &defaultRoot)
Configures the base path which should be used if the relativeStorage property is set to QgsFileWidget...
QLineEdit subclass with built in support for clearing the widget&#39;s value and handling custom null val...
static QString nullRepresentation()
This string is used to represent the value NULL throughout QGIS.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer&#39;s project and layer.
Document type for external resource.
void showIndeterminateState() override
Sets the widget to display in an indeterminate "mixed value" state.
const QgsAttributeEditorContext & context() const
Returns information about the context in which this widget is shown.
FormMode formMode() const
Returns the form mode.
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:635
StorageMode
The StorageMode enum determines if the file picker should pick files or directories.
Definition: qgsfilewidget.h:63
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...
Widget passed constraints successfully.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:212
QWidget * createWidget(QWidget *parent) override
This method should create a new widget with the provided parent.
Widget to display file path with a push button for an "open file" dialog It can also be used to displ...
ConstraintResult constraintResult() const
Returns the constraint result, which is the current result of the constraint on the widget influencin...
bool hasActiveProperties() const override
Returns true if the collection has any active properties, or false if all properties within the colle...
QWidget * widget()
Access the widget managed by this wrapper.
void setNullValue(const QString &nullValue)
Sets the string representation for null values in the widget.
void setReadOnly(bool readOnly)
defines if the widget is readonly
QgsVectorLayer * layer() const
Returns the vector layer associated with the widget.
Represents a vector layer which manages a vector based data sets.
Q_DECL_DEPRECATED void valueChanged(const QVariant &value)
Emit this signal, whenever the value changed.
void setFeature(const QgsFeature &feature) override
RelativeStorage
The RelativeStorage enum determines if path is absolute, relative to the current project path or rela...
Definition: qgsfilewidget.h:74