16 #include <QMessageBox>
21 #include "qgssettings.h"
22 #include "qgsvectorlayerproperties.h"
35 setWindowTitle( tr(
"Database Styles Manager" ) );
37 mDeleteButton = mButtonBox->button( QDialogButtonBox::StandardButton::Close );
38 mDeleteButton->setText( tr(
"Delete Style" ) );
40 mLoadButton = mButtonBox->button( QDialogButtonBox::StandardButton::Open );
41 mLoadButton->setText( tr(
"Load Style" ) );
42 mCancelButton = mButtonBox->button( QDialogButtonBox::StandardButton::Cancel );
47 if ( providerName == QLatin1String(
"ogr" ) )
51 if ( providerName == QLatin1String(
"GPKG" ) )
52 providerName = QStringLiteral(
"GeoPackage" );
55 QString myLastUsedDir = settings.value( QStringLiteral(
"style/lastStyleDir" ), QDir::homePath() ).toString();
58 connect( mStyleTypeComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, [ = ](
int )
62 mFileLabel->setVisible( !vl || type != QgsVectorLayerProperties::StyleType::DB );
63 mFileWidget->setVisible( !vl || type != QgsVectorLayerProperties::StyleType::DB );
66 mFromDbWidget->setVisible( type == QgsVectorLayerProperties::StyleType::DB );
71 mFromDbWidget->setVisible(
false );
72 mDeleteButton->setVisible(
false );
75 mStyleCategoriesListView->setEnabled( !vl ||
currentStyleType() != QgsVectorLayerProperties::StyleType::SLD );
76 updateLoadButtonState();
78 mStyleTypeComboBox->addItem( tr(
"From File" ), QgsVectorLayerProperties::QML );
80 if (
QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( mLayer ) )
82 if ( vl->dataProvider()->isSaveAndLoadStyleToDatabaseSupported() )
84 mStyleTypeComboBox->addItem( tr(
"From Database (%1)" ).arg( providerName ), QgsVectorLayerProperties::StyleType::DB );
85 if ( settings.value( QStringLiteral(
"style/lastLoadStyleTypeSelection" ) ) == QgsVectorLayerProperties::StyleType::DB )
87 mStyleTypeComboBox->setCurrentIndex( mStyleTypeComboBox->findData( QgsVectorLayerProperties::StyleType::DB ) );
94 QgsMapLayer::StyleCategories lastStyleCategories = settings.flagValue( QStringLiteral(
"style/lastStyleCategories" ),
QgsMapLayer::AllStyleCategories );
96 mStyleCategoriesListView->setModel( mModel );
99 switch ( mLayer->
type() )
102 mFileWidget->setFilter( tr(
"QGIS Layer Style File, SLD File" ) + QStringLiteral(
" (*.qml *.sld)" ) );
106 mFileWidget->setFilter( tr(
"All Styles" ) + QStringLiteral(
" (*.qml *.json);;" )
107 + tr(
"QGIS Layer Style File" ) + QStringLiteral(
" (*.qml);;" )
108 + tr(
"MapBox GL Style JSON File" ) + QStringLiteral(
" (*.json)" ) );
121 mFileWidget->setDefaultRoot( myLastUsedDir );
125 mStyleCategoriesListView->setEnabled( !vl ||
currentStyleType() != QgsVectorLayerProperties::SLD );
126 QgsSettings settings;
127 QFileInfo tmplFileInfo( path );
128 settings.setValue( QStringLiteral(
"style/lastStyleDir" ), tmplFileInfo.absolutePath() );
130 updateLoadButtonState();
134 mLoadButton->setDisabled(
true );
135 mDeleteButton->setDisabled(
true );
136 mRelatedTable->setEditTriggers( QTableWidget::NoEditTriggers );
137 mRelatedTable->horizontalHeader()->setStretchLastSection(
true );
138 mRelatedTable->setSelectionBehavior( QTableWidget::SelectRows );
139 mRelatedTable->verticalHeader()->setVisible(
false );
140 mOthersTable->setEditTriggers( QTableWidget::NoEditTriggers );
141 mOthersTable->horizontalHeader()->setStretchLastSection(
true );
142 mOthersTable->setSelectionBehavior( QTableWidget::SelectRows );
143 mOthersTable->verticalHeader()->setVisible(
false );
144 connect( mRelatedTable->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsMapLayerLoadStyleDialog::onRelatedTableSelectionChanged );
145 connect( mOthersTable->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsMapLayerLoadStyleDialog::onOthersTableSelectionChanged );
146 connect( mRelatedTable, &QTableWidget::doubleClicked,
this, &QDialog::accept );
147 connect( mOthersTable, &QTableWidget::doubleClicked,
this, &QDialog::accept );
148 connect( mCancelButton, &QPushButton::clicked,
this, &QDialog::reject );
149 connect( mButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsMapLayerLoadStyleDialog::showHelp );
150 connect( mLoadButton, &QPushButton::clicked,
this, &QDialog::accept );
151 connect( mDeleteButton, &QPushButton::clicked,
this, &QgsMapLayerLoadStyleDialog::deleteStyleFromDB );
152 connect(
this, &QgsMapLayerLoadStyleDialog::rejected, [ = ]
154 QgsSettings().setValue( QStringLiteral(
"style/lastLoadStyleTypeSelection" ),
currentStyleType() );
157 setTabOrder( mRelatedTable, mOthersTable );
159 mStyleCategoriesListView->adjustSize();
169 QgsVectorLayerProperties::StyleType type = mStyleTypeComboBox->currentData().value<QgsVectorLayerProperties::StyleType>();
170 if ( type == QgsVectorLayerProperties::QML )
172 QFileInfo fi( mFileWidget->filePath() );
173 if ( fi.exists() && fi.suffix().compare( QStringLiteral(
"sld" ), Qt::CaseInsensitive ) == 0 )
174 type = QgsVectorLayerProperties::SLD;
181 return QFileInfo( mFileWidget->filePath() ).suffix();
186 return mFileWidget->filePath();
192 mSectionLimit = sectionLimit;
193 int relatedTableNOfCols = sectionLimit > 0 ? 2 : 1;
194 int othersTableNOfCols = ( sectionLimit >= 0 && ids.count() - sectionLimit > 0 ) ? 2 : 1;
195 QString twoColsHeader( QStringLiteral(
"Name;Description" ) );
196 QString oneColsHeader( QStringLiteral(
"No styles found in the database" ) );
197 QString relatedTableHeader = relatedTableNOfCols == 1 ? oneColsHeader : twoColsHeader;
198 QString othersTableHeader = othersTableNOfCols == 1 ? oneColsHeader : twoColsHeader;
200 mRelatedTable->setColumnCount( relatedTableNOfCols );
201 mOthersTable->setColumnCount( othersTableNOfCols );
202 mRelatedTable->setHorizontalHeaderLabels( relatedTableHeader.split(
';' ) );
203 mOthersTable->setHorizontalHeaderLabels( othersTableHeader.split(
';' ) );
204 mRelatedTable->setRowCount( sectionLimit );
205 mOthersTable->setRowCount( sectionLimit >= 0 ? ( ids.count() - sectionLimit ) : 0 );
206 mRelatedTable->setDisabled( relatedTableNOfCols == 1 );
207 mOthersTable->setDisabled( othersTableNOfCols == 1 );
209 if ( sectionLimit >= 0 )
211 for (
int i = 0; i < sectionLimit; i++ )
213 QTableWidgetItem *item =
new QTableWidgetItem( names.value( i, QString() ) );
214 item->setData( Qt::UserRole, ids[i] );
215 mRelatedTable->setItem( i, 0, item );
216 mRelatedTable->setItem( i, 1,
new QTableWidgetItem( descriptions.value( i, QString() ) ) );
218 for (
int i = sectionLimit; i < ids.count(); i++ )
220 int j = i - sectionLimit;
221 QTableWidgetItem *item =
new QTableWidgetItem( names.value( i, QString() ) );
222 item->setData( Qt::UserRole, ids[i] );
223 mOthersTable->setItem( j, 0, item );
224 mOthersTable->setItem( j, 1,
new QTableWidgetItem( descriptions.value( i, QString() ) ) );
231 return mSelectedStyleId;
234 void QgsMapLayerLoadStyleDialog::onRelatedTableSelectionChanged()
236 selectionChanged( mRelatedTable );
237 if ( mRelatedTable->selectionModel()->hasSelection() )
239 if ( mOthersTable->selectionModel()->hasSelection() )
241 disconnect( mOthersTable->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsMapLayerLoadStyleDialog::onOthersTableSelectionChanged );
242 QTableWidgetSelectionRange range( 0, 0, mOthersTable->rowCount() - 1, mOthersTable->columnCount() - 1 );
243 mOthersTable->setRangeSelected( range,
false );
244 connect( mOthersTable->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsMapLayerLoadStyleDialog::onOthersTableSelectionChanged );
249 void QgsMapLayerLoadStyleDialog::onOthersTableSelectionChanged()
251 selectionChanged( mOthersTable );
252 if ( mOthersTable->selectionModel()->hasSelection() )
254 if ( mRelatedTable->selectionModel()->hasSelection() )
256 disconnect( mRelatedTable->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsMapLayerLoadStyleDialog::onRelatedTableSelectionChanged );
257 QTableWidgetSelectionRange range( 0, 0, mRelatedTable->rowCount() - 1, mRelatedTable->columnCount() - 1 );
258 mRelatedTable->setRangeSelected( range,
false );
259 connect( mRelatedTable->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsMapLayerLoadStyleDialog::onRelatedTableSelectionChanged );
264 void QgsMapLayerLoadStyleDialog::selectionChanged( QTableWidget *styleTable )
266 QTableWidgetItem *item =
nullptr;
267 QList<QTableWidgetItem *> selected = styleTable->selectedItems();
269 if ( !selected.isEmpty() )
271 item = selected.at( 0 );
272 mSelectedStyleName = item->text();
273 mSelectedStyleId = item->data( Qt::UserRole ).toString();
274 mLoadButton->setEnabled(
true );
275 mDeleteButton->setEnabled(
true );
279 mSelectedStyleName.clear();
280 mSelectedStyleId.clear();
281 mLoadButton->setEnabled(
false );
282 mDeleteButton->setEnabled(
false );
285 updateLoadButtonState();
290 QgsSettings settings;
291 settings.setFlagValue( QStringLiteral(
"style/lastStyleCategories" ),
styleCategories() );
292 settings.setValue( QStringLiteral(
"style/lastLoadStyleTypeSelection" ),
currentStyleType() );
296 void QgsMapLayerLoadStyleDialog::deleteStyleFromDB()
303 QString opInfo = QObject::tr(
"Delete style %1 from %2" ).arg( mSelectedStyleName, mLayer->
providerType() );
305 if ( QMessageBox::question(
nullptr, QObject::tr(
"Delete Style" ),
306 QObject::tr(
"Are you sure you want to delete the style %1?" ).arg( mSelectedStyleName ),
307 QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) != QMessageBox::Yes )
311 if ( !msgError.isNull() )
314 QMessageBox::warning(
this, opInfo, tr(
"%1: fail. %2" ).arg( opInfo, msgError ) );
321 mRelatedTable->setRowCount( 0 );
322 mOthersTable->setRowCount( 0 );
326 QStringList ids, names, descriptions;
329 if ( !errorMsg.isNull() )
331 QMessageBox::warning(
this, tr(
"Error occurred while retrieving styles from database" ), errorMsg );
340 void QgsMapLayerLoadStyleDialog::updateLoadButtonState()
345 mLoadButton->setEnabled( ( type == QgsVectorLayerProperties::DB
346 && ( mRelatedTable->selectionModel()->hasSelection() || mOthersTable->selectionModel()->hasSelection()
348 ( type != QgsVectorLayerProperties::DB && !mFileWidget->filePath().isEmpty() ) );
352 mLoadButton->setEnabled( !mFileWidget->filePath().isEmpty() );
356 void QgsMapLayerLoadStyleDialog::showHelp()
358 QgsHelp::openHelp( QStringLiteral(
"introduction/general_tools.html#save-and-share-layer-properties" ) );
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QgsGui * instance()
Returns a pointer to the singleton instance.
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...
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
QgsMapLayer::StyleCategories styleCategories() const
Returns the list of selected style categories the user has opted to load.
void initializeLists(const QStringList &ids, const QStringList &names, const QStringList &descriptions, int sectionLimit)
Initialize list of database stored styles.
QString selectedStyleId()
Returns the ID of the selected database stored style.
QgsMapLayerLoadStyleDialog(QgsMapLayer *layer, QWidget *parent=nullptr)
Constructor for QgsMapLayerLoadStyleDialog, associated with the specified map layer.
QString filePath() const
Returns the full path to the selected layer style source file.
QString fileExtension() const
Returns the file extension for the selected layer style source file.
QgsVectorLayerProperties::StyleType currentStyleType() const
Returns the selected vector style type, for vector layers only.
Model for layer style categories.
void setCategories(QgsMapLayer::StyleCategories categories)
Reset the model data.
QgsMapLayer::StyleCategories categories() const
Returns the categories as defined in the model.
Base class for all map layer types.
QString providerType() const
Returns the provider type (provider key) for this layer.
virtual QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
virtual bool isDeleteStyleFromDatabaseSupported() const
It returns false by default.
Represents a vector layer which manages a vector based data sets.
virtual int listStylesInDatabase(QStringList &ids, QStringList &names, QStringList &descriptions, QString &msgError)
Lists all the style in db split into related to the layer and not related to.
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
virtual bool deleteStyleFromDatabase(const QString &styleId, QString &msgError)
Deletes a style from the database.
@ PointCloudLayer
Added in 3.18.
@ VectorTileLayer
Added in 3.14.
@ AnnotationLayer
Contains freeform, georeferenced annotations. Added in QGIS 3.16.