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