QGIS API Documentation 3.35.0-Master (ffb31addd7f)
Loading...
Searching...
No Matches
qgsvectorlayerproperties.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsdlgvectorlayerproperties.cpp
3 Unified property dialog for vector layers
4 -------------------
5 begin : 2004-01-28
6 copyright : (C) 2004 by Gary E.Sherman
7 email : sherman at mrcc.com
8***************************************************************************/
9
10/***************************************************************************
11 * *
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
16 * *
17 ***************************************************************************/
18
19#include <memory>
20#include <limits>
21
22#include "qgsactionmanager.h"
23#include "qgsjoindialog.h"
24#include "qgssldexportcontext.h"
27#include "qgsapplication.h"
33#include "qgslabelingwidget.h"
34#include "qgsmapcanvas.h"
36#include "qgsmetadatawidget.h"
38#include "qgsproject.h"
39#include "qgsvectorlayer.h"
44#include "qgsdatasourceuri.h"
45#include "qgsrenderer.h"
47#include "qgssettings.h"
49#include "qgsstyle.h"
50#include "qgsauxiliarystorage.h"
55#include "qgslabelinggui.h"
56#include "qgsmessagebar.h"
59#include "qgsmaskingwidget.h"
62#include "qgsproviderregistry.h"
64#include "qgslayertreemodel.h"
65#include "qgsmaptip.h"
66#include "qgsgui.h"
67#include "qgsnative.h"
70#include "qgsfileutils.h"
71#include "qgswebview.h"
72#include "qgswebframe.h"
73#include "qgsexpressionfinder.h"
74#if WITH_QTWEBKIT
75#include <QWebElement>
76#endif
77
78#include <QDesktopServices>
79#include <QMessageBox>
80#include <QDir>
81#include <QFile>
82#include <QFileDialog>
83#include <QFileInfo>
84#include <QFontDialog>
85#include <QComboBox>
86#include <QCheckBox>
87#include <QHeaderView>
88#include <QColorDialog>
89#include <QMenu>
90#include <QUrl>
91#include <QRegularExpressionValidator>
92
93
95 QgsMapCanvas *canvas,
96 QgsMessageBar *messageBar,
97 QgsVectorLayer *lyr,
98 QWidget *parent,
99 Qt::WindowFlags fl
100)
101 : QgsLayerPropertiesDialog( lyr, canvas, QStringLiteral( "VectorLayerProperties" ), parent, fl )
102 , mMessageBar( messageBar )
103 , mLayer( lyr )
104 , mOriginalSubsetSQL( lyr->subsetString() )
105{
106 setupUi( this );
107 connect( pbnQueryBuilder, &QPushButton::clicked, this, &QgsVectorLayerProperties::pbnQueryBuilder_clicked );
108 connect( pbnIndex, &QPushButton::clicked, this, &QgsVectorLayerProperties::pbnIndex_clicked );
109 connect( mCrsSelector, &QgsProjectionSelectionWidget::crsChanged, this, &QgsVectorLayerProperties::mCrsSelector_crsChanged );
110 connect( pbnUpdateExtents, &QPushButton::clicked, this, &QgsVectorLayerProperties::pbnUpdateExtents_clicked );
111 connect( mButtonAddJoin, &QPushButton::clicked, this, &QgsVectorLayerProperties::mButtonAddJoin_clicked );
112 connect( mButtonEditJoin, &QPushButton::clicked, this, &QgsVectorLayerProperties::mButtonEditJoin_clicked );
113 connect( mJoinTreeWidget, &QTreeWidget::itemDoubleClicked, this, &QgsVectorLayerProperties::mJoinTreeWidget_itemDoubleClicked );
114 connect( mButtonRemoveJoin, &QPushButton::clicked, this, &QgsVectorLayerProperties::mButtonRemoveJoin_clicked );
115 connect( mButtonAddWmsDimension, &QPushButton::clicked, this, &QgsVectorLayerProperties::mButtonAddWmsDimension_clicked );
116 connect( mButtonEditWmsDimension, &QPushButton::clicked, this, &QgsVectorLayerProperties::mButtonEditWmsDimension_clicked );
117 connect( mWmsDimensionsTreeWidget, &QTreeWidget::itemDoubleClicked, this, &QgsVectorLayerProperties::mWmsDimensionsTreeWidget_itemDoubleClicked );
118 connect( mButtonRemoveWmsDimension, &QPushButton::clicked, this, &QgsVectorLayerProperties::mButtonRemoveWmsDimension_clicked );
119 connect( mSimplifyDrawingGroupBox, &QGroupBox::toggled, this, &QgsVectorLayerProperties::mSimplifyDrawingGroupBox_toggled );
120 connect( buttonRemoveMetadataUrl, &QPushButton::clicked, this, &QgsVectorLayerProperties::removeSelectedMetadataUrl );
121 connect( buttonAddMetadataUrl, &QPushButton::clicked, this, &QgsVectorLayerProperties::addMetadataUrl );
122 connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsVectorLayerProperties::showHelp );
123
124 mProjectDirtyBlocker = std::make_unique<QgsProjectDirtyBlocker>( QgsProject::instance() );
125
126 // QgsOptionsDialogBase handles saving/restoring of geometry, splitter and current tab states,
127 // switching vertical tabs between icon/text to icon-only modes (splitter collapsed to left),
128 // and connecting QDialogButtonBox's accepted/rejected signals to dialog's accept/reject slots
129 initOptionsBase( false );
130
131 mBtnStyle = new QPushButton( tr( "Style" ), this );
132 QMenu *menuStyle = new QMenu( this );
133 mActionLoadStyle = new QAction( tr( "Load Style…" ), this );
134 connect( mActionLoadStyle, &QAction::triggered, this, &QgsVectorLayerProperties::loadStyle );
135
136 mActionSaveStyle = new QAction( tr( "Save Current Style…" ), this );
137 connect( mActionSaveStyle, &QAction::triggered, this, &QgsVectorLayerProperties::saveStyleAs );
138
139 mActionSaveMultipleStyles = new QAction( tr( "Save Multiple Styles…" ), this );
140 connect( mActionSaveMultipleStyles, &QAction::triggered, this, &QgsVectorLayerProperties::saveMultipleStylesAs );
141
142 mSourceGroupBox->hide();
143
144 mBtnStyle->setMenu( menuStyle );
145 connect( menuStyle, &QMenu::aboutToShow, this, &QgsVectorLayerProperties::aboutToShowStyleMenu );
146 buttonBox->addButton( mBtnStyle, QDialogButtonBox::ResetRole );
147
149
150 connect( buttonBox->button( QDialogButtonBox::Apply ), &QAbstractButton::clicked, this, &QgsVectorLayerProperties::apply );
151 connect( this, &QDialog::accepted, this, &QgsVectorLayerProperties::apply );
152 connect( this, &QDialog::rejected, this, &QgsVectorLayerProperties::rollback );
153
159
160 mMapTipFieldComboBox->setLayer( lyr );
161 mDisplayExpressionWidget->setLayer( lyr );
162 mDisplayExpressionWidget->registerExpressionContextGenerator( this );
163 initMapTipPreview();
164
165 connect( mMapTipInsertFieldButton, &QAbstractButton::clicked, this, &QgsVectorLayerProperties::insertField );
166 connect( mMapTipInsertExpressionButton, &QAbstractButton::clicked, this, &QgsVectorLayerProperties::insertOrEditExpression );
167
168 if ( !mLayer )
169 return;
170
171 connect( mEnableMapTips, &QAbstractButton::toggled, mHtmlMapTipGroupBox, &QWidget::setEnabled );
172 mEnableMapTips->setChecked( mLayer->mapTipsEnabled() );
173
174 QVBoxLayout *layout = nullptr;
175
176 if ( mLayer->isSpatial() )
177 {
178 // Create the Labeling dialog tab
179 layout = new QVBoxLayout( labelingFrame );
180 layout->setContentsMargins( 0, 0, 0, 0 );
181 labelingDialog = new QgsLabelingWidget( mLayer, mCanvas, labelingFrame );
182 labelingDialog->layout()->setContentsMargins( 0, 0, 0, 0 );
183 connect( labelingDialog, &QgsLabelingWidget::auxiliaryFieldCreated, this, [ = ] { updateAuxiliaryStoragePage(); } );
184 layout->addWidget( labelingDialog );
185 labelingFrame->setLayout( layout );
186
187 // Create the masking dialog tab
188 layout = new QVBoxLayout( mMaskingFrame );
189 layout->setContentsMargins( 0, 0, 0, 0 );
190 mMaskingWidget = new QgsMaskingWidget( mMaskingFrame );
191 mMaskingWidget->setLayer( mLayer );
192 mMaskingWidget->layout()->setContentsMargins( 0, 0, 0, 0 );
193 layout->addWidget( mMaskingWidget );
194 mMaskingFrame->setLayout( layout );
195 }
196 else
197 {
198 labelingDialog = nullptr;
199 mOptsPage_Labels->setEnabled( false ); // disable labeling item
200 mOptsPage_Masks->setEnabled( false ); // disable masking item
201 mGeomGroupBox->setEnabled( false );
202 mGeomGroupBox->setVisible( false );
203 mCrsGroupBox->setEnabled( false );
204 mCrsGroupBox->setVisible( false );
205 }
206
207 // Create the Actions dialog tab
208 QVBoxLayout *actionLayout = new QVBoxLayout( actionOptionsFrame );
209 actionLayout->setContentsMargins( 0, 0, 0, 0 );
210 mActionDialog = new QgsAttributeActionDialog( *mLayer->actions(), actionOptionsFrame );
211 mActionDialog->layout()->setContentsMargins( 0, 0, 0, 0 );
212 actionLayout->addWidget( mActionDialog );
213
214 mSourceFieldsPropertiesDialog = new QgsSourceFieldsProperties( mLayer, mSourceFieldsFrame );
215 mSourceFieldsPropertiesDialog->layout()->setContentsMargins( 0, 0, 0, 0 );
216 mSourceFieldsFrame->setLayout( new QVBoxLayout( mSourceFieldsFrame ) );
217 mSourceFieldsFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
218 mSourceFieldsFrame->layout()->addWidget( mSourceFieldsPropertiesDialog );
219
220 connect( mSourceFieldsPropertiesDialog, &QgsSourceFieldsProperties::toggleEditing, this, static_cast<void ( QgsVectorLayerProperties::* )()>( &QgsVectorLayerProperties::toggleEditing ) );
221
222 mAttributesFormPropertiesDialog = new QgsAttributesFormProperties( mLayer, mAttributesFormFrame );
223 mAttributesFormPropertiesDialog->layout()->setContentsMargins( 0, 0, 0, 0 );
224 mAttributesFormFrame->setLayout( new QVBoxLayout( mAttributesFormFrame ) );
225 mAttributesFormFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
226 mAttributesFormFrame->layout()->addWidget( mAttributesFormPropertiesDialog );
227
228 // Metadata tab, before the syncToLayer
229 QVBoxLayout *metadataLayout = new QVBoxLayout( metadataFrame );
230 metadataLayout->setContentsMargins( 0, 0, 0, 0 );
231 mMetadataWidget = new QgsMetadataWidget( this, mLayer );
232 mMetadataWidget->layout()->setContentsMargins( 0, 0, 0, 0 );
233 mMetadataWidget->setMapCanvas( mCanvas );
234 metadataLayout->addWidget( mMetadataWidget );
235 metadataFrame->setLayout( metadataLayout );
236
237 QVBoxLayout *temporalLayout = new QVBoxLayout( temporalFrame );
238 temporalLayout->setContentsMargins( 0, 0, 0, 0 );
239 mTemporalWidget = new QgsVectorLayerTemporalPropertiesWidget( this, mLayer );
240 temporalLayout->addWidget( mTemporalWidget );
241
242 setMetadataWidget( mMetadataWidget, mOptsPage_Metadata );
243
244 mBtnMetadata = new QPushButton( tr( "Metadata" ), this );
245 QMenu *menuMetadata = new QMenu( this );
246 mActionLoadMetadata = menuMetadata->addAction( tr( "Load Metadata…" ), this, &QgsVectorLayerProperties::loadMetadataFromFile );
247 mActionSaveMetadataAs = menuMetadata->addAction( tr( "Save Metadata…" ), this, &QgsVectorLayerProperties::saveMetadataToFile );
248 menuMetadata->addSeparator();
249 menuMetadata->addAction( tr( "Save as Default" ), this, &QgsVectorLayerProperties::saveMetadataAsDefault );
250 menuMetadata->addAction( tr( "Restore Default" ), this, &QgsVectorLayerProperties::loadDefaultMetadata );
251 mBtnMetadata->setMenu( menuMetadata );
252 buttonBox->addButton( mBtnMetadata, QDialogButtonBox::ResetRole );
253
254 mSelectionColorButton->setAllowOpacity( true );
255 mSelectionColorButton->setColorDialogTitle( tr( "Override Selection Color" ) );
256 if ( mCanvas )
257 {
258 mSelectionColorButton->setColor( mCanvas->selectionColor() );
259 mSelectionColorButton->setDefaultColor( mCanvas->selectionColor() );
260 }
261 connect( mRadioOverrideSelectionColor, &QRadioButton::toggled, mSelectionColorButton, &QWidget::setEnabled );
262 mSelectionColorButton->setEnabled( false );
263 connect( mRadioOverrideSelectionSymbol, &QRadioButton::toggled, mSelectionSymbolButton, &QWidget::setEnabled );
264 switch ( mLayer->geometryType() )
265 {
266
268 mSelectionSymbolButton->setSymbolType( Qgis::SymbolType::Marker );
269 break;
271 mSelectionSymbolButton->setSymbolType( Qgis::SymbolType::Line );
272 break;
274 mSelectionSymbolButton->setSymbolType( Qgis::SymbolType::Fill );
275 break;
276
279 break;
280 }
281 mSelectionSymbolButton->setEnabled( false );
282 mRadioDefaultSelectionColor->setChecked( true );
283
284 syncToLayer();
285
286 if ( mLayer->dataProvider() )
287 {
288 //enable spatial index button group if supported by provider, or if one already exists
289 QgsVectorDataProvider::Capabilities capabilities = mLayer->dataProvider()->capabilities();
290 if ( !( capabilities & QgsVectorDataProvider::CreateSpatialIndex ) )
291 {
292 pbnIndex->setEnabled( false );
293 }
295 {
296 pbnIndex->setEnabled( false );
297 pbnIndex->setText( tr( "Spatial Index Exists" ) );
298 }
299
300 if ( capabilities & QgsVectorDataProvider::SelectEncoding )
301 {
302 cboProviderEncoding->addItems( QgsVectorDataProvider::availableEncodings() );
303 QString enc = mLayer->dataProvider()->encoding();
304 int encindex = cboProviderEncoding->findText( enc );
305 if ( encindex < 0 )
306 {
307 cboProviderEncoding->insertItem( 0, enc );
308 encindex = 0;
309 }
310 cboProviderEncoding->setCurrentIndex( encindex );
311 }
312 else if ( mLayer->providerType() == QLatin1String( "ogr" ) )
313 {
314 // if OGR_L_TestCapability(OLCStringsAsUTF8) returns true, OGR provider encoding can be set to only UTF-8
315 // so make encoding box grayed out
316 cboProviderEncoding->addItem( mLayer->dataProvider()->encoding() );
317 cboProviderEncoding->setEnabled( false );
318 }
319 else
320 {
321 // other providers do not use mEncoding, so hide the group completely
322 mDataSourceEncodingFrame->hide();
323 }
324 }
325
326 mCrsSelector->setCrs( mLayer->crs() );
327
328 //insert existing join info
329 const QList< QgsVectorLayerJoinInfo > &joins = mLayer->vectorJoins();
330 for ( const QgsVectorLayerJoinInfo &join : joins )
331 {
332 addJoinToTreeWidget( join );
333 }
334
335 mOldJoins = mLayer->vectorJoins();
336
337 QVBoxLayout *diagLayout = new QVBoxLayout( mDiagramFrame );
338 diagLayout->setContentsMargins( 0, 0, 0, 0 );
339 diagramPropertiesDialog = new QgsDiagramProperties( mLayer, mDiagramFrame, mCanvas );
340 diagramPropertiesDialog->layout()->setContentsMargins( 0, 0, 0, 0 );
341 connect( diagramPropertiesDialog, &QgsDiagramProperties::auxiliaryFieldCreated, this, [ = ] { updateAuxiliaryStoragePage(); } );
342 diagLayout->addWidget( diagramPropertiesDialog );
343 mDiagramFrame->setLayout( diagLayout );
344
345 // Legend tab
346 mLegendWidget->setMapCanvas( mCanvas );
347 mLegendWidget->setLayer( mLayer );
348 mLegendConfigEmbeddedWidget->setLayer( mLayer );
349
350 // WMS Name as layer short name
351 mLayerShortNameLineEdit->setText( mLayer->shortName() );
352 // WMS Name validator
353 QValidator *shortNameValidator = new QRegularExpressionValidator( QgsApplication::shortNameRegularExpression(), this );
354 mLayerShortNameLineEdit->setValidator( shortNameValidator );
355
356 //layer title and abstract
357 mLayerTitleLineEdit->setText( mLayer->title() );
358 mLayerAbstractTextEdit->setPlainText( mLayer->abstract() );
359 mLayerKeywordListLineEdit->setText( mLayer->keywordList() );
360 mLayerDataUrlLineEdit->setText( mLayer->dataUrl() );
361 mLayerDataUrlFormatComboBox->setCurrentIndex(
362 mLayerDataUrlFormatComboBox->findText(
363 mLayer->dataUrlFormat()
364 )
365 );
366 //layer attribution
367 mLayerAttributionLineEdit->setText( mLayer->attribution() );
368 mLayerAttributionUrlLineEdit->setText( mLayer->attributionUrl() );
369
370 // Setup the layer metadata URL
371 tableViewMetadataUrl->setSelectionMode( QAbstractItemView::SingleSelection );
372 tableViewMetadataUrl->setSelectionBehavior( QAbstractItemView::SelectRows );
373 tableViewMetadataUrl->horizontalHeader()->setStretchLastSection( true );
374 tableViewMetadataUrl->horizontalHeader()->setSectionResizeMode( QHeaderView::Stretch );
375
376 mMetadataUrlModel = new QStandardItemModel( tableViewMetadataUrl );
377 mMetadataUrlModel->clear();
378 mMetadataUrlModel->setColumnCount( 3 );
379 QStringList metadataUrlHeaders;
380 metadataUrlHeaders << tr( "URL" ) << tr( "Type" ) << tr( "Format" );
381 mMetadataUrlModel->setHorizontalHeaderLabels( metadataUrlHeaders );
382 tableViewMetadataUrl->setModel( mMetadataUrlModel );
383 tableViewMetadataUrl->setItemDelegate( new MetadataUrlItemDelegate( this ) );
384
385 const QList<QgsMapLayerServerProperties::MetadataUrl> &metaUrls = mLayer->serverProperties()->metadataUrls();
386 for ( const QgsMapLayerServerProperties::MetadataUrl &metaUrl : metaUrls )
387 {
388 const int row = mMetadataUrlModel->rowCount();
389 mMetadataUrlModel->setItem( row, 0, new QStandardItem( metaUrl.url ) );
390 mMetadataUrlModel->setItem( row, 1, new QStandardItem( metaUrl.type ) );
391 mMetadataUrlModel->setItem( row, 2, new QStandardItem( metaUrl.format ) );
392 }
393
394 // layer legend url
395 mLayerLegendUrlLineEdit->setText( mLayer->legendUrl() );
396 mLayerLegendUrlFormatComboBox->setCurrentIndex(
397 mLayerLegendUrlFormatComboBox->findText(
398 mLayer->legendUrlFormat()
399 )
400 );
401
402 //insert existing dimension info
403 QgsMapLayerServerProperties *serverProperties = static_cast<QgsMapLayerServerProperties *>( mLayer->serverProperties() );
404 const QList<QgsMapLayerServerProperties::WmsDimensionInfo> &wmsDims = serverProperties->wmsDimensions();
405 for ( const QgsMapLayerServerProperties::WmsDimensionInfo &dim : wmsDims )
406 {
407 addWmsDimensionInfoToTreeWidget( dim );
408 }
409
410 QString myStyle = QgsApplication::reportStyleSheet();
411 myStyle.append( QStringLiteral( "body { margin: 10px; }\n " ) );
412 teMetadataViewer->clear();
413 teMetadataViewer->document()->setDefaultStyleSheet( myStyle );
414 teMetadataViewer->setHtml( htmlMetadata() );
415 teMetadataViewer->setOpenLinks( false );
416 connect( teMetadataViewer, &QTextBrowser::anchorClicked, this, &QgsVectorLayerProperties::openUrl );
417 mMetadataFilled = true;
418
419 QgsSettings settings;
420 // if dialog hasn't been opened/closed yet, default to Styles tab, which is used most often
421 // this will be read by restoreOptionsBaseUi()
422 if ( !settings.contains( QStringLiteral( "/Windows/VectorLayerProperties/tab" ) ) )
423 {
424 settings.setValue( QStringLiteral( "Windows/VectorLayerProperties/tab" ),
425 mOptStackedWidget->indexOf( mOptsPage_Style ) );
426 }
427
428 QList<QgsMapLayer *> dependencySources;
429 const QSet<QgsMapLayerDependency> constDependencies = mLayer->dependencies();
430 for ( const QgsMapLayerDependency &dep : constDependencies )
431 {
432 QgsMapLayer *layer = QgsProject::instance()->mapLayer( dep.layerId() );
433 if ( layer )
434 dependencySources << layer;
435 }
436
437 mLayersDependenciesTreeModel = new QgsLayerTreeFilterProxyModel( this );
438 mLayersDependenciesTreeModel->setLayerTreeModel( new QgsLayerTreeModel( QgsProject::instance()->layerTreeRoot(), mLayersDependenciesTreeModel ) );
439 mLayersDependenciesTreeModel->setCheckedLayers( dependencySources );
440 connect( QgsProject::instance(), &QObject::destroyed, this, [ = ] {mLayersDependenciesTreeView->setModel( nullptr );} );
441 mLayersDependenciesTreeView->setModel( mLayersDependenciesTreeModel );
442
443 mRefreshSettingsWidget->setLayer( mLayer );
444
445 // auxiliary layer
446 QMenu *menu = new QMenu( this );
447
448 mAuxiliaryLayerActionNew = new QAction( tr( "Create" ), this );
449 menu->addAction( mAuxiliaryLayerActionNew );
450 connect( mAuxiliaryLayerActionNew, &QAction::triggered, this, &QgsVectorLayerProperties::onAuxiliaryLayerNew );
451
452 mAuxiliaryLayerActionClear = new QAction( tr( "Clear" ), this );
453 menu->addAction( mAuxiliaryLayerActionClear );
454 connect( mAuxiliaryLayerActionClear, &QAction::triggered, this, &QgsVectorLayerProperties::onAuxiliaryLayerClear );
455
456 mAuxiliaryLayerActionDelete = new QAction( tr( "Delete" ), this );
457 menu->addAction( mAuxiliaryLayerActionDelete );
458 connect( mAuxiliaryLayerActionDelete, &QAction::triggered, this, &QgsVectorLayerProperties::onAuxiliaryLayerDelete );
459
460 mAuxiliaryLayerActionExport = new QAction( tr( "Export" ), this );
461 menu->addAction( mAuxiliaryLayerActionExport );
462 connect( mAuxiliaryLayerActionExport, &QAction::triggered, this, [ = ] { emit exportAuxiliaryLayer( mLayer->auxiliaryLayer() ); } );
463
464 mAuxiliaryStorageActions->setMenu( menu );
465
466 connect( mAuxiliaryStorageFieldsDeleteBtn, &QPushButton::clicked, this, &QgsVectorLayerProperties::onAuxiliaryLayerDeleteField );
467 connect( mAuxiliaryStorageFieldsAddBtn, &QPushButton::clicked, this, &QgsVectorLayerProperties::onAuxiliaryLayerAddField );
468
469 updateAuxiliaryStoragePage();
470
471 mOptsPage_Information->setProperty( "helpPage", QStringLiteral( "working_with_vector/vector_properties.html#information-properties" ) );
472 mOptsPage_Source->setProperty( "helpPage", QStringLiteral( "working_with_vector/vector_properties.html#source-properties" ) );
473 mOptsPage_Style->setProperty( "helpPage", QStringLiteral( "working_with_vector/vector_properties.html#symbology-properties" ) );
474 mOptsPage_Labels->setProperty( "helpPage", QStringLiteral( "working_with_vector/vector_properties.html#labels-properties" ) );
475 mOptsPage_Masks->setProperty( "helpPage", QStringLiteral( "working_with_vector/vector_properties.html#masks-properties" ) );
476 mOptsPage_Diagrams->setProperty( "helpPage", QStringLiteral( "working_with_vector/vector_properties.html#diagrams-properties" ) );
477 mOptsPage_SourceFields->setProperty( "helpPage", QStringLiteral( "working_with_vector/vector_properties.html#fields-properties" ) );
478 mOptsPage_AttributesForm->setProperty( "helpPage", QStringLiteral( "working_with_vector/vector_properties.html#attributes-form-properties" ) );
479 mOptsPage_Joins->setProperty( "helpPage", QStringLiteral( "working_with_vector/vector_properties.html#joins-properties" ) );
480 mOptsPage_AuxiliaryStorage->setProperty( "helpPage", QStringLiteral( "working_with_vector/vector_properties.html#auxiliary-storage-properties" ) );
481 mOptsPage_Actions->setProperty( "helpPage", QStringLiteral( "working_with_vector/vector_properties.html#actions-properties" ) );
482 mOptsPage_Display->setProperty( "helpPage", QStringLiteral( "working_with_vector/vector_properties.html#display-properties" ) );
483 mOptsPage_Rendering->setProperty( "helpPage", QStringLiteral( "working_with_vector/vector_properties.html#rendering-properties" ) );
484 mOptsPage_Temporal->setProperty( "helpPage", QStringLiteral( "working_with_vector/vector_properties.html#temporal-properties" ) );
485 mOptsPage_Variables->setProperty( "helpPage", QStringLiteral( "working_with_vector/vector_properties.html#variables-properties" ) );
486 mOptsPage_Metadata->setProperty( "helpPage", QStringLiteral( "working_with_vector/vector_properties.html#metadata-properties" ) );
487 mOptsPage_DataDependencies->setProperty( "helpPage", QStringLiteral( "working_with_vector/vector_properties.html#dependencies-properties" ) ) ;
488 mOptsPage_Legend->setProperty( "helpPage", QStringLiteral( "working_with_vector/vector_properties.html#legend-properties" ) );
489 mOptsPage_Server->setProperty( "helpPage", QStringLiteral( "working_with_vector/vector_properties.html#qgis-server-properties" ) );
490
491
493
494 initialize();
495}
496
497void QgsVectorLayerProperties::toggleEditing()
498{
499 if ( !mLayer )
500 return;
501
502 emit toggleEditing( mLayer );
503
504 setPbnQueryBuilderEnabled();
505}
506
507void QgsVectorLayerProperties::insertField()
508{
509 // Convert the selected field to an expression and
510 // insert it into the action at the cursor position
511 if ( mMapTipFieldComboBox->currentField().isEmpty() )
512 return;
513 QString expression = QStringLiteral( "[%\"" );
514 expression += mMapTipFieldComboBox->currentField();
515 expression += QLatin1String( "\"%]" );
516
517 mMapTipWidget->insertText( expression );
518}
519
520void QgsVectorLayerProperties::insertOrEditExpression()
521{
522 // Get the linear indexes if the start and end of the selection
523 int selectionStart = mMapTipWidget->selectionStart();
524 int selectionEnd = mMapTipWidget->selectionEnd();
525 QString expression = QgsExpressionFinder::findAndSelectActiveExpression( mMapTipWidget );
526
527 QgsExpressionContext context = createExpressionContext();
528 QgsExpressionBuilderDialog exprDlg( mLayer, expression, this, QStringLiteral( "generic" ), context );
529
530 exprDlg.setWindowTitle( tr( "Insert Expression" ) );
531 if ( exprDlg.exec() == QDialog::Accepted && !exprDlg.expressionText().trimmed().isEmpty() )
532 mMapTipWidget->insertText( "[%" + exprDlg.expressionText().trimmed() + "%]" );
533 else // Restore the selection
534 mMapTipWidget->setLinearSelection( selectionStart, selectionEnd );
535}
536
537void QgsVectorLayerProperties::addMetadataUrl()
538{
539 const int row = mMetadataUrlModel->rowCount();
540 mMetadataUrlModel->setItem( row, 0, new QStandardItem( QLatin1String() ) );
541 mMetadataUrlModel->setItem( row, 1, new QStandardItem( QLatin1String() ) );
542 mMetadataUrlModel->setItem( row, 2, new QStandardItem( QLatin1String() ) );
543}
544
545void QgsVectorLayerProperties::removeSelectedMetadataUrl()
546{
547 const QModelIndexList selectedRows = tableViewMetadataUrl->selectionModel()->selectedRows();
548 if ( selectedRows.empty() )
549 return;
550 mMetadataUrlModel->removeRow( selectedRows[0].row() );
551}
552
554{
555 if ( !mSourceWidget )
556 {
557 mSourceWidget = QgsGui::sourceWidgetProviderRegistry()->createWidget( mLayer );
558 if ( mSourceWidget )
559 {
560 QHBoxLayout *layout = new QHBoxLayout();
561 layout->addWidget( mSourceWidget );
562 mSourceGroupBox->setLayout( layout );
563 mSourceGroupBox->show();
564
565 connect( mSourceWidget, &QgsProviderSourceWidget::validChanged, this, [ = ]( bool isValid )
566 {
567 buttonBox->button( QDialogButtonBox::Apply )->setEnabled( isValid );
568 buttonBox->button( QDialogButtonBox::Ok )->setEnabled( isValid );
569 } );
570 }
571 }
572
573 if ( mSourceWidget )
574 mSourceWidget->setSourceUri( mLayer->source() );
575
576 // populate the general information
577 mLayerOrigNameLineEdit->setText( mLayer->name() );
578 mBackupCrs = mLayer->crs();
579
580 //see if we are dealing with a pg layer here
581 mSubsetGroupBox->setEnabled( true );
582 txtSubsetSQL->setText( mLayer->subsetString() );
583 // if the user is allowed to type an adhoc query, the app will crash if the query
584 // is bad. For this reason, the sql box is disabled and the query must be built
585 // using the query builder, either by typing it in by hand or using the buttons, etc
586 // on the builder. If the ability to enter a query directly into the box is required,
587 // a mechanism to check it must be implemented.
588 txtSubsetSQL->setReadOnly( true );
589 txtSubsetSQL->setCaretWidth( 0 );
590 txtSubsetSQL->setCaretLineVisible( false );
591 setPbnQueryBuilderEnabled();
592
593 mDisplayExpressionWidget->setField( mLayer->displayExpression() );
594 mEnableMapTips->setChecked( mLayer->mapTipsEnabled() );
595 mMapTipWidget->setText( mLayer->mapTipTemplate() );
596
597 // set up the scale based layer visibility stuff....
598 mScaleRangeWidget->setScaleRange( mLayer->minimumScale(), mLayer->maximumScale() );
599 mScaleVisibilityGroupBox->setChecked( mLayer->hasScaleBasedVisibility() );
600 mScaleRangeWidget->setMapCanvas( mCanvas );
601
602 mUseReferenceScaleGroupBox->setChecked( mLayer->renderer() && mLayer->renderer()->referenceScale() > 0 );
603 mReferenceScaleWidget->setShowCurrentScaleButton( true );
604 mReferenceScaleWidget->setMapCanvas( mCanvas );
605 if ( mUseReferenceScaleGroupBox->isChecked() )
606 mReferenceScaleWidget->setScale( mLayer->renderer()->referenceScale() );
607 else if ( mCanvas )
608 mReferenceScaleWidget->setScale( mCanvas->scale() );
609
610 // get simplify drawing configuration
611 const QgsVectorSimplifyMethod &simplifyMethod = mLayer->simplifyMethod();
612 mSimplifyDrawingGroupBox->setChecked( simplifyMethod.simplifyHints() != QgsVectorSimplifyMethod::NoSimplification );
613 mSimplifyDrawingSpinBox->setValue( simplifyMethod.threshold() );
614 mSimplifyDrawingSpinBox->setClearValue( 1.0 );
615
616 QgsVectorLayerSelectionProperties *selectionProperties = qobject_cast< QgsVectorLayerSelectionProperties *>( mLayer->selectionProperties() );
617 if ( selectionProperties->selectionColor().isValid() )
618 {
619 mSelectionColorButton->setColor( selectionProperties->selectionColor() );
620 }
621 if ( QgsSymbol *symbol = selectionProperties->selectionSymbol() )
622 {
623 mSelectionSymbolButton->setSymbol( symbol->clone() );
624 }
625 switch ( selectionProperties->selectionRenderingMode() )
626 {
628 mRadioDefaultSelectionColor->setChecked( true );
629 break;
630
632 {
633 if ( selectionProperties->selectionColor().isValid() )
634 {
635 mRadioOverrideSelectionColor->setChecked( true );
636 }
637 else
638 {
639 mRadioDefaultSelectionColor->setChecked( true );
640 }
641 break;
642 }
643
645 if ( selectionProperties->selectionSymbol() )
646 {
647 mRadioOverrideSelectionSymbol->setChecked( true );
648 }
649 else
650 {
651 mRadioDefaultSelectionColor->setChecked( true );
652 }
653 break;
654 }
655
656 QString remark = QStringLiteral( " (%1)" ).arg( tr( "Not supported" ) );
657 const QgsVectorDataProvider *provider = mLayer->dataProvider();
658 if ( !( provider && ( provider->capabilities() & QgsVectorDataProvider::SimplifyGeometries ) ) )
659 {
660 mSimplifyDrawingAtProvider->setChecked( false );
661 mSimplifyDrawingAtProvider->setEnabled( false );
662 if ( !mSimplifyDrawingAtProvider->text().endsWith( remark ) )
663 mSimplifyDrawingAtProvider->setText( mSimplifyDrawingAtProvider->text().append( remark ) );
664 }
665 else
666 {
667 mSimplifyDrawingAtProvider->setChecked( !simplifyMethod.forceLocalOptimization() );
668 mSimplifyDrawingAtProvider->setEnabled( mSimplifyDrawingGroupBox->isChecked() );
669 if ( mSimplifyDrawingAtProvider->text().endsWith( remark ) )
670 {
671 QString newText = mSimplifyDrawingAtProvider->text();
672 newText.chop( remark.size() );
673 mSimplifyDrawingAtProvider->setText( newText );
674 }
675 }
676
677 // disable simplification for point layers, now it is not implemented
678 if ( mLayer->geometryType() == Qgis::GeometryType::Point )
679 {
680 mSimplifyDrawingGroupBox->setChecked( false );
681 mSimplifyDrawingGroupBox->setEnabled( false );
682 }
683
684 // Default local simplification algorithm
685 mSimplifyAlgorithmComboBox->addItem( tr( "Distance" ), QgsVectorSimplifyMethod::Distance );
686 mSimplifyAlgorithmComboBox->addItem( tr( "SnapToGrid" ), QgsVectorSimplifyMethod::SnapToGrid );
687 mSimplifyAlgorithmComboBox->addItem( tr( "Visvalingam" ), QgsVectorSimplifyMethod::Visvalingam );
688 mSimplifyAlgorithmComboBox->setCurrentIndex( mSimplifyAlgorithmComboBox->findData( simplifyMethod.simplifyAlgorithm() ) );
689
690 QStringList myScalesList = Qgis::defaultProjectScales().split( ',' );
691 myScalesList.append( QStringLiteral( "1:1" ) );
692 mSimplifyMaximumScaleComboBox->updateScales( myScalesList );
693 mSimplifyMaximumScaleComboBox->setScale( simplifyMethod.maximumScale() );
694
695 mForceRasterCheckBox->setChecked( mLayer->renderer() && mLayer->renderer()->forceRasterRender() );
696
697 mRefreshSettingsWidget->syncToLayer();
698
699 mRefreshLayerNotificationCheckBox->setChecked( mLayer->isRefreshOnNotifyEnabled() );
700 mNotificationMessageCheckBox->setChecked( !mLayer->refreshOnNotifyMessage().isEmpty() );
701 mNotifyMessagValueLineEdit->setText( mLayer->refreshOnNotifyMessage() );
702
703
704 // load appropriate symbology page (V1 or V2)
705 updateSymbologyPage();
706
707 mActionDialog->init( *mLayer->actions(), mLayer->attributeTableConfig() );
708
709 if ( labelingDialog )
710 labelingDialog->adaptToLayer();
711
712 mSourceFieldsPropertiesDialog->init();
713 mAttributesFormPropertiesDialog->init();
714
715 // set initial state for variable editor
716 updateVariableEditor();
717
718 if ( diagramPropertiesDialog )
719 diagramPropertiesDialog->syncToLayer();
720
721 // sync all plugin dialogs
722 for ( QgsMapLayerConfigWidget *page : std::as_const( mConfigWidgets ) )
723 {
724 page->syncToLayer( mLayer );
725 }
726
727 mMetadataWidget->setMetadata( &mLayer->metadata() );
728
729 mTemporalWidget->syncToLayer();
730
731 mLegendWidget->setLayer( mLayer );
732
733}
734
736{
737 if ( mSourceWidget )
738 {
739 const QString newSource = mSourceWidget->sourceUri();
740 if ( newSource != mLayer->source() )
741 {
742 mLayer->setDataSource( newSource, mLayer->name(), mLayer->providerType(),
743 QgsDataProvider::ProviderOptions(), QgsDataProvider::ReadFlags() );
744 }
745 }
746
747 if ( labelingDialog )
748 {
749 labelingDialog->writeSettingsToLayer();
750 }
751 mBackupCrs = mLayer->crs();
752 // apply legend settings
753 mLegendWidget->applyToLayer();
754 mLegendConfigEmbeddedWidget->applyToLayer();
755
756 // save metadata
757 mMetadataWidget->acceptMetadata();
758 mMetadataFilled = false;
759
760 // save masking settings
761 if ( mMaskingWidget && mMaskingWidget->hasBeenPopulated() )
762 mMaskingWidget->apply();
763
764 //
765 // Set up sql subset query if applicable
766 //
767 mSubsetGroupBox->setEnabled( true );
768
769 if ( txtSubsetSQL->text() != mLayer->subsetString() )
770 {
771 // set the subset sql for the layer
772 mLayer->setSubsetString( txtSubsetSQL->text() );
773 mMetadataFilled = false;
774 }
775 mOriginalSubsetSQL = mLayer->subsetString();
776
777 // set up the scale based layer visibility stuff....
778 mLayer->setScaleBasedVisibility( mScaleVisibilityGroupBox->isChecked() );
779 mLayer->setMaximumScale( mScaleRangeWidget->maximumScale() );
780 mLayer->setMinimumScale( mScaleRangeWidget->minimumScale() );
781
782 // provider-specific options
783 if ( mLayer->dataProvider() )
784 {
786 {
787 mLayer->setProviderEncoding( cboProviderEncoding->currentText() );
788 }
789 }
790
791 mLayer->setDisplayExpression( mDisplayExpressionWidget->asExpression() );
792 mLayer->setMapTipsEnabled( mEnableMapTips->isChecked() );
793 mLayer->setMapTipTemplate( mMapTipWidget->text() );
794
795 mLayer->actions()->clearActions();
796 const auto constActions = mActionDialog->actions();
797 for ( const QgsAction &action : constActions )
798 {
799 mLayer->actions()->addAction( action );
800 }
801 QgsAttributeTableConfig attributeTableConfig = mLayer->attributeTableConfig();
802 attributeTableConfig.update( mLayer->fields() );
803 attributeTableConfig.setActionWidgetStyle( mActionDialog->attributeTableWidgetStyle() );
804 QVector<QgsAttributeTableConfig::ColumnConfig> columns = attributeTableConfig.columns();
805
806 for ( int i = 0; i < columns.size(); ++i )
807 {
808 if ( columns.at( i ).type == QgsAttributeTableConfig::Action )
809 {
810 columns[i].hidden = !mActionDialog->showWidgetInAttributeTable();
811 }
812 }
813
814 attributeTableConfig.setColumns( columns );
815
816 mLayer->setAttributeTableConfig( attributeTableConfig );
817
818 mLayer->setName( mLayerOrigNameLineEdit->text() );
819
820 mAttributesFormPropertiesDialog->apply();
821 mSourceFieldsPropertiesDialog->apply();
822
823 // Update temporal properties
824 mTemporalWidget->saveTemporalProperties();
825
826 if ( mLayer->renderer() )
827 {
828 QgsRendererPropertiesDialog *dlg = static_cast<QgsRendererPropertiesDialog *>( widgetStackRenderers->currentWidget() );
829 dlg->apply();
830 }
831
832 //apply diagram settings
833 diagramPropertiesDialog->apply();
834
835 // apply all plugin dialogs
836 for ( QgsMapLayerConfigWidget *page : std::as_const( mConfigWidgets ) )
837 {
838 page->apply();
839 }
840
841 //layer title and abstract
842 if ( mLayer->shortName() != mLayerShortNameLineEdit->text() )
843 mMetadataFilled = false;
844 mLayer->setShortName( mLayerShortNameLineEdit->text() );
845
846 if ( mLayer->title() != mLayerTitleLineEdit->text() )
847 mMetadataFilled = false;
848 mLayer->setTitle( mLayerTitleLineEdit->text() );
849
850 if ( mLayer->abstract() != mLayerAbstractTextEdit->toPlainText() )
851 mMetadataFilled = false;
852 mLayer->setAbstract( mLayerAbstractTextEdit->toPlainText() );
853
854 if ( mLayer->keywordList() != mLayerKeywordListLineEdit->text() )
855 mMetadataFilled = false;
856 mLayer->setKeywordList( mLayerKeywordListLineEdit->text() );
857
858 if ( mLayer->dataUrl() != mLayerDataUrlLineEdit->text() )
859 mMetadataFilled = false;
860 mLayer->setDataUrl( mLayerDataUrlLineEdit->text() );
861
862 if ( mLayer->dataUrlFormat() != mLayerDataUrlFormatComboBox->currentText() )
863 mMetadataFilled = false;
864 mLayer->setDataUrlFormat( mLayerDataUrlFormatComboBox->currentText() );
865
866 //layer attribution
867 if ( mLayer->attribution() != mLayerAttributionLineEdit->text() )
868 mMetadataFilled = false;
869 mLayer->setAttribution( mLayerAttributionLineEdit->text() );
870
871 if ( mLayer->attributionUrl() != mLayerAttributionUrlLineEdit->text() )
872 mMetadataFilled = false;
873 mLayer->setAttributionUrl( mLayerAttributionUrlLineEdit->text() );
874
875 // Metadata URL
876 QList<QgsMapLayerServerProperties::MetadataUrl> metaUrls;
877 for ( int row = 0; row < mMetadataUrlModel->rowCount() ; row++ )
878 {
880 metaUrl.url = mMetadataUrlModel->item( row, 0 )->text();
881 metaUrl.type = mMetadataUrlModel->item( row, 1 )->text();
882 metaUrl.format = mMetadataUrlModel->item( row, 2 )->text();
883 metaUrls.append( metaUrl );
884 mMetadataFilled = false;
885 }
886 mLayer->serverProperties()->setMetadataUrls( metaUrls );
887
888 // LegendURL
889 if ( mLayer->legendUrl() != mLayerLegendUrlLineEdit->text() )
890 mMetadataFilled = false;
891 mLayer->setLegendUrl( mLayerLegendUrlLineEdit->text() );
892
893 if ( mLayer->legendUrlFormat() != mLayerLegendUrlFormatComboBox->currentText() )
894 mMetadataFilled = false;
895 mLayer->setLegendUrlFormat( mLayerLegendUrlFormatComboBox->currentText() );
896
897 //layer simplify drawing configuration
898 QgsVectorSimplifyMethod::SimplifyHints simplifyHints = QgsVectorSimplifyMethod::NoSimplification;
899 if ( mSimplifyDrawingGroupBox->isChecked() )
900 {
902 if ( mSimplifyDrawingSpinBox->value() > 1 ) simplifyHints |= QgsVectorSimplifyMethod::AntialiasingSimplification;
903 }
904 QgsVectorSimplifyMethod simplifyMethod = mLayer->simplifyMethod();
905 simplifyMethod.setSimplifyHints( simplifyHints );
906 simplifyMethod.setSimplifyAlgorithm( static_cast< QgsVectorSimplifyMethod::SimplifyAlgorithm >( mSimplifyAlgorithmComboBox->currentData().toInt() ) );
907 simplifyMethod.setThreshold( mSimplifyDrawingSpinBox->value() );
908 simplifyMethod.setForceLocalOptimization( !mSimplifyDrawingAtProvider->isChecked() );
909 simplifyMethod.setMaximumScale( mSimplifyMaximumScaleComboBox->scale() );
910 mLayer->setSimplifyMethod( simplifyMethod );
911
912 if ( mLayer->renderer() )
913 {
914 mLayer->renderer()->setForceRasterRender( mForceRasterCheckBox->isChecked() );
915 mLayer->renderer()->setReferenceScale( mUseReferenceScaleGroupBox->isChecked() ? mReferenceScaleWidget->scale() : -1 );
916 }
917
918
919 QgsVectorLayerSelectionProperties *selectionProperties = qobject_cast< QgsVectorLayerSelectionProperties *>( mLayer->selectionProperties() );
920 if ( mSelectionColorButton->color() != mSelectionColorButton->defaultColor() )
921 selectionProperties->setSelectionColor( mSelectionColorButton->color() );
922 else
923 selectionProperties->setSelectionColor( QColor() );
924 if ( QgsSymbol *symbol = mSelectionSymbolButton->symbol() )
925 selectionProperties->setSelectionSymbol( symbol->clone() );
926
927 if ( mRadioOverrideSelectionSymbol->isChecked() )
928 {
930 }
931 else if ( mRadioOverrideSelectionColor->isChecked() )
932 {
934 }
935 else
936 {
938 }
939
940 mRefreshSettingsWidget->saveToLayer();
941
942 mLayer->setRefreshOnNotifyEnabled( mRefreshLayerNotificationCheckBox->isChecked() );
943 mLayer->setRefreshOnNofifyMessage( mNotificationMessageCheckBox->isChecked() ? mNotifyMessagValueLineEdit->text() : QString() );
944
945 mOldJoins = mLayer->vectorJoins();
946
947 //save variables
948 QgsExpressionContextUtils::setLayerVariables( mLayer, mVariableEditor->variablesInActiveScope() );
949 updateVariableEditor();
950
951 // save dependencies
952 QSet<QgsMapLayerDependency> deps;
953 const auto checkedLayers = mLayersDependenciesTreeModel->checkedLayers();
954 for ( const QgsMapLayer *layer : checkedLayers )
955 deps << QgsMapLayerDependency( layer->id() );
956 if ( ! mLayer->setDependencies( deps ) )
957 {
958 QMessageBox::warning( nullptr, tr( "Save Dependency" ), tr( "This configuration introduces a cycle in data dependencies and will be ignored." ) );
959 }
960
961 mLayer->triggerRepaint();
962 // notify the project we've made a change
963 mProjectDirtyBlocker.reset();
965 mProjectDirtyBlocker = std::make_unique<QgsProjectDirtyBlocker>( QgsProject::instance() );
966
967}
968
970{
971 if ( mOldJoins != mLayer->vectorJoins() )
972 {
973 // need to undo changes in vector layer joins - they are applied directly to the layer (not in apply())
974 // so other parts of the properties dialog can use the fields from the joined layers
975
976 const auto constVectorJoins = mLayer->vectorJoins();
977 for ( const QgsVectorLayerJoinInfo &info : constVectorJoins )
978 mLayer->removeJoin( info.joinLayerId() );
979
980 for ( const QgsVectorLayerJoinInfo &info : std::as_const( mOldJoins ) )
981 mLayer->addJoin( info );
982 }
983
984 if ( mOriginalSubsetSQL != mLayer->subsetString() )
985 {
986 // need to undo changes in subset string - they are applied directly to the layer (not in apply())
987 // by QgsQueryBuilder::accept()
988
989 mLayer->setSubsetString( mOriginalSubsetSQL );
990 }
991
992 // Store it because QgsLayerPropertiesDialog::rollback() calls syncToLayer() which
993 // resets the backupCrs
994 const QgsCoordinateReferenceSystem backupCrs { mBackupCrs };
995
997
998 if ( backupCrs != mLayer->crs() )
999 mLayer->setCrs( backupCrs );
1000
1001}
1002
1003void QgsVectorLayerProperties::pbnQueryBuilder_clicked()
1004{
1005 // launch the query builder
1007
1008 // Set the sql in the query builder to the same in the prop dialog
1009 // (in case the user has already changed it)
1010 dialog->setSubsetString( txtSubsetSQL->text() );
1011 // Open the query builder
1012 if ( dialog->exec() )
1013 {
1014 // if the sql is changed, update it in the prop subset text box
1015 txtSubsetSQL->setText( dialog->subsetString() );
1016 //TODO If the sql is changed in the prop dialog, the layer extent should be recalculated
1017
1018 // The datasource for the layer needs to be updated with the new sql since this gets
1019 // saved to the project file. This should happen at the map layer level...
1020
1021 }
1022 // delete the query builder object
1023 delete dialog;
1024}
1025
1026void QgsVectorLayerProperties::pbnIndex_clicked()
1027{
1028 QgsVectorDataProvider *pr = mLayer->dataProvider();
1029 if ( pr )
1030 {
1031 setCursor( Qt::WaitCursor );
1032 bool errval = pr->createSpatialIndex();
1033 setCursor( Qt::ArrowCursor );
1034 if ( errval )
1035 {
1036 pbnIndex->setEnabled( false );
1037 pbnIndex->setText( tr( "Spatial Index Exists" ) );
1038 QMessageBox::information( this, tr( "Spatial Index" ), tr( "Creation of spatial index successful" ) );
1039 }
1040 else
1041 {
1042 QMessageBox::warning( this, tr( "Spatial Index" ), tr( "Creation of spatial index failed" ) );
1043 }
1044 }
1045}
1046
1047QString QgsVectorLayerProperties::htmlMetadata()
1048{
1049 return mLayer->htmlMetadata();
1050}
1051
1052void QgsVectorLayerProperties::mCrsSelector_crsChanged( const QgsCoordinateReferenceSystem &crs )
1053{
1054
1055 QgsDatumTransformDialog::run( crs, QgsProject::instance()->crs(), this, mCanvas, tr( "Select Transformation for the vector layer" ) );
1056 mLayer->setCrs( crs );
1057 mMetadataFilled = false;
1058 mMetadataWidget->crsChanged();
1059}
1060
1061void QgsVectorLayerProperties::saveMultipleStylesAs()
1062{
1063 QgsMapLayerSaveStyleDialog dlg( mLayer );
1064 dlg.setSaveOnlyCurrentStyle( false );
1065 QgsSettings settings;
1066
1067 if ( dlg.exec() )
1068 {
1069 apply();
1070
1071 // Store the original style, that we can restore at the end
1072 const QString originalStyle { mLayer->styleManager()->currentStyle() };
1073 const QListWidget *stylesWidget { dlg.stylesWidget() };
1074
1075 // Collect selected (checked) styles for export/save
1076 QStringList stylesSelected;
1077 for ( int i = 0; i < stylesWidget->count(); i++ )
1078 {
1079 if ( stylesWidget->item( i )->checkState() == Qt::CheckState::Checked )
1080 {
1081 stylesSelected.push_back( stylesWidget->item( i )->text() );
1082 }
1083 }
1084
1085 if ( ! stylesSelected.isEmpty() )
1086 {
1087 int styleIndex = 0;
1088 for ( const QString &styleName : std::as_const( stylesSelected ) )
1089 {
1090 bool defaultLoadedFlag = false;
1091
1092 StyleType type = dlg.currentStyleType();
1093 mLayer->styleManager()->setCurrentStyle( styleName );
1094 switch ( type )
1095 {
1096 case QML:
1097 case SLD:
1098 {
1099 QString message;
1100 const QString filePath { dlg.outputFilePath() };
1101 const QFileInfo fi { filePath };
1102 QString safePath { QString( filePath ).replace( fi.baseName(),
1103 QStringLiteral( "%1_%2" ).arg( fi.baseName(), QgsFileUtils::stringToSafeFilename( styleName ) ) ) };
1104 if ( styleIndex > 0 && stylesSelected.count( ) > 1 )
1105 {
1106 int i = 1;
1107 while ( QFile::exists( safePath ) )
1108 {
1109 const QFileInfo fi { safePath };
1110 safePath = QString( safePath ).replace( '.' + fi.completeSuffix(),
1111 QStringLiteral( "_%1.%2" ).arg( QString::number( i ), fi.completeSuffix() ) );
1112 i++;
1113 }
1114 }
1115 if ( type == QML )
1116 message = mLayer->saveNamedStyle( safePath, defaultLoadedFlag, dlg.styleCategories() );
1117 else
1118 message = mLayer->saveSldStyle( safePath, defaultLoadedFlag );
1119
1120 //reset if the default style was loaded OK only
1121 if ( defaultLoadedFlag )
1122 {
1123 syncToLayer();
1124 }
1125 else
1126 {
1127 //let the user know what went wrong
1128 QMessageBox::information( this, tr( "Save Style" ), message );
1129 }
1130
1131 break;
1132 }
1133 case DatasourceDatabase:
1134 {
1135 QString infoWindowTitle = QObject::tr( "Save style '%1' to DB (%2)" )
1136 .arg( styleName, mLayer->providerType() );
1137 QString msgError;
1138
1139 QgsMapLayerSaveStyleDialog::SaveToDbSettings dbSettings = dlg.saveToDbSettings();
1140
1141 // If a name is defined, we add _1 etc. else we use the style name
1142 QString name { dbSettings.name };
1143 if ( name.isEmpty() )
1144 {
1145 name = styleName;
1146 }
1147 else
1148 {
1149 name += QStringLiteral( "_%1" ).arg( styleName );
1150 QStringList ids, names, descriptions;
1151 mLayer->listStylesInDatabase( ids, names, descriptions, msgError );
1152 int i = 1;
1153 while ( names.contains( name ) )
1154 {
1155 name = QStringLiteral( "%1 %2" ).arg( name, QString::number( i ) );
1156 i++;
1157 }
1158 }
1159
1160 QString errorMessage;
1161 if ( QgsProviderRegistry::instance()->styleExists( mLayer->providerType(), mLayer->source(), dbSettings.name, errorMessage ) )
1162 {
1163 if ( QMessageBox::question( nullptr, QObject::tr( "Save style in database" ),
1164 QObject::tr( "A matching style already exists in the database for this layer. Do you want to overwrite it?" ),
1165 QMessageBox::Yes | QMessageBox::No ) == QMessageBox::No )
1166 {
1167 return;
1168 }
1169 }
1170 else if ( !errorMessage.isEmpty() )
1171 {
1172 QMessageBox::warning( this, infoWindowTitle, errorMessage );
1173 return;
1174 }
1175
1176 mLayer->saveStyleToDatabase( name, dbSettings.description, dbSettings.isDefault, dbSettings.uiFileContent, msgError, dlg.styleCategories() );
1177
1178 if ( !msgError.isNull() )
1179 {
1180 QMessageBox::warning( this, infoWindowTitle, msgError );
1181 }
1182 else
1183 {
1184 QMessageBox::information( this, infoWindowTitle, tr( "Style '%1' saved" ).arg( styleName ) );
1185 }
1186 break;
1187 }
1188 case UserDatabase:
1189 break;
1190 }
1191 styleIndex ++;
1192 }
1193 // Restore original style
1194 mLayer->styleManager()->setCurrentStyle( originalStyle );
1195 }
1196 } // Nothing selected!
1197}
1198
1199void QgsVectorLayerProperties::aboutToShowStyleMenu()
1200{
1201 // this should be unified with QgsRasterLayerProperties::aboutToShowStyleMenu()
1202 QMenu *m = qobject_cast<QMenu *>( sender() );
1203 m->clear();
1204
1205 m->addAction( mActionLoadStyle );
1206 m->addAction( mActionSaveStyle );
1207
1208 // If we have multiple styles, offer an option to save them at once
1209 if ( mLayer->styleManager()->styles().count() > 1 )
1210 {
1211 mActionSaveStyle->setText( tr( "Save Current Style…" ) );
1212 m->addAction( mActionSaveMultipleStyles );
1213 }
1214 else
1215 {
1216 mActionSaveStyle->setText( tr( "Save Style…" ) );
1217 }
1218
1219 m->addSeparator();
1220 m->addAction( tr( "Save as Default" ), this, &QgsVectorLayerProperties::saveDefaultStyle );
1221 m->addAction( tr( "Restore Default" ), this, &QgsVectorLayerProperties::loadDefaultStyle );
1222
1223 // re-add style manager actions!
1224 m->addSeparator();
1226}
1227
1228void QgsVectorLayerProperties::mButtonAddJoin_clicked()
1229{
1230 if ( !mLayer )
1231 return;
1232
1233 QList<QgsMapLayer *> joinedLayers;
1234 const QList< QgsVectorLayerJoinInfo > &joins = mLayer->vectorJoins();
1235 joinedLayers.reserve( joins.size() );
1236 for ( int i = 0; i < joins.size(); ++i )
1237 {
1238 joinedLayers.append( joins[i].joinLayer() );
1239 }
1240
1241 QgsJoinDialog d( mLayer, joinedLayers );
1242 if ( d.exec() == QDialog::Accepted )
1243 {
1244 QgsVectorLayerJoinInfo info = d.joinInfo();
1245 //create attribute index if possible
1246 if ( d.createAttributeIndex() )
1247 {
1248 QgsVectorLayer *joinLayer = info.joinLayer();
1249 if ( joinLayer )
1250 {
1251 joinLayer->dataProvider()->createAttributeIndex( joinLayer->fields().indexFromName( info.joinFieldName() ) );
1252 }
1253 }
1254 mLayer->addJoin( info );
1255 addJoinToTreeWidget( info );
1256 setPbnQueryBuilderEnabled();
1257 mSourceFieldsPropertiesDialog->init();
1258 mAttributesFormPropertiesDialog->init();
1259 }
1260}
1261
1262void QgsVectorLayerProperties::mButtonEditJoin_clicked()
1263{
1264 QTreeWidgetItem *currentJoinItem = mJoinTreeWidget->currentItem();
1265 mJoinTreeWidget_itemDoubleClicked( currentJoinItem, 0 );
1266}
1267
1268void QgsVectorLayerProperties::mJoinTreeWidget_itemDoubleClicked( QTreeWidgetItem *item, int )
1269{
1270 if ( !mLayer || !item )
1271 {
1272 return;
1273 }
1274
1275 QList<QgsMapLayer *> joinedLayers;
1276 QString joinLayerId = item->data( 0, Qt::UserRole ).toString();
1277 const QList< QgsVectorLayerJoinInfo > &joins = mLayer->vectorJoins();
1278 int j = -1;
1279 for ( int i = 0; i < joins.size(); ++i )
1280 {
1281 QgsVectorLayer *joinLayer = joins[i].joinLayer();
1282 if ( !joinLayer )
1283 continue; // invalid join (unresolved join layer)
1284
1285 if ( joinLayer->id() == joinLayerId )
1286 {
1287 j = i;
1288 }
1289 else
1290 {
1291 // remove already joined layers from possible list to be displayed in dialog
1292 joinedLayers.append( joinLayer );
1293 }
1294 }
1295 if ( j == -1 )
1296 {
1297 return;
1298 }
1299
1300 QgsJoinDialog d( mLayer, joinedLayers );
1301 d.setWindowTitle( tr( "Edit Vector Join" ) );
1302 d.setJoinInfo( joins[j] );
1303
1304 if ( d.exec() == QDialog::Accepted )
1305 {
1306 QgsVectorLayerJoinInfo info = d.joinInfo();
1307
1308 // remove old join
1309 mLayer->removeJoin( joinLayerId );
1310 int idx = mJoinTreeWidget->indexOfTopLevelItem( item );
1311 mJoinTreeWidget->takeTopLevelItem( idx );
1312
1313 // add the new edited
1314
1315 //create attribute index if possible
1316 if ( d.createAttributeIndex() )
1317 {
1318 QgsVectorLayer *joinLayer = info.joinLayer();
1319 if ( joinLayer )
1320 {
1321 joinLayer->dataProvider()->createAttributeIndex( joinLayer->fields().indexFromName( info.joinFieldName() ) );
1322 }
1323 }
1324 mLayer->addJoin( info );
1325 addJoinToTreeWidget( info, idx );
1326
1327 setPbnQueryBuilderEnabled();
1328 mSourceFieldsPropertiesDialog->init();
1329 mAttributesFormPropertiesDialog->init();
1330 }
1331}
1332
1333void QgsVectorLayerProperties::addJoinToTreeWidget( const QgsVectorLayerJoinInfo &join, const int insertIndex )
1334{
1335 QTreeWidgetItem *joinItem = new QTreeWidgetItem();
1336 joinItem->setFlags( Qt::ItemIsEnabled );
1337
1338 QgsVectorLayer *joinLayer = join.joinLayer();
1339 if ( !mLayer || !joinLayer )
1340 {
1341 return;
1342 }
1343
1344 joinItem->setText( 0, tr( "Join layer" ) );
1345 if ( mLayer->auxiliaryLayer() && mLayer->auxiliaryLayer()->id() == join.joinLayerId() )
1346 {
1347 return;
1348 }
1349
1350 joinItem->setText( 1, joinLayer->name() );
1351
1352 QFont f = joinItem->font( 0 );
1353 f.setBold( true );
1354 joinItem->setFont( 0, f );
1355 joinItem->setFont( 1, f );
1356
1357 joinItem->setData( 0, Qt::UserRole, join.joinLayerId() );
1358
1359 QTreeWidgetItem *childJoinField = new QTreeWidgetItem();
1360 childJoinField->setText( 0, tr( "Join field" ) );
1361 childJoinField->setText( 1, join.joinFieldName() );
1362 childJoinField->setFlags( Qt::ItemIsEnabled );
1363 joinItem->addChild( childJoinField );
1364
1365 QTreeWidgetItem *childTargetField = new QTreeWidgetItem();
1366 childTargetField->setText( 0, tr( "Target field" ) );
1367 childTargetField->setText( 1, join.targetFieldName() );
1368 joinItem->addChild( childTargetField );
1369
1370 QTreeWidgetItem *childMemCache = new QTreeWidgetItem();
1371 childMemCache->setText( 0, tr( "Cache join layer in virtual memory" ) );
1372 if ( join.isUsingMemoryCache() )
1373 childMemCache->setText( 1, QChar( 0x2714 ) );
1374 joinItem->addChild( childMemCache );
1375
1376 QTreeWidgetItem *childDynForm = new QTreeWidgetItem();
1377 childDynForm->setText( 0, tr( "Dynamic form" ) );
1378 if ( join.isDynamicFormEnabled() )
1379 childDynForm->setText( 1, QChar( 0x2714 ) );
1380 joinItem->addChild( childDynForm );
1381
1382 QTreeWidgetItem *childEditable = new QTreeWidgetItem();
1383 childEditable->setText( 0, tr( "Editable join layer" ) );
1384 if ( join.isEditable() )
1385 childEditable->setText( 1, QChar( 0x2714 ) );
1386 joinItem->addChild( childEditable );
1387
1388 QTreeWidgetItem *childUpsert = new QTreeWidgetItem();
1389 childUpsert->setText( 0, tr( "Upsert on edit" ) );
1390 if ( join.hasUpsertOnEdit() )
1391 childUpsert->setText( 1, QChar( 0x2714 ) );
1392 joinItem->addChild( childUpsert );
1393
1394 QTreeWidgetItem *childCascade = new QTreeWidgetItem();
1395 childCascade->setText( 0, tr( "Delete cascade" ) );
1396 if ( join.hasCascadedDelete() )
1397 childCascade->setText( 1, QChar( 0x2714 ) );
1398 joinItem->addChild( childCascade );
1399
1400 QTreeWidgetItem *childPrefix = new QTreeWidgetItem();
1401 childPrefix->setText( 0, tr( "Custom field name prefix" ) );
1402 childPrefix->setText( 1, join.prefix() );
1403 joinItem->addChild( childPrefix );
1404
1405 QTreeWidgetItem *childFields = new QTreeWidgetItem();
1406 childFields->setText( 0, tr( "Joined fields" ) );
1407 const QStringList *list = join.joinFieldNamesSubset();
1408 if ( list )
1409 childFields->setText( 1, QLocale().toString( list->count() ) );
1410 else
1411 childFields->setText( 1, tr( "all" ) );
1412 joinItem->addChild( childFields );
1413
1414 if ( insertIndex >= 0 )
1415 mJoinTreeWidget->insertTopLevelItem( insertIndex, joinItem );
1416 else
1417 mJoinTreeWidget->addTopLevelItem( joinItem );
1418
1419 mJoinTreeWidget->setCurrentItem( joinItem );
1420 mJoinTreeWidget->header()->setSectionResizeMode( QHeaderView::ResizeToContents );
1421}
1422
1423QgsExpressionContext QgsVectorLayerProperties::createExpressionContext() const
1424{
1425 return mContext;
1426}
1427
1428void QgsVectorLayerProperties::openPanel( QgsPanelWidget *panel )
1429{
1430 QDialog *dlg = new QDialog();
1431 QString key = QStringLiteral( "/UI/paneldialog/%1" ).arg( panel->panelTitle() );
1432 QgsSettings settings;
1433 dlg->restoreGeometry( settings.value( key ).toByteArray() );
1434 dlg->setWindowTitle( panel->panelTitle() );
1435 dlg->setLayout( new QVBoxLayout() );
1436 dlg->layout()->addWidget( panel );
1437 QDialogButtonBox *buttonBox = new QDialogButtonBox( QDialogButtonBox::Ok );
1438 connect( buttonBox, &QDialogButtonBox::accepted, dlg, &QDialog::accept );
1439 dlg->layout()->addWidget( buttonBox );
1440 dlg->exec();
1441 settings.setValue( key, dlg->saveGeometry() );
1442 panel->acceptPanel();
1443}
1444
1445void QgsVectorLayerProperties::mButtonRemoveJoin_clicked()
1446{
1447 QTreeWidgetItem *currentJoinItem = mJoinTreeWidget->currentItem();
1448 if ( !mLayer || !currentJoinItem )
1449 {
1450 return;
1451 }
1452
1453 mLayer->removeJoin( currentJoinItem->data( 0, Qt::UserRole ).toString() );
1454 mJoinTreeWidget->takeTopLevelItem( mJoinTreeWidget->indexOfTopLevelItem( currentJoinItem ) );
1455 setPbnQueryBuilderEnabled();
1456 mSourceFieldsPropertiesDialog->init();
1457 mAttributesFormPropertiesDialog->init();
1458}
1459
1460
1461void QgsVectorLayerProperties::mButtonAddWmsDimension_clicked()
1462{
1463 if ( !mLayer )
1464 return;
1465
1466 // get wms dimensions name
1467 QStringList alreadyDefinedDimensions;
1468 QgsMapLayerServerProperties *serverProperties = static_cast<QgsMapLayerServerProperties *>( mLayer->serverProperties() );
1469 const QList<QgsMapLayerServerProperties::WmsDimensionInfo> &dims = serverProperties->wmsDimensions();
1470 for ( const QgsMapLayerServerProperties::WmsDimensionInfo &dim : dims )
1471 {
1472 alreadyDefinedDimensions << dim.name;
1473 }
1474
1475 QgsWmsDimensionDialog d( mLayer, alreadyDefinedDimensions );
1476 if ( d.exec() == QDialog::Accepted )
1477 {
1479 // save dimension
1480 serverProperties->addWmsDimension( info );
1481 addWmsDimensionInfoToTreeWidget( info );
1482 }
1483}
1484
1485void QgsVectorLayerProperties::mButtonEditWmsDimension_clicked()
1486{
1487 QTreeWidgetItem *currentWmsDimensionItem = mWmsDimensionsTreeWidget->currentItem();
1488 mWmsDimensionsTreeWidget_itemDoubleClicked( currentWmsDimensionItem, 0 );
1489}
1490
1491void QgsVectorLayerProperties::mWmsDimensionsTreeWidget_itemDoubleClicked( QTreeWidgetItem *item, int )
1492{
1493 if ( !mLayer || !item )
1494 {
1495 return;
1496 }
1497
1498 QString wmsDimName = item->data( 0, Qt::UserRole ).toString();
1499 QgsMapLayerServerProperties *serverProperties = static_cast<QgsMapLayerServerProperties *>( mLayer->serverProperties() );
1500 const QList<QgsMapLayerServerProperties::WmsDimensionInfo> &dims = serverProperties->wmsDimensions();
1501 QStringList alreadyDefinedDimensions;
1502 int j = -1;
1503 for ( int i = 0; i < dims.size(); ++i )
1504 {
1505 QString dimName = dims[i].name;
1506 if ( dimName == wmsDimName )
1507 {
1508 j = i;
1509 }
1510 else
1511 {
1512 alreadyDefinedDimensions << dimName;
1513 }
1514 }
1515 if ( j == -1 )
1516 {
1517 return;
1518 }
1519
1520 QgsWmsDimensionDialog d( mLayer, alreadyDefinedDimensions );
1521 d.setWindowTitle( tr( "Edit WMS Dimension" ) );
1522 d.setInfo( dims[j] );
1523
1524 if ( d.exec() == QDialog::Accepted )
1525 {
1527
1528 // remove old
1529 QgsMapLayerServerProperties *serverProperties = static_cast<QgsMapLayerServerProperties *>( mLayer->serverProperties() );
1530 serverProperties->removeWmsDimension( wmsDimName );
1531 int idx = mWmsDimensionsTreeWidget->indexOfTopLevelItem( item );
1532 mWmsDimensionsTreeWidget->takeTopLevelItem( idx );
1533
1534 // save new
1535 serverProperties->addWmsDimension( info );
1536 addWmsDimensionInfoToTreeWidget( info, idx );
1537 }
1538}
1539
1540void QgsVectorLayerProperties::addWmsDimensionInfoToTreeWidget( const QgsMapLayerServerProperties::WmsDimensionInfo &wmsDim, const int insertIndex )
1541{
1542 QTreeWidgetItem *wmsDimensionItem = new QTreeWidgetItem();
1543 wmsDimensionItem->setFlags( Qt::ItemIsEnabled );
1544
1545 wmsDimensionItem->setText( 0, tr( "Dimension" ) );
1546 wmsDimensionItem->setText( 1, wmsDim.name );
1547
1548 QFont f = wmsDimensionItem->font( 0 );
1549 f.setBold( true );
1550 wmsDimensionItem->setFont( 0, f );
1551 wmsDimensionItem->setFont( 1, f );
1552
1553 wmsDimensionItem->setData( 0, Qt::UserRole, wmsDim.name );
1554
1555 QTreeWidgetItem *childWmsDimensionField = new QTreeWidgetItem();
1556 childWmsDimensionField->setText( 0, tr( "Field" ) );
1557 childWmsDimensionField->setText( 1, wmsDim.fieldName );
1558 childWmsDimensionField->setFlags( Qt::ItemIsEnabled );
1559 wmsDimensionItem->addChild( childWmsDimensionField );
1560
1561 QTreeWidgetItem *childWmsDimensionEndField = new QTreeWidgetItem();
1562 childWmsDimensionEndField->setText( 0, tr( "End field" ) );
1563 childWmsDimensionEndField->setText( 1, wmsDim.endFieldName );
1564 childWmsDimensionEndField->setFlags( Qt::ItemIsEnabled );
1565 wmsDimensionItem->addChild( childWmsDimensionEndField );
1566
1567 QTreeWidgetItem *childWmsDimensionUnits = new QTreeWidgetItem();
1568 childWmsDimensionUnits->setText( 0, tr( "Units" ) );
1569 childWmsDimensionUnits->setText( 1, wmsDim.units );
1570 childWmsDimensionUnits->setFlags( Qt::ItemIsEnabled );
1571 wmsDimensionItem->addChild( childWmsDimensionUnits );
1572
1573 QTreeWidgetItem *childWmsDimensionUnitSymbol = new QTreeWidgetItem();
1574 childWmsDimensionUnitSymbol->setText( 0, tr( "Unit symbol" ) );
1575 childWmsDimensionUnitSymbol->setText( 1, wmsDim.unitSymbol );
1576 childWmsDimensionUnitSymbol->setFlags( Qt::ItemIsEnabled );
1577 wmsDimensionItem->addChild( childWmsDimensionUnitSymbol );
1578
1579 QTreeWidgetItem *childWmsDimensionDefaultValue = new QTreeWidgetItem();
1580 childWmsDimensionDefaultValue->setText( 0, tr( "Default display" ) );
1581 childWmsDimensionDefaultValue->setText( 1, QgsMapLayerServerProperties::wmsDimensionDefaultDisplayLabels().value( wmsDim.defaultDisplayType ) );
1582 childWmsDimensionDefaultValue->setFlags( Qt::ItemIsEnabled );
1583 wmsDimensionItem->addChild( childWmsDimensionDefaultValue );
1584
1585 QTreeWidgetItem *childWmsDimensionRefValue = new QTreeWidgetItem();
1586 childWmsDimensionRefValue->setText( 0, tr( "Reference value" ) );
1587 childWmsDimensionRefValue->setText( 1, wmsDim.referenceValue.toString() );
1588 childWmsDimensionRefValue->setFlags( Qt::ItemIsEnabled );
1589 wmsDimensionItem->addChild( childWmsDimensionRefValue );
1590
1591 if ( insertIndex >= 0 )
1592 mWmsDimensionsTreeWidget->insertTopLevelItem( insertIndex, wmsDimensionItem );
1593 else
1594 mWmsDimensionsTreeWidget->addTopLevelItem( wmsDimensionItem );
1595
1596 mWmsDimensionsTreeWidget->setCurrentItem( wmsDimensionItem );
1597 mWmsDimensionsTreeWidget->header()->setSectionResizeMode( QHeaderView::ResizeToContents );
1598}
1599
1600void QgsVectorLayerProperties::mButtonRemoveWmsDimension_clicked()
1601{
1602 QTreeWidgetItem *currentWmsDimensionItem = mWmsDimensionsTreeWidget->currentItem();
1603 if ( !mLayer || !currentWmsDimensionItem )
1604 {
1605 return;
1606 }
1607
1608 QgsMapLayerServerProperties *serverProperties = static_cast<QgsMapLayerServerProperties *>( mLayer->serverProperties() );
1609 serverProperties->removeWmsDimension( currentWmsDimensionItem->data( 0, Qt::UserRole ).toString() );
1610 mWmsDimensionsTreeWidget->takeTopLevelItem( mWmsDimensionsTreeWidget->indexOfTopLevelItem( currentWmsDimensionItem ) );
1611}
1612
1613
1614void QgsVectorLayerProperties::updateSymbologyPage()
1615{
1616
1617 //find out the type of renderer in the vectorlayer, create a dialog with these settings and add it to the form
1618 delete mRendererDialog;
1619 mRendererDialog = nullptr;
1620
1621 if ( mLayer->renderer() )
1622 {
1623 mRendererDialog = new QgsRendererPropertiesDialog( mLayer, QgsStyle::defaultStyle(), true, this );
1624 mRendererDialog->setDockMode( false );
1625 QgsSymbolWidgetContext context;
1626 context.setMapCanvas( mCanvas );
1627 context.setMessageBar( mMessageBar );
1628 mRendererDialog->setContext( context );
1629 connect( mRendererDialog, &QgsRendererPropertiesDialog::showPanel, this, &QgsVectorLayerProperties::openPanel );
1630 connect( mRendererDialog, &QgsRendererPropertiesDialog::layerVariablesChanged, this, &QgsVectorLayerProperties::updateVariableEditor );
1631 connect( mRendererDialog, &QgsRendererPropertiesDialog::widgetChanged, this, [ = ] { updateAuxiliaryStoragePage(); } );
1632 }
1633 else
1634 {
1635 mOptsPage_Style->setEnabled( false ); // hide symbology item
1636 }
1637
1638 if ( mRendererDialog )
1639 {
1640 mRendererDialog->layout()->setContentsMargins( 0, 0, 0, 0 );
1641 widgetStackRenderers->addWidget( mRendererDialog );
1642 widgetStackRenderers->setCurrentWidget( mRendererDialog );
1643 widgetStackRenderers->currentWidget()->layout()->setContentsMargins( 0, 0, 0, 0 );
1644 }
1645}
1646
1647void QgsVectorLayerProperties::setPbnQueryBuilderEnabled()
1648{
1649 pbnQueryBuilder->setEnabled( mLayer &&
1650 mLayer->dataProvider() &&
1651 mLayer->dataProvider()->supportsSubsetString() &&
1652 !mLayer->isEditable() );
1653
1654 if ( mLayer && mLayer->isEditable() )
1655 {
1656 pbnQueryBuilder->setToolTip( tr( "Stop editing mode to enable this." ) );
1657 }
1658
1659}
1660
1661void QgsVectorLayerProperties::pbnUpdateExtents_clicked()
1662{
1663 mLayer->updateExtents( true ); // force update whatever options activated
1664 mMetadataFilled = false;
1665}
1666
1668{
1670
1671 if ( index == mOptStackedWidget->indexOf( mOptsPage_Information ) && ! mMetadataFilled )
1672 {
1673 //set the metadata contents (which can be expensive)
1674 teMetadataViewer->clear();
1675 teMetadataViewer->setHtml( htmlMetadata() );
1676 mMetadataFilled = true;
1677 }
1678
1679 resizeAlltabs( index );
1680}
1681
1682void QgsVectorLayerProperties::mSimplifyDrawingGroupBox_toggled( bool checked )
1683{
1684 const QgsVectorDataProvider *provider = mLayer->dataProvider();
1685 if ( !( provider && ( provider->capabilities() & QgsVectorDataProvider::SimplifyGeometries ) != 0 ) )
1686 {
1687 mSimplifyDrawingAtProvider->setEnabled( false );
1688 }
1689 else
1690 {
1691 mSimplifyDrawingAtProvider->setEnabled( checked );
1692 }
1693}
1694
1695void QgsVectorLayerProperties::updateVariableEditor()
1696{
1697 QgsExpressionContext context;
1698 mVariableEditor->setContext( &context );
1699 mVariableEditor->context()->appendScope( QgsExpressionContextUtils::globalScope() );
1700 mVariableEditor->context()->appendScope( QgsExpressionContextUtils::projectScope( QgsProject::instance() ) );
1701 mVariableEditor->context()->appendScope( QgsExpressionContextUtils::layerScope( mLayer ) );
1702 mVariableEditor->reloadContext();
1703 mVariableEditor->setEditableScopeIndex( 2 );
1704}
1705
1706void QgsVectorLayerProperties::showHelp()
1707{
1708 const QVariant helpPage = mOptionsStackedWidget->currentWidget()->property( "helpPage" );
1709
1710 if ( helpPage.isValid() )
1711 {
1712 QgsHelp::openHelp( helpPage.toString() );
1713 }
1714 else
1715 {
1716 QgsHelp::openHelp( QStringLiteral( "working_with_vector/vector_properties.html" ) );
1717 }
1718}
1719
1720void QgsVectorLayerProperties::updateAuxiliaryStoragePage()
1721{
1722 const QgsAuxiliaryLayer *alayer = mLayer->auxiliaryLayer();
1723
1724 if ( alayer )
1725 {
1726 // set widgets to enable state
1727 mAuxiliaryStorageInformationGrpBox->setEnabled( true );
1728 mAuxiliaryStorageFieldsGrpBox->setEnabled( true );
1729
1730 // update key
1731 mAuxiliaryStorageKeyLineEdit->setText( alayer->joinInfo().targetFieldName() );
1732
1733 // update feature count
1734 const qlonglong features = alayer->featureCount();
1735 mAuxiliaryStorageFeaturesLineEdit->setText( QLocale().toString( features ) );
1736
1737 // update actions
1738 mAuxiliaryLayerActionClear->setEnabled( true );
1739 mAuxiliaryLayerActionDelete->setEnabled( true );
1740 mAuxiliaryLayerActionExport->setEnabled( true );
1741 mAuxiliaryLayerActionNew->setEnabled( false );
1742
1743 const QgsAuxiliaryLayer *alayer = mLayer->auxiliaryLayer();
1744 if ( alayer )
1745 {
1746 const int fields = alayer->auxiliaryFields().count();
1747 mAuxiliaryStorageFieldsLineEdit->setText( QLocale().toString( fields ) );
1748
1749 // add fields
1750 mAuxiliaryStorageFieldsTree->clear();
1751 for ( const QgsField &field : alayer->auxiliaryFields() )
1752 {
1754 QTreeWidgetItem *item = new QTreeWidgetItem();
1755
1756 item->setText( 0, prop.origin() );
1757 item->setText( 1, prop.name() );
1758 item->setText( 2, prop.comment() );
1759 item->setText( 3, field.typeName() );
1760 item->setText( 4, field.name() );
1761
1762 mAuxiliaryStorageFieldsTree->addTopLevelItem( item );
1763 }
1764 }
1765 }
1766 else
1767 {
1768 mAuxiliaryStorageInformationGrpBox->setEnabled( false );
1769 mAuxiliaryStorageFieldsGrpBox->setEnabled( false );
1770
1771 mAuxiliaryLayerActionClear->setEnabled( false );
1772 mAuxiliaryLayerActionDelete->setEnabled( false );
1773 mAuxiliaryLayerActionExport->setEnabled( false );
1774 mAuxiliaryLayerActionNew->setEnabled( true );
1775
1776 mAuxiliaryStorageFieldsTree->clear();
1777 mAuxiliaryStorageKeyLineEdit->setText( QString() );
1778 mAuxiliaryStorageFieldsLineEdit->setText( QString() );
1779 mAuxiliaryStorageFeaturesLineEdit->setText( QString() );
1780 }
1781}
1782
1783void QgsVectorLayerProperties::onAuxiliaryLayerNew()
1784{
1785 QgsAuxiliaryLayer *alayer = mLayer->auxiliaryLayer();
1786
1787 if ( alayer )
1788 return;
1789
1790 QgsNewAuxiliaryLayerDialog dlg( mLayer, this );
1791 if ( dlg.exec() == QDialog::Accepted )
1792 {
1793 updateAuxiliaryStoragePage();
1794 }
1795}
1796
1797void QgsVectorLayerProperties::onAuxiliaryLayerClear()
1798{
1799 QgsAuxiliaryLayer *alayer = mLayer->auxiliaryLayer();
1800
1801 if ( !alayer )
1802 return;
1803
1804 const QString msg = tr( "Are you sure you want to clear auxiliary data for %1?" ).arg( mLayer->name() );
1805 QMessageBox::StandardButton reply;
1806 reply = QMessageBox::question( this, "Clear Auxiliary Data", msg, QMessageBox::Yes | QMessageBox::No );
1807
1808 if ( reply == QMessageBox::Yes )
1809 {
1810 QApplication::setOverrideCursor( Qt::WaitCursor );
1811 alayer->clear();
1812 QApplication::restoreOverrideCursor();
1813 updateAuxiliaryStoragePage();
1814 mLayer->triggerRepaint();
1815 }
1816}
1817
1818void QgsVectorLayerProperties::onAuxiliaryLayerDelete()
1819{
1820 QgsAuxiliaryLayer *alayer = mLayer->auxiliaryLayer();
1821 if ( !alayer )
1822 return;
1823
1824 const QString msg = tr( "Are you sure you want to delete auxiliary storage for %1?" ).arg( mLayer->name() );
1825 QMessageBox::StandardButton reply;
1826 reply = QMessageBox::question( this, "Delete Auxiliary Storage", msg, QMessageBox::Yes | QMessageBox::No );
1827
1828 if ( reply == QMessageBox::Yes )
1829 {
1830 QApplication::setOverrideCursor( Qt::WaitCursor );
1831 QgsDataSourceUri uri( alayer->source() );
1832
1833 // delete each attribute to correctly update layer settings and data
1834 // defined buttons
1835 while ( alayer->auxiliaryFields().size() > 0 )
1836 {
1837 QgsField aField = alayer->auxiliaryFields()[0];
1838 deleteAuxiliaryField( alayer->fields().indexOf( aField.name() ) );
1839 }
1840
1841 mLayer->setAuxiliaryLayer(); // remove auxiliary layer
1843 QApplication::restoreOverrideCursor();
1844 updateAuxiliaryStoragePage();
1845 mLayer->triggerRepaint();
1846 }
1847}
1848
1849void QgsVectorLayerProperties::onAuxiliaryLayerDeleteField()
1850{
1851 QgsAuxiliaryLayer *alayer = mLayer->auxiliaryLayer();
1852 if ( !alayer )
1853 return;
1854
1855 QList<QTreeWidgetItem *> items = mAuxiliaryStorageFieldsTree->selectedItems();
1856 if ( items.count() < 1 )
1857 return;
1858
1859 // get auxiliary field name and index from item
1860 const QTreeWidgetItem *item = items[0];
1862 def.setOrigin( item->text( 0 ) );
1863 def.setName( item->text( 1 ) );
1864 def.setComment( item->text( 2 ) );
1865
1866 const QString fieldName = QgsAuxiliaryLayer::nameFromProperty( def );
1867
1868 const int index = mLayer->auxiliaryLayer()->fields().indexOf( fieldName );
1869 if ( index < 0 )
1870 return;
1871
1872 // should be only 1 field
1873 const QString msg = tr( "Are you sure you want to delete auxiliary field %1 for %2?" ).arg( item->text( 1 ), item->text( 0 ) );
1874
1875 QMessageBox::StandardButton reply;
1876 const QString title = QObject::tr( "Delete Auxiliary Field" );
1877 reply = QMessageBox::question( this, title, msg, QMessageBox::Yes | QMessageBox::No );
1878
1879 if ( reply == QMessageBox::Yes )
1880 {
1881 QApplication::setOverrideCursor( Qt::WaitCursor );
1882 deleteAuxiliaryField( index );
1883 mLayer->triggerRepaint();
1884 QApplication::restoreOverrideCursor();
1885 }
1886}
1887
1888void QgsVectorLayerProperties::onAuxiliaryLayerAddField()
1889{
1890 QgsAuxiliaryLayer *alayer = mLayer->auxiliaryLayer();
1891 if ( !alayer )
1892 return;
1893
1894 QgsNewAuxiliaryFieldDialog dlg( QgsPropertyDefinition(), mLayer, false );
1895 if ( dlg.exec() == QDialog::Accepted )
1896 {
1897 updateAuxiliaryStoragePage();
1898 }
1899}
1900
1901void QgsVectorLayerProperties::deleteAuxiliaryField( int index )
1902{
1903 if ( !mLayer->auxiliaryLayer() )
1904 return;
1905
1906 int key = mLayer->auxiliaryLayer()->propertyFromIndex( index );
1908
1909 if ( mLayer->auxiliaryLayer()->deleteAttribute( index ) )
1910 {
1911 mLayer->updateFields();
1912
1913 // immediately deactivate data defined button
1914 if ( key >= 0 && def.origin().compare( "labeling", Qt::CaseInsensitive ) == 0
1915 && labelingDialog
1916 && labelingDialog->labelingGui() )
1917 {
1918 labelingDialog->labelingGui()->deactivateField( static_cast<QgsPalLayerSettings::Property>( key ) );
1919 }
1920
1921 updateAuxiliaryStoragePage();
1922 mSourceFieldsPropertiesDialog->init();
1923 }
1924 else
1925 {
1926 const QString title = QObject::tr( "Delete Auxiliary Field" );
1927 const QString errors = mLayer->auxiliaryLayer()->commitErrors().join( QLatin1String( "\n " ) );
1928 const QString msg = QObject::tr( "Unable to remove auxiliary field (%1)" ).arg( errors );
1929 mMessageBar->pushMessage( title, msg, Qgis::MessageLevel::Warning );
1930 }
1931}
1932
1933bool QgsVectorLayerProperties::eventFilter( QObject *obj, QEvent *ev )
1934{
1935 // If the map tip preview container is resized, resize the map tip
1936 if ( obj == mMapTipPreviewContainer && ev->type() == QEvent::Resize )
1937 {
1938 resizeMapTip();
1939 }
1940 return QgsOptionsDialogBase::eventFilter( obj, ev );
1941}
1942
1943void QgsVectorLayerProperties::initMapTipPreview()
1944{
1945 // HTML editor and preview are in a splitter. By default, the editor takes 2/3 of the space
1946 mMapTipSplitter->setSizes( { 400, 200 } );
1947 // Event filter is used to resize the map tip when the container is resized
1948 mMapTipPreviewContainer->installEventFilter( this );
1949
1950 // Note: there's quite a bit of overlap between this and the code in QgsMapTip::showMapTip
1951 // Create the WebView
1952 mMapTipPreview = new QgsWebView( mMapTipPreviewContainer );
1953
1954#if WITH_QTWEBKIT
1955 mMapTipPreview->page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks );//Handle link clicks by yourself
1956 mMapTipPreview->setContextMenuPolicy( Qt::NoContextMenu ); //No context menu is allowed if you don't need it
1957 connect( mMapTipPreview, &QWebView::loadFinished, this, &QgsVectorLayerProperties::resizeMapTip );
1958#endif
1959
1960 mMapTipPreview->page()->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, true );
1961 mMapTipPreview->page()->settings()->setAttribute( QWebSettings::JavascriptEnabled, true );
1962 mMapTipPreview->page()->settings()->setAttribute( QWebSettings::LocalStorageEnabled, true );
1963
1964 // Disable scrollbars, avoid random resizing issues
1965 mMapTipPreview->page()->mainFrame()->setScrollBarPolicy( Qt::Horizontal, Qt::ScrollBarAlwaysOff );
1966 mMapTipPreview->page()->mainFrame()->setScrollBarPolicy( Qt::Vertical, Qt::ScrollBarAlwaysOff );
1967
1968 // Update the map tip preview when the expression or the map tip template changes
1969 connect( mMapTipWidget, &QgsCodeEditorHTML::textChanged, this, &QgsVectorLayerProperties::updateMapTipPreview );
1970 connect( mDisplayExpressionWidget, qOverload< const QString & >( &QgsFieldExpressionWidget::fieldChanged ), this, &QgsVectorLayerProperties::updateMapTipPreview );
1971}
1972
1973void QgsVectorLayerProperties::updateMapTipPreview()
1974{
1975 mMapTipPreview->setMaximumSize( mMapTipPreviewContainer->width(), mMapTipPreviewContainer->height() );
1976 const QString htmlContent = QgsMapTip::vectorMapTipPreviewText( mLayer, mCanvas, mMapTipWidget->text(), mDisplayExpressionWidget->asExpression() );
1977 mMapTipPreview->setHtml( htmlContent );
1978}
1979
1980void QgsVectorLayerProperties::resizeMapTip()
1981{
1982 // Ensure the map tip is not bigger than the container
1983 mMapTipPreview->setMaximumSize( mMapTipPreviewContainer->width(), mMapTipPreviewContainer->height() );
1984#if WITH_QTWEBKIT
1985 // Get the content size
1986 const QWebElement container = mMapTipPreview->page()->mainFrame()->findFirstElement(
1987 QStringLiteral( "#QgsWebViewContainer" ) );
1988 const int width = container.geometry().width();
1989 const int height = container.geometry().height();
1990 mMapTipPreview->resize( width, height );
1991
1992 // Move the map tip to the center of the container
1993 mMapTipPreview->move( ( mMapTipPreviewContainer->width() - mMapTipPreview->width() ) / 2,
1994 ( mMapTipPreviewContainer->height() - mMapTipPreview->height() ) / 2 );
1995
1996#else
1997 mMapTipPreview->adjustSize();
1998#endif
1999}
@ Warning
Warning message.
Definition qgis.h:101
static QString defaultProjectScales()
A string with default project scales.
Definition qgis.cpp:252
@ Polygon
Polygons.
@ Unknown
Unknown types.
@ Null
No geometry.
@ Marker
Marker symbol.
@ Line
Line symbol.
@ Fill
Fill symbol.
@ CustomColor
Use default symbol with a custom selection color.
@ CustomSymbol
Use a custom symbol.
@ Default
Use default symbol and selection colors.
void clearActions()
Removes all actions.
QUuid addAction(Qgis::AttributeActionType type, const QString &name, const QString &command, bool capture=false)
Add an action with the given name and action details.
Utility class that encapsulates an action based on vector attributes.
Definition qgsaction.h:37
static QString reportStyleSheet(QgsApplication::StyleSheetType styleSheetType=QgsApplication::StyleSheetType::Qt)
Returns a css style sheet for reports, the styleSheetType argument determines what type of stylesheet...
static QRegularExpression shortNameRegularExpression()
Returns the short name regular expression for line edit validator.
void init(const QgsActionManager &action, const QgsAttributeTableConfig &attributeTableConfig)
QList< QgsAction > actions() const
QgsAttributeTableConfig::ActionWidgetStyle attributeTableWidgetStyle() const
This is a container for configuration of the attribute table.
@ Action
This column represents an action widget.
QVector< QgsAttributeTableConfig::ColumnConfig > columns() const
Gets the list with all columns and their configuration.
void update(const QgsFields &fields)
Update the configuration with the given fields.
void setActionWidgetStyle(ActionWidgetStyle actionWidgetStyle)
Set the style of the action widget.
void setColumns(const QVector< QgsAttributeTableConfig::ColumnConfig > &columns)
Set the list of columns visible in the attribute table.
Class allowing to manage the auxiliary storage for a vector layer.
static QString nameFromProperty(const QgsPropertyDefinition &def, bool joined=false)
Returns the name of the auxiliary field for a property definition.
static QgsPropertyDefinition propertyDefinitionFromField(const QgsField &field)
Returns the property definition from an auxiliary field.
bool clear()
Deletes all features from the layer.
bool deleteAttribute(int attr) override
Removes attribute from the layer and commits changes.
QgsFields auxiliaryFields() const
Returns a list of all auxiliary fields currently managed by the layer.
int propertyFromIndex(int index) const
Returns the underlying property key for the field index.
QgsVectorLayerJoinInfo joinInfo() const
Returns information to use for joining with primary key and so on.
QgsPropertyDefinition propertyDefinitionFromIndex(int index) const
Returns the property definition for the underlying field index.
static bool deleteTable(const QgsDataSourceUri &uri)
Removes a table from the auxiliary storage.
This class represents a coordinate reference system (CRS).
virtual bool supportsSubsetString() const
Returns true if the provider supports setting of subset strings.
Class for storing the component parts of a RDBMS data source URI (e.g.
static bool run(const QgsCoordinateReferenceSystem &sourceCrs=QgsCoordinateReferenceSystem(), const QgsCoordinateReferenceSystem &destinationCrs=QgsCoordinateReferenceSystem(), QWidget *parent=nullptr, QgsMapCanvas *mapCanvas=nullptr, const QString &windowTitle=QString())
Runs the dialog (if required) prompting for the desired transform to use from sourceCrs to destinatio...
void syncToLayer()
Updates the widget to reflect the layer's current diagram settings.
A generic dialog for building expression strings.
static void setLayerVariables(QgsMapLayer *layer, const QVariantMap &variables)
Sets all layer context variables.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * atlasScope(const QgsLayoutAtlas *atlas)
Creates a new scope which contains variables and functions relating to a QgsLayoutAtlas.
static QgsExpressionContextScope * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
static QString findAndSelectActiveExpression(QgsCodeEditor *editor, const QString &pattern=QString())
Find the expression under the cursor in the given editor and select it.
bool forceRasterRender() const
Returns whether the renderer must render as a raster.
void setForceRasterRender(bool forceRaster)
Sets whether the renderer should be rendered to a raster destination.
double referenceScale() const
Returns the symbology reference scale.
void setReferenceScale(double scale)
Sets the symbology reference scale.
@ SpatialIndexPresent
A valid spatial index exists for the source.
virtual SpatialIndexPresence hasSpatialIndex() const
Returns an enum value representing the presence of a valid spatial index on the source,...
void fieldChanged(const QString &fieldName)
Emitted when the currently selected field changes.
Encapsulate a field in an attribute table or data source.
Definition qgsfield.h:53
QString name
Definition qgsfield.h:62
int indexFromName(const QString &fieldName) const
Gets the field index from the field name.
int indexOf(const QString &fieldName) const
Gets the field index from the field name.
int count() const
Returns number of items.
int size() const
Returns number of items.
static QString stringToSafeFilename(const QString &string)
Converts a string to a safe filename, replacing characters which are not safe for filenames with an '...
static QgsProviderSourceWidgetProviderRegistry * sourceWidgetProviderRegistry()
Returns the registry of provider source widget providers.
Definition qgsgui.cpp:114
static QgsSubsetStringEditorProviderRegistry * subsetStringEditorProviderRegistry()
Returns the registry of subset string editors of data providers.
Definition qgsgui.cpp:109
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition qgshelp.cpp:38
Master widget for configuration of labeling of a vector layer.
void adaptToLayer()
reload the settings shown in the dialog from the current layer
QgsLabelingGui * labelingGui()
Returns the labeling gui widget or nullptr if none.
void auxiliaryFieldCreated()
Emitted when an auxiliary field is created.
void writeSettingsToLayer()
save config to layer
Base class for "layer properties" dialogs, containing common utilities for handling functionality in ...
QPushButton * mBtnStyle
Style button.
void saveMetadataToFile()
Allows the user to save the layer's metadata as a file.
virtual void rollback()
Rolls back changes made to the layer.
void optionsStackedWidget_CurrentChanged(int index) override
QList< QgsMapLayerConfigWidget * > mConfigWidgets
Layer config widgets.
void setMetadataWidget(QgsMetadataWidget *widget, QWidget *page)
Sets the metadata widget and page associated with the dialog.
void loadDefaultStyle()
Reloads the default style for the layer.
void saveStyleAs()
Saves a style when appriate button is pressed.
void loadStyle()
Triggers a dialog to load a saved style.
QgsMapCanvas * mCanvas
Associated map canvas.
void loadDefaultMetadata()
Reloads the default layer metadata for the layer.
void loadMetadataFromFile()
Allows the user to load layer metadata from a file.
void saveDefaultStyle()
Saves the default style when appropriate button is pressed.
QPushButton * mBtnMetadata
Metadata button.
void initialize()
Initialize the dialog.
void saveMetadataAsDefault()
Saves the current layer metadata as the default for the layer.
void openUrl(const QUrl &url)
Handles opening a url from the dialog.
QgsLayerTreeFilterProxyModel is a sort filter proxy model to easily reproduce the legend/layer tree i...
QList< QgsMapLayer * > checkedLayers() const
Returns the checked layers.
void setLayerTreeModel(QgsLayerTreeModel *layerTreeModel)
Sets the layer tree model.
void setCheckedLayers(const QList< QgsMapLayer * > layers)
Initialize the list of checked layers.
The QgsLayerTreeModel class is model implementation for Qt item views framework.
Map canvas is a class for displaying all GIS data types on a canvas.
QColor selectionColor() const
Returns color for selected features.
double scale() const
Returns the last reported scale of the canvas.
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
A panel widget that can be shown in the map style dock.
This class models dependencies with or between map layers.
The QgsMapLayerSaveStyleDialog class provides the UI to save the current style or multiple styles int...
Manages QGIS Server properties for a map layer.
void addStyleManagerActions(QMenu *m, QgsMapLayer *layer)
adds actions to the menu in accordance to the layer
static QgsMapLayerStyleGuiUtils * instance()
returns a singleton instance of this class
QString currentStyle() const
Returns name of the current style.
QStringList styles() const
Returns list of all defined style names.
bool setCurrentStyle(const QString &name)
Set a different style as the current style - will apply it to the layer.
void currentStyleChanged(const QString &currentName)
Emitted when the current style has been changed.
Base class for all map layer types.
Definition qgsmaplayer.h:75
void setShortName(const QString &shortName)
Sets the short name of the layer used by QGIS Server to identify the layer.
QString name
Definition qgsmaplayer.h:78
QString legendUrlFormat() const
Returns the format for a URL based layer legend.
void setRefreshOnNotifyEnabled(bool enabled)
Set whether provider notification is connected to triggerRepaint.
void setAbstract(const QString &abstract)
Sets the abstract of the layer used by QGIS Server in GetCapabilities request.
virtual QString saveSldStyle(const QString &uri, bool &resultFlag) const
Saves the properties of this layer to an SLD format file.
QString source() const
Returns the source for the layer.
void setLegendUrl(const QString &legendUrl)
Sets the URL for the layer's legend.
QString providerType() const
Returns the provider type (provider key) for this layer.
void setMinimumScale(double scale)
Sets the minimum map scale (i.e.
QgsCoordinateReferenceSystem crs
Definition qgsmaplayer.h:81
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the map layer.
QString attribution() const
Returns the attribution of the layer used by QGIS Server in GetCapabilities request.
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.
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
void triggerRepaint(bool deferredUpdate=false)
Will advise the map canvas (and any other interested party) that this layer requires to be repainted.
void setAttributionUrl(const QString &attribUrl)
Sets the attribution URL of the layer used by QGIS Server in GetCapabilities request.
void setMaximumScale(double scale)
Sets the maximum map scale (i.e.
QgsLayerMetadata metadata
Definition qgsmaplayer.h:80
QString abstract() const
Returns the abstract of the layer used by QGIS Server in GetCapabilities request.
QString dataUrlFormat() const
Returns the DataUrl format of the layer used by QGIS Server in GetCapabilities request.
void setDataUrl(const QString &dataUrl)
Sets the DataUrl of the layer used by QGIS Server in GetCapabilities request.
void setKeywordList(const QString &keywords)
Sets the keyword list of the layer used by QGIS Server in GetCapabilities request.
void setAttribution(const QString &attrib)
Sets the attribution of the layer used by QGIS Server in GetCapabilities request.
bool isRefreshOnNotifyEnabled() const
Returns true if the refresh on provider nofification is enabled.
QString shortName() const
Returns the short name of the layer used by QGIS Server to identify the layer.
void setDataUrlFormat(const QString &dataUrlFormat)
Sets the DataUrl format of the layer used by QGIS Server in GetCapabilities request.
virtual void saveStyleToDatabase(const QString &name, const QString &description, bool useAsDefault, const QString &uiFileContent, QString &msgError, QgsMapLayer::StyleCategories categories=QgsMapLayer::AllStyleCategories)
Saves named and sld style of the layer to the style table in the db.
QString title() const
Returns the title of the layer used by QGIS Server in GetCapabilities request.
void setScaleBasedVisibility(bool enabled)
Sets whether scale based visibility is enabled for the layer.
QString dataUrl() const
Returns the DataUrl of the layer used by QGIS Server in GetCapabilities request.
bool hasScaleBasedVisibility() const
Returns whether scale based visibility is enabled for the layer.
void setRefreshOnNofifyMessage(const QString &message)
Set the notification message that triggers repaint If refresh on notification is enabled,...
void setName(const QString &name)
Set the display name of the layer.
QString refreshOnNotifyMessage() const
Returns the message that should be notified by the provider to triggerRepaint.
void setMapTipsEnabled(bool enabled)
Enable or disable map tips for this layer.
QString attributionUrl() const
Returns the attribution URL of the layer used by QGIS Server in GetCapabilities request.
void setDataSource(const QString &dataSource, const QString &baseName, const QString &provider, bool loadDefaultStyleFlag=false)
Updates the data source of the layer.
double minimumScale() const
Returns the minimum map scale (i.e.
QgsMapLayerStyleManager * styleManager() const
Gets access to the layer's style manager.
QString legendUrl() const
Returns the URL for the layer's legend.
void setLegendUrlFormat(const QString &legendUrlFormat)
Sets the format for a URL based layer legend.
virtual QString saveNamedStyle(const QString &uri, bool &resultFlag, StyleCategories categories=AllStyleCategories)
Save the properties of this layer as a named style (either as a .qml file on disk or as a record in t...
void setMapTipTemplate(const QString &mapTipTemplate)
The mapTip is a pretty, html representation for feature information.
bool mapTipsEnabled
Definition qgsmaplayer.h:86
double maximumScale() const
Returns the maximum map scale (i.e.
QString keywordList() const
Returns the keyword list of the layer used by QGIS Server in GetCapabilities request.
QString mapTipTemplate
Definition qgsmaplayer.h:85
void setTitle(const QString &title)
Sets the title of the layer used by QGIS Server in GetCapabilities request.
void setCrs(const QgsCoordinateReferenceSystem &srs, bool emitSignal=true)
Sets layer's spatial reference system.
static QString vectorMapTipPreviewText(QgsMapLayer *layer, QgsMapCanvas *mapCanvas, const QString &mapTemplate, const QString &displayExpression)
Returns the html that would be displayed in a maptip for a given layer.
A bar for displaying non-blocking messages to the user.
void pushMessage(const QString &text, Qgis::MessageLevel level=Qgis::MessageLevel::Info, int duration=-1)
A convenience method for pushing a message with the specified text to the bar.
A wizard to edit metadata on a map layer.
void acceptMetadata()
Saves the metadata to the layer.
void crsChanged()
If the CRS is updated.
void setMapCanvas(QgsMapCanvas *canvas)
Sets a map canvas associated with the widget.
void setMetadata(const QgsAbstractMetadataBase *metadata)
Sets the metadata to display in the widget.
A dialog to create a new auxiliary field.
A dialog to create a new auxiliary layer.
void resizeAlltabs(int index)
Resizes all tabs when the dialog is resized.
QStackedWidget * mOptStackedWidget
void initOptionsBase(bool restoreUi=true, const QString &title=QString())
Set up the base ui connections for vertical tabs.
Property
Data definable properties.
Base class for any widget that can be shown as a inline panel.
QString panelTitle()
The title of the panel.
void acceptPanel()
Accept the panel.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
void setDirty(bool b=true)
Flag the project as dirty (modified).
void crsChanged(const QgsCoordinateReferenceSystem &)
Emitted when the selected CRS is changed.
Definition for a property.
Definition qgsproperty.h:46
QString comment() const
Returns the comment of the property.
void setOrigin(const QString &origin)
Sets the origin of the property.
QString name() const
Returns the name of the property.
void setName(const QString &name)
Sets the name of the property.
QString origin() const
Returns the origin of the property.
void setComment(const QString &comment)
Sets comment of the property.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
QgsProviderSourceWidget * createWidget(QgsMapLayer *layer, QWidget *parent=nullptr)
Creates a new widget to configure the source of the specified layer.
void validChanged(bool isValid)
Emitted whenever the validation status of the widget changes.
virtual QString sourceUri() const =0
Returns the source URI as currently defined by the widget.
virtual void setSourceUri(const QString &uri)=0
Sets the source uri to show in the widget.
void showPanel(QgsPanelWidget *panel)
Emit when you require a panel to be show in the interface.
void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the dialog is shown, e.g., the associated map canvas and expression context...
void apply()
Apply the changes from the dialog to the layer.
void layerVariablesChanged()
Emitted when expression context variables on the associated vector layers have been changed.
void widgetChanged()
Emitted when something on the widget has changed.
void setDockMode(bool dockMode)
Set the widget in dock mode which tells the widget to emit panel widgets and not open dialogs.
void setMetadataUrls(const QList< QgsServerMetadataUrlProperties::MetadataUrl > &metaUrls)
Sets a the list of metadata URL for the layer.
QList< QgsServerMetadataUrlProperties::MetadataUrl > metadataUrls() const
Returns a list of metadataUrl resources associated for the layer.
static QMap< int, QString > wmsDimensionDefaultDisplayLabels()
Returns WMS Dimension default display labels.
bool addWmsDimension(const QgsServerWmsDimensionProperties::WmsDimensionInfo &wmsDimInfo)
Adds a QGIS Server WMS Dimension.
bool removeWmsDimension(const QString &wmsDimName)
Removes a QGIS Server WMS Dimension.
const QList< QgsServerWmsDimensionProperties::WmsDimensionInfo > wmsDimensions() const
Returns the QGIS Server WMS Dimension list.
This class is a composition of two QSettings instances:
Definition qgssettings.h:63
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
bool contains(const QString &key, QgsSettings::Section section=QgsSettings::NoSection) const
Returns true if there exists a setting called key; returns false otherwise.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
static QgsStyle * defaultStyle()
Returns default application-wide style.
Definition qgsstyle.cpp:145
Interface for a dialog that can edit subset strings.
virtual QString subsetString() const =0
Returns the subset string entered in the dialog.
virtual void setSubsetString(const QString &subsetString)=0
Sets a subset string into the dialog.
QgsSubsetStringEditorInterface * createDialog(QgsVectorLayer *layer, QWidget *parent=nullptr, Qt::WindowFlags fl=QgsGuiUtils::ModalDialogFlags)
Creates a new dialog to edit the subset string of the provided layer.
Contains settings which reflect the context in which a symbol (or renderer) widget is shown,...
void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
void setMessageBar(QgsMessageBar *bar)
Sets the message bar associated with the widget.
Abstract base class for all rendered symbols.
Definition qgssymbol.h:94
This is the base class for vector data providers.
static QStringList availableEncodings()
Returns a list of available encodings.
@ SimplifyGeometries
Supports simplification of geometries on provider side according to a distance tolerance.
@ SelectEncoding
Allows user to select encoding.
@ CreateSpatialIndex
Allows creation of spatial index.
virtual bool createSpatialIndex()
Creates a spatial index on the datasource (if supported by the provider type).
virtual bool createAttributeIndex(int field)
Create an attribute index on the datasource.
QString encoding() const
Returns the encoding which is used for accessing data.
virtual Q_INVOKABLE QgsVectorDataProvider::Capabilities capabilities() const
Returns flags containing the supported capabilities.
Defines left outer join from our vector layer to some other vector layer.
bool hasCascadedDelete() const
Returns whether a feature deleted on the target layer has to impact the joined layer by deleting the ...
bool isDynamicFormEnabled() const
Returns whether the form has to be dynamically updated with joined fields when a feature is being cre...
bool hasUpsertOnEdit() const
Returns whether a feature created on the target layer has to impact the joined layer by creating a ne...
bool isEditable() const
Returns whether joined fields may be edited through the form of the target layer.
bool isUsingMemoryCache() const
Returns whether values from the joined layer should be cached in memory to speed up lookups.
QString prefix() const
Returns prefix of fields from the joined layer. If nullptr, joined layer's name will be used.
static QStringList joinFieldNamesSubset(const QgsVectorLayerJoinInfo &info, bool blocklisted=true)
Returns the list of field names to use for joining considering blocklisted fields and subset.
QString joinFieldName() const
Returns name of the field of joined layer that will be used for join.
QString targetFieldName() const
Returns name of the field of our layer that will be used for join.
QString joinLayerId() const
ID of the joined layer - may be used to resolve reference to the joined layer.
QgsVectorLayer * joinLayer() const
Returns joined layer (may be nullptr if the reference was set by layer ID and not resolved yet)
bool eventFilter(QObject *obj, QEvent *ev) override
QgsVectorLayerProperties(QgsMapCanvas *canvas, QgsMessageBar *messageBar, QgsVectorLayer *lyr=nullptr, QWidget *parent=nullptr, Qt::WindowFlags fl=QgsGuiUtils::ModalDialogFlags)
void optionsStackedWidget_CurrentChanged(int index) final
void toggleEditing(QgsMapLayer *)
void exportAuxiliaryLayer(QgsAuxiliaryLayer *layer)
Implementation of layer selection properties for vector layers.
void setSelectionSymbol(QgsSymbol *symbol)
Sets the symbol used to render selected features in the layer.
QgsSymbol * selectionSymbol() const
Returns the symbol used to render selected features in the layer.
Qgis::SelectionRenderingMode selectionRenderingMode() const
Returns the selection rendering mode to use for selected features in the layer.
QColor selectionColor() const
Returns the color to use for rendering selected features in the layer.
void setSelectionColor(const QColor &color)
Sets the color to use for rendering selected features in the layer.
void setSelectionRenderingMode(Qgis::SelectionRenderingMode mode)
Sets the selection rendering mode to use for selected features in the layer.
A widget for configuring the temporal properties for a vector layer.
void syncToLayer()
Updates the widget state to match the current layer state.
void saveTemporalProperties()
Save widget temporal properties inputs.
Represents a vector layer which manages a vector based data sets.
void setAuxiliaryLayer(QgsAuxiliaryLayer *layer=nullptr)
Sets the current auxiliary layer.
bool addJoin(const QgsVectorLayerJoinInfo &joinInfo)
Joins another vector layer to this layer.
QSet< QgsMapLayerDependency > dependencies() const FINAL
Gets the list of dependencies.
long long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
void updateFields()
Will regenerate the fields property of this layer by obtaining all fields from the dataProvider,...
bool isSpatial() const FINAL
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
QString htmlMetadata() const FINAL
Obtain a formatted HTML string containing assorted metadata for this layer.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
void setSimplifyMethod(const QgsVectorSimplifyMethod &simplifyMethod)
Sets the simplification settings for fast rendering of features.
QgsAuxiliaryLayer * auxiliaryLayer()
Returns the current auxiliary layer.
bool setDependencies(const QSet< QgsMapLayerDependency > &layers) FINAL
Sets the list of dependencies.
void setProviderEncoding(const QString &encoding)
Sets the text encoding of the data provider.
void setDisplayExpression(const QString &displayExpression)
Set the preview expression, used to create a human readable preview string.
bool removeJoin(const QString &joinLayerId)
Removes a vector layer join.
bool isEditable() const FINAL
Returns true if the provider is in editing mode.
QStringList commitErrors() const
Returns a list containing any error messages generated when attempting to commit changes to the layer...
virtual void updateExtents(bool force=false)
Update the extents for the layer.
QgsFeatureRenderer * renderer()
Returns the feature renderer used for rendering the features in the layer in 2D map views.
QString displayExpression
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
QgsAttributeTableConfig attributeTableConfig() const
Returns the attribute table configuration object.
QgsActionManager * actions()
Returns all layer actions defined on this layer.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
void setAttributeTableConfig(const QgsAttributeTableConfig &attributeTableConfig)
Sets the attribute table configuration object.
virtual bool setSubsetString(const QString &subset)
Sets the string (typically sql) used to define a subset of the layer.
const QgsVectorSimplifyMethod & simplifyMethod() const
Returns the simplification settings for fast rendering of features.
const QList< QgsVectorLayerJoinInfo > vectorJoins() const
QgsMapLayerSelectionProperties * selectionProperties() override
Returns the layer's selection properties.
This class contains information how to simplify geometries fetched from a vector layer.
bool forceLocalOptimization() const
Gets where the simplification executes, after fetch the geometries from provider, or when supported,...
void setSimplifyHints(SimplifyHints simplifyHints)
Sets the simplification hints of the vector layer managed.
float maximumScale() const
Gets the maximum scale at which the layer should be simplified.
void setThreshold(float threshold)
Sets the simplification threshold of the vector layer managed.
void setSimplifyAlgorithm(SimplifyAlgorithm simplifyAlgorithm)
Sets the local simplification algorithm of the vector layer managed.
void setForceLocalOptimization(bool localOptimization)
Sets where the simplification executes, after fetch the geometries from provider, or when supported,...
SimplifyHints simplifyHints() const
Gets the simplification hints of the vector layer managed.
SimplifyAlgorithm simplifyAlgorithm() const
Gets the local simplification algorithm of the vector layer managed.
float threshold() const
Gets the simplification threshold of the vector layer managed.
@ GeometrySimplification
The geometries can be simplified using the current map2pixel context state.
@ AntialiasingSimplification
The geometries can be rendered with 'AntiAliasing' disabled because of it is '1-pixel size'.
@ NoSimplification
No simplification can be applied.
SimplifyAlgorithm
Types of local simplification algorithms that can be used.
@ Distance
The simplification uses the distance between points to remove duplicate points.
@ SnapToGrid
The simplification uses a grid (similar to ST_SnapToGrid) to remove duplicate points.
@ Visvalingam
The simplification gives each point in a line an importance weighting, so that least important points...
void setMaximumScale(float maximumScale)
Sets the maximum scale at which the layer should be simplified.
The QgsWebView class is a collection of stubs to mimic the API of QWebView on systems where the real ...
Definition qgswebview.h:66
The QgsWmsDimensionDialog class provides an interface for WMS/OAPIF (WFS3) dimensions configuration A...
const QgsCoordinateReferenceSystem & crs
Setting options for creating vector data providers.
QString format
Format specification of online resource.
Setting to define QGIS Server WMS Dimension.