43 #include "qgsnative.h" 
   48 #include "qgsconfig.h" 
   80 #include <QDesktopServices> 
   81 #include <QMessageBox> 
   84 #include <QFileDialog> 
   86 #include <QFontDialog> 
   89 #include <QHeaderView> 
   90 #include <QColorDialog> 
   93 #include <QRegularExpressionValidator> 
  108   , mMessageBar( messageBar )
 
  110   , mOriginalSubsetSQL( lyr->subsetString() )
 
  113   connect( pbnQueryBuilder, &QPushButton::clicked, 
this, &QgsVectorLayerProperties::pbnQueryBuilder_clicked );
 
  114   connect( pbnIndex, &QPushButton::clicked, 
this, &QgsVectorLayerProperties::pbnIndex_clicked );
 
  116   connect( pbnUpdateExtents, &QPushButton::clicked, 
this, &QgsVectorLayerProperties::pbnUpdateExtents_clicked );
 
  117   connect( mButtonAddJoin, &QPushButton::clicked, 
this, &QgsVectorLayerProperties::mButtonAddJoin_clicked );
 
  118   connect( mButtonEditJoin, &QPushButton::clicked, 
this, &QgsVectorLayerProperties::mButtonEditJoin_clicked );
 
  119   connect( mJoinTreeWidget, &QTreeWidget::itemDoubleClicked, 
this, &QgsVectorLayerProperties::mJoinTreeWidget_itemDoubleClicked );
 
  120   connect( mButtonRemoveJoin, &QPushButton::clicked, 
this, &QgsVectorLayerProperties::mButtonRemoveJoin_clicked );
 
  121   connect( mButtonAddWmsDimension, &QPushButton::clicked, 
this, &QgsVectorLayerProperties::mButtonAddWmsDimension_clicked );
 
  122   connect( mButtonEditWmsDimension, &QPushButton::clicked, 
this, &QgsVectorLayerProperties::mButtonEditWmsDimension_clicked );
 
  123   connect( mWmsDimensionsTreeWidget, &QTreeWidget::itemDoubleClicked, 
this, &QgsVectorLayerProperties::mWmsDimensionsTreeWidget_itemDoubleClicked );
 
  124   connect( mButtonRemoveWmsDimension, &QPushButton::clicked, 
this, &QgsVectorLayerProperties::mButtonRemoveWmsDimension_clicked );
 
  125   connect( mSimplifyDrawingGroupBox, &QGroupBox::toggled, 
this, &QgsVectorLayerProperties::mSimplifyDrawingGroupBox_toggled );
 
  126   connect( buttonRemoveMetadataUrl, &QPushButton::clicked, 
this, &QgsVectorLayerProperties::removeSelectedMetadataUrl );
 
  127   connect( buttonAddMetadataUrl, &QPushButton::clicked, 
this, &QgsVectorLayerProperties::addMetadataUrl );
 
  128   connect( buttonBox, &QDialogButtonBox::helpRequested, 
this, &QgsVectorLayerProperties::showHelp );
 
  135   mBtnStyle = 
new QPushButton( tr( 
"Style" ), 
this );
 
  136   QMenu *menuStyle = 
new QMenu( 
this );
 
  137   mActionLoadStyle = 
new QAction( tr( 
"Load Style…" ), 
this );
 
  138   connect( mActionLoadStyle, &QAction::triggered, 
this, &QgsVectorLayerProperties::loadStyle );
 
  140   mActionSaveStyle = 
new QAction( tr( 
"Save Current Style…" ), 
this );
 
  141   connect( mActionSaveStyle, &QAction::triggered, 
this, &QgsVectorLayerProperties::saveStyleAs );
 
  143   mActionSaveMultipleStyles = 
new QAction( tr( 
"Save Multiple Styles…" ), 
this );
 
  144   connect( mActionSaveMultipleStyles, &QAction::triggered, 
this, &QgsVectorLayerProperties::saveMultipleStylesAs );
 
  146   mSourceGroupBox->hide();
 
  148   mBtnStyle->setMenu( menuStyle );
 
  149   connect( menuStyle, &QMenu::aboutToShow, 
this, &QgsVectorLayerProperties::aboutToShowStyleMenu );
 
  150   buttonBox->addButton( mBtnStyle, QDialogButtonBox::ResetRole );
 
  152   mBtnMetadata = 
new QPushButton( tr( 
"Metadata" ), 
this );
 
  153   QMenu *menuMetadata = 
new QMenu( 
this );
 
  154   mActionLoadMetadata = menuMetadata->addAction( tr( 
"Load Metadata…" ), 
this, &QgsVectorLayerProperties::loadMetadata );
 
  155   mActionSaveMetadataAs = menuMetadata->addAction( tr( 
"Save Metadata…" ), 
this, &QgsVectorLayerProperties::saveMetadataAs );
 
  156   menuMetadata->addSeparator();
 
  157   menuMetadata->addAction( tr( 
"Save as Default" ), 
this, &QgsVectorLayerProperties::saveDefaultMetadata );
 
  158   menuMetadata->addAction( tr( 
"Restore Default" ), 
this, &QgsVectorLayerProperties::loadDefaultMetadata );
 
  159   mBtnMetadata->setMenu( menuMetadata );
 
  160   buttonBox->addButton( mBtnMetadata, QDialogButtonBox::ResetRole );
 
  164   connect( buttonBox->button( QDialogButtonBox::Apply ), &QAbstractButton::clicked, 
this, &QgsVectorLayerProperties::apply );
 
  165   connect( 
this, &QDialog::accepted, 
this, &QgsVectorLayerProperties::apply );
 
  166   connect( 
this, &QDialog::rejected, 
this, &QgsVectorLayerProperties::onCancel );
 
  174   mMapTipExpressionFieldWidget->setLayer( lyr );
 
  175   mMapTipExpressionFieldWidget->registerExpressionContextGenerator( 
this );
 
  176   mDisplayExpressionWidget->setLayer( lyr );
 
  177   mDisplayExpressionWidget->registerExpressionContextGenerator( 
this );
 
  179   connect( mInsertExpressionButton, &QAbstractButton::clicked, 
this, &QgsVectorLayerProperties::insertFieldOrExpression );
 
  184   QVBoxLayout *layout = 
nullptr;
 
  189     layout = 
new QVBoxLayout( labelingFrame );
 
  190     layout->setContentsMargins( 0, 0, 0, 0 );
 
  191     labelingDialog = 
new QgsLabelingWidget( mLayer, mCanvas, labelingFrame );
 
  192     labelingDialog->layout()->setContentsMargins( 0, 0, 0, 0 );
 
  194     layout->addWidget( labelingDialog );
 
  195     labelingFrame->setLayout( layout );
 
  198     layout = 
new QVBoxLayout( mMaskingFrame );
 
  199     layout->setContentsMargins( 0, 0, 0, 0 );
 
  200     mMaskingWidget = 
new QgsMaskingWidget( mMaskingFrame );
 
  201     mMaskingWidget->setLayer( mLayer );
 
  202     mMaskingWidget->layout()->setContentsMargins( 0, 0, 0, 0 );
 
  203     layout->addWidget( mMaskingWidget );
 
  204     mMaskingFrame->setLayout( layout );
 
  208     labelingDialog = 
nullptr;
 
  209     mOptsPage_Labels->setEnabled( 
false ); 
 
  210     mOptsPage_Masks->setEnabled( 
false ); 
 
  211     mGeomGroupBox->setEnabled( 
false );
 
  212     mGeomGroupBox->setVisible( 
false );
 
  213     mCrsGroupBox->setEnabled( 
false );
 
  214     mCrsGroupBox->setVisible( 
false );
 
  218   QVBoxLayout *actionLayout = 
new QVBoxLayout( actionOptionsFrame );
 
  219   actionLayout->setContentsMargins( 0, 0, 0, 0 );
 
  221   mActionDialog->layout()->setContentsMargins( 0, 0, 0, 0 );
 
  222   actionLayout->addWidget( mActionDialog );
 
  225   mSourceFieldsPropertiesDialog->layout()->setContentsMargins( 0, 0, 0, 0 );
 
  226   mSourceFieldsFrame->setLayout( 
new QVBoxLayout( mSourceFieldsFrame ) );
 
  227   mSourceFieldsFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
 
  228   mSourceFieldsFrame->layout()->addWidget( mSourceFieldsPropertiesDialog );
 
  233   mAttributesFormPropertiesDialog->layout()->setContentsMargins( 0, 0, 0, 0 );
 
  234   mAttributesFormFrame->setLayout( 
new QVBoxLayout( mAttributesFormFrame ) );
 
  235   mAttributesFormFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
 
  236   mAttributesFormFrame->layout()->addWidget( mAttributesFormPropertiesDialog );
 
  239   QVBoxLayout *metadataLayout = 
new QVBoxLayout( metadataFrame );
 
  240   metadataLayout->setContentsMargins( 0, 0, 0, 0 );
 
  242   mMetadataWidget->layout()->setContentsMargins( 0, 0, 0, 0 );
 
  244   metadataLayout->addWidget( mMetadataWidget );
 
  245   metadataFrame->setLayout( metadataLayout );
 
  247   QVBoxLayout *temporalLayout = 
new QVBoxLayout( temporalFrame );
 
  248   temporalLayout->setContentsMargins( 0, 0, 0, 0 );
 
  250   temporalLayout->addWidget( mTemporalWidget );
 
  260       pbnIndex->setEnabled( 
false );
 
  264       pbnIndex->setEnabled( 
false );
 
  265       pbnIndex->setText( tr( 
"Spatial Index Exists" ) );
 
  272       int encindex = cboProviderEncoding->findText( enc );
 
  275         cboProviderEncoding->insertItem( 0, enc );
 
  278       cboProviderEncoding->setCurrentIndex( encindex );
 
  280     else if ( mLayer->
providerType() == QLatin1String( 
"ogr" ) )
 
  285       cboProviderEncoding->setEnabled( 
false );
 
  290       mDataSourceEncodingFrame->hide();
 
  294   mCrsSelector->setCrs( mLayer->
crs() );
 
  297   const QList< QgsVectorLayerJoinInfo > &joins = mLayer->
vectorJoins();
 
  300     addJoinToTreeWidget( join );
 
  305   QVBoxLayout *diagLayout = 
