QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
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
17
18#include "qgsgui.h"
19#include "qgshelp.h"
22#include "qgssettings.h"
23#include "qgsvectorlayer.h"
24
25#include <QListWidgetItem>
26#include <QMessageBox>
27#include <QPushButton>
28
29#include "moc_qgsmaplayersavestyledialog.cpp"
30
32 : QDialog( parent )
33 , mLayer( layer )
34{
35 setupUi( this );
37
38 QgsSettings settings;
39
40 const QString myLastUsedDir = settings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString();
41
42 // save style type combobox
43 connect( mStyleTypeComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this, layer]( int ) {
47 mSaveToDbWidget->setVisible( type == QgsLayerPropertiesDialog::DatasourceDatabase );
48 mSaveToSldWidget->setVisible( type == QgsLayerPropertiesDialog::SLD && layer->type() == Qgis::LayerType::Vector && static_cast<QgsVectorLayer *>( layer )->geometryType() == Qgis::GeometryType::Polygon );
49 mStyleCategoriesListView->setEnabled( type != QgsLayerPropertiesDialog::SLD );
50 mFileWidget->setFilter( type == QgsLayerPropertiesDialog::QML ? tr( "QGIS Layer Style File (*.qml)" ) : tr( "SLD File (*.sld)" ) );
51 updateSaveButtonState();
52 } );
53
54 // Save to DB setup
55 connect( mDbStyleNameEdit, &QLineEdit::textChanged, this, &QgsMapLayerSaveStyleDialog::updateSaveButtonState );
56 mDbStyleDescriptionEdit->setTabChangesFocus( true );
57 setTabOrder( mDbStyleNameEdit, mDbStyleDescriptionEdit );
58 setTabOrder( mDbStyleDescriptionEdit, mDbStyleUseAsDefault );
59 mDbStyleUIFileWidget->setDefaultRoot( myLastUsedDir );
60 mDbStyleUIFileWidget->setFilter( tr( "Qt Designer UI file (*.ui)" ) );
61 connect( mDbStyleUIFileWidget, &QgsFileWidget::fileChanged, this, &QgsMapLayerSaveStyleDialog::readUiFileContent );
62 connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsMapLayerSaveStyleDialog::showHelp );
63
64 // save to file setup
65 connect( mFileWidget, &QgsFileWidget::fileChanged, this, &QgsMapLayerSaveStyleDialog::updateSaveButtonState );
66 mFileWidget->setStorageMode( QgsFileWidget::SaveFile );
67 mFileWidget->setDefaultRoot( myLastUsedDir );
68 connect( mFileWidget, &QgsFileWidget::fileChanged, this, []( const QString &path ) {
69 QgsSettings settings;
70 const QFileInfo tmplFileInfo( path );
71 settings.setValue( QStringLiteral( "style/lastStyleDir" ), tmplFileInfo.absolutePath() );
72 } );
73
74 // fill style categories
75 mModel = new QgsMapLayerStyleCategoriesModel( mLayer->type(), this );
76 const QgsMapLayer::StyleCategories lastStyleCategories = settings.flagValue( QStringLiteral( "style/lastStyleCategories" ), QgsMapLayer::AllStyleCategories );
77 mModel->setCategories( lastStyleCategories );
78 mStyleCategoriesListView->setModel( mModel );
79 mStyleCategoriesListView->setWordWrap( true );
80 mStyleCategoriesListView->setItemDelegate( new QgsCategoryDisplayLabelDelegate( this ) );
81
82 // select and deselect all categories
83 connect( mSelectAllButton, &QPushButton::clicked, this, &QgsMapLayerSaveStyleDialog::selectAll );
84 connect( mDeselectAllButton, &QPushButton::clicked, this, &QgsMapLayerSaveStyleDialog::deselectAll );
85 connect( mInvertSelectionButton, &QPushButton::clicked, this, &QgsMapLayerSaveStyleDialog::invertSelection );
86
87 mStyleCategoriesListView->adjustSize();
88
89 setupMultipleStyles();
90}
91
92void QgsMapLayerSaveStyleDialog::invertSelection()
93{
94 for ( int i = 0; i < mModel->rowCount( QModelIndex() ); i++ )
95 {
96 QModelIndex index = mModel->index( i, 0 );
97 Qt::CheckState currentState = Qt::CheckState( mModel->data( index, Qt::CheckStateRole ).toInt() );
98 Qt::CheckState newState = ( currentState == Qt::Checked ) ? Qt::Unchecked : Qt::Checked;
99 mModel->setData( index, newState, Qt::CheckStateRole );
100 }
101}
102
103void QgsMapLayerSaveStyleDialog::selectAll()
104{
105 for ( int i = 0; i < mModel->rowCount( QModelIndex() ); i++ )
106 {
107 QModelIndex index = mModel->index( i, 0 );
108 mModel->setData( index, Qt::Checked, Qt::CheckStateRole );
109 }
110}
111
112void QgsMapLayerSaveStyleDialog::deselectAll()
113{
114 for ( int i = 0; i < mModel->rowCount( QModelIndex() ); i++ )
115 {
116 QModelIndex index = mModel->index( i, 0 );
117 mModel->setData( index, Qt::Unchecked, Qt::CheckStateRole );
118 }
119}
120
121void QgsMapLayerSaveStyleDialog::populateStyleComboBox()
122{
123 mStyleTypeComboBox->clear();
124 mStyleTypeComboBox->addItem( tr( "As QGIS QML style file" ), QgsLayerPropertiesDialog::QML );
125 mStyleTypeComboBox->addItem( tr( "As SLD style file" ), QgsLayerPropertiesDialog::SLD );
126
127 if ( mLayer->dataProvider()->styleStorageCapabilities().testFlag( Qgis::ProviderStyleStorageCapability::SaveToDatabase ) )
128 mStyleTypeComboBox->addItem( tr( "In datasource database" ), QgsLayerPropertiesDialog::DatasourceDatabase );
129
130 if ( mSaveOnlyCurrentStyle )
131 mStyleTypeComboBox->addItem( tr( "As default in local user database" ), QgsLayerPropertiesDialog::UserDatabase );
132}
133
135{
136 QgsSettings().setFlagValue( QStringLiteral( "style/lastStyleCategories" ), styleCategories() );
137 QDialog::accept();
138}
139
140void QgsMapLayerSaveStyleDialog::updateSaveButtonState()
141{
143 bool enabled { false };
144 switch ( type )
145 {
147 if ( saveOnlyCurrentStyle() )
148 {
149 enabled = !mDbStyleNameEdit->text().isEmpty();
150 }
151 else
152 {
153 enabled = true;
154 }
155 break;
158 enabled = !mFileWidget->filePath().isEmpty();
159 break;
161 enabled = true;
162 break;
163 }
164 buttonBox->button( QDialogButtonBox::Ok )->setEnabled( enabled );
165}
166
168{
169 SaveToDbSettings settings;
170 settings.name = mDbStyleNameEdit->text();
171 settings.description = mDbStyleDescriptionEdit->toPlainText();
172 settings.isDefault = mDbStyleUseAsDefault->isChecked();
173 settings.uiFileContent = mUiFileContent;
174 return settings;
175}
176
178{
179 return mFileWidget->filePath();
180}
181
183{
184 return mModel->categories();
185}
186
191
192void QgsMapLayerSaveStyleDialog::readUiFileContent( const QString &filePath )
193{
194 QgsSettings myQSettings; // where we keep last used filter in persistent state
195 mUiFileContent = QString();
196
197 if ( filePath.isNull() )
198 {
199 return;
200 }
201
202 const QFileInfo myFI( filePath );
203 QFile uiFile( myFI.filePath() );
204
205 const QString myPath = myFI.path();
206 myQSettings.setValue( QStringLiteral( "style/lastStyleDir" ), myPath );
207
208 if ( uiFile.open( QIODevice::ReadOnly ) )
209 {
210 const QString content( uiFile.readAll() );
211 QDomDocument doc;
212
213 if ( !doc.setContent( content ) || doc.documentElement().tagName().compare( QLatin1String( "ui" ) ) )
214 {
215 QMessageBox::warning( this, tr( "Attach UI File" ), tr( "The selected file does not appear to be a valid Qt Designer UI file." ) );
216 return;
217 }
218 mUiFileContent = content;
219 }
220}
221
222void QgsMapLayerSaveStyleDialog::setupMultipleStyles()
223{
224 // Show/hide part of the UI according to multiple style support
225 if ( !mSaveOnlyCurrentStyle )
226 {
227 const QgsMapLayerStyleManager *styleManager { mLayer->styleManager() };
228 const QStringList constStyles = styleManager->styles();
229 for ( const QString &name : constStyles )
230 {
231 QListWidgetItem *item = new QListWidgetItem( name, mStylesWidget );
232 item->setCheckState( Qt::CheckState::Checked );
233 // Highlight the current style
234 if ( name == styleManager->currentStyle() )
235 {
236 item->setToolTip( tr( "Current style" ) );
237 QFont font { item->font() };
238 font.setItalic( true );
239 item->setFont( font );
240 }
241 mStylesWidget->addItem( item );
242 }
243 mDbStyleNameEdit->setToolTip( tr( "Leave blank to use style names or set the base name (an incremental number will be automatically appended)" ) );
244 }
245 else
246 {
247 mDbStyleNameEdit->setToolTip( QString() );
248 }
249
250 mStylesWidget->setVisible( !mSaveOnlyCurrentStyle );
251 mStylesWidgetLabel->setVisible( !mSaveOnlyCurrentStyle );
252
253 mDbStyleDescriptionEdit->setVisible( mSaveOnlyCurrentStyle );
254 descriptionLabel->setVisible( mSaveOnlyCurrentStyle );
255 mDbStyleUseAsDefault->setVisible( mSaveOnlyCurrentStyle );
256
257 populateStyleComboBox();
258}
259
261{
262 return mSaveOnlyCurrentStyle;
263}
264
266{
267 if ( mSaveOnlyCurrentStyle != saveOnlyCurrentStyle )
268 {
269 mSaveOnlyCurrentStyle = saveOnlyCurrentStyle;
270 setupMultipleStyles();
271 }
272}
273
275{
276 return mStylesWidget;
277}
278
280{
282
283 if ( mStyleTypeComboBox->currentData() == QgsLayerPropertiesDialog::SLD && mSldExportPng->isChecked() )
284 {
285 options.setFlag( Qgis::SldExportOption::Png );
286 }
287 return options;
288}
289
290void QgsMapLayerSaveStyleDialog::showHelp()
291{
292 QgsHelp::openHelp( QStringLiteral( "introduction/general_tools.html#save-and-share-layer-properties" ) );
293}
@ Png
Export complex styles to separate PNG files for better compatibility with OGC servers.
Definition qgis.h:699
@ Polygon
Polygons.
Definition qgis.h:361
@ Vector
Vector layer.
Definition qgis.h:191
QFlags< SldExportOption > SldExportOptions
Definition qgis.h:702
A label delegate able to display HTML encoded content.
@ SaveFile
Select a single new or pre-existing file.
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:221
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition qgshelp.cpp:38
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.
QVariant data(const QModelIndex &index, int role) const override
bool setData(const QModelIndex &index, const QVariant &value, int role) override
int rowCount(const QModelIndex &=QModelIndex()) const override
QString currentStyle() const
Returns name of the current style.
QStringList styles() const
Returns list of all defined style names.
Base class for all map layer types.
Definition qgsmaplayer.h:80
Qgis::LayerType type
Definition qgsmaplayer.h:90
QFlags< StyleCategory > StyleCategories
Stores settings for use within QGIS.
Definition qgssettings.h:65
T flagValue(const QString &key, const T &defaultValue, const Section section=NoSection)
Returns the setting value for a setting based on a flag.
void setFlagValue(const QString &key, const T &value, const Section section=NoSection)
Set the value of a setting based on a flag.
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 dataset.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.