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();
 
  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   const QgsProcessingModelChildParameterSource::Source sourceType = 
static_cast< QgsProcessingModelChildParameterSource::Source  
>( action->data().toInt() );
 
  322 QgsProcessingModelerParameterWidget::SourceType QgsProcessingModelerParameterWidget::currentSourceType()
 const 
  324   return static_cast< SourceType 
>( mStackedWidget->currentIndex() );
 
  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: