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.