23 #include "models/qgsprocessingmodelalgorithm.h"
30 #include <QHBoxLayout>
31 #include <QToolButton>
32 #include <QStackedWidget>
38 const QString &childId,
44 , mParameterDefinition( parameter )
47 setFocusPolicy( Qt::StrongFocus );
52 QHBoxLayout *hLayout =
new QHBoxLayout();
54 mSourceButton =
new QToolButton();
55 mSourceButton->setFocusPolicy( Qt::StrongFocus );
58 mSourceButton->setFixedSize( 2 *
static_cast< int >( 1.25 *
iconSize / 2.0 ), 2 *
static_cast< int >(
iconSize * 1.1 / 2.0 ) );
60 mSourceButton->setPopupMode( QToolButton::InstantPopup );
62 mSourceMenu =
new QMenu(
this );
63 connect( mSourceMenu, &QMenu::aboutToShow,
this, &QgsProcessingModelerParameterWidget::sourceMenuAboutToShow );
64 connect( mSourceMenu, &QMenu::triggered,
this, &QgsProcessingModelerParameterWidget::sourceMenuActionTriggered );
65 mSourceButton->setMenu( mSourceMenu );
67 hLayout->addWidget( mSourceButton );
69 mStackedWidget =
new QStackedWidget();
72 if ( mStaticWidgetWrapper )
74 QWidget *widget = mStaticWidgetWrapper->createWrappedWidget( context );
77 mHasStaticWrapper =
true;
78 mStackedWidget->addWidget( widget );
81 mStackedWidget->addWidget(
new QWidget() );
85 mStackedWidget->addWidget(
new QWidget() );
90 mStackedWidget->addWidget( mExpressionWidget );
92 mModelInputCombo =
new QComboBox();
93 QHBoxLayout *hLayout2 =
new QHBoxLayout();
94 hLayout2->setMargin( 0 );
95 hLayout2->setContentsMargins( 0, 0, 0, 0 );
96 hLayout2->addWidget(
new QLabel( tr(
"Using model input" ) ) );
97 hLayout2->addWidget( mModelInputCombo, 1 );
98 QWidget *hWidget2 =
new QWidget();
99 hWidget2->setLayout( hLayout2 );
100 mStackedWidget->addWidget( hWidget2 );
102 mChildOutputCombo =
new QComboBox();
103 QHBoxLayout *hLayout3 =
new QHBoxLayout();
104 hLayout3->setMargin( 0 );
105 hLayout3->setContentsMargins( 0, 0, 0, 0 );
106 hLayout3->addWidget(
new QLabel( tr(
"Using algorithm output" ) ) );
107 hLayout3->addWidget( mChildOutputCombo, 1 );
108 QWidget *hWidget3 =
new QWidget();
109 hWidget3->setLayout( hLayout3 );
110 mStackedWidget->addWidget( hWidget3 );
115 mModelOutputName->setPlaceholderText( tr(
"[Enter name if this is a final result]" ) );
116 QHBoxLayout *hLayout4 =
new QHBoxLayout();
117 hLayout4->setMargin( 0 );
118 hLayout4->setContentsMargins( 0, 0, 0, 0 );
119 hLayout4->addWidget( mModelOutputName );
120 QWidget *hWidget4 =
new QWidget();
121 hWidget4->setLayout( hLayout4 );
122 mStackedWidget->addWidget( hWidget4 );
125 hLayout->setMargin( 0 );
126 hLayout->setContentsMargins( 0, 0, 0, 0 );
127 hLayout->addWidget( mStackedWidget, 1 );
129 setLayout( hLayout );
130 setSourceType( mParameterDefinition->
isDestination() ? QgsProcessingModelChildParameterSource::ModelOutput : QgsProcessingModelChildParameterSource::StaticValue );
137 if ( mStaticWidgetWrapper )
138 mStaticWidgetWrapper->setWidgetContext( context );
143 if ( mStaticWidgetWrapper )
144 mStaticWidgetWrapper->registerProcessingContextGenerator( generator );
149 return mParameterDefinition;
154 if ( mStaticWidgetWrapper )
155 return mStaticWidgetWrapper->createWrappedLabel();
164 mStaticValue =
value.staticValue();
165 mModelInputParameterName =
value.parameterName();
166 mOutputChildId =
value.outputChildId();
167 mOutputName =
value.outputName();
168 mExpression =
value.expression();
171 setSourceType(
value.source() );
176 if ( values.size() == 1 )
181 for (
const QgsProcessingModelChildParameterSource &v : values )
182 r << QVariant::fromValue( v );
185 setSourceType( QgsProcessingModelChildParameterSource::StaticValue );
191 if ( mModelOutputName )
192 mModelOutputName->setText(
value );
193 setSourceType( QgsProcessingModelChildParameterSource::ModelOutput );
198 return currentSourceType() == ModelOutput;
203 return mModelOutputName ? mModelOutputName->text().trimmed() : QString();
208 switch ( currentSourceType() )
212 const QVariant v = mStaticWidgetWrapper->parameterValue();
214 if ( v.type() == QVariant::List )
216 const QVariantList vList = v.toList();
217 if ( std::all_of( vList.begin(), vList.end(), [](
const QVariant & val )
219 return val.canConvert< QgsProcessingModelChildParameterSource >();
225 return QVariant::fromValue( QgsProcessingModelChildParameterSource::fromStaticValue( v ) );
229 return QVariant::fromValue( QgsProcessingModelChildParameterSource::fromExpression( mExpressionWidget->
expression() ) );
232 return QVariant::fromValue( QgsProcessingModelChildParameterSource::fromModelParameter( mModelInputCombo->currentData().toString() ) );
236 const QStringList parts = mChildOutputCombo->currentData().toStringList();
237 return QVariant::fromValue( QgsProcessingModelChildParameterSource::fromChildOutput( parts.value( 0, QString() ), parts.value( 1, QString() ) ) );
241 return mModelOutputName ? ( mModelOutputName->text().trimmed().isEmpty() ? QVariant() : mModelOutputName->text() ) : QVariant();
244 return QVariant::fromValue( QgsProcessingModelChildParameterSource() );
249 if ( mStaticWidgetWrapper )
250 mStaticWidgetWrapper->setDialog( dialog );
259 if ( mModel->childAlgorithms().contains( mChildId ) )
260 alg = mModel->childAlgorithm( mChildId ).algorithm();
265 QgsExpressionContextScope *childScope = mModel->createExpressionContextScopeForChildAlgorithm( mChildId, mContext, QVariantMap(), QVariantMap() );
268 QStringList highlightedVariables = childScope->
variableNames();
269 QStringList highlightedFunctions = childScope->functionNames();
270 highlightedVariables += algorithmScope->variableNames();
271 highlightedVariables += mModel->variables().keys();
272 highlightedFunctions += algorithmScope->functionNames();
273 c.setHighlightedVariables( highlightedVariables );
274 c.setHighlightedFunctions( highlightedFunctions );
280 void QgsProcessingModelerParameterWidget::sourceMenuAboutToShow()
282 mSourceMenu->clear();
284 const SourceType currentSource = currentSourceType();
288 QAction *modelOutputAction = mSourceMenu->addAction( tr(
"Model Output" ) );
289 modelOutputAction->setCheckable( currentSource == ModelOutput );
290 modelOutputAction->setChecked( currentSource == ModelOutput );
291 modelOutputAction->setData( QgsProcessingModelChildParameterSource::ModelOutput );
294 if ( mHasStaticWrapper )
296 QAction *fixedValueAction = mSourceMenu->addAction( tr(
"Value" ) );
297 fixedValueAction->setCheckable( currentSource == StaticValue );
298 fixedValueAction->setChecked( currentSource == StaticValue );
299 fixedValueAction->setData( QgsProcessingModelChildParameterSource::StaticValue );
302 QAction *calculatedValueAction = mSourceMenu->addAction( tr(
"Pre-calculated Value" ) );
303 calculatedValueAction->setCheckable( currentSource == Expression );
304 calculatedValueAction->setChecked( currentSource == Expression );
305 calculatedValueAction->setData( QgsProcessingModelChildParameterSource::Expression );
307 QAction *inputValueAction = mSourceMenu->addAction( tr(
"Model Input" ) );
308 inputValueAction->setCheckable( currentSource == ModelParameter );
309 inputValueAction->setChecked( currentSource == ModelParameter );
310 inputValueAction->setData( QgsProcessingModelChildParameterSource::ModelParameter );
312 QAction *childOutputValueAction = mSourceMenu->addAction( tr(
"Algorithm Output" ) );
313 childOutputValueAction->setCheckable( currentSource == ChildOutput );
314 childOutputValueAction->setChecked( currentSource == ChildOutput );
315 childOutputValueAction->setData( QgsProcessingModelChildParameterSource::ChildOutput );
320 void QgsProcessingModelerParameterWidget::sourceMenuActionTriggered( QAction *action )
322 QgsProcessingModelChildParameterSource::Source sourceType =
static_cast< QgsProcessingModelChildParameterSource::Source
>( action->data().toInt() );
323 setSourceType( sourceType );
326 QgsProcessingModelerParameterWidget::SourceType QgsProcessingModelerParameterWidget::currentSourceType()
const
328 return static_cast< SourceType
>( mStackedWidget->currentIndex() );
331 void QgsProcessingModelerParameterWidget::setSourceType( QgsProcessingModelChildParameterSource::Source type )
335 case QgsProcessingModelChildParameterSource::StaticValue:
336 mStackedWidget->setCurrentIndex(
static_cast< int >( StaticValue ) );
338 mSourceButton->setToolTip( tr(
"Value" ) );
341 case QgsProcessingModelChildParameterSource::Expression:
343 mStackedWidget->setCurrentIndex(
static_cast< int >( Expression ) );
344 mSourceButton->setToolTip( tr(
"Pre-calculated Value" ) );
347 case QgsProcessingModelChildParameterSource::ModelParameter:
350 mStackedWidget->setCurrentIndex(
static_cast< int >( ModelParameter ) );
351 mSourceButton->setToolTip( tr(
"Model Input" ) );
355 case QgsProcessingModelChildParameterSource::ChildOutput:
358 mStackedWidget->setCurrentIndex(
static_cast< int >( ChildOutput ) );
359 mSourceButton->setToolTip( tr(
"Algorithm Output" ) );
363 case QgsProcessingModelChildParameterSource::ModelOutput:
366 mStackedWidget->setCurrentIndex(
static_cast< int >( ModelOutput ) );
367 mSourceButton->setToolTip( tr(
"Model Output" ) );
371 case QgsProcessingModelChildParameterSource::ExpressionText:
376 void QgsProcessingModelerParameterWidget::updateUi()
378 mStaticWidgetWrapper->setParameterValue( mStaticValue, mContext );
382 int currentIndex = mModelInputCombo->findData( mModelInputParameterName );
383 if ( currentIndex == -1 && mModelInputCombo->count() > 0 )
385 mModelInputCombo->setCurrentIndex( currentIndex );
387 const QStringList parts = QStringList() << mOutputChildId << mOutputName;
388 currentIndex = mChildOutputCombo->findData( parts );
389 if ( currentIndex == -1 && mChildOutputCombo->count() > 0 )
391 mChildOutputCombo->setCurrentIndex( currentIndex );
396 const QList< QgsProcessingModelChildParameterSource > sources = mModel->availableSourcesForChild( mChildId,
397 compatibleParameterTypes, compatibleOutputTypes, compatibleDataTypes );
399 for (
const QgsProcessingModelChildParameterSource &source : sources )
401 switch ( source.source() )
403 case QgsProcessingModelChildParameterSource::ModelParameter:
404 mModelInputCombo->addItem( mModel->parameterDefinition( source.parameterName() )->description(), source.parameterName() );
407 case QgsProcessingModelChildParameterSource::ChildOutput:
409 if ( !mModel->childAlgorithms().contains( source.outputChildId() ) )
412 const QgsProcessingModelChildAlgorithm &alg = mModel->childAlgorithm( source.outputChildId() );
413 if ( !alg.algorithm() )
415 const QString outputDescription = alg.algorithm()->outputDefinition( source.outputName() )->description();
416 const QString childDescription = alg.description();
418 mChildOutputCombo->addItem( tr(
"“%1” from algorithm “%2”" ).arg( outputDescription, childDescription ), QStringList() << source.outputChildId() << source.outputName() );
422 case QgsProcessingModelChildParameterSource::StaticValue:
423 case QgsProcessingModelChildParameterSource::Expression:
424 case QgsProcessingModelChildParameterSource::ExpressionText:
425 case QgsProcessingModelChildParameterSource::ModelOutput: