31 #include <QToolButton>
32 #include <QVBoxLayout>
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,
59 &QAction::triggered,
this, &QgsProcessingMeshDatasetGroupsWidget::selectCurrentActiveDatasetGroup );
61 mActionAvailableDatasetGroups = toolButtonMenu->addAction( tr(
"Select in Available Dataset Groups" ) );
62 connect( mActionAvailableDatasetGroups, &QAction::triggered,
this, &QgsProcessingMeshDatasetGroupsWidget::showDialog );
64 mToolButton->setMenu( toolButtonMenu );
67 void QgsProcessingMeshDatasetGroupsWidget::setMeshLayer(
QgsMeshLayer *layer,
bool layerFromProject )
69 mActionCurrentActiveDatasetGroups->setEnabled( layer && layerFromProject );
70 mActionAvailableDatasetGroups->setEnabled( layer );
72 if ( mMeshLayer == layer )
75 mDatasetGroupsNames.clear();
77 if ( layerFromProject )
85 for (
int i : datasetGroupsIndexes )
88 if ( mParam->isDataTypeSupported( meta.
dataType() ) )
90 mDatasetGroupsNames[i] = meta.
name();
100 void QgsProcessingMeshDatasetGroupsWidget::setValue(
const QVariant &value )
102 if ( value.isValid() )
103 mValue = value.type() == QVariant::List ? value.toList() : QVariantList() << value;
111 QVariant QgsProcessingMeshDatasetGroupsWidget::value()
const
116 void QgsProcessingMeshDatasetGroupsWidget::showDialog()
118 QList<int> datasetGroupsIndexes;
120 QVariantList availableOptions;
123 datasetGroupsIndexes = mMeshLayer->datasetGroupsIndexes();
124 for (
int i : std::as_const( datasetGroupsIndexes ) )
127 if ( mParam->isDataTypeSupported( meta.
dataType() ) )
129 availableOptions.append( i );
130 options.append( meta.
name() );
136 for (
int i : mDatasetGroupsNames.keys() )
138 availableOptions.append( i );
139 options.append( mDatasetGroupsNames.value( i ) );
146 QgsProcessingMultipleSelectionPanelWidget *widget =
new QgsProcessingMultipleSelectionPanelWidget( availableOptions, mValue );
147 widget->setPanelTitle( tr(
"Dataset Groups Available" ) );
149 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, [ = ]()
158 setValue( widget->selectedOptions() );
165 QgsProcessingMultipleSelectionDialog dlg( availableOptions, mValue,
this, Qt::WindowFlags() );
167 dlg.setValueFormatter( [datasetGroupsIndexes, options](
const QVariant & v ) -> QString
169 const int index = v.toInt();
170 const int pos = datasetGroupsIndexes.indexOf( index );
171 return ( pos >= 0 && pos < options.size() ) ? options.at( pos ) : QString();
175 setValue( dlg.selectedOptions() );
180 void QgsProcessingMeshDatasetGroupsWidget::selectCurrentActiveDatasetGroup()
182 QVariantList options;
183 if ( mMeshLayer && mParam )
185 int scalarDatasetGroup = mMeshLayer->rendererSettings().activeScalarDatasetGroup();
186 int vectorDatasetGroup = mMeshLayer->rendererSettings().activeVectorDatasetGroup();
188 if ( scalarDatasetGroup >= 0 && mParam->isDataTypeSupported( mMeshLayer->datasetGroupMetadata( scalarDatasetGroup ).dataType() ) )
189 options.append( scalarDatasetGroup );
191 if ( vectorDatasetGroup >= 0
192 && mParam->isDataTypeSupported( mMeshLayer->datasetGroupMetadata( vectorDatasetGroup ).dataType() )
193 && vectorDatasetGroup != scalarDatasetGroup )
194 options.append( vectorDatasetGroup );
204 QString QgsProcessingMeshDatasetGroupsWidgetWrapper::parameterType()
const
211 return new QgsProcessingMeshDatasetGroupsWidgetWrapper( parameter, type );
216 return new QgsProcessingMeshDatasetGroupsParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
219 void QgsProcessingMeshDatasetGroupsWidgetWrapper::postInitialize(
const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
231 setMeshLayerWrapperValue( wrapper );
234 setMeshLayerWrapperValue( wrapper );
253 if ( mProcessingContextGenerator )
254 context = mProcessingContextGenerator->processingContext();
256 bool layerFromProject;
262 layerFromProject =
false;
271 mWidget->setMeshLayer( meshLayer, layerFromProject );
274 QStringList QgsProcessingMeshDatasetGroupsWidgetWrapper::compatibleParameterTypes()
const
281 QStringList QgsProcessingMeshDatasetGroupsWidgetWrapper::compatibleOutputTypes()
const
287 QWidget *QgsProcessingMeshDatasetGroupsWidgetWrapper::createWidget()
SIP_FACTORY
290 connect( mWidget, &QgsProcessingMeshDatasetGroupsWidget::changed,
this, [ = ]
292 emit widgetValueHasChanged(
this );
298 void QgsProcessingMeshDatasetGroupsWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
303 QList<int> datasetGroupIndexes;
304 if ( value.type() == QVariant::List )
312 QVariantList varList;
313 for (
const int index : std::as_const( datasetGroupIndexes ) )
314 varList.append( index );
316 mWidget->setValue( varList );
319 QVariant QgsProcessingMeshDatasetGroupsWidgetWrapper::widgetValue()
const
322 return mWidget->value();
327 void QgsProcessingMeshDatasetGroupsWidget::updateSummaryText()
329 mLineEdit->setText( tr(
"%n option(s) selected",
nullptr, mValue.count() ) );
340 QString QgsProcessingMeshDatasetTimeWidgetWrapper::parameterType()
const
347 return new QgsProcessingMeshDatasetTimeWidgetWrapper( parameter, type );
350 void QgsProcessingMeshDatasetTimeWidgetWrapper::postInitialize(
const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
363 layerParameterWrapper = wrapper;
366 datasetGroupsParameterWrapper = wrapper;
368 setMeshLayerWrapperValue( layerParameterWrapper );
369 setDatasetGroupIndexesWrapperValue( datasetGroupsParameterWrapper );
372 setMeshLayerWrapperValue( layerParameterWrapper );
373 setDatasetGroupIndexesWrapperValue( datasetGroupsParameterWrapper );
386 return new QgsProcessingMeshDatasetTimeParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
391 if ( !mWidget || !wrapper )
396 if ( mProcessingContextGenerator )
397 context = mProcessingContextGenerator->processingContext();
399 bool layerFromProject;
405 layerFromProject =
false;
413 mWidget->setMeshLayer( meshLayer, layerFromProject );
418 if ( !mWidget || !wrapper )
423 if ( !datasetGroupsVariant.isValid() || datasetGroupsVariant.type() != QVariant::List )
424 mWidget->setDatasetGroupIndexes( QList<int>() );
426 QVariantList datasetGroupsListVariant = datasetGroupsVariant.toList();
428 QList<int> datasetGroupsIndexes;
429 for (
const QVariant &variantIndex : datasetGroupsListVariant )
430 datasetGroupsIndexes << variantIndex.toInt();
432 mWidget->setDatasetGroupIndexes( datasetGroupsIndexes );
436 QStringList QgsProcessingMeshDatasetTimeWidgetWrapper::compatibleParameterTypes()
const
444 QStringList QgsProcessingMeshDatasetTimeWidgetWrapper::compatibleOutputTypes()
const
450 QWidget *QgsProcessingMeshDatasetTimeWidgetWrapper::createWidget()
459 connect( mWidget, &QgsProcessingMeshDatasetTimeWidget::changed,
this, [ = ]
461 emit widgetValueHasChanged(
this );
467 void QgsProcessingMeshDatasetTimeWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
471 mWidget->setValue( value );
474 QVariant QgsProcessingMeshDatasetTimeWidgetWrapper::widgetValue()
const
477 return mWidget->value();
481 QgsProcessingMeshDatasetTimeWidget::QgsProcessingMeshDatasetTimeWidget( QWidget *parent,
489 mValue.insert( QStringLiteral(
"type" ), QStringLiteral(
"static" ) );
491 dateTimeEdit->setDisplayFormat(
"yyyy-MM-dd HH:mm:ss" );
495 connect( radioButtonCurrentCanvasTime, &QRadioButton::toggled,
this, [
this](
bool isChecked ) {
if ( isChecked ) this->updateValue();} );
496 connect( radioButtonDefinedDateTime, &QRadioButton::toggled,
this, [
this](
bool isChecked ) {
if ( isChecked ) this->updateValue();} );
497 connect( radioButtonDatasetGroupTimeStep, &QRadioButton::toggled,
this, [
this](
bool isChecked ) {
if ( isChecked ) this->updateValue();} );
498 connect( dateTimeEdit, &QgsDateTimeEdit::dateTimeChanged,
this, &QgsProcessingMeshDatasetTimeWidget::updateValue );
499 connect( comboBoxDatasetTimeStep, qOverload<int>( &QComboBox::currentIndexChanged ),
500 this, &QgsProcessingMeshDatasetTimeWidget::updateValue );
505 void QgsProcessingMeshDatasetTimeWidget::setMeshLayer(
QgsMeshLayer *layer,
bool layerFromProject )
507 if ( mMeshLayer == layer )
510 mReferenceTime = QDateTime();
512 if ( layerFromProject )
519 mMeshLayer =
nullptr;
522 storeTimeStepsFromLayer( layer );
525 if ( mReferenceTime.isValid() )
526 whileBlocking( dateTimeEdit )->setDateTime( mReferenceTime );
531 void QgsProcessingMeshDatasetTimeWidget::setDatasetGroupIndexes(
const QList<int> datasetGroupIndexes )
533 if ( datasetGroupIndexes == mDatasetGroupIndexes )
535 mDatasetGroupIndexes = datasetGroupIndexes;
540 void QgsProcessingMeshDatasetTimeWidget::setValue(
const QVariant &value )
542 if ( !value.isValid() || ( value.type() != QVariant::Map && !value.toDateTime().isValid() ) )
546 if ( value.toDateTime().isValid() )
548 QDateTime dateTime = value.toDateTime();
549 dateTime.setTimeSpec( Qt::UTC );
550 mValue.insert( QStringLiteral(
"type" ), QStringLiteral(
"defined-date-time" ) );
551 mValue.insert( QStringLiteral(
"value" ), dateTime );
554 mValue = value.toMap();
556 if ( !mValue.contains( QStringLiteral(
"type" ) ) || !mValue.contains( QStringLiteral(
"value" ) ) )
559 QString type = mValue.value( QStringLiteral(
"type" ) ).toString();
562 if ( type == QLatin1String(
"static" ) )
566 else if ( type == QLatin1String(
"dataset-time-step" ) )
568 QVariantList dataset = mValue.value( QStringLiteral(
"value" ) ).toList();
569 whileBlocking( comboBoxDatasetTimeStep )->setCurrentIndex( comboBoxDatasetTimeStep->findData( dataset ) );
570 whileBlocking( radioButtonDatasetGroupTimeStep )->setChecked(
true );
572 else if ( type == QLatin1String(
"defined-date-time" ) )
574 whileBlocking( dateTimeEdit )->setDateTime( mValue.value( QStringLiteral(
"value" ) ).toDateTime() );
575 whileBlocking( radioButtonDefinedDateTime )->setChecked(
true );
577 else if ( type == QLatin1String(
"current-context-time" ) )
579 whileBlocking( radioButtonCurrentCanvasTime )->setChecked(
true );
586 QVariant QgsProcessingMeshDatasetTimeWidget::value()
const
591 void QgsProcessingMeshDatasetTimeWidget::updateWidget()
593 bool isStatic = !hasTemporalDataset();
594 setEnabled( !isStatic );
596 if ( mCanvas !=
nullptr && mCanvas->mapSettings().isTemporal() )
598 whileBlocking( radioButtonCurrentCanvasTime )->setEnabled(
true && mReferenceTime.isValid() );
599 labelCurrentCanvasTime->setText( mCanvas->mapSettings().temporalRange().begin().toString(
"yyyy-MM-dd HH:mm:ss" ) );
603 whileBlocking( radioButtonCurrentCanvasTime )->setEnabled(
false );
604 if ( radioButtonCurrentCanvasTime->isChecked() )
605 whileBlocking( radioButtonDefinedDateTime )->setChecked(
true );
608 if ( ! mReferenceTime.isValid() )
609 whileBlocking( radioButtonDatasetGroupTimeStep )->setChecked(
true );
611 whileBlocking( radioButtonDefinedDateTime )->setEnabled( mReferenceTime.isValid() );
613 dateTimeEdit->setVisible( radioButtonDefinedDateTime->isChecked() && !isStatic );
614 labelCurrentCanvasTime->setVisible( radioButtonCurrentCanvasTime->isChecked() && !isStatic );
615 comboBoxDatasetTimeStep->setVisible( radioButtonDatasetGroupTimeStep->isChecked() && !isStatic );
618 bool QgsProcessingMeshDatasetTimeWidget::hasTemporalDataset()
const
620 for (
int index : mDatasetGroupIndexes )
622 if ( mMeshLayer && mMeshLayer->datasetGroupMetadata( index ).isTemporal() )
624 else if ( mDatasetTimeSteps.contains( index ) )
632 void QgsProcessingMeshDatasetTimeWidget::populateTimeSteps()
636 populateTimeStepsFromLayer();
640 QMap<quint64, QgsMeshDatasetIndex> timeStep;
641 for (
int groupIndex : mDatasetGroupIndexes )
643 if ( !mDatasetTimeSteps.contains( groupIndex ) )
645 const QList<qint64> relativeTimeSteps = mDatasetTimeSteps.value( groupIndex );
646 for (
int index = 0; index < relativeTimeSteps.count(); ++index )
649 if ( timeStep.contains( relativeTimeSteps.at( index ) ) )
651 timeStep[relativeTimeSteps.at( index )] = datasetIndex;
655 for ( qint64 key : timeStep.keys() )
657 QString stringTime = QgsMeshLayerUtils::formatTime( key / 1000 / 3600, mReferenceTime,
QgsMeshTimeSettings() );
661 whileBlocking( comboBoxDatasetTimeStep )->addItem( stringTime, data );
666 void QgsProcessingMeshDatasetTimeWidget::populateTimeStepsFromLayer()
673 QMap<quint64, QgsMeshDatasetIndex> timeStep;
674 for (
int groupIndex : std::as_const( mDatasetGroupIndexes ) )
679 int datasetCount = mMeshLayer->datasetCount( groupIndex );
681 for (
int index = 0; index < datasetCount; ++index )
684 qint64 relativeTime = mMeshLayer->datasetRelativeTimeInMilliseconds( datasetIndex );
685 if ( timeStep.contains( relativeTime ) )
687 timeStep[relativeTime] = datasetIndex;
691 for ( qint64 key : timeStep.keys() )
693 QString stringTime = mMeshLayer->formatTime( key / 1000.0 / 3600.0 );
697 whileBlocking( comboBoxDatasetTimeStep )->addItem( stringTime, data );
701 void QgsProcessingMeshDatasetTimeWidget::storeTimeStepsFromLayer(
QgsMeshLayer *layer )
703 mDatasetTimeSteps.clear();
707 for (
int groupIndex : datasetGroupsList )
713 QList<qint64> relativeTimeSteps;
714 relativeTimeSteps.reserve( datasetCount );
715 for (
int index = 0; index < datasetCount; ++index )
717 mDatasetTimeSteps[groupIndex] = relativeTimeSteps;
721 void QgsProcessingMeshDatasetTimeWidget::buildValue()
727 mValue[QStringLiteral(
"type" )] = QStringLiteral(
"static" );
729 else if ( radioButtonDatasetGroupTimeStep->isChecked() )
731 mValue[QStringLiteral(
"type" )] = QStringLiteral(
"dataset-time-step" );
732 mValue[QStringLiteral(
"value" )] = comboBoxDatasetTimeStep->currentData();
734 else if ( radioButtonDefinedDateTime->isChecked() )
736 mValue[QStringLiteral(
"type" )] = QStringLiteral(
"defined-date-time" );
737 mValue[QStringLiteral(
"value" )] = dateTimeEdit->dateTime();
739 else if ( radioButtonCurrentCanvasTime->isChecked() && mCanvas )
741 mValue[QStringLiteral(
"type" )] = QStringLiteral(
"current-context-time" );
747 void QgsProcessingMeshDatasetTimeWidget::updateValue()
754 QgsProcessingMeshDatasetGroupsParameterDefinitionWidget::QgsProcessingMeshDatasetGroupsParameterDefinitionWidget(
762 QVBoxLayout *vlayout =
new QVBoxLayout();
763 vlayout->setContentsMargins( 0, 0, 0, 0 );
765 vlayout->addWidget(
new QLabel( tr(
"Linked input" ) ) );
767 mParentLayerComboBox =
new QComboBox();
768 vlayout->addWidget( mParentLayerComboBox );
770 if ( QgsProcessingModelAlgorithm *model = widgetContext.
model() )
772 const QMap<QString, QgsProcessingModelParameter> components = model->parameterComponents();
773 for (
auto it = components.constBegin(); it != components.constEnd(); ++it )
786 if ( currentIndex != -1 )
787 mParentLayerComboBox->setCurrentIndex( currentIndex );
792 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
795 setLayout( vlayout );
800 const QString &description,
801 QgsProcessingParameterDefinition::Flags flags )
const
803 QSet<int> supportedDataType;
808 std::unique_ptr<QgsProcessingParameterMeshDatasetGroups> param =
809 std::make_unique<QgsProcessingParameterMeshDatasetGroups>( name, description, mParentLayerComboBox->currentData().toString(), supportedDataType );
810 param->setFlags( flags );
811 return param.release();
814 QgsProcessingMeshDatasetTimeParameterDefinitionWidget::QgsProcessingMeshDatasetTimeParameterDefinitionWidget(
829 QVBoxLayout *vlayout =
new QVBoxLayout();
830 vlayout->setContentsMargins( 0, 0, 0, 0 );
832 vlayout->addWidget(
new QLabel( tr(
"Linked input" ) ) );
834 mParentDatasetComboBox =
new QComboBox();
835 vlayout->addWidget( mParentDatasetComboBox );
837 QgsProcessingModelAlgorithm *model = widgetContext.
model();
840 const QMap<QString, QgsProcessingModelParameter> components = model->parameterComponents();
841 for (
auto it = components.constBegin(); it != components.constEnd(); ++it )
854 if ( currentIndex != -1 )
855 mParentDatasetComboBox->setCurrentIndex( currentIndex );
860 mParentDatasetComboBox->setCurrentIndex( mParentDatasetComboBox->count() - 1 );
870 connect( mParentDatasetComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, [
this, model]
878 setLayout( vlayout );
881 QgsProcessingParameterDefinition *QgsProcessingMeshDatasetTimeParameterDefinitionWidget::createParameter(
const QString &name,
const QString &description, QgsProcessingParameterDefinition::Flags flags )
const
883 std::unique_ptr<QgsProcessingParameterMeshDatasetTime> param = std::make_unique<QgsProcessingParameterMeshDatasetTime>(
884 name, description, mMeshLayerParameterName, mParentDatasetComboBox->currentData().toString() );
886 param->setFlags( flags );
887 return param.release();