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 const 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 && type != QgsVectorLayerProperties::StyleType::Local ) );
63 mFileWidget->setVisible( !vl || ( type != QgsVectorLayerProperties::StyleType::DB && type != QgsVectorLayerProperties::StyleType::Local ) );
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();
81 if (
QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( mLayer ) )
83 if ( vl->dataProvider()->isSaveAndLoadStyleToDatabaseSupported() )
85 mStyleTypeComboBox->addItem( tr(
"From Database (%1)" ).arg( providerName ), QgsVectorLayerProperties::StyleType::DB );
86 if ( settings.
value( QStringLiteral(
"style/lastLoadStyleTypeSelection" ) ) == QgsVectorLayerProperties::StyleType::DB )
88 mStyleTypeComboBox->setCurrentIndex( mStyleTypeComboBox->findData( QgsVectorLayerProperties::StyleType::DB ) );
97 mStyleCategoriesListView->setModel( mModel );
100 switch ( mLayer->
type() )
102 case Qgis::LayerType::Vector:
103 mFileWidget->setFilter( tr(
"QGIS Layer Style File, SLD File" ) + QStringLiteral(
" (*.qml *.sld)" ) );
106 case Qgis::LayerType::VectorTile:
107 mFileWidget->setFilter( tr(
"All Styles" ) + QStringLiteral(
" (*.qml *.json);;" )
108 + tr(
"QGIS Layer Style File" ) + QStringLiteral(
" (*.qml);;" )
109 + tr(
"MapBox GL Style JSON File" ) + QStringLiteral(
" (*.json)" ) );
112 case Qgis::LayerType::Raster:
113 case Qgis::LayerType::Mesh:
114 case Qgis::LayerType::Annotation:
115 case Qgis::LayerType::Plugin:
116 case Qgis::LayerType::PointCloud:
117 case Qgis::LayerType::Group:
123 mFileWidget->setDefaultRoot( myLastUsedDir );
129 const QFileInfo tmplFileInfo( path );
130 settings.
setValue( QStringLiteral(
"style/lastStyleDir" ), tmplFileInfo.absolutePath() );
132 updateLoadButtonState();
136 mLoadButton->setDisabled(
true );
137 mDeleteButton->setDisabled(
true );
138 mRelatedTable->setEditTriggers( QTableWidget::NoEditTriggers );
139 mRelatedTable->horizontalHeader()->setStretchLastSection(
true );
140 mRelatedTable->setSelectionBehavior( QTableWidget::SelectRows );
141 mRelatedTable->verticalHeader()->setVisible(
false );
142 mOthersTable->setEditTriggers( QTableWidget::NoEditTriggers );
143 mOthersTable->horizontalHeader()->setStretchLastSection(
true );
144 mOthersTable->setSelectionBehavior( QTableWidget::SelectRows );
145 mOthersTable->verticalHeader()->setVisible(
false );
146 connect( mRelatedTable->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsMapLayerLoadStyleDialog::onRelatedTableSelectionChanged );
147 connect( mOthersTable->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsMapLayerLoadStyleDialog::onOthersTableSelectionChanged );
148 connect( mRelatedTable, &QTableWidget::doubleClicked,
this, &QDialog::accept );
149 connect( mOthersTable, &QTableWidget::doubleClicked,
this, &QDialog::accept );
150 connect( mCancelButton, &QPushButton::clicked,
this, &QDialog::reject );
151 connect( mButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsMapLayerLoadStyleDialog::showHelp );
152 connect( mLoadButton, &QPushButton::clicked,
this, &QDialog::accept );
153 connect( mDeleteButton, &QPushButton::clicked,
this, &QgsMapLayerLoadStyleDialog::deleteStyleFromDB );
154 connect(
this, &QgsMapLayerLoadStyleDialog::rejected, [ = ]
159 setTabOrder( mRelatedTable, mOthersTable );
161 mStyleCategoriesListView->adjustSize();
174 const QFileInfo fi( mFileWidget->filePath() );
175 if ( fi.exists() && fi.suffix().compare( QStringLiteral(
"sld" ), Qt::CaseInsensitive ) == 0 )
183 return QFileInfo( mFileWidget->filePath() ).suffix();
188 return mFileWidget->filePath();
194 mSectionLimit = sectionLimit;
195 const int relatedTableNOfCols = sectionLimit > 0 ? 2 : 1;
196 const int othersTableNOfCols = ( sectionLimit >= 0 && ids.count() - sectionLimit > 0 ) ? 2 : 1;
197 const QString twoColsHeader( QStringLiteral(
"Name;Description" ) );
198 const QString oneColsHeader( QStringLiteral(
"No styles found in the database" ) );
199 const QString relatedTableHeader = relatedTableNOfCols == 1 ? oneColsHeader : twoColsHeader;
200 const QString othersTableHeader = othersTableNOfCols == 1 ? oneColsHeader : twoColsHeader;
202 mRelatedTable->setColumnCount( relatedTableNOfCols );
203 mOthersTable->setColumnCount( othersTableNOfCols );
204 mRelatedTable->setHorizontalHeaderLabels( relatedTableHeader.split(
';' ) );
205 mOthersTable->setHorizontalHeaderLabels( othersTableHeader.split(
';' ) );
206 mRelatedTable->setRowCount( sectionLimit );
207 mOthersTable->setRowCount( sectionLimit >= 0 ? ( ids.count() - sectionLimit ) : 0 );
208 mRelatedTable->setDisabled( relatedTableNOfCols == 1 );
209 mOthersTable->setDisabled( othersTableNOfCols == 1 );
211 if ( sectionLimit >= 0 )
213 for (
int i = 0; i < sectionLimit; i++ )
215 QTableWidgetItem *item =
new QTableWidgetItem( names.value( i, QString() ) );
216 item->setData( Qt::UserRole, ids[i] );
217 mRelatedTable->setItem( i, 0, item );
218 mRelatedTable->setItem( i, 1,
new QTableWidgetItem( descriptions.value( i, QString() ) ) );
220 for (
int i = sectionLimit; i < ids.count(); i++ )
222 const int j = i - sectionLimit;
223 QTableWidgetItem *item =
new QTableWidgetItem( names.value( i, QString() ) );
224 item->setData( Qt::UserRole, ids[i] );
225 mOthersTable->setItem( j, 0, item );
226 mOthersTable->setItem( j, 1,
new QTableWidgetItem( descriptions.value( i, QString() ) ) );
233 return mSelectedStyleId;
236void QgsMapLayerLoadStyleDialog::onRelatedTableSelectionChanged()
238 selectionChanged( mRelatedTable );
239 if ( mRelatedTable->selectionModel()->hasSelection() )
241 if ( mOthersTable->selectionModel()->hasSelection() )
243 disconnect( mOthersTable->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsMapLayerLoadStyleDialog::onOthersTableSelectionChanged );
244 const QTableWidgetSelectionRange range( 0, 0, mOthersTable->rowCount() - 1, mOthersTable->columnCount() - 1 );
245 mOthersTable->setRangeSelected( range,
false );
246 connect( mOthersTable->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsMapLayerLoadStyleDialog::onOthersTableSelectionChanged );
251void QgsMapLayerLoadStyleDialog::onOthersTableSelectionChanged()
253 selectionChanged( mOthersTable );
254 if ( mOthersTable->selectionModel()->hasSelection() )
256 if ( mRelatedTable->selectionModel()->hasSelection() )
258 disconnect( mRelatedTable->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsMapLayerLoadStyleDialog::onRelatedTableSelectionChanged );
259 const QTableWidgetSelectionRange range( 0, 0, mRelatedTable->rowCount() - 1, mRelatedTable->columnCount() - 1 );
260 mRelatedTable->setRangeSelected( range,
false );
261 connect( mRelatedTable->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsMapLayerLoadStyleDialog::onRelatedTableSelectionChanged );
266void QgsMapLayerLoadStyleDialog::selectionChanged( QTableWidget *styleTable )
268 QTableWidgetItem *item =
nullptr;
269 const QList<QTableWidgetItem *> selected = styleTable->selectedItems();
271 if ( !selected.isEmpty() )
273 item = selected.at( 0 );
274 mSelectedStyleName = item->text();
275 mSelectedStyleId = item->data( Qt::UserRole ).toString();
276 mLoadButton->setEnabled(
true );
277 mDeleteButton->setEnabled(
true );
281 mSelectedStyleName.clear();
282 mSelectedStyleId.clear();
283 mLoadButton->setEnabled(
false );
284 mDeleteButton->setEnabled(
false );
287 updateLoadButtonState();
298void QgsMapLayerLoadStyleDialog::deleteStyleFromDB()
305 const QString opInfo = QObject::tr(
"Delete style %1 from %2" ).arg( mSelectedStyleName, mLayer->
providerType() );
307 if ( QMessageBox::question(
nullptr, QObject::tr(
"Delete Style" ),
308 QObject::tr(
"Are you sure you want to delete the style %1?" ).arg( mSelectedStyleName ),
309 QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) != QMessageBox::Yes )
313 if ( !msgError.isNull() )
316 QMessageBox::warning(
this, opInfo, tr(
"%1: fail. %2" ).arg( opInfo, msgError ) );
323 mRelatedTable->setRowCount( 0 );
324 mOthersTable->setRowCount( 0 );
328 QStringList ids, names, descriptions;
331 if ( !errorMsg.isNull() )
333 QMessageBox::warning(
this, tr(
"Error occurred while retrieving styles from database" ), errorMsg );
342void QgsMapLayerLoadStyleDialog::updateLoadButtonState()
345 if ( mLayer->
type() == Qgis::LayerType::Vector )
348 && ( mRelatedTable->selectionModel()->hasSelection() || mOthersTable->selectionModel()->hasSelection()
355 mLoadButton->setEnabled( !mFileWidget->filePath().isEmpty() );
359void QgsMapLayerLoadStyleDialog::showHelp()
361 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 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.
This class is a composition of two QSettings instances:
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.
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.
#define QgsDebugError(str)