37#include <QDesktopServices>
43#include "moc_qgsmodelchildalgorithmwidgets.cpp"
45using namespace Qt::StringLiterals;
55 , mAlgorithm( childAlgorithm ? childAlgorithm->create() : nullptr )
58 , mConfiguration( configuration )
71 return mAlgorithm.get();
74void QgsProcessingModelerParametersPanelWidget::setupUi()
76 auto mainLayout =
new QVBoxLayout();
77 mainLayout->setContentsMargins( 0, 0, 0, 0 );
79 auto verticalLayout =
new QVBoxLayout();
82 mMessageBar->setSizePolicy( QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Fixed );
83 verticalLayout->addWidget( mMessageBar );
85 auto hLayout =
new QHBoxLayout();
86 hLayout->setContentsMargins( 0, 0, 0, 0 );
87 hLayout->addWidget(
new QLabel( tr(
"Description" ) ) );
88 mDescriptionBox =
new QLineEdit();
89 mDescriptionBox->setObjectName( u
"mDescriptionBox"_s );
92 mDescriptionBox->setText( mAlgorithm->displayName() );
94 hLayout->addWidget( mDescriptionBox );
95 connect( mDescriptionBox, &QLineEdit::textChanged,
this, &QgsProcessingModelerParametersPanelWidget::emitChangedSignal );
97 verticalLayout->addLayout( hLayout );
99 auto line =
new QFrame();
100 line->setFrameShape( QFrame::Shape::HLine );
101 line->setFrameShadow( QFrame::Shadow::Sunken );
102 verticalLayout->addWidget( line );
107 if ( mAlgorithmItem )
109 mAlgorithmItem->registerProcessingContextGenerator(
this );
110 if ( !mConfiguration.isEmpty() )
111 mAlgorithmItem->setConfiguration( mConfiguration );
113 verticalLayout->addWidget( mAlgorithmItem );
119 const QList<const QgsProcessingParameterDefinition *> parameters = mAlgorithm->parameterDefinitions();
121 bool hasAdvancedParameters =
false;
122 for (
const QgsProcessingParameterDefinition *parameter : parameters )
126 hasAdvancedParameters =
true;
130 QgsCollapsibleGroupBox *advancedGroup =
nullptr;
131 QVBoxLayout *advancedGroupLayout =
nullptr;
132 if ( hasAdvancedParameters )
134 advancedGroup =
new QgsCollapsibleGroupBox( tr(
"Advanced Parameters" ) );
135 advancedGroupLayout =
new QVBoxLayout();
136 advancedGroup->setLayout( advancedGroupLayout );
137 verticalLayout->addWidget( advancedGroup );
140 for (
const QgsProcessingParameterDefinition *parameter : parameters )
153 mWrappers.insert( parameter->name(), widget );
160 advancedGroupLayout->addWidget( label );
161 advancedGroupLayout->addWidget( widget );
166 verticalLayout->insertWidget( verticalLayout->count() - 1, label );
167 verticalLayout->insertWidget( verticalLayout->count() - 1, widget );
171 const QList< const QgsProcessingParameterDefinition * > destinationsParameters = mAlgorithm->destinationParameterDefinitions();
172 for (
const QgsProcessingParameterDefinition *output : destinationsParameters )
186 mWrappers.insert( output->name(), widget );
189 verticalLayout->addWidget( label );
191 verticalLayout->addWidget( widget );
195 const QFontMetrics fm( font() );
196 auto spacer =
new QSpacerItem( 20, fm.height() );
197 verticalLayout->addItem( spacer );
199 auto dependenciesLabel =
new QLabel( tr(
"Dependencies" ) );
200 mDependenciesPanel =
new QgsModelChildDependenciesWidget(
this, mModel, mChildId );
201 verticalLayout->addWidget( dependenciesLabel );
202 verticalLayout->addWidget( mDependenciesPanel );
203 connect( mDependenciesPanel, &QgsModelChildDependenciesWidget::changed,
this, &QgsProcessingModelerParametersPanelWidget::emitChangedSignal );
204 verticalLayout->addStretch( 1 );
206 auto scrollAreaContainer =
new QVBoxLayout();
207 scrollAreaContainer->setSpacing( 2 );
208 scrollAreaContainer->setContentsMargins( 0, 0, 0, 0 );
210 auto paramPanel =
new QWidget();
211 paramPanel->setLayout( verticalLayout );
213 auto scrollArea =
new QgsScrollArea();
214 scrollArea->setWidget( paramPanel );
215 scrollArea->setWidgetResizable(
true );
216 scrollArea->setFrameStyle( QFrame::Shape::NoFrame );
218 scrollAreaContainer->addWidget( scrollArea );
220 auto scrollAreaContainerWidget =
new QWidget();
221 scrollAreaContainerWidget->setLayout( scrollAreaContainer );
222 mainLayout->addWidget( scrollAreaContainerWidget );
223 setLayout( mainLayout );
226void QgsProcessingModelerParametersPanelWidget::emitChangedSignal()
228 if ( !mBlockChangesSignal )
234 if ( mChildId.isEmpty() || !mModel->childAlgorithms().contains( mChildId ) )
237 const QgsProcessingModelChildAlgorithm childAlgorithm = mModel->childAlgorithm( mChildId );
239 std::unique_ptr< QgsProcessingAlgorithm > tempAlgorithm;
240 if ( mAlgorithmItem )
247 tempAlgorithm.reset( childAlgorithm.algorithm()->create( mAlgorithmItem->configuration() ) );
248 sourceAlgorithm = tempAlgorithm.get();
251 if ( !sourceAlgorithm )
254 const QList< const QgsProcessingParameterDefinition * > parameters = sourceAlgorithm->
parameterDefinitions();
257 mBlockChangesSignal++;
259 mDescriptionBox->setText( childAlgorithm.description() );
266 QList< QgsProcessingModelChildParameterSource > valueList;
267 std::optional< QgsProcessingModelChildParameterSource > singleValue;
268 if ( childAlgorithm.parameterSources().contains( param->name() ) )
270 valueList = childAlgorithm.parameterSources().value( param->name() );
271 if ( valueList.size() == 1 )
273 singleValue = valueList.at( 0 );
278 if ( valueList.isEmpty() && !singleValue.has_value() )
280 singleValue = QgsProcessingModelChildParameterSource::fromStaticValue( param->defaultValue() );
283 if ( mWrappers.contains( param->name() ) )
285 if ( !valueList.isEmpty() )
287 mWrappers.value( param->name() )->setWidgetValue( valueList );
289 else if ( singleValue.has_value() )
291 mWrappers.value( param->name() )->setWidgetValue( singleValue.value() );
301 QString modelOutputName;
302 const QMap< QString, QgsProcessingModelOutput > outputs = childAlgorithm.modelOutputs();
303 for (
auto it = outputs.constBegin(); it != outputs.constEnd(); ++it )
305 if ( it.value().childId() == mChildId && it.value().childOutputName() == output->name() )
308 modelOutputName = it.value().name();
309 mPreviousOutputDefinitions.insert( output->name(), it.value() );
314 QList< QgsProcessingModelChildParameterSource > valueList;
315 std::optional< QgsProcessingModelChildParameterSource > singleValue;
316 if ( modelOutputName.isEmpty() && childAlgorithm.parameterSources().contains( output->name() ) )
318 valueList = childAlgorithm.parameterSources().value( output->name() );
319 if ( valueList.size() == 1 )
321 singleValue = valueList.at( 0 );
326 if ( mWrappers.contains( output->name() ) )
329 if ( !modelOutputName.isEmpty() )
333 else if ( !valueList.empty() )
337 else if ( singleValue.has_value() )
341 else if ( output->defaultValue().isValid() )
343 wrapper->
setWidgetValue( QgsProcessingModelChildParameterSource::fromStaticValue( output->defaultValue() ) );
348 mDependenciesPanel->setValue( childAlgorithm.dependencies() );
350 mBlockChangesSignal--;
358 auto newChildAlgorithm = std::make_unique< QgsProcessingModelChildAlgorithm >( mAlgorithm->id() );
359 if ( mChildId.isEmpty() )
360 newChildAlgorithm->generateChildId( *mModel );
362 newChildAlgorithm->setChildId( mChildId );
364 newChildAlgorithm->setDescription( mDescriptionBox->text() );
365 if ( mAlgorithmItem )
367 newChildAlgorithm->setConfiguration( mAlgorithmItem->configuration() );
368 mAlgorithm.reset( newChildAlgorithm->algorithm()->create( mAlgorithmItem->configuration() ) );
371 const QList<const QgsProcessingParameterDefinition * > parameterDefinitions = mAlgorithm->parameterDefinitions();
377 if ( !mWrappers.contains( parameter->name() ) )
381 QVariant value = wrapper->
value();
383 QList< QgsProcessingModelChildParameterSource > sources;
384 if ( value.userType() == qMetaTypeId< QgsProcessingModelChildParameterSource >() )
386 sources.append( value.value< QgsProcessingModelChildParameterSource >() );
388 else if ( value.userType() == QMetaType::Type::QVariantList )
390 const QVariantList list = value.toList();
391 for (
const QVariant &subValue : list )
393 if ( subValue.userType() == qMetaTypeId< QgsProcessingModelChildParameterSource >() )
394 sources.append( subValue.value< QgsProcessingModelChildParameterSource >() );
396 sources.append( QgsProcessingModelChildParameterSource::fromStaticValue( subValue ) );
401 sources.append( QgsProcessingModelChildParameterSource::fromStaticValue( value ) );
405 for (
const QgsProcessingModelChildParameterSource &subValue : std::as_const( sources ) )
415 newChildAlgorithm->addParameterSources( parameter->name(), sources );
418 QMap< QString, QgsProcessingModelOutput > outputs;
419 const QList< const QgsProcessingParameterDefinition * > destinationParameters = mAlgorithm->destinationParameterDefinitions();
424 if ( mWrappers.contains( output->name() ) )
430 if ( !name.isEmpty() )
434 QgsProcessingModelOutput modelOutput = mPreviousOutputDefinitions.value( output->name(), QgsProcessingModelOutput( name, name ) );
435 modelOutput.setDescription( name );
436 modelOutput.setChildId( newChildAlgorithm->childId() );
437 modelOutput.setChildOutputName( output->name() );
438 outputs.insert( name, modelOutput );
443 const QVariant val = wrapper->
value();
444 QList< QgsProcessingModelChildParameterSource > sources;
445 if ( val.userType() == qMetaTypeId< QgsProcessingModelChildParameterSource >() )
447 sources.append( val.value< QgsProcessingModelChildParameterSource >() );
449 else if ( val.userType() == QMetaType::Type::QVariantList )
451 const QVariantList list = val.toList();
452 for (
const QVariant &subValue : list )
454 if ( subValue.userType() == qMetaTypeId< QgsProcessingModelChildParameterSource >() )
455 sources.append( subValue.value< QgsProcessingModelChildParameterSource >() );
457 sources.append( QgsProcessingModelChildParameterSource::fromStaticValue( subValue ) );
461 newChildAlgorithm->addParameterSources( output->name(), sources );
468 if ( !outputs.contains( output->name() ) )
470 QgsProcessingModelOutput modelOutput( output->name(), output->name() );
471 modelOutput.setChildId( newChildAlgorithm->childId() );
472 modelOutput.setChildOutputName( output->name() );
473 outputs.insert( output->name(), modelOutput );
478 newChildAlgorithm->setModelOutputs( outputs );
479 newChildAlgorithm->setDependencies( mDependenciesPanel->value() );
481 return newChildAlgorithm;
491 if ( mAlgorithmItem )
493 mAlgorithmItem->setWidgetContext( context );
495 for (
auto it = mWrappers.constBegin(); it != mWrappers.constEnd(); ++it )
497 it.value()->setWidgetContext( context );
521 return mParametersPanel->algorithm();
526 mTabWidget->setCurrentIndex( 1 );
527 mCommentEdit->setFocus();
528 mCommentEdit->selectAll();
533 mParametersPanel->setWidgetContext( context );
536void QgsProcessingModelerParametersWidget::setupUi()
538 auto mainLayout =
new QVBoxLayout();
539 mainLayout->setContentsMargins( 0, 0, 0, 0 );
541 mTabWidget =
new QTabWidget();
542 mainLayout->addWidget( mTabWidget );
548 mTabWidget->addTab( mPanelWidgetStack, tr(
"Properties" ) );
550 auto commentLayout =
new QVBoxLayout();
551 mCommentEdit =
new QTextEdit();
552 mCommentEdit->setAcceptRichText(
false );
553 commentLayout->addWidget( mCommentEdit, 1 );
556 auto hl =
new QHBoxLayout();
557 hl->setContentsMargins( 0, 0, 0, 0 );
558 hl->addWidget(
new QLabel( tr(
"Color" ) ) );
562 mCommentColorButton->setWindowTitle( tr(
"Comment Color" ) );
563 mCommentColorButton->
setShowNull(
true, tr(
"Default" ) );
564 hl->addWidget( mCommentColorButton );
565 commentLayout->addLayout( hl );
568 auto commentWidget =
new QWidget();
569 commentWidget->setLayout( commentLayout );
570 mTabWidget->addTab( commentWidget, tr(
"Comments" ) );
572 setLayout( mainLayout );
577 mCommentEdit->setPlainText( text );
582 return mCommentEdit->toPlainText();
587 if ( color.isValid() )
588 mCommentColorButton->setColor( color );
590 mCommentColorButton->setToNull();
595 return !mCommentColorButton->isNull() ? mCommentColorButton->color() : QColor();
600 mParametersPanel->setStateFromChildAlgorithm();
605 std::unique_ptr< QgsProcessingModelChildAlgorithm > alg = mParametersPanel->createAlgorithm();
608 alg->comment()->setDescription(
comments() );
623 setObjectName( u
"QgsProcessingModelerParametersDialog"_s );
630 setWindowTitle( childAlgorithm ? ( childAlgorithm->
group().isEmpty() ? childAlgorithm->
displayName() : u
"%1 - %2"_s.arg( childAlgorithm->
group(), childAlgorithm->
displayName() ) ) : QString() );
634 mButtonBox =
new QDialogButtonBox();
635 mButtonBox->setOrientation( Qt::Orientation::Horizontal );
636 mButtonBox->setStandardButtons( QDialogButtonBox::StandardButton::Cancel | QDialogButtonBox::StandardButton::Ok | QDialogButtonBox::StandardButton::Help );
638 connect( mButtonBox, &QDialogButtonBox::accepted,
this, &QgsProcessingModelerParametersDialog::okPressed );
639 connect( mButtonBox, &QDialogButtonBox::rejected,
this, &QDialog::reject );
640 connect( mButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsProcessingModelerParametersDialog::openHelp );
642 auto mainLayout =
new QVBoxLayout();
643 mainLayout->addWidget( mWidget, 1 );
644 mainLayout->addWidget( mButtonBox );
645 setLayout( mainLayout );
652 return mWidget->algorithm();
657 mWidget->setComments( text );
662 return mWidget->comments();
667 mWidget->setCommentColor( color );
672 return mWidget->commentColor();
677 mWidget->switchToCommentTab();
682 mWidget->setWidgetContext( context );
687 mWidget->setStateFromChildAlgorithm();
692 return mWidget->createAlgorithm();
695void QgsProcessingModelerParametersDialog::okPressed()
701void QgsProcessingModelerParametersDialog::openHelp()
707 if ( algHelp.isEmpty() &&
algorithm()->provider() )
714 if ( !algHelp.isEmpty() )
715 QDesktopServices::openUrl( QUrl( algHelp ) );
@ StaticValue
Parameter value is a static value.
@ Hidden
Parameter is hidden and should not be shown to users.
@ Advanced
Parameter is an advanced parameter which should be hidden from users by default.
@ IsModelOutput
Destination parameter is final output. The parameter name will be used.
static QgsProcessingGuiRegistry * processingGuiRegistry()
Returns the global processing gui registry, used for registering the GUI behavior of processing algor...
void applicationStyleSheetChanged(const QString &styleSheet)
Emitted whenever the application style sheet is changed.
static QString applicationStyleSheet()
Returns the application style sheet.
static QgsGui * instance()
Returns a pointer to the singleton instance.
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
static QUrl helpUrl(const QString &key)
Returns URI of the help topic for the given key.
A bar for displaying non-blocking messages to the user.
Abstract base class for processing algorithms.
virtual QString group() const
Returns the name of the group this algorithm belongs to.
virtual QString helpUrl() const
Returns a url pointing to the algorithm's help page.
QgsProcessingParameterDefinitions parameterDefinitions() const
Returns an ordered list of parameter definitions utilized by the algorithm.
virtual QString displayName() const =0
Returns the translated algorithm name, which should be used for any user-visible display of the algor...
QgsProcessingParameterDefinitions destinationParameterDefinitions() const
Returns a list of destination parameters definitions utilized by the algorithm.
Contains information about the context in which a processing algorithm is executed.
QgsProcessingAlgorithmConfigurationWidget * algorithmConfigurationWidget(const QgsProcessingAlgorithm *algorithm) const
Gets the configuration widget for an algorithm.
QgsProcessingModelerParameterWidget * createModelerParameterWidget(QgsProcessingModelAlgorithm *model, const QString &childId, const QgsProcessingParameterDefinition *parameter, QgsProcessingContext &context)
Creates a new modeler parameter widget for the given parameter.
~QgsProcessingModelerParametersDialog() override
void setCommentColor(const QColor &color)
Sets the algorithm's comment color.
QgsProcessingModelerParametersDialog(const QgsProcessingAlgorithm *childAlgorithm, QgsProcessingModelAlgorithm *model, QgsProcessingContext &context, const QString &childId=QString(), const QVariantMap &configuration=QVariantMap(), QWidget *parent=nullptr)
Constructor for QgsProcessingModelerParametersDialog.
QString comments() const
Returns the algorithm's comments.
std::unique_ptr< QgsProcessingModelChildAlgorithm > createAlgorithm()
Creates the child algorithm instance, populated with the current dialog parameter values and comments...
void setStateFromChildAlgorithm()
Sets widget state from the existing child algorithm definition in the model.
void setWidgetContext(const QgsProcessingParameterWidgetContext &context)
Sets the context in which the dialog is shown, e.g., the parent model algorithm, a linked map canvas,...
void setComments(const QString &comments)
Sets the algorithm's comments.
const QgsProcessingAlgorithm * algorithm() const
Returns the algorithm associated with the dialog.
void switchToCommentTab()
Focuses the dialog on the comment editing tab.
QColor commentColor() const
Returns the algorithm's comment color.
Base class for the definition of processing parameters.
Contains settings which reflect the context in which a Processing parameter widget is shown.