new QVBoxLayout( mDiagramFrame );
 
  306   diagLayout->setContentsMargins( 0, 0, 0, 0 );
 
  308   diagramPropertiesDialog->layout()->setContentsMargins( 0, 0, 0, 0 );
 
  310   diagLayout->addWidget( diagramPropertiesDialog );
 
  311   mDiagramFrame->setLayout( diagLayout );
 
  314   mLegendWidget->setMapCanvas( mCanvas );
 
  315   mLegendWidget->setLayer( mLayer );
 
  316   mLegendConfigEmbeddedWidget->setLayer( mLayer );
 
  319   mLayerShortNameLineEdit->setText( mLayer->
shortName() );
 
  322   mLayerShortNameLineEdit->setValidator( shortNameValidator );
 
  325   mLayerTitleLineEdit->setText( mLayer->
title() );
 
  326   mLayerAbstractTextEdit->setPlainText( mLayer->
abstract() );
 
  327   mLayerKeywordListLineEdit->setText( mLayer->
keywordList() );
 
  328   mLayerDataUrlLineEdit->setText( mLayer->
dataUrl() );
 
  329   mLayerDataUrlFormatComboBox->setCurrentIndex(
 
  330     mLayerDataUrlFormatComboBox->findText(
 
  335   mLayerAttributionLineEdit->setText( mLayer->
attribution() );
 
  336   mLayerAttributionUrlLineEdit->setText( mLayer->
attributionUrl() );
 
  339   tableViewMetadataUrl->setSelectionMode( QAbstractItemView::SingleSelection );
 
  340   tableViewMetadataUrl->setSelectionBehavior( QAbstractItemView::SelectRows );
 
  341   tableViewMetadataUrl->horizontalHeader()->setStretchLastSection( 
true );
 
  342   tableViewMetadataUrl->horizontalHeader()->setSectionResizeMode( QHeaderView::Stretch );
 
  344   mMetadataUrlModel = 
new QStandardItemModel( tableViewMetadataUrl );
 
  345   mMetadataUrlModel->clear();
 
  346   mMetadataUrlModel->setColumnCount( 3 );
 
  347   QStringList metadataUrlHeaders;
 
  348   metadataUrlHeaders << tr( 
"URL" ) << tr( 
"Type" ) << tr( 
"Format" );
 
  349   mMetadataUrlModel->setHorizontalHeaderLabels( metadataUrlHeaders );
 
  350   tableViewMetadataUrl->setModel( mMetadataUrlModel );
 
  351   tableViewMetadataUrl->setItemDelegate( 
new MetadataUrlItemDelegate( 
this ) );
 
  356     const int row = mMetadataUrlModel->rowCount();
 
  357     mMetadataUrlModel->setItem( row, 0, 
new QStandardItem( metaUrl.url ) );
 
  358     mMetadataUrlModel->setItem( row, 1, 
new QStandardItem( metaUrl.type ) );
 
  359     mMetadataUrlModel->setItem( row, 2, 
new QStandardItem( metaUrl.format ) );
 
  363   mLayerLegendUrlLineEdit->setText( mLayer->
legendUrl() );
 
  364   mLayerLegendUrlFormatComboBox->setCurrentIndex(
 
  365     mLayerLegendUrlFormatComboBox->findText(
 
  372   const QList<QgsMapLayerServerProperties::WmsDimensionInfo> &wmsDims = serverProperties->
wmsDimensions();
 
  375     addWmsDimensionInfoToTreeWidget( dim );
 
  379   myStyle.append( QStringLiteral( 
"body { margin: 10px; }\n " ) );
 
  380   teMetadataViewer->clear();
 
  381   teMetadataViewer->document()->setDefaultStyleSheet( myStyle );
 
  382   teMetadataViewer->setHtml( htmlMetadata() );
 
  383   teMetadataViewer->setOpenLinks( 
false );
 
  384   connect( teMetadataViewer, &QTextBrowser::anchorClicked, 
this, &QgsVectorLayerProperties::urlClicked );
 
  385   mMetadataFilled = 
true;
 
  390   if ( !settings.
contains( QStringLiteral( 
"/Windows/VectorLayerProperties/tab" ) ) )
 
  392     settings.
setValue( QStringLiteral( 
"Windows/VectorLayerProperties/tab" ),
 
  396   QString title = tr( 
"Layer Properties — %1" ).arg( mLayer->
name() );
 
  401   QList<QgsMapLayer *> dependencySources;
 
  402   const QSet<QgsMapLayerDependency> constDependencies = mLayer->
dependencies();
 
  407       dependencySources << layer;
 
  413   connect( 
QgsProject::instance(), &QObject::destroyed, 
this, [ = ] {mLayersDependenciesTreeView->setModel( 
nullptr );} );
 
  414   mLayersDependenciesTreeView->setModel( mLayersDependenciesTreeModel );
 
  416   connect( mRefreshLayerCheckBox, &QCheckBox::toggled, mRefreshLayerIntervalSpinBox, &QDoubleSpinBox::setEnabled );
 
  419   QMenu *menu = 
new QMenu( 
this );
 
  421   mAuxiliaryLayerActionNew = 
new QAction( tr( 
"Create" ), 
this );
 
  422   menu->addAction( mAuxiliaryLayerActionNew );
 
  423   connect( mAuxiliaryLayerActionNew, &QAction::triggered, 
this, &QgsVectorLayerProperties::onAuxiliaryLayerNew );
 
  425   mAuxiliaryLayerActionClear = 
new QAction( tr( 
"Clear" ), 
this );
 
  426   menu->addAction( mAuxiliaryLayerActionClear );
 
  427   connect( mAuxiliaryLayerActionClear, &QAction::triggered, 
this, &QgsVectorLayerProperties::onAuxiliaryLayerClear );
 
  429   mAuxiliaryLayerActionDelete = 
new QAction( tr( 
"Delete" ), 
this );
 
  430   menu->addAction( mAuxiliaryLayerActionDelete );
 
  431   connect( mAuxiliaryLayerActionDelete, &QAction::triggered, 
this, &QgsVectorLayerProperties::onAuxiliaryLayerDelete );
 
  433   mAuxiliaryLayerActionExport = 
new QAction( tr( 
"Export" ), 
this );
 
  434   menu->addAction( mAuxiliaryLayerActionExport );
 
  437   mAuxiliaryStorageActions->setMenu( menu );
 
  439   connect( mAuxiliaryStorageFieldsDeleteBtn, &QPushButton::clicked, 
this, &QgsVectorLayerProperties::onAuxiliaryLayerDeleteField );
 
  440   connect( mAuxiliaryStorageFieldsAddBtn, &QPushButton::clicked, 
this, &QgsVectorLayerProperties::onAuxiliaryLayerAddField );
 
  442   updateAuxiliaryStoragePage();
 
  444   mOptsPage_Information->setProperty( 
"helpPage", QStringLiteral( 
"working_with_vector/vector_properties.html#information-properties" ) );
 
  445   mOptsPage_Source->setProperty( 
"helpPage", QStringLiteral( 
"working_with_vector/vector_properties.html#source-properties" ) );
 
  446   mOptsPage_Style->setProperty( 
"helpPage", QStringLiteral( 
"working_with_vector/vector_properties.html#symbology-properties" ) );
 
  447   mOptsPage_Labels->setProperty( 
"helpPage", QStringLiteral( 
"working_with_vector/vector_properties.html#labels-properties" ) );
 
  448   mOptsPage_Masks->setProperty( 
"helpPage", QStringLiteral( 
"working_with_vector/vector_properties.html#masks-properties" ) );
 
  449   mOptsPage_Diagrams->setProperty( 
"helpPage", QStringLiteral( 
"working_with_vector/vector_properties.html#diagrams-properties" ) );
 
  450   mOptsPage_SourceFields->setProperty( 
"helpPage", QStringLiteral( 
"working_with_vector/vector_properties.html#fields-properties" ) );
 
  451   mOptsPage_AttributesForm->setProperty( 
"helpPage", QStringLiteral( 
"working_with_vector/vector_properties.html#attributes-form-properties" ) );
 
  452   mOptsPage_Joins->setProperty( 
"helpPage", QStringLiteral( 
"working_with_vector/vector_properties.html#joins-properties" ) );
 
  453   mOptsPage_AuxiliaryStorage->setProperty( 
"helpPage", QStringLiteral( 
"working_with_vector/vector_properties.html#auxiliary-storage-properties" ) );
 
  454   mOptsPage_Actions->setProperty( 
"helpPage", QStringLiteral( 
"working_with_vector/vector_properties.html#actions-properties" ) );
 
  455   mOptsPage_Display->setProperty( 
"helpPage", QStringLiteral( 
"working_with_vector/vector_properties.html#display-properties" ) );
 
  456   mOptsPage_Rendering->setProperty( 
"helpPage", QStringLiteral( 
"working_with_vector/vector_properties.html#rendering-properties" ) );
 
  457   mOptsPage_Variables->setProperty( 
"helpPage", QStringLiteral( 
"working_with_vector/vector_properties.html#variables-properties" ) );
 
  458   mOptsPage_Metadata->setProperty( 
"helpPage", QStringLiteral( 
"working_with_vector/vector_properties.html#metadata-properties" ) );
 
  459   mOptsPage_DataDependencies->setProperty( 
"helpPage", QStringLiteral( 
"working_with_vector/vector_properties.html#dependencies-properties" ) ) ;
 
  460   mOptsPage_Legend->setProperty( 
"helpPage", QStringLiteral( 
"working_with_vector/vector_properties.html#legend-properties" ) );
 
  461   mOptsPage_Server->setProperty( 
"helpPage", QStringLiteral( 
"working_with_vector/vector_properties.html#qgis-server-properties" ) );
 
  467 void QgsVectorLayerProperties::toggleEditing()
 
  472   emit toggleEditing( mLayer );
 
  474   setPbnQueryBuilderEnabled();
 
  488     mLayerPropertiesPages << page;
 
  491     if ( beforePage.isEmpty() )
 
  498 void QgsVectorLayerProperties::insertFieldOrExpression()
 
  502   QString expression = QStringLiteral( 
"[% " );
 
  503   expression += mMapTipExpressionFieldWidget->asExpression();
 
  504   expression += QLatin1String( 
" %]" );
 
  506   mMapTipWidget->insertText( expression );
 
  509 void QgsVectorLayerProperties::addMetadataUrl()
 
  511   const int row = mMetadataUrlModel->rowCount();
 
  512   mMetadataUrlModel->setItem( row, 0, 
new QStandardItem( QLatin1String() ) );
 
  513   mMetadataUrlModel->setItem( row, 1, 
new QStandardItem( QLatin1String() ) );
 
  514   mMetadataUrlModel->setItem( row, 2, 
new QStandardItem( QLatin1String() ) );
 
  517 void QgsVectorLayerProperties::removeSelectedMetadataUrl()
 
  519   const QModelIndexList selectedRows = tableViewMetadataUrl->selectionModel()->selectedRows();
 
  520   if ( selectedRows.empty() )
 
  522   mMetadataUrlModel->removeRow( selectedRows[0].row() );
 
  526 void QgsVectorLayerProperties::syncToLayer()
 
  528   if ( !mSourceWidget )
 
  533       QHBoxLayout *layout = 
new QHBoxLayout();
 
  534       layout->addWidget( mSourceWidget );
 
  535       mSourceGroupBox->setLayout( layout );
 
  536       mSourceGroupBox->show();
 
  540         buttonBox->button( QDialogButtonBox::Apply )->setEnabled( isValid );
 
  541         buttonBox->button( QDialogButtonBox::Ok )->setEnabled( isValid );
 
  550   mLayerOrigNameLineEdit->setText( mLayer->
name() );
 
  551   mBackupCrs = mLayer->
crs();
 
  553   mSubsetGroupBox->setEnabled( 
true );
 
  560   txtSubsetSQL->setReadOnly( 
true );
 
  561   txtSubsetSQL->setCaretWidth( 0 );
 
  562   txtSubsetSQL->setCaretLineVisible( 
false );
 
  563   setPbnQueryBuilderEnabled();
 
  571   mScaleRangeWidget->setMapCanvas( mCanvas );
 
  574   mReferenceScaleWidget->setShowCurrentScaleButton( 
true );
 
  575   mReferenceScaleWidget->setMapCanvas( mCanvas );
 
  576   if ( mUseReferenceScaleGroupBox->isChecked() )
 
  579     mReferenceScaleWidget->setScale( mCanvas->
scale() );
 
  584   mSimplifyDrawingSpinBox->setValue( simplifyMethod.
threshold() );
 
  585   mSimplifyDrawingSpinBox->setClearValue( 1.0 );
 
  587   QString remark = QStringLiteral( 
" (%1)" ).arg( tr( 
"Not supported" ) );
 
  591     mSimplifyDrawingAtProvider->setChecked( 
false );
 
  592     mSimplifyDrawingAtProvider->setEnabled( 
false );
 
  593     if ( !mSimplifyDrawingAtProvider->text().endsWith( remark ) )
 
  594       mSimplifyDrawingAtProvider->setText( mSimplifyDrawingAtProvider->text().append( remark ) );
 
  599     mSimplifyDrawingAtProvider->setEnabled( mSimplifyDrawingGroupBox->isChecked() );
 
  600     if ( mSimplifyDrawingAtProvider->text().endsWith( remark ) )
 
  602       QString newText = mSimplifyDrawingAtProvider->text();
 
  603       newText.chop( remark.size() );
 
  604       mSimplifyDrawingAtProvider->setText( newText );
 
  611     mSimplifyDrawingGroupBox->setChecked( 
false );
 
  612     mSimplifyDrawingGroupBox->setEnabled( 
false );
 
  619   mSimplifyAlgorithmComboBox->setCurrentIndex( mSimplifyAlgorithmComboBox->findData( simplifyMethod.
simplifyAlgorithm() ) );
 
  622   myScalesList.append( QStringLiteral( 
"1:1" ) );
 
  623   mSimplifyMaximumScaleComboBox->updateScales( myScalesList );
 
  624   mSimplifyMaximumScaleComboBox->setScale( simplifyMethod.
maximumScale() );
 
  638   updateSymbologyPage();
 
  642   if ( labelingDialog )
 
  643     labelingDialog->adaptToLayer();
 
  645   mSourceFieldsPropertiesDialog->
init();
 
  646   mAttributesFormPropertiesDialog->
init();
 
  649   updateVariableEditor();
 
  651   if ( diagramPropertiesDialog )
 
  655   const auto constMLayerPropertiesPages = mLayerPropertiesPages;
 
  658     page->syncToLayer( mLayer );
 
  665   mLegendWidget->setLayer( mLayer );
 
  669 void QgsVectorLayerProperties::apply()
 
  673     const QString newSource = mSourceWidget->
sourceUri();
 
  674     if ( newSource != mLayer->
source() )
 
  681   if ( labelingDialog )
 
  683     labelingDialog->writeSettingsToLayer();
 
  685   mBackupCrs = mLayer->
crs();
 
  687   mLegendWidget->applyToLayer();
 
  688   mLegendConfigEmbeddedWidget->applyToLayer();
 
  692   mMetadataFilled = 
false;
 
  695   if ( mMaskingWidget && mMaskingWidget->hasBeenPopulated() )
 
  696     mMaskingWidget->apply();
 
  701   mSubsetGroupBox->setEnabled( 
true );
 
  707     mMetadataFilled = 
false;
 
  729   const auto constActions = mActionDialog->
actions();
 
  730   for ( 
const QgsAction &action : constActions )
 
  737   QVector<QgsAttributeTableConfig::ColumnConfig> columns = attributeTableConfig.
columns();
 
  739   for ( 
int i = 0; i < columns.size(); ++i )
 
  751   mLayer->
setName( mLayerOrigNameLineEdit->text() );
 
  753   mAttributesFormPropertiesDialog->
apply();
 
  754   mSourceFieldsPropertiesDialog->
apply();
 
  766   diagramPropertiesDialog->
apply();
 
  769   const auto constMLayerPropertiesPages = mLayerPropertiesPages;
 
  776   if ( mLayer->
shortName() != mLayerShortNameLineEdit->text() )
 
  777     mMetadataFilled = 
false;
 
  778   mLayer->
setShortName( mLayerShortNameLineEdit->text() );
 
  780   if ( mLayer->
title() != mLayerTitleLineEdit->text() )
 
  781     mMetadataFilled = 
false;
 
  782   mLayer->
setTitle( mLayerTitleLineEdit->text() );
 
  784   if ( mLayer->
abstract() != mLayerAbstractTextEdit->toPlainText() )
 
  785     mMetadataFilled = 
false;
 
  786   mLayer->
setAbstract( mLayerAbstractTextEdit->toPlainText() );
 
  788   if ( mLayer->
keywordList() != mLayerKeywordListLineEdit->text() )
 
  789     mMetadataFilled = 
false;
 
  792   if ( mLayer->
dataUrl() != mLayerDataUrlLineEdit->text() )
 
  793     mMetadataFilled = 
false;
 
  794   mLayer->
setDataUrl( mLayerDataUrlLineEdit->text() );
 
  796   if ( mLayer->
dataUrlFormat() != mLayerDataUrlFormatComboBox->currentText() )
 
  797     mMetadataFilled = 
false;
 
  801   if ( mLayer->
attribution() != mLayerAttributionLineEdit->text() )
 
  802     mMetadataFilled = 
false;
 
  805   if ( mLayer->
attributionUrl() != mLayerAttributionUrlLineEdit->text() )
 
  806     mMetadataFilled = 
false;
 
  810   QList<QgsMapLayerServerProperties::MetadataUrl> metaUrls;
 
  811   for ( 
int row = 0; row < mMetadataUrlModel->rowCount() ; row++ )
 
  814     metaUrl.
url = mMetadataUrlModel->item( row, 0 )->text();
 
  815     metaUrl.
type = mMetadataUrlModel->item( row, 1 )->text();
 
  816     metaUrl.
format = mMetadataUrlModel->item( row, 2 )->text();
 
  817     metaUrls.append( metaUrl );
 
  818     mMetadataFilled = 
false;
 
  823   if ( mLayer->
legendUrl() != mLayerLegendUrlLineEdit->text() )
 
  824     mMetadataFilled = 
false;
 
  825   mLayer->
setLegendUrl( mLayerLegendUrlLineEdit->text() );
 
  827   if ( mLayer->
legendUrlFormat() != mLayerLegendUrlFormatComboBox->currentText() )
 
  828     mMetadataFilled = 
false;
 
  833   if ( mSimplifyDrawingGroupBox->isChecked() )
 
  841   simplifyMethod.
setThreshold( mSimplifyDrawingSpinBox->value() );
 
  843   simplifyMethod.
setMaximumScale( mSimplifyMaximumScaleComboBox->scale() );
 
  856   mLayer->
setRefreshOnNofifyMessage( mNotificationMessageCheckBox->isChecked() ? mNotifyMessagValueLineEdit->text() : QString() );
 
  862   updateVariableEditor();
 
  865   QSet<QgsMapLayerDependency> deps;
 
  866   const auto checkedLayers = mLayersDependenciesTreeModel->
checkedLayers();
 
  871     QMessageBox::warning( 
nullptr, tr( 
"Save Dependency" ), tr( 
"This configuration introduces a cycle in data dependencies and will be ignored." ) );
 
  879 void QgsVectorLayerProperties::onCancel()
 
  886     const auto constVectorJoins = mLayer->
vectorJoins();
 
  906     QDomDocument doc( QStringLiteral( 
"qgis" ) );
 
  907     int errorLine, errorColumn;
 
  908     doc.setContent( mOldStyle.
xmlData(), 
false, &myMessage, &errorLine, &errorColumn );
 
  912   if ( mBackupCrs != mLayer->
crs() )
 
  913     mLayer->
setCrs( mBackupCrs );
 
  916 void QgsVectorLayerProperties::urlClicked( 
const QUrl &url )
 
  918   QFileInfo file( url.toLocalFile() );
 
  919   if ( file.exists() && !file.isDir() )
 
  922     QDesktopServices::openUrl( url );
 
  925 void QgsVectorLayerProperties::pbnQueryBuilder_clicked()
 
  934   if ( dialog->exec() )
 
  948 void QgsVectorLayerProperties::pbnIndex_clicked()
 
  953     setCursor( Qt::WaitCursor );
 
  955     setCursor( Qt::ArrowCursor );
 
  958       pbnIndex->setEnabled( 
false );
 
  959       pbnIndex->setText( tr( 
"Spatial Index Exists" ) );
 
  960       QMessageBox::information( 
this, tr( 
"Spatial Index" ), tr( 
"Creation of spatial index successful" ) );
 
  964       QMessageBox::warning( 
this, tr( 
"Spatial Index" ), tr( 
"Creation of spatial index failed" ) );
 
  969 QString QgsVectorLayerProperties::htmlMetadata()
 
  979   mMetadataFilled = 
false;
 
  983 void QgsVectorLayerProperties::loadDefaultStyle_clicked()
 
  986   bool defaultLoadedFlag = 
false;
 
  993     QMessageBox askToUser;
 
  994     askToUser.setText( tr( 
"Load default style from: " ) );
 
  995     askToUser.setIcon( QMessageBox::Question );
 
  996     askToUser.addButton( tr( 
"Cancel" ), QMessageBox::RejectRole );
 
  997     askToUser.addButton( tr( 
"Local Database" ), QMessageBox::NoRole );
 
  998     askToUser.addButton( tr( 
"Datasource Database" ), QMessageBox::YesRole );
 
 1000     switch ( askToUser.exec() )
 
 1006         if ( !defaultLoadedFlag )
 
 1009           QMessageBox::information( 
this, tr( 
"Default Style" ), msg );
 
 1011         if ( msg.compare( tr( 
"Loaded from Provider" ) ) )
 
 1013           QMessageBox::information( 
this, tr( 
"Default Style" ),
 
 1014                                     tr( 
"No default style was found for this layer." ) );
 
 1030   if ( defaultLoadedFlag )
 
 1038     QMessageBox::information( 
this, tr( 
"Default Style" ), myMessage );
 
 1042 void QgsVectorLayerProperties::saveDefaultStyle_clicked()
 
 1051     QMessageBox askToUser;
 
 1052     askToUser.setText( tr( 
"Save default style to: " ) );
 
 1053     askToUser.setIcon( QMessageBox::Question );
 
 1054     askToUser.addButton( tr( 
"Cancel" ), QMessageBox::RejectRole );
 
 1055     askToUser.addButton( tr( 
"Local Database" ), QMessageBox::NoRole );
 
 1056     askToUser.addButton( tr( 
"Datasource Database" ), QMessageBox::YesRole );
 
 1058     switch ( askToUser.exec() )
 
 1064         QString errorMessage;
 
 1067           if ( QMessageBox::question( 
nullptr, QObject::tr( 
"Save style in database" ),
 
 1068                                       QObject::tr( 
"A matching style already exists in the database for this layer. Do you want to overwrite it?" ),
 
 1069                                       QMessageBox::Yes | QMessageBox::No ) == QMessageBox::No )
 
 1074         else if ( !errorMessage.isEmpty() )
 
 1076           QMessageBox::warning( 
nullptr, QObject::tr( 
"Save style in database" ),
 
 1082         if ( errorMsg.isNull() )
 
 1093   bool defaultSavedFlag = 
false;
 
 1099   if ( !defaultSavedFlag )
 
 1101     QMessageBox::warning( 
this, tr( 
"Default Style" ), errorMsg );
 
 1105 void QgsVectorLayerProperties::loadMetadata()
 
 1108   QString myLastUsedDir = myQSettings.
value( QStringLiteral( 
"style/lastStyleDir" ), QDir::homePath() ).toString();
 
 1110   QString myFileName = QFileDialog::getOpenFileName( 
this, tr( 
"Load Layer Metadata from Metadata File" ), myLastUsedDir,
 
 1111                        tr( 
"QGIS Layer Metadata File" ) + 
" (*.qmd)" );
 
 1112   if ( myFileName.isNull() )
 
 1118   bool defaultLoadedFlag = 
false;
 
 1122   if ( defaultLoadedFlag )
 
 1129     QMessageBox::warning( 
this, tr( 
"Load Metadata" ), myMessage );
 
 1132   QFileInfo myFI( myFileName );
 
 1133   QString myPath = myFI.path();
 
 1134   myQSettings.
setValue( QStringLiteral( 
"style/lastStyleDir" ), myPath );
 
 1139 void QgsVectorLayerProperties::saveMetadataAs()
 
 1142   QString myLastUsedDir = myQSettings.
value( QStringLiteral( 
"style/lastStyleDir" ), QDir::homePath() ).toString();
 
 1144   QString myOutputFileName = QFileDialog::getSaveFileName( 
this, tr( 
"Save Layer Metadata as QMD" ),
 
 1145                              myLastUsedDir, tr( 
"QMD File" ) + 
" (*.qmd)" );
 
 1146   if ( myOutputFileName.isNull() ) 
 
 1160   bool defaultLoadedFlag = 
false;
 
 1164   if ( defaultLoadedFlag )
 
 1171     QMessageBox::information( 
this, tr( 
"Save Metadata" ), myMessage );
 
 1174   QFileInfo myFI( myOutputFileName );
 
 1175   QString myPath = myFI.path();
 
 1177   myQSettings.
setValue( QStringLiteral( 
"style/lastStyleDir" ), myPath );
 
 1180 void QgsVectorLayerProperties::saveDefaultMetadata()
 
 1184   bool defaultSavedFlag = 
false;
 
 1186   if ( !defaultSavedFlag )
 
 1188     QMessageBox::warning( 
this, tr( 
"Default Metadata" ), errorMsg );
 
 1192 void QgsVectorLayerProperties::loadDefaultMetadata()
 
 1194   bool defaultLoadedFlag = 
false;
 
 1197   if ( defaultLoadedFlag )
 
 1203     QMessageBox::information( 
this, tr( 
"Default Metadata" ), myMessage );
 
 1208 void QgsVectorLayerProperties::saveStyleAs()
 
 1212   QgsVectorLayerSaveStyleDialog dlg( mLayer );
 
 1219     bool defaultLoadedFlag = 
false;
 
 1220     QString errorMessage;
 
 1222     StyleType type = dlg.currentStyleType();
 
 1228         QString filePath = dlg.outputFilePath();
 
 1230           errorMessage = mLayer->
saveNamedStyle( filePath, defaultLoadedFlag, dlg.styleCategories() );
 
 1232           errorMessage = mLayer->
saveSldStyle( filePath, defaultLoadedFlag );
 
 1235         if ( defaultLoadedFlag )
 
 1242           QMessageBox::information( 
this, tr( 
"Save Style" ), errorMessage );
 
 1249         QString infoWindowTitle = QObject::tr( 
"Save style to DB (%1)" ).arg( mLayer->
providerType() );
 
 1255           if ( QMessageBox::question( 
nullptr, QObject::tr( 
"Save style in database" ),
 
 1256                                       QObject::tr( 
"A matching style already exists in the database for this layer. Do you want to overwrite it?" ),
 
 1257                                       QMessageBox::Yes | QMessageBox::No ) == QMessageBox::No )
 
 1262         else if ( !errorMessage.isEmpty() )
 
 1264           mMessageBar->
pushMessage( infoWindowTitle, errorMessage, Qgis::MessageLevel::Warning );
 
 1270         if ( !errorMessage.isNull() )
 
 1272           mMessageBar->
pushMessage( infoWindowTitle, errorMessage, Qgis::MessageLevel::Warning );
 
 1276           mMessageBar->
pushMessage( infoWindowTitle, tr( 
"Style saved" ), Qgis::MessageLevel::Success );
 
 1282         QString infoWindowTitle = tr( 
"Save default style to local database" );
 
 1283         errorMessage = mLayer->
saveDefaultStyle( defaultLoadedFlag, dlg.styleCategories() );
 
 1284         if ( !defaultLoadedFlag )
 
 1286           mMessageBar->
pushMessage( infoWindowTitle, errorMessage, Qgis::MessageLevel::Warning );
 
 1290           mMessageBar->
pushMessage( infoWindowTitle, tr( 
"Style saved" ), Qgis::MessageLevel::Success );
 
 1298 void QgsVectorLayerProperties::saveMultipleStylesAs()
 
 1300   QgsVectorLayerSaveStyleDialog dlg( mLayer );
 
 1301   dlg.setSaveOnlyCurrentStyle( 
false );
 
 1310     const QListWidget *stylesWidget { dlg.stylesWidget() };
 
 1313     QStringList stylesSelected;
 
 1314     for ( 
int i = 0; i < stylesWidget->count(); i++ )
 
 1316       if ( stylesWidget->item( i )->checkState() == Qt::CheckState::Checked )
 
 1318         stylesSelected.push_back( stylesWidget->item( i )->text() );
 
 1322     if ( ! stylesSelected.isEmpty() )
 
 1325       for ( 
const QString &styleName : std::as_const( stylesSelected ) )
 
 1327         bool defaultLoadedFlag = 
false;
 
 1329         StyleType type = dlg.currentStyleType();
 
 1337             const QString filePath { dlg.outputFilePath() };
 
 1338             QString safePath { filePath };
 
 1339             if ( styleIndex > 0 && stylesSelected.count( ) > 1 )
 
 1342               while ( QFile::exists( safePath ) )
 
 1344                 const QFileInfo fi { filePath };
 
 1345                 safePath = QString( filePath ).replace( 
'.' + fi.completeSuffix(), QStringLiteral( 
"_%1.%2" )
 
 1346                                                         .arg( QString::number( i ) )
 
 1347                                                         .arg( fi.completeSuffix() ) );
 
 1352               message = mLayer->
saveNamedStyle( safePath, defaultLoadedFlag, dlg.styleCategories() );
 
 1354               message = mLayer->
saveSldStyle( safePath, defaultLoadedFlag );
 
 1357             if ( defaultLoadedFlag )
 
 1364               QMessageBox::information( 
this, tr( 
"Save Style" ), message );
 
 1371             QString infoWindowTitle = QObject::tr( 
"Save style '%1' to DB (%2)" )
 
 1379             QString name { dbSettings.
name };
 
 1380             if ( name.isEmpty() )
 
 1386               QStringList ids, names, descriptions;
 
 1389               while ( names.contains( name ) )
 
 1391                 name = QStringLiteral( 
"%1 %2" ).arg( name ).arg( QString::number( i ) );
 
 1396             QString errorMessage;
 
 1399               if ( QMessageBox::question( 
nullptr, QObject::tr( 
"Save style in database" ),
 
 1400                                           QObject::tr( 
"A matching style already exists in the database for this layer. Do you want to overwrite it?" ),
 
 1401                                           QMessageBox::Yes | QMessageBox::No ) == QMessageBox::No )
 
 1406             else if ( !errorMessage.isEmpty() )
 
 1408               mMessageBar->
pushMessage( infoWindowTitle, errorMessage, Qgis::MessageLevel::Warning );
 
 1414             if ( !msgError.isNull() )
 
 1416               mMessageBar->
pushMessage( infoWindowTitle, msgError, Qgis::MessageLevel::Warning );
 
 1420               mMessageBar->
pushMessage( infoWindowTitle, tr( 
"Style '%1' saved" ).arg( styleName ),
 
 1421                                         Qgis::MessageLevel::Success );
 
 1436 void QgsVectorLayerProperties::aboutToShowStyleMenu()
 
 1439   QMenu *m = qobject_cast<QMenu *>( sender() );
 
 1442   m->addAction( mActionLoadStyle );
 
 1443   m->addAction( mActionSaveStyle );
 
 1448     mActionSaveStyle->setText( tr( 
"Save Current Style…" ) );
 
 1449     m->addAction( mActionSaveMultipleStyles );
 
 1453     mActionSaveStyle->setText( tr( 
"Save Style…" ) );
 
 1457   m->addAction( tr( 
"Save as Default" ), 
this, &QgsVectorLayerProperties::saveDefaultStyle_clicked );
 
 1458   m->addAction( tr( 
"Restore Default" ), 
this, &QgsVectorLayerProperties::loadDefaultStyle_clicked );
 
 1465 void QgsVectorLayerProperties::loadStyle()
 
 1470   QStringList ids, names, descriptions;
 
 1475   dlg.initializeLists( ids, names, descriptions, sectionLimit );
 
 1480     QgsMapLayer::StyleCategories categories = dlg.styleCategories();
 
 1481     StyleType type = dlg.currentStyleType();
 
 1482     bool defaultLoadedFlag = 
false;
 
 1488         QString filePath = dlg.filePath();
 
 1491           errorMsg = mLayer->
loadSldStyle( filePath, defaultLoadedFlag );
 
 1495           errorMsg = mLayer->
loadNamedStyle( filePath, defaultLoadedFlag, 
true, categories );
 
 1498         if ( defaultLoadedFlag )
 
 1505           QMessageBox::warning( 
this, tr( 
"Load Style" ), errorMsg );
 
 1511         QString selectedStyleId = dlg.selectedStyleId();
 
 1514         if ( !errorMsg.isNull() )
 
 1516           QMessageBox::warning( 
this, tr( 
"Load Styles from Database" ), errorMsg );
 
 1520         QDomDocument myDocument( QStringLiteral( 
"qgis" ) );
 
 1521         myDocument.setContent( qmlStyle );
 
 1529           QMessageBox::warning( 
this, tr( 
"Load Styles from Database" ),
 
 1530                                 tr( 
"The retrieved style is not a valid named style. Error message: %1" )
 
 1539         if ( defaultLoadedFlag )
 
 1545           QMessageBox::warning( 
this, tr( 
"Load Default Style" ), errorMsg );
 
 1554 void QgsVectorLayerProperties::mButtonAddJoin_clicked()
 
 1559   QList<QgsMapLayer *> joinedLayers;
 
 1560   const QList< QgsVectorLayerJoinInfo > &joins = mLayer->
vectorJoins();
 
 1561   joinedLayers.reserve( joins.size() );
 
 1562   for ( 
int i = 0; i < joins.size(); ++i )
 
 1564     joinedLayers.append( joins[i].joinLayer() );
 
 1568   if ( d.exec() == QDialog::Accepted )
 
 1572     if ( d.createAttributeIndex() )
 
 1581     addJoinToTreeWidget( info );
 
 1582     setPbnQueryBuilderEnabled();
 
 1583     mSourceFieldsPropertiesDialog->
init();
 
 1584     mAttributesFormPropertiesDialog->
init();
 
 1588 void QgsVectorLayerProperties::mButtonEditJoin_clicked()
 
 1590   QTreeWidgetItem *currentJoinItem = mJoinTreeWidget->currentItem();
 
 1591   mJoinTreeWidget_itemDoubleClicked( currentJoinItem, 0 );
 
 1594 void QgsVectorLayerProperties::mJoinTreeWidget_itemDoubleClicked( QTreeWidgetItem *item, 
int )
 
 1596   if ( !mLayer || !item )
 
 1601   QList<QgsMapLayer *> joinedLayers;
 
 1602   QString joinLayerId = item->data( 0, Qt::UserRole ).toString();
 
 1603   const QList< QgsVectorLayerJoinInfo > &joins = mLayer->
vectorJoins();
 
 1605   for ( 
int i = 0; i < joins.size(); ++i )
 
 1611     if ( joinLayer->
id() == joinLayerId )
 
 1618       joinedLayers.append( joinLayer );
 
 1627   d.setWindowTitle( tr( 
"Edit Vector Join" ) );
 
 1628   d.setJoinInfo( joins[j] );
 
 1630   if ( d.exec() == QDialog::Accepted )
 
 1636     int idx = mJoinTreeWidget->indexOfTopLevelItem( item );
 
 1637     mJoinTreeWidget->takeTopLevelItem( idx );
 
 1642     if ( d.createAttributeIndex() )
 
 1651     addJoinToTreeWidget( info, idx );
 
 1653     setPbnQueryBuilderEnabled();
 
 1654     mSourceFieldsPropertiesDialog->
init();
 
 1655     mAttributesFormPropertiesDialog->
init();
 
 1659 void QgsVectorLayerProperties::addJoinToTreeWidget( 
const QgsVectorLayerJoinInfo &join, 
const int insertIndex )
 
 1661   QTreeWidgetItem *joinItem = 
new QTreeWidgetItem();
 
 1662   joinItem->setFlags( Qt::ItemIsEnabled );
 
 1665   if ( !mLayer || !joinLayer )
 
 1670   joinItem->setText( 0, tr( 
"Join layer" ) );
 
 1676   joinItem->setText( 1, joinLayer->
name() );
 
 1678   QFont f = joinItem->font( 0 );
 
 1680   joinItem->setFont( 0, f );
 
 1681   joinItem->setFont( 1, f );
 
 1683   joinItem->setData( 0, Qt::UserRole, join.
joinLayerId() );
 
 1685   QTreeWidgetItem *childJoinField = 
new QTreeWidgetItem();
 
 1686   childJoinField->setText( 0, tr( 
"Join field" ) );
 
 1688   childJoinField->setFlags( Qt::ItemIsEnabled );
 
 1689   joinItem->addChild( childJoinField );
 
 1691   QTreeWidgetItem *childTargetField = 
new QTreeWidgetItem();
 
 1692   childTargetField->setText( 0, tr( 
"Target field" ) );
 
 1694   joinItem->addChild( childTargetField );
 
 1696   QTreeWidgetItem *childMemCache = 
new QTreeWidgetItem();
 
 1697   childMemCache->setText( 0, tr( 
"Cache join layer in virtual memory" ) );
 
 1699     childMemCache->setText( 1, QChar( 0x2714 ) );
 
 1700   joinItem->addChild( childMemCache );
 
 1702   QTreeWidgetItem *childDynForm = 
new QTreeWidgetItem();
 
 1703   childDynForm->setText( 0, tr( 
"Dynamic form" ) );
 
 1705     childDynForm->setText( 1, QChar( 0x2714 ) );
 
 1706   joinItem->addChild( childDynForm );
 
 1708   QTreeWidgetItem *childEditable = 
new QTreeWidgetItem();
 
 1709   childEditable->setText( 0, tr( 
"Editable join layer" ) );
 
 1711     childEditable->setText( 1, QChar( 0x2714 ) );
 
 1712   joinItem->addChild( childEditable );
 
 1714   QTreeWidgetItem *childUpsert = 
new QTreeWidgetItem();
 
 1715   childUpsert->setText( 0, tr( 
"Upsert on edit" ) );
 
 1717     childUpsert->setText( 1, QChar( 0x2714 ) );
 
 1718   joinItem->addChild( childUpsert );
 
 1720   QTreeWidgetItem *childCascade = 
new QTreeWidgetItem();
 
 1721   childCascade->setText( 0, tr( 
"Delete cascade" ) );
 
 1723     childCascade->setText( 1, QChar( 0x2714 ) );
 
 1724   joinItem->addChild( childCascade );
 
 1726   QTreeWidgetItem *childPrefix = 
new QTreeWidgetItem();
 
 1727   childPrefix->setText( 0, tr( 
"Custom field name prefix" ) );
 
 1728   childPrefix->setText( 1, join.
prefix() );
 
 1729   joinItem->addChild( childPrefix );
 
 1731   QTreeWidgetItem *childFields = 
new QTreeWidgetItem();
 
 1732   childFields->setText( 0, tr( 
"Joined fields" ) );
 
 1735     childFields->setText( 1, QLocale().toString( list->count() ) );
 
 1737     childFields->setText( 1, tr( 
"all" ) );
 
 1738   joinItem->addChild( childFields );
 
 1740   if ( insertIndex >= 0 )
 
 1741     mJoinTreeWidget->insertTopLevelItem( insertIndex, joinItem );
 
 1743     mJoinTreeWidget->addTopLevelItem( joinItem );
 
 1745   mJoinTreeWidget->setCurrentItem( joinItem );
 
 1746   mJoinTreeWidget->header()->setSectionResizeMode( QHeaderView::ResizeToContents );
 
 1754 void QgsVectorLayerProperties::openPanel( 
QgsPanelWidget *panel )
 
 1756   QDialog *dlg = 
new QDialog();
 
 1757   QString key = QStringLiteral( 
"/UI/paneldialog/%1" ).arg( panel->
panelTitle() );
 
 1759   dlg->restoreGeometry( settings.
value( key ).toByteArray() );
 
 1761   dlg->setLayout( 
new QVBoxLayout() );
 
 1762   dlg->layout()->addWidget( panel );
 
 1763   QDialogButtonBox *buttonBox = 
new QDialogButtonBox( QDialogButtonBox::Ok );
 
 1764   connect( buttonBox, &QDialogButtonBox::accepted, dlg, &QDialog::accept );
 
 1765   dlg->layout()->addWidget( buttonBox );
 
 1767   settings.
setValue( key, dlg->saveGeometry() );
 
 1771 void QgsVectorLayerProperties::mButtonRemoveJoin_clicked()
 
 1773   QTreeWidgetItem *currentJoinItem = mJoinTreeWidget->currentItem();
 
 1774   if ( !mLayer || !currentJoinItem )
 
 1779   mLayer->
removeJoin( currentJoinItem->data( 0, Qt::UserRole ).toString() );
 
 1780   mJoinTreeWidget->takeTopLevelItem( mJoinTreeWidget->indexOfTopLevelItem( currentJoinItem ) );
 
 1781   setPbnQueryBuilderEnabled();
 
 1782   mSourceFieldsPropertiesDialog->
init();
 
 1783   mAttributesFormPropertiesDialog->
init();
 
 1787 void QgsVectorLayerProperties::mButtonAddWmsDimension_clicked()
 
 1793   QStringList alreadyDefinedDimensions;
 
 1795   const QList<QgsMapLayerServerProperties::WmsDimensionInfo> &dims = serverProperties->
wmsDimensions();
 
 1798     alreadyDefinedDimensions << dim.name;
 
 1802   if ( d.exec() == QDialog::Accepted )
 
 1807     addWmsDimensionInfoToTreeWidget( info );
 
 1811 void QgsVectorLayerProperties::mButtonEditWmsDimension_clicked()
 
 1813   QTreeWidgetItem *currentWmsDimensionItem = mWmsDimensionsTreeWidget->currentItem();
 
 1814   mWmsDimensionsTreeWidget_itemDoubleClicked( currentWmsDimensionItem, 0 );
 
 1817 void QgsVectorLayerProperties::mWmsDimensionsTreeWidget_itemDoubleClicked( QTreeWidgetItem *item, 
int )
 
 1819   if ( !mLayer || !item )
 
 1824   QString wmsDimName = item->data( 0, Qt::UserRole ).toString();
 
 1826   const QList<QgsMapLayerServerProperties::WmsDimensionInfo> &dims = serverProperties->
wmsDimensions();
 
 1827   QStringList alreadyDefinedDimensions;
 
 1829   for ( 
int i = 0; i < dims.size(); ++i )
 
 1831     QString dimName = dims[i].name;
 
 1832     if ( dimName == wmsDimName )
 
 1838       alreadyDefinedDimensions << dimName;
 
 1847   d.setWindowTitle( tr( 
"Edit WMS Dimension" ) );
 
 1848   d.setInfo( dims[j] );
 
 1850   if ( d.exec() == QDialog::Accepted )
 
 1857     int idx = mWmsDimensionsTreeWidget->indexOfTopLevelItem( item );
 
 1858     mWmsDimensionsTreeWidget->takeTopLevelItem( idx );
 
 1862     addWmsDimensionInfoToTreeWidget( info, idx );
 
 1868   QTreeWidgetItem *wmsDimensionItem = 
new QTreeWidgetItem();
 
 1869   wmsDimensionItem->setFlags( Qt::ItemIsEnabled );
 
 1871   wmsDimensionItem->setText( 0, tr( 
"Dimension" ) );
 
 1872   wmsDimensionItem->setText( 1, wmsDim.
name );
 
 1874   QFont f = wmsDimensionItem->font( 0 );
 
 1876   wmsDimensionItem->setFont( 0, f );
 
 1877   wmsDimensionItem->setFont( 1, f );
 
 1879   wmsDimensionItem->setData( 0, Qt::UserRole, wmsDim.
name );
 
 1881   QTreeWidgetItem *childWmsDimensionField = 
new QTreeWidgetItem();
 
 1882   childWmsDimensionField->setText( 0, tr( 
"Field" ) );
 
 1883   childWmsDimensionField->setText( 1, wmsDim.
fieldName );
 
 1884   childWmsDimensionField->setFlags( Qt::ItemIsEnabled );
 
 1885   wmsDimensionItem->addChild( childWmsDimensionField );
 
 1887   QTreeWidgetItem *childWmsDimensionEndField = 
new QTreeWidgetItem();
 
 1888   childWmsDimensionEndField->setText( 0, tr( 
"End field" ) );
 
 1889   childWmsDimensionEndField->setText( 1, wmsDim.
endFieldName );
 
 1890   childWmsDimensionEndField->setFlags( Qt::ItemIsEnabled );
 
 1891   wmsDimensionItem->addChild( childWmsDimensionEndField );
 
 1893   QTreeWidgetItem *childWmsDimensionUnits = 
new QTreeWidgetItem();
 
 1894   childWmsDimensionUnits->setText( 0, tr( 
"Units" ) );
 
 1895   childWmsDimensionUnits->setText( 1, wmsDim.
units );
 
 1896   childWmsDimensionUnits->setFlags( Qt::ItemIsEnabled );
 
 1897   wmsDimensionItem->addChild( childWmsDimensionUnits );
 
 1899   QTreeWidgetItem *childWmsDimensionUnitSymbol = 
new QTreeWidgetItem();
 
 1900   childWmsDimensionUnitSymbol->setText( 0, tr( 
"Unit symbol" ) );
 
 1901   childWmsDimensionUnitSymbol->setText( 1, wmsDim.
unitSymbol );
 
 1902   childWmsDimensionUnitSymbol->setFlags( Qt::ItemIsEnabled );
 
 1903   wmsDimensionItem->addChild( childWmsDimensionUnitSymbol );
 
 1905   QTreeWidgetItem *childWmsDimensionDefaultValue = 
new QTreeWidgetItem();
 
 1906   childWmsDimensionDefaultValue->setText( 0, tr( 
"Default display" ) );
 
 1908   childWmsDimensionDefaultValue->setFlags( Qt::ItemIsEnabled );
 
 1909   wmsDimensionItem->addChild( childWmsDimensionDefaultValue );
 
 1911   QTreeWidgetItem *childWmsDimensionRefValue = 
new QTreeWidgetItem();
 
 1912   childWmsDimensionRefValue->setText( 0, tr( 
"Reference value" ) );
 
 1913   childWmsDimensionRefValue->setText( 1, wmsDim.
referenceValue.toString() );
 
 1914   childWmsDimensionRefValue->setFlags( Qt::ItemIsEnabled );
 
 1915   wmsDimensionItem->addChild( childWmsDimensionRefValue );
 
 1917   if ( insertIndex >= 0 )
 
 1918     mWmsDimensionsTreeWidget->insertTopLevelItem( insertIndex, wmsDimensionItem );
 
 1920     mWmsDimensionsTreeWidget->addTopLevelItem( wmsDimensionItem );
 
 1922   mWmsDimensionsTreeWidget->setCurrentItem( wmsDimensionItem );
 
 1923   mWmsDimensionsTreeWidget->header()->setSectionResizeMode( QHeaderView::ResizeToContents );
 
 1926 void QgsVectorLayerProperties::mButtonRemoveWmsDimension_clicked()
 
 1928   QTreeWidgetItem *currentWmsDimensionItem = mWmsDimensionsTreeWidget->currentItem();
 
 1929   if ( !mLayer || !currentWmsDimensionItem )
 
 1935   serverProperties->
removeWmsDimension( currentWmsDimensionItem->data( 0, Qt::UserRole ).toString() );
 
 1936   mWmsDimensionsTreeWidget->takeTopLevelItem( mWmsDimensionsTreeWidget->indexOfTopLevelItem( currentWmsDimensionItem ) );
 
 1940 void QgsVectorLayerProperties::updateSymbologyPage()
 
 1944   delete mRendererDialog;
 
 1945   mRendererDialog = 
nullptr;
 
 1961     mOptsPage_Style->setEnabled( 
false ); 
 
 1964   if ( mRendererDialog )
 
 1966     mRendererDialog->layout()->setContentsMargins( 0, 0, 0, 0 );
 
 1967     widgetStackRenderers->addWidget( mRendererDialog );
 
 1968     widgetStackRenderers->setCurrentWidget( mRendererDialog );
 
 1969     widgetStackRenderers->currentWidget()->layout()->setContentsMargins( 0, 0, 0, 0 );
 
 1973 void QgsVectorLayerProperties::setPbnQueryBuilderEnabled()
 
 1975   pbnQueryBuilder->setEnabled( mLayer &&
 
 1982     pbnQueryBuilder->setToolTip( tr( 
"Stop editing mode to enable this." ) );
 
 1987 void QgsVectorLayerProperties::pbnUpdateExtents_clicked()
 
 1990   mMetadataFilled = 
false;
 
 1997   bool isMetadataPanel = ( index == 
mOptStackedWidget->indexOf( mOptsPage_Metadata ) );
 
 1998   mBtnStyle->setVisible( ! isMetadataPanel );
 
 1999   mBtnMetadata->setVisible( isMetadataPanel );
 
 2001   if ( index == 
mOptStackedWidget->indexOf( mOptsPage_Information ) && ! mMetadataFilled )
 
 2004     teMetadataViewer->clear();
 
 2005     teMetadataViewer->setHtml( htmlMetadata() );
 
 2006     mMetadataFilled = 
true;
 
 2012 void QgsVectorLayerProperties::mSimplifyDrawingGroupBox_toggled( 
bool checked )
 
 2017     mSimplifyDrawingAtProvider->setEnabled( 
false );
 
 2021     mSimplifyDrawingAtProvider->setEnabled( checked );
 
 2025 void QgsVectorLayerProperties::updateVariableEditor()
 
 2028   mVariableEditor->setContext( &context );
 
 2032   mVariableEditor->reloadContext();
 
 2033   mVariableEditor->setEditableScopeIndex( 2 );
 
 2036 void QgsVectorLayerProperties::showHelp()
 
 2038   const QVariant helpPage = mOptionsStackedWidget->currentWidget()->property( 
"helpPage" );
 
 2040   if ( helpPage.isValid() )
 
 2046     QgsHelp::openHelp( QStringLiteral( 
"working_with_vector/vector_properties.html" ) );
 
 2050 void QgsVectorLayerProperties::updateAuxiliaryStoragePage()
 
 2057     mAuxiliaryStorageInformationGrpBox->setEnabled( 
true );
 
 2058     mAuxiliaryStorageFieldsGrpBox->setEnabled( 
true );
 
 2065     mAuxiliaryStorageFeaturesLineEdit->setText( QLocale().toString( features ) );
 
 2068     mAuxiliaryLayerActionClear->setEnabled( 
true );
 
 2069     mAuxiliaryLayerActionDelete->setEnabled( 
true );
 
 2070     mAuxiliaryLayerActionExport->setEnabled( 
true );
 
 2071     mAuxiliaryLayerActionNew->setEnabled( 
false );
 
 2077       mAuxiliaryStorageFieldsLineEdit->setText( QLocale().toString( fields ) );
 
 2080       mAuxiliaryStorageFieldsTree->clear();
 
 2084         QTreeWidgetItem *item = 
new QTreeWidgetItem();
 
 2086         item->setText( 0, prop.
origin() );
 
 2087         item->setText( 1, prop.
name() );
 
 2088         item->setText( 2, prop.
comment() );
 
 2092         mAuxiliaryStorageFieldsTree->addTopLevelItem( item );
 
 2098     mAuxiliaryStorageInformationGrpBox->setEnabled( 
false );
 
 2099     mAuxiliaryStorageFieldsGrpBox->setEnabled( 
false );
 
 2101     mAuxiliaryLayerActionClear->setEnabled( 
false );
 
 2102     mAuxiliaryLayerActionDelete->setEnabled( 
false );
 
 2103     mAuxiliaryLayerActionExport->setEnabled( 
false );
 
 2104     mAuxiliaryLayerActionNew->setEnabled( 
true );
 
 2106     mAuxiliaryStorageFieldsTree->clear();
 
 2107     mAuxiliaryStorageKeyLineEdit->setText( QString() );
 
 2108     mAuxiliaryStorageFieldsLineEdit->setText( QString() );
 
 2109     mAuxiliaryStorageFeaturesLineEdit->setText( QString() );
 
 2113 void QgsVectorLayerProperties::onAuxiliaryLayerNew()
 
 2121   if ( dlg.exec() == QDialog::Accepted )
 
 2123     updateAuxiliaryStoragePage();
 
 2127 void QgsVectorLayerProperties::onAuxiliaryLayerClear()
 
 2134   const QString msg = tr( 
"Are you sure you want to clear auxiliary data for %1?" ).arg( mLayer->
name() );
 
 2135   QMessageBox::StandardButton reply;
 
 2136   reply = QMessageBox::question( 
this, 
"Clear Auxiliary Data", msg, QMessageBox::Yes | QMessageBox::No );
 
 2138   if ( reply == QMessageBox::Yes )
 
 2140     QApplication::setOverrideCursor( Qt::WaitCursor );
 
 2142     QApplication::restoreOverrideCursor();
 
 2143     updateAuxiliaryStoragePage();
 
 2148 void QgsVectorLayerProperties::onAuxiliaryLayerDelete()
 
 2154   const QString msg = tr( 
"Are you sure you want to delete auxiliary storage for %1?" ).arg( mLayer->
name() );
 
 2155   QMessageBox::StandardButton reply;
 
 2156   reply = QMessageBox::question( 
this, 
"Delete Auxiliary Storage", msg, QMessageBox::Yes | QMessageBox::No );
 
 2158   if ( reply == QMessageBox::Yes )
 
 2160     QApplication::setOverrideCursor( Qt::WaitCursor );
 
 2173     QApplication::restoreOverrideCursor();
 
 2174     updateAuxiliaryStoragePage();
 
 2179 void QgsVectorLayerProperties::onAuxiliaryLayerDeleteField()
 
 2185   QList<QTreeWidgetItem *> items = mAuxiliaryStorageFieldsTree->selectedItems();
 
 2186   if ( items.count() < 1 )
 
 2190   const QTreeWidgetItem *item = items[0];
 
 2193   def.
setName( item->text( 1 ) );
 
 2203   const QString msg = tr( 
"Are you sure you want to delete auxiliary field %1 for %2?" ).arg( item->text( 1 ), item->text( 0 ) );
 
 2205   QMessageBox::StandardButton reply;
 
 2206   const QString title = QObject::tr( 
"Delete Auxiliary Field" );
 
 2207   reply = QMessageBox::question( 
this, title, msg, QMessageBox::Yes | QMessageBox::No );
 
 2209   if ( reply == QMessageBox::Yes )
 
 2211     QApplication::setOverrideCursor( Qt::WaitCursor );
 
 2212     deleteAuxiliaryField( index );
 
 2214     QApplication::restoreOverrideCursor();
 
 2218 void QgsVectorLayerProperties::onAuxiliaryLayerAddField()
 
 2225   if ( dlg.exec() == QDialog::Accepted )
 
 2227     updateAuxiliaryStoragePage();
 
 2231 void QgsVectorLayerProperties::deleteAuxiliaryField( 
int index )
 
 2244     if ( key >= 0 && def.
origin().compare( 
"labeling", Qt::CaseInsensitive ) == 0
 
 2246          && labelingDialog->labelingGui() )
 
 2251     updateAuxiliaryStoragePage();
 
 2252     mSourceFieldsPropertiesDialog->
init();
 
 2256     const QString title = QObject::tr( 
"Delete Auxiliary Field" );
 
 2258     const QString msg = QObject::tr( 
"Unable to remove auxiliary field (%1)" ).arg( errors );
 
 2259     mMessageBar->
pushMessage( title, msg, Qgis::MessageLevel::Warning );