QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgsmeshlayerproperties.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmeshlayerproperties.cpp
3  --------------------------
4  begin : Jun 2018
5  copyright : (C) 2018 by Peter Petrik
6  email : zilolv at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include <limits>
19 #include <typeinfo>
20 
21 #include "qgsapplication.h"
22 #include "qgscoordinatetransform.h"
23 #include "qgsfileutils.h"
24 #include "qgshelp.h"
25 #include "qgslogger.h"
26 #include "qgsmapcanvas.h"
29 #include "qgsmeshlayer.h"
30 #include "qgsmeshlayerproperties.h"
32 #include "qgsproject.h"
36 #include "qgssettings.h"
37 #include "qgsprojecttimesettings.h"
38 #include "qgsproviderregistry.h"
41 #include "qgsgui.h"
42 #include "qgsnative.h"
43 #include "qgsmetadatawidget.h"
44 
45 #include <QDesktopServices>
46 #include <QFileDialog>
47 #include <QMessageBox>
48 
49 QgsMeshLayerProperties::QgsMeshLayerProperties( QgsMapLayer *lyr, QgsMapCanvas *canvas, QWidget *parent, Qt::WindowFlags fl )
50  : QgsOptionsDialogBase( QStringLiteral( "MeshLayerProperties" ), parent, fl )
51  , mMeshLayer( qobject_cast<QgsMeshLayer *>( lyr ) )
52  , mCanvas( canvas )
53 {
54  Q_ASSERT( mMeshLayer );
55 
56  setupUi( this );
57  mRendererMeshPropertiesWidget = new QgsRendererMeshPropertiesWidget( mMeshLayer, canvas, this );
58  mConfigWidgets << mRendererMeshPropertiesWidget;
59  mOptsPage_StyleContent->layout()->addWidget( mRendererMeshPropertiesWidget );
60 
61  mSimplifyReductionFactorSpinBox->setClearValue( 10.0 );
62  mSimplifyMeshResolutionSpinBox->setClearValue( 5 );
63 
64  mStaticDatasetWidget->setLayer( mMeshLayer );
65  mIsMapSettingsTemporal = mMeshLayer && canvas && canvas->mapSettings().isTemporal();
66 
67  mTemporalProviderTimeUnitComboBox->addItem( tr( "Seconds" ), QgsUnitTypes::TemporalSeconds );
68  mTemporalProviderTimeUnitComboBox->addItem( tr( "Minutes" ), QgsUnitTypes::TemporalMinutes );
69  mTemporalProviderTimeUnitComboBox->addItem( tr( "Hours" ), QgsUnitTypes::TemporalHours );
70  mTemporalProviderTimeUnitComboBox->addItem( tr( "Days" ), QgsUnitTypes::TemporalDays );
71 
72  connect( mCrsSelector, &QgsProjectionSelectionWidget::crsChanged, this, &QgsMeshLayerProperties::changeCrs );
73  connect( mDatasetGroupTreeWidget, &QgsMeshDatasetGroupTreeWidget::datasetGroupAdded, this, &QgsMeshLayerProperties::syncToLayer );
74 
75  // QgsOptionsDialogBase handles saving/restoring of geometry, splitter and current tab states,
76  // switching vertical tabs between icon/text to icon-only modes (splitter collapsed to left),
77  // and connecting QDialogButtonBox's accepted/rejected signals to dialog's accept/reject slots
78  initOptionsBase( false );
79 
80  connect( lyr->styleManager(), &QgsMapLayerStyleManager::currentStyleChanged, this, &QgsMeshLayerProperties::syncAndRepaint );
81 
82  connect( this, &QDialog::accepted, this, &QgsMeshLayerProperties::apply );
83  connect( this, &QDialog::rejected, this, &QgsMeshLayerProperties::onCancel );
84  connect( buttonBox->button( QDialogButtonBox::Apply ), &QAbstractButton::clicked, this, &QgsMeshLayerProperties::apply );
85 
86  connect( mMeshLayer, &QgsMeshLayer::dataChanged, this, &QgsMeshLayerProperties::syncAndRepaint );
87  connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsMeshLayerProperties::showHelp );
88 
89  connect( mTemporalReloadButton, &QPushButton::clicked, this, &QgsMeshLayerProperties::reloadTemporalProperties );
90  connect( mTemporalDateTimeReference, &QDateTimeEdit::dateTimeChanged, this, &QgsMeshLayerProperties::onTimeReferenceChange );
93 
94  mComboBoxTemporalDatasetMatchingMethod->addItem( tr( "Find Closest Dataset Before Requested Time" ),
96  mComboBoxTemporalDatasetMatchingMethod->addItem( tr( "Find Closest Dataset From Requested Time (After or Before)" ),
98 
99  QVBoxLayout *layout = new QVBoxLayout( metadataFrame );
100  layout->setContentsMargins( 0, 0, 0, 0 );
101  metadataFrame->setContentsMargins( 0, 0, 0, 0 );
102  mMetadataWidget = new QgsMetadataWidget( this, mMeshLayer );
103  mMetadataWidget->layout()->setContentsMargins( 0, 0, 0, 0 );
104  mMetadataWidget->setMapCanvas( mCanvas );
105  layout->addWidget( mMetadataWidget );
106  metadataFrame->setLayout( layout );
107  mOptsPage_Metadata->setContentsMargins( 0, 0, 0, 0 );
108  mBackupCrs = mMeshLayer->crs();
109 
110  mTemporalDateTimeStart->setDisplayFormat( "yyyy-MM-dd HH:mm:ss" );
111  mTemporalDateTimeEnd->setDisplayFormat( "yyyy-MM-dd HH:mm:ss" );
112  mTemporalDateTimeReference->setDisplayFormat( "yyyy-MM-dd HH:mm:ss" );
113 
114  // update based on lyr's current state
115  syncToLayer();
116 
117  QgsSettings settings;
118  // if dialog hasn't been opened/closed yet, default to Styles tab, which is used most often
119  // this will be read by restoreOptionsBaseUi()
120  if ( !settings.contains( QStringLiteral( "/Windows/MeshLayerProperties/tab" ) ) )
121  {
122  settings.setValue( QStringLiteral( "Windows/MeshLayerProperties/tab" ),
123  mOptStackedWidget->indexOf( mOptsPage_Style ) );
124  }
125 
126  //Add help page references
127  mOptsPage_Information->setProperty( "helpPage", QStringLiteral( "working_with_mesh/mesh_properties.html#information-properties" ) );
128  mOptsPage_Source->setProperty( "helpPage", QStringLiteral( "working_with_mesh/mesh_properties.html#source-properties" ) );
129  mOptsPage_Style->setProperty( "helpPage", QStringLiteral( "working_with_mesh/mesh_properties.html#symbology-properties" ) );
130  mOptsPage_Rendering->setProperty( "helpPage", QStringLiteral( "working_with_mesh/mesh_properties.html#rendering-properties" ) );
131 
132  mBtnStyle = new QPushButton( tr( "Style" ) );
133  QMenu *menuStyle = new QMenu( this );
134  menuStyle->addAction( tr( "Load Style…" ), this, &QgsMeshLayerProperties::loadStyle );
135  menuStyle->addAction( tr( "Save Style…" ), this, &QgsMeshLayerProperties::saveStyleAs );
136  menuStyle->addSeparator();
137  menuStyle->addAction( tr( "Save as Default" ), this, &QgsMeshLayerProperties::saveDefaultStyle );
138  menuStyle->addAction( tr( "Restore Default" ), this, &QgsMeshLayerProperties::loadDefaultStyle );
139  mBtnStyle->setMenu( menuStyle );
140  connect( menuStyle, &QMenu::aboutToShow, this, &QgsMeshLayerProperties::aboutToShowStyleMenu );
141 
142  buttonBox->addButton( mBtnStyle, QDialogButtonBox::ResetRole );
143 
144  mBtnMetadata = new QPushButton( tr( "Metadata" ), this );
145  QMenu *menuMetadata = new QMenu( this );
146  mActionLoadMetadata = menuMetadata->addAction( tr( "Load Metadata…" ), this, &QgsMeshLayerProperties::loadMetadata );
147  mActionSaveMetadataAs = menuMetadata->addAction( tr( "Save Metadata…" ), this, &QgsMeshLayerProperties::saveMetadataAs );
148  mBtnMetadata->setMenu( menuMetadata );
149  buttonBox->addButton( mBtnMetadata, QDialogButtonBox::ResetRole );
150 
151  QString title = tr( "Layer Properties — %1" ).arg( lyr->name() );
152 
153  if ( !mMeshLayer->styleManager()->isDefault( mMeshLayer->styleManager()->currentStyle() ) )
154  title += QStringLiteral( " (%1)" ).arg( mMeshLayer->styleManager()->currentStyle() );
155  restoreOptionsBaseUi( title );
156 }
157 
159 {
160  if ( !factory->supportsLayer( mMeshLayer ) || !factory->supportLayerPropertiesDialog() )
161  {
162  return;
163  }
164 
165  QgsMapLayerConfigWidget *page = factory->createWidget( mMeshLayer, mCanvas, false, this );
166  mConfigWidgets << page;
167 
168  page->setProperty( "helpPage", QStringLiteral( "working_with_mesh/mesh_properties.html#d-view-properties" ) );
169 
170  const QString beforePage = factory->layerPropertiesPagePositionHint();
171  if ( beforePage.isEmpty() )
172  addPage( factory->title(), factory->title(), factory->icon(), page );
173  else
174  insertPage( factory->title(), factory->title(), factory->icon(), page, beforePage );
175 
176  page->syncToLayer( mMeshLayer );
177 
178 }
179 
181 {
183 
184  bool isMetadataPanel = ( index == mOptStackedWidget->indexOf( mOptsPage_Metadata ) );
185  mBtnStyle->setVisible( ! isMetadataPanel );
186  mBtnMetadata->setVisible( isMetadataPanel );
187 }
188 
189 void QgsMeshLayerProperties::syncToLayer()
190 {
191  Q_ASSERT( mRendererMeshPropertiesWidget );
192 
193  QgsDebugMsgLevel( QStringLiteral( "populate general information tab" ), 4 );
194  /*
195  * Information Tab
196  */
197  QString myStyle = QgsApplication::reportStyleSheet();
198  myStyle.append( QStringLiteral( "body { margin: 10px; }\n " ) );
199  mInformationTextBrowser->clear();
200  mInformationTextBrowser->document()->setDefaultStyleSheet( myStyle );
201  mInformationTextBrowser->setHtml( mMeshLayer->htmlMetadata() );
202  mInformationTextBrowser->setOpenLinks( false );
203  connect( mInformationTextBrowser, &QTextBrowser::anchorClicked, this, &QgsMeshLayerProperties::urlClicked );
204 
205  QgsDebugMsgLevel( QStringLiteral( "populate source tab" ), 4 );
206  /*
207  * Source Tab
208  */
209  mLayerOrigNameLineEd->setText( mMeshLayer->name() );
210  whileBlocking( mCrsSelector )->setCrs( mMeshLayer->crs() );
211 
212  if ( mMeshLayer )
213  mDatasetGroupTreeWidget->syncToLayer( mMeshLayer );
214 
215  QgsDebugMsgLevel( QStringLiteral( "populate config tab" ), 4 );
216  for ( QgsMapLayerConfigWidget *w : std::as_const( mConfigWidgets ) )
217  w->syncToLayer( mMeshLayer );
218 
219  QgsDebugMsgLevel( QStringLiteral( "populate rendering tab" ), 4 );
220  if ( mMeshLayer->isEditable() )
221  mSimplifyMeshGroupBox->setEnabled( false );
222 
223  QgsMeshSimplificationSettings simplifySettings = mMeshLayer->meshSimplificationSettings();
224  mSimplifyMeshGroupBox->setChecked( simplifySettings.isEnabled() );
225  mSimplifyReductionFactorSpinBox->setValue( simplifySettings.reductionFactor() );
226  mSimplifyMeshResolutionSpinBox->setValue( simplifySettings.meshResolution() );
227 
228  QgsDebugMsgLevel( QStringLiteral( "populate temporal tab" ), 4 );
229  const QgsMeshLayerTemporalProperties *temporalProperties = qobject_cast< const QgsMeshLayerTemporalProperties * >( mMeshLayer->temporalProperties() );
230  whileBlocking( mTemporalDateTimeReference )->setDateTime( temporalProperties->referenceTime() );
231  const QgsDateTimeRange timeRange = temporalProperties->timeExtent();
232  mTemporalDateTimeStart->setDateTime( timeRange.begin() );
233  mTemporalDateTimeEnd->setDateTime( timeRange.end() );
234  if ( mMeshLayer->dataProvider() )
235  {
236  mTemporalProviderTimeUnitComboBox->setCurrentIndex(
237  mTemporalProviderTimeUnitComboBox->findData( mMeshLayer->dataProvider()->temporalCapabilities()->temporalUnit() ) );
238  }
239  mComboBoxTemporalDatasetMatchingMethod->setCurrentIndex(
240  mComboBoxTemporalDatasetMatchingMethod->findData( temporalProperties->matchingMethod() ) );
241 
242  mStaticDatasetWidget->syncToLayer();
243  mStaticDatasetGroupBox->setChecked( !mMeshLayer->temporalProperties()->isActive() );
244 }
245 
246 void QgsMeshLayerProperties::loadDefaultStyle()
247 {
248  bool defaultLoadedFlag = false;
249  QString myMessage = mMeshLayer->loadDefaultStyle( defaultLoadedFlag );
250  // reset if the default style was loaded OK only
251  if ( defaultLoadedFlag )
252  {
253  syncToLayer();
254  }
255  else
256  {
257  // otherwise let the user know what went wrong
258  QMessageBox::information( this,
259  tr( "Default Style" ),
260  myMessage
261  );
262  }
263 }
264 
265 void QgsMeshLayerProperties::saveDefaultStyle()
266 {
267  apply(); // make sure the style to save is up-to-date
268 
269  // a flag passed by reference
270  bool defaultSavedFlag = false;
271  // TODO Once the deprecated `saveDefaultStyle()` method is gone, just
272  // remove the NOWARN_DEPRECATED tags
274  // after calling this the above flag will be set true for success
275  // or false if the save operation failed
276  QString myMessage = mMeshLayer->saveDefaultStyle( defaultSavedFlag );
278  if ( !defaultSavedFlag )
279  {
280  // let the user know what went wrong
281  QMessageBox::information( this,
282  tr( "Default Style" ),
283  myMessage
284  );
285  }
286 }
287 
288 void QgsMeshLayerProperties::loadStyle()
289 {
290  QgsSettings settings;
291  QString lastUsedDir = settings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString();
292 
293  QString fileName = QFileDialog::getOpenFileName(
294  this,
295  tr( "Load rendering setting from style file" ),
296  lastUsedDir,
297  tr( "QGIS Layer Style File" ) + " (*.qml)" );
298  if ( fileName.isEmpty() )
299  return;
300 
301  // ensure the user never omits the extension from the file name
302  if ( !fileName.endsWith( QLatin1String( ".qml" ), Qt::CaseInsensitive ) )
303  fileName += QLatin1String( ".qml" );
304 
305  mOldStyle = mMeshLayer->styleManager()->style( mMeshLayer->styleManager()->currentStyle() );
306 
307  bool defaultLoadedFlag = false;
308  QString message = mMeshLayer->loadNamedStyle( fileName, defaultLoadedFlag );
309  if ( defaultLoadedFlag )
310  {
311  settings.setValue( QStringLiteral( "style/lastStyleDir" ), QFileInfo( fileName ).absolutePath() );
312  syncToLayer();
313  }
314  else
315  {
316  QMessageBox::information( this, tr( "Load Style" ), message );
317  }
318 }
319 
320 void QgsMeshLayerProperties::saveStyleAs()
321 {
322  QgsSettings settings;
323  QString lastUsedDir = settings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString();
324 
325  QString outputFileName = QFileDialog::getSaveFileName(
326  this,
327  tr( "Save layer properties as style file" ),
328  lastUsedDir,
329  tr( "QGIS Layer Style File" ) + " (*.qml)" );
330  if ( outputFileName.isEmpty() )
331  return;
332 
333  // ensure the user never omits the extension from the file name
334  outputFileName = QgsFileUtils::ensureFileNameHasExtension( outputFileName, QStringList() << QStringLiteral( "qml" ) );
335 
336  apply(); // make sure the style to save is up-to-date
337 
338  // then export style
339  bool defaultLoadedFlag = false;
340  QString message;
341  message = mMeshLayer->saveNamedStyle( outputFileName, defaultLoadedFlag );
342 
343  if ( defaultLoadedFlag )
344  {
345  settings.setValue( QStringLiteral( "style/lastStyleDir" ), QFileInfo( outputFileName ).absolutePath() );
346  }
347  else
348  QMessageBox::information( this, tr( "Save Style" ), message );
349 }
350 
351 void QgsMeshLayerProperties::apply()
352 {
353  Q_ASSERT( mRendererMeshPropertiesWidget );
354 
355  QgsDebugMsgLevel( QStringLiteral( "processing general tab" ), 4 );
356  /*
357  * General Tab
358  */
359  mMeshLayer->setName( mLayerOrigNameLineEd->text() );
360 
361  QgsDebugMsgLevel( QStringLiteral( "processing source tab" ), 4 );
362  /*
363  * Source Tab
364  */
365  mDatasetGroupTreeWidget->apply();
366 
367  QgsDebugMsgLevel( QStringLiteral( "processing config tabs" ), 4 );
368 
369  for ( QgsMapLayerConfigWidget *w : std::as_const( mConfigWidgets ) )
370  w->apply();
371 
372  QgsDebugMsgLevel( QStringLiteral( "processing rendering tab" ), 4 );
373  /*
374  * Rendering Tab
375  */
376  QgsMeshSimplificationSettings simplifySettings;
377  simplifySettings.setEnabled( mSimplifyMeshGroupBox->isChecked() );
378  simplifySettings.setReductionFactor( mSimplifyReductionFactorSpinBox->value() );
379  simplifySettings.setMeshResolution( mSimplifyMeshResolutionSpinBox->value() );
380  bool needMeshUpdating = ( ( simplifySettings.isEnabled() != mMeshLayer->meshSimplificationSettings().isEnabled() ) ||
381  ( simplifySettings.reductionFactor() != mMeshLayer->meshSimplificationSettings().reductionFactor() ) );
382 
383  mMeshLayer->setMeshSimplificationSettings( simplifySettings );
384 
385  QgsDebugMsgLevel( QStringLiteral( "processing temporal tab" ), 4 );
386  /*
387  * Temporal Tab
388  */
389 
390  mMeshLayer->setReferenceTime( mTemporalDateTimeReference->dateTime() );
391  if ( mMeshLayer->dataProvider() )
392  mMeshLayer->dataProvider()->setTemporalUnit(
393  static_cast<QgsUnitTypes::TemporalUnit>( mTemporalProviderTimeUnitComboBox->currentData().toInt() ) );
394 
395  mStaticDatasetWidget->apply();
396  bool needEmitRendererChanged = mMeshLayer->temporalProperties()->isActive() == mStaticDatasetGroupBox->isChecked();
397  mMeshLayer->temporalProperties()->setIsActive( !mStaticDatasetGroupBox->isChecked() );
399  mComboBoxTemporalDatasetMatchingMethod->currentData().toInt() ) );
400 
401  mMetadataWidget->acceptMetadata();
402 
403  mBackupCrs = mMeshLayer->crs();
404 
405  if ( needMeshUpdating )
406  mMeshLayer->reload();
407 
408  if ( needEmitRendererChanged )
409  emit mMeshLayer->rendererChanged();
410 
411  //make sure the layer is redrawn
412  mMeshLayer->triggerRepaint();
413 
414  // notify the project we've made a change
415  QgsProject::instance()->setDirty( true );
416 
417  // Resync what have to be resync (widget that can be changed by other properties part)
418  mStaticDatasetWidget->syncToLayer();
419  for ( QgsMapLayerConfigWidget *w : std::as_const( mConfigWidgets ) )
420  w->syncToLayer( mMeshLayer );
421 }
422 
423 void QgsMeshLayerProperties::changeCrs( const QgsCoordinateReferenceSystem &crs )
424 {
425  QgsDatumTransformDialog::run( crs, QgsProject::instance()->crs(), this, mCanvas, tr( "Select Transformation" ) );
426  mMeshLayer->setCrs( crs );
427 }
428 
429 void QgsMeshLayerProperties::syncAndRepaint()
430 {
431  syncToLayer();
432  mMeshLayer->triggerRepaint();
433 }
434 
435 void QgsMeshLayerProperties::showHelp()
436 {
437  const QVariant helpPage = mOptionsStackedWidget->currentWidget()->property( "helpPage" );
438 
439  if ( helpPage.isValid() )
440  {
441  QgsHelp::openHelp( helpPage.toString() );
442  }
443  else
444  {
445  QgsHelp::openHelp( QStringLiteral( "working_with_mesh/mesh_properties.html" ) );
446  }
447 }
448 
449 void QgsMeshLayerProperties::aboutToShowStyleMenu()
450 {
451  QMenu *m = qobject_cast<QMenu *>( sender() );
452 
454  // re-add style manager actions!
455  m->addSeparator();
457 }
458 
459 void QgsMeshLayerProperties::reloadTemporalProperties()
460 {
461  if ( !mMeshLayer->dataProvider() )
462  return;
463  QgsMeshDataProviderTemporalCapabilities *temporalCapabalities = mMeshLayer->dataProvider()->temporalCapabilities();
464  QgsDateTimeRange timeExtent;
465  QDateTime referenceTime = temporalCapabalities->referenceTime();
466  if ( referenceTime.isValid() )
467  {
468  timeExtent = temporalCapabalities->timeExtent();
469  whileBlocking( mTemporalDateTimeReference )->setDateTime( referenceTime );
470  }
471  else
472  // The reference time already here is used again to define the time extent
473  timeExtent = temporalCapabalities->timeExtent( mTemporalDateTimeReference->dateTime() );
474 
475  mTemporalDateTimeStart->setDateTime( timeExtent.begin() );
476  mTemporalDateTimeEnd->setDateTime( timeExtent.end() );
477 }
478 
479 void QgsMeshLayerProperties::onTimeReferenceChange()
480 {
481  if ( !mMeshLayer->dataProvider() )
482  return;
483  const QgsDateTimeRange &timeExtent = mMeshLayer->dataProvider()->temporalCapabilities()->timeExtent( mTemporalDateTimeReference->dateTime() );
484  mTemporalDateTimeStart->setDateTime( timeExtent.begin() );
485  mTemporalDateTimeEnd->setDateTime( timeExtent.end() );
486 }
487 
488 void QgsMeshLayerProperties::urlClicked( const QUrl &url )
489 {
490  QFileInfo file( url.toLocalFile() );
491  if ( file.exists() && !file.isDir() )
492  QgsGui::nativePlatformInterface()->openFileExplorerAndSelectFile( url.toLocalFile() );
493  else
494  QDesktopServices::openUrl( url );
495 }
496 
497 void QgsMeshLayerProperties::loadMetadata()
498 {
499  QgsSettings myQSettings; // where we keep last used filter in persistent state
500  QString myLastUsedDir = myQSettings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString();
501 
502  QString myFileName = QFileDialog::getOpenFileName( this, tr( "Load layer metadata from metadata file" ), myLastUsedDir,
503  tr( "QGIS Layer Metadata File" ) + " (*.qmd)" );
504  if ( myFileName.isNull() )
505  {
506  return;
507  }
508 
509  QString myMessage;
510  bool defaultLoadedFlag = false;
511  myMessage = mMeshLayer->loadNamedMetadata( myFileName, defaultLoadedFlag );
512 
513  //reset if the default style was loaded OK only
514  if ( defaultLoadedFlag )
515  {
516  mMetadataWidget->setMetadata( &mMeshLayer->metadata() );
517  }
518  else
519  {
520  //let the user know what went wrong
521  QMessageBox::warning( this, tr( "Load Metadata" ), myMessage );
522  }
523 
524  QFileInfo myFI( myFileName );
525  QString myPath = myFI.path();
526  myQSettings.setValue( QStringLiteral( "style/lastStyleDir" ), myPath );
527 
528  activateWindow(); // set focus back to properties dialog
529 }
530 
531 void QgsMeshLayerProperties::saveMetadataAs()
532 {
533  QgsSettings myQSettings; // where we keep last used filter in persistent state
534  QString myLastUsedDir = myQSettings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString();
535 
536  QString myOutputFileName = QFileDialog::getSaveFileName( this, tr( "Save Layer Metadata as QMD" ),
537  myLastUsedDir, tr( "QMD File" ) + " (*.qmd)" );
538  if ( myOutputFileName.isNull() ) //dialog canceled
539  {
540  return;
541  }
542 
543  mMetadataWidget->acceptMetadata();
544 
545  //ensure the user never omitted the extension from the file name
546  if ( !myOutputFileName.endsWith( QgsMapLayer::extensionPropertyType( QgsMapLayer::Metadata ), Qt::CaseInsensitive ) )
547  {
549  }
550 
551  bool defaultLoadedFlag = false;
552  QString message = mMeshLayer->saveNamedMetadata( myOutputFileName, defaultLoadedFlag );
553  if ( defaultLoadedFlag )
554  myQSettings.setValue( QStringLiteral( "style/lastStyleDir" ), QFileInfo( myOutputFileName ).absolutePath() );
555  else
556  QMessageBox::information( this, tr( "Save Metadata" ), message );
557 }
558 
559 void QgsMeshLayerProperties::onCancel()
560 {
561  if ( mBackupCrs != mMeshLayer->crs() )
562  mMeshLayer->setCrs( mBackupCrs );
563 }
QgsMetadataWidget::setMapCanvas
void setMapCanvas(QgsMapCanvas *canvas)
Sets a map canvas associated with the widget.
Definition: qgsmetadatawidget.cpp:957
QgsMeshSimplificationSettings::setEnabled
void setEnabled(bool isEnabled)
Sets if the overview is active.
Definition: qgsmeshsimplificationsettings.cpp:25
QgsMeshDataProviderTemporalCapabilities::temporalUnit
QgsUnitTypes::TemporalUnit temporalUnit() const
Returns the temporal unit used to read data by the data provider.
Definition: qgsmeshdataprovidertemporalcapabilities.cpp:153
QgsMapLayer::crs
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:79
QgsMapLayerConfigWidgetFactory::title
virtual QString title() const
The title of the panel.
Definition: qgsmaplayerconfigwidgetfactory.h:75
qgsmaplayerstylemanager.h
QgsRendererMeshPropertiesWidget
Widget for renderer properties of the mesh, contours (scalars) and vectors data associated with the m...
Definition: qgsrenderermeshpropertieswidget.h:39
QgsMeshLayer::setReferenceTime
void setReferenceTime(const QDateTime &referenceTime)
Sets the reference time of the layer.
Definition: qgsmeshlayer.cpp:800
QgsOptionsDialogBase
A base dialog for options and properties dialogs that offers vertical tabs. It handles saving/restori...
Definition: qgsoptionsdialogbase.h:86
QgsMetadataWidget::setMetadata
void setMetadata(const QgsAbstractMetadataBase *metadata)
Sets the metadata to display in the widget.
Definition: qgsmetadatawidget.cpp:165
QgsOptionsDialogBase::insertPage
void insertPage(const QString &title, const QString &tooltip, const QIcon &icon, QWidget *widget, const QString &before, const QStringList &path=QStringList())
Inserts a new page into the dialog pages.
Definition: qgsoptionsdialogbase.cpp:401
QgsSettings::value
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Definition: qgssettings.cpp:161
QgsOptionsDialogBase::addPage
void addPage(const QString &title, const QString &tooltip, const QIcon &icon, QWidget *widget, const QStringList &path=QStringList())
Adds a new page to the dialog pages.
Definition: qgsoptionsdialogbase.cpp:327
qgsmapcanvas.h
QgsMeshLayer::setMeshSimplificationSettings
void setMeshSimplificationSettings(const QgsMeshSimplificationSettings &meshSimplificationSettings)
Sets mesh simplification settings.
Definition: qgsmeshlayer.cpp:1341
QgsMeshSimplificationSettings::setMeshResolution
void setMeshResolution(int meshResolution)
Sets the mesh resolution i.e., the minimum size (average) of triangles in pixels This value is used d...
Definition: qgsmeshsimplificationsettings.cpp:63
QgsDebugMsgLevel
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
QgsMapLayerConfigWidgetFactory::layerPropertiesPagePositionHint
virtual QString layerPropertiesPagePositionHint() const
Returns a tab name hinting at where this page should be inserted into the layer properties tab list.
Definition: qgsmaplayerconfigwidgetfactory.cpp:24
QgsMeshDataProviderTemporalCapabilities
Class for handling properties relating to a mesh data provider's temporal capabilities.
Definition: qgsmeshdataprovidertemporalcapabilities.h:34
QgsMapCanvas::mapSettings
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
Definition: qgsmapcanvas.cpp:437
QgsTemporalRangeObject::isTemporal
bool isTemporal() const
Returns true if the object's temporal range is enabled, and the object will be filtered when renderin...
Definition: qgstemporalrangeobject.cpp:30
qgsgui.h
crs
const QgsCoordinateReferenceSystem & crs
Definition: qgswfsgetfeature.cpp:105
QgsMeshLayer::reload
void reload() override
Synchronises with changes in the datasource.
Definition: qgsmeshlayer.cpp:1653
QgsProjectionSelectionWidget::crsChanged
void crsChanged(const QgsCoordinateReferenceSystem &)
Emitted when the selected CRS is changed.
QgsUnitTypes::TemporalDays
@ TemporalDays
Days.
Definition: qgsunittypes.h:155
QgsMeshLayer::meshSimplificationSettings
QgsMeshSimplificationSettings meshSimplificationSettings() const
Returns mesh simplification settings.
Definition: qgsmeshlayer.cpp:1336
QgsMapCanvas
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:89
QgsMapLayer::styleManager
QgsMapLayerStyleManager * styleManager() const
Gets access to the layer's style manager.
Definition: qgsmaplayer.cpp:2092
QgsMapLayer::Metadata
@ Metadata
Definition: qgsmaplayer.h:135
QgsMeshLayerTemporalProperties
Implementation of map layer temporal properties for mesh layers.
Definition: qgsmeshlayertemporalproperties.h:51
QgsMeshLayerProperties::optionsStackedWidget_CurrentChanged
void optionsStackedWidget_CurrentChanged(int index) override
Definition: qgsmeshlayerproperties.cpp:180
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:480
QgsMapLayerStyleManager::currentStyleChanged
void currentStyleChanged(const QString &currentName)
Emitted when the current style has been changed.
qgsmeshlayerproperties.h
QgsSettings
This class is a composition of two QSettings instances:
Definition: qgssettings.h:61
QgsMapLayer::saveDefaultStyle
virtual QString saveDefaultStyle(bool &resultFlag, StyleCategories categories)
Save the properties of this layer as the default style (either as a .qml file on disk or as a record ...
Definition: qgsmaplayer.cpp:1330
QgsMeshLayer::setTemporalMatchingMethod
void setTemporalMatchingMethod(const QgsMeshDataProviderTemporalCapabilities::MatchingTemporalDatasetMethod &matchingMethod)
Sets the method used to match the temporal dataset from a requested time, see activeVectorDatasetAtTi...
Definition: qgsmeshlayer.cpp:808
QgsMapLayer::saveNamedStyle
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...
Definition: qgsmaplayer.cpp:1576
qgsmaplayerstyleguiutils.h
QgsUnitTypes::TemporalUnit
TemporalUnit
Temporal units.
Definition: qgsunittypes.h:149
QgsMeshSimplificationSettings::setReductionFactor
void setReductionFactor(double value)
Sets the reduction factor used to build simplified mesh.
Definition: qgsmeshsimplificationsettings.cpp:35
QgsMapLayer::setCrs
void setCrs(const QgsCoordinateReferenceSystem &srs, bool emitSignal=true)
Sets layer's spatial reference system.
Definition: qgsmaplayer.cpp:937
QgsMeshDataProviderTemporalCapabilities::FindClosestDatasetFromStartRangeTime
@ FindClosestDatasetFromStartRangeTime
Finds the closest dataset which have its time before the requested start range time.
Definition: qgsmeshdataprovidertemporalcapabilities.h:44
QgsMeshLayerTemporalProperties::timeExtent
QgsDateTimeRange timeExtent() const
Returns the time extent.
Definition: qgsmeshlayertemporalproperties.cpp:87
qgsrenderermeshpropertieswidget.h
QgsMeshDataProvider::temporalCapabilities
QgsMeshDataProviderTemporalCapabilities * temporalCapabilities() override
Returns the provider's temporal capabilities.
Definition: qgsmeshdataprovider.cpp:29
QgsMapLayer::saveNamedMetadata
QString saveNamedMetadata(const QString &uri, bool &resultFlag)
Save the current metadata of this layer as a named metadata (either as a .qmd file on disk or as a re...
Definition: qgsmaplayer.cpp:1335
QgsMapLayerConfigWidget
A panel widget that can be shown in the map style dock.
Definition: qgsmaplayerconfigwidget.h:115
QgsUnitTypes::TemporalSeconds
@ TemporalSeconds
Seconds.
Definition: qgsunittypes.h:152
qgsapplication.h
qgsprojectionselectiondialog.h
QgsMapLayer::triggerRepaint
void triggerRepaint(bool deferredUpdate=false)
Will advise the map canvas (and any other interested party) that this layer requires to be repainted.
Definition: qgsmaplayer.cpp:2114
Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:2820
QgsMapLayer::metadata
QgsLayerMetadata metadata
Definition: qgsmaplayer.h:78
QgsMapLayerStyleGuiUtils::addStyleManagerActions
void addStyleManagerActions(QMenu *m, QgsMapLayer *layer)
adds actions to the menu in accordance to the layer
Definition: qgsmaplayerstyleguiutils.cpp:83
QgsMeshLayer::htmlMetadata
QString htmlMetadata() const override
Obtain a formatted HTML string containing assorted metadata for this layer.
Definition: qgsmeshlayer.cpp:1681
qgsproviderregistry.h
QgsTemporalProperty::isActive
bool isActive() const
Returns true if the temporal property is active.
Definition: qgstemporalproperty.cpp:36
whileBlocking
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:2191
QgsMeshSimplificationSettings::isEnabled
bool isEnabled() const
Returns if the overview is active.
Definition: qgsmeshsimplificationsettings.cpp:20
QgsMetadataWidget::acceptMetadata
void acceptMetadata()
Saves the metadata to the layer.
Definition: qgsmetadatawidget.cpp:977
qgsmetadatawidget.h
QgsMeshLayer
Represents a mesh layer supporting display of data on structured or unstructured meshes.
Definition: qgsmeshlayer.h:98
QgsMeshStaticDatasetWidget::setScalarDatasetGroup
void setScalarDatasetGroup(int index)
Sets the scalar dataset group.
Definition: qgsmeshstaticdatasetwidget.cpp:70
QgsMapLayerConfigWidgetFactory::createWidget
virtual QgsMapLayerConfigWidget * createWidget(QgsMapLayer *layer, QgsMapCanvas *canvas, bool dockWidget=true, QWidget *parent=nullptr) const =0
Factory function to create the widget on demand as needed by the dock.
QgsMapLayerStyleGuiUtils::instance
static QgsMapLayerStyleGuiUtils * instance()
returns a singleton instance of this class
Definition: qgsmaplayerstyleguiutils.cpp:29
QgsMeshDataProvider::setTemporalUnit
void setTemporalUnit(QgsUnitTypes::TemporalUnit unit)
Sets the temporal unit of the provider and reload data if it changes.
Definition: qgsmeshdataprovider.cpp:39
QgsMeshLayerTemporalProperties::referenceTime
QDateTime referenceTime() const
Returns the reference time.
Definition: qgsmeshlayertemporalproperties.cpp:92
qgscoordinatetransform.h
QgsMeshDataProviderTemporalCapabilities::MatchingTemporalDatasetMethod
MatchingTemporalDatasetMethod
Method for selection of temporal mesh dataset from a range time.
Definition: qgsmeshdataprovidertemporalcapabilities.h:41
QgsOptionsDialogBase::initOptionsBase
void initOptionsBase(bool restoreUi=true, const QString &title=QString())
Set up the base ui connections for vertical tabs.
Definition: qgsoptionsdialogbase.cpp:67
QgsMapLayerStyleManager::isDefault
static bool isDefault(const QString &styleName)
Returns true if this is the default style.
Definition: qgsmaplayerstylemanager.cpp:229
QgsProject::setDirty
void setDirty(bool b=true)
Flag the project as dirty (modified).
Definition: qgsproject.cpp:576
QgsSettings::setValue
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
Definition: qgssettings.cpp:279
QgsTemporalProperty::setIsActive
void setIsActive(bool active)
Sets whether the temporal property is active.
Definition: qgstemporalproperty.cpp:27
QgsMeshLayerProperties::addPropertiesPageFactory
void addPropertiesPageFactory(const QgsMapLayerConfigWidgetFactory *factory)
Adds properties page from a factory.
Definition: qgsmeshlayerproperties.cpp:158
QgsMapLayer::rendererChanged
void rendererChanged()
Signal emitted when renderer is changed.
QgsMapLayerStyleManager::currentStyle
QString currentStyle() const
Returns name of the current style.
Definition: qgsmaplayerstylemanager.cpp:164
QgsMeshDatasetGroupTreeWidget::datasetGroupAdded
void datasetGroupAdded()
QgsGui::nativePlatformInterface
static QgsNative * nativePlatformInterface()
Returns the global native interface, which offers abstraction to the host OS's underlying public inte...
Definition: qgsgui.cpp:75
qgsfileutils.h
QgsCoordinateReferenceSystem
This class represents a coordinate reference system (CRS).
Definition: qgscoordinatereferencesystem.h:211
QgsMeshSimplificationSettings
Represents an overview renderer settings.
Definition: qgsmeshsimplificationsettings.h:39
QgsMeshLayer::activeScalarDatasetGroupChanged
void activeScalarDatasetGroupChanged(int index)
Emitted when active scalar group dataset is changed.
qgsmeshlayer.h
QgsUnitTypes::TemporalHours
@ TemporalHours
Hours.
Definition: qgsunittypes.h:154
qgsprojecttimesettings.h
QgsMapLayer::dataChanged
void dataChanged()
Data of layer changed.
QgsUnitTypes::TemporalMinutes
@ TemporalMinutes
Minutes.
Definition: qgsunittypes.h:153
QgsFileUtils::ensureFileNameHasExtension
static QString ensureFileNameHasExtension(const QString &fileName, const QStringList &extensions)
Ensures that a fileName ends with an extension from the provided list of extensions.
Definition: qgsfileutils.cpp:111
QgsDatumTransformDialog::run
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...
Definition: qgsdatumtransformdialog.cpp:34
QgsMapLayerStyleManager::style
QgsMapLayerStyle style(const QString &name) const
Returns data of a stored style - accessed by its unique name.
Definition: qgsmaplayerstylemanager.cpp:96
QgsMapLayer::extensionPropertyType
static QString extensionPropertyType(PropertyType type)
Returns the extension of a Property.
Definition: qgsmaplayer.cpp:68
QgsMeshDataProviderTemporalCapabilities::FindClosestDatasetBeforeStartRangeTime
@ FindClosestDatasetBeforeStartRangeTime
Definition: qgsmeshdataprovidertemporalcapabilities.h:43
QgsMapLayerStyleGuiUtils::removesExtraMenuSeparators
void removesExtraMenuSeparators(QMenu *m)
removes extra separators from the menu
Definition: qgsmaplayerstyleguiutils.cpp:98
qgsmeshstaticdatasetwidget.h
QgsMapLayer::setName
void setName(const QString &name)
Set the display name of the layer.
Definition: qgsmaplayer.cpp:174
QgsHelp::openHelp
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:36
QgsOptionsDialogBase::optionsStackedWidget_CurrentChanged
virtual void optionsStackedWidget_CurrentChanged(int index)
Select relevant tab on current page change.
Definition: qgsoptionsdialogbase.cpp:783
QgsMapLayer
Base class for all map layer types. This is the base class for all map layer types (vector,...
Definition: qgsmaplayer.h:72
QgsMeshLayerProperties::QgsMeshLayerProperties
QgsMeshLayerProperties(QgsMapLayer *lyr, QgsMapCanvas *canvas, QWidget *parent=nullptr, Qt::WindowFlags=QgsGuiUtils::ModalDialogFlags)
Constructor.
Definition: qgsmeshlayerproperties.cpp:49
QgsMeshLayer::loadDefaultStyle
QString loadDefaultStyle(bool &resultFlag) FINAL
Retrieve the default style for this layer if one exists (either as a .qml file on disk or as a record...
Definition: qgsmeshlayer.cpp:169
qgssettings.h
QgsMapLayer::name
QString name
Definition: qgsmaplayer.h:76
qgsdatumtransformdialog.h
QgsMetadataWidget
A wizard to edit metadata on a map layer.
Definition: qgsmetadatawidget.h:41
QgsOptionsDialogBase::mOptStackedWidget
QStackedWidget * mOptStackedWidget
Definition: qgsoptionsdialogbase.h:226
QgsMapLayerConfigWidgetFactory::supportsLayer
virtual bool supportsLayer(QgsMapLayer *layer) const
Check if the layer is supported for this widget.
Definition: qgsmaplayerconfigwidgetfactory.cpp:29
QgsSettings::contains
bool contains(const QString &key, QgsSettings::Section section=QgsSettings::NoSection) const
Returns true if there exists a setting called key; returns false otherwise.
Definition: qgssettings.cpp:175
QgsMeshLayer::temporalProperties
QgsMapLayerTemporalProperties * temporalProperties() override
Returns the layer's temporal properties.
Definition: qgsmeshlayer.cpp:1824
qgslogger.h
QgsMeshLayerTemporalProperties::matchingMethod
QgsMeshDataProviderTemporalCapabilities::MatchingTemporalDatasetMethod matchingMethod() const
Returns the method used to match dataset from temporal capabilities.
Definition: qgsmeshlayertemporalproperties.cpp:109
QgsMapLayerConfigWidgetFactory::supportLayerPropertiesDialog
virtual bool supportLayerPropertiesDialog() const
Flag if widget is supported for use in layer properties dialog.
Definition: qgsmaplayerconfigwidgetfactory.h:103
QgsMeshLayer::activeVectorDatasetGroupChanged
void activeVectorDatasetGroupChanged(int index)
Emitted when active vector group dataset is changed.
Q_NOWARN_DEPRECATED_PUSH
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:2819
QgsMeshSimplificationSettings::reductionFactor
double reductionFactor() const
Returns the reduction factor used to build simplified mesh.
Definition: qgsmeshsimplificationsettings.cpp:30
qgsmaplayerconfigwidgetfactory.h
QgsMapLayer::loadNamedStyle
virtual QString loadNamedStyle(const QString &uri, bool &resultFlag, QgsMapLayer::StyleCategories categories=QgsMapLayer::AllStyleCategories)
Retrieve a named style for this layer if one exists (either as a .qml file on disk or as a record in ...
Definition: qgsmaplayer.cpp:1116
QgsApplication::reportStyleSheet
static QString reportStyleSheet(QgsApplication::StyleSheetType styleSheetType=QgsApplication::StyleSheetType::Qt)
Returns a css style sheet for reports, the styleSheetType argument determines what type of stylesheet...
Definition: qgsapplication.cpp:1517
QgsMapLayerConfigWidgetFactory::icon
virtual QIcon icon() const
The icon that will be shown in the UI for the panel.
Definition: qgsmaplayerconfigwidgetfactory.h:62
qgshelp.h
QgsMapLayer::loadNamedMetadata
virtual QString loadNamedMetadata(const QString &uri, bool &resultFlag)
Retrieve a named metadata for this layer if one exists (either as a .qmd file on disk or as a record ...
Definition: qgsmaplayer.cpp:1340
QgsMeshStaticDatasetWidget::setVectorDatasetGroup
void setVectorDatasetGroup(int index)
Sets the vector dataset group.
Definition: qgsmeshstaticdatasetwidget.cpp:82
QgsMeshLayer::dataProvider
QgsMeshDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
Definition: qgsmeshlayer.cpp:110
qgsproject.h
QgsOptionsDialogBase::restoreOptionsBaseUi
void restoreOptionsBaseUi(const QString &title=QString())
Restore the base ui.
Definition: qgsoptionsdialogbase.cpp:206
QgsMeshDataProviderTemporalCapabilities::timeExtent
QgsDateTimeRange timeExtent() const
Returns the time extent using the internal reference time and the first and last times available from...
Definition: qgsmeshdataprovidertemporalcapabilities.cpp:109
qgsmeshlayertemporalproperties.h
QgsMeshLayer::isEditable
bool isEditable() const override
Returns true if the layer can be edited.
Definition: qgsmeshlayer.cpp:1759
QgsMeshDataProviderTemporalCapabilities::referenceTime
QDateTime referenceTime() const
Returns the reference time.
Definition: qgsmeshdataprovidertemporalcapabilities.cpp:104
QgsMeshSimplificationSettings::meshResolution
int meshResolution() const
Returns the mesh resolution i.e., the minimum size (average) of triangles in pixels.
Definition: qgsmeshsimplificationsettings.cpp:58
QgsMapLayerConfigWidgetFactory
Factory class for creating custom map layer property pages.
Definition: qgsmaplayerconfigwidgetfactory.h:34