QGIS API Documentation  3.20.0-Odense (decaadbb31)
qgsprocessingmeshdatasetwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsprocessingmeshdatasetgroupswidget.h
3  ---------------------
4  Date : October 2020
5  Copyright : (C) 2020 by Vincent Cloarec
6  Email : vcloarec at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 #include "qgsdatetimeedit.h"
19 #include "qgsprocessingoutputs.h"
20 #include "qgsmeshlayer.h"
21 #include "qgsmeshlayerutils.h"
23 #include "qgspanelwidget.h"
24 #include "qgsmapcanvas.h"
25 
26 #include <QLineEdit>
27 #include <QLabel>
28 #include <QMenu>
29 #include <QToolButton>
30 #include <QVBoxLayout>
31 
33 
34 QgsProcessingMeshDatasetGroupsWidget::QgsProcessingMeshDatasetGroupsWidget( QWidget *parent, const QgsProcessingParameterMeshDatasetGroups *param )
35  : QWidget( parent ),
36  mParam( param )
37 {
38  QHBoxLayout *hl = new QHBoxLayout();
39  hl->setContentsMargins( 0, 0, 0, 0 );
40 
41  mLineEdit = new QLineEdit();
42  mLineEdit->setEnabled( false );
43  hl->addWidget( mLineEdit, 1 );
44 
45  mToolButton = new QToolButton();
46  mToolButton->setText( QString( QChar( 0x2026 ) ) );
47  hl->addWidget( mToolButton );
48 
49  setLayout( hl );
50 
51  mLineEdit->setText( tr( "%1 dataset groups selected" ).arg( 0 ) );
52 
53  mToolButton->setPopupMode( QToolButton::InstantPopup );
54  QMenu *toolButtonMenu = new QMenu( this );
55  mActionCurrentActiveDatasetGroups = toolButtonMenu->addAction( tr( "Current Active Dataset Group" ) );
56  connect( mActionCurrentActiveDatasetGroups,
57  &QAction::triggered, this, &QgsProcessingMeshDatasetGroupsWidget::selectCurrentActiveDatasetGroup );
58 
59  mActionAvailableDatasetGroups = toolButtonMenu->addAction( tr( "Select in Available Dataset Groups" ) );
60  connect( mActionAvailableDatasetGroups, &QAction::triggered, this, &QgsProcessingMeshDatasetGroupsWidget::showDialog );
61 
62  mToolButton->setMenu( toolButtonMenu );
63 }
64 
65 void QgsProcessingMeshDatasetGroupsWidget::setMeshLayer( QgsMeshLayer *layer, bool layerFromProject )
66 {
67  mActionCurrentActiveDatasetGroups->setEnabled( layer && layerFromProject );
68  mActionAvailableDatasetGroups->setEnabled( layer );
69 
70  if ( mMeshLayer == layer )
71  return;
72 
73  mDatasetGroupsNames.clear();
74 
75  if ( layerFromProject )
76  mMeshLayer = layer;
77  else
78  {
79  mMeshLayer = nullptr;
80  if ( layer )
81  {
82  QList<int> datasetGroupsIndexes = layer->datasetGroupsIndexes();
83  for ( int i : datasetGroupsIndexes )
84  {
86  if ( mParam->isDataTypeSupported( meta.dataType() ) )
87  {
88  mDatasetGroupsNames[i] = meta.name();
89  }
90  }
91  }
92  }
93  mValue.clear();
94  updateSummaryText();
95  emit changed();
96 }
97 
98 void QgsProcessingMeshDatasetGroupsWidget::setValue( const QVariant &value )
99 {
100  if ( value.isValid() )
101  mValue = value.type() == QVariant::List ? value.toList() : QVariantList() << value;
102  else
103  mValue.clear();
104 
105  updateSummaryText();
106  emit changed();
107 }
108 
109 QVariant QgsProcessingMeshDatasetGroupsWidget::value() const
110 {
111  return mValue;
112 }
113 
114 void QgsProcessingMeshDatasetGroupsWidget::showDialog()
115 {
116  QList<int> datasetGroupsIndexes;
117  QStringList options;
118  QVariantList availableOptions;
119  if ( mMeshLayer )
120  {
121  datasetGroupsIndexes = mMeshLayer->datasetGroupsIndexes();
122  for ( int i : std::as_const( datasetGroupsIndexes ) )
123  {
124  QgsMeshDatasetGroupMetadata meta = mMeshLayer->datasetGroupMetadata( i );
125  if ( mParam->isDataTypeSupported( meta.dataType() ) )
126  {
127  availableOptions.append( i );
128  options.append( meta.name() );
129  }
130 
131  }
132  }
133  else
134  {
135  for ( int i : mDatasetGroupsNames.keys() )
136  {
137  availableOptions.append( i );
138  options.append( mDatasetGroupsNames.value( i ) );
139  }
140  }
141 
143  if ( panel && panel->dockMode() )
144  {
145  QgsProcessingMultipleSelectionPanelWidget *widget = new QgsProcessingMultipleSelectionPanelWidget( availableOptions, mValue );
146  widget->setPanelTitle( tr( "Dataset Groups Available" ) );
147 
148  widget->setValueFormatter( [availableOptions, options]( const QVariant & v ) -> QString
149  {
150  const int index = v.toInt();
151  const int pos = availableOptions.indexOf( index );
152  return ( pos >= 0 && pos < options.size() ) ? options.at( pos ) : QString();
153  } );
154 
155  connect( widget, &QgsProcessingMultipleSelectionPanelWidget::selectionChanged, this, [ = ]()
156  {
157  setValue( widget->selectedOptions() );
158  } );
159  connect( widget, &QgsProcessingMultipleSelectionPanelWidget::acceptClicked, widget, &QgsPanelWidget::acceptPanel );
160  panel->openPanel( widget );
161  }
162  else
163  {
164  QgsProcessingMultipleSelectionDialog dlg( availableOptions, mValue, this, Qt::WindowFlags() );
165 
166  dlg.setValueFormatter( [datasetGroupsIndexes, options]( const QVariant & v ) -> QString
167  {
168  const int index = v.toInt();
169  const int pos = datasetGroupsIndexes.indexOf( index );
170  return ( pos >= 0 && pos < options.size() ) ? options.at( pos ) : QString();
171  } );
172  if ( dlg.exec() )
173  {
174  setValue( dlg.selectedOptions() );
175  }
176  }
177 }
178 
179 void QgsProcessingMeshDatasetGroupsWidget::selectCurrentActiveDatasetGroup()
180 {
181  QVariantList options;
182  if ( mMeshLayer && mParam )
183  {
184  int scalarDatasetGroup = mMeshLayer->rendererSettings().activeScalarDatasetGroup();
185  int vectorDatasetGroup = mMeshLayer->rendererSettings().activeVectorDatasetGroup();
186 
187  if ( scalarDatasetGroup >= 0 && mParam->isDataTypeSupported( mMeshLayer->datasetGroupMetadata( scalarDatasetGroup ).dataType() ) )
188  options.append( scalarDatasetGroup );
189 
190  if ( vectorDatasetGroup >= 0
191  && mParam->isDataTypeSupported( mMeshLayer->datasetGroupMetadata( vectorDatasetGroup ).dataType() )
192  && vectorDatasetGroup != scalarDatasetGroup )
193  options.append( vectorDatasetGroup );
194  }
195 
196  setValue( options );
197 }
198 
199 QgsProcessingMeshDatasetGroupsWidgetWrapper::QgsProcessingMeshDatasetGroupsWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent ):
200  QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
201 {}
202 
203 QString QgsProcessingMeshDatasetGroupsWidgetWrapper::parameterType() const
204 {
206 }
207 
208 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingMeshDatasetGroupsWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
209 {
210  return new QgsProcessingMeshDatasetGroupsWidgetWrapper( parameter, type );
211 }
212 
213 void QgsProcessingMeshDatasetGroupsWidgetWrapper::postInitialize( const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
214 {
216  switch ( type() )
217  {
220  {
221  for ( const QgsAbstractProcessingParameterWidgetWrapper *wrapper : wrappers )
222  {
223  if ( wrapper->parameterDefinition()->name() == static_cast< const QgsProcessingParameterMeshDatasetGroups * >( parameterDefinition() )->meshLayerParameterName() )
224  {
225  setMeshLayerWrapperValue( wrapper );
227  {
228  setMeshLayerWrapperValue( wrapper );
229  } );
230  break;
231  }
232  }
233  break;
234  }
235 
237  break;
238  }
239 }
240 
241 void QgsProcessingMeshDatasetGroupsWidgetWrapper::setMeshLayerWrapperValue( const QgsAbstractProcessingParameterWidgetWrapper *wrapper )
242 {
243  if ( ! mWidget )
244  return;
245 
246  // evaluate value to layer
247  QgsProcessingContext *context = nullptr;
248  if ( mProcessingContextGenerator )
249  context = mProcessingContextGenerator->processingContext();
250 
251  bool layerFromProject;
252  QgsMeshLayer *meshLayer;
253  if ( !context )
254  {
255  QgsProcessingContext dummyContext;
256  meshLayer = QgsProcessingParameters::parameterAsMeshLayer( wrapper->parameterDefinition(), wrapper->parameterValue(), dummyContext );
257  layerFromProject = false;
258  }
259  else
260  {
261  meshLayer = QgsProcessingParameters::parameterAsMeshLayer( wrapper->parameterDefinition(), wrapper->parameterValue(), *context );
262  layerFromProject = context->project() && context->project()->layerStore()->layers<QgsMeshLayer *>().contains( meshLayer );
263  }
264 
265  if ( mWidget )
266  mWidget->setMeshLayer( meshLayer, layerFromProject );
267 }
268 
269 QStringList QgsProcessingMeshDatasetGroupsWidgetWrapper::compatibleParameterTypes() const
270 {
271  return QStringList() << QgsProcessingParameterMeshDatasetGroups::typeName()
274 }
275 
276 QStringList QgsProcessingMeshDatasetGroupsWidgetWrapper::compatibleOutputTypes() const
277 {
278  return QStringList() << QgsProcessingOutputString::typeName()
280 }
281 
282 QWidget *QgsProcessingMeshDatasetGroupsWidgetWrapper::createWidget() SIP_FACTORY
283 {
284  mWidget = new QgsProcessingMeshDatasetGroupsWidget( nullptr, static_cast<const QgsProcessingParameterMeshDatasetGroups *>( parameterDefinition() ) );
285  connect( mWidget, &QgsProcessingMeshDatasetGroupsWidget::changed, this, [ = ]
286  {
287  emit widgetValueHasChanged( this );
288  } );
289 
290  return mWidget;
291 }
292 
293 void QgsProcessingMeshDatasetGroupsWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
294 {
295  if ( !mWidget )
296  return;
297 
298  QList<int> datasetGroupIndexes;
299  if ( value.type() == QVariant::List )
300  {
301  //here we can't use QgsProcessingParameters::parameterAsInts() because this method return empry list when first value is 0...
302  datasetGroupIndexes = QgsProcessingParameters::parameterAsInts( parameterDefinition(), value, context );
303  }
304  else
305  datasetGroupIndexes.append( QgsProcessingParameters::parameterAsInt( parameterDefinition(), value, context ) );
306 
307  QVariantList varList;
308  for ( const int index : std::as_const( datasetGroupIndexes ) )
309  varList.append( index );
310 
311  mWidget->setValue( varList );
312 }
313 
314 QVariant QgsProcessingMeshDatasetGroupsWidgetWrapper::widgetValue() const
315 {
316  if ( mWidget )
317  return mWidget->value();
318  return QVariant();
319 }
320 
321 
322 void QgsProcessingMeshDatasetGroupsWidget::updateSummaryText()
323 {
324  mLineEdit->setText( tr( "%1 options selected" ).arg( mValue.count() ) );
325 }
326 
327 QgsProcessingMeshDatasetTimeWidgetWrapper::QgsProcessingMeshDatasetTimeWidgetWrapper( const QgsProcessingParameterDefinition *parameter,
329  QWidget *parent )
330  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
331 {
332 
333 }
334 
335 QString QgsProcessingMeshDatasetTimeWidgetWrapper::parameterType() const
336 {
338 }
339 
340 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingMeshDatasetTimeWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
341 {
342  return new QgsProcessingMeshDatasetTimeWidgetWrapper( parameter, type );
343 }
344 
345 void QgsProcessingMeshDatasetTimeWidgetWrapper::postInitialize( const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
346 {
348  switch ( type() )
349  {
352  {
353  const QgsAbstractProcessingParameterWidgetWrapper *layerParameterWrapper = nullptr;
354  const QgsAbstractProcessingParameterWidgetWrapper *datasetGroupsParameterWrapper = nullptr;
355  for ( const QgsAbstractProcessingParameterWidgetWrapper *wrapper : wrappers )
356  {
357  if ( wrapper->parameterDefinition()->name() == static_cast< const QgsProcessingParameterMeshDatasetTime * >( parameterDefinition() )->meshLayerParameterName() )
358  layerParameterWrapper = wrapper;
359 
360  if ( wrapper->parameterDefinition()->name() == static_cast< const QgsProcessingParameterMeshDatasetTime * >( parameterDefinition() )->datasetGroupParameterName() )
361  datasetGroupsParameterWrapper = wrapper;
362  }
363  setMeshLayerWrapperValue( layerParameterWrapper );
364  setDatasetGroupIndexesWrapperValue( datasetGroupsParameterWrapper );
365  connect( datasetGroupsParameterWrapper, &QgsAbstractProcessingParameterWidgetWrapper::widgetValueHasChanged, this, [ = ]
366  {
367  setMeshLayerWrapperValue( layerParameterWrapper );
368  setDatasetGroupIndexesWrapperValue( datasetGroupsParameterWrapper );
369  } );
370 
371  break;
372  }
373 
375  break;
376  }
377 }
378 
379 void QgsProcessingMeshDatasetTimeWidgetWrapper::setMeshLayerWrapperValue( const QgsAbstractProcessingParameterWidgetWrapper *wrapper )
380 {
381  if ( !mWidget || !wrapper )
382  return;
383 
384  // evaluate value to layer
385  QgsProcessingContext *context = nullptr;
386  if ( mProcessingContextGenerator )
387  context = mProcessingContextGenerator->processingContext();
388 
389  bool layerFromProject;
390  QgsMeshLayer *meshLayer;
391  if ( !context )
392  {
393  QgsProcessingContext dummyContext;
394  meshLayer = QgsProcessingParameters::parameterAsMeshLayer( wrapper->parameterDefinition(), wrapper->parameterValue(), dummyContext );
395  layerFromProject = false;
396  }
397  else
398  {
399  meshLayer = QgsProcessingParameters::parameterAsMeshLayer( wrapper->parameterDefinition(), wrapper->parameterValue(), *context );
400  layerFromProject = context->project() && context->project()->layerStore()->layers<QgsMeshLayer *>().contains( meshLayer );
401  }
402 
403  mWidget->setMeshLayer( meshLayer, layerFromProject );
404 }
405 
406 void QgsProcessingMeshDatasetTimeWidgetWrapper::setDatasetGroupIndexesWrapperValue( const QgsAbstractProcessingParameterWidgetWrapper *wrapper )
407 {
408  if ( !mWidget || !wrapper )
409  return;
410 
411  QVariant datasetGroupsVariant = wrapper->parameterValue();
412 
413  if ( !datasetGroupsVariant.isValid() || datasetGroupsVariant.type() != QVariant::List )
414  mWidget->setDatasetGroupIndexes( QList<int>() );
415 
416  QVariantList datasetGroupsListVariant = datasetGroupsVariant.toList();
417 
418  QList<int> datasetGroupsIndexes;
419  for ( const QVariant &variantIndex : datasetGroupsListVariant )
420  datasetGroupsIndexes << variantIndex.toInt();
421 
422  mWidget->setDatasetGroupIndexes( datasetGroupsIndexes );
423 
424 }
425 
426 QStringList QgsProcessingMeshDatasetTimeWidgetWrapper::compatibleParameterTypes() const
427 {
428  return QStringList()
432 }
433 
434 QStringList QgsProcessingMeshDatasetTimeWidgetWrapper::compatibleOutputTypes() const
435 {
436  return QStringList()
438 }
439 
440 QWidget *QgsProcessingMeshDatasetTimeWidgetWrapper::createWidget()
441 {
442  mWidget = new QgsProcessingMeshDatasetTimeWidget( nullptr, static_cast<const QgsProcessingParameterMeshDatasetTime *>( parameterDefinition() ), widgetContext() );
443 
444  QgsMapCanvas *canvas = widgetContext().mapCanvas();
445  if ( canvas )
446  {
447  connect( canvas, &QgsMapCanvas::temporalRangeChanged, mWidget, &QgsProcessingMeshDatasetTimeWidget::updateValue );
448  }
449  connect( mWidget, &QgsProcessingMeshDatasetTimeWidget::changed, this, [ = ]
450  {
451  emit widgetValueHasChanged( this );
452  } );
453 
454  return mWidget;
455 }
456 
457 void QgsProcessingMeshDatasetTimeWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
458 {
459  Q_UNUSED( context );
460  if ( mWidget )
461  mWidget->setValue( value );
462 }
463 
464 QVariant QgsProcessingMeshDatasetTimeWidgetWrapper::widgetValue() const
465 {
466  if ( mWidget )
467  return mWidget->value();
468  return QVariant();
469 }
470 
471 QgsProcessingMeshDatasetTimeWidget::QgsProcessingMeshDatasetTimeWidget( QWidget *parent,
473  const QgsProcessingParameterWidgetContext &context ):
474  QWidget( parent ),
475  mParam( param )
476 {
477  setupUi( this );
478 
479  mValue.insert( QStringLiteral( "type" ), QStringLiteral( "static" ) );
480 
481  dateTimeEdit->setDisplayFormat( "yyyy-MM-dd HH:mm:ss" );
482 
483  mCanvas = context.mapCanvas();
484 
485  connect( radioButtonCurrentCanvasTime, &QRadioButton::toggled, [this]( bool isChecked ) {if ( isChecked ) this->updateValue();} );
486  connect( radioButtonDefinedDateTime, &QRadioButton::toggled, [this]( bool isChecked ) {if ( isChecked ) this->updateValue();} );
487  connect( radioButtonDatasetGroupTimeStep, &QRadioButton::toggled, [this]( bool isChecked ) {if ( isChecked ) this->updateValue();} );
488  connect( dateTimeEdit, &QgsDateTimeEdit::dateTimeChanged, this, &QgsProcessingMeshDatasetTimeWidget::updateValue );
489  connect( comboBoxDatasetTimeStep, qOverload<int>( &QComboBox::currentIndexChanged ),
490  this, &QgsProcessingMeshDatasetTimeWidget::updateValue );
491 
492  updateWidget();
493 }
494 
495 void QgsProcessingMeshDatasetTimeWidget::setMeshLayer( QgsMeshLayer *layer, bool layerFromProject )
496 {
497  if ( mMeshLayer == layer )
498  return;
499 
500  mReferenceTime = QDateTime();
501 
502  if ( layerFromProject )
503  {
504  mMeshLayer = layer;
505  mReferenceTime = static_cast<QgsMeshLayerTemporalProperties *>( layer->temporalProperties() )->referenceTime();
506  }
507  else
508  {
509  mMeshLayer = nullptr;
510  if ( layer )
511  mReferenceTime = layer->dataProvider()->temporalCapabilities()->referenceTime();
512  storeTimeStepsFromLayer( layer );
513  }
514 
515  if ( mReferenceTime.isValid() )
516  whileBlocking( dateTimeEdit )->setDateTime( mReferenceTime );
517 
518  updateValue();
519 }
520 
521 void QgsProcessingMeshDatasetTimeWidget::setDatasetGroupIndexes( const QList<int> datasetGroupIndexes )
522 {
523  if ( datasetGroupIndexes == mDatasetGroupIndexes )
524  return;
525  mDatasetGroupIndexes = datasetGroupIndexes;
526  populateTimeSteps();
527  updateValue();
528 }
529 
530 void QgsProcessingMeshDatasetTimeWidget::setValue( const QVariant &value )
531 {
532  if ( !value.isValid() || ( value.type() != QVariant::Map && !value.toDateTime().isValid() ) )
533  return;
534 
535  mValue.clear();
536  if ( value.toDateTime().isValid() )
537  {
538  QDateTime dateTime = value.toDateTime();
539  dateTime.setTimeSpec( Qt::UTC );
540  mValue.insert( QStringLiteral( "type" ), QStringLiteral( "defined-date-time" ) );
541  mValue.insert( QStringLiteral( "value" ), dateTime );
542  }
543  else
544  mValue = value.toMap();
545 
546  if ( !mValue.contains( QStringLiteral( "type" ) ) || !mValue.contains( QStringLiteral( "value" ) ) )
547  return;
548 
549  QString type = mValue.value( QStringLiteral( "type" ) ).toString();
550 
551  setEnabled( true );
552  if ( type == QLatin1String( "static" ) )
553  {
554  setEnabled( false );
555  }
556  else if ( type == QLatin1String( "dataset-time-step" ) )
557  {
558  QVariantList dataset = mValue.value( QStringLiteral( "value" ) ).toList();
559  whileBlocking( comboBoxDatasetTimeStep )->setCurrentIndex( comboBoxDatasetTimeStep->findData( dataset ) );
560  whileBlocking( radioButtonDatasetGroupTimeStep )->setChecked( true );
561  }
562  else if ( type == QLatin1String( "defined-date-time" ) )
563  {
564  whileBlocking( dateTimeEdit )->setDateTime( mValue.value( QStringLiteral( "value" ) ).toDateTime() );
565  whileBlocking( radioButtonDefinedDateTime )->setChecked( true );
566  }
567  else if ( type == QLatin1String( "current-context-time" ) )
568  {
569  whileBlocking( radioButtonCurrentCanvasTime )->setChecked( true );
570  }
571 
572  emit changed();
573  updateWidget();
574 }
575 
576 QVariant QgsProcessingMeshDatasetTimeWidget::value() const
577 {
578  return mValue;
579 }
580 
581 void QgsProcessingMeshDatasetTimeWidget::updateWidget()
582 {
583  bool isStatic = !hasTemporalDataset();
584  setEnabled( !isStatic );
585 
586  if ( mCanvas != nullptr && mCanvas->mapSettings().isTemporal() )
587  {
588  whileBlocking( radioButtonCurrentCanvasTime )->setEnabled( true && mReferenceTime.isValid() );
589  labelCurrentCanvasTime->setText( mCanvas->mapSettings().temporalRange().begin().toString( "yyyy-MM-dd HH:mm:ss" ) );
590  }
591  else
592  {
593  whileBlocking( radioButtonCurrentCanvasTime )->setEnabled( false );
594  if ( radioButtonCurrentCanvasTime->isChecked() )
595  whileBlocking( radioButtonDefinedDateTime )->setChecked( true );
596  }
597 
598  if ( ! mReferenceTime.isValid() )
599  whileBlocking( radioButtonDatasetGroupTimeStep )->setChecked( true );
600 
601  whileBlocking( radioButtonDefinedDateTime )->setEnabled( mReferenceTime.isValid() );
602 
603  dateTimeEdit->setVisible( radioButtonDefinedDateTime->isChecked() && !isStatic );
604  labelCurrentCanvasTime->setVisible( radioButtonCurrentCanvasTime->isChecked() && !isStatic );
605  comboBoxDatasetTimeStep->setVisible( radioButtonDatasetGroupTimeStep->isChecked() && !isStatic );
606 }
607 
608 bool QgsProcessingMeshDatasetTimeWidget::hasTemporalDataset() const
609 {
610  for ( int index : mDatasetGroupIndexes )
611  {
612  if ( mMeshLayer && mMeshLayer->datasetGroupMetadata( index ).isTemporal() )
613  return true;
614  else if ( mDatasetTimeSteps.contains( index ) )
615  return true;
616  }
617 
618  return false;
619 }
620 
621 
622 void QgsProcessingMeshDatasetTimeWidget::populateTimeSteps()
623 {
624  if ( mMeshLayer )
625  {
626  populateTimeStepsFromLayer();
627  return;
628  }
629 
630  QMap<quint64, QgsMeshDatasetIndex> timeStep;
631  for ( int groupIndex : mDatasetGroupIndexes )
632  {
633  if ( !mDatasetTimeSteps.contains( groupIndex ) )
634  continue;
635  const QList<qint64> relativeTimeSteps = mDatasetTimeSteps.value( groupIndex );
636  for ( int index = 0; index < relativeTimeSteps.count(); ++index )
637  {
638  QgsMeshDatasetIndex datasetIndex( groupIndex, index );
639  if ( timeStep.contains( relativeTimeSteps.at( index ) ) )
640  continue;
641  timeStep[relativeTimeSteps.at( index )] = datasetIndex;
642  }
643  }
644 
645  for ( qint64 key : timeStep.keys() )
646  {
647  QString stringTime = QgsMeshLayerUtils::formatTime( key / 1000 / 3600, mReferenceTime, QgsMeshTimeSettings() );
648  QVariantList data;
649  const QgsMeshDatasetIndex &index = timeStep.value( key );
650  data << index.group() << index.dataset();
651  whileBlocking( comboBoxDatasetTimeStep )->addItem( stringTime, data );
652  }
653 
654 }
655 
656 void QgsProcessingMeshDatasetTimeWidget::populateTimeStepsFromLayer()
657 {
658  whileBlocking( comboBoxDatasetTimeStep )->clear();
659 
660  if ( !mMeshLayer )
661  return;
662 
663  QMap<quint64, QgsMeshDatasetIndex> timeStep;
664  for ( int groupIndex : std::as_const( mDatasetGroupIndexes ) )
665  {
666  QgsMeshDatasetGroupMetadata meta = mMeshLayer->datasetGroupMetadata( groupIndex );
667  if ( !meta.isTemporal() )
668  continue;
669  int datasetCount = mMeshLayer->datasetCount( groupIndex );
670 
671  for ( int index = 0; index < datasetCount; ++index )
672  {
673  QgsMeshDatasetIndex datasetIndex( groupIndex, index );
674  qint64 relativeTime = mMeshLayer->datasetRelativeTimeInMilliseconds( datasetIndex );
675  if ( timeStep.contains( relativeTime ) )
676  continue;
677  timeStep[relativeTime] = datasetIndex;
678  }
679  }
680 
681  for ( qint64 key : timeStep.keys() )
682  {
683  QString stringTime = mMeshLayer->formatTime( key / 1000.0 / 3600.0 );
684  QVariantList data;
685  const QgsMeshDatasetIndex &index = timeStep.value( key );
686  data << index.group() << index.dataset();
687  whileBlocking( comboBoxDatasetTimeStep )->addItem( stringTime, data );
688  }
689 }
690 
691 void QgsProcessingMeshDatasetTimeWidget::storeTimeStepsFromLayer( QgsMeshLayer *layer )
692 {
693  mDatasetTimeSteps.clear();
694  if ( !layer )
695  return;
696  QList<int> datasetGroupsList = layer->datasetGroupsIndexes();
697  for ( int groupIndex : datasetGroupsList )
698  {
699  QgsMeshDatasetGroupMetadata meta = layer->datasetGroupMetadata( groupIndex );
700  if ( !meta.isTemporal() )
701  continue;
702  int datasetCount = layer->datasetCount( groupIndex );
703  QList<qint64> relativeTimeSteps;
704  relativeTimeSteps.reserve( datasetCount );
705  for ( int index = 0; index < datasetCount; ++index )
706  relativeTimeSteps.append( layer->datasetRelativeTimeInMilliseconds( QgsMeshDatasetIndex( groupIndex, index ) ) );
707  mDatasetTimeSteps[groupIndex] = relativeTimeSteps;
708  }
709 }
710 
711 void QgsProcessingMeshDatasetTimeWidget::buildValue()
712 {
713  mValue.clear();
714 
715  if ( !isEnabled() )
716  {
717  mValue[QStringLiteral( "type" )] = QStringLiteral( "static" );
718  }
719  else if ( radioButtonDatasetGroupTimeStep->isChecked() )
720  {
721  mValue[QStringLiteral( "type" )] = QStringLiteral( "dataset-time-step" );
722  mValue[QStringLiteral( "value" )] = comboBoxDatasetTimeStep->currentData();
723  }
724  else if ( radioButtonDefinedDateTime->isChecked() )
725  {
726  mValue[QStringLiteral( "type" )] = QStringLiteral( "defined-date-time" );
727  mValue[QStringLiteral( "value" )] = dateTimeEdit->dateTime();
728  }
729  else if ( radioButtonCurrentCanvasTime->isChecked() && mCanvas )
730  {
731  mValue[QStringLiteral( "type" )] = QStringLiteral( "current-context-time" );
732  }
733 
734  emit changed();
735 }
736 
737 void QgsProcessingMeshDatasetTimeWidget::updateValue()
738 {
739  updateWidget();
740  buildValue();
741 }
742 
A widget wrapper for Processing parameter value widgets.
QVariant parameterValue() const
Returns the current value of the parameter.
void widgetValueHasChanged(QgsAbstractProcessingParameterWidgetWrapper *wrapper)
Emitted whenever the parameter value (as defined by the wrapped widget) is changed.
virtual void postInitialize(const QList< QgsAbstractProcessingParameterWidgetWrapper * > &wrappers)
Called after all wrappers have been created within a particular dialog or context,...
const QgsProcessingParameterDefinition * parameterDefinition() const
Returns the parameter definition associated with this wrapper.
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:86
void temporalRangeChanged()
Emitted when the map canvas temporal range changes.
QVector< T > layers() const
Returns a list of registered map layers with a specified layer type.
QDateTime referenceTime() const
Returns the reference time.
QgsMeshDataProviderTemporalCapabilities * temporalCapabilities() override
Returns the provider's temporal capabilities.
QgsMeshDatasetGroupMetadata is a collection of dataset group metadata such as whether the data is vec...
bool isTemporal() const
Returns whether the dataset group is temporal (contains time-related dataset)
QString name() const
Returns name of the dataset group.
DataType dataType() const
Returns whether dataset group data is defined on vertices or faces or volumes.
QgsMeshDatasetIndex is index that identifies the dataset group (e.g.
int group() const
Returns a group index.
int dataset() const
Returns a dataset index within group()
Implementation of map layer temporal properties for mesh layers.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
Definition: qgsmeshlayer.h:95
int datasetCount(const QgsMeshDatasetIndex &index) const
Returns the dataset count in the dataset groups.
QList< int > datasetGroupsIndexes() const
Returns the list of indexes of dataset groups handled by the layer.
QgsMeshDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
QgsMapLayerTemporalProperties * temporalProperties() override
Returns the layer's temporal properties.
qint64 datasetRelativeTimeInMilliseconds(const QgsMeshDatasetIndex &index)
Returns the relative time (in milliseconds) of the dataset from the reference time of its group.
QgsMeshDatasetGroupMetadata datasetGroupMetadata(const QgsMeshDatasetIndex &index) const
Returns the dataset groups metadata.
Represents a mesh time settings for mesh datasets.
Base class for any widget that can be shown as a inline panel.
void openPanel(QgsPanelWidget *panel)
Open a panel or dialog depending on dock mode setting If dock mode is true this method will emit the ...
void acceptPanel()
Accept the panel.
static QgsPanelWidget * findParentPanel(QWidget *widget)
Traces through the parents of a widget to find if it is contained within a QgsPanelWidget widget.
bool dockMode()
Returns the dock mode state.
Contains information about the context in which a processing algorithm is executed.
QgsProject * project() const
Returns the project in which the algorithm is being executed.
WidgetType
Types of dialogs which Processing widgets can be created for.
@ Modeler
Modeler dialog.
@ Standard
Standard algorithm dialog.
@ Batch
Batch processing dialog.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the parameter class.
Base class for the definition of processing parameters.
QString name() const
Returns the name of the parameter.
A parameter for processing algorithms that need a list of mesh dataset groups.
static QString typeName()
Returns the type name for the parameter class.
A parameter for processing algorithms that need a list of mesh dataset index from time parameter.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
Contains settings which reflect the context in which a Processing parameter widget is shown,...
QgsMapCanvas * mapCanvas() const
Returns the map canvas associated with the widget.
static QList< int > parameterAsInts(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a list of integer values.
static QgsMeshLayer * parameterAsMeshLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition and value to a mesh layer.
static int parameterAsInt(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static integer value.
QgsMapLayerStore * layerStore()
Returns a pointer to the project's internal layer store.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:537
#define SIP_FACTORY
Definition: qgis_sip.h:76