QGIS API Documentation 3.41.0-Master (3440c17df1d)
Loading...
Searching...
No Matches
qgsexternalresourceconfigdlg.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsexternalresourceconfigdlg.cpp
3 --------------------------------------
4 Date : 2015-11-26
5 Copyright : (C) 2015 Médéric Ribreux
6 Email : mederic.ribreux at medspx dot fr
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#include "moc_qgsexternalresourceconfigdlg.cpp"
19#include "qgsproject.h"
20#include "qgssettings.h"
22#include "qgsapplication.h"
23#include "qgsvectorlayer.h"
26#include "qgsexternalstorage.h"
30
31#include <QFileDialog>
32#include <QComboBox>
33
35
37 : QgsEditorConfigWidget( vl, fieldIdx, parent )
38{
39 setupUi( this );
40
41 mStorageType->addItem( tr( "Select Existing file" ), QString() );
43 {
44 mStorageType->addItem( storage->displayName(), storage->type() );
45 }
46
47 mExternalStorageGroupBox->setVisible( false );
48
50 mStorageUrlPropertyOverrideButton->registerVisibleWidget( mStorageUrlExpression );
51 mStorageUrlPropertyOverrideButton->registerExpressionWidget( mStorageUrlExpression );
52 mStorageUrlPropertyOverrideButton->registerVisibleWidget( mStorageUrl, false );
53 mStorageUrlPropertyOverrideButton->registerExpressionContextGenerator( this );
54
55 // By default, uncheck some options
56 mUseLink->setChecked( false );
57 mFullUrl->setChecked( false );
58
59 const QString defpath = QgsProject::instance()->fileName().isEmpty() ? QDir::homePath() : QFileInfo( QgsProject::instance()->absoluteFilePath() ).path();
60
61 mRootPath->setPlaceholderText( QgsSettings().value( QStringLiteral( "/UI/lastExternalResourceWidgetDefaultPath" ), QDir::toNativeSeparators( QDir::cleanPath( defpath ) ) ).toString() );
62
63 connect( mRootPathButton, &QToolButton::clicked, this, &QgsExternalResourceConfigDlg::chooseDefaultPath );
64
66 mRootPathPropertyOverrideButton->registerVisibleWidget( mRootPathExpression );
67 mRootPathPropertyOverrideButton->registerExpressionWidget( mRootPathExpression );
68 mRootPathPropertyOverrideButton->registerVisibleWidget( mRootPath, false );
69 mRootPathPropertyOverrideButton->registerEnabledWidget( mRootPathButton, false );
70
71 initializeDataDefinedButton( mDocumentViewerContentPropertyOverrideButton, QgsEditorWidgetWrapper::Property::DocumentViewerContent );
72 mDocumentViewerContentPropertyOverrideButton->registerVisibleWidget( mDocumentViewerContentExpression );
73 mDocumentViewerContentPropertyOverrideButton->registerExpressionWidget( mDocumentViewerContentExpression );
74 mDocumentViewerContentPropertyOverrideButton->registerEnabledWidget( mDocumentViewerContentComboBox, false );
75
76 // Activate Relative Default Path option only if Default Path is set
77 connect( mRootPath, &QLineEdit::textChanged, this, &QgsExternalResourceConfigDlg::enableRelativeDefault );
78 connect( mRootPathExpression, &QLineEdit::textChanged, this, &QgsExternalResourceConfigDlg::enableRelativeDefault );
79
80 // Add storage modes
81 mStorageModeCbx->addItem( tr( "File Paths" ), QgsFileWidget::GetFile );
82 mStorageModeCbx->addItem( tr( "Directory Paths" ), QgsFileWidget::GetDirectory );
83
84 // Add storage path options
85 mStoragePathCbx->addItem( tr( "Absolute Path" ), QgsFileWidget::Absolute );
86 mStoragePathCbx->addItem( tr( "Relative to Project Path" ), QgsFileWidget::RelativeProject );
87 mStoragePathCbx->addItem( tr( "Relative to Default Path" ), QgsFileWidget::RelativeDefaultPath );
88 enableCbxItem( mStoragePathCbx, 2, false );
89
90 connect( mStorageType, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsExternalResourceConfigDlg::changeStorageType );
91 connect( mFileWidgetGroupBox, &QGroupBox::toggled, this, &QgsEditorConfigWidget::changed );
92 connect( mFileWidgetButtonGroupBox, &QGroupBox::toggled, this, &QgsEditorConfigWidget::changed );
93 connect( mFileWidgetFilterLineEdit, &QLineEdit::textChanged, this, &QgsEditorConfigWidget::changed );
94 connect( mUseLink, &QGroupBox::toggled, this, &QgsEditorConfigWidget::changed );
95 connect( mFullUrl, &QAbstractButton::toggled, this, &QgsEditorConfigWidget::changed );
96 connect( mRootPath, &QLineEdit::textChanged, this, &QgsEditorConfigWidget::changed );
97 connect( mStorageModeCbx, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsEditorConfigWidget::changed );
98 connect( mStoragePathCbx, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsEditorConfigWidget::changed );
99 connect( mDocumentViewerGroupBox, &QGroupBox::toggled, this, &QgsEditorConfigWidget::changed );
100 connect( mDocumentViewerContentComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [ = ]( int )
101 {
102 const QgsExternalResourceWidget::DocumentViewerContent content = static_cast<QgsExternalResourceWidget::DocumentViewerContent>( mDocumentViewerContentComboBox->currentData().toInt() );
103 const bool hasSizeSettings = ( content != QgsExternalResourceWidget::NoContent && content != QgsExternalResourceWidget::Audio );
104 mDocumentViewerContentSettingsWidget->setEnabled( hasSizeSettings );
105 } );
106 connect( mDocumentViewerHeight, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ), this, &QgsEditorConfigWidget::changed );
107 connect( mDocumentViewerWidth, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ), this, &QgsEditorConfigWidget::changed );
108 connect( mStorageUrlExpression, &QLineEdit::textChanged, this, &QgsEditorConfigWidget::changed );
109
110 mDocumentViewerContentComboBox->addItem( tr( "No Content" ), QgsExternalResourceWidget::NoContent );
111 mDocumentViewerContentComboBox->addItem( tr( "Image" ), QgsExternalResourceWidget::Image );
112 mDocumentViewerContentComboBox->addItem( tr( "Audio" ), QgsExternalResourceWidget::Audio );
113 mDocumentViewerContentComboBox->addItem( tr( "Video" ), QgsExternalResourceWidget::Video );
114 mDocumentViewerContentComboBox->addItem( tr( "Web View" ), QgsExternalResourceWidget::Web );
115}
116
117void QgsExternalResourceConfigDlg::chooseDefaultPath()
118{
119 QString dir;
120 if ( !mRootPath->text().isEmpty() )
121 {
122 dir = mRootPath->text();
123 }
124 else
125 {
126 const QString path = QFileInfo( QgsProject::instance()->absoluteFilePath() ).path();
127 dir = QgsSettings().value( QStringLiteral( "/UI/lastExternalResourceWidgetDefaultPath" ), QDir::toNativeSeparators( QDir::cleanPath( path ) ) ).toString();
128 }
129
130 const QString rootName = QFileDialog::getExistingDirectory( this, tr( "Select a Directory" ), dir, QFileDialog::Options() );
131
132 if ( !rootName.isNull() )
133 mRootPath->setText( rootName );
134}
135
136void QgsExternalResourceConfigDlg::enableCbxItem( QComboBox *comboBox, int index, bool enabled )
137{
138 // https://stackoverflow.com/a/62261745
139 const auto *model = qobject_cast<QStandardItemModel *>( comboBox->model() );
140 assert( model );
141 if ( !model )
142 return;
143
144 auto *item = model->item( index );
145 assert( item );
146 if ( !item )
147 return;
148 item->setEnabled( enabled );
149}
150
151void QgsExternalResourceConfigDlg::enableRelativeDefault()
152{
153 bool relativePathActive = false;
154
155 if ( mRootPathPropertyOverrideButton->isActive() )
156 {
157 if ( !mRootPathExpression->text().isEmpty() )
158 relativePathActive = true;
159 }
160 else
161 {
162 if ( !mRootPath->text().isEmpty() )
163 relativePathActive = true;
164 }
165 // Activate (or not) the RelativeDefault item if default path
166 enableCbxItem( mStoragePathCbx, 2, relativePathActive );
167}
168
170{
171 QVariantMap cfg;
172
173 cfg.insert( QStringLiteral( "StorageType" ), mStorageType->currentData() );
174 cfg.insert( QStringLiteral( "StorageAuthConfigId" ), mAuthSettingsProtocol->configId() );
175 if ( !mStorageUrl->text().isEmpty() )
176 cfg.insert( QStringLiteral( "StorageUrl" ), mStorageUrl->text() );
177
178 cfg.insert( QStringLiteral( "FileWidget" ), mFileWidgetGroupBox->isChecked() );
179 cfg.insert( QStringLiteral( "FileWidgetButton" ), mFileWidgetButtonGroupBox->isChecked() );
180 cfg.insert( QStringLiteral( "FileWidgetFilter" ), mFileWidgetFilterLineEdit->text() );
181
182 if ( mUseLink->isChecked() )
183 {
184 cfg.insert( QStringLiteral( "UseLink" ), mUseLink->isChecked() );
185 if ( mFullUrl->isChecked() )
186 cfg.insert( QStringLiteral( "FullUrl" ), mFullUrl->isChecked() );
187 }
188
189 cfg.insert( QStringLiteral( "PropertyCollection" ), mPropertyCollection.toVariant( QgsWidgetWrapper::propertyDefinitions() ) );
190
191 if ( !mRootPath->text().isEmpty() )
192 cfg.insert( QStringLiteral( "DefaultRoot" ), mRootPath->text() );
193
194 if ( !mStorageType->currentIndex() )
195 {
196 // Save Storage Mode
197 cfg.insert( QStringLiteral( "StorageMode" ), mStorageModeCbx->currentData().toInt() );
198 // Save Relative Paths option
199 cfg.insert( QStringLiteral( "RelativeStorage" ), mStoragePathCbx->currentData().toInt() );
200 }
201 else
202 {
203 // Only file mode and absolute paths are supported for external storage
204 cfg.insert( QStringLiteral( "StorageMode" ), static_cast<int>( QgsFileWidget::GetFile ) );
205 cfg.insert( QStringLiteral( "RelativeStorage" ), static_cast<int>( QgsFileWidget::Absolute ) );
206 }
207
208 cfg.insert( QStringLiteral( "DocumentViewer" ), mDocumentViewerContentComboBox->currentData().toInt() );
209 cfg.insert( QStringLiteral( "DocumentViewerHeight" ), mDocumentViewerHeight->value() );
210 cfg.insert( QStringLiteral( "DocumentViewerWidth" ), mDocumentViewerWidth->value() );
211
212 return cfg;
213}
214
215
217{
218 if ( config.contains( QStringLiteral( "StorageType" ) ) )
219 {
220 const int index = mStorageType->findData( config.value( QStringLiteral( "StorageType" ) ) );
221 if ( index >= 0 )
222 mStorageType->setCurrentIndex( index );
223 }
224
225 mAuthSettingsProtocol->setConfigId( config.value( QStringLiteral( "StorageAuthConfigId" ) ).toString() );
226 mStorageUrl->setText( config.value( QStringLiteral( "StorageUrl" ) ).toString() );
227
228 if ( config.contains( QStringLiteral( "FileWidget" ) ) )
229 {
230 mFileWidgetGroupBox->setChecked( config.value( QStringLiteral( "FileWidget" ) ).toBool() );
231 }
232 if ( config.contains( QStringLiteral( "FileWidget" ) ) )
233 {
234 mFileWidgetButtonGroupBox->setChecked( config.value( QStringLiteral( "FileWidgetButton" ) ).toBool() );
235 }
236 if ( config.contains( QStringLiteral( "FileWidgetFilter" ) ) )
237 {
238 mFileWidgetFilterLineEdit->setText( config.value( QStringLiteral( "FileWidgetFilter" ) ).toString() );
239 }
240
241 if ( config.contains( QStringLiteral( "UseLink" ) ) )
242 {
243 mUseLink->setChecked( config.value( QStringLiteral( "UseLink" ) ).toBool() );
244 if ( config.contains( QStringLiteral( "FullUrl" ) ) )
245 mFullUrl->setChecked( true );
246 }
247
248 mPropertyCollection.loadVariant( config.value( QStringLiteral( "PropertyCollection" ) ), QgsWidgetWrapper::propertyDefinitions() );
250
251 mRootPath->setText( config.value( QStringLiteral( "DefaultRoot" ) ).toString() );
252
253 // relative storage
254 if ( config.contains( QStringLiteral( "RelativeStorage" ) ) )
255 {
256 const int relative = config.value( QStringLiteral( "RelativeStorage" ) ).toInt();
257 mStoragePathCbx->setCurrentIndex( relative );
258 }
259
260 // set storage mode
261 if ( config.contains( QStringLiteral( "StorageMode" ) ) )
262 {
263 const int mode = config.value( QStringLiteral( "StorageMode" ) ).toInt();
264 mStorageModeCbx->setCurrentIndex( mode );
265 }
266
267 // Document viewer
268 if ( config.contains( QStringLiteral( "DocumentViewer" ) ) )
269 {
270 const QgsExternalResourceWidget::DocumentViewerContent content = ( QgsExternalResourceWidget::DocumentViewerContent )config.value( QStringLiteral( "DocumentViewer" ) ).toInt();
271 const int idx = mDocumentViewerContentComboBox->findData( content );
272 if ( idx >= 0 )
273 {
274 mDocumentViewerContentComboBox->setCurrentIndex( idx );
275 }
276 if ( config.contains( QStringLiteral( "DocumentViewerHeight" ) ) )
277 {
278 mDocumentViewerHeight->setValue( config.value( QStringLiteral( "DocumentViewerHeight" ) ).toInt() );
279 }
280 if ( config.contains( QStringLiteral( "DocumentViewerWidth" ) ) )
281 {
282 mDocumentViewerWidth->setValue( config.value( QStringLiteral( "DocumentViewerWidth" ) ).toInt() );
283 }
284 }
285}
286
299
300void QgsExternalResourceConfigDlg::changeStorageType( int storageTypeIndex )
301{
302 // first one in combo box is not an external storage
303 mExternalStorageGroupBox->setVisible( storageTypeIndex > 0 );
304
305 // for now, we store only files in external storage
306 mStorageModeCbx->setVisible( !storageTypeIndex );
307 mStorageModeLbl->setVisible( !storageTypeIndex );
308
309 // Absolute path are mandatory when using external storage
310 mStoragePathCbx->setVisible( !storageTypeIndex );
311 mStoragePathLbl->setVisible( !storageTypeIndex );
312
313 emit changed();
314}
static QgsExternalStorageRegistry * externalStorageRegistry()
Returns registry of available external storage implementations.
This class should be subclassed for every configurable editor widget type.
void updateDataDefinedButtons()
Updates all property override buttons to reflect the widgets's current properties.
QgsPropertyCollection mPropertyCollection
Temporary property collection for config widgets.
void initializeDataDefinedButton(QgsPropertyOverrideButton *button, QgsWidgetWrapper::Property key)
Registers a property override button, setting up its initial value, connections and description.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
void changed()
Emitted when the configuration of the widget is changed.
int fieldIdx() const
Access the field index.
Single scope for storing variables and functions for use within a QgsExpressionContext.
QStringList variableNames() const
Returns a list of variable names contained within the scope.
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...
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user.
void setConfig(const QVariantMap &config) override
Update the configuration widget to represent the given configuration.
QVariantMap config() override
Create a configuration from the current GUI state.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
QgsExternalResourceConfigDlg(QgsVectorLayer *vl, int fieldIdx, QWidget *parent=nullptr)
Constructor for QgsExternalResourceConfigDlg.
static QgsExpressionContextScope * createFileWidgetScope()
Creates and Returns an expression context scope specific to QgsExternalStorageFileWidget It defines t...
QList< QgsExternalStorage * > externalStorages() const
Returns a list of registered project storage implementations.
Abstract interface for external storage - to be implemented by various backends and registered in Qgs...
@ GetFile
Select a single file.
@ GetDirectory
Select a directory.
static QgsProject * instance()
Returns the QgsProject singleton instance.
QString fileName
Definition qgsproject.h:110
QVariant toVariant(const QgsPropertiesDefinition &definitions) const final
Saves this property collection to a QVariantMap, wrapped in a QVariant.
bool loadVariant(const QVariant &configuration, const QgsPropertiesDefinition &definitions) final
Loads this property collection from a QVariantMap, wrapped in a QVariant.
This class is a composition of two QSettings instances:
Definition qgssettings.h:64
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Represents a vector layer which manages a vector based data sets.
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the editor widget property definitions.
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.