QGIS API Documentation  3.22.4-Białowieża (ce8e65e95e)
qgsvectorlayersavestyledialog.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsvectorlayersavestyledialog.h
3  --------------------------------------
4  Date : September 2018
5  Copyright : (C) 2018 by Denis Rouzaud
6  Email : [email protected]
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 
20 #include "qgsvectorlayer.h"
21 #include "qgssettings.h"
22 #include "qgshelp.h"
23 #include "qgsgui.h"
25 
27  : QDialog( parent )
28  , mLayer( layer )
29 {
30  setupUi( this );
32 
33  QgsSettings settings;
34 
35  QString providerName = mLayer->providerType();
36  if ( providerName == QLatin1String( "ogr" ) )
37  {
38  providerName = mLayer->dataProvider()->storageType();
39  if ( providerName == QLatin1String( "GPKG" ) )
40  providerName = QStringLiteral( "GeoPackage" );
41  }
42 
43  const QString myLastUsedDir = settings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString();
44 
45  // save style type combobox
46  connect( mStyleTypeComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, [ = ]( int )
47  {
49  mSaveToFileWidget->setVisible( type != QgsVectorLayerProperties::DB );
50  mSaveToDbWidget->setVisible( type == QgsVectorLayerProperties::DB );
51  mStyleCategoriesListView->setEnabled( type == QgsVectorLayerProperties::QML );
52  mFileWidget->setFilter( type == QgsVectorLayerProperties::QML ? tr( "QGIS Layer Style File (*.qml)" ) : tr( "SLD File (*.sld)" ) );
53  updateSaveButtonState();
54  } );
55  mStyleTypeComboBox->addItem( tr( "As QGIS QML Style File" ), QgsVectorLayerProperties::QML );
56  mStyleTypeComboBox->addItem( tr( "As SLD Style File" ), QgsVectorLayerProperties::SLD );
58  mStyleTypeComboBox->addItem( tr( "In Database (%1)" ).arg( providerName ), QgsVectorLayerProperties::DB );
59 
60  // Save to DB setup
61  connect( mDbStyleNameEdit, &QLineEdit::textChanged, this, &QgsVectorLayerSaveStyleDialog::updateSaveButtonState );
62  mDbStyleDescriptionEdit->setTabChangesFocus( true );
63  setTabOrder( mDbStyleNameEdit, mDbStyleDescriptionEdit );
64  setTabOrder( mDbStyleDescriptionEdit, mDbStyleUseAsDefault );
65  mDbStyleUIFileWidget->setDefaultRoot( myLastUsedDir );
66  mDbStyleUIFileWidget->setFilter( tr( "Qt Designer UI file (*.ui)" ) );
67  connect( mDbStyleUIFileWidget, &QgsFileWidget::fileChanged, this, &QgsVectorLayerSaveStyleDialog::readUiFileContent );
68  connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsVectorLayerSaveStyleDialog::showHelp );
69 
70  // save to file setup
71  connect( mFileWidget, &QgsFileWidget::fileChanged, this, &QgsVectorLayerSaveStyleDialog::updateSaveButtonState );
72  mFileWidget->setStorageMode( QgsFileWidget::SaveFile );
73  mFileWidget->setDefaultRoot( myLastUsedDir );
74  connect( mFileWidget, &QgsFileWidget::fileChanged, this, [ = ]( const QString & path )
75  {
76  QgsSettings settings;
77  const QFileInfo tmplFileInfo( path );
78  settings.setValue( QStringLiteral( "style/lastStyleDir" ), tmplFileInfo.absolutePath() );
79  } );
80 
81  // fill style categories
82  mModel = new QgsMapLayerStyleCategoriesModel( mLayer->type(), this );
83  const QgsMapLayer::StyleCategories lastStyleCategories = settings.flagValue( QStringLiteral( "style/lastStyleCategories" ), QgsMapLayer::AllStyleCategories );
84  mModel->setCategories( lastStyleCategories );
85  mStyleCategoriesListView->setModel( mModel );
86 
87  mStyleCategoriesListView->adjustSize();
88 
89  setupMultipleStyles();
90 
91 }
92 
94 {
95  QgsSettings().setFlagValue( QStringLiteral( "style/lastStyleCategories" ), styleCategories() );
96  QDialog::accept();
97 }
98 
99 void QgsVectorLayerSaveStyleDialog::updateSaveButtonState()
100 {
102  bool enabled { false };
103  switch ( type )
104  {
106  if ( saveOnlyCurrentStyle( ) )
107  {
108  enabled = ! mDbStyleNameEdit->text().isEmpty();
109  }
110  else
111  {
112  enabled = true;
113  }
114  break;
117  enabled = ! mFileWidget->filePath().isEmpty();
118  break;
119  }
120  buttonBox->button( QDialogButtonBox::Ok )->setEnabled( enabled );
121 }
122 
124 {
125  SaveToDbSettings settings;
126  settings.name = mDbStyleNameEdit->text();
127  settings.description = mDbStyleDescriptionEdit->toPlainText();
128  settings.isDefault = mDbStyleUseAsDefault->isChecked();
129  settings.uiFileContent = mUiFileContent;
130  return settings;
131 }
132 
134 {
135  return mFileWidget->filePath();
136 }
137 
138 QgsMapLayer::StyleCategories QgsVectorLayerSaveStyleDialog::styleCategories() const
139 {
140  return mModel->categories();
141 }
142 
144 {
145  return mStyleTypeComboBox->currentData().value<QgsVectorLayerProperties::StyleType>();
146 }
147 
148 void QgsVectorLayerSaveStyleDialog::readUiFileContent( const QString &filePath )
149 {
150  QgsSettings myQSettings; // where we keep last used filter in persistent state
151  mUiFileContent = QString();
152 
153  if ( filePath.isNull() )
154  {
155  return;
156  }
157 
158  const QFileInfo myFI( filePath );
159  QFile uiFile( myFI.filePath() );
160 
161  const QString myPath = myFI.path();
162  myQSettings.setValue( QStringLiteral( "style/lastStyleDir" ), myPath );
163 
164  if ( uiFile.open( QIODevice::ReadOnly ) )
165  {
166  const QString content( uiFile.readAll() );
167  QDomDocument doc;
168 
169  if ( !doc.setContent( content ) || doc.documentElement().tagName().compare( QLatin1String( "ui" ) ) )
170  {
171  QMessageBox::warning( this, tr( "Attach UI File" ),
172  tr( "The selected file does not appear to be a valid Qt Designer UI file." ) );
173  return;
174  }
175  mUiFileContent = content;
176  }
177 }
178 
179 void QgsVectorLayerSaveStyleDialog::setupMultipleStyles()
180 {
181  // Show/hide part of the UI according to multiple style support
182  if ( ! mSaveOnlyCurrentStyle )
183  {
184  const QgsMapLayerStyleManager *styleManager { mLayer->styleManager() };
185  const QStringList constStyles = styleManager->styles();
186  for ( const QString &name : constStyles )
187  {
188  QListWidgetItem *item = new QListWidgetItem( name, mStylesWidget );
189  item->setCheckState( Qt::CheckState::Checked );
190  // Highlight the current style
191  if ( name == styleManager->currentStyle() )
192  {
193  item->setToolTip( tr( "Current style" ) );
194  QFont font { item->font() };
195  font.setItalic( true );
196  item->setFont( font );
197  }
198  mStylesWidget->addItem( item );
199  }
200  mDbStyleNameEdit->setToolTip( tr( "Leave blank to use style names or set the base name (an incremental number will be automatically appended)" ) );
201  }
202  else
203  {
204  mDbStyleNameEdit->setToolTip( QString() );
205  }
206 
207  mStylesWidget->setVisible( ! mSaveOnlyCurrentStyle );
208  mStylesWidgetLabel->setVisible( ! mSaveOnlyCurrentStyle );
209 
210  mDbStyleDescriptionEdit->setVisible( mSaveOnlyCurrentStyle );
211  descriptionLabel->setVisible( mSaveOnlyCurrentStyle );
212  mDbStyleUseAsDefault->setVisible( mSaveOnlyCurrentStyle );
213 }
214 
216 {
217  return mSaveOnlyCurrentStyle;
218 }
219 
221 {
222  if ( mSaveOnlyCurrentStyle != saveOnlyCurrentStyle )
223  {
224  mSaveOnlyCurrentStyle = saveOnlyCurrentStyle;
225  setupMultipleStyles();
226  }
227 }
228 
230 {
231  return mStylesWidget;
232 }
233 
234 
235 void QgsVectorLayerSaveStyleDialog::showHelp()
236 {
237  QgsHelp::openHelp( QStringLiteral( "introduction/general_tools.html#save-and-share-layer-properties" ) );
238 }
@ 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:168
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:36
Model for layer style categories.
QgsMapLayer::StyleCategories categories() const
Returns the categories as defined in the model.
Management of styles for use with one map layer.
QStringList styles() const
Returns list of all defined style names.
QString providerType() const
Returns the provider type (provider key) for this layer.
QgsMapLayerType type
Definition: qgsmaplayer.h:80
QgsMapLayerStyleManager * styleManager() const
Gets access to the layer's style manager.
@ AllStyleCategories
Definition: qgsmaplayer.h:175
This class is a composition of two QSettings instances:
Definition: qgssettings.h:62
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:331
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:395
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.
virtual bool isSaveAndLoadStyleToDatabaseSupported() const
It returns false by default.
virtual QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
void setSaveOnlyCurrentStyle(bool saveCurrentStyle)
QgsVectorLayerSaveStyleDialog(QgsVectorLayer *layer, QWidget *parent=nullptr)
QgsMapLayer::StyleCategories styleCategories() const
QgsVectorLayerProperties::StyleType currentStyleType() const
Represents a vector layer which manages a vector based data sets.
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.