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->setContentsMargins( 0, 0, 0, 0 );
95 hLayout2->addWidget(
new QLabel( tr(
"Using model input" ) ) );
96 hLayout2->addWidget( mModelInputCombo, 1 );
97 QWidget *hWidget2 =
new QWidget();
98 hWidget2->setLayout( hLayout2 );
99 mStackedWidget->addWidget( hWidget2 );
101 mChildOutputCombo =
new QComboBox();
102 QHBoxLayout *hLayout3 =
new QHBoxLayout();
103 hLayout3->setContentsMargins( 0, 0, 0, 0 );
104 hLayout3->addWidget(
new QLabel( tr(
"Using algorithm output" ) ) );
105 hLayout3->addWidget( mChildOutputCombo, 1 );
106 QWidget *hWidget3 =
new QWidget();
107 hWidget3->setLayout( hLayout3 );
108 mStackedWidget->addWidget( hWidget3 );
113 mModelOutputName->setPlaceholderText( tr(
"[Enter name if this is a final result]" ) );
114 QHBoxLayout *hLayout4 =
new QHBoxLayout();
115 hLayout4->setContentsMargins( 0, 0, 0, 0 );
116 hLayout4->addWidget( mModelOutputName );
117 QWidget *hWidget4 =
new QWidget();
118 hWidget4->setLayout( hLayout4 );
119 mStackedWidget->addWidget( hWidget4 );
122 hLayout->setContentsMargins( 0, 0, 0, 0 );
123 hLayout->addWidget( mStackedWidget, 1 );
125 setLayout( hLayout );
126 setSourceType( mParameterDefinition->
isDestination() ? QgsProcessingModelChildParameterSource::ModelOutput : QgsProcessingModelChildParameterSource::StaticValue );
133 if ( mStaticWidgetWrapper )
134 mStaticWidgetWrapper->setWidgetContext( context );
139 if ( mStaticWidgetWrapper )
140 mStaticWidgetWrapper->registerProcessingContextGenerator( generator );
145 return mParameterDefinition;
150 if ( mStaticWidgetWrapper )
151 return mStaticWidgetWrapper->createWrappedLabel();
160 mStaticValue =
value.staticValue();
161 mModelInputParameterName =
value.parameterName();
162 mOutputChildId =
value.outputChildId();
163 mOutputName =
value.outputName();
164 mExpression =
value.expression();
167 setSourceType(
value.source() );
172 if ( values.size() == 1 )
177 for (
const QgsProcessingModelChildParameterSource &v : values )
178 r << QVariant::fromValue( v );
181 setSourceType( QgsProcessingModelChildParameterSource::StaticValue );
187 if ( mModelOutputName )
188 mModelOutputName->setText(
value );
189 setSourceType( QgsProcessingModelChildParameterSource::ModelOutput );
194 return currentSourceType() == ModelOutput;
199 return mModelOutputName ? mModelOutputName->text().trimmed() : QString();
204 switch ( currentSourceType() )
208 const QVariant v = mStaticWidgetWrapper->parameterValue();
210 if ( v.type() == QVariant::List )
212 const QVariantList vList = v.toList();
213 if ( std::all_of( vList.begin(), vList.end(), [](
const QVariant & val )
215 return val.canConvert< QgsProcessingModelChildParameterSource >();
221 return QVariant::fromValue( QgsProcessingModelChildParameterSource::fromStaticValue( v ) );
225 return QVariant::fromValue( QgsProcessingModelChildParameterSource::fromExpression( mExpressionWidget->
expression() ) );
228 return QVariant::fromValue( QgsProcessingModelChildParameterSource::fromModelParameter( mModelInputCombo->currentData().toString() ) );
232 const QStringList parts = mChildOutputCombo->currentData().toStringList();
233 return QVariant::fromValue( QgsProcessingModelChildParameterSource::fromChildOutput( parts.value( 0, QString() ), parts.value( 1, QString() ) ) );
237 return mModelOutputName ? ( mModelOutputName->text().trimmed().isEmpty() ? QVariant() : mModelOutputName->text() ) : QVariant();
240 return QVariant::fromValue( QgsProcessingModelChildParameterSource() );
245 if ( mStaticWidgetWrapper )
246 mStaticWidgetWrapper->setDialog( dialog );
255 if ( mModel->childAlgorithms().contains( mChildId ) )
256 alg = mModel->childAlgorithm( mChildId ).algorithm();
261 QgsExpressionContextScope *childScope = mModel->createExpressionContextScopeForChildAlgorithm( mChildId, mContext, QVariantMap(), QVariantMap() );
264 QStringList highlightedVariables = childScope->
variableNames();
265 QStringList highlightedFunctions = childScope->functionNames();
266 highlightedVariables += algorithmScope->variableNames();
267 highlightedVariables += mModel->variables().keys();
268 highlightedFunctions += algorithmScope->functionNames();
269 c.setHighlightedVariables( highlightedVariables );
270 c.setHighlightedFunctions( highlightedFunctions );
276 void QgsProcessingModelerParameterWidget::sourceMenuAboutToShow()
278 mSourceMenu->clear();
280 const SourceType currentSource = currentSourceType();
284 QAction *modelOutputAction = mSourceMenu->addAction( tr(
"Model Output" ) );
285 modelOutputAction->setCheckable( currentSource == ModelOutput );
286 modelOutputAction->setChecked( currentSource == ModelOutput );
287 modelOutputAction->setData( QgsProcessingModelChildParameterSource::ModelOutput );
290 if ( mHasStaticWrapper )
292 QAction *fixedValueAction = mSourceMenu->addAction( tr(
"Value" ) );
293 fixedValueAction->setCheckable( currentSource == StaticValue );
294 fixedValueAction->setChecked( currentSource == StaticValue );
295 fixedValueAction->setData( QgsProcessingModelChildParameterSource::StaticValue );
298 QAction *calculatedValueAction = mSourceMenu->addAction( tr(
"Pre-calculated Value" ) );
299 calculatedValueAction->setCheckable( currentSource == Expression );
300 calculatedValueAction->setChecked( currentSource == Expression );
301 calculatedValueAction->setData( QgsProcessingModelChildParameterSource::Expression );
303 QAction *inputValueAction = mSourceMenu->addAction( tr(
"Model Input" ) );
304 inputValueAction->setCheckable( currentSource == ModelParameter );
305 inputValueAction->setChecked( currentSource == ModelParameter );
306 inputValueAction->setData( QgsProcessingModelChildParameterSource::ModelParameter );
308 QAction *childOutputValueAction = mSourceMenu->addAction( tr(
"Algorithm Output" ) );
309 childOutputValueAction->setCheckable( currentSource == ChildOutput );
310 childOutputValueAction->setChecked( currentSource == ChildOutput );
311 childOutputValueAction->setData( QgsProcessingModelChildParameterSource::ChildOutput );
316 void QgsProcessingModelerParameterWidget::sourceMenuActionTriggered( QAction *action )
318 QgsProcessingModelChildParameterSource::Source sourceType =
static_cast< QgsProcessingModelChildParameterSource::Source
>( action->data().toInt() );
319 setSourceType( sourceType );
322 QgsProcessingModelerParameterWidget::SourceType QgsProcessingModelerParameterWidget::currentSourceType()
const
324 return static_cast< SourceType
>( mStackedWidget->currentIndex() );
327 void QgsProcessingModelerParameterWidget::setSourceType( QgsProcessingModelChildParameterSource::Source type )
331 case QgsProcessingModelChildParameterSource::StaticValue:
332 mStackedWidget->setCurrentIndex(
static_cast< int >( StaticValue ) );
334 mSourceButton->setToolTip( tr(
"Value" ) );
337 case QgsProcessingModelChildParameterSource::Expression:
339 mStackedWidget->setCurrentIndex(
static_cast< int >( Expression ) );
340 mSourceButton->setToolTip( tr(
"Pre-calculated Value" ) );
343 case QgsProcessingModelChildParameterSource::ModelParameter:
346 mStackedWidget->setCurrentIndex(
static_cast< int >( ModelParameter ) );
347 mSourceButton->setToolTip( tr(
"Model Input" ) );
351 case QgsProcessingModelChildParameterSource::ChildOutput:
354 mStackedWidget->setCurrentIndex(
static_cast< int >( ChildOutput ) );
355 mSourceButton->setToolTip( tr(
"Algorithm Output" ) );
359 case QgsProcessingModelChildParameterSource::ModelOutput:
362 mStackedWidget->setCurrentIndex(
static_cast< int >( ModelOutput ) );
363 mSourceButton->setToolTip( tr(
"Model Output" ) );
367 case QgsProcessingModelChildParameterSource::ExpressionText:
372 void QgsProcessingModelerParameterWidget::updateUi()
374 mStaticWidgetWrapper->setParameterValue( mStaticValue, mContext );
378 int currentIndex = mModelInputCombo->findData( mModelInputParameterName );
379 if ( currentIndex == -1 && mModelInputCombo->count() > 0 )
381 mModelInputCombo->setCurrentIndex( currentIndex );
383 const QStringList parts = QStringList() << mOutputChildId << mOutputName;
384 currentIndex = mChildOutputCombo->findData( parts );
385 if ( currentIndex == -1 && mChildOutputCombo->count() > 0 )
387 mChildOutputCombo->setCurrentIndex( currentIndex );
392 const QList< QgsProcessingModelChildParameterSource > sources = mModel->availableSourcesForChild( mChildId,
393 compatibleParameterTypes, compatibleOutputTypes, compatibleDataTypes );
395 for (
const QgsProcessingModelChildParameterSource &source : sources )
397 switch ( source.source() )
399 case QgsProcessingModelChildParameterSource::ModelParameter:
400 mModelInputCombo->addItem( mModel->parameterDefinition( source.parameterName() )->description(), source.parameterName() );
403 case QgsProcessingModelChildParameterSource::ChildOutput:
405 if ( !mModel->childAlgorithms().contains( source.outputChildId() ) )
408 const QgsProcessingModelChildAlgorithm &alg = mModel->childAlgorithm( source.outputChildId() );
409 if ( !alg.algorithm() )
411 const QString outputDescription = alg.algorithm()->outputDefinition( source.outputName() )->description();
412 const QString childDescription = alg.description();
414 mChildOutputCombo->addItem( tr(
"“%1” from algorithm “%2”" ).arg( outputDescription, childDescription ), QStringList() << source.outputChildId() << source.outputName() );
418 case QgsProcessingModelChildParameterSource::StaticValue:
419 case QgsProcessingModelChildParameterSource::Expression:
420 case QgsProcessingModelChildParameterSource::ExpressionText:
421 case QgsProcessingModelChildParameterSource::ModelOutput: