QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 "qgsmeshlayer.h"
20 #include "qgsmeshlayerutils.h"
22 #include "qgspanelwidget.h"
23 #include "qgsmapcanvas.h"
24 
25 #include <QLineEdit>
26 #include <QLabel>
27 #include <QMenu>
28 #include <QToolButton>
29 #include <QVBoxLayout>
30 
32 
33 QgsProcessingMeshDatasetGroupsWidget::QgsProcessingMeshDatasetGroupsWidget( QWidget *parent, const QgsProcessingParameterMeshDatasetGroups *param )
34  : QWidget( parent ),
35  mParam( param )
36 {
37  QHBoxLayout *hl = new QHBoxLayout();
38  hl->setContentsMargins( 0, 0, 0, 0 );
39 
40  mLineEdit = new QLineEdit();
41  mLineEdit->setEnabled( false );
42  hl->addWidget( mLineEdit, 1 );
43 
44  mToolButton = new QToolButton();
45  mToolButton->setText( QString( QChar( 0x2026 ) ) );
46  hl->addWidget( mToolButton );
47 
48  setLayout( hl );
49 
50  mLineEdit->setText( tr( "%1 dataset groups selected" ).arg( 0 ) );
51 
52  mToolButton->setPopupMode( QToolButton::InstantPopup );
53  QMenu *toolButtonMenu = new QMenu( this );
54  mActionCurrentActiveDatasetGroups = toolButtonMenu->addAction( tr( "Current Active Dataset Group" ) );
55  connect( mActionCurrentActiveDatasetGroups,
56  &QAction::triggered, this, &QgsProcessingMeshDatasetGroupsWidget::selectCurrentActiveDatasetGroup );
57 
58  mActionAvailableDatasetGroups = toolButtonMenu->addAction( tr( "Select in Available Dataset Groups" ) );
59  connect( mActionAvailableDatasetGroups, &QAction::triggered, this, &QgsProcessingMeshDatasetGroupsWidget::showDialog );
60 
61  mToolButton->setMenu( toolButtonMenu );
62 }
63 
64 void QgsProcessingMeshDatasetGroupsWidget::setMeshLayer( QgsMeshLayer *layer, bool layerFromProject )
65 {
66  mActionCurrentActiveDatasetGroups->setEnabled( layer && layerFromProject );
67  mActionAvailableDatasetGroups->setEnabled( layer );
68 
69  if ( mMeshLayer == layer )
70  return;
71 
72  mDatasetGroupsNames.clear();
73 
74  if ( layerFromProject )
75  mMeshLayer = layer;
76  else
77  {
78  mMeshLayer = nullptr;
79  if ( layer )
80  {
81  QList<int> datasetGroupsIndexes = layer->datasetGroupsIndexes();
82  for ( int i : datasetGroupsIndexes )
83  {
85  if ( mParam->isDataTypeSupported( meta.dataType() ) )
86  {
87  mDatasetGroupsNames[i] = meta.name();
88  }
89  }
90  }
91  }
92  mValue.clear();
93  updateSummaryText();
94  emit changed();
95 }
96 
97 void QgsProcessingMeshDatasetGroupsWidget::setValue( const QVariant &value )
98 {
99  if ( value.isValid() )
100  mValue = value.type() == QVariant::List ? value.toList() : QVariantList() << value;
101  else
102  mValue.clear();
103 
104  updateSummaryText();
105  emit changed();
106 }
107 
108 QVariant QgsProcessingMeshDatasetGroupsWidget::value() const
109 {
110  return mValue;
111 }
112 
113 void QgsProcessingMeshDatasetGroupsWidget::showDialog()
114 {
115  QList<int> datasetGroupsIndexes;
116  QStringList options;
117  QVariantList availableOptions;
118  if ( mMeshLayer )
119  {
120  datasetGroupsIndexes = mMeshLayer->datasetGroupsIndexes();
121  for ( int i : datasetGroupsIndexes )
122  {
123  QgsMeshDatasetGroupMetadata meta = mMeshLayer->datasetGroupMetadata( i );
124  if ( mParam->isDataTypeSupported( meta.dataType() ) )
125  {
126  availableOptions.append( i );
127  options.append( meta.name() );
128  }
129 
130  }
131  }
132  else
133  {
134  for ( int i : mDatasetGroupsNames.keys() )
135  {
136  availableOptions.append( i );
137  options.append( mDatasetGroupsNames.value( i ) );
138  }
139  }
140 
142  if ( panel && panel->dockMode() )
143  {
144  QgsProcessingMultipleSelectionPanelWidget *widget = new QgsProcessingMultipleSelectionPanelWidget( availableOptions, mValue );
145  widget->setPanelTitle( tr( "Dataset Groups Available" ) );
146 
147  widget->setValueFormatter( [availableOptions, options]( const QVariant & v ) -> QString
148  {
149  const int index = v.toInt();
150  const int pos = availableOptions.indexOf( index );
151  return ( pos >= 0 && pos < options.size() ) ? options.at( pos ) : QString();
152  } );
153 
154  connect( widget, &QgsProcessingMultipleSelectionPanelWidget::selectionChanged, this, [ = ]()
155  {
156  setValue( widget->selectedOptions() );
157  } );
158  connect( widget, &QgsProcessingMultipleSelectionPanelWidget::acceptClicked, widget, &QgsPanelWidget::acceptPanel );
159  panel->openPanel( widget );
160  }
161  else
162  {
163  QgsProcessingMultipleSelectionDialog dlg( availableOptions, mValue, this, Qt::WindowFlags() );
164 
165  dlg.setValueFormatter( [datasetGroupsIndexes, options]( const QVariant & v ) -> QString
166  {
167  const int index = v.toInt();
168  const int pos = datasetGroupsIndexes.indexOf( index );
169  return ( pos >= 0 && pos < options.size() ) ? options.at( pos ) : QString();
170  } );
171  if ( dlg.exec() )
172  {
173  setValue( dlg.selectedOptions() );
174  }
175  }
176 }
177 
178 void QgsProcessingMeshDatasetGroupsWidget::selectCurrentActiveDatasetGroup()
179 {
180  QVariantList options;
181  if ( mMeshLayer && mParam )
182  {
183  int scalarDatasetGroup = mMeshLayer->rendererSettings().activeScalarDatasetGroup();
184  int vectorDatasetGroup = mMeshLayer->rendererSettings().activeVectorDatasetGroup();
185 
186  if ( scalarDatasetGroup >= 0 && mParam->isDataTypeSupported( mMeshLayer->datasetGroupMetadata( scalarDatasetGroup ).dataType() ) )
187  options.append( scalarDatasetGroup );
188 
189  if ( vectorDatasetGroup >= 0
190  && mParam->isDataTypeSupported( mMeshLayer->datasetGroupMetadata( vectorDatasetGroup ).dataType() )
191  && vectorDatasetGroup != scalarDatasetGroup )
192  options.append( vectorDatasetGroup );
193  }
194 
195  setValue( options );
196 }
197 
198 QgsProcessingMeshDatasetGroupsWidgetWrapper::QgsProcessingMeshDatasetGroupsWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent ):
199  QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
200 {}
201 
202 QString QgsProcessingMeshDatasetGroupsWidgetWrapper::parameterType() const
203 {
205 }
206 
207 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingMeshDatasetGroupsWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
208 {
209  return new QgsProcessingMeshDatasetGroupsWidgetWrapper( parameter, type );
210 }
211 
212 void QgsProcessingMeshDatasetGroupsWidgetWrapper::postInitialize( const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
213 {
215  switch ( type() )
216  {
219  {
220  for ( const QgsAbstractProcessingParameterWidgetWrapper *wrapper : wrappers )
221  {
222  if ( wrapper->parameterDefinition()->name() == static_cast< const QgsProcessingParameterMeshDatasetGroups * >( parameterDefinition() )->meshLayerParameterName() )
223  {
224  setMeshLayerWrapperValue( wrapper );
226  {
227  setMeshLayerWrapperValue( wrapper );
228  } );
229  break;
230  }
231  }
232  break;
233  }
234 
236  break;
237  }
238 }
239 
240 void QgsProcessingMeshDatasetGroupsWidgetWrapper::setMeshLayerWrapperValue( const QgsAbstractProcessingParameterWidgetWrapper *wrapper )
241 {
242  if ( ! mWidget )
243  return;
244 
245  // evaluate value to layer
246  QgsProcessingContext *context = nullptr;
247  if ( mProcessingContextGenerator )
248  context = mProcessingContextGenerator->processingContext();
249 
250  bool layerFromProject;
251  QgsMeshLayer *meshLayer;
252  if ( !context )
253  {
254  QgsProcessingContext dummyContext;
255  meshLayer = QgsProcessingParameters::parameterAsMeshLayer( wrapper->parameterDefinition(), wrapper->parameterValue(), dummyContext );
256  layerFromProject = false;
257  }
258  else
259  {
260  meshLayer = QgsProcessingParameters::parameterAsMeshLayer( wrapper->parameterDefinition(), wrapper->parameterValue(), *context );
261  layerFromProject = context->project() && context->project()->layerStore()->layers<QgsMeshLayer *>().contains( meshLayer );
262  }
263 
264  if ( mWidget )
265  mWidget->setMeshLayer( meshLayer, layerFromProject );
266 }
267 
268 QWidget *QgsProcessingMeshDatasetGroupsWidgetWrapper::createWidget() SIP_FACTORY
269 {
270  mWidget = new QgsProcessingMeshDatasetGroupsWidget( nullptr, static_cast<const QgsProcessingParameterMeshDatasetGroups *>( parameterDefinition() ) );
271  connect( mWidget, &QgsProcessingMeshDatasetGroupsWidget::changed, this, [ = ]
272  {
273  emit widgetValueHasChanged( this );
274  } );
275 
276  return mWidget;
277 }
278 
279 void QgsProcessingMeshDatasetGroupsWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
280 {
281  Q_UNUSED( context );
282  if ( mWidget )
283  mWidget->setValue( value );
284 }
285 
286 QVariant QgsProcessingMeshDatasetGroupsWidgetWrapper::widgetValue() const
287 {
288  if ( mWidget )
289  return mWidget->value();
290  return QVariant();
291 }
292 
293 
294 void QgsProcessingMeshDatasetGroupsWidget::updateSummaryText()
295 {
296  mLineEdit->setText( tr( "%1 options selected" ).arg( mValue.count() ) );
297 }
298 
299 QgsProcessingMeshDatasetTimeWidgetWrapper::QgsProcessingMeshDatasetTimeWidgetWrapper( const QgsProcessingParameterDefinition *parameter,
301  QWidget *parent )
302  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
303 {
304 
305 }
306 
307 QString QgsProcessingMeshDatasetTimeWidgetWrapper::parameterType() const
308 {
310 }
311 
312 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingMeshDatasetTimeWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
313 {
314  return new QgsProcessingMeshDatasetTimeWidgetWrapper( parameter, type );
315 }
316 
317 void QgsProcessingMeshDatasetTimeWidgetWrapper::postInitialize( const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
318 {
320  switch ( type() )
321  {
324  {
325  const QgsAbstractProcessingParameterWidgetWrapper *layerParameterWrapper = nullptr;
326  const QgsAbstractProcessingParameterWidgetWrapper *datasetGroupsParameterWrapper = nullptr;
327  for ( const QgsAbstractProcessingParameterWidgetWrapper *wrapper : wrappers )
328  {
329  if ( wrapper->parameterDefinition()->name() == static_cast< const QgsProcessingParameterMeshDatasetTime * >( parameterDefinition() )->meshLayerParameterName() )
330  layerParameterWrapper = wrapper;
331 
332  if ( wrapper->parameterDefinition()->name() == static_cast< const QgsProcessingParameterMeshDatasetTime * >( parameterDefinition() )->datasetGroupParameterName() )
333  datasetGroupsParameterWrapper = wrapper;
334  }
335  setMeshLayerWrapperValue( layerParameterWrapper );
336  setDatasetGroupIndexesWrapperValue( datasetGroupsParameterWrapper );
337  connect( datasetGroupsParameterWrapper, &QgsAbstractProcessingParameterWidgetWrapper::widgetValueHasChanged, this, [ = ]
338  {
339  setMeshLayerWrapperValue( layerParameterWrapper );
340  setDatasetGroupIndexesWrapperValue( datasetGroupsParameterWrapper );
341  } );
342 
343  break;
344  }
345 
347  break;
348  }
349 }
350 
351 void QgsProcessingMeshDatasetTimeWidgetWrapper::setMeshLayerWrapperValue( const QgsAbstractProcessingParameterWidgetWrapper *wrapper )
352 {
353  if ( !mWidget )
354  return;
355 
356  // evaluate value to layer
357  QgsProcessingContext *context = nullptr;
358  if ( mProcessingContextGenerator )
359  context = mProcessingContextGenerator->processingContext();
360 
361  bool layerFromProject;
362  QgsMeshLayer *meshLayer;
363  if ( !context )
364  {
365  QgsProcessingContext dummyContext;
366  meshLayer = QgsProcessingParameters::parameterAsMeshLayer( wrapper->parameterDefinition(), wrapper->parameterValue(), dummyContext );
367  layerFromProject = false;
368  }
369  else
370  {
371  meshLayer = QgsProcessingParameters::parameterAsMeshLayer( wrapper->parameterDefinition(), wrapper->parameterValue(), *context );
372  layerFromProject = context->project() && context->project()->layerStore()->layers<QgsMeshLayer *>().contains( meshLayer );
373  }
374 
375  mWidget->setMeshLayer( meshLayer, layerFromProject );
376 }
377 
378 void QgsProcessingMeshDatasetTimeWidgetWrapper::setDatasetGroupIndexesWrapperValue( const QgsAbstractProcessingParameterWidgetWrapper *wrapper )
379 {
380  if ( !mWidget )
381  return;
382 
383  QVariant datasetGroupsVariant = wrapper->parameterValue();
384 
385  if ( !datasetGroupsVariant.isValid() || datasetGroupsVariant.type() != QVariant::List )
386  mWidget->setDatasetGroupIndexes( QList<int>() );
387 
388  QVariantList datasetGroupsListVariant = datasetGroupsVariant.toList();
389 
390  QList<int> datasetGroupsIndexes;
391  for ( const QVariant &variantIndex : datasetGroupsListVariant )
392  datasetGroupsIndexes << variantIndex.toInt();
393 
394  mWidget->setDatasetGroupIndexes( datasetGroupsIndexes );
395 
396 }
397 
398 QWidget *QgsProcessingMeshDatasetTimeWidgetWrapper::createWidget()
399 {
400  mWidget = new QgsProcessingMeshDatasetTimeWidget( nullptr, static_cast<const QgsProcessingParameterMeshDatasetTime *>( parameterDefinition() ), widgetContext() );
401 
402  QgsMapCanvas *canvas = widgetContext().mapCanvas();
403  if ( canvas )
404  {
405  connect( canvas, &QgsMapCanvas::temporalRangeChanged, mWidget, &QgsProcessingMeshDatasetTimeWidget::updateValue );
406  }
407  connect( mWidget, &QgsProcessingMeshDatasetTimeWidget::changed, this, [ = ]
408  {
409  emit widgetValueHasChanged( this );
410  } );
411 
412  return mWidget;
413 }
414 
415 void QgsProcessingMeshDatasetTimeWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
416 {
417  Q_UNUSED( context );
418  if ( mWidget )
419  mWidget->setValue( value );
420 }
421 
422 QVariant QgsProcessingMeshDatasetTimeWidgetWrapper::widgetValue() const
423 {
424  if ( mWidget )
425  return mWidget->value();
426  return QVariant();
427 }
428 
429 QgsProcessingMeshDatasetTimeWidget::QgsProcessingMeshDatasetTimeWidget( QWidget *parent,
431  const QgsProcessingParameterWidgetContext &context ):
432  QWidget( parent ),
433  mParam( param )
434 {
435  setupUi( this );
436 
437  dateTimeEdit->setDisplayFormat( "yyyy-MM-dd HH:mm:ss" );
438 
439  mCanvas = context.mapCanvas();
440 
441  connect( radioButtonCurrentCanvasTime, &QRadioButton::toggled, [this]( bool isChecked ) {if ( isChecked ) this->updateValue();} );
442  connect( radioButtonDefinedDateTime, &QRadioButton::toggled, [this]( bool isChecked ) {if ( isChecked ) this->updateValue();} );
443  connect( radioButtonDatasetGroupTimeStep, &QRadioButton::toggled, [this]( bool isChecked ) {if ( isChecked ) this->updateValue();} );
444  connect( dateTimeEdit, &QgsDateTimeEdit::dateTimeChanged, this, &QgsProcessingMeshDatasetTimeWidget::updateValue );
445  connect( comboBoxDatasetTimeStep, qgis::overload<int>::of( &QComboBox::currentIndexChanged ),
446  this, &QgsProcessingMeshDatasetTimeWidget::updateValue );
447 
448  updateWidget();
449 }
450 
451 void QgsProcessingMeshDatasetTimeWidget::setMeshLayer( QgsMeshLayer *layer, bool layerFromProject )
452 {
453  if ( mMeshLayer == layer )
454  return;
455 
456  if ( layerFromProject )
457  {
458  mMeshLayer = layer;
459  mReferenceTime = static_cast<QgsMeshLayerTemporalProperties *>( layer->temporalProperties() )->referenceTime();
460  }
461  else
462  {
463  mMeshLayer = nullptr;
464  mReferenceTime = layer->dataProvider()->temporalCapabilities()->referenceTime();
465  storeTimeStepsFromLayer( layer );
466  }
467 
468  if ( mReferenceTime.isValid() )
469  whileBlocking( dateTimeEdit )->setDateTime( mReferenceTime );
470 
471  updateValue();
472 }
473 
474 void QgsProcessingMeshDatasetTimeWidget::setDatasetGroupIndexes( const QList<int> datasetGroupIndexes )
475 {
476  if ( datasetGroupIndexes == mDatasetGroupIndexes )
477  return;
478  mDatasetGroupIndexes = datasetGroupIndexes;
479  populateTimeSteps();
480  updateValue();
481 }
482 
483 void QgsProcessingMeshDatasetTimeWidget::setValue( const QVariant &value )
484 {
485  if ( !value.isValid() || value.type() != QVariant::Map )
486  return;
487 
488  mValue = value.toMap();
489 
490  if ( !mValue.contains( QStringLiteral( "type" ) ) || !mValue.contains( QStringLiteral( "value" ) ) )
491  return;
492 
493  QString type = mValue.value( QStringLiteral( "type" ) ).toString();
494 
495  setEnabled( true );
496  if ( type == QLatin1String( "static" ) )
497  {
498  setEnabled( false );
499  }
500  else if ( type == QLatin1String( "dataset-time-step" ) )
501  {
502  whileBlocking( radioButtonDatasetGroupTimeStep )->setChecked( true );
503  whileBlocking( comboBoxDatasetTimeStep )->setCurrentIndex( comboBoxDatasetTimeStep->findData( mValue.value( QStringLiteral( "value" ) ) ) );
504  }
505  else if ( type == QLatin1String( "dataset-time-step" ) )
506  {
507  radioButtonDefinedDateTime->setChecked( true );
508  whileBlocking( dateTimeEdit )->setDate( mValue.value( QStringLiteral( "value" ) ).toDate() );
509  }
510  else if ( type == QLatin1String( "current-context-time" ) )
511  {
512  whileBlocking( radioButtonCurrentCanvasTime )->setChecked( true );
513  }
514 
515  emit changed();
516  updateWidget();
517 }
518 
519 QVariant QgsProcessingMeshDatasetTimeWidget::value() const
520 {
521  return mValue;
522 }
523 
524 void QgsProcessingMeshDatasetTimeWidget::updateWidget()
525 {
526  bool isStatic = !hasTemporalDataset();
527  setEnabled( !isStatic );
528 
529  if ( mCanvas != nullptr && mCanvas->mapSettings().isTemporal() )
530  {
531  whileBlocking( radioButtonCurrentCanvasTime )->setEnabled( true && mReferenceTime.isValid() );
532  labelCurrentCanvasTime->setText( mCanvas->mapSettings().temporalRange().begin().toString( "yyyy-MM-dd HH:mm:ss" ) );
533  }
534  else
535  {
536  whileBlocking( radioButtonCurrentCanvasTime )->setEnabled( false );
537  if ( radioButtonCurrentCanvasTime->isChecked() )
538  whileBlocking( radioButtonDefinedDateTime )->setChecked( true );
539  }
540 
541  if ( ! mReferenceTime.isValid() )
542  whileBlocking( radioButtonDatasetGroupTimeStep )->setChecked( true );
543 
544  whileBlocking( radioButtonDefinedDateTime )->setEnabled( mReferenceTime.isValid() );
545 
546  dateTimeEdit->setVisible( radioButtonDefinedDateTime->isChecked() && !isStatic );
547  labelCurrentCanvasTime->setVisible( radioButtonCurrentCanvasTime->isChecked() && !isStatic );
548  comboBoxDatasetTimeStep->setVisible( radioButtonDatasetGroupTimeStep->isChecked() && !isStatic );
549 }
550 
551 bool QgsProcessingMeshDatasetTimeWidget::hasTemporalDataset() const
552 {
553  for ( int index : mDatasetGroupIndexes )
554  {
555  if ( mMeshLayer && mMeshLayer->datasetGroupMetadata( index ).isTemporal() )
556  return true;
557  else if ( mDatasetTimeSteps.contains( index ) )
558  return true;
559  }
560 
561  return false;
562 }
563 
564 
565 void QgsProcessingMeshDatasetTimeWidget::populateTimeSteps()
566 {
567  if ( mMeshLayer )
568  {
569  populateTimeStepsFromLayer();
570  return;
571  }
572 
573  QMap<quint64, QgsMeshDatasetIndex> timeStep;
574  for ( int groupIndex : mDatasetGroupIndexes )
575  {
576  if ( !mDatasetTimeSteps.contains( groupIndex ) )
577  continue;
578  const QList<qint64> relativeTimeSteps = mDatasetTimeSteps.value( groupIndex );
579  for ( int index = 0; index < relativeTimeSteps.count(); ++index )
580  {
581  QgsMeshDatasetIndex datasetIndex( groupIndex, index );
582  if ( timeStep.contains( relativeTimeSteps.at( index ) ) )
583  continue;
584  timeStep[relativeTimeSteps.at( index )] = datasetIndex;
585  }
586  }
587 
588  for ( qint64 key : timeStep.keys() )
589  {
590  QString stringTime = QgsMeshLayerUtils::formatTime( key / 1000 / 3600, mReferenceTime, QgsMeshTimeSettings() );
591  QVariantList data;
592  const QgsMeshDatasetIndex &index = timeStep.value( key );
593  data << index.group() << index.dataset();
594  whileBlocking( comboBoxDatasetTimeStep )->addItem( stringTime, data );
595  }
596 
597 }
598 
599 void QgsProcessingMeshDatasetTimeWidget::populateTimeStepsFromLayer()
600 {
601  whileBlocking( comboBoxDatasetTimeStep )->clear();
602 
603  if ( !mMeshLayer )
604  return;
605 
606  QMap<quint64, QgsMeshDatasetIndex> timeStep;
607  for ( int groupIndex : mDatasetGroupIndexes )
608  {
609  QgsMeshDatasetGroupMetadata meta = mMeshLayer->datasetGroupMetadata( groupIndex );
610  if ( !meta.isTemporal() )
611  continue;
612  int datasetCount = mMeshLayer->datasetCount( groupIndex );
613 
614  for ( int index = 0; index < datasetCount; ++index )
615  {
616  QgsMeshDatasetIndex datasetIndex( groupIndex, index );
617  qint64 relativeTime = mMeshLayer->datasetRelativeTimeInMilliseconds( datasetIndex );
618  if ( timeStep.contains( relativeTime ) )
619  continue;
620  timeStep[relativeTime] = datasetIndex;
621  }
622  }
623 
624  for ( qint64 key : timeStep.keys() )
625  {
626  QString stringTime = mMeshLayer->formatTime( key / 1000.0 / 3600.0 );
627  QVariantList data;
628  const QgsMeshDatasetIndex &index = timeStep.value( key );
629  data << index.group() << index.dataset();
630  whileBlocking( comboBoxDatasetTimeStep )->addItem( stringTime, data );
631  }
632 }
633 
634 void QgsProcessingMeshDatasetTimeWidget::storeTimeStepsFromLayer( QgsMeshLayer *layer )
635 {
636  mDatasetTimeSteps.clear();
637  if ( !layer )
638  return;
639  QList<int> datasetGroupsList = layer->datasetGroupsIndexes();
640  for ( int groupIndex : datasetGroupsList )
641  {
642  QgsMeshDatasetGroupMetadata meta = layer->datasetGroupMetadata( groupIndex );
643  if ( !meta.isTemporal() )
644  continue;
645  int datasetCount = layer->datasetCount( groupIndex );
646  QList<qint64> relativeTimeSteps;
647  relativeTimeSteps.reserve( datasetCount );
648  for ( int index = 0; index < datasetCount; ++index )
649  relativeTimeSteps.append( layer->datasetRelativeTimeInMilliseconds( QgsMeshDatasetIndex( groupIndex, index ) ) );
650  mDatasetTimeSteps[groupIndex] = relativeTimeSteps;
651  }
652 }
653 
654 void QgsProcessingMeshDatasetTimeWidget::buildValue()
655 {
656  mValue.clear();
657 
658  if ( !isEnabled() )
659  {
660  mValue[QStringLiteral( "type" )] = QStringLiteral( "static" );
661  }
662  else if ( radioButtonDatasetGroupTimeStep->isChecked() )
663  {
664  mValue[QStringLiteral( "type" )] = QStringLiteral( "dataset-time-step" );
665  mValue[QStringLiteral( "value" )] = comboBoxDatasetTimeStep->currentData();
666  }
667  else if ( radioButtonDefinedDateTime->isChecked() )
668  {
669  mValue[QStringLiteral( "type" )] = QStringLiteral( "defined-date-time" );
670  mValue[QStringLiteral( "value" )] = dateTimeEdit->dateTime();
671  }
672  else if ( radioButtonCurrentCanvasTime->isChecked() && mCanvas )
673  {
674  mValue[QStringLiteral( "type" )] = QStringLiteral( "current-context-time" );
675  }
676 
677  emit changed();
678 }
679 
680 void QgsProcessingMeshDatasetTimeWidget::updateValue()
681 {
682  updateWidget();
683  buildValue();
684 }
685 
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.
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.
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 QgsMeshLayer * parameterAsMeshLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition and value to a mesh layer.
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:263
#define SIP_FACTORY
Definition: qgis_sip.h:76