QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsmaplayersavestyledialog.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmaplayersavestyledialog.h
3 --------------------------------------
4 Date : September 2018
5 Copyright : (C) 2018 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
16#include <QListWidgetItem>
17#include <QMessageBox>
18#include <QPushButton>
19
21#include "qgssettings.h"
22#include "qgshelp.h"
23#include "qgsgui.h"
26#include "qgsvectorlayer.h"
27
29 : QDialog( parent )
30 , mLayer( layer )
31{
32 setupUi( this );
34
35 QgsSettings settings;
36
37 const QString myLastUsedDir = settings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString();
38
39 // save style type combobox
40 connect( mStyleTypeComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, [ = ]( int )
41 {
45 mSaveToDbWidget->setVisible( type == QgsLayerPropertiesDialog::DatasourceDatabase );
46 mSaveToSldWidget->setVisible( type == QgsLayerPropertiesDialog::SLD && layer->type() == Qgis::LayerType::Vector && static_cast<QgsVectorLayer *>( layer )->geometryType() == Qgis::GeometryType::Polygon );
47 mStyleCategoriesListView->setEnabled( type != QgsLayerPropertiesDialog::SLD );
48 mFileWidget->setFilter( type == QgsLayerPropertiesDialog::QML ? tr( "QGIS Layer Style File (*.qml)" ) : tr( "SLD File (*.sld)" ) );
49 updateSaveButtonState();
50 } );
51
52 // Save to DB setup
53 connect( mDbStyleNameEdit, &QLineEdit::textChanged, this, &QgsMapLayerSaveStyleDialog::updateSaveButtonState );
54 mDbStyleDescriptionEdit->setTabChangesFocus( true );
55 setTabOrder( mDbStyleNameEdit, mDbStyleDescriptionEdit );
56 setTabOrder( mDbStyleDescriptionEdit, mDbStyleUseAsDefault );
57 mDbStyleUIFileWidget->setDefaultRoot( myLastUsedDir );
58 mDbStyleUIFileWidget->setFilter( tr( "Qt Designer UI file (*.ui)" ) );
59 connect( mDbStyleUIFileWidget, &QgsFileWidget::fileChanged, this, &QgsMapLayerSaveStyleDialog::readUiFileContent );
60 connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsMapLayerSaveStyleDialog::showHelp );
61
62 // save to file setup
63 connect( mFileWidget, &QgsFileWidget::fileChanged, this, &QgsMapLayerSaveStyleDialog::updateSaveButtonState );
64 mFileWidget->setStorageMode( QgsFileWidget::SaveFile );
65 mFileWidget->setDefaultRoot( myLastUsedDir );
66 connect( mFileWidget, &QgsFileWidget::fileChanged, this, [ = ]( const QString & path )
67 {
68 QgsSettings settings;
69 const QFileInfo tmplFileInfo( path );
70 settings.setValue( QStringLiteral( "style/lastStyleDir" ), tmplFileInfo.absolutePath() );
71 } );
72
73 // fill style categories
74 mModel = new QgsMapLayerStyleCategoriesModel( mLayer->type(), this );
75 const QgsMapLayer::StyleCategories lastStyleCategories = settings.flagValue( QStringLiteral( "style/lastStyleCategories" ), QgsMapLayer::AllStyleCategories );
76 mModel->setCategories( lastStyleCategories );
77 mStyleCategoriesListView->setModel( mModel );
78
79 // select and deselect all categories
80 connect( mSelectAllButton, &QPushButton::clicked, this, &QgsMapLayerSaveStyleDialog::selectAll );
81 connect( mDeselectAllButton, &QPushButton::clicked, this, &QgsMapLayerSaveStyleDialog::deselectAll );
82 connect( mInvertSelectionButton, &QPushButton::clicked, this, &QgsMapLayerSaveStyleDialog::invertSelection );
83
84 mStyleCategoriesListView->adjustSize();
85
86 setupMultipleStyles();
87
88}
89
90void QgsMapLayerSaveStyleDialog::invertSelection()
91{
92 for ( int i = 0; i < mModel->rowCount( QModelIndex() ); i++ )
93 {
94 QModelIndex index = mModel->index( i, 0 );
95 Qt::CheckState currentState = Qt::CheckState( mModel->data( index, Qt::CheckStateRole ).toInt() );
96 Qt::CheckState newState = ( currentState == Qt::Checked ) ? Qt::Unchecked : Qt::Checked;
97 mModel->setData( index, newState, Qt::CheckStateRole );
98 }
99}
100
101void QgsMapLayerSaveStyleDialog::selectAll()
102{
103 for ( int i = 0; i < mModel->rowCount( QModelIndex() ); i++ )
104 {
105 QModelIndex index = mModel->index( i, 0 );
106 mModel->setData( index, Qt::Checked, Qt::CheckStateRole );
107 }
108}
109
110void QgsMapLayerSaveStyleDialog::deselectAll()
111{
112 for ( int i = 0; i < mModel->rowCount( QModelIndex() ); i++ )
113 {
114 QModelIndex index = mModel->index( i, 0 );
115 mModel->setData( index, Qt::Unchecked, Qt::CheckStateRole );
116 }
117}
118
119void QgsMapLayerSaveStyleDialog::populateStyleComboBox()
120{
121 mStyleTypeComboBox->clear();
122 mStyleTypeComboBox->addItem( tr( "As QGIS QML style file" ), QgsLayerPropertiesDialog::QML );
123 mStyleTypeComboBox->addItem( tr( "As SLD style file" ), QgsLayerPropertiesDialog::SLD );
124
126 mStyleTypeComboBox->addItem( tr( "In datasource database" ), QgsLayerPropertiesDialog::DatasourceDatabase );
127
128 if ( mSaveOnlyCurrentStyle )
129 mStyleTypeComboBox->addItem( tr( "As default in local user database" ), QgsLayerPropertiesDialog::UserDatabase );
130}
131
133{
134 QgsSettings().setFlagValue( QStringLiteral( "style/lastStyleCategories" ), styleCategories() );
135 QDialog::accept();
136}
137
138void QgsMapLayerSaveStyleDialog::updateSaveButtonState()
139{
141 bool enabled { false };
142 switch ( type )
143 {
145 if ( saveOnlyCurrentStyle( ) )
146 {
147 enabled = ! mDbStyleNameEdit->text().isEmpty();
148 }
149 else
150 {
151 enabled = true;
152 }
153 break;
156 enabled = ! mFileWidget->filePath().isEmpty();
157 break;
159 enabled = true;
160 break;
161 }
162 buttonBox->button( QDialogButtonBox::Ok )->setEnabled( enabled );
163}
164
166{
167 SaveToDbSettings settings;
168 settings.name = mDbStyleNameEdit->text();
169 settings.description = mDbStyleDescriptionEdit->toPlainText();
170 settings.isDefault = mDbStyleUseAsDefault->isChecked();
171 settings.uiFileContent = mUiFileContent;
172 return settings;
173}
174
176{
177 return mFileWidget->filePath();
178}
179
181{
182 return mModel->categories();
183}
184
186{
187 return mStyleTypeComboBox->currentData().value<QgsLayerPropertiesDialog::StyleType>();
188}
189
190void QgsMapLayerSaveStyleDialog::readUiFileContent( const QString &filePath )
191{
192 QgsSettings myQSettings; // where we keep last used filter in persistent state
193 mUiFileContent = QString();
194
195 if ( filePath.isNull() )
196 {
197 return;
198 }
199
200 const QFileInfo myFI( filePath );
201 QFile uiFile( myFI.filePath() );
202
203 const QString myPath = myFI.path();
204 myQSettings.setValue( QStringLiteral( "style/lastStyleDir" ), myPath );
205
206 if ( uiFile.open( QIODevice::ReadOnly ) )
207 {
208 const QString content( uiFile.readAll() );
209 QDomDocument doc;
210
211 if ( !doc.setContent( content ) || doc.documentElement().tagName().compare( QLatin1String( "ui" ) ) )
212 {
213 QMessageBox::warning( this, tr( "Attach UI File" ),
214 tr( "The selected file does not appear to be a valid Qt Designer UI file." ) );
215 return;
216 }
217 mUiFileContent = content;
218 }
219}
220
221void QgsMapLayerSaveStyleDialog::setupMultipleStyles()
222{
223 // Show/hide part of the UI according to multiple style support
224 if ( ! mSaveOnlyCurrentStyle )
225 {
226 const QgsMapLayerStyleManager *styleManager { mLayer->styleManager() };
227 const QStringList constStyles = styleManager->styles();
228 for ( const QString &name : constStyles )
229 {
230 QListWidgetItem *item = new QListWidgetItem( name, mStylesWidget );
231 item->setCheckState( Qt::CheckState::Checked );
232 // Highlight the current style
233 if ( name == styleManager->currentStyle() )
234 {
235 item->setToolTip( tr( "Current style" ) );
236 QFont font { item->font() };
237 font.setItalic( true );
238 item->setFont( font );
239 }
240 mStylesWidget->addItem( item );
241 }
242 mDbStyleNameEdit->setToolTip( tr( "Leave blank to use style names or set the base name (an incremental number will be automatically appended)" ) );
243 }
244 else
245 {
246 mDbStyleNameEdit->setToolTip( QString() );
247 }
248
249 mStylesWidget->setVisible( ! mSaveOnlyCurrentStyle );
250 mStylesWidgetLabel->setVisible( ! mSaveOnlyCurrentStyle );
251
252 mDbStyleDescriptionEdit->setVisible( mSaveOnlyCurrentStyle );
253 descriptionLabel->setVisible( mSaveOnlyCurrentStyle );
254 mDbStyleUseAsDefault->setVisible( mSaveOnlyCurrentStyle );
255
256 populateStyleComboBox();
257}
258
260{
261 return mSaveOnlyCurrentStyle;
262}
263
265{
266 if ( mSaveOnlyCurrentStyle != saveOnlyCurrentStyle )
267 {
268 mSaveOnlyCurrentStyle = saveOnlyCurrentStyle;
269 setupMultipleStyles();
270 }
271}
272
274{
275 return mStylesWidget;
276}
277
279{
281
282 if ( mStyleTypeComboBox->currentData( ) == QgsLayerPropertiesDialog::SLD && mSldExportPng->isChecked() )
283 {
284 options.setFlag( Qgis::SldExportOption::Png );
285 }
286 return options;
287}
288
289void QgsMapLayerSaveStyleDialog::showHelp()
290{
291 QgsHelp::openHelp( QStringLiteral( "introduction/general_tools.html#save-and-share-layer-properties" ) );
292}
@ Png
Export complex styles to separate PNG files for better compatibility with OGC servers.
@ Polygon
Polygons.
@ Vector
Vector layer.
QFlags< SldExportOption > SldExportOptions
Definition: qgis.h:493
virtual Qgis::ProviderStyleStorageCapabilities styleStorageCapabilities() const
Returns the style storage capabilities.
@ SaveFile
Select a single new or pre-existing file.
Definition: qgsfilewidget.h:71
void fileChanged(const QString &path)
Emitted whenever the current file or directory path is changed.
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
Definition: qgsgui.cpp:194
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:39
QString outputFilePath() const
Returns the selected file output path.
Qgis::SldExportOptions sldExportOptions() const
Returns the SLD export options.
SaveToDbSettings saveToDbSettings() const
Returns the database settings for saving the style in the DB.
void setSaveOnlyCurrentStyle(bool saveCurrentStyle)
Sets whether the user only allowed to save the current style.
bool saveOnlyCurrentStyle() const
Returns whether the user only allowed to save the current style.
QgsMapLayer::StyleCategories styleCategories() const
Returns the available style categories.
QgsLayerPropertiesDialog::StyleType currentStyleType() const
Returns the selected style storage type.
QgsMapLayerSaveStyleDialog(QgsMapLayer *layer, QWidget *parent=nullptr)
Constructor.
const QListWidget * stylesWidget()
Returns the styles list widget.
Model for layer style categories.
QVariant data(const QModelIndex &index, int role) const override
bool setData(const QModelIndex &index, const QVariant &value, int role) override
QgsMapLayer::StyleCategories categories() const
Returns the categories as defined in the model.
int rowCount(const QModelIndex &=QModelIndex()) const override
Management of styles for use with one map layer.
QStringList styles() const
Returns list of all defined style names.
Base class for all map layer types.
Definition: qgsmaplayer.h:75
Qgis::LayerType type
Definition: qgsmaplayer.h:82
QFlags< StyleCategory > StyleCategories
Definition: qgsmaplayer.h:188
QgsMapLayerStyleManager * styleManager() const
Gets access to the layer's style manager.
virtual Q_INVOKABLE QgsDataProvider * dataProvider()
Returns the layer's data provider, it may be nullptr.
@ AllStyleCategories
Definition: qgsmaplayer.h:184
This class is a composition of two QSettings instances:
Definition: qgssettings.h:64
T flagValue(const QString &key, const T &defaultValue, const Section section=NoSection)
Returns the setting value for a setting based on a flag.
Definition: qgssettings.h:341
void setFlagValue(const QString &key, const T &value, const Section section=NoSection)
Set the value of a setting based on a flag.
Definition: qgssettings.h:405
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.