17#include "moc_qgsprocessingmeshdatasetwidget.cpp"
38 : QWidget( parent ), mParam( param )
40 QHBoxLayout *hl =
new QHBoxLayout();
41 hl->setContentsMargins( 0, 0, 0, 0 );
43 mLineEdit =
new QLineEdit();
44 mLineEdit->setEnabled(
false );
45 hl->addWidget( mLineEdit, 1 );
47 mToolButton =
new QToolButton();
48 mToolButton->setText( QString( QChar( 0x2026 ) ) );
49 hl->addWidget( mToolButton );
53 mLineEdit->setText( tr(
"%1 dataset groups selected" ).arg( 0 ) );
55 mToolButton->setPopupMode( QToolButton::InstantPopup );
56 QMenu *toolButtonMenu =
new QMenu(
this );
57 mActionCurrentActiveDatasetGroups = toolButtonMenu->addAction( tr(
"Current Active Dataset Group" ) );
58 connect( mActionCurrentActiveDatasetGroups, &QAction::triggered,
this, &QgsProcessingMeshDatasetGroupsWidget::selectCurrentActiveDatasetGroup );
60 mActionAvailableDatasetGroups = toolButtonMenu->addAction( tr(
"Select in Available Dataset Groups" ) );
61 connect( mActionAvailableDatasetGroups, &QAction::triggered,
this, &QgsProcessingMeshDatasetGroupsWidget::showDialog );
63 mToolButton->setMenu( toolButtonMenu );
66void QgsProcessingMeshDatasetGroupsWidget::setMeshLayer(
QgsMeshLayer *layer,
bool layerFromProject )
68 mActionCurrentActiveDatasetGroups->setEnabled( layer && layerFromProject );
69 mActionAvailableDatasetGroups->setEnabled( layer );
71 if ( mMeshLayer == layer )
74 mDatasetGroupsNames.clear();
76 if ( layerFromProject )
84 for (
int i : datasetGroupsIndexes )
87 if ( mParam->isDataTypeSupported( meta.
dataType() ) )
89 mDatasetGroupsNames[i] = meta.
name();
99void QgsProcessingMeshDatasetGroupsWidget::setValue(
const QVariant &value )
101 if ( value.isValid() )
102 mValue = value.userType() == QMetaType::Type::QVariantList ? value.toList() : QVariantList() << value;
110QVariant QgsProcessingMeshDatasetGroupsWidget::value()
const
115void QgsProcessingMeshDatasetGroupsWidget::showDialog()
117 QList<int> datasetGroupsIndexes;
119 QVariantList availableOptions;
122 datasetGroupsIndexes = mMeshLayer->datasetGroupsIndexes();
123 for (
int i : std::as_const( datasetGroupsIndexes ) )
126 if ( mParam->isDataTypeSupported( meta.
dataType() ) )
128 availableOptions.append( i );
129 options.append( meta.
name() );
135 for (
auto it = mDatasetGroupsNames.constBegin(); it != mDatasetGroupsNames.constEnd(); it++ )
137 availableOptions.append( it.key() );
138 options.append( it.value() );
145 QgsProcessingMultipleSelectionPanelWidget *widget =
new QgsProcessingMultipleSelectionPanelWidget( availableOptions, mValue );
146 widget->setPanelTitle( tr(
"Dataset Groups Available" ) );
148 widget->setValueFormatter( [availableOptions, options](
const QVariant &v ) -> QString {
149 const int index = v.toInt();
150 const int pos = availableOptions.indexOf( index );
151 return ( pos >= 0 && pos < options.size() ) ? options.at( pos ) : QString();
154 connect( widget, &QgsProcessingMultipleSelectionPanelWidget::selectionChanged,
this, [=]() {
155 setValue( widget->selectedOptions() );
162 QgsProcessingMultipleSelectionDialog dlg( availableOptions, mValue,
this, Qt::WindowFlags() );
164 dlg.setValueFormatter( [datasetGroupsIndexes, options](
const QVariant &v ) -> QString {
165 const int index = v.toInt();
166 const int pos = datasetGroupsIndexes.indexOf( index );
167 return ( pos >= 0 && pos < options.size() ) ? options.at( pos ) : QString();
171 setValue( dlg.selectedOptions() );
176void QgsProcessingMeshDatasetGroupsWidget::selectCurrentActiveDatasetGroup()
178 QVariantList options;
179 if ( mMeshLayer && mParam )
181 int scalarDatasetGroup = mMeshLayer->rendererSettings().activeScalarDatasetGroup();
182 int vectorDatasetGroup = mMeshLayer->rendererSettings().activeVectorDatasetGroup();
184 if ( scalarDatasetGroup >= 0 && mParam->isDataTypeSupported( mMeshLayer->datasetGroupMetadata( scalarDatasetGroup ).dataType() ) )
185 options.append( scalarDatasetGroup );
187 if ( vectorDatasetGroup >= 0
188 && mParam->isDataTypeSupported( mMeshLayer->datasetGroupMetadata( vectorDatasetGroup ).dataType() )
189 && vectorDatasetGroup != scalarDatasetGroup )
190 options.append( vectorDatasetGroup );
200QString QgsProcessingMeshDatasetGroupsWidgetWrapper::parameterType()
const
207 return new QgsProcessingMeshDatasetGroupsWidgetWrapper( parameter, type );
212 return new QgsProcessingMeshDatasetGroupsParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
215void QgsProcessingMeshDatasetGroupsWidgetWrapper::postInitialize(
const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
227 setMeshLayerWrapperValue( wrapper );
229 setMeshLayerWrapperValue( wrapper );
248 if ( mProcessingContextGenerator )
249 context = mProcessingContextGenerator->processingContext();
251 bool layerFromProject;
257 layerFromProject =
false;
266 mWidget->setMeshLayer( meshLayer, layerFromProject );
269QWidget *QgsProcessingMeshDatasetGroupsWidgetWrapper::createWidget()
SIP_FACTORY
272 connect( mWidget, &QgsProcessingMeshDatasetGroupsWidget::changed,
this, [=] {
273 emit widgetValueHasChanged(
this );
279void QgsProcessingMeshDatasetGroupsWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
284 QList<int> datasetGroupIndexes;
285 if ( value.userType() == QMetaType::Type::QVariantList )
293 QVariantList varList;
294 for (
const int index : std::as_const( datasetGroupIndexes ) )
295 varList.append( index );
297 mWidget->setValue( varList );
300QVariant QgsProcessingMeshDatasetGroupsWidgetWrapper::widgetValue()
const
303 return mWidget->value();
308void QgsProcessingMeshDatasetGroupsWidget::updateSummaryText()
310 mLineEdit->setText( tr(
"%n option(s) selected",
nullptr, mValue.count() ) );
318QString QgsProcessingMeshDatasetTimeWidgetWrapper::parameterType()
const
325 return new QgsProcessingMeshDatasetTimeWidgetWrapper( parameter, type );
328void QgsProcessingMeshDatasetTimeWidgetWrapper::postInitialize(
const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
341 layerParameterWrapper = wrapper;
344 datasetGroupsParameterWrapper = wrapper;
346 setMeshLayerWrapperValue( layerParameterWrapper );
347 setDatasetGroupIndexesWrapperValue( datasetGroupsParameterWrapper );
349 setMeshLayerWrapperValue( layerParameterWrapper );
350 setDatasetGroupIndexesWrapperValue( datasetGroupsParameterWrapper );
363 return new QgsProcessingMeshDatasetTimeParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
368 if ( !mWidget || !wrapper )
373 if ( mProcessingContextGenerator )
374 context = mProcessingContextGenerator->processingContext();
376 bool layerFromProject;
382 layerFromProject =
false;
390 mWidget->setMeshLayer( meshLayer, layerFromProject );
395 if ( !mWidget || !wrapper )
400 if ( !datasetGroupsVariant.isValid() || datasetGroupsVariant.userType() != QMetaType::Type::QVariantList )
401 mWidget->setDatasetGroupIndexes( QList<int>() );
403 QVariantList datasetGroupsListVariant = datasetGroupsVariant.toList();
405 QList<int> datasetGroupsIndexes;
406 for (
const QVariant &variantIndex : datasetGroupsListVariant )
407 datasetGroupsIndexes << variantIndex.toInt();
409 mWidget->setDatasetGroupIndexes( datasetGroupsIndexes );
412QWidget *QgsProcessingMeshDatasetTimeWidgetWrapper::createWidget()
421 connect( mWidget, &QgsProcessingMeshDatasetTimeWidget::changed,
this, [=] {
422 emit widgetValueHasChanged(
this );
428void QgsProcessingMeshDatasetTimeWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
432 mWidget->setValue( value );
435QVariant QgsProcessingMeshDatasetTimeWidgetWrapper::widgetValue()
const
438 return mWidget->value();
443 : QWidget( parent ), mParam( param )
447 mValue.insert( QStringLiteral(
"type" ), QStringLiteral(
"static" ) );
449 dateTimeEdit->setDisplayFormat(
"yyyy-MM-dd HH:mm:ss" );
453 connect( radioButtonCurrentCanvasTime, &QRadioButton::toggled,
this, [
this](
bool isChecked ) {
if ( isChecked ) this->updateValue(); } );
454 connect( radioButtonDefinedDateTime, &QRadioButton::toggled,
this, [
this](
bool isChecked ) {
if ( isChecked ) this->updateValue(); } );
455 connect( radioButtonDatasetGroupTimeStep, &QRadioButton::toggled,
this, [
this](
bool isChecked ) {
if ( isChecked ) this->updateValue(); } );
456 connect( dateTimeEdit, &QgsDateTimeEdit::dateTimeChanged,
this, &QgsProcessingMeshDatasetTimeWidget::updateValue );
457 connect( comboBoxDatasetTimeStep, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsProcessingMeshDatasetTimeWidget::updateValue );
462void QgsProcessingMeshDatasetTimeWidget::setMeshLayer(
QgsMeshLayer *layer,
bool layerFromProject )
464 if ( mMeshLayer == layer )
467 mReferenceTime = QDateTime();
469 if ( layerFromProject )
476 mMeshLayer =
nullptr;
479 storeTimeStepsFromLayer( layer );
482 if ( mReferenceTime.isValid() )
483 whileBlocking( dateTimeEdit )->setDateTime( mReferenceTime );
488void QgsProcessingMeshDatasetTimeWidget::setDatasetGroupIndexes(
const QList<int> datasetGroupIndexes )
490 if ( datasetGroupIndexes == mDatasetGroupIndexes )
492 mDatasetGroupIndexes = datasetGroupIndexes;
497void QgsProcessingMeshDatasetTimeWidget::setValue(
const QVariant &value )
499 if ( !value.isValid() || ( value.userType() != QMetaType::Type::QVariantMap && !value.toDateTime().isValid() ) )
503 if ( value.toDateTime().isValid() )
505 QDateTime dateTime = value.toDateTime();
506 dateTime.setTimeSpec( Qt::UTC );
507 mValue.insert( QStringLiteral(
"type" ), QStringLiteral(
"defined-date-time" ) );
508 mValue.insert( QStringLiteral(
"value" ), dateTime );
511 mValue = value.toMap();
513 if ( !mValue.contains( QStringLiteral(
"type" ) ) || !mValue.contains( QStringLiteral(
"value" ) ) )
516 QString type = mValue.value( QStringLiteral(
"type" ) ).toString();
519 if ( type == QLatin1String(
"static" ) )
523 else if ( type == QLatin1String(
"dataset-time-step" ) )
525 QVariantList dataset = mValue.value( QStringLiteral(
"value" ) ).toList();
526 whileBlocking( comboBoxDatasetTimeStep )->setCurrentIndex( comboBoxDatasetTimeStep->findData( dataset ) );
527 whileBlocking( radioButtonDatasetGroupTimeStep )->setChecked(
true );
529 else if ( type == QLatin1String(
"defined-date-time" ) )
531 whileBlocking( dateTimeEdit )->setDateTime( mValue.value( QStringLiteral(
"value" ) ).toDateTime() );
532 whileBlocking( radioButtonDefinedDateTime )->setChecked(
true );
534 else if ( type == QLatin1String(
"current-context-time" ) )
536 whileBlocking( radioButtonCurrentCanvasTime )->setChecked(
true );
543QVariant QgsProcessingMeshDatasetTimeWidget::value()
const
548void QgsProcessingMeshDatasetTimeWidget::updateWidget()
550 bool isStatic = !hasTemporalDataset();
551 setEnabled( !isStatic );
553 if ( mCanvas && mCanvas->mapSettings().isTemporal() )
555 whileBlocking( radioButtonCurrentCanvasTime )->setEnabled(
true && mReferenceTime.isValid() );
556 labelCurrentCanvasTime->setText( mCanvas->mapSettings().temporalRange().begin().toString(
"yyyy-MM-dd HH:mm:ss" ) );
560 whileBlocking( radioButtonCurrentCanvasTime )->setEnabled(
false );
561 if ( radioButtonCurrentCanvasTime->isChecked() )
562 whileBlocking( radioButtonDefinedDateTime )->setChecked(
true );
565 if ( !mReferenceTime.isValid() )
566 whileBlocking( radioButtonDatasetGroupTimeStep )->setChecked(
true );
568 whileBlocking( radioButtonDefinedDateTime )->setEnabled( mReferenceTime.isValid() );
570 dateTimeEdit->setVisible( radioButtonDefinedDateTime->isChecked() && !isStatic );
571 labelCurrentCanvasTime->setVisible( radioButtonCurrentCanvasTime->isChecked() && !isStatic );
572 comboBoxDatasetTimeStep->setVisible( radioButtonDatasetGroupTimeStep->isChecked() && !isStatic );
575bool QgsProcessingMeshDatasetTimeWidget::hasTemporalDataset()
const
577 for (
int index : mDatasetGroupIndexes )
579 if ( mMeshLayer && mMeshLayer->datasetGroupMetadata( index ).isTemporal() )
581 else if ( mDatasetTimeSteps.contains( index ) )
589void QgsProcessingMeshDatasetTimeWidget::populateTimeSteps()
593 populateTimeStepsFromLayer();
597 QMap<quint64, QgsMeshDatasetIndex> timeStep;
598 for (
int groupIndex : mDatasetGroupIndexes )
600 if ( !mDatasetTimeSteps.contains( groupIndex ) )
602 const QList<qint64> relativeTimeSteps = mDatasetTimeSteps.value( groupIndex );
603 for (
int index = 0; index < relativeTimeSteps.count(); ++index )
606 if ( timeStep.contains( relativeTimeSteps.at( index ) ) )
608 timeStep[relativeTimeSteps.at( index )] = datasetIndex;
612 for (
auto it = timeStep.constBegin(); it != timeStep.constEnd(); it++ )
614 QString stringTime = QgsMeshLayerUtils::formatTime(
static_cast<double>( it.key() ) / 1000. / 3600., mReferenceTime,
QgsMeshTimeSettings() );
618 whileBlocking( comboBoxDatasetTimeStep )->addItem( stringTime, data );
622void QgsProcessingMeshDatasetTimeWidget::populateTimeStepsFromLayer()
629 QMap<quint64, QgsMeshDatasetIndex> timeStep;
630 for (
int groupIndex : std::as_const( mDatasetGroupIndexes ) )
635 int datasetCount = mMeshLayer->datasetCount( groupIndex );
637 for (
int index = 0; index < datasetCount; ++index )
640 qint64 relativeTime = mMeshLayer->datasetRelativeTimeInMilliseconds( datasetIndex );
641 if ( timeStep.contains( relativeTime ) )
643 timeStep[relativeTime] = datasetIndex;
647 for (
auto it = timeStep.constBegin(); it != timeStep.constEnd(); it++ )
649 QString stringTime = mMeshLayer->formatTime(
static_cast<double>( it.key() ) / 1000.0 / 3600.0 );
653 whileBlocking( comboBoxDatasetTimeStep )->addItem( stringTime, data );
657void QgsProcessingMeshDatasetTimeWidget::storeTimeStepsFromLayer(
QgsMeshLayer *layer )
659 mDatasetTimeSteps.clear();
663 for (
int groupIndex : datasetGroupsList )
669 QList<qint64> relativeTimeSteps;
670 relativeTimeSteps.reserve( datasetCount );
671 for (
int index = 0; index < datasetCount; ++index )
673 mDatasetTimeSteps[groupIndex] = relativeTimeSteps;
677void QgsProcessingMeshDatasetTimeWidget::buildValue()
683 mValue[QStringLiteral(
"type" )] = QStringLiteral(
"static" );
685 else if ( radioButtonDatasetGroupTimeStep->isChecked() )
687 mValue[QStringLiteral(
"type" )] = QStringLiteral(
"dataset-time-step" );
688 mValue[QStringLiteral(
"value" )] = comboBoxDatasetTimeStep->currentData();
690 else if ( radioButtonDefinedDateTime->isChecked() )
692 mValue[QStringLiteral(
"type" )] = QStringLiteral(
"defined-date-time" );
693 mValue[QStringLiteral(
"value" )] = dateTimeEdit->dateTime();
695 else if ( radioButtonCurrentCanvasTime->isChecked() && mCanvas )
697 mValue[QStringLiteral(
"type" )] = QStringLiteral(
"current-context-time" );
703void QgsProcessingMeshDatasetTimeWidget::updateValue()
710QgsProcessingMeshDatasetGroupsParameterDefinitionWidget::QgsProcessingMeshDatasetGroupsParameterDefinitionWidget(
719 QVBoxLayout *vlayout =
new QVBoxLayout();
720 vlayout->setContentsMargins( 0, 0, 0, 0 );
722 vlayout->addWidget(
new QLabel( tr(
"Linked input" ) ) );
724 mParentLayerComboBox =
new QComboBox();
725 vlayout->addWidget( mParentLayerComboBox );
727 if ( QgsProcessingModelAlgorithm *model = widgetContext.
model() )
729 const QMap<QString, QgsProcessingModelParameter> components = model->parameterComponents();
730 for (
auto it = components.constBegin(); it != components.constEnd(); ++it )
741 if ( datasetGroupDef )
744 if ( currentIndex != -1 )
745 mParentLayerComboBox->setCurrentIndex( currentIndex );
750 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
754 setLayout( vlayout );
759 const QString &description,
763 QSet<int> supportedDataType;
768 auto param = std::make_unique<QgsProcessingParameterMeshDatasetGroups>( name, description, mParentLayerComboBox->currentData().toString(), supportedDataType );
770 return param.release();
773QgsProcessingMeshDatasetTimeParameterDefinitionWidget::QgsProcessingMeshDatasetTimeParameterDefinitionWidget(
788 QVBoxLayout *vlayout =
new QVBoxLayout();
789 vlayout->setContentsMargins( 0, 0, 0, 0 );
791 vlayout->addWidget(
new QLabel( tr(
"Linked input" ) ) );
793 mParentDatasetComboBox =
new QComboBox();
794 vlayout->addWidget( mParentDatasetComboBox );
796 QgsProcessingModelAlgorithm *model = widgetContext.
model();
799 const QMap<QString, QgsProcessingModelParameter> components = model->parameterComponents();
800 for (
auto it = components.constBegin(); it != components.constEnd(); ++it )
812 if ( currentIndex != -1 )
813 mParentDatasetComboBox->setCurrentIndex( currentIndex );
818 mParentDatasetComboBox->setCurrentIndex( mParentDatasetComboBox->count() - 1 );
828 connect( mParentDatasetComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, [
this, model] {
835 setLayout( vlayout );
840 auto param = std::make_unique<QgsProcessingParameterMeshDatasetTime>(
841 name, description, mMeshLayerParameterName, mParentDatasetComboBox->currentData().toString()
845 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.
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.