QGIS API Documentation 3.99.0-Master (2fe06baccd8)
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
18#include "qgsapplication.h"
23#include "qgsexternalstorage.h"
26#include "qgsproject.h"
28#include "qgssettings.h"
29#include "qgsvectorlayer.h"
30
31#include <QComboBox>
32#include <QFileDialog>
33
34#include "moc_qgsexternalresourceconfigdlg.cpp"
35
37
39 : QgsEditorConfigWidget( vl, fieldIdx, parent )
40{
41 setupUi( this );
42
43 mStorageType->addItem( tr( "Select Existing file" ), QString() );
44 for ( QgsExternalStorage *storage : QgsApplication::externalStorageRegistry()->externalStorages() )
45 {
46 mStorageType->addItem( storage->displayName(), storage->type() );
47 }
48 mAuthSettingsProtocol->removeBasicSettings();
49 mExternalStorageGroupBox->setVisible( false );
50
52 mStorageUrlPropertyOverrideButton->registerVisibleWidget( mStorageUrlExpression );
53 mStorageUrlPropertyOverrideButton->registerExpressionWidget( mStorageUrlExpression );
54 mStorageUrlPropertyOverrideButton->registerVisibleWidget( mStorageUrl, false );
55 mStorageUrlPropertyOverrideButton->registerExpressionContextGenerator( this );
56
57 // By default, uncheck some options
58 mUseLink->setChecked( false );
59 mFullUrl->setChecked( false );
60
61 const QString defpath = QgsProject::instance()->fileName().isEmpty() ? QDir::homePath() : QFileInfo( QgsProject::instance()->absoluteFilePath() ).path();
62
63 mRootPath->setPlaceholderText( QgsSettings().value( QStringLiteral( "/UI/lastExternalResourceWidgetDefaultPath" ), QDir::toNativeSeparators( QDir::cleanPath( defpath ) ) ).toString() );
64
65 connect( mRootPathButton, &QToolButton::clicked, this, &QgsExternalResourceConfigDlg::chooseDefaultPath );
66
68 mRootPathPropertyOverrideButton->registerVisibleWidget( mRootPathExpression );
69 mRootPathPropertyOverrideButton->registerExpressionWidget( mRootPathExpression );
70 mRootPathPropertyOverrideButton->registerVisibleWidget( mRootPath, false );
71 mRootPathPropertyOverrideButton->registerEnabledWidget( mRootPathButton, false );
72
73 initializeDataDefinedButton( mDocumentViewerContentPropertyOverrideButton, QgsEditorWidgetWrapper::Property::DocumentViewerContent );
74 mDocumentViewerContentPropertyOverrideButton->registerVisibleWidget( mDocumentViewerContentExpression );
75 mDocumentViewerContentPropertyOverrideButton->registerExpressionWidget( mDocumentViewerContentExpression );
76 mDocumentViewerContentPropertyOverrideButton->registerEnabledWidget( mDocumentViewerContentComboBox, false );
77
78 // Activate Relative Default Path option only if Default Path is set
79 connect( mRootPath, &QLineEdit::textChanged, this, &QgsExternalResourceConfigDlg::enableRelativeDefault );
80 connect( mRootPathExpression, &QLineEdit::textChanged, this, &QgsExternalResourceConfigDlg::enableRelativeDefault );
81
82 // Add storage modes
83 mStorageModeCbx->addItem( tr( "File Paths" ), QgsFileWidget::GetFile );
84 mStorageModeCbx->addItem( tr( "Directory Paths" ), QgsFileWidget::GetDirectory );
85
86 // Add storage path options
87 mStoragePathCbx->addItem( tr( "Absolute Path" ), QgsFileWidget::Absolute );
88 mStoragePathCbx->addItem( tr( "Relative to Project Path" ), QgsFileWidget::RelativeProject );
89 mStoragePathCbx->addItem( tr( "Relative to Default Path" ), QgsFileWidget::RelativeDefaultPath );
90 enableCbxItem( mStoragePathCbx, 2, false );
91
92 connect( mStorageType, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsExternalResourceConfigDlg::changeStorageType );
93 connect( mFileWidgetGroupBox, &QGroupBox::toggled, this, &QgsEditorConfigWidget::changed );
94 connect( mFileWidgetButtonGroupBox, &QGroupBox::toggled, this, &QgsEditorConfigWidget::changed );
95 connect( mFileWidgetFilterLineEdit, &QLineEdit::textChanged, this, &QgsEditorConfigWidget::changed );
96 connect( mUseLink, &QGroupBox::toggled, this, &QgsEditorConfigWidget::changed );
97 connect( mFullUrl, &QAbstractButton::toggled, this, &QgsEditorConfigWidget::changed );
98 connect( mRootPath, &QLineEdit::textChanged, this, &QgsEditorConfigWidget::changed );
99 connect( mStorageModeCbx, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsEditorConfigWidget::changed );
100 connect( mStoragePathCbx, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsEditorConfigWidget::changed );
101 connect( mDocumentViewerGroupBox, &QGroupBox::toggled, this, &QgsEditorConfigWidget::changed );
102 connect( mDocumentViewerContentComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
103 const QgsExternalResourceWidget::DocumentViewerContent content = static_cast<QgsExternalResourceWidget::DocumentViewerContent>( mDocumentViewerContentComboBox->currentData().toInt() );
104 const bool hasSizeSettings = ( content != QgsExternalResourceWidget::NoContent && content != QgsExternalResourceWidget::Audio );
105 mDocumentViewerContentSettingsWidget->setEnabled( hasSizeSettings );
106 } );
107 connect( mDocumentViewerHeight, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ), this, &QgsEditorConfigWidget::changed );
108 connect( mDocumentViewerWidth, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ), this, &QgsEditorConfigWidget::changed );
109 connect( mStorageUrlExpression, &QLineEdit::textChanged, this, &QgsEditorConfigWidget::changed );
110
111 mDocumentViewerContentComboBox->addItem( tr( "No Content" ), QgsExternalResourceWidget::NoContent );
112 mDocumentViewerContentComboBox->addItem( tr( "Image" ), QgsExternalResourceWidget::Image );
113 mDocumentViewerContentComboBox->addItem( tr( "Audio" ), QgsExternalResourceWidget::Audio );
114 mDocumentViewerContentComboBox->addItem( tr( "Video" ), QgsExternalResourceWidget::Video );
115 mDocumentViewerContentComboBox->addItem( tr( "Web View" ), QgsExternalResourceWidget::Web );
116}
117
118void QgsExternalResourceConfigDlg::chooseDefaultPath()
119{
120 QString dir;
121 if ( !mRootPath->text().isEmpty() )
122 {
123 dir = mRootPath->text();
124 }
125 else
126 {
127 const QString path = QFileInfo( QgsProject::instance()->absoluteFilePath() ).path();
128 dir = QgsSettings().value( QStringLiteral( "/UI/lastExternalResourceWidgetDefaultPath" ), QDir::toNativeSeparators( QDir::cleanPath( path ) ) ).toString();
129 }
130
131 const QString rootName = QFileDialog::getExistingDirectory( this, tr( "Select a Directory" ), dir, QFileDialog::Options() );
132
133 if ( !rootName.isNull() )
134 mRootPath->setText( rootName );
135}
136
137void QgsExternalResourceConfigDlg::enableCbxItem( QComboBox *comboBox, int index, bool enabled )
138{
139 // https://stackoverflow.com/a/62261745
140 const auto *model = qobject_cast<QStandardItemModel *>( comboBox->model() );
141 assert( model );
142 if ( !model )
143 return;
144
145 auto *item = model->item( index );
146 assert( item );
147 if ( !item )
148 return;
149 item->setEnabled( enabled );
150}
151
152void QgsExternalResourceConfigDlg::enableRelativeDefault()
153{
154 bool relativePathActive = false;
155
156 if ( mRootPathPropertyOverrideButton->isActive() )
157 {
158 if ( !mRootPathExpression->text().isEmpty() )
159 relativePathActive = true;
160 }
161 else
162 {
163 if ( !mRootPath->text().isEmpty() )
164 relativePathActive = true;
165 }
166 // Activate (or not) the RelativeDefault item if default path
167 enableCbxItem( mStoragePathCbx, 2, relativePathActive );
168}
169
171{
172 QVariantMap cfg;
173
174 cfg.insert( QStringLiteral( "StorageType" ), mStorageType->currentData() );
175 cfg.insert( QStringLiteral( "StorageAuthConfigId" ), mAuthSettingsProtocol->configId() );
176 if ( !mStorageUrl->text().isEmpty() )
177 cfg.insert( QStringLiteral( "StorageUrl" ), mStorageUrl->text() );
178
179 cfg.insert( QStringLiteral( "FileWidget" ), mFileWidgetGroupBox->isChecked() );
180 cfg.insert( QStringLiteral( "FileWidgetButton" ), mFileWidgetButtonGroupBox->isChecked() );
181 cfg.insert( QStringLiteral( "FileWidgetFilter" ), mFileWidgetFilterLineEdit->text() );
182
183 if ( mUseLink->isChecked() )
184 {
185 cfg.insert( QStringLiteral( "UseLink" ), mUseLink->isChecked() );
186 if ( mFullUrl->isChecked() )
187 cfg.insert( QStringLiteral( "FullUrl" ), mFullUrl->isChecked() );
188 }
189
190 cfg.insert( QStringLiteral( "PropertyCollection" ), mPropertyCollection.toVariant( QgsWidgetWrapper::propertyDefinitions() ) );
191
192 if ( !mRootPath->text().isEmpty() )
193 cfg.insert( QStringLiteral( "DefaultRoot" ), mRootPath->text() );
194
195 if ( !mStorageType->currentIndex() )
196 {
197 // Save Storage Mode
198 cfg.insert( QStringLiteral( "StorageMode" ), mStorageModeCbx->currentData().toInt() );
199 // Save Relative Paths option
200 cfg.insert( QStringLiteral( "RelativeStorage" ), mStoragePathCbx->currentData().toInt() );
201 }
202 else
203 {
204 // Only file mode and absolute paths are supported for external storage
205 cfg.insert( QStringLiteral( "StorageMode" ), static_cast<int>( QgsFileWidget::GetFile ) );
206 cfg.insert( QStringLiteral( "RelativeStorage" ), static_cast<int>( QgsFileWidget::Absolute ) );
207 }
208
209 cfg.insert( QStringLiteral( "DocumentViewer" ), mDocumentViewerContentComboBox->currentData().toInt() );
210 cfg.insert( QStringLiteral( "DocumentViewerHeight" ), mDocumentViewerHeight->value() );
211 cfg.insert( QStringLiteral( "DocumentViewerWidth" ), mDocumentViewerWidth->value() );
212
213 return cfg;
214}
215
216
218{
219 if ( config.contains( QStringLiteral( "StorageType" ) ) )
220 {
221 const int index = mStorageType->findData( config.value( QStringLiteral( "StorageType" ) ) );
222 if ( index >= 0 )
223 mStorageType->setCurrentIndex( index );
224 }
225
226 mAuthSettingsProtocol->setConfigId( config.value( QStringLiteral( "StorageAuthConfigId" ) ).toString() );
227 mStorageUrl->setText( config.value( QStringLiteral( "StorageUrl" ) ).toString() );
228
229 if ( config.contains( QStringLiteral( "FileWidget" ) ) )
230 {
231 mFileWidgetGroupBox->setChecked( config.value( QStringLiteral( "FileWidget" ) ).toBool() );
232 }
233 if ( config.contains( QStringLiteral( "FileWidget" ) ) )
234 {
235 mFileWidgetButtonGroupBox->setChecked( config.value( QStringLiteral( "FileWidgetButton" ) ).toBool() );
236 }
237 if ( config.contains( QStringLiteral( "FileWidgetFilter" ) ) )
238 {
239 mFileWidgetFilterLineEdit->setText( config.value( QStringLiteral( "FileWidgetFilter" ) ).toString() );
240 }
241
242 if ( config.contains( QStringLiteral( "UseLink" ) ) )
243 {
244 mUseLink->setChecked( config.value( QStringLiteral( "UseLink" ) ).toBool() );
245 if ( config.contains( QStringLiteral( "FullUrl" ) ) )
246 mFullUrl->setChecked( true );
247 }
248
249 mPropertyCollection.loadVariant( config.value( QStringLiteral( "PropertyCollection" ) ), QgsWidgetWrapper::propertyDefinitions() );
251
252 mRootPath->setText( config.value( QStringLiteral( "DefaultRoot" ) ).toString() );
253
254 // relative storage
255 if ( config.contains( QStringLiteral( "RelativeStorage" ) ) )
256 {
257 const int relative = config.value( QStringLiteral( "RelativeStorage" ) ).toInt();
258 mStoragePathCbx->setCurrentIndex( relative );
259 }
260
261 // set storage mode
262 if ( config.contains( QStringLiteral( "StorageMode" ) ) )
263 {
264 const int mode = config.value( QStringLiteral( "StorageMode" ) ).toInt();
265 mStorageModeCbx->setCurrentIndex( mode );
266 }
267
268 // Document viewer
269 if ( config.contains( QStringLiteral( "DocumentViewer" ) ) )
270 {
271 const QgsExternalResourceWidget::DocumentViewerContent content = ( QgsExternalResourceWidget::DocumentViewerContent ) config.value( QStringLiteral( "DocumentViewer" ) ).toInt();
272 const int idx = mDocumentViewerContentComboBox->findData( content );
273 if ( idx >= 0 )
274 {
275 mDocumentViewerContentComboBox->setCurrentIndex( idx );
276 }
277 if ( config.contains( QStringLiteral( "DocumentViewerHeight" ) ) )
278 {
279 mDocumentViewerHeight->setValue( config.value( QStringLiteral( "DocumentViewerHeight" ) ).toInt() );
280 }
281 if ( config.contains( QStringLiteral( "DocumentViewerWidth" ) ) )
282 {
283 mDocumentViewerWidth->setValue( config.value( QStringLiteral( "DocumentViewerWidth" ) ).toInt() );
284 }
285 }
286}
287
300
301void QgsExternalResourceConfigDlg::changeStorageType( int storageTypeIndex )
302{
303 // first one in combo box is not an external storage
304 mExternalStorageGroupBox->setVisible( storageTypeIndex > 0 );
305
306 // for now, we store only files in external storage
307 mStorageModeCbx->setVisible( !storageTypeIndex );
308 mStorageModeLbl->setVisible( !storageTypeIndex );
309
310 // Absolute path are mandatory when using external storage
311 mStoragePathCbx->setVisible( !storageTypeIndex );
312 mStoragePathLbl->setVisible( !storageTypeIndex );
313
314 emit changed();
315}
static QgsExternalStorageRegistry * externalStorageRegistry()
Returns registry of available external storage implementations.
QgsEditorConfigWidget(QgsVectorLayer *vl, int fieldIdx, QWidget *parent)
Create a new configuration widget.
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...
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:113
Stores settings for use within QGIS.
Definition qgssettings.h:65
Represents a vector layer which manages a vector based dataset.
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the editor widget property definitions.
@ DocumentViewerContent
Document type for external resource.
@ StorageUrl
Storage URL for external resource.
@ RootPath
Root path for external resource.