29 #include <QToolButton> 
   30 #include <QVBoxLayout> 
   38   QHBoxLayout *hl = 
new QHBoxLayout();
 
   39   hl->setContentsMargins( 0, 0, 0, 0 );
 
   41   mLineEdit = 
new QLineEdit();
 
   42   mLineEdit->setEnabled( 
false );
 
   43   hl->addWidget( mLineEdit, 1 );
 
   45   mToolButton = 
new QToolButton();
 
   46   mToolButton->setText( QString( QChar( 0x2026 ) ) );
 
   47   hl->addWidget( mToolButton );
 
   51   mLineEdit->setText( tr( 
"%1 dataset groups selected" ).arg( 0 ) );
 
   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 );
 
   59   mActionAvailableDatasetGroups = toolButtonMenu->addAction( tr( 
"Select in Available Dataset Groups" ) );
 
   60   connect( mActionAvailableDatasetGroups, &QAction::triggered, 
this, &QgsProcessingMeshDatasetGroupsWidget::showDialog );
 
   62   mToolButton->setMenu( toolButtonMenu );
 
   65 void QgsProcessingMeshDatasetGroupsWidget::setMeshLayer( 
QgsMeshLayer *layer, 
bool layerFromProject )
 
   67   mActionCurrentActiveDatasetGroups->setEnabled( layer && layerFromProject );
 
   68   mActionAvailableDatasetGroups->setEnabled( layer );
 
   70   if ( mMeshLayer == layer )
 
   73   mDatasetGroupsNames.clear();
 
   75   if ( layerFromProject )
 
   83       for ( 
int i : datasetGroupsIndexes )
 
   86         if ( mParam->isDataTypeSupported( meta.
dataType() ) )
 
   88           mDatasetGroupsNames[i] = meta.
name();
 
   98 void QgsProcessingMeshDatasetGroupsWidget::setValue( 
const QVariant &value )
 
  100   if ( value.isValid() )
 
  101     mValue = value.type() == QVariant::List ? value.toList() : QVariantList() << value;
 
  109 QVariant QgsProcessingMeshDatasetGroupsWidget::value()
 const 
  114 void QgsProcessingMeshDatasetGroupsWidget::showDialog()
 
  116   QList<int> datasetGroupsIndexes;
 
  118   QVariantList availableOptions;
 
  121     datasetGroupsIndexes = mMeshLayer->datasetGroupsIndexes();
 
  122     for ( 
int i : std::as_const( datasetGroupsIndexes ) )
 
  125       if ( mParam->isDataTypeSupported( meta.
dataType() ) )
 
  127         availableOptions.append( i );
 
  128         options.append( meta.
name() );
 
  135     for ( 
int i : mDatasetGroupsNames.keys() )
 
  137       availableOptions.append( i );
 
  138       options.append( mDatasetGroupsNames.value( i ) );
 
  145     QgsProcessingMultipleSelectionPanelWidget *widget = 
