35#include "moc_qgsprocessingmeshdatasetwidget.cpp"
40 : QWidget( parent ), mParam( param )
42 QHBoxLayout *hl =
new QHBoxLayout();
43 hl->setContentsMargins( 0, 0, 0, 0 );
45 mLineEdit =
new QLineEdit();
46 mLineEdit->setEnabled(
false );
47 hl->addWidget( mLineEdit, 1 );
49 mToolButton =
new QToolButton();
50 mToolButton->setText( QString( QChar( 0x2026 ) ) );
51 hl->addWidget( mToolButton );
55 mLineEdit->setText( tr(
"%1 dataset groups selected" ).arg( 0 ) );
57 mToolButton->setPopupMode( QToolButton::InstantPopup );
58 QMenu *toolButtonMenu =
new QMenu(
this );
59 mActionCurrentActiveDatasetGroups = toolButtonMenu->addAction( tr(
"Current Active Dataset Group" ) );
60 connect( mActionCurrentActiveDatasetGroups, &QAction::triggered,
this, &QgsProcessingMeshDatasetGroupsWidget::selectCurrentActiveDatasetGroup );
62 mActionAvailableDatasetGroups = toolButtonMenu->addAction( tr(
"Select in Available Dataset Groups" ) );
63 connect( mActionAvailableDatasetGroups, &QAction::triggered,
this, &QgsProcessingMeshDatasetGroupsWidget::showDialog );
65 mToolButton->setMenu( toolButtonMenu );
68void QgsProcessingMeshDatasetGroupsWidget::setMeshLayer(
QgsMeshLayer *layer,
bool layerFromProject )
70 mActionCurrentActiveDatasetGroups->setEnabled( layer && layerFromProject );
71 mActionAvailableDatasetGroups->setEnabled( layer );
73 if ( mMeshLayer == layer )
76 mDatasetGroupsNames.clear();
78 if ( layerFromProject )
86 for (
int i : datasetGroupsIndexes )
89 if ( mParam->isDataTypeSupported( meta.
dataType() ) )
91 mDatasetGroupsNames[i] = meta.
name();
101void QgsProcessingMeshDatasetGroupsWidget::setValue(
const QVariant &value )
103 if ( value.isValid() )
104 mValue = value.userType() == QMetaType::Type::QVariantList ? value.toList() : QVariantList() << value;
112QVariant QgsProcessingMeshDatasetGroupsWidget::value()
const
117void QgsProcessingMeshDatasetGroupsWidget::showDialog()
119 QList<int> datasetGroupsIndexes;
121 QVariantList availableOptions;
124 datasetGroupsIndexes = mMeshLayer->datasetGroupsIndexes();
125 for (
int i : std::as_const( datasetGroupsIndexes ) )
128 if ( mParam->isDataTypeSupported( meta.
dataType() ) )
130 availableOptions.append( i );
131 options.append( meta.
name() );
137 for (
auto it = mDatasetGroupsNames.constBegin(); it != mDatasetGroupsNames.constEnd(); it++ )
139 availableOptions.append( it.key() );
140 options.append( it.value() );
147 QgsProcessingMultipleSelectionPanelWidget *widget =
new QgsProcessingMultipleSelectionPanelWidget( availableOptions, mValue );
148 widget->setPanelTitle( tr(
"Dataset Groups Available" ) );
150 widget->setValueFormatter( [availableOptions, options](
const QVariant &v ) -> QString {
151 const int index = v.toInt();
152 const int pos = availableOptions.indexOf( index );
153 return ( pos >= 0 && pos < options.size() ) ? options.at( pos ) : QString();
156 connect( widget, &QgsProcessingMultipleSelectionPanelWidget::selectionChanged,
this, [
this, widget]() {
157 setValue( widget->selectedOptions() );
164 QgsProcessingMultipleSelectionDialog dlg( availableOptions, mValue,
this, Qt::WindowFlags() );
166 dlg.setValueFormatter( [datasetGroupsIndexes, options](
const QVariant &v ) -> QString {
167 const int index = v.toInt();
168 const int pos = datasetGroupsIndexes.indexOf( index );
169 return ( pos >= 0 && pos < options.size() ) ? options.at( pos ) : QString();
173 setValue( dlg.selectedOptions() );
178void QgsProcessingMeshDatasetGroupsWidget::selectCurrentActiveDatasetGroup()
180 QVariantList options;
181 if ( mMeshLayer && mParam )
183 int scalarDatasetGroup = mMeshLayer->rendererSettings().activeScalarDatasetGroup();
184 int vectorDatasetGroup = mMeshLayer->rendererSettings().activeVectorDatasetGroup();
186 if ( scalarDatasetGroup >= 0 && mParam->isDataTypeSupported( mMeshLayer->datasetGroupMetadata( scalarDatasetGroup ).dataType() ) )
187 options.append( scalarDatasetGroup );
189 if ( vectorDatasetGroup >= 0
190 && mParam->isDataTypeSupported( mMeshLayer->datasetGroupMetadata( vectorDatasetGroup ).dataType() )
191 && vectorDatasetGroup != scalarDatasetGroup )
192 options.append( vectorDatasetGroup );
202QString QgsProcessingMeshDatasetGroupsWidgetWrapper::parameterType()
const
209 return new QgsProcessingMeshDatasetGroupsWidgetWrapper( parameter, type );
214 return new QgsProcessingMeshDatasetGroupsParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
217void QgsProcessingMeshDatasetGroupsWidgetWrapper::postInitialize(
const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
229 setMeshLayerWrapperValue( wrapper );
231 setMeshLayerWrapperValue( wrapper );
250 if ( mProcessingContextGenerator )
251 context = mProcessingContextGenerator->processingContext();
253 bool layerFromProject;
259 layerFromProject =
false;
268 mWidget->setMeshLayer( meshLayer, layerFromProject );
271QWidget *QgsProcessingMeshDatasetGroupsWidgetWrapper::createWidget()
SIP_FACTORY
274 connect( mWidget, &QgsProcessingMeshDatasetGroupsWidget::changed,
this, [
this] {
275 emit widgetValueHasChanged(
this );
281void QgsProcessingMeshDatasetGroupsWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
286 QList<int> datasetGroupIndexes;
287 if ( value.userType() == QMetaType::Type::QVariantList )
295 QVariantList varList;
296 for (
const int index : std::as_const( datasetGroupIndexes ) )
297 varList.append( index );
299 mWidget->setValue( varList );
302QVariant QgsProcessingMeshDatasetGroupsWidgetWrapper::widgetValue()
const
305 return mWidget->value();
310void QgsProcessingMeshDatasetGroupsWidget::updateSummaryText()
312 mLineEdit->setText( tr(
"%n option(s) selected",
nullptr, mValue.count() ) );
320QString QgsProcessingMeshDatasetTimeWidgetWrapper::parameterType()
const
327 return new QgsProcessingMeshDatasetTimeWidgetWrapper( parameter, type );
330void QgsProcessingMeshDatasetTimeWidgetWrapper::postInitialize(
const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
343 layerParameterWrapper = wrapper;
346 datasetGroupsParameterWrapper = wrapper;
348 setMeshLayerWrapperValue( layerParameterWrapper );
349 setDatasetGroupIndexesWrapperValue( datasetGroupsParameterWrapper );
351 setMeshLayerWrapperValue( layerParameterWrapper );
352 setDatasetGroupIndexesWrapperValue( datasetGroupsParameterWrapper );
365 return new QgsProcessingMeshDatasetTimeParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
370 if ( !mWidget || !wrapper )
375 if ( mProcessingContextGenerator )
376 context = mProcessingContextGenerator->processingContext();
378 bool layerFromProject;
384 layerFromProject =
false;
392 mWidget->setMeshLayer( meshLayer, layerFromProject );
397 if ( !mWidget || !wrapper )
402 if ( !datasetGroupsVariant.isValid() || datasetGroupsVariant.userType() != QMetaType::Type::QVariantList )
403 mWidget->setDatasetGroupIndexes( QList<int>() );
405 QVariantList datasetGroupsListVariant = datasetGroupsVariant.toList();
407 QList<int> datasetGroupsIndexes;
408 for (
const QVariant &variantIndex : datasetGroupsListVariant )
409 datasetGroupsIndexes << variantIndex.toInt();
411 mWidget->setDatasetGroupIndexes( datasetGroupsIndexes );
414QWidget *QgsProcessingMeshDatasetTimeWidgetWrapper::createWidget()
423 connect( mWidget, &QgsProcessingMeshDatasetTimeWidget::changed,
this, [
this] {
424 emit widgetValueHasChanged(
this );
430void QgsProcessingMeshDatasetTimeWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
434 mWidget->setValue( value );
437QVariant QgsProcessingMeshDatasetTimeWidgetWrapper::widgetValue()
const
440 return mWidget->value();
445 : QWidget( parent ), mParam( param )
449 mValue.insert( QStringLiteral(
"type" ), QStringLiteral(
"static" ) );
451 dateTimeEdit->setDisplayFormat(
"yyyy-MM-dd HH:mm:ss" );
455 connect( radioButtonCurrentCanvasTime, &QRadioButton::toggled,
this, [
this](
bool isChecked ) {
if ( isChecked ) this->updateValue(); } );
456 connect( radioButtonDefinedDateTime, &QRadioButton::toggled,
this, [
this](
bool isChecked ) {
if ( isChecked ) this->updateValue(); } );
457 connect( radioButtonDatasetGroupTimeStep, &QRadioButton::toggled,
this, [
this](
bool isChecked ) {
if ( isChecked ) this->updateValue(); } );
458 connect( dateTimeEdit, &QgsDateTimeEdit::dateTimeChanged,
this, &QgsProcessingMeshDatasetTimeWidget::updateValue );
459 connect( comboBoxDatasetTimeStep, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsProcessingMeshDatasetTimeWidget::updateValue );
464void QgsProcessingMeshDatasetTimeWidget::setMeshLayer(
QgsMeshLayer *layer,
bool layerFromProject )
466 if ( mMeshLayer == layer )
469 mReferenceTime = QDateTime();
471 if ( layerFromProject )
478 mMeshLayer =
nullptr;
481 storeTimeStepsFromLayer( layer );
484 if ( mReferenceTime.isValid() )
485 whileBlocking( dateTimeEdit )->setDateTime( mReferenceTime );
490void QgsProcessingMeshDatasetTimeWidget::setDatasetGroupIndexes(
const QList<int> datasetGroupIndexes )
492 if ( datasetGroupIndexes == mDatasetGroupIndexes )
494 mDatasetGroupIndexes = datasetGroupIndexes;
499void QgsProcessingMeshDatasetTimeWidget::setValue(
const QVariant &value )
501 if ( !value.isValid() || ( value.userType() != QMetaType::Type::QVariantMap && !value.toDateTime().isValid() ) )
505 if ( value.toDateTime().isValid() )
507 QDateTime dateTime = value.toDateTime();
508 dateTime.setTimeSpec( Qt::UTC );
509 mValue.insert( QStringLiteral(
"type" ), QStringLiteral(
"defined-date-time" ) );
510 mValue.insert( QStringLiteral(
"value" ), dateTime );
513 mValue = value.toMap();
515 if ( !mValue.contains( QStringLiteral(
"type" ) ) || !mValue.contains( QStringLiteral(
"value" ) ) )
518 QString type = mValue.value( QStringLiteral(
"type" ) ).toString();
521 if ( type == QLatin1String(
"static" ) )
525 else if ( type == QLatin1String(
"dataset-time-step" ) )
527 QVariantList dataset = mValue.value( QStringLiteral(
"value" ) ).toList();
528 whileBlocking( comboBoxDatasetTimeStep )->setCurrentIndex( comboBoxDatasetTimeStep->findData( dataset ) );
529 whileBlocking( radioButtonDatasetGroupTimeStep )->setChecked(
true );
531 else if ( type == QLatin1String(
"defined-date-time" ) )
533 whileBlocking( dateTimeEdit )->setDateTime( mValue.value( QStringLiteral(
"value" ) ).toDateTime() );
534 whileBlocking( radioButtonDefinedDateTime )->setChecked(
true );
536 else if ( type == QLatin1String(
"current-context-time" ) )
538 whileBlocking( radioButtonCurrentCanvasTime )->setChecked(
true );
545QVariant QgsProcessingMeshDatasetTimeWidget::value()
const
550void QgsProcessingMeshDatasetTimeWidget::updateWidget()
552 bool isStatic = !hasTemporalDataset();
553 setEnabled( !isStatic );
555 if ( mCanvas && mCanvas->mapSettings().isTemporal() )
557 whileBlocking( radioButtonCurrentCanvasTime )->setEnabled(
true && mReferenceTime.isValid() );
558 labelCurrentCanvasTime->setText( mCanvas->mapSettings().temporalRange().begin().toString(
"yyyy-MM-dd HH:mm:ss" ) );
562 whileBlocking( radioButtonCurrentCanvasTime )->setEnabled(
false );
563 if ( radioButtonCurrentCanvasTime->isChecked() )
564 whileBlocking( radioButtonDefinedDateTime )->setChecked(
true );
567 if ( !mReferenceTime.isValid() )
568 whileBlocking( radioButtonDatasetGroupTimeStep )->setChecked(
true );
570 whileBlocking( radioButtonDefinedDateTime )->setEnabled( mReferenceTime.isValid() );
572 dateTimeEdit->setVisible( radioButtonDefinedDateTime->isChecked() && !isStatic );
573 labelCurrentCanvasTime->setVisible( radioButtonCurrentCanvasTime->isChecked() && !isStatic );
574 comboBoxDatasetTimeStep->setVisible( radioButtonDatasetGroupTimeStep->isChecked() && !isStatic );
577bool QgsProcessingMeshDatasetTimeWidget::hasTemporalDataset()
const
579 for (
int index : mDatasetGroupIndexes )
581 if ( mMeshLayer && mMeshLayer->datasetGroupMetadata( index ).isTemporal() )
583 else if ( mDatasetTimeSteps.contains( index ) )
591void QgsProcessingMeshDatasetTimeWidget::populateTimeSteps()
595 populateTimeStepsFromLayer();
599 QMap<quint64, QgsMeshDatasetIndex> timeStep;
600 for (
int groupIndex : mDatasetGroupIndexes )
602 if ( !mDatasetTimeSteps.contains( groupIndex ) )
604 const QList<qint64> relativeTimeSteps = mDatasetTimeSteps.value( groupIndex );
605 for (
int index = 0; index < relativeTimeSteps.count(); ++index )
608 if ( timeStep.contains( relativeTimeSteps.at( index ) ) )
610 timeStep[relativeTimeSteps.at( index )] = datasetIndex;
614 for (
auto it = timeStep.constBegin(); it != timeStep.constEnd(); it++ )
616 QString stringTime = QgsMeshLayerUtils::formatTime(
static_cast<double>( it.key() ) / 1000. / 3600., mReferenceTime,
QgsMeshTimeSettings() );
620 whileBlocking( comboBoxDatasetTimeStep )->addItem( stringTime, data );
624void QgsProcessingMeshDatasetTimeWidget::populateTimeStepsFromLayer()
631 QMap<quint64, QgsMeshDatasetIndex> timeStep;
632 for (
int groupIndex : std::as_const( mDatasetGroupIndexes ) )
637 int datasetCount = mMeshLayer->datasetCount( groupIndex );
639 for (
int index = 0; index < datasetCount; ++index )
642 qint64 relativeTime = mMeshLayer->datasetRelativeTimeInMilliseconds( datasetIndex );
643 if ( timeStep.contains( relativeTime ) )
645 timeStep[relativeTime] = datasetIndex;
649 for (
auto it = timeStep.constBegin(); it != timeStep.constEnd(); it++ )
651 QString stringTime = mMeshLayer->formatTime(
static_cast<double>( it.key() ) / 1000.0 / 3600.0 );
655 whileBlocking( comboBoxDatasetTimeStep )->addItem( stringTime, data );
659void QgsProcessingMeshDatasetTimeWidget::storeTimeStepsFromLayer(
QgsMeshLayer *layer )
661 mDatasetTimeSteps.clear();
665 for (
int groupIndex : datasetGroupsList )
671 QList<qint64> relativeTimeSteps;
672 relativeTimeSteps.reserve( datasetCount );
673 for (
int index = 0; index < datasetCount; ++index )
675 mDatasetTimeSteps[groupIndex] = relativeTimeSteps;
679void QgsProcessingMeshDatasetTimeWidget::buildValue()
685 mValue[QStringLiteral(
"type" )] = QStringLiteral(
"static" );
687 else if ( radioButtonDatasetGroupTimeStep->isChecked() )
689 mValue[QStringLiteral(
"type" )] = QStringLiteral(
"dataset-time-step" );
690 mValue[QStringLiteral(
"value" )] = comboBoxDatasetTimeStep->currentData();
692 else if ( radioButtonDefinedDateTime->isChecked() )
694 mValue[QStringLiteral(
"type" )] = QStringLiteral(
"defined-date-time" );
695 mValue[QStringLiteral(
"value" )] = dateTimeEdit->dateTime();
697 else if ( radioButtonCurrentCanvasTime->isChecked() && mCanvas )
699 mValue[QStringLiteral(
"type" )] = QStringLiteral(
"current-context-time" );
705void QgsProcessingMeshDatasetTimeWidget::updateValue()
712QgsProcessingMeshDatasetGroupsParameterDefinitionWidget::QgsProcessingMeshDatasetGroupsParameterDefinitionWidget(
721 QVBoxLayout *vlayout =
new QVBoxLayout();
722 vlayout->setContentsMargins( 0, 0, 0, 0 );
724 vlayout->addWidget(
new QLabel( tr(
"Linked input" ) ) );
726 mParentLayerComboBox =
new QComboBox();
727 vlayout->addWidget( mParentLayerComboBox );
729 if ( QgsProcessingModelAlgorithm *model = widgetContext.
model() )
731 const QMap<QString, QgsProcessingModelParameter> components = model->parameterComponents();
732 for (
auto it = components.constBegin(); it != components.constEnd(); ++it )
743 if ( datasetGroupDef )
746 if ( currentIndex != -1 )
747 mParentLayerComboBox->setCurrentIndex( currentIndex );
752 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
756 setLayout( vlayout );
761 const QString &description,
765 QSet<int> supportedDataType;
770 auto param = std::make_unique<QgsProcessingParameterMeshDatasetGroups>( name, description, mParentLayerComboBox->currentData().toString(), supportedDataType );
772 return param.release();
775QgsProcessingMeshDatasetTimeParameterDefinitionWidget::QgsProcessingMeshDatasetTimeParameterDefinitionWidget(
790 QVBoxLayout *vlayout =
new QVBoxLayout();
791 vlayout->setContentsMargins( 0, 0, 0, 0 );
793 vlayout->addWidget(
new QLabel( tr(
"Linked input" ) ) );
795 mParentDatasetComboBox =
new QComboBox();
796 vlayout->addWidget( mParentDatasetComboBox );
798 QgsProcessingModelAlgorithm *model = widgetContext.
model();
801 const QMap<QString, QgsProcessingModelParameter> components = model->parameterComponents();
802 for (
auto it = components.constBegin(); it != components.constEnd(); ++it )
814 if ( currentIndex != -1 )
815 mParentDatasetComboBox->setCurrentIndex( currentIndex );
820 mParentDatasetComboBox->setCurrentIndex( mParentDatasetComboBox->count() - 1 );
830 connect( mParentDatasetComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, [
this, model] {
837 setLayout( vlayout );
842 auto param = std::make_unique<QgsProcessingParameterMeshDatasetTime>(
843 name, description, mMeshLayerParameterName, mParentDatasetComboBox->currentData().toString()
847 return param.release();
ProcessingMode
Types of modes which Processing widgets can be created for.
@ Batch
Batch processing mode.
@ Standard
Standard (single-run) algorithm mode.
QFlags< ProcessingParameterFlag > ProcessingParameterFlags
Flags which dictate the behavior of Processing parameters.
Map canvas is a class for displaying all GIS data types on a canvas.
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.
An 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.
QDateTime referenceTime() const
Returns the reference time.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
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.
Abstract base class for processing algorithms.
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.
Base class for the definition of processing parameters.
void setFlags(Qgis::ProcessingParameterFlags flags)
Sets the flags associated with the parameter.
QString description() const
Returns the description for the parameter.
virtual QString type() const =0
Unique parameter type name.
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.
QString meshLayerParameterName() const
Returns the name of the mesh layer parameter.
A parameter for processing algorithms that need a list of mesh dataset index from time parameter.
QString datasetGroupParameterName() const
Returns the name of the dataset groups parameter.
QString meshLayerParameterName() const
Returns the name of the mesh layer parameter.
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.
QgsProcessingModelAlgorithm * model() const
Returns the model which the parameter widget is associated with.
static QList< int > parameterAsInts(const QgsProcessingParameterDefinition *definition, const QVariantMap ¶meters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a list of integer values.
static QgsMeshLayer * parameterAsMeshLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap ¶meters, QgsProcessingContext &context)
Evaluates the parameter with matching definition and value to a mesh layer.
static int parameterAsInt(const QgsProcessingParameterDefinition *definition, const QVariantMap ¶meters, 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.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into allowing algorithms to be written in pure substantial changes are required in order to port existing x Processing algorithms for QGIS x The most significant changes are outlined not GeoAlgorithm For algorithms which operate on features one by consider subclassing the QgsProcessingFeatureBasedAlgorithm class This class allows much of the boilerplate code for looping over features from a vector layer to be bypassed and instead requires implementation of a processFeature method Ensure that your algorithm(or algorithm 's parent class) implements the new pure virtual createInstance(self) call
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.