new QgsProcessingMultipleSelectionPanelWidget( availableOptions, mValue );
 
  146     widget->setPanelTitle( tr( 
"Dataset Groups Available" ) );
 
  148     widget->setValueFormatter( [availableOptions, options]( 
const QVariant & v ) -> QString
 
  150       const int index = v.toInt();
 
  151       const int pos = availableOptions.indexOf( index );
 
  152       return ( pos >= 0 && pos < options.size() ) ? options.at( pos ) : QString();
 
  155     connect( widget, &QgsProcessingMultipleSelectionPanelWidget::selectionChanged, 
this, [ = ]()
 
  157       setValue( widget->selectedOptions() );
 
  164     QgsProcessingMultipleSelectionDialog dlg( availableOptions, mValue, 
this, Qt::WindowFlags() );
 
  166     dlg.setValueFormatter( [datasetGroupsIndexes, options]( 
const QVariant & v ) -> QString
 
  168       const int index = v.toInt();
 
  169       const int pos = datasetGroupsIndexes.indexOf( index );
 
  170       return ( pos >= 0 && pos < options.size() ) ? options.at( pos ) : QString();
 
  174       setValue( dlg.selectedOptions() );
 
  179 void QgsProcessingMeshDatasetGroupsWidget::selectCurrentActiveDatasetGroup()
 
  181   QVariantList options;
 
  182   if ( mMeshLayer && mParam )
 
  184     int scalarDatasetGroup = mMeshLayer->rendererSettings().activeScalarDatasetGroup();
 
  185     int vectorDatasetGroup = mMeshLayer->rendererSettings().activeVectorDatasetGroup();
 
  187     if ( scalarDatasetGroup >= 0 && mParam->isDataTypeSupported( mMeshLayer->datasetGroupMetadata( scalarDatasetGroup ).dataType() ) )
 
  188       options.append( scalarDatasetGroup );
 
  190     if ( vectorDatasetGroup >= 0
 
  191          && mParam->isDataTypeSupported( mMeshLayer->datasetGroupMetadata( vectorDatasetGroup ).dataType() )
 
  192          && vectorDatasetGroup != scalarDatasetGroup )
 
  193       options.append( vectorDatasetGroup );
 
  203 QString QgsProcessingMeshDatasetGroupsWidgetWrapper::parameterType()
 const 
  210   return new QgsProcessingMeshDatasetGroupsWidgetWrapper( parameter, type );
 
  213 void QgsProcessingMeshDatasetGroupsWidgetWrapper::postInitialize( 
const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
 
  225           setMeshLayerWrapperValue( wrapper );
 
  228             setMeshLayerWrapperValue( wrapper );
 
  248   if ( mProcessingContextGenerator )
 
  249     context = mProcessingContextGenerator->processingContext();
 
  251   bool layerFromProject;
 
  257     layerFromProject = 
false;
 
  266     mWidget->setMeshLayer( meshLayer, layerFromProject );
 
  269 QStringList QgsProcessingMeshDatasetGroupsWidgetWrapper::compatibleParameterTypes()
 const 
  276 QStringList QgsProcessingMeshDatasetGroupsWidgetWrapper::compatibleOutputTypes()
 const 
  282 QWidget *QgsProcessingMeshDatasetGroupsWidgetWrapper::createWidget() 
SIP_FACTORY 
  285   connect( mWidget, &QgsProcessingMeshDatasetGroupsWidget::changed, 
this, [ = ]
 
  287     emit widgetValueHasChanged( 
this );
 
  293 void QgsProcessingMeshDatasetGroupsWidgetWrapper::setWidgetValue( 
const QVariant &value, 
QgsProcessingContext &context )
 
  298   QList<int> datasetGroupIndexes;
 
  299   if ( value.type() == QVariant::List )
 
  307   QVariantList varList;
 
  308   for ( 
const int index : std::as_const( datasetGroupIndexes ) )
 
  309     varList.append( index );
 
  311   mWidget->setValue( varList );
 
  314 QVariant QgsProcessingMeshDatasetGroupsWidgetWrapper::widgetValue()
 const 
  317     return mWidget->value();
 
  322 void QgsProcessingMeshDatasetGroupsWidget::updateSummaryText()
 
  324   mLineEdit->setText( tr( 
"%1 options selected" ).arg( mValue.count() ) );
 
  335 QString QgsProcessingMeshDatasetTimeWidgetWrapper::parameterType()
 const 
  342   return new QgsProcessingMeshDatasetTimeWidgetWrapper( parameter, type );
 
  345 void QgsProcessingMeshDatasetTimeWidgetWrapper::postInitialize( 
const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
 
  358           layerParameterWrapper = wrapper;
 
  361           datasetGroupsParameterWrapper = wrapper;
 
  363       setMeshLayerWrapperValue( layerParameterWrapper );
 
  364       setDatasetGroupIndexesWrapperValue( datasetGroupsParameterWrapper );
 
  367         setMeshLayerWrapperValue( layerParameterWrapper );
 
  368         setDatasetGroupIndexesWrapperValue( datasetGroupsParameterWrapper );
 
  381   if ( !mWidget || !wrapper )
 
  386   if ( mProcessingContextGenerator )
 
  387     context = mProcessingContextGenerator->processingContext();
 
  389   bool layerFromProject;
 
  395     layerFromProject = 
false;
 
  403   mWidget->setMeshLayer( meshLayer, layerFromProject );
 
  408   if ( !mWidget || !wrapper )
 
  413   if ( !datasetGroupsVariant.isValid() || datasetGroupsVariant.type() != QVariant::List )
 
  414     mWidget->setDatasetGroupIndexes( QList<int>() );
 
  416   QVariantList datasetGroupsListVariant = datasetGroupsVariant.toList();
 
  418   QList<int> datasetGroupsIndexes;
 
  419   for ( 
const QVariant &variantIndex : datasetGroupsListVariant )
 
  420     datasetGroupsIndexes << variantIndex.toInt();
 
  422   mWidget->setDatasetGroupIndexes( datasetGroupsIndexes );
 
  426 QStringList QgsProcessingMeshDatasetTimeWidgetWrapper::compatibleParameterTypes()
 const 
  434 QStringList QgsProcessingMeshDatasetTimeWidgetWrapper::compatibleOutputTypes()
 const 
  440 QWidget *QgsProcessingMeshDatasetTimeWidgetWrapper::createWidget()
 
  449   connect( mWidget, &QgsProcessingMeshDatasetTimeWidget::changed, 
this, [ = ]
 
  451     emit widgetValueHasChanged( 
this );
 
  457 void QgsProcessingMeshDatasetTimeWidgetWrapper::setWidgetValue( 
const QVariant &value, 
QgsProcessingContext &context )
 
  461     mWidget->setValue( value );
 
  464 QVariant QgsProcessingMeshDatasetTimeWidgetWrapper::widgetValue()
 const 
  467     return mWidget->value();
 
  471 QgsProcessingMeshDatasetTimeWidget::QgsProcessingMeshDatasetTimeWidget( QWidget *parent,
 
  479   mValue.insert( QStringLiteral( 
"type" ), QStringLiteral( 
"static" ) );
 
  481   dateTimeEdit->setDisplayFormat( 
"yyyy-MM-dd HH:mm:ss" );
 
  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 );
 
  495 void QgsProcessingMeshDatasetTimeWidget::setMeshLayer( 
QgsMeshLayer *layer, 
bool layerFromProject )
 
  497   if ( mMeshLayer == layer )
 
  500   mReferenceTime = QDateTime();
 
  502   if ( layerFromProject )
 
  509     mMeshLayer = 
nullptr;
 
  512     storeTimeStepsFromLayer( layer );
 
  515   if ( mReferenceTime.isValid() )
 
  516     whileBlocking( dateTimeEdit )->setDateTime( mReferenceTime );
 
  521 void QgsProcessingMeshDatasetTimeWidget::setDatasetGroupIndexes( 
const QList<int> datasetGroupIndexes )
 
  523   if ( datasetGroupIndexes == mDatasetGroupIndexes )
 
  525   mDatasetGroupIndexes = datasetGroupIndexes;
 
  530 void QgsProcessingMeshDatasetTimeWidget::setValue( 
const QVariant &value )
 
  532   if ( !value.isValid() || ( value.type() != QVariant::Map && !value.toDateTime().isValid() ) )
 
  536   if ( value.toDateTime().isValid() )
 
  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 );
 
  544     mValue = value.toMap();
 
  546   if ( !mValue.contains( QStringLiteral( 
"type" ) ) || !mValue.contains( QStringLiteral( 
"value" ) ) )
 
  549   QString type = mValue.value( QStringLiteral( 
"type" ) ).toString();
 
  552   if ( type == QLatin1String( 
"static" ) )
 
  556   else if ( type == QLatin1String( 
"dataset-time-step" ) )
 
  558     QVariantList dataset = mValue.value( QStringLiteral( 
"value" ) ).toList();
 
  559     whileBlocking( comboBoxDatasetTimeStep )->setCurrentIndex( comboBoxDatasetTimeStep->findData( dataset ) );
 
  560     whileBlocking( radioButtonDatasetGroupTimeStep )->setChecked( 
true );
 
  562   else if ( type == QLatin1String( 
"defined-date-time" ) )
 
  564     whileBlocking( dateTimeEdit )->setDateTime( mValue.value( QStringLiteral( 
"value" ) ).toDateTime() );
 
  565     whileBlocking( radioButtonDefinedDateTime )->setChecked( 
true );
 
  567   else if ( type == QLatin1String( 
"current-context-time" ) )
 
  569     whileBlocking( radioButtonCurrentCanvasTime )->setChecked( 
true );
 
  576 QVariant QgsProcessingMeshDatasetTimeWidget::value()
 const 
  581 void QgsProcessingMeshDatasetTimeWidget::updateWidget()
 
  583   bool isStatic = !hasTemporalDataset();
 
  584   setEnabled( !isStatic );
 
  586   if ( mCanvas != 
nullptr  && mCanvas->mapSettings().isTemporal() )
 
  588     whileBlocking( radioButtonCurrentCanvasTime )->setEnabled( 
true && mReferenceTime.isValid() );
 
  589     labelCurrentCanvasTime->setText( mCanvas->mapSettings().temporalRange().begin().toString( 
"yyyy-MM-dd HH:mm:ss" ) );
 
  593     whileBlocking( radioButtonCurrentCanvasTime )->setEnabled( 
false );
 
  594     if ( radioButtonCurrentCanvasTime->isChecked() )
 
  595       whileBlocking( radioButtonDefinedDateTime )->setChecked( 
true );
 
  598   if ( ! mReferenceTime.isValid() )
 
  599     whileBlocking( radioButtonDatasetGroupTimeStep )->setChecked( 
true );
 
  601   whileBlocking( radioButtonDefinedDateTime )->setEnabled( mReferenceTime.isValid() );
 
  603   dateTimeEdit->setVisible( radioButtonDefinedDateTime->isChecked() && !isStatic );
 
  604   labelCurrentCanvasTime->setVisible( radioButtonCurrentCanvasTime->isChecked() && !isStatic );
 
  605   comboBoxDatasetTimeStep->setVisible( radioButtonDatasetGroupTimeStep->isChecked() && !isStatic );
 
  608 bool QgsProcessingMeshDatasetTimeWidget::hasTemporalDataset()
 const 
  610   for ( 
int index : mDatasetGroupIndexes )
 
  612     if ( mMeshLayer && mMeshLayer->datasetGroupMetadata( index ).isTemporal() )
 
  614     else if ( mDatasetTimeSteps.contains( index ) )
 
  622 void QgsProcessingMeshDatasetTimeWidget::populateTimeSteps()
 
  626     populateTimeStepsFromLayer();
 
  630   QMap<quint64, QgsMeshDatasetIndex> timeStep;
 
  631   for ( 
int groupIndex : mDatasetGroupIndexes )
 
  633     if ( !mDatasetTimeSteps.contains( groupIndex ) )
 
  635     const QList<qint64> relativeTimeSteps = mDatasetTimeSteps.value( groupIndex );
 
  636     for ( 
int index = 0; index < relativeTimeSteps.count(); ++index )
 
  639       if ( timeStep.contains( relativeTimeSteps.at( index ) ) )
 
  641       timeStep[relativeTimeSteps.at( index )] = datasetIndex;
 
  645   for ( qint64 key : timeStep.keys() )
 
  647     QString stringTime = QgsMeshLayerUtils::formatTime( key / 1000 / 3600, mReferenceTime, 
QgsMeshTimeSettings() );
 
  651     whileBlocking( comboBoxDatasetTimeStep )->addItem( stringTime, data );
 
  656 void QgsProcessingMeshDatasetTimeWidget::populateTimeStepsFromLayer()
 
  663   QMap<quint64, QgsMeshDatasetIndex> timeStep;
 
  664   for ( 
int groupIndex : std::as_const( mDatasetGroupIndexes ) )
 
  669     int datasetCount = mMeshLayer->datasetCount( groupIndex );
 
  671     for ( 
int index = 0; index < datasetCount; ++index )
 
  674       qint64 relativeTime = mMeshLayer->datasetRelativeTimeInMilliseconds( datasetIndex );
 
  675       if ( timeStep.contains( relativeTime ) )
 
  677       timeStep[relativeTime] = datasetIndex;
 
  681   for ( qint64 key : timeStep.keys() )
 
  683     QString stringTime = mMeshLayer->formatTime( key / 1000.0 / 3600.0 );
 
  687     whileBlocking( comboBoxDatasetTimeStep )->addItem( stringTime, data );
 
  691 void QgsProcessingMeshDatasetTimeWidget::storeTimeStepsFromLayer( 
QgsMeshLayer *layer )
 
  693   mDatasetTimeSteps.clear();
 
  697   for ( 
int groupIndex : datasetGroupsList )
 
  703     QList<qint64> relativeTimeSteps;
 
  704     relativeTimeSteps.reserve( datasetCount );
 
  705     for ( 
int index = 0; index < datasetCount; ++index )
 
  707     mDatasetTimeSteps[groupIndex] = relativeTimeSteps;
 
  711 void QgsProcessingMeshDatasetTimeWidget::buildValue()
 
  717     mValue[QStringLiteral( 
"type" )] = QStringLiteral( 
"static" );
 
  719   else if ( radioButtonDatasetGroupTimeStep->isChecked() )
 
  721     mValue[QStringLiteral( 
"type" )] = QStringLiteral( 
"dataset-time-step" );
 
  722     mValue[QStringLiteral( 
"value" )] = comboBoxDatasetTimeStep->currentData();
 
  724   else if ( radioButtonDefinedDateTime->isChecked() )
 
  726     mValue[QStringLiteral( 
"type" )] = QStringLiteral( 
"defined-date-time" );
 
  727     mValue[QStringLiteral( 
"value" )] = dateTimeEdit->dateTime();
 
  729   else if ( radioButtonCurrentCanvasTime->isChecked() && mCanvas )
 
  731     mValue[QStringLiteral( 
"type" )] = QStringLiteral( 
"current-context-time" );
 
  737 void QgsProcessingMeshDatasetTimeWidget::updateValue()
 
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.
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.
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.
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.
@ 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 ¶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.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.