QGIS API Documentation  3.14.0-Pi (9f7028fd23)
qgsprocessingwidgetwrapperimpl.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsprocessingwidgetwrapperimpl.cpp
3  ---------------------
4  begin : August 2018
5  copyright : (C) 2018 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
20 #include "processing/models/qgsprocessingmodelalgorithm.h"
21 #include "qgsprocessingoutputs.h"
24 #include "qgsspinbox.h"
25 #include "qgsdoublespinbox.h"
26 #include "qgsprocessingcontext.h"
27 #include "qgsauthconfigselect.h"
28 #include "qgsapplication.h"
29 #include "qgsfilewidget.h"
30 #include "qgssettings.h"
31 #include "qgsexpressionlineedit.h"
34 #include "qgslayoutmanager.h"
35 #include "qgsproject.h"
36 #include "qgslayoutcombobox.h"
37 #include "qgslayoutitemcombobox.h"
38 #include "qgsprintlayout.h"
39 #include "qgsscalewidget.h"
40 #include "qgssnapindicator.h"
41 #include "qgsmapmouseevent.h"
42 #include "qgsfilterlineedit.h"
43 #include "qgsmapcanvas.h"
44 #include "qgsmessagebar.h"
45 #include "qgscolorbutton.h"
48 #include "qgsfieldcombobox.h"
49 #include "qgsmapthemecollection.h"
50 #include "qgsdatetimeedit.h"
54 #include "qgsextentwidget.h"
58 #include "qgsrasterbandcombobox.h"
60 #include "qgscheckablecombobox.h"
61 #include <QToolButton>
62 #include <QLabel>
63 #include <QHBoxLayout>
64 #include <QVBoxLayout>
65 #include <QCheckBox>
66 #include <QComboBox>
67 #include <QLineEdit>
68 #include <QPlainTextEdit>
69 #include <QRadioButton>
70 #include <QButtonGroup>
71 #include <QMenu>
72 #include <QFileDialog>
73 
75 
76 //
77 // QgsProcessingBooleanWidgetWrapper
78 //
79 
80 
81 QgsProcessingBooleanParameterDefinitionWidget::QgsProcessingBooleanParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
82  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
83 {
84  QVBoxLayout *vlayout = new QVBoxLayout();
85  vlayout->setMargin( 0 );
86  vlayout->setContentsMargins( 0, 0, 0, 0 );
87 
88  mDefaultCheckBox = new QCheckBox( tr( "Checked" ) );
89  if ( const QgsProcessingParameterBoolean *boolParam = dynamic_cast<const QgsProcessingParameterBoolean *>( definition ) )
90  mDefaultCheckBox->setChecked( QgsProcessingParameters::parameterAsBool( boolParam, boolParam->defaultValue(), context ) );
91  else
92  mDefaultCheckBox->setChecked( false );
93  vlayout->addWidget( mDefaultCheckBox );
94  setLayout( vlayout );
95 }
96 
97 QgsProcessingParameterDefinition *QgsProcessingBooleanParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
98 {
99  auto param = qgis::make_unique< QgsProcessingParameterBoolean >( name, description, mDefaultCheckBox->isChecked() );
100  param->setFlags( flags );
101  return param.release();
102 }
103 
104 
105 QgsProcessingBooleanWidgetWrapper::QgsProcessingBooleanWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
106  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
107 {
108 
109 }
110 
111 QWidget *QgsProcessingBooleanWidgetWrapper::createWidget()
112 {
113  switch ( type() )
114  {
116  {
117  QString description = parameterDefinition()->description();
118  if ( parameterDefinition()->flags() & QgsProcessingParameterDefinition::FlagOptional )
119  description = QObject::tr( "%1 [optional]" ).arg( description );
120 
121  mCheckBox = new QCheckBox( description );
122  mCheckBox->setToolTip( parameterDefinition()->toolTip() );
123 
124  connect( mCheckBox, &QCheckBox::toggled, this, [ = ]
125  {
126  emit widgetValueHasChanged( this );
127  } );
128  return mCheckBox;
129  }
130 
133  {
134  mComboBox = new QComboBox();
135  mComboBox->addItem( tr( "Yes" ), true );
136  mComboBox->addItem( tr( "No" ), false );
137  mComboBox->setToolTip( parameterDefinition()->toolTip() );
138 
139  connect( mComboBox, qgis::overload< int>::of( &QComboBox::currentIndexChanged ), this, [ = ]
140  {
141  emit widgetValueHasChanged( this );
142  } );
143 
144  return mComboBox;
145  }
146  }
147  return nullptr;
148 }
149 
150 QLabel *QgsProcessingBooleanWidgetWrapper::createLabel()
151 {
152  // avoid creating labels in standard dialogs
153  if ( type() == QgsProcessingGui::Standard )
154  return nullptr;
155  else
157 }
158 
159 void QgsProcessingBooleanWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
160 {
161  switch ( type() )
162  {
164  {
165  const bool v = QgsProcessingParameters::parameterAsBool( parameterDefinition(), value, context );
166  mCheckBox->setChecked( v );
167  break;
168  }
169 
172  {
173  const bool v = QgsProcessingParameters::parameterAsBool( parameterDefinition(), value, context );
174  mComboBox->setCurrentIndex( mComboBox->findData( v ) );
175  break;
176  }
177  }
178 }
179 
180 QVariant QgsProcessingBooleanWidgetWrapper::widgetValue() const
181 {
182  switch ( type() )
183  {
185  return mCheckBox->isChecked();
186 
189  return mComboBox->currentData();
190  }
191  return QVariant();
192 }
193 
194 QStringList QgsProcessingBooleanWidgetWrapper::compatibleParameterTypes() const
195 {
196  //pretty much everything is compatible here and can be converted to a bool!
197  return QStringList() << QgsProcessingParameterBoolean::typeName()
211 }
212 
213 QStringList QgsProcessingBooleanWidgetWrapper::compatibleOutputTypes() const
214 {
215  return QStringList() << QgsProcessingOutputNumber::typeName()
222 }
223 
224 QString QgsProcessingBooleanWidgetWrapper::parameterType() const
225 {
227 }
228 
229 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingBooleanWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
230 {
231  return new QgsProcessingBooleanWidgetWrapper( parameter, type );
232 }
233 
234 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingBooleanWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
235 {
236  return new QgsProcessingBooleanParameterDefinitionWidget( context, widgetContext, definition, algorithm );
237 }
238 
239 
240 //
241 // QgsProcessingCrsWidgetWrapper
242 //
243 
244 QgsProcessingCrsParameterDefinitionWidget::QgsProcessingCrsParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
245  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
246 {
247  QVBoxLayout *vlayout = new QVBoxLayout();
248  vlayout->setMargin( 0 );
249  vlayout->setContentsMargins( 0, 0, 0, 0 );
250 
251  vlayout->addWidget( new QLabel( tr( "Default value" ) ) );
252 
253  mCrsSelector = new QgsProjectionSelectionWidget();
254  if ( const QgsProcessingParameterCrs *crsParam = dynamic_cast<const QgsProcessingParameterCrs *>( definition ) )
255  mCrsSelector->setCrs( QgsProcessingParameters::parameterAsCrs( crsParam, crsParam->defaultValue(), context ) );
256  else
257  mCrsSelector->setCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:4326" ) ) );
258 
259  vlayout->addWidget( mCrsSelector );
260  setLayout( vlayout );
261 }
262 
263 QgsProcessingParameterDefinition *QgsProcessingCrsParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
264 {
265  auto param = qgis::make_unique< QgsProcessingParameterCrs >( name, description, mCrsSelector->crs().authid() );
266  param->setFlags( flags );
267  return param.release();
268 }
269 
270 QgsProcessingCrsWidgetWrapper::QgsProcessingCrsWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
271  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
272 {
273 
274 }
275 
276 QWidget *QgsProcessingCrsWidgetWrapper::createWidget()
277 {
278  Q_ASSERT( mProjectionSelectionWidget == nullptr );
279  mProjectionSelectionWidget = new QgsProjectionSelectionWidget();
280  mProjectionSelectionWidget->setToolTip( parameterDefinition()->toolTip() );
281 
282  if ( parameterDefinition()->flags() & QgsProcessingParameterDefinition::FlagOptional )
283  mProjectionSelectionWidget->setOptionVisible( QgsProjectionSelectionWidget::CrsNotSet, true );
284  else
285  mProjectionSelectionWidget->setOptionVisible( QgsProjectionSelectionWidget::CrsNotSet, false );
286 
287  connect( mProjectionSelectionWidget, &QgsProjectionSelectionWidget::crsChanged, this, [ = ]
288  {
289  emit widgetValueHasChanged( this );
290  } );
291 
292  switch ( type() )
293  {
296  {
297  return mProjectionSelectionWidget;
298  }
299 
301  {
302  QWidget *w = new QWidget();
303  w->setToolTip( parameterDefinition()->toolTip() );
304 
305  QVBoxLayout *vl = new QVBoxLayout();
306  vl->setMargin( 0 );
307  vl->setContentsMargins( 0, 0, 0, 0 );
308  w->setLayout( vl );
309 
310  mUseProjectCrsCheckBox = new QCheckBox( tr( "Use project CRS" ) );
311  mUseProjectCrsCheckBox->setToolTip( tr( "Always use the current project CRS when running the model" ) );
312  vl->addWidget( mUseProjectCrsCheckBox );
313  connect( mUseProjectCrsCheckBox, &QCheckBox::toggled, mProjectionSelectionWidget, &QgsProjectionSelectionWidget::setDisabled );
314  connect( mUseProjectCrsCheckBox, &QCheckBox::toggled, this, [ = ]
315  {
316  emit widgetValueHasChanged( this );
317  } );
318 
319  vl->addWidget( mProjectionSelectionWidget );
320 
321  return w;
322  }
323  }
324  return nullptr;
325 }
326 
327 void QgsProcessingCrsWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
328 {
329  if ( mUseProjectCrsCheckBox )
330  {
331  if ( value.toString().compare( QLatin1String( "ProjectCrs" ), Qt::CaseInsensitive ) == 0 )
332  {
333  mUseProjectCrsCheckBox->setChecked( true );
334  return;
335  }
336  else
337  {
338  mUseProjectCrsCheckBox->setChecked( false );
339  }
340  }
341 
342  const QgsCoordinateReferenceSystem v = QgsProcessingParameters::parameterAsCrs( parameterDefinition(), value, context );
343  if ( mProjectionSelectionWidget )
344  mProjectionSelectionWidget->setCrs( v );
345 }
346 
347 QVariant QgsProcessingCrsWidgetWrapper::widgetValue() const
348 {
349  if ( mUseProjectCrsCheckBox && mUseProjectCrsCheckBox->isChecked() )
350  return QStringLiteral( "ProjectCrs" );
351  else if ( mProjectionSelectionWidget )
352  return mProjectionSelectionWidget->crs().isValid() ? mProjectionSelectionWidget->crs() : QVariant();
353  else
354  return QVariant();
355 }
356 
357 QStringList QgsProcessingCrsWidgetWrapper::compatibleParameterTypes() const
358 {
359  return QStringList()
367 }
368 
369 QStringList QgsProcessingCrsWidgetWrapper::compatibleOutputTypes() const
370 {
371  return QStringList() << QgsProcessingOutputVectorLayer::typeName()
375 }
376 
377 QString QgsProcessingCrsWidgetWrapper::modelerExpressionFormatString() const
378 {
379  return tr( "string as EPSG code, WKT or PROJ format, or a string identifying a map layer" );
380 }
381 
382 QString QgsProcessingCrsWidgetWrapper::parameterType() const
383 {
385 }
386 
387 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingCrsWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
388 {
389  return new QgsProcessingCrsWidgetWrapper( parameter, type );
390 }
391 
392 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingCrsWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
393 {
394  return new QgsProcessingCrsParameterDefinitionWidget( context, widgetContext, definition, algorithm );
395 }
396 
397 
398 
399 //
400 // QgsProcessingStringWidgetWrapper
401 //
402 
403 
404 QgsProcessingStringParameterDefinitionWidget::QgsProcessingStringParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
405  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
406 {
407  QVBoxLayout *vlayout = new QVBoxLayout();
408  vlayout->setMargin( 0 );
409  vlayout->setContentsMargins( 0, 0, 0, 0 );
410 
411  vlayout->addWidget( new QLabel( tr( "Default value" ) ) );
412 
413  mDefaultLineEdit = new QLineEdit();
414  if ( const QgsProcessingParameterString *stringParam = dynamic_cast<const QgsProcessingParameterString *>( definition ) )
415  mDefaultLineEdit->setText( QgsProcessingParameters::parameterAsString( stringParam, stringParam->defaultValue(), context ) );
416  vlayout->addWidget( mDefaultLineEdit );
417 
418  mMultiLineCheckBox = new QCheckBox( tr( "Multiline input" ) );
419  if ( const QgsProcessingParameterString *stringParam = dynamic_cast<const QgsProcessingParameterString *>( definition ) )
420  mMultiLineCheckBox->setChecked( stringParam->multiLine() );
421  vlayout->addWidget( mMultiLineCheckBox );
422 
423  setLayout( vlayout );
424 }
425 
426 QgsProcessingParameterDefinition *QgsProcessingStringParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
427 {
428  auto param = qgis::make_unique< QgsProcessingParameterString >( name, description, mDefaultLineEdit->text(), mMultiLineCheckBox->isChecked() );
429  param->setFlags( flags );
430  return param.release();
431 }
432 
433 
434 
435 QgsProcessingStringWidgetWrapper::QgsProcessingStringWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
436  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
437 {
438 
439 }
440 
441 QWidget *QgsProcessingStringWidgetWrapper::createWidget()
442 {
443  switch ( type() )
444  {
447  {
448  if ( static_cast< const QgsProcessingParameterString * >( parameterDefinition() )->multiLine() )
449  {
450  mPlainTextEdit = new QPlainTextEdit();
451  mPlainTextEdit->setToolTip( parameterDefinition()->toolTip() );
452 
453  connect( mPlainTextEdit, &QPlainTextEdit::textChanged, this, [ = ]
454  {
455  emit widgetValueHasChanged( this );
456  } );
457  return mPlainTextEdit;
458  }
459  else
460  {
461  mLineEdit = new QLineEdit();
462  mLineEdit->setToolTip( parameterDefinition()->toolTip() );
463 
464  connect( mLineEdit, &QLineEdit::textChanged, this, [ = ]
465  {
466  emit widgetValueHasChanged( this );
467  } );
468  return mLineEdit;
469  }
470  }
471 
473  {
474  mLineEdit = new QLineEdit();
475  mLineEdit->setToolTip( parameterDefinition()->toolTip() );
476 
477  connect( mLineEdit, &QLineEdit::textChanged, this, [ = ]
478  {
479  emit widgetValueHasChanged( this );
480  } );
481  return mLineEdit;
482  }
483  }
484  return nullptr;
485 }
486 
487 void QgsProcessingStringWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
488 {
489  const QString v = QgsProcessingParameters::parameterAsString( parameterDefinition(), value, context );
490  if ( mLineEdit )
491  mLineEdit->setText( v );
492  if ( mPlainTextEdit )
493  mPlainTextEdit->setPlainText( v );
494 }
495 
496 QVariant QgsProcessingStringWidgetWrapper::widgetValue() const
497 {
498  if ( mLineEdit )
499  return mLineEdit->text();
500  else if ( mPlainTextEdit )
501  return mPlainTextEdit->toPlainText();
502  else
503  return QVariant();
504 }
505 
506 QStringList QgsProcessingStringWidgetWrapper::compatibleParameterTypes() const
507 {
508  return QStringList()
519 }
520 
521 QStringList QgsProcessingStringWidgetWrapper::compatibleOutputTypes() const
522 {
523  return QStringList() << QgsProcessingOutputNumber::typeName()
527 }
528 
529 QString QgsProcessingStringWidgetWrapper::parameterType() const
530 {
532 }
533 
534 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingStringWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
535 {
536  return new QgsProcessingStringWidgetWrapper( parameter, type );
537 }
538 
539 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingStringWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
540 {
541  return new QgsProcessingStringParameterDefinitionWidget( context, widgetContext, definition, algorithm );
542 }
543 
544 
545 
546 //
547 // QgsProcessingAuthConfigWidgetWrapper
548 //
549 
550 QgsProcessingAuthConfigWidgetWrapper::QgsProcessingAuthConfigWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
551  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
552 {
553 
554 }
555 
556 QWidget *QgsProcessingAuthConfigWidgetWrapper::createWidget()
557 {
558  switch ( type() )
559  {
563  {
564  mAuthConfigSelect = new QgsAuthConfigSelect();
565  mAuthConfigSelect->setToolTip( parameterDefinition()->toolTip() );
566 
567  connect( mAuthConfigSelect, &QgsAuthConfigSelect::selectedConfigIdChanged, this, [ = ]
568  {
569  emit widgetValueHasChanged( this );
570  } );
571  return mAuthConfigSelect;
572  }
573  }
574  return nullptr;
575 }
576 
577 void QgsProcessingAuthConfigWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
578 {
579  const QString v = QgsProcessingParameters::parameterAsString( parameterDefinition(), value, context );
580  if ( mAuthConfigSelect )
581  mAuthConfigSelect->setConfigId( v );
582 }
583 
584 QVariant QgsProcessingAuthConfigWidgetWrapper::widgetValue() const
585 {
586  if ( mAuthConfigSelect )
587  return mAuthConfigSelect->configId();
588  else
589  return QVariant();
590 }
591 
592 QStringList QgsProcessingAuthConfigWidgetWrapper::compatibleParameterTypes() const
593 {
594  return QStringList()
598 }
599 
600 QStringList QgsProcessingAuthConfigWidgetWrapper::compatibleOutputTypes() const
601 {
602  return QStringList() << QgsProcessingOutputString::typeName();
603 }
604 
605 QString QgsProcessingAuthConfigWidgetWrapper::parameterType() const
606 {
608 }
609 
610 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingAuthConfigWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
611 {
612  return new QgsProcessingAuthConfigWidgetWrapper( parameter, type );
613 }
614 
615 //
616 // QgsProcessingNumericWidgetWrapper
617 //
618 
619 QgsProcessingNumberParameterDefinitionWidget::QgsProcessingNumberParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
620  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
621 {
622  QVBoxLayout *vlayout = new QVBoxLayout();
623  vlayout->setMargin( 0 );
624  vlayout->setContentsMargins( 0, 0, 0, 0 );
625 
626  vlayout->addWidget( new QLabel( tr( "Number type" ) ) );
627 
628  mTypeComboBox = new QComboBox();
629  mTypeComboBox->addItem( tr( "Float" ), QgsProcessingParameterNumber::Double );
630  mTypeComboBox->addItem( tr( "Integer" ), QgsProcessingParameterNumber::Integer );
631  vlayout->addWidget( mTypeComboBox );
632 
633  vlayout->addWidget( new QLabel( tr( "Minimum value" ) ) );
634  mMinLineEdit = new QLineEdit();
635  vlayout->addWidget( mMinLineEdit );
636 
637  vlayout->addWidget( new QLabel( tr( "Maximum value" ) ) );
638  mMaxLineEdit = new QLineEdit();
639  vlayout->addWidget( mMaxLineEdit );
640 
641  vlayout->addWidget( new QLabel( tr( "Default value" ) ) );
642  mDefaultLineEdit = new QLineEdit();
643  vlayout->addWidget( mDefaultLineEdit );
644 
645  if ( const QgsProcessingParameterNumber *numberParam = dynamic_cast<const QgsProcessingParameterNumber *>( definition ) )
646  {
647  mTypeComboBox->setCurrentIndex( mTypeComboBox->findData( numberParam->dataType() ) );
648  mMinLineEdit->setText( QString::number( numberParam->minimum() ) );
649  mMaxLineEdit->setText( QString::number( numberParam->maximum() ) );
650  mDefaultLineEdit->setText( numberParam->defaultValue().toString() );
651  }
652 
653  setLayout( vlayout );
654 }
655 
656 QgsProcessingParameterDefinition *QgsProcessingNumberParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
657 {
658  bool ok;
659  double val = mDefaultLineEdit->text().toDouble( &ok );
660 
661  QgsProcessingParameterNumber::Type dataType = static_cast< QgsProcessingParameterNumber::Type >( mTypeComboBox->currentData().toInt() );
662  auto param = qgis::make_unique< QgsProcessingParameterNumber >( name, description, dataType, ok ? val : QVariant() );
663 
664  val = mMinLineEdit->text().toDouble( &ok );
665  if ( ok )
666  {
667  param->setMinimum( val );
668  }
669 
670  val = mMaxLineEdit->text().toDouble( &ok );
671  if ( ok )
672  {
673  param->setMaximum( val );
674  }
675 
676  param->setFlags( flags );
677  return param.release();
678 }
679 
680 QgsProcessingNumericWidgetWrapper::QgsProcessingNumericWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
681  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
682 {
683 
684 }
685 
686 QWidget *QgsProcessingNumericWidgetWrapper::createWidget()
687 {
688  const QgsProcessingParameterNumber *numberDef = static_cast< const QgsProcessingParameterNumber * >( parameterDefinition() );
689  const QVariantMap metadata = numberDef->metadata();
690  const int decimals = metadata.value( QStringLiteral( "widget_wrapper" ) ).toMap().value( QStringLiteral( "decimals" ), 6 ).toInt();
691  switch ( type() )
692  {
696  {
697  // lots of duplicate code here -- but there's no common interface between QSpinBox/QDoubleSpinBox which would allow us to avoid this
698  QAbstractSpinBox *spinBox = nullptr;
699  switch ( numberDef->dataType() )
700  {
702  mDoubleSpinBox = new QgsDoubleSpinBox();
703  mDoubleSpinBox->setExpressionsEnabled( true );
704  mDoubleSpinBox->setDecimals( decimals );
705 
706  // guess reasonable step value for double spin boxes
707  if ( !qgsDoubleNear( numberDef->maximum(), std::numeric_limits<double>::max() ) &&
708  !qgsDoubleNear( numberDef->minimum(), std::numeric_limits<double>::lowest() + 1 ) )
709  {
710  double singleStep = calculateStep( numberDef->minimum(), numberDef->maximum() );
711  singleStep = std::max( singleStep, std::pow( 10, -decimals ) );
712  mDoubleSpinBox->setSingleStep( singleStep );
713  }
714 
715  spinBox = mDoubleSpinBox;
716  break;
717 
719  mSpinBox = new QgsSpinBox();
720  mSpinBox->setExpressionsEnabled( true );
721  spinBox = mSpinBox;
722  break;
723  }
724  spinBox->setToolTip( parameterDefinition()->toolTip() );
725 
726  double max = 999999999;
727  if ( !qgsDoubleNear( numberDef->maximum(), std::numeric_limits<double>::max() ) )
728  {
729  max = numberDef->maximum();
730  }
731  double min = -999999999;
732  if ( !qgsDoubleNear( numberDef->minimum(), std::numeric_limits<double>::lowest() ) )
733  {
734  min = numberDef->minimum();
735  }
736  if ( mDoubleSpinBox )
737  {
738  mDoubleSpinBox->setMinimum( min );
739  mDoubleSpinBox->setMaximum( max );
740  }
741  else
742  {
743  mSpinBox->setMinimum( static_cast< int >( min ) );
744  mSpinBox->setMaximum( static_cast< int >( max ) );
745  }
746 
748  {
749  mAllowingNull = true;
750  if ( mDoubleSpinBox )
751  {
752  mDoubleSpinBox->setShowClearButton( true );
753  const double min = mDoubleSpinBox->minimum() - 1;
754  mDoubleSpinBox->setMinimum( min );
755  mDoubleSpinBox->setValue( min );
756  }
757  else
758  {
759  mSpinBox->setShowClearButton( true );
760  const int min = mSpinBox->minimum() - 1;
761  mSpinBox->setMinimum( min );
762  mSpinBox->setValue( min );
763  }
764  spinBox->setSpecialValueText( tr( "Not set" ) );
765  }
766  else
767  {
768  if ( numberDef->defaultValue().isValid() )
769  {
770  // if default value for parameter, we clear to that
771  bool ok = false;
772  if ( mDoubleSpinBox )
773  {
774  double defaultVal = numberDef->defaultValue().toDouble( &ok );
775  if ( ok )
776  mDoubleSpinBox->setClearValue( defaultVal );
777  }
778  else
779  {
780  int intVal = numberDef->defaultValue().toInt( &ok );
781  if ( ok )
782  mSpinBox->setClearValue( intVal );
783  }
784  }
785  else if ( !qgsDoubleNear( numberDef->minimum(), std::numeric_limits<double>::lowest() ) )
786  {
787  // otherwise we clear to the minimum, if it's set
788  if ( mDoubleSpinBox )
789  mDoubleSpinBox->setClearValue( numberDef->minimum() );
790  else
791  mSpinBox->setClearValue( static_cast< int >( numberDef->minimum() ) );
792  }
793  else
794  {
795  // last resort, we clear to 0
796  if ( mDoubleSpinBox )
797  {
798  mDoubleSpinBox->setValue( 0 );
799  mDoubleSpinBox->setClearValue( 0 );
800  }
801  else
802  {
803  mSpinBox->setValue( 0 );
804  mSpinBox->setClearValue( 0 );
805  }
806  }
807  }
808 
809  if ( mDoubleSpinBox )
810  connect( mDoubleSpinBox, qgis::overload<double>::of( &QgsDoubleSpinBox::valueChanged ), this, [ = ] { emit widgetValueHasChanged( this ); } );
811  else if ( mSpinBox )
812  connect( mSpinBox, qgis::overload<int>::of( &QgsSpinBox::valueChanged ), this, [ = ] { emit widgetValueHasChanged( this ); } );
813 
814  return spinBox;
815  }
816  }
817  return nullptr;
818 }
819 
820 void QgsProcessingNumericWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
821 {
822  if ( mDoubleSpinBox )
823  {
824  if ( mAllowingNull && !value.isValid() )
825  mDoubleSpinBox->clear();
826  else
827  {
828  const double v = QgsProcessingParameters::parameterAsDouble( parameterDefinition(), value, context );
829  mDoubleSpinBox->setValue( v );
830  }
831  }
832  else if ( mSpinBox )
833  {
834  if ( mAllowingNull && !value.isValid() )
835  mSpinBox->clear();
836  else
837  {
838  const int v = QgsProcessingParameters::parameterAsInt( parameterDefinition(), value, context );
839  mSpinBox->setValue( v );
840  }
841  }
842 }
843 
844 QVariant QgsProcessingNumericWidgetWrapper::widgetValue() const
845 {
846  if ( mDoubleSpinBox )
847  {
848  if ( mAllowingNull && qgsDoubleNear( mDoubleSpinBox->value(), mDoubleSpinBox->minimum() ) )
849  return QVariant();
850  else
851  return mDoubleSpinBox->value();
852  }
853  else if ( mSpinBox )
854  {
855  if ( mAllowingNull && mSpinBox->value() == mSpinBox->minimum() )
856  return QVariant();
857  else
858  return mSpinBox->value();
859  }
860  else
861  return QVariant();
862 }
863 
864 QStringList QgsProcessingNumericWidgetWrapper::compatibleParameterTypes() const
865 {
866  return QStringList()
871 }
872 
873 QStringList QgsProcessingNumericWidgetWrapper::compatibleOutputTypes() const
874 {
875  return QStringList() << QgsProcessingOutputNumber::typeName()
877 }
878 
879 double QgsProcessingNumericWidgetWrapper::calculateStep( const double minimum, const double maximum )
880 {
881  const double valueRange = maximum - minimum;
882  if ( valueRange <= 1.0 )
883  {
884  const double step = valueRange / 10.0;
885  // round to 1 significant figure
886  return qgsRound( step, -std::floor( std::log( step ) ) );
887  }
888  else
889  {
890  return 1.0;
891  }
892 }
893 
894 QString QgsProcessingNumericWidgetWrapper::parameterType() const
895 {
897 }
898 
899 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingNumericWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
900 {
901  return new QgsProcessingNumericWidgetWrapper( parameter, type );
902 }
903 
904 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingNumericWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
905 {
906  return new QgsProcessingNumberParameterDefinitionWidget( context, widgetContext, definition, algorithm );
907 }
908 
909 //
910 // QgsProcessingDistanceWidgetWrapper
911 //
912 
913 QgsProcessingDistanceParameterDefinitionWidget::QgsProcessingDistanceParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
914  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
915 {
916  QVBoxLayout *vlayout = new QVBoxLayout();
917  vlayout->setMargin( 0 );
918  vlayout->setContentsMargins( 0, 0, 0, 0 );
919 
920  vlayout->addWidget( new QLabel( tr( "Linked input" ) ) );
921 
922  mParentLayerComboBox = new QComboBox();
923 
924  QString initialParent;
925  if ( const QgsProcessingParameterDistance *distParam = dynamic_cast<const QgsProcessingParameterDistance *>( definition ) )
926  initialParent = distParam->parentParameterName();
927 
928  if ( widgetContext.model() )
929  {
930  // populate combo box with other model input choices
931  const QMap<QString, QgsProcessingModelParameter> components = widgetContext.model()->parameterComponents();
932  for ( auto it = components.constBegin(); it != components.constEnd(); ++it )
933  {
934  if ( const QgsProcessingParameterFeatureSource *definition = dynamic_cast< const QgsProcessingParameterFeatureSource * >( widgetContext.model()->parameterDefinition( it.value().parameterName() ) ) )
935  {
936  mParentLayerComboBox-> addItem( definition->description(), definition->name() );
937  if ( !initialParent.isEmpty() && initialParent == definition->name() )
938  {
939  mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
940  }
941  }
942  else if ( const QgsProcessingParameterVectorLayer *definition = dynamic_cast< const QgsProcessingParameterVectorLayer * >( widgetContext.model()->parameterDefinition( it.value().parameterName() ) ) )
943  {
944  mParentLayerComboBox-> addItem( definition->description(), definition->name() );
945  if ( !initialParent.isEmpty() && initialParent == definition->name() )
946  {
947  mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
948  }
949  }
950  else if ( const QgsProcessingParameterMapLayer *definition = dynamic_cast< const QgsProcessingParameterMapLayer * >( widgetContext.model()->parameterDefinition( it.value().parameterName() ) ) )
951  {
952  mParentLayerComboBox-> addItem( definition->description(), definition->name() );
953  if ( !initialParent.isEmpty() && initialParent == definition->name() )
954  {
955  mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
956  }
957  }
958  else if ( const QgsProcessingParameterCrs *definition = dynamic_cast< const QgsProcessingParameterCrs * >( widgetContext.model()->parameterDefinition( it.value().parameterName() ) ) )
959  {
960  mParentLayerComboBox-> addItem( definition->description(), definition->name() );
961  if ( !initialParent.isEmpty() && initialParent == definition->name() )
962  {
963  mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
964  }
965  }
966  }
967  }
968 
969  if ( mParentLayerComboBox->count() == 0 && !initialParent.isEmpty() )
970  {
971  // if no parent candidates found, we just add the existing one as a placeholder
972  mParentLayerComboBox->addItem( initialParent, initialParent );
973  mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
974  }
975 
976  vlayout->addWidget( mParentLayerComboBox );
977 
978  vlayout->addWidget( new QLabel( tr( "Minimum value" ) ) );
979  mMinLineEdit = new QLineEdit();
980  vlayout->addWidget( mMinLineEdit );
981 
982  vlayout->addWidget( new QLabel( tr( "Maximum value" ) ) );
983  mMaxLineEdit = new QLineEdit();
984  vlayout->addWidget( mMaxLineEdit );
985 
986  vlayout->addWidget( new QLabel( tr( "Default value" ) ) );
987  mDefaultLineEdit = new QLineEdit();
988  vlayout->addWidget( mDefaultLineEdit );
989 
990  if ( const QgsProcessingParameterDistance *distParam = dynamic_cast<const QgsProcessingParameterDistance *>( definition ) )
991  {
992  mMinLineEdit->setText( QString::number( distParam->minimum() ) );
993  mMaxLineEdit->setText( QString::number( distParam->maximum() ) );
994  mDefaultLineEdit->setText( distParam->defaultValue().toString() );
995  }
996 
997  setLayout( vlayout );
998 }
999 
1000 QgsProcessingParameterDefinition *QgsProcessingDistanceParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
1001 {
1002  bool ok;
1003  double val = mDefaultLineEdit->text().toDouble( &ok );
1004 
1005  auto param = qgis::make_unique< QgsProcessingParameterDistance >( name, description, ok ? val : QVariant(), mParentLayerComboBox->currentData().toString() );
1006 
1007  val = mMinLineEdit->text().toDouble( &ok );
1008  if ( ok )
1009  {
1010  param->setMinimum( val );
1011  }
1012 
1013  val = mMaxLineEdit->text().toFloat( &ok );
1014  if ( ok )
1015  {
1016  param->setMaximum( val );
1017  }
1018 
1019  param->setFlags( flags );
1020  return param.release();
1021 }
1022 
1023 QgsProcessingDistanceWidgetWrapper::QgsProcessingDistanceWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
1024  : QgsProcessingNumericWidgetWrapper( parameter, type, parent )
1025 {
1026 
1027 }
1028 
1029 QString QgsProcessingDistanceWidgetWrapper::parameterType() const
1030 {
1032 }
1033 
1034 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingDistanceWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
1035 {
1036  return new QgsProcessingDistanceWidgetWrapper( parameter, type );
1037 }
1038 
1039 QWidget *QgsProcessingDistanceWidgetWrapper::createWidget()
1040 {
1041  const QgsProcessingParameterDistance *distanceDef = static_cast< const QgsProcessingParameterDistance * >( parameterDefinition() );
1042 
1043  QWidget *spin = QgsProcessingNumericWidgetWrapper::createWidget();
1044  switch ( type() )
1045  {
1047  {
1048  mLabel = new QLabel();
1049  mUnitsCombo = new QComboBox();
1050 
1056 
1057 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
1058  const int labelMargin = static_cast< int >( std::round( mUnitsCombo->fontMetrics().width( 'X' ) ) );
1059 #else
1060  const int labelMargin = static_cast< int >( std::round( mUnitsCombo->fontMetrics().horizontalAdvance( 'X' ) ) );
1061 #endif
1062  QHBoxLayout *layout = new QHBoxLayout();
1063  layout->addWidget( spin, 1 );
1064  layout->insertSpacing( 1, labelMargin / 2 );
1065  layout->insertWidget( 2, mLabel );
1066  layout->insertWidget( 3, mUnitsCombo );
1067 
1068  // bit of fiddlyness here -- we want the initial spacing to only be visible
1069  // when the warning label is shown, so it's embedded inside mWarningLabel
1070  // instead of outside it
1071  mWarningLabel = new QWidget();
1072  QHBoxLayout *warningLayout = new QHBoxLayout();
1073  warningLayout->setMargin( 0 );
1074  warningLayout->setContentsMargins( 0, 0, 0, 0 );
1075  QLabel *warning = new QLabel();
1076  QIcon icon = QgsApplication::getThemeIcon( QStringLiteral( "mIconWarning.svg" ) );
1077  const int size = static_cast< int >( std::max( 24.0, spin->minimumSize().height() * 0.5 ) );
1078  warning->setPixmap( icon.pixmap( icon.actualSize( QSize( size, size ) ) ) );
1079  warning->setToolTip( tr( "Distance is in geographic degrees. Consider reprojecting to a projected local coordinate system for accurate results." ) );
1080  warningLayout->insertSpacing( 0, labelMargin / 2 );
1081  warningLayout->insertWidget( 1, warning );
1082  mWarningLabel->setLayout( warningLayout );
1083  layout->insertWidget( 4, mWarningLabel );
1084 
1085  QWidget *w = new QWidget();
1086  layout->setMargin( 0 );
1087  layout->setContentsMargins( 0, 0, 0, 0 );
1088  w->setLayout( layout );
1089 
1090  setUnits( distanceDef->defaultUnit() );
1091 
1092  return w;
1093  }
1094 
1097  return spin;
1098 
1099  }
1100  return nullptr;
1101 }
1102 
1103 void QgsProcessingDistanceWidgetWrapper::postInitialize( const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
1104 {
1105  QgsProcessingNumericWidgetWrapper::postInitialize( wrappers );
1106  switch ( type() )
1107  {
1109  {
1110  for ( const QgsAbstractProcessingParameterWidgetWrapper *wrapper : wrappers )
1111  {
1112  if ( wrapper->parameterDefinition()->name() == static_cast< const QgsProcessingParameterDistance * >( parameterDefinition() )->parentParameterName() )
1113  {
1114  setUnitParameterValue( wrapper->parameterValue() );
1116  {
1117  setUnitParameterValue( wrapper->parameterValue() );
1118  } );
1119  break;
1120  }
1121  }
1122  break;
1123  }
1124 
1127  break;
1128  }
1129 }
1130 
1131 void QgsProcessingDistanceWidgetWrapper::setUnitParameterValue( const QVariant &value )
1132 {
1134 
1135  // evaluate value to layer
1136  QgsProcessingContext *context = nullptr;
1137  std::unique_ptr< QgsProcessingContext > tmpContext;
1138  if ( mProcessingContextGenerator )
1139  context = mProcessingContextGenerator->processingContext();
1140 
1141  if ( !context )
1142  {
1143  tmpContext = qgis::make_unique< QgsProcessingContext >();
1144  context = tmpContext.get();
1145  }
1146 
1147  QgsCoordinateReferenceSystem crs = QgsProcessingParameters::parameterAsCrs( parameterDefinition(), value, *context );
1148  if ( crs.isValid() )
1149  {
1150  units = crs.mapUnits();
1151  }
1152 
1153  setUnits( units );
1154 }
1155 
1156 void QgsProcessingDistanceWidgetWrapper::setUnits( const QgsUnitTypes::DistanceUnit units )
1157 {
1158  mLabel->setText( QgsUnitTypes::toString( units ) );
1160  {
1161  mUnitsCombo->hide();
1162  mLabel->show();
1163  }
1164  else
1165  {
1166  mUnitsCombo->setCurrentIndex( mUnitsCombo->findData( units ) );
1167  mUnitsCombo->show();
1168  mLabel->hide();
1169  }
1170  mWarningLabel->setVisible( units == QgsUnitTypes::DistanceDegrees );
1171  mBaseUnit = units;
1172 }
1173 
1174 QVariant QgsProcessingDistanceWidgetWrapper::widgetValue() const
1175 {
1176  const QVariant val = QgsProcessingNumericWidgetWrapper::widgetValue();
1177  if ( val.type() == QVariant::Double && mUnitsCombo && mUnitsCombo->isVisible() )
1178  {
1179  QgsUnitTypes::DistanceUnit displayUnit = static_cast<QgsUnitTypes::DistanceUnit >( mUnitsCombo->currentData().toInt() );
1180  return val.toDouble() * QgsUnitTypes::fromUnitToUnitFactor( displayUnit, mBaseUnit );
1181  }
1182  else
1183  {
1184  return val;
1185  }
1186 }
1187 
1188 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingDistanceWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
1189 {
1190  return new QgsProcessingDistanceParameterDefinitionWidget( context, widgetContext, definition, algorithm );
1191 }
1192 
1193 //
1194 // QgsProcessingScaleWidgetWrapper
1195 //
1196 
1197 QgsProcessingScaleParameterDefinitionWidget::QgsProcessingScaleParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
1198  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
1199 {
1200  QVBoxLayout *vlayout = new QVBoxLayout();
1201  vlayout->setMargin( 0 );
1202  vlayout->setContentsMargins( 0, 0, 0, 0 );
1203 
1204  vlayout->addWidget( new QLabel( tr( "Default value" ) ) );
1205 
1206  mDefaultLineEdit = new QLineEdit();
1207 
1208  if ( const QgsProcessingParameterScale *scaleParam = dynamic_cast<const QgsProcessingParameterScale *>( definition ) )
1209  {
1210  mDefaultLineEdit->setText( scaleParam->defaultValue().toString() );
1211  }
1212 
1213  vlayout->addWidget( mDefaultLineEdit );
1214 
1215  setLayout( vlayout );
1216 }
1217 
1218 QgsProcessingParameterDefinition *QgsProcessingScaleParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
1219 {
1220  bool ok;
1221  double val = mDefaultLineEdit->text().toDouble( &ok );
1222  auto param = qgis::make_unique< QgsProcessingParameterScale >( name, description, ok ? val : QVariant() );
1223  param->setFlags( flags );
1224  return param.release();
1225 }
1226 
1227 QgsProcessingScaleWidgetWrapper::QgsProcessingScaleWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
1228  : QgsProcessingNumericWidgetWrapper( parameter, type, parent )
1229 {
1230 
1231 }
1232 
1233 QString QgsProcessingScaleWidgetWrapper::parameterType() const
1234 {
1236 }
1237 
1238 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingScaleWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
1239 {
1240  return new QgsProcessingScaleWidgetWrapper( parameter, type );
1241 }
1242 
1243 QWidget *QgsProcessingScaleWidgetWrapper::createWidget()
1244 {
1245  const QgsProcessingParameterScale *scaleDef = static_cast< const QgsProcessingParameterScale * >( parameterDefinition() );
1246 
1247  switch ( type() )
1248  {
1252  {
1253  mScaleWidget = new QgsScaleWidget( nullptr );
1255  mScaleWidget->setAllowNull( true );
1256 
1257  mScaleWidget->setMapCanvas( widgetContext().mapCanvas() );
1258  mScaleWidget->setShowCurrentScaleButton( true );
1259 
1260  mScaleWidget->setToolTip( parameterDefinition()->toolTip() );
1261  connect( mScaleWidget, &QgsScaleWidget::scaleChanged, this, [ = ]( double )
1262  {
1263  emit widgetValueHasChanged( this );
1264  } );
1265  return mScaleWidget;
1266  }
1267  }
1268  return nullptr;
1269 }
1270 
1271 void QgsProcessingScaleWidgetWrapper::setWidgetContext( const QgsProcessingParameterWidgetContext &context )
1272 {
1273  if ( mScaleWidget )
1274  mScaleWidget->setMapCanvas( context.mapCanvas() );
1276 }
1277 
1278 
1279 QVariant QgsProcessingScaleWidgetWrapper::widgetValue() const
1280 {
1281  return mScaleWidget && !mScaleWidget->isNull() ? QVariant( mScaleWidget->scale() ) : QVariant();
1282 }
1283 
1284 void QgsProcessingScaleWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
1285 {
1286  if ( mScaleWidget )
1287  {
1288  if ( mScaleWidget->allowNull() && !value.isValid() )
1289  mScaleWidget->setNull();
1290  else
1291  {
1292  const double v = QgsProcessingParameters::parameterAsDouble( parameterDefinition(), value, context );
1293  mScaleWidget->setScale( v );
1294  }
1295  }
1296 }
1297 
1298 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingScaleWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
1299 {
1300  return new QgsProcessingScaleParameterDefinitionWidget( context, widgetContext, definition, algorithm );
1301 }
1302 
1303 
1304 //
1305 // QgsProcessingRangeWidgetWrapper
1306 //
1307 
1308 QgsProcessingRangeParameterDefinitionWidget::QgsProcessingRangeParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
1309  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
1310 {
1311  QVBoxLayout *vlayout = new QVBoxLayout();
1312  vlayout->setMargin( 0 );
1313  vlayout->setContentsMargins( 0, 0, 0, 0 );
1314 
1315  vlayout->addWidget( new QLabel( tr( "Number type" ) ) );
1316 
1317  mTypeComboBox = new QComboBox();
1318  mTypeComboBox->addItem( tr( "Float" ), QgsProcessingParameterNumber::Double );
1319  mTypeComboBox->addItem( tr( "Integer" ), QgsProcessingParameterNumber::Integer );
1320  vlayout->addWidget( mTypeComboBox );
1321 
1322  vlayout->addWidget( new QLabel( tr( "Minimum value" ) ) );
1323  mMinLineEdit = new QLineEdit();
1324  vlayout->addWidget( mMinLineEdit );
1325 
1326  vlayout->addWidget( new QLabel( tr( "Maximum value" ) ) );
1327  mMaxLineEdit = new QLineEdit();
1328  vlayout->addWidget( mMaxLineEdit );
1329 
1330  if ( const QgsProcessingParameterRange *rangeParam = dynamic_cast<const QgsProcessingParameterRange *>( definition ) )
1331  {
1332  mTypeComboBox->setCurrentIndex( mTypeComboBox->findData( rangeParam->dataType() ) );
1333  const QList< double > range = QgsProcessingParameters::parameterAsRange( rangeParam, rangeParam->defaultValue(), context );
1334  mMinLineEdit->setText( QString::number( range.at( 0 ) ) );
1335  mMaxLineEdit->setText( QString::number( range.at( 1 ) ) );
1336  }
1337 
1338  setLayout( vlayout );
1339 }
1340 
1341 QgsProcessingParameterDefinition *QgsProcessingRangeParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
1342 {
1343  QString defaultValue;
1344  if ( mMinLineEdit->text().isEmpty() )
1345  {
1346  defaultValue = QStringLiteral( "None" );
1347  }
1348  else
1349  {
1350  defaultValue = mMinLineEdit->text();
1351  }
1352 
1353  if ( mMaxLineEdit->text().isEmpty() )
1354  {
1355  defaultValue += QStringLiteral( ",None" );
1356  }
1357  else
1358  {
1359  defaultValue += QStringLiteral( "," ) + mMaxLineEdit->text();
1360  }
1361 
1362  QgsProcessingParameterNumber::Type dataType = static_cast< QgsProcessingParameterNumber::Type >( mTypeComboBox->currentData().toInt() );
1363  auto param = qgis::make_unique< QgsProcessingParameterRange >( name, description, dataType, defaultValue );
1364  param->setFlags( flags );
1365  return param.release();
1366 }
1367 
1368 
1369 QgsProcessingRangeWidgetWrapper::QgsProcessingRangeWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
1370  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
1371 {
1372 
1373 }
1374 
1375 QWidget *QgsProcessingRangeWidgetWrapper::createWidget()
1376 {
1377  const QgsProcessingParameterRange *rangeDef = static_cast< const QgsProcessingParameterRange * >( parameterDefinition() );
1378  switch ( type() )
1379  {
1383  {
1384  QHBoxLayout *layout = new QHBoxLayout();
1385 
1386  mMinSpinBox = new QgsDoubleSpinBox();
1387  mMaxSpinBox = new QgsDoubleSpinBox();
1388 
1389  mMinSpinBox->setExpressionsEnabled( true );
1390  mMinSpinBox->setShowClearButton( false );
1391  mMaxSpinBox->setExpressionsEnabled( true );
1392  mMaxSpinBox->setShowClearButton( false );
1393 
1394  QLabel *minLabel = new QLabel( tr( "Min" ) );
1395  layout->addWidget( minLabel );
1396  layout->addWidget( mMinSpinBox, 1 );
1397 
1398  QLabel *maxLabel = new QLabel( tr( "Max" ) );
1399  layout->addWidget( maxLabel );
1400  layout->addWidget( mMaxSpinBox, 1 );
1401 
1402  QWidget *w = new QWidget();
1403  layout->setMargin( 0 );
1404  layout->setContentsMargins( 0, 0, 0, 0 );
1405  w->setLayout( layout );
1406 
1407  if ( rangeDef->dataType() == QgsProcessingParameterNumber::Double )
1408  {
1409  mMinSpinBox->setDecimals( 6 );
1410  mMaxSpinBox->setDecimals( 6 );
1411  }
1412  else
1413  {
1414  mMinSpinBox->setDecimals( 0 );
1415  mMaxSpinBox->setDecimals( 0 );
1416  }
1417 
1418  mMinSpinBox->setMinimum( -99999999.999999 );
1419  mMaxSpinBox->setMinimum( -99999999.999999 );
1420  mMinSpinBox->setMaximum( 99999999.999999 );
1421  mMaxSpinBox->setMaximum( 99999999.999999 );
1422 
1424  {
1425  mAllowingNull = true;
1426 
1427  const double min = mMinSpinBox->minimum() - 1;
1428  mMinSpinBox->setMinimum( min );
1429  mMaxSpinBox->setMinimum( min );
1430  mMinSpinBox->setValue( min );
1431  mMaxSpinBox->setValue( min );
1432 
1433  mMinSpinBox->setShowClearButton( true );
1434  mMaxSpinBox->setShowClearButton( true );
1435  mMinSpinBox->setSpecialValueText( tr( "Not set" ) );
1436  mMaxSpinBox->setSpecialValueText( tr( "Not set" ) );
1437  }
1438 
1439  w->setToolTip( parameterDefinition()->toolTip() );
1440 
1441  connect( mMinSpinBox, qgis::overload<double>::of( &QgsDoubleSpinBox::valueChanged ), this, [ = ]( const double v )
1442  {
1443  mBlockChangedSignal++;
1444  if ( !mAllowingNull && v > mMaxSpinBox->value() )
1445  mMaxSpinBox->setValue( v );
1446  mBlockChangedSignal--;
1447 
1448  if ( !mBlockChangedSignal )
1449  emit widgetValueHasChanged( this );
1450  } );
1451  connect( mMaxSpinBox, qgis::overload<double>::of( &QgsDoubleSpinBox::valueChanged ), this, [ = ]( const double v )
1452  {
1453  mBlockChangedSignal++;
1454  if ( !mAllowingNull && v < mMinSpinBox->value() )
1455  mMinSpinBox->setValue( v );
1456  mBlockChangedSignal--;
1457 
1458  if ( !mBlockChangedSignal )
1459  emit widgetValueHasChanged( this );
1460  } );
1461 
1462  return w;
1463  }
1464  }
1465  return nullptr;
1466 }
1467 
1468 void QgsProcessingRangeWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
1469 {
1470  const QList< double > v = QgsProcessingParameters::parameterAsRange( parameterDefinition(), value, context );
1471  if ( mAllowingNull && v.empty() )
1472  {
1473  mMinSpinBox->clear();
1474  mMaxSpinBox->clear();
1475  }
1476  else
1477  {
1478  if ( v.empty() )
1479  return;
1480 
1481  if ( mAllowingNull )
1482  {
1483  mBlockChangedSignal++;
1484  if ( std::isnan( v.at( 0 ) ) )
1485  mMinSpinBox->clear();
1486  else
1487  mMinSpinBox->setValue( v.at( 0 ) );
1488 
1489  if ( v.count() >= 2 )
1490  {
1491  if ( std::isnan( v.at( 1 ) ) )
1492  mMaxSpinBox->clear();
1493  else
1494  mMaxSpinBox->setValue( v.at( 1 ) );
1495  }
1496  mBlockChangedSignal--;
1497  }
1498  else
1499  {
1500  mBlockChangedSignal++;
1501  mMinSpinBox->setValue( v.at( 0 ) );
1502  if ( v.count() >= 2 )
1503  mMaxSpinBox->setValue( v.at( 1 ) );
1504  mBlockChangedSignal--;
1505  }
1506  }
1507 
1508  if ( !mBlockChangedSignal )
1509  emit widgetValueHasChanged( this );
1510 }
1511 
1512 QVariant QgsProcessingRangeWidgetWrapper::widgetValue() const
1513 {
1514  if ( mAllowingNull )
1515  {
1516  QString value;
1517  if ( qgsDoubleNear( mMinSpinBox->value(), mMinSpinBox->minimum() ) )
1518  value = QStringLiteral( "None" );
1519  else
1520  value = QStringLiteral( "%1" ).arg( mMinSpinBox->value() );
1521 
1522  if ( qgsDoubleNear( mMaxSpinBox->value(), mMaxSpinBox->minimum() ) )
1523  value += QStringLiteral( ",None" );
1524  else
1525  value += QStringLiteral( ",%1" ).arg( mMaxSpinBox->value() );
1526 
1527  return value;
1528  }
1529  else
1530  return QStringLiteral( "%1,%2" ).arg( mMinSpinBox->value() ).arg( mMaxSpinBox->value() );
1531 }
1532 
1533 QStringList QgsProcessingRangeWidgetWrapper::compatibleParameterTypes() const
1534 {
1535  return QStringList()
1538 }
1539 
1540 QStringList QgsProcessingRangeWidgetWrapper::compatibleOutputTypes() const
1541 {
1542  return QStringList() << QgsProcessingOutputString::typeName();
1543 }
1544 
1545 QString QgsProcessingRangeWidgetWrapper::modelerExpressionFormatString() const
1546 {
1547  return tr( "string as two comma delimited floats, e.g. '1,10'" );
1548 }
1549 
1550 QString QgsProcessingRangeWidgetWrapper::parameterType() const
1551 {
1553 }
1554 
1555 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingRangeWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
1556 {
1557  return new QgsProcessingRangeWidgetWrapper( parameter, type );
1558 }
1559 
1560 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingRangeWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
1561 {
1562  return new QgsProcessingRangeParameterDefinitionWidget( context, widgetContext, definition, algorithm );
1563 }
1564 
1565 
1566 //
1567 // QgsProcessingMatrixWidgetWrapper
1568 //
1569 
1570 QgsProcessingMatrixParameterDefinitionWidget::QgsProcessingMatrixParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
1571  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
1572 {
1573  QVBoxLayout *vlayout = new QVBoxLayout();
1574  vlayout->setMargin( 0 );
1575  vlayout->setContentsMargins( 0, 0, 0, 0 );
1576 
1577  mMatrixWidget = new QgsProcessingMatrixModelerWidget();
1578  if ( const QgsProcessingParameterMatrix *matrixParam = dynamic_cast<const QgsProcessingParameterMatrix *>( definition ) )
1579  {
1580  mMatrixWidget->setValue( matrixParam->headers(), matrixParam->defaultValue() );
1581  mMatrixWidget->setFixedRows( matrixParam->hasFixedNumberRows() );
1582  }
1583  vlayout->addWidget( mMatrixWidget );
1584  setLayout( vlayout );
1585 }
1586 
1587 QgsProcessingParameterDefinition *QgsProcessingMatrixParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
1588 {
1589  auto param = qgis::make_unique< QgsProcessingParameterMatrix >( name, description, 1, mMatrixWidget->fixedRows(), mMatrixWidget->headers(), mMatrixWidget->value() );
1590  param->setFlags( flags );
1591  return param.release();
1592 }
1593 
1594 
1595 QgsProcessingMatrixWidgetWrapper::QgsProcessingMatrixWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
1596  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
1597 {
1598 
1599 }
1600 
1601 QWidget *QgsProcessingMatrixWidgetWrapper::createWidget()
1602 {
1603  mMatrixWidget = new QgsProcessingMatrixParameterPanel( nullptr, dynamic_cast< const QgsProcessingParameterMatrix *>( parameterDefinition() ) );
1604  mMatrixWidget->setToolTip( parameterDefinition()->toolTip() );
1605 
1606  connect( mMatrixWidget, &QgsProcessingMatrixParameterPanel::changed, this, [ = ]
1607  {
1608  emit widgetValueHasChanged( this );
1609  } );
1610 
1611  switch ( type() )
1612  {
1616  {
1617  return mMatrixWidget;
1618  }
1619  }
1620  return nullptr;
1621 }
1622 
1623 void QgsProcessingMatrixWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
1624 {
1625  const QVariantList v = QgsProcessingParameters::parameterAsMatrix( parameterDefinition(), value, context );
1626  if ( mMatrixWidget )
1627  mMatrixWidget->setValue( v );
1628 }
1629 
1630 QVariant QgsProcessingMatrixWidgetWrapper::widgetValue() const
1631 {
1632  if ( mMatrixWidget )
1633  return mMatrixWidget->value().isEmpty() ? QVariant() : mMatrixWidget->value();
1634  else
1635  return QVariant();
1636 }
1637 
1638 QStringList QgsProcessingMatrixWidgetWrapper::compatibleParameterTypes() const
1639 {
1640  return QStringList()
1642 }
1643 
1644 QStringList QgsProcessingMatrixWidgetWrapper::compatibleOutputTypes() const
1645 {
1646  return QStringList();
1647 }
1648 
1649 QString QgsProcessingMatrixWidgetWrapper::modelerExpressionFormatString() const
1650 {
1651  return tr( "comma delimited string of values, or an array of values" );
1652 }
1653 
1654 QString QgsProcessingMatrixWidgetWrapper::parameterType() const
1655 {
1657 }
1658 
1659 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingMatrixWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
1660 {
1661  return new QgsProcessingMatrixWidgetWrapper( parameter, type );
1662 }
1663 
1664 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingMatrixWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
1665 {
1666  return new QgsProcessingMatrixParameterDefinitionWidget( context, widgetContext, definition, algorithm );
1667 }
1668 
1669 
1670 //
1671 // QgsProcessingFileWidgetWrapper
1672 //
1673 
1674 
1675 QgsProcessingFileParameterDefinitionWidget::QgsProcessingFileParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
1676  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
1677 {
1678  QVBoxLayout *vlayout = new QVBoxLayout();
1679  vlayout->setMargin( 0 );
1680  vlayout->setContentsMargins( 0, 0, 0, 0 );
1681 
1682  vlayout->addWidget( new QLabel( tr( "Type" ) ) );
1683 
1684  mTypeComboBox = new QComboBox();
1685  mTypeComboBox->addItem( tr( "File" ), QgsProcessingParameterFile::File );
1686  mTypeComboBox->addItem( tr( "Folder" ), QgsProcessingParameterFile::Folder );
1687  if ( const QgsProcessingParameterFile *fileParam = dynamic_cast<const QgsProcessingParameterFile *>( definition ) )
1688  mTypeComboBox->setCurrentIndex( mTypeComboBox->findData( fileParam->behavior() ) );
1689  else
1690  mTypeComboBox->setCurrentIndex( 0 );
1691  vlayout->addWidget( mTypeComboBox );
1692 
1693  vlayout->addWidget( new QLabel( tr( "File filter" ) ) );
1694 
1695  mFilterComboBox = new QComboBox();
1696  mFilterComboBox->setEditable( true );
1697  // add some standard ones -- these also act as a demonstration of the required format
1698  mFilterComboBox->addItem( tr( "All Files (*.*)" ) );
1699  mFilterComboBox->addItem( tr( "CSV Files (*.csv)" ) );
1700  mFilterComboBox->addItem( tr( "HTML Files (*.html *.htm)" ) );
1701  mFilterComboBox->addItem( tr( "Text Files (*.txt)" ) );
1702  if ( const QgsProcessingParameterFile *fileParam = dynamic_cast<const QgsProcessingParameterFile *>( definition ) )
1703  mFilterComboBox->setCurrentText( fileParam->fileFilter() );
1704  else
1705  mFilterComboBox->setCurrentIndex( 0 );
1706  vlayout->addWidget( mFilterComboBox );
1707 
1708  vlayout->addWidget( new QLabel( tr( "Default value" ) ) );
1709 
1710  mDefaultFileWidget = new QgsFileWidget();
1711  mDefaultFileWidget->lineEdit()->setShowClearButton( true );
1712  if ( const QgsProcessingParameterFile *fileParam = dynamic_cast<const QgsProcessingParameterFile *>( definition ) )
1713  {
1714  mDefaultFileWidget->setStorageMode( fileParam->behavior() == QgsProcessingParameterFile::File ? QgsFileWidget::GetFile : QgsFileWidget::GetDirectory );
1715  mDefaultFileWidget->setFilePath( fileParam->defaultValue().toString() );
1716  }
1717  else
1718  mDefaultFileWidget->setStorageMode( QgsFileWidget::GetFile );
1719  vlayout->addWidget( mDefaultFileWidget );
1720 
1721  connect( mTypeComboBox, qgis::overload<int>::of( &QComboBox::currentIndexChanged ), this, [ = ]
1722  {
1723  QgsProcessingParameterFile::Behavior behavior = static_cast< QgsProcessingParameterFile::Behavior >( mTypeComboBox->currentData().toInt() );
1724  mFilterComboBox->setEnabled( behavior == QgsProcessingParameterFile::File );
1725  mDefaultFileWidget->setStorageMode( behavior == QgsProcessingParameterFile::File ? QgsFileWidget::GetFile : QgsFileWidget::GetDirectory );
1726  } );
1727  mFilterComboBox->setEnabled( static_cast< QgsProcessingParameterFile::Behavior >( mTypeComboBox->currentData().toInt() ) == QgsProcessingParameterFile::File );
1728 
1729 
1730  setLayout( vlayout );
1731 }
1732 
1733 QgsProcessingParameterDefinition *QgsProcessingFileParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
1734 {
1735  auto param = qgis::make_unique< QgsProcessingParameterFile >( name, description );
1736  param->setBehavior( static_cast< QgsProcessingParameterFile::Behavior>( mTypeComboBox->currentData().toInt() ) );
1737  if ( param->behavior() == QgsProcessingParameterFile::File )
1738  param->setFileFilter( mFilterComboBox->currentText() );
1739  if ( !mDefaultFileWidget->filePath().isEmpty() )
1740  param->setDefaultValue( mDefaultFileWidget->filePath() );
1741  param->setFlags( flags );
1742  return param.release();
1743 }
1744 
1745 
1746 QgsProcessingFileWidgetWrapper::QgsProcessingFileWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
1747  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
1748 {
1749 
1750 }
1751 
1752 QWidget *QgsProcessingFileWidgetWrapper::createWidget()
1753 {
1754  const QgsProcessingParameterFile *fileParam = dynamic_cast< const QgsProcessingParameterFile *>( parameterDefinition() );
1755  switch ( type() )
1756  {
1760  {
1761  mFileWidget = new QgsFileWidget();
1762  mFileWidget->setToolTip( parameterDefinition()->toolTip() );
1763  mFileWidget->setDialogTitle( parameterDefinition()->description() );
1764 
1765  mFileWidget->setDefaultRoot( QgsSettings().value( QStringLiteral( "/Processing/LastInputPath" ), QDir::homePath() ).toString() );
1766 
1767  switch ( fileParam->behavior() )
1768  {
1770  mFileWidget->setStorageMode( QgsFileWidget::GetFile );
1771  if ( !fileParam->fileFilter().isEmpty() )
1772  mFileWidget->setFilter( fileParam->fileFilter() );
1773  else if ( !fileParam->extension().isEmpty() )
1774  mFileWidget->setFilter( tr( "%1 files" ).arg( fileParam->extension().toUpper() ) + QStringLiteral( " (*." ) + fileParam->extension().toLower() + ')' );
1775  break;
1776 
1778  mFileWidget->setStorageMode( QgsFileWidget::GetDirectory );
1779  break;
1780  }
1781 
1782  connect( mFileWidget, &QgsFileWidget::fileChanged, this, [ = ]( const QString & path )
1783  {
1784  QgsSettings().setValue( QStringLiteral( "/Processing/LastInputPath" ), QFileInfo( path ).canonicalPath() );
1785  emit widgetValueHasChanged( this );
1786  } );
1787  return mFileWidget;
1788  }
1789  }
1790  return nullptr;
1791 }
1792 
1793 void QgsProcessingFileWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
1794 {
1795  const QString v = QgsProcessingParameters::parameterAsString( parameterDefinition(), value, context );
1796  if ( mFileWidget )
1797  mFileWidget->setFilePath( v );
1798 }
1799 
1800 QVariant QgsProcessingFileWidgetWrapper::widgetValue() const
1801 {
1802  if ( mFileWidget )
1803  return mFileWidget->filePath();
1804  else
1805  return QVariant();
1806 }
1807 
1808 QStringList QgsProcessingFileWidgetWrapper::compatibleParameterTypes() const
1809 {
1810  return QStringList()
1813 }
1814 
1815 QStringList QgsProcessingFileWidgetWrapper::compatibleOutputTypes() const
1816 {
1817  return QStringList() << QgsProcessingOutputFile::typeName()
1823 }
1824 
1825 QString QgsProcessingFileWidgetWrapper::modelerExpressionFormatString() const
1826 {
1827  return tr( "string representing a path to a file or folder" );
1828 }
1829 
1830 QString QgsProcessingFileWidgetWrapper::parameterType() const
1831 {
1833 }
1834 
1835 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingFileWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
1836 {
1837  return new QgsProcessingFileWidgetWrapper( parameter, type );
1838 }
1839 
1840 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingFileWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
1841 {
1842  return new QgsProcessingFileParameterDefinitionWidget( context, widgetContext, definition, algorithm );
1843 }
1844 
1845 
1846 
1847 //
1848 // QgsProcessingExpressionWidgetWrapper
1849 //
1850 
1851 QgsProcessingExpressionParameterDefinitionWidget::QgsProcessingExpressionParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
1852  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
1853 {
1854  QVBoxLayout *vlayout = new QVBoxLayout();
1855  vlayout->setMargin( 0 );
1856  vlayout->setContentsMargins( 0, 0, 0, 0 );
1857 
1858  vlayout->addWidget( new QLabel( tr( "Default value" ) ) );
1859 
1860  mDefaultLineEdit = new QgsExpressionLineEdit();
1861  if ( const QgsProcessingParameterExpression *expParam = dynamic_cast<const QgsProcessingParameterExpression *>( definition ) )
1862  mDefaultLineEdit->setExpression( QgsProcessingParameters::parameterAsExpression( expParam, expParam->defaultValue(), context ) );
1863  vlayout->addWidget( mDefaultLineEdit );
1864 
1865  vlayout->addWidget( new QLabel( tr( "Parent layer" ) ) );
1866 
1867  mParentLayerComboBox = new QComboBox();
1868  mParentLayerComboBox->addItem( tr( "None" ), QVariant() );
1869 
1870  QString initialParent;
1871  if ( const QgsProcessingParameterExpression *expParam = dynamic_cast<const QgsProcessingParameterExpression *>( definition ) )
1872  initialParent = expParam->parentLayerParameterName();
1873 
1874  if ( widgetContext.model() )
1875  {
1876  // populate combo box with other model input choices
1877  const QMap<QString, QgsProcessingModelParameter> components = widgetContext.model()->parameterComponents();
1878  for ( auto it = components.constBegin(); it != components.constEnd(); ++it )
1879  {
1880  if ( const QgsProcessingParameterFeatureSource *definition = dynamic_cast< const QgsProcessingParameterFeatureSource * >( widgetContext.model()->parameterDefinition( it.value().parameterName() ) ) )
1881  {
1882  mParentLayerComboBox-> addItem( definition->description(), definition->name() );
1883  if ( !initialParent.isEmpty() && initialParent == definition->name() )
1884  {
1885  mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
1886  }
1887  }
1888  else if ( const QgsProcessingParameterVectorLayer *definition = dynamic_cast< const QgsProcessingParameterVectorLayer * >( widgetContext.model()->parameterDefinition( it.value().parameterName() ) ) )
1889  {
1890  mParentLayerComboBox-> addItem( definition->description(), definition->name() );
1891  if ( !initialParent.isEmpty() && initialParent == definition->name() )
1892  {
1893  mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
1894  }
1895  }
1896  }
1897  }
1898 
1899  if ( mParentLayerComboBox->count() == 1 && !initialParent.isEmpty() )
1900  {
1901  // if no parent candidates found, we just add the existing one as a placeholder
1902  mParentLayerComboBox->addItem( initialParent, initialParent );
1903  mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
1904  }
1905 
1906  vlayout->addWidget( mParentLayerComboBox );
1907  setLayout( vlayout );
1908 }
1909 
1910 QgsProcessingParameterDefinition *QgsProcessingExpressionParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
1911 {
1912  auto param = qgis::make_unique< QgsProcessingParameterExpression >( name, description, mDefaultLineEdit->expression(), mParentLayerComboBox->currentData().toString() );
1913  param->setFlags( flags );
1914  return param.release();
1915 }
1916 
1917 QgsProcessingExpressionWidgetWrapper::QgsProcessingExpressionWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
1918  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
1919 {
1920 
1921 }
1922 
1923 QWidget *QgsProcessingExpressionWidgetWrapper::createWidget()
1924 {
1925  const QgsProcessingParameterExpression *expParam = dynamic_cast< const QgsProcessingParameterExpression *>( parameterDefinition() );
1926  switch ( type() )
1927  {
1931  {
1932  if ( expParam->parentLayerParameterName().isEmpty() )
1933  {
1934  mExpLineEdit = new QgsExpressionLineEdit();
1935  mExpLineEdit->setToolTip( parameterDefinition()->toolTip() );
1936  mExpLineEdit->setExpressionDialogTitle( parameterDefinition()->description() );
1937  mExpLineEdit->registerExpressionContextGenerator( this );
1938  connect( mExpLineEdit, &QgsExpressionLineEdit::expressionChanged, this, [ = ]( const QString & )
1939  {
1940  emit widgetValueHasChanged( this );
1941  } );
1942  return mExpLineEdit;
1943  }
1944  else
1945  {
1946  mFieldExpWidget = new QgsFieldExpressionWidget();
1947  mFieldExpWidget->setToolTip( parameterDefinition()->toolTip() );
1948  mFieldExpWidget->setExpressionDialogTitle( parameterDefinition()->description() );
1949  mFieldExpWidget->registerExpressionContextGenerator( this );
1950  connect( mFieldExpWidget, static_cast < void ( QgsFieldExpressionWidget::* )( const QString & ) >( &QgsFieldExpressionWidget::fieldChanged ), this, [ = ]( const QString & )
1951  {
1952  emit widgetValueHasChanged( this );
1953  } );
1954  return mFieldExpWidget;
1955  }
1956  }
1957  }
1958  return nullptr;
1959 }
1960 
1961 void QgsProcessingExpressionWidgetWrapper::postInitialize( const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
1962 {
1964  switch ( type() )
1965  {
1968  {
1969  for ( const QgsAbstractProcessingParameterWidgetWrapper *wrapper : wrappers )
1970  {
1971  if ( wrapper->parameterDefinition()->name() == static_cast< const QgsProcessingParameterExpression * >( parameterDefinition() )->parentLayerParameterName() )
1972  {
1973  setParentLayerWrapperValue( wrapper );
1975  {
1976  setParentLayerWrapperValue( wrapper );
1977  } );
1978  break;
1979  }
1980  }
1981  break;
1982  }
1983 
1985  break;
1986  }
1987 }
1988 
1989 void QgsProcessingExpressionWidgetWrapper::setParentLayerWrapperValue( const QgsAbstractProcessingParameterWidgetWrapper *parentWrapper )
1990 {
1991  // evaluate value to layer
1992  QgsProcessingContext *context = nullptr;
1993  std::unique_ptr< QgsProcessingContext > tmpContext;
1994  if ( mProcessingContextGenerator )
1995  context = mProcessingContextGenerator->processingContext();
1996 
1997  if ( !context )
1998  {
1999  tmpContext = qgis::make_unique< QgsProcessingContext >();
2000  context = tmpContext.get();
2001  }
2002 
2003  QgsVectorLayer *layer = QgsProcessingParameters::parameterAsVectorLayer( parentWrapper->parameterDefinition(), parentWrapper->parameterValue(), *context );
2004  if ( !layer )
2005  {
2006  if ( mFieldExpWidget )
2007  mFieldExpWidget->setLayer( nullptr );
2008  else if ( mExpLineEdit )
2009  mExpLineEdit->setLayer( nullptr );
2010  return;
2011  }
2012 
2013  // need to grab ownership of layer if required - otherwise layer may be deleted when context
2014  // goes out of scope
2015  std::unique_ptr< QgsMapLayer > ownedLayer( context->takeResultLayer( layer->id() ) );
2016  if ( ownedLayer && ownedLayer->type() == QgsMapLayerType::VectorLayer )
2017  {
2018  mParentLayer.reset( qobject_cast< QgsVectorLayer * >( ownedLayer.release() ) );
2019  layer = mParentLayer.get();
2020  }
2021  else
2022  {
2023  // don't need ownership of this layer - it wasn't owned by context (so e.g. is owned by the project)
2024  }
2025 
2026  if ( mFieldExpWidget )
2027  mFieldExpWidget->setLayer( layer );
2028  else if ( mExpLineEdit )
2029  mExpLineEdit->setLayer( layer );
2030 }
2031 
2032 void QgsProcessingExpressionWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
2033 {
2034  const QString v = QgsProcessingParameters::parameterAsString( parameterDefinition(), value, context );
2035  if ( mFieldExpWidget )
2036  mFieldExpWidget->setExpression( v );
2037  else if ( mExpLineEdit )
2038  mExpLineEdit->setExpression( v );
2039 }
2040 
2041 QVariant QgsProcessingExpressionWidgetWrapper::widgetValue() const
2042 {
2043  if ( mFieldExpWidget )
2044  return mFieldExpWidget->expression();
2045  else if ( mExpLineEdit )
2046  return mExpLineEdit->expression();
2047  else
2048  return QVariant();
2049 }
2050 
2051 QStringList QgsProcessingExpressionWidgetWrapper::compatibleParameterTypes() const
2052 {
2053  return QStringList()
2060 }
2061 
2062 QStringList QgsProcessingExpressionWidgetWrapper::compatibleOutputTypes() const
2063 {
2064  return QStringList()
2067 }
2068 
2069 QString QgsProcessingExpressionWidgetWrapper::modelerExpressionFormatString() const
2070 {
2071  return tr( "string representation of an expression" );
2072 }
2073 
2074 const QgsVectorLayer *QgsProcessingExpressionWidgetWrapper::linkedVectorLayer() const
2075 {
2076  if ( mFieldExpWidget && mFieldExpWidget->layer() )
2077  return mFieldExpWidget->layer();
2078 
2080 }
2081 
2082 QString QgsProcessingExpressionWidgetWrapper::parameterType() const
2083 {
2085 }
2086 
2087 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingExpressionWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
2088 {
2089  return new QgsProcessingExpressionWidgetWrapper( parameter, type );
2090 }
2091 
2092 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingExpressionWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
2093 {
2094  return new QgsProcessingExpressionParameterDefinitionWidget( context, widgetContext, definition, algorithm );
2095 }
2096 
2097 
2098 
2099 //
2100 // QgsProcessingEnumPanelWidget
2101 //
2102 
2103 QgsProcessingEnumPanelWidget::QgsProcessingEnumPanelWidget( QWidget *parent, const QgsProcessingParameterEnum *param )
2104  : QWidget( parent )
2105  , mParam( param )
2106 {
2107  QHBoxLayout *hl = new QHBoxLayout();
2108  hl->setMargin( 0 );
2109  hl->setContentsMargins( 0, 0, 0, 0 );
2110 
2111  mLineEdit = new QLineEdit();
2112  mLineEdit->setEnabled( false );
2113  hl->addWidget( mLineEdit, 1 );
2114 
2115  mToolButton = new QToolButton();
2116  mToolButton->setText( QString( QChar( 0x2026 ) ) );
2117  hl->addWidget( mToolButton );
2118 
2119  setLayout( hl );
2120 
2121  if ( mParam )
2122  {
2123  mLineEdit->setText( tr( "%1 options selected" ).arg( 0 ) );
2124  }
2125 
2126  connect( mToolButton, &QToolButton::clicked, this, &QgsProcessingEnumPanelWidget::showDialog );
2127 }
2128 
2129 void QgsProcessingEnumPanelWidget::setValue( const QVariant &value )
2130 {
2131  if ( value.isValid() )
2132  mValue = value.type() == QVariant::List ? value.toList() : QVariantList() << value;
2133  else
2134  mValue.clear();
2135 
2136  updateSummaryText();
2137  emit changed();
2138 }
2139 
2140 void QgsProcessingEnumPanelWidget::showDialog()
2141 {
2142  QVariantList availableOptions;
2143  if ( mParam )
2144  {
2145  availableOptions.reserve( mParam->options().size() );
2146  for ( int i = 0; i < mParam->options().count(); ++i )
2147  availableOptions << i;
2148  }
2149 
2150  const QStringList options = mParam ? mParam->options() : QStringList();
2152  if ( panel && panel->dockMode() )
2153  {
2154  QgsProcessingMultipleSelectionPanelWidget *widget = new QgsProcessingMultipleSelectionPanelWidget( availableOptions, mValue );
2155  widget->setPanelTitle( mParam->description() );
2156 
2157  widget->setValueFormatter( [options]( const QVariant & v ) -> QString
2158  {
2159  const int i = v.toInt();
2160  return options.size() > i ? options.at( i ) : QString();
2161  } );
2162 
2163  connect( widget, &QgsProcessingMultipleSelectionPanelWidget::selectionChanged, this, [ = ]()
2164  {
2165  setValue( widget->selectedOptions() );
2166  } );
2167  connect( widget, &QgsProcessingMultipleSelectionPanelWidget::acceptClicked, widget, &QgsPanelWidget::acceptPanel );
2168  panel->openPanel( widget );
2169  }
2170  else
2171  {
2172  QgsProcessingMultipleSelectionDialog dlg( availableOptions, mValue, this, nullptr );
2173 
2174  dlg.setValueFormatter( [options]( const QVariant & v ) -> QString
2175  {
2176  const int i = v.toInt();
2177  return options.size() > i ? options.at( i ) : QString();
2178  } );
2179  if ( dlg.exec() )
2180  {
2181  setValue( dlg.selectedOptions() );
2182  }
2183  }
2184 }
2185 
2186 void QgsProcessingEnumPanelWidget::updateSummaryText()
2187 {
2188  if ( mParam )
2189  mLineEdit->setText( tr( "%1 options selected" ).arg( mValue.count() ) );
2190 }
2191 
2192 
2193 //
2194 // QgsProcessingEnumCheckboxPanelWidget
2195 //
2196 QgsProcessingEnumCheckboxPanelWidget::QgsProcessingEnumCheckboxPanelWidget( QWidget *parent, const QgsProcessingParameterEnum *param, int columns )
2197  : QWidget( parent )
2198  , mParam( param )
2199  , mButtonGroup( new QButtonGroup( this ) )
2200  , mColumns( columns )
2201 {
2202  mButtonGroup->setExclusive( !mParam->allowMultiple() );
2203 
2204  QGridLayout *l = new QGridLayout();
2205  l->setContentsMargins( 0, 0, 0, 0 );
2206  l->setMargin( 0 );
2207 
2208  int rows = static_cast< int >( std::ceil( mParam->options().count() / static_cast< double >( mColumns ) ) );
2209  for ( int i = 0; i < mParam->options().count(); ++i )
2210  {
2211  QAbstractButton *button = nullptr;
2212  if ( mParam->allowMultiple() )
2213  button = new QCheckBox( mParam->options().at( i ) );
2214  else
2215  button = new QRadioButton( mParam->options().at( i ) );
2216 
2217  connect( button, &QAbstractButton::toggled, this, [ = ]
2218  {
2219  if ( !mBlockChangedSignal )
2220  emit changed();
2221  } );
2222 
2223  mButtons.insert( i, button );
2224  mButtonGroup->addButton( button, i );
2225  l->addWidget( button, i % rows, i / rows );
2226  }
2227  l->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, mColumns );
2228  setLayout( l );
2229 
2230  if ( mParam->allowMultiple() )
2231  {
2232  setContextMenuPolicy( Qt::CustomContextMenu );
2233  connect( this, &QWidget::customContextMenuRequested, this, &QgsProcessingEnumCheckboxPanelWidget::showPopupMenu );
2234  }
2235 }
2236 
2237 QVariant QgsProcessingEnumCheckboxPanelWidget::value() const
2238 {
2239  if ( mParam->allowMultiple() )
2240  {
2241  QVariantList value;
2242  for ( auto it = mButtons.constBegin(); it != mButtons.constEnd(); ++it )
2243  {
2244  if ( it.value()->isChecked() )
2245  value.append( it.key() );
2246  }
2247  return value;
2248  }
2249  else
2250  {
2251  return mButtonGroup->checkedId() >= 0 ? mButtonGroup->checkedId() : QVariant();
2252  }
2253 }
2254 
2255 void QgsProcessingEnumCheckboxPanelWidget::setValue( const QVariant &value )
2256 {
2257  mBlockChangedSignal = true;
2258  if ( mParam->allowMultiple() )
2259  {
2260  QVariantList selected;
2261  if ( value.isValid() )
2262  selected = value.type() == QVariant::List ? value.toList() : QVariantList() << value;
2263  for ( auto it = mButtons.constBegin(); it != mButtons.constEnd(); ++it )
2264  {
2265  it.value()->setChecked( selected.contains( it.key() ) );
2266  }
2267  }
2268  else
2269  {
2270  QVariant v = value;
2271  if ( v.type() == QVariant::List )
2272  v = v.toList().value( 0 );
2273  if ( mButtons.contains( v ) )
2274  mButtons.value( v )->setChecked( true );
2275  }
2276  mBlockChangedSignal = false;
2277  emit changed();
2278 }
2279 
2280 void QgsProcessingEnumCheckboxPanelWidget::showPopupMenu()
2281 {
2282  QMenu popupMenu;
2283  QAction *selectAllAction = new QAction( tr( "Select All" ), &popupMenu );
2284  connect( selectAllAction, &QAction::triggered, this, &QgsProcessingEnumCheckboxPanelWidget::selectAll );
2285  QAction *clearAllAction = new QAction( tr( "Clear Selection" ), &popupMenu );
2286  connect( clearAllAction, &QAction::triggered, this, &QgsProcessingEnumCheckboxPanelWidget::deselectAll );
2287  popupMenu.addAction( selectAllAction );
2288  popupMenu.addAction( clearAllAction );
2289  popupMenu.exec( QCursor::pos() );
2290 }
2291 
2292 void QgsProcessingEnumCheckboxPanelWidget::selectAll()
2293 {
2294  mBlockChangedSignal = true;
2295  for ( auto it = mButtons.constBegin(); it != mButtons.constEnd(); ++it )
2296  it.value()->setChecked( true );
2297  mBlockChangedSignal = false;
2298  emit changed();
2299 }
2300 
2301 void QgsProcessingEnumCheckboxPanelWidget::deselectAll()
2302 {
2303  mBlockChangedSignal = true;
2304  for ( auto it = mButtons.constBegin(); it != mButtons.constEnd(); ++it )
2305  it.value()->setChecked( false );
2306  mBlockChangedSignal = false;
2307  emit changed();
2308 }
2309 
2310 
2311 //
2312 // QgsProcessingEnumWidgetWrapper
2313 //
2314 
2315 QgsProcessingEnumParameterDefinitionWidget::QgsProcessingEnumParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
2316  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
2317 {
2318  QVBoxLayout *vlayout = new QVBoxLayout();
2319  vlayout->setMargin( 0 );
2320  vlayout->setContentsMargins( 0, 0, 0, 0 );
2321 
2322  mEnumWidget = new QgsProcessingEnumModelerWidget();
2323  if ( const QgsProcessingParameterEnum *enumParam = dynamic_cast<const QgsProcessingParameterEnum *>( definition ) )
2324  {
2325  mEnumWidget->setAllowMultiple( enumParam->allowMultiple() );
2326  mEnumWidget->setOptions( enumParam->options() );
2327  mEnumWidget->setDefaultOptions( enumParam->defaultValue() );
2328  }
2329  vlayout->addWidget( mEnumWidget );
2330  setLayout( vlayout );
2331 }
2332 
2333 QgsProcessingParameterDefinition *QgsProcessingEnumParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
2334 {
2335  auto param = qgis::make_unique< QgsProcessingParameterEnum >( name, description, mEnumWidget->options(), mEnumWidget->allowMultiple(), mEnumWidget->defaultOptions() );
2336  param->setFlags( flags );
2337  return param.release();
2338 }
2339 
2340 
2341 QgsProcessingEnumWidgetWrapper::QgsProcessingEnumWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
2342  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
2343 {
2344 
2345 }
2346 
2347 QWidget *QgsProcessingEnumWidgetWrapper::createWidget()
2348 {
2349  const QgsProcessingParameterEnum *expParam = dynamic_cast< const QgsProcessingParameterEnum *>( parameterDefinition() );
2350  switch ( type() )
2351  {
2353  {
2354  // checkbox panel only for use outside in standard gui!
2355  if ( expParam->metadata().value( QStringLiteral( "widget_wrapper" ) ).toMap().value( QStringLiteral( "useCheckBoxes" ), false ).toBool() )
2356  {
2357  const int columns = expParam->metadata().value( QStringLiteral( "widget_wrapper" ) ).toMap().value( QStringLiteral( "columns" ), 2 ).toInt();
2358  mCheckboxPanel = new QgsProcessingEnumCheckboxPanelWidget( nullptr, expParam, columns );
2359  mCheckboxPanel->setToolTip( parameterDefinition()->toolTip() );
2360  connect( mCheckboxPanel, &QgsProcessingEnumCheckboxPanelWidget::changed, this, [ = ]
2361  {
2362  emit widgetValueHasChanged( this );
2363  } );
2364  return mCheckboxPanel;
2365  }
2366  }
2367  FALLTHROUGH
2370  {
2371  if ( expParam->allowMultiple() )
2372  {
2373  mPanel = new QgsProcessingEnumPanelWidget( nullptr, expParam );
2374  mPanel->setToolTip( parameterDefinition()->toolTip() );
2375  connect( mPanel, &QgsProcessingEnumPanelWidget::changed, this, [ = ]
2376  {
2377  emit widgetValueHasChanged( this );
2378  } );
2379  return mPanel;
2380  }
2381  else
2382  {
2383  mComboBox = new QComboBox();
2384 
2386  mComboBox->addItem( tr( "[Not selected]" ), QVariant() );
2387  const QStringList options = expParam->options();
2388  for ( int i = 0; i < options.count(); ++i )
2389  mComboBox->addItem( options.at( i ), i );
2390 
2391  mComboBox->setToolTip( parameterDefinition()->toolTip() );
2392  connect( mComboBox, qgis::overload<int>::of( &QComboBox::currentIndexChanged ), this, [ = ]( int )
2393  {
2394  emit widgetValueHasChanged( this );
2395  } );
2396  return mComboBox;
2397  }
2398  }
2399  }
2400  return nullptr;
2401 }
2402 
2403 void QgsProcessingEnumWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
2404 {
2405  if ( mComboBox )
2406  {
2407  if ( !value.isValid() )
2408  mComboBox->setCurrentIndex( mComboBox->findData( QVariant() ) );
2409  else
2410  {
2411  const int v = QgsProcessingParameters::parameterAsEnum( parameterDefinition(), value, context );
2412  mComboBox->setCurrentIndex( mComboBox->findData( v ) );
2413  }
2414  }
2415  else if ( mPanel || mCheckboxPanel )
2416  {
2417  QVariantList opts;
2418  if ( value.isValid() )
2419  {
2420  const QList< int > v = QgsProcessingParameters::parameterAsEnums( parameterDefinition(), value, context );
2421  opts.reserve( v.size() );
2422  for ( int i : v )
2423  opts << i;
2424  }
2425  if ( mPanel )
2426  mPanel->setValue( opts );
2427  else if ( mCheckboxPanel )
2428  mCheckboxPanel->setValue( opts );
2429  }
2430 }
2431 
2432 QVariant QgsProcessingEnumWidgetWrapper::widgetValue() const
2433 {
2434  if ( mComboBox )
2435  return mComboBox->currentData();
2436  else if ( mPanel )
2437  return mPanel->value();
2438  else if ( mCheckboxPanel )
2439  return mCheckboxPanel->value();
2440  else
2441  return QVariant();
2442 }
2443 
2444 QStringList QgsProcessingEnumWidgetWrapper::compatibleParameterTypes() const
2445 {
2446  return QStringList()
2450 }
2451 
2452 QStringList QgsProcessingEnumWidgetWrapper::compatibleOutputTypes() const
2453 {
2454  return QStringList()
2457 }
2458 
2459 QString QgsProcessingEnumWidgetWrapper::modelerExpressionFormatString() const
2460 {
2461  return tr( "selected option index (starting from 0), array of indices, or comma separated string of options (e.g. '1,3')" );
2462 }
2463 
2464 QString QgsProcessingEnumWidgetWrapper::parameterType() const
2465 {
2467 }
2468 
2469 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingEnumWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
2470 {
2471  return new QgsProcessingEnumWidgetWrapper( parameter, type );
2472 }
2473 
2474 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingEnumWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
2475 {
2476  return new QgsProcessingEnumParameterDefinitionWidget( context, widgetContext, definition, algorithm );
2477 }
2478 
2479 //
2480 // QgsProcessingLayoutWidgetWrapper
2481 //
2482 
2483 QgsProcessingLayoutWidgetWrapper::QgsProcessingLayoutWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
2484  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
2485 {
2486 
2487 }
2488 
2489 QWidget *QgsProcessingLayoutWidgetWrapper::createWidget()
2490 {
2491  const QgsProcessingParameterLayout *layoutParam = dynamic_cast< const QgsProcessingParameterLayout *>( parameterDefinition() );
2492  switch ( type() )
2493  {
2496  {
2497  // combobox only for use outside modeler!
2498  mComboBox = new QgsLayoutComboBox( nullptr, widgetContext().project() ? widgetContext().project()->layoutManager() : nullptr );
2500  mComboBox->setAllowEmptyLayout( true );
2501  mComboBox->setFilters( QgsLayoutManagerProxyModel::FilterPrintLayouts );
2502 
2503  mComboBox->setToolTip( parameterDefinition()->toolTip() );
2504  connect( mComboBox, &QgsLayoutComboBox::layoutChanged, this, [ = ]( QgsMasterLayoutInterface * )
2505  {
2506  emit widgetValueHasChanged( this );
2507  } );
2508  return mComboBox;
2509  }
2510 
2512  {
2513  mLineEdit = new QLineEdit();
2514  mLineEdit->setToolTip( tr( "Name of an existing print layout" ) );
2515  connect( mLineEdit, &QLineEdit::textChanged, this, [ = ]( const QString & )
2516  {
2517  emit widgetValueHasChanged( this );
2518  } );
2519  return mLineEdit;
2520  }
2521  }
2522  return nullptr;
2523 }
2524 
2525 void QgsProcessingLayoutWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
2526 {
2527  if ( mComboBox )
2528  {
2529  if ( !value.isValid() )
2530  mComboBox->setCurrentLayout( nullptr );
2531  else
2532  {
2533  if ( QgsPrintLayout *l = QgsProcessingParameters::parameterAsLayout( parameterDefinition(), value, context ) )
2534  mComboBox->setCurrentLayout( l );
2535  else
2536  mComboBox->setCurrentLayout( nullptr );
2537  }
2538  }
2539  else if ( mLineEdit )
2540  {
2541  const QString v = QgsProcessingParameters::parameterAsString( parameterDefinition(), value, context );
2542  mLineEdit->setText( v );
2543  }
2544 }
2545 
2546 QVariant QgsProcessingLayoutWidgetWrapper::widgetValue() const
2547 {
2548  if ( mComboBox )
2549  {
2550  const QgsMasterLayoutInterface *l = mComboBox->currentLayout();
2551  return l ? l->name() : QVariant();
2552  }
2553  else if ( mLineEdit )
2554  return mLineEdit->text().isEmpty() ? QVariant() : mLineEdit->text();
2555  else
2556  return QVariant();
2557 }
2558 
2559 QStringList QgsProcessingLayoutWidgetWrapper::compatibleParameterTypes() const
2560 {
2561  return QStringList()
2564 }
2565 
2566 QStringList QgsProcessingLayoutWidgetWrapper::compatibleOutputTypes() const
2567 {
2568  return QStringList()
2570 }
2571 
2572 QString QgsProcessingLayoutWidgetWrapper::modelerExpressionFormatString() const
2573 {
2574  return tr( "string representing the name of an existing print layout" );
2575 }
2576 
2577 QString QgsProcessingLayoutWidgetWrapper::parameterType() const
2578 {
2580 }
2581 
2582 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingLayoutWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
2583 {
2584  return new QgsProcessingLayoutWidgetWrapper( parameter, type );
2585 }
2586 
2587 
2588 
2589 
2590 //
2591 // QgsProcessingLayoutItemWidgetWrapper
2592 //
2593 
2594 
2595 QgsProcessingLayoutItemParameterDefinitionWidget::QgsProcessingLayoutItemParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
2596  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
2597 {
2598  QVBoxLayout *vlayout = new QVBoxLayout();
2599  vlayout->setMargin( 0 );
2600  vlayout->setContentsMargins( 0, 0, 0, 0 );
2601 
2602  vlayout->addWidget( new QLabel( tr( "Parent layout" ) ) );
2603 
2604  mParentLayoutComboBox = new QComboBox();
2605  QString initialParent;
2606  if ( const QgsProcessingParameterLayoutItem *itemParam = dynamic_cast<const QgsProcessingParameterLayoutItem *>( definition ) )
2607  initialParent = itemParam->parentLayoutParameterName();
2608 
2609  if ( widgetContext.model() )
2610  {
2611  // populate combo box with other model input choices
2612  const QMap<QString, QgsProcessingModelParameter> components = widgetContext.model()->parameterComponents();
2613  for ( auto it = components.constBegin(); it != components.constEnd(); ++it )
2614  {
2615  if ( const QgsProcessingParameterLayout *definition = dynamic_cast< const QgsProcessingParameterLayout * >( widgetContext.model()->parameterDefinition( it.value().parameterName() ) ) )
2616  {
2617  mParentLayoutComboBox-> addItem( definition->description(), definition->name() );
2618  if ( !initialParent.isEmpty() && initialParent == definition->name() )
2619  {
2620  mParentLayoutComboBox->setCurrentIndex( mParentLayoutComboBox->count() - 1 );
2621  }
2622  }
2623  }
2624  }
2625 
2626  if ( mParentLayoutComboBox->count() == 0 && !initialParent.isEmpty() )
2627  {
2628  // if no parent candidates found, we just add the existing one as a placeholder
2629  mParentLayoutComboBox->addItem( initialParent, initialParent );
2630  mParentLayoutComboBox->setCurrentIndex( mParentLayoutComboBox->count() - 1 );
2631  }
2632 
2633  vlayout->addWidget( mParentLayoutComboBox );
2634  setLayout( vlayout );
2635 }
2636 QgsProcessingParameterDefinition *QgsProcessingLayoutItemParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
2637 {
2638  auto param = qgis::make_unique< QgsProcessingParameterLayoutItem >( name, description, QVariant(), mParentLayoutComboBox->currentData().toString() );
2639  param->setFlags( flags );
2640  return param.release();
2641 }
2642 
2643 
2644 QgsProcessingLayoutItemWidgetWrapper::QgsProcessingLayoutItemWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
2645  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
2646 {
2647 
2648 }
2649 
2650 QWidget *QgsProcessingLayoutItemWidgetWrapper::createWidget()
2651 {
2652  const QgsProcessingParameterLayoutItem *layoutParam = dynamic_cast< const QgsProcessingParameterLayoutItem *>( parameterDefinition() );
2653  switch ( type() )
2654  {
2657  {
2658  // combobox only for use outside modeler!
2659  mComboBox = new QgsLayoutItemComboBox( nullptr, nullptr );
2661  mComboBox->setAllowEmptyItem( true );
2662  if ( layoutParam->itemType() >= 0 )
2663  mComboBox->setItemType( static_cast< QgsLayoutItemRegistry::ItemType >( layoutParam->itemType() ) );
2664 
2665  mComboBox->setToolTip( parameterDefinition()->toolTip() );
2666  connect( mComboBox, &QgsLayoutItemComboBox::itemChanged, this, [ = ]( QgsLayoutItem * )
2667  {
2668  emit widgetValueHasChanged( this );
2669  } );
2670  return mComboBox;
2671  }
2672 
2674  {
2675  mLineEdit = new QLineEdit();
2676  mLineEdit->setToolTip( tr( "UUID or ID of an existing print layout item" ) );
2677  connect( mLineEdit, &QLineEdit::textChanged, this, [ = ]( const QString & )
2678  {
2679  emit widgetValueHasChanged( this );
2680  } );
2681  return mLineEdit;
2682  }
2683  }
2684  return nullptr;
2685 }
2686 
2687 void QgsProcessingLayoutItemWidgetWrapper::postInitialize( const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
2688 {
2690  switch ( type() )
2691  {
2694  {
2695  for ( const QgsAbstractProcessingParameterWidgetWrapper *wrapper : wrappers )
2696  {
2697  if ( wrapper->parameterDefinition()->name() == static_cast< const QgsProcessingParameterLayoutItem * >( parameterDefinition() )->parentLayoutParameterName() )
2698  {
2699  setLayoutParameterValue( wrapper->parameterValue() );
2701  {
2702  setLayoutParameterValue( wrapper->parameterValue() );
2703  } );
2704  break;
2705  }
2706  }
2707  break;
2708  }
2709 
2711  break;
2712  }
2713 }
2714 
2715 void QgsProcessingLayoutItemWidgetWrapper::setLayoutParameterValue( const QVariant &value )
2716 {
2717  QgsPrintLayout *layout = nullptr;
2718 
2719  // evaluate value to layout
2720  QgsProcessingContext *context = nullptr;
2721  std::unique_ptr< QgsProcessingContext > tmpContext;
2722  if ( mProcessingContextGenerator )
2723  context = mProcessingContextGenerator->processingContext();
2724 
2725  if ( !context )
2726  {
2727  tmpContext = qgis::make_unique< QgsProcessingContext >();
2728  context = tmpContext.get();
2729  }
2730 
2731  layout = QgsProcessingParameters::parameterAsLayout( parameterDefinition(), value, *context );
2732  setLayout( layout );
2733 }
2734 
2735 void QgsProcessingLayoutItemWidgetWrapper::setLayout( QgsPrintLayout *layout )
2736 {
2737  if ( mComboBox )
2738  mComboBox->setCurrentLayout( layout );
2739 }
2740 
2741 void QgsProcessingLayoutItemWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
2742 {
2743  if ( mComboBox )
2744  {
2745  if ( !value.isValid() )
2746  mComboBox->setItem( nullptr );
2747  else
2748  {
2749  QgsLayoutItem *item = QgsProcessingParameters::parameterAsLayoutItem( parameterDefinition(), value, context, qobject_cast< QgsPrintLayout * >( mComboBox->currentLayout() ) );
2750  mComboBox->setItem( item );
2751  }
2752  }
2753  else if ( mLineEdit )
2754  {
2755  const QString v = QgsProcessingParameters::parameterAsString( parameterDefinition(), value, context );
2756  mLineEdit->setText( v );
2757  }
2758 }
2759 
2760 QVariant QgsProcessingLayoutItemWidgetWrapper::widgetValue() const
2761 {
2762  if ( mComboBox )
2763  {
2764  const QgsLayoutItem *i = mComboBox->currentItem();
2765  return i ? i->uuid() : QVariant();
2766  }
2767  else if ( mLineEdit )
2768  return mLineEdit->text().isEmpty() ? QVariant() : mLineEdit->text();
2769  else
2770  return QVariant();
2771 }
2772 
2773 QStringList QgsProcessingLayoutItemWidgetWrapper::compatibleParameterTypes() const
2774 {
2775  return QStringList()
2778 }
2779 
2780 QStringList QgsProcessingLayoutItemWidgetWrapper::compatibleOutputTypes() const
2781 {
2782  return QStringList()
2784 }
2785 
2786 QString QgsProcessingLayoutItemWidgetWrapper::modelerExpressionFormatString() const
2787 {
2788  return tr( "string representing the UUID or ID of an existing print layout item" );
2789 }
2790 
2791 QString QgsProcessingLayoutItemWidgetWrapper::parameterType() const
2792 {
2794 }
2795 
2796 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingLayoutItemWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
2797 {
2798  return new QgsProcessingLayoutItemWidgetWrapper( parameter, type );
2799 }
2800 
2801 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingLayoutItemWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
2802 {
2803  return new QgsProcessingLayoutItemParameterDefinitionWidget( context, widgetContext, definition, algorithm );
2804 }
2805 
2806 //
2807 // QgsProcessingPointMapTool
2808 //
2809 
2810 QgsProcessingPointMapTool::QgsProcessingPointMapTool( QgsMapCanvas *canvas )
2811  : QgsMapTool( canvas )
2812 {
2813  setCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::CapturePoint ) );
2814  mSnapIndicator.reset( new QgsSnapIndicator( canvas ) );
2815 }
2816 
2817 QgsProcessingPointMapTool::~QgsProcessingPointMapTool() = default;
2818 
2819 void QgsProcessingPointMapTool::deactivate()
2820 {
2821  mSnapIndicator->setMatch( QgsPointLocator::Match() );
2823 }
2824 
2825 void QgsProcessingPointMapTool::canvasMoveEvent( QgsMapMouseEvent *e )
2826 {
2827  e->snapPoint();
2828  mSnapIndicator->setMatch( e->mapPointMatch() );
2829 }
2830 
2831 void QgsProcessingPointMapTool::canvasPressEvent( QgsMapMouseEvent *e )
2832 {
2833  if ( e->button() == Qt::LeftButton )
2834  {
2835  QgsPointXY point = e->snapPoint();
2836  emit clicked( point );
2837  emit complete();
2838  }
2839 }
2840 
2841 void QgsProcessingPointMapTool::keyPressEvent( QKeyEvent *e )
2842 {
2843  if ( e->key() == Qt::Key_Escape )
2844  {
2845 
2846  // Override default shortcut management in MapCanvas
2847  e->ignore();
2848  emit complete();
2849  }
2850 }
2851 
2852 
2853 
2854 //
2855 // QgsProcessingPointPanel
2856 //
2857 
2858 QgsProcessingPointPanel::QgsProcessingPointPanel( QWidget *parent )
2859  : QWidget( parent )
2860 {
2861  QHBoxLayout *l = new QHBoxLayout();
2862  l->setContentsMargins( 0, 0, 0, 0 );
2863  l->setMargin( 0 );
2864  mLineEdit = new QgsFilterLineEdit( );
2865  mLineEdit->setShowClearButton( false );
2866  l->addWidget( mLineEdit, 1 );
2867  mButton = new QToolButton();
2868  mButton->setText( QString( QChar( 0x2026 ) ) );
2869  l->addWidget( mButton );
2870  setLayout( l );
2871 
2872  connect( mLineEdit, &QLineEdit::textChanged, this, &QgsProcessingPointPanel::changed );
2873  connect( mButton, &QToolButton::clicked, this, &QgsProcessingPointPanel::selectOnCanvas );
2874  mButton->setVisible( false );
2875 }
2876 
2877 void QgsProcessingPointPanel::setMapCanvas( QgsMapCanvas *canvas )
2878 {
2879  mCanvas = canvas;
2880  mButton->setVisible( true );
2881 
2882  mCrs = canvas->mapSettings().destinationCrs();
2883  mTool = qgis::make_unique< QgsProcessingPointMapTool >( mCanvas );
2884  connect( mTool.get(), &QgsProcessingPointMapTool::clicked, this, &QgsProcessingPointPanel::updatePoint );
2885  connect( mTool.get(), &QgsProcessingPointMapTool::complete, this, &QgsProcessingPointPanel::pointPicked );
2886 }
2887 
2888 void QgsProcessingPointPanel::setAllowNull( bool allowNull )
2889 {
2890  mLineEdit->setShowClearButton( allowNull );
2891 }
2892 
2893 QVariant QgsProcessingPointPanel::value() const
2894 {
2895  return mLineEdit->showClearButton() && mLineEdit->text().trimmed().isEmpty() ? QVariant() : QVariant( mLineEdit->text() );
2896 }
2897 
2898 void QgsProcessingPointPanel::clear()
2899 {
2900  mLineEdit->clear();
2901 }
2902 
2903 void QgsProcessingPointPanel::setValue( const QgsPointXY &point, const QgsCoordinateReferenceSystem &crs )
2904 {
2905  QString newText = QStringLiteral( "%1,%2" )
2906  .arg( QString::number( point.x(), 'f' ),
2907  QString::number( point.y(), 'f' ) );
2908 
2909  mCrs = crs;
2910  if ( mCrs.isValid() )
2911  {
2912  newText += QStringLiteral( " [%1]" ).arg( mCrs.authid() );
2913  }
2914  mLineEdit->setText( newText );
2915 }
2916 
2917 void QgsProcessingPointPanel::selectOnCanvas()
2918 {
2919  if ( !mCanvas )
2920  return;
2921 
2922  mPrevTool = mCanvas->mapTool();
2923  mCanvas->setMapTool( mTool.get() );
2924 
2925  emit toggleDialogVisibility( false );
2926 }
2927 
2928 void QgsProcessingPointPanel::updatePoint( const QgsPointXY &point )
2929 {
2930  setValue( point, mCanvas->mapSettings().destinationCrs() );
2931 }
2932 
2933 void QgsProcessingPointPanel::pointPicked()
2934 {
2935  if ( !mCanvas )
2936  return;
2937 
2938  mCanvas->setMapTool( mPrevTool );
2939 
2940  emit toggleDialogVisibility( true );
2941 }
2942 
2943 
2944 
2945 //
2946 // QgsProcessingPointWidgetWrapper
2947 //
2948 
2949 QgsProcessingPointParameterDefinitionWidget::QgsProcessingPointParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
2950  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
2951 {
2952  QVBoxLayout *vlayout = new QVBoxLayout();
2953  vlayout->setMargin( 0 );
2954  vlayout->setContentsMargins( 0, 0, 0, 0 );
2955 
2956  vlayout->addWidget( new QLabel( tr( "Default value" ) ) );
2957 
2958  mDefaultLineEdit = new QLineEdit();
2959  mDefaultLineEdit->setToolTip( tr( "Point as 'x,y'" ) );
2960  mDefaultLineEdit->setPlaceholderText( tr( "Point as 'x,y'" ) );
2961  if ( const QgsProcessingParameterPoint *pointParam = dynamic_cast<const QgsProcessingParameterPoint *>( definition ) )
2962  {
2963  QgsPointXY point = QgsProcessingParameters::parameterAsPoint( pointParam, pointParam->defaultValue(), context );
2964  mDefaultLineEdit->setText( QStringLiteral( "%1,%2" ).arg( QString::number( point.x(), 'f' ), QString::number( point.y(), 'f' ) ) );
2965  }
2966 
2967  vlayout->addWidget( mDefaultLineEdit );
2968  setLayout( vlayout );
2969 }
2970 
2971 QgsProcessingParameterDefinition *QgsProcessingPointParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
2972 {
2973  auto param = qgis::make_unique< QgsProcessingParameterPoint >( name, description, mDefaultLineEdit->text() );
2974  param->setFlags( flags );
2975  return param.release();
2976 }
2977 
2978 QgsProcessingPointWidgetWrapper::QgsProcessingPointWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
2979  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
2980 {
2981 
2982 }
2983 
2984 QWidget *QgsProcessingPointWidgetWrapper::createWidget()
2985 {
2986  const QgsProcessingParameterPoint *pointParam = dynamic_cast< const QgsProcessingParameterPoint *>( parameterDefinition() );
2987  switch ( type() )
2988  {
2991  {
2992  mPanel = new QgsProcessingPointPanel( nullptr );
2993  if ( widgetContext().mapCanvas() )
2994  mPanel->setMapCanvas( widgetContext().mapCanvas() );
2995 
2997  mPanel->setAllowNull( true );
2998 
2999  mPanel->setToolTip( parameterDefinition()->toolTip() );
3000 
3001  connect( mPanel, &QgsProcessingPointPanel::changed, this, [ = ]
3002  {
3003  emit widgetValueHasChanged( this );
3004  } );
3005 
3006  if ( mDialog )
3007  setDialog( mDialog ); // setup connections to panel - dialog was previously set before the widget was created
3008  return mPanel;
3009  }
3010 
3012  {
3013  mLineEdit = new QLineEdit();
3014  mLineEdit->setToolTip( tr( "Point as 'x,y'" ) );
3015  connect( mLineEdit, &QLineEdit::textChanged, this, [ = ]( const QString & )
3016  {
3017  emit widgetValueHasChanged( this );
3018  } );
3019  return mLineEdit;
3020  }
3021  }
3022  return nullptr;
3023 }
3024 
3025 void QgsProcessingPointWidgetWrapper::setWidgetContext( const QgsProcessingParameterWidgetContext &context )
3026 {
3028  if ( mPanel && context.mapCanvas() )
3029  mPanel->setMapCanvas( context.mapCanvas() );
3030 }
3031 
3032 void QgsProcessingPointWidgetWrapper::setDialog( QDialog *dialog )
3033 {
3034  mDialog = dialog;
3035  if ( mPanel )
3036  {
3037  connect( mPanel, &QgsProcessingPointPanel::toggleDialogVisibility, mDialog, [ = ]( bool visible )
3038  {
3039  if ( !visible )
3040  mDialog->showMinimized();
3041  else
3042  {
3043  mDialog->showNormal();
3044  mDialog->raise();
3045  mDialog->activateWindow();
3046  }
3047  } );
3048  }
3050 }
3051 
3052 void QgsProcessingPointWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
3053 {
3054  if ( mPanel )
3055  {
3056  if ( !value.isValid() || ( value.type() == QVariant::String && value.toString().isEmpty() ) )
3057  mPanel->clear();
3058  else
3059  {
3060  QgsPointXY p = QgsProcessingParameters::parameterAsPoint( parameterDefinition(), value, context );
3061  QgsCoordinateReferenceSystem crs = QgsProcessingParameters::parameterAsPointCrs( parameterDefinition(), value, context );
3062  mPanel->setValue( p, crs );
3063  }
3064  }
3065  else if ( mLineEdit )
3066  {
3067  const QString v = QgsProcessingParameters::parameterAsString( parameterDefinition(), value, context );
3068  mLineEdit->setText( v );
3069  }
3070 }
3071 
3072 QVariant QgsProcessingPointWidgetWrapper::widgetValue() const
3073 {
3074  if ( mPanel )
3075  {
3076  return mPanel->value();
3077  }
3078  else if ( mLineEdit )
3079  return mLineEdit->text().isEmpty() ? QVariant() : mLineEdit->text();
3080  else
3081  return QVariant();
3082 }
3083 
3084 QStringList QgsProcessingPointWidgetWrapper::compatibleParameterTypes() const
3085 {
3086  return QStringList()
3089 }
3090 
3091 QStringList QgsProcessingPointWidgetWrapper::compatibleOutputTypes() const
3092 {
3093  return QStringList()
3095 }
3096 
3097 QString QgsProcessingPointWidgetWrapper::modelerExpressionFormatString() const
3098 {
3099  return tr( "string of the format 'x,y' or a geometry value (centroid is used)" );
3100 }
3101 
3102 QString QgsProcessingPointWidgetWrapper::parameterType() const
3103 {
3105 }
3106 
3107 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingPointWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
3108 {
3109  return new QgsProcessingPointWidgetWrapper( parameter, type );
3110 }
3111 
3112 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingPointWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
3113 {
3114  return new QgsProcessingPointParameterDefinitionWidget( context, widgetContext, definition, algorithm );
3115 }
3116 
3117 
3118 
3119 //
3120 // QgsProcessingColorWidgetWrapper
3121 //
3122 
3123 
3124 QgsProcessingColorParameterDefinitionWidget::QgsProcessingColorParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
3125  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
3126 {
3127  QVBoxLayout *vlayout = new QVBoxLayout();
3128  vlayout->setMargin( 0 );
3129  vlayout->setContentsMargins( 0, 0, 0, 0 );
3130 
3131  vlayout->addWidget( new QLabel( tr( "Default value" ) ) );
3132 
3133  mDefaultColorButton = new QgsColorButton();
3134  mDefaultColorButton->setShowNull( true );
3135  mAllowOpacity = new QCheckBox( tr( "Allow opacity control" ) );
3136 
3137  if ( const QgsProcessingParameterColor *colorParam = dynamic_cast<const QgsProcessingParameterColor *>( definition ) )
3138  {
3139  const QColor c = QgsProcessingParameters::parameterAsColor( colorParam, colorParam->defaultValue(), context );
3140  if ( !c.isValid() )
3141  mDefaultColorButton->setToNull();
3142  else
3143  mDefaultColorButton->setColor( c );
3144  mAllowOpacity->setChecked( colorParam->opacityEnabled() );
3145  }
3146  else
3147  {
3148  mDefaultColorButton->setToNull();
3149  mAllowOpacity->setChecked( true );
3150  }
3151 
3152  vlayout->addWidget( mDefaultColorButton );
3153  vlayout->addWidget( mAllowOpacity );
3154  setLayout( vlayout );
3155 }
3156 
3157 QgsProcessingParameterDefinition *QgsProcessingColorParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
3158 {
3159  auto param = qgis::make_unique< QgsProcessingParameterColor >( name, description, mDefaultColorButton->color(), mAllowOpacity->isChecked() );
3160  param->setFlags( flags );
3161  return param.release();
3162 }
3163 
3164 QgsProcessingColorWidgetWrapper::QgsProcessingColorWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
3165  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
3166 {
3167 
3168 }
3169 
3170 QWidget *QgsProcessingColorWidgetWrapper::createWidget()
3171 {
3172  const QgsProcessingParameterColor *colorParam = dynamic_cast< const QgsProcessingParameterColor *>( parameterDefinition() );
3173  switch ( type() )
3174  {
3178  {
3179  mColorButton = new QgsColorButton( nullptr );
3180  mColorButton->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
3181 
3183  mColorButton->setShowNull( true );
3184 
3185  mColorButton->setAllowOpacity( colorParam->opacityEnabled() );
3186  mColorButton->setToolTip( parameterDefinition()->toolTip() );
3187  mColorButton->setColorDialogTitle( parameterDefinition()->description() );
3188  if ( colorParam->defaultValue().value< QColor >().isValid() )
3189  {
3190  mColorButton->setDefaultColor( colorParam->defaultValue().value< QColor >() );
3191  }
3192 
3193  connect( mColorButton, &QgsColorButton::colorChanged, this, [ = ]
3194  {
3195  emit widgetValueHasChanged( this );
3196  } );
3197 
3198  return mColorButton;
3199  }
3200  }
3201  return nullptr;
3202 }
3203 
3204 void QgsProcessingColorWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
3205 {
3206  if ( mColorButton )
3207  {
3208  if ( !value.isValid() ||
3209  ( value.type() == QVariant::String && value.toString().isEmpty() )
3210  || ( value.type() == QVariant::Color && !value.value< QColor >().isValid() ) )
3211  mColorButton->setToNull();
3212  else
3213  {
3214  const QColor c = QgsProcessingParameters::parameterAsColor( parameterDefinition(), value, context );
3215  if ( !c.isValid() && mColorButton->showNull() )
3216  mColorButton->setToNull();
3217  else
3218  mColorButton->setColor( c );
3219  }
3220  }
3221 }
3222 
3223 QVariant QgsProcessingColorWidgetWrapper::widgetValue() const
3224 {
3225  if ( mColorButton )
3226  return mColorButton->isNull() ? QVariant() : mColorButton->color();
3227  else
3228  return QVariant();
3229 }
3230 
3231 QStringList QgsProcessingColorWidgetWrapper::compatibleParameterTypes() const
3232 {
3233  return QStringList()
3236 }
3237 
3238 QStringList QgsProcessingColorWidgetWrapper::compatibleOutputTypes() const
3239 {
3240  return QStringList()
3242 }
3243 
3244 QString QgsProcessingColorWidgetWrapper::modelerExpressionFormatString() const
3245 {
3246  return tr( "color style string, e.g. #ff0000 or 255,0,0" );
3247 }
3248 
3249 QString QgsProcessingColorWidgetWrapper::parameterType() const
3250 {
3252 }
3253 
3254 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingColorWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
3255 {
3256  return new QgsProcessingColorWidgetWrapper( parameter, type );
3257 }
3258 
3259 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingColorWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
3260 {
3261  return new QgsProcessingColorParameterDefinitionWidget( context, widgetContext, definition, algorithm );
3262 }
3263 
3264 
3265 //
3266 // QgsProcessingCoordinateOperationWidgetWrapper
3267 //
3268 
3269 QgsProcessingCoordinateOperationParameterDefinitionWidget::QgsProcessingCoordinateOperationParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
3270  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
3271 {
3272  QVBoxLayout *vlayout = new QVBoxLayout();
3273  vlayout->setMargin( 0 );
3274  vlayout->setContentsMargins( 0, 0, 0, 0 );
3275 
3276  vlayout->addWidget( new QLabel( tr( "Default value" ) ) );
3277 
3278  mDefaultLineEdit = new QLineEdit();
3279  if ( const QgsProcessingParameterCoordinateOperation *coordParam = dynamic_cast<const QgsProcessingParameterCoordinateOperation *>( definition ) )
3280  mDefaultLineEdit->setText( QgsProcessingParameters::parameterAsString( coordParam, coordParam->defaultValue(), context ) );
3281  vlayout->addWidget( mDefaultLineEdit );
3282 
3283  mSourceParamComboBox = new QComboBox();
3284  mDestParamComboBox = new QComboBox();
3285  QString initialSource;
3286  QString initialDest;
3287  QgsCoordinateReferenceSystem sourceCrs;
3289  if ( const QgsProcessingParameterCoordinateOperation *itemParam = dynamic_cast<const QgsProcessingParameterCoordinateOperation *>( definition ) )
3290  {
3291  initialSource = itemParam->sourceCrsParameterName();
3292  initialDest = itemParam->destinationCrsParameterName();
3293  sourceCrs = QgsProcessingUtils::variantToCrs( itemParam->sourceCrs(), context );
3294  destCrs = QgsProcessingUtils::variantToCrs( itemParam->destinationCrs(), context );
3295  }
3296 
3297  mSourceParamComboBox->addItem( QString(), QString() );
3298  mDestParamComboBox->addItem( QString(), QString() );
3299  if ( widgetContext.model() )
3300  {
3301  // populate combo box with other model input choices
3302  const QMap<QString, QgsProcessingModelParameter> components = widgetContext.model()->parameterComponents();
3303  for ( auto it = components.constBegin(); it != components.constEnd(); ++it )
3304  {
3305  if ( definition && it->parameterName() == definition->name() )
3306  continue;
3307 
3308  // TODO - we should probably filter this list?
3309  mSourceParamComboBox->addItem( it->parameterName(), it->parameterName() );
3310  mDestParamComboBox->addItem( it->parameterName(), it->parameterName() );
3311  if ( !initialSource.isEmpty() && initialSource == it->parameterName() )
3312  {
3313  mSourceParamComboBox->setCurrentIndex( mSourceParamComboBox->count() - 1 );
3314  }
3315  if ( !initialDest.isEmpty() && initialDest == it->parameterName() )
3316  {
3317  mDestParamComboBox->setCurrentIndex( mDestParamComboBox->count() - 1 );
3318  }
3319  }
3320  }
3321 
3322  if ( mSourceParamComboBox->count() == 1 && !initialSource.isEmpty() )
3323  {
3324  // if no source candidates found, we just add the existing one as a placeholder
3325  mSourceParamComboBox->addItem( initialSource, initialSource );
3326  mSourceParamComboBox->setCurrentIndex( mSourceParamComboBox->count() - 1 );
3327  }
3328  if ( mDestParamComboBox->count() == 1 && !initialDest.isEmpty() )
3329  {
3330  // if no dest candidates found, we just add the existing one as a placeholder
3331  mDestParamComboBox->addItem( initialDest, initialDest );
3332  mDestParamComboBox->setCurrentIndex( mDestParamComboBox->count() - 1 );
3333  }
3334 
3335  vlayout->addWidget( new QLabel( tr( "Source CRS parameter" ) ) );
3336  vlayout->addWidget( mSourceParamComboBox );
3337  vlayout->addWidget( new QLabel( tr( "Destination CRS parameter" ) ) );
3338  vlayout->addWidget( mDestParamComboBox );
3339 
3340  mStaticSourceWidget = new QgsProjectionSelectionWidget();
3341  mStaticSourceWidget->setOptionVisible( QgsProjectionSelectionWidget::CrsNotSet, true );
3342  mStaticSourceWidget->setCrs( sourceCrs );
3343  mStaticDestWidget = new QgsProjectionSelectionWidget();
3344  mStaticDestWidget->setOptionVisible( QgsProjectionSelectionWidget::CrsNotSet, true );
3345  mStaticDestWidget->setCrs( destCrs );
3346 
3347  vlayout->addWidget( new QLabel( tr( "Static source CRS" ) ) );
3348  vlayout->addWidget( mStaticSourceWidget );
3349  vlayout->addWidget( new QLabel( tr( "Static destination CRS" ) ) );
3350  vlayout->addWidget( mStaticDestWidget );
3351 
3352  setLayout( vlayout );
3353 }
3354 
3355 QgsProcessingParameterDefinition *QgsProcessingCoordinateOperationParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
3356 {
3357  auto param = qgis::make_unique< QgsProcessingParameterCoordinateOperation >( name, description, mDefaultLineEdit->text(),
3358  mSourceParamComboBox->currentText(),
3359  mDestParamComboBox->currentText(),
3360  mStaticSourceWidget->crs().isValid() ? QVariant::fromValue( mStaticSourceWidget->crs() ) : QVariant(),
3361  mStaticDestWidget->crs().isValid() ? QVariant::fromValue( mStaticDestWidget->crs() ) : QVariant() );
3362  param->setFlags( flags );
3363  return param.release();
3364 }
3365 
3366 QgsProcessingCoordinateOperationWidgetWrapper::QgsProcessingCoordinateOperationWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
3367  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
3368 {
3369 
3370 }
3371 
3372 QWidget *QgsProcessingCoordinateOperationWidgetWrapper::createWidget()
3373 {
3374  const QgsProcessingParameterCoordinateOperation *coordParam = dynamic_cast< const QgsProcessingParameterCoordinateOperation *>( parameterDefinition() );
3376  mSourceCrs = QgsProcessingUtils::variantToCrs( coordParam->sourceCrs(), c );
3377  mDestCrs = QgsProcessingUtils::variantToCrs( coordParam->destinationCrs(), c );
3378  switch ( type() )
3379  {
3381  {
3382  mOperationWidget = new QgsCoordinateOperationWidget( nullptr );
3383  mOperationWidget->setShowMakeDefault( false );
3384  mOperationWidget->setShowFallbackOption( false );
3385  mOperationWidget->setToolTip( parameterDefinition()->toolTip() );
3386  mOperationWidget->setSourceCrs( mSourceCrs );
3387  mOperationWidget->setDestinationCrs( mDestCrs );
3388  mOperationWidget->setMapCanvas( mCanvas );
3389  if ( !coordParam->defaultValue().toString().isEmpty() )
3390  {
3392  deets.proj = coordParam->defaultValue().toString();
3393  mOperationWidget->setSelectedOperation( deets );
3394  }
3395 
3396  connect( mOperationWidget, &QgsCoordinateOperationWidget::operationChanged, this, [ = ]
3397  {
3398  emit widgetValueHasChanged( this );
3399  } );
3400 
3401  return mOperationWidget;
3402  }
3403 
3406  {
3407  mLineEdit = new QLineEdit();
3408  QHBoxLayout *layout = new QHBoxLayout();
3409  layout->addWidget( mLineEdit, 1 );
3410  connect( mLineEdit, &QLineEdit::textChanged, this, [ = ]
3411  {
3412  emit widgetValueHasChanged( this );
3413  } );
3414 
3415  QToolButton *button = new QToolButton();
3416  button->setText( QString( QChar( 0x2026 ) ) );
3417  connect( button, &QToolButton::clicked, this, [ = ]
3418  {
3419  QgsDatumTransformDialog dlg( mSourceCrs, mDestCrs, false, false, false, qMakePair( -1, -1 ), button, nullptr, mLineEdit->text(), mCanvas );
3420  if ( dlg.exec() )
3421  {
3422  mLineEdit->setText( dlg.selectedDatumTransform().proj );
3423  emit widgetValueHasChanged( this );
3424  }
3425  } );
3426  layout->addWidget( button );
3427 
3428  QWidget *w = new QWidget();
3429  layout->setMargin( 0 );
3430  layout->setContentsMargins( 0, 0, 0, 0 );
3431  w->setLayout( layout );
3432  return w;
3433  }
3434 
3435  }
3436  return nullptr;
3437 }
3438 
3439 void QgsProcessingCoordinateOperationWidgetWrapper::postInitialize( const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
3440 {
3442  switch ( type() )
3443  {
3446  {
3447  for ( const QgsAbstractProcessingParameterWidgetWrapper *wrapper : wrappers )
3448  {
3449  if ( wrapper->parameterDefinition()->name() == static_cast< const QgsProcessingParameterCoordinateOperation * >( parameterDefinition() )->sourceCrsParameterName() )
3450  {
3451  setSourceCrsParameterValue( wrapper->parameterValue() );
3453  {
3454  setSourceCrsParameterValue( wrapper->parameterValue() );
3455  } );
3456  }
3457  if ( wrapper->parameterDefinition()->name() == static_cast< const QgsProcessingParameterCoordinateOperation * >( parameterDefinition() )->destinationCrsParameterName() )
3458  {
3459  setDestinationCrsParameterValue( wrapper->parameterValue() );
3461  {
3462  setDestinationCrsParameterValue( wrapper->parameterValue() );
3463  } );
3464  }
3465  }
3466  break;
3467  }
3468 
3470  break;
3471  }
3472 }
3473 
3474 void QgsProcessingCoordinateOperationWidgetWrapper::setWidgetContext( const QgsProcessingParameterWidgetContext &context )
3475 {
3476  mCanvas = context.mapCanvas();
3477  if ( mOperationWidget )
3478  mOperationWidget->setMapCanvas( context.mapCanvas() );
3479 }
3480 
3481 void QgsProcessingCoordinateOperationWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext & )
3482 {
3483  if ( mOperationWidget )
3484  {
3485  if ( !value.isValid() ||
3486  ( value.type() == QVariant::String ) )
3487  {
3489  deets.proj = value.toString();
3490  mOperationWidget->setSelectedOperation( deets );
3491  }
3492  }
3493  if ( mLineEdit )
3494  {
3495  if ( !value.isValid() ||
3496  ( value.type() == QVariant::String ) )
3497  {
3498  mLineEdit->setText( value.toString() );
3499  }
3500  }
3501 }
3502 
3503 QVariant QgsProcessingCoordinateOperationWidgetWrapper::widgetValue() const
3504 {
3505  if ( mOperationWidget )
3506  return mOperationWidget->selectedOperation().proj;
3507  else if ( mLineEdit )
3508  return mLineEdit->text();
3509  else
3510  return QVariant();
3511 }
3512 
3513 QStringList QgsProcessingCoordinateOperationWidgetWrapper::compatibleParameterTypes() const
3514 {
3515  return QStringList()
3518 }
3519 
3520 QStringList QgsProcessingCoordinateOperationWidgetWrapper::compatibleOutputTypes() const
3521 {
3522  return QStringList()
3524 }
3525 
3526 QString QgsProcessingCoordinateOperationWidgetWrapper::modelerExpressionFormatString() const
3527 {
3528  return tr( "Proj coordinate operation string, e.g. '+proj=pipeline +step +inv...'" );
3529 }
3530 
3531 void QgsProcessingCoordinateOperationWidgetWrapper::setSourceCrsParameterValue( const QVariant &value )
3532 {
3533  QgsProcessingContext *context = nullptr;
3534  std::unique_ptr< QgsProcessingContext > tmpContext;
3535  if ( mProcessingContextGenerator )
3536  context = mProcessingContextGenerator->processingContext();
3537 
3538  if ( !context )
3539  {
3540  tmpContext = qgis::make_unique< QgsProcessingContext >();
3541  context = tmpContext.get();
3542  }
3543 
3544  mSourceCrs = QgsProcessingUtils::variantToCrs( value, *context );
3545  if ( mOperationWidget )
3546  {
3547  mOperationWidget->setSourceCrs( mSourceCrs );
3548  mOperationWidget->setSelectedOperationUsingContext( context->transformContext() );
3549  }
3550 }
3551 
3552 void QgsProcessingCoordinateOperationWidgetWrapper::setDestinationCrsParameterValue( const QVariant &value )
3553 {
3554  QgsProcessingContext *context = nullptr;
3555  std::unique_ptr< QgsProcessingContext > tmpContext;
3556  if ( mProcessingContextGenerator )
3557  context = mProcessingContextGenerator->processingContext();
3558 
3559  if ( !context )
3560  {
3561  tmpContext = qgis::make_unique< QgsProcessingContext >();
3562  context = tmpContext.get();
3563  }
3564 
3565  mDestCrs = QgsProcessingUtils::variantToCrs( value, *context );
3566  if ( mOperationWidget )
3567  {
3568  mOperationWidget->setDestinationCrs( mDestCrs );
3569  mOperationWidget->setSelectedOperationUsingContext( context->transformContext() );
3570  }
3571 }
3572 
3573 QString QgsProcessingCoordinateOperationWidgetWrapper::parameterType() const
3574 {
3576 }
3577 
3578 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingCoordinateOperationWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
3579 {
3580  return new QgsProcessingCoordinateOperationWidgetWrapper( parameter, type );
3581 }
3582 
3583 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingCoordinateOperationWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
3584 {
3585  return new QgsProcessingCoordinateOperationParameterDefinitionWidget( context, widgetContext, definition, algorithm );
3586 }
3587 
3588 
3589 
3590 //
3591 // QgsProcessingFieldPanelWidget
3592 //
3593 
3594 QgsProcessingFieldPanelWidget::QgsProcessingFieldPanelWidget( QWidget *parent, const QgsProcessingParameterField *param )
3595  : QWidget( parent )
3596  , mParam( param )
3597 {
3598  QHBoxLayout *hl = new QHBoxLayout();
3599  hl->setMargin( 0 );
3600  hl->setContentsMargins( 0, 0, 0, 0 );
3601 
3602  mLineEdit = new QLineEdit();
3603  mLineEdit->setEnabled( false );
3604  hl->addWidget( mLineEdit, 1 );
3605 
3606  mToolButton = new QToolButton();
3607  mToolButton->setText( QString( QChar( 0x2026 ) ) );
3608  hl->addWidget( mToolButton );
3609 
3610  setLayout( hl );
3611 
3612  if ( mParam )
3613  {
3614  mLineEdit->setText( tr( "%1 options selected" ).arg( 0 ) );
3615  }
3616 
3617  connect( mToolButton, &QToolButton::clicked, this, &QgsProcessingFieldPanelWidget::showDialog );
3618 }
3619 
3620 void QgsProcessingFieldPanelWidget::setFields( const QgsFields &fields )
3621 {
3622  mFields = fields;
3623 }
3624 
3625 void QgsProcessingFieldPanelWidget::setValue( const QVariant &value )
3626 {
3627  if ( value.isValid() )
3628  mValue = value.type() == QVariant::List ? value.toList() : QVariantList() << value;
3629  else
3630  mValue.clear();
3631 
3632  updateSummaryText();
3633  emit changed();
3634 }
3635 
3636 void QgsProcessingFieldPanelWidget::showDialog()
3637 {
3638  QVariantList availableOptions;
3639  QStringList fieldNames;
3640  availableOptions.reserve( mFields.size() );
3641  for ( const QgsField &field : qgis::as_const( mFields ) )
3642  {
3643  availableOptions << field.name();
3644  }
3645 
3647  if ( panel && panel->dockMode() )
3648  {
3649  QgsProcessingMultipleSelectionPanelWidget *widget = new QgsProcessingMultipleSelectionPanelWidget( availableOptions, mValue );
3650  widget->setPanelTitle( mParam->description() );
3651 
3652  widget->setValueFormatter( []( const QVariant & v ) -> QString
3653  {
3654  return v.toString();
3655  } );
3656 
3657  connect( widget, &QgsProcessingMultipleSelectionPanelWidget::selectionChanged, this, [ = ]()
3658  {
3659  setValue( widget->selectedOptions() );
3660  } );
3661  connect( widget, &QgsProcessingMultipleSelectionPanelWidget::acceptClicked, widget, &QgsPanelWidget::acceptPanel );
3662  panel->openPanel( widget );
3663  }
3664  else
3665  {
3666  QgsProcessingMultipleSelectionDialog dlg( availableOptions, mValue, this, nullptr );
3667 
3668  dlg.setValueFormatter( []( const QVariant & v ) -> QString
3669  {
3670  return v.toString();
3671  } );
3672  if ( dlg.exec() )
3673  {
3674  setValue( dlg.selectedOptions() );
3675  }
3676  }
3677 }
3678 
3679 void QgsProcessingFieldPanelWidget::updateSummaryText()
3680 {
3681  if ( mParam )
3682  mLineEdit->setText( tr( "%1 options selected" ).arg( mValue.count() ) );
3683 }
3684 
3685 
3686 //
3687 // QgsProcessingFieldWidgetWrapper
3688 //
3689 
3690 QgsProcessingFieldParameterDefinitionWidget::QgsProcessingFieldParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
3691  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
3692 {
3693  QVBoxLayout *vlayout = new QVBoxLayout();
3694  vlayout->setMargin( 0 );
3695  vlayout->setContentsMargins( 0, 0, 0, 0 );
3696 
3697  vlayout->addWidget( new QLabel( tr( "Parent layer" ) ) );
3698  mParentLayerComboBox = new QComboBox();
3699 
3700  QString initialParent;
3701  if ( const QgsProcessingParameterField *fieldParam = dynamic_cast<const QgsProcessingParameterField *>( definition ) )
3702  initialParent = fieldParam->parentLayerParameterName();
3703 
3704  if ( widgetContext.model() )
3705  {
3706  // populate combo box with other model input choices
3707  const QMap<QString, QgsProcessingModelParameter> components = widgetContext.model()->parameterComponents();
3708  for ( auto it = components.constBegin(); it != components.constEnd(); ++it )
3709  {
3710  if ( const QgsProcessingParameterFeatureSource *definition = dynamic_cast< const QgsProcessingParameterFeatureSource * >( widgetContext.model()->parameterDefinition( it.value().parameterName() ) ) )
3711  {
3712  mParentLayerComboBox-> addItem( definition->description(), definition->name() );
3713  if ( !initialParent.isEmpty() && initialParent == definition->name() )
3714  {
3715  mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
3716  }
3717  }
3718  else if ( const QgsProcessingParameterVectorLayer *definition = dynamic_cast< const QgsProcessingParameterVectorLayer * >( widgetContext.model()->parameterDefinition( it.value().parameterName() ) ) )
3719  {
3720  mParentLayerComboBox-> addItem( definition->description(), definition->name() );
3721  if ( !initialParent.isEmpty() && initialParent == definition->name() )
3722  {
3723  mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
3724  }
3725  }
3726  }
3727  }
3728 
3729  if ( mParentLayerComboBox->count() == 0 && !initialParent.isEmpty() )
3730  {
3731  // if no parent candidates found, we just add the existing one as a placeholder
3732  mParentLayerComboBox->addItem( initialParent, initialParent );
3733  mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
3734  }
3735 
3736  vlayout->addWidget( mParentLayerComboBox );
3737 
3738  vlayout->addWidget( new QLabel( tr( "Allowed data type" ) ) );
3739  mDataTypeComboBox = new QComboBox();
3740  mDataTypeComboBox->addItem( tr( "Any" ), QgsProcessingParameterField::Any );
3741  mDataTypeComboBox->addItem( tr( "Number" ), QgsProcessingParameterField::Numeric );
3742  mDataTypeComboBox->addItem( tr( "String" ), QgsProcessingParameterField::String );
3743  mDataTypeComboBox->addItem( tr( "Date/time" ), QgsProcessingParameterField::DateTime );
3744  if ( const QgsProcessingParameterField *fieldParam = dynamic_cast<const QgsProcessingParameterField *>( definition ) )
3745  mDataTypeComboBox->setCurrentIndex( mDataTypeComboBox->findData( fieldParam->dataType() ) );
3746 
3747  vlayout->addWidget( mDataTypeComboBox );
3748 
3749  mAllowMultipleCheckBox = new QCheckBox( tr( "Accept multiple fields" ) );
3750  if ( const QgsProcessingParameterField *fieldParam = dynamic_cast<const QgsProcessingParameterField *>( definition ) )
3751  mAllowMultipleCheckBox->setChecked( fieldParam->allowMultiple() );
3752 
3753  vlayout->addWidget( mAllowMultipleCheckBox );
3754 
3755  mDefaultToAllCheckBox = new QCheckBox( tr( "Select all fields by default" ) );
3756  mDefaultToAllCheckBox->setEnabled( mAllowMultipleCheckBox->isChecked() );
3757  if ( const QgsProcessingParameterField *fieldParam = dynamic_cast<const QgsProcessingParameterField *>( definition ) )
3758  mDefaultToAllCheckBox->setChecked( fieldParam->defaultToAllFields() );
3759 
3760  vlayout->addWidget( mDefaultToAllCheckBox );
3761 
3762  connect( mAllowMultipleCheckBox, &QCheckBox::stateChanged, this, [ = ]
3763  {
3764  mDefaultToAllCheckBox->setEnabled( mAllowMultipleCheckBox->isChecked() );
3765  } );
3766 
3767  vlayout->addWidget( new QLabel( tr( "Default value" ) ) );
3768 
3769  mDefaultLineEdit = new QLineEdit();
3770  mDefaultLineEdit->setToolTip( tr( "Default field name, or ; separated list of field names for multiple field parameters" ) );
3771  if ( const QgsProcessingParameterField *fieldParam = dynamic_cast<const QgsProcessingParameterField *>( definition ) )
3772  {
3773  const QStringList fields = QgsProcessingParameters::parameterAsFields( fieldParam, fieldParam->defaultValue(), context );
3774  mDefaultLineEdit->setText( fields.join( ';' ) );
3775  }
3776  vlayout->addWidget( mDefaultLineEdit );
3777 
3778  setLayout( vlayout );
3779 }
3780 
3781 QgsProcessingParameterDefinition *QgsProcessingFieldParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
3782 {
3783  QgsProcessingParameterField::DataType dataType = static_cast< QgsProcessingParameterField::DataType >( mDataTypeComboBox->currentData().toInt() );
3784  auto param = qgis::make_unique< QgsProcessingParameterField >( name, description, mDefaultLineEdit->text(), mParentLayerComboBox->currentData().toString(), dataType, mAllowMultipleCheckBox->isChecked(), false, mDefaultToAllCheckBox->isChecked() );
3785  param->setFlags( flags );
3786  return param.release();
3787 }
3788 
3789 QgsProcessingFieldWidgetWrapper::QgsProcessingFieldWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
3790  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
3791 {
3792 
3793 }
3794 
3795 QWidget *QgsProcessingFieldWidgetWrapper::createWidget()
3796 {
3797  const QgsProcessingParameterField *fieldParam = dynamic_cast< const QgsProcessingParameterField *>( parameterDefinition() );
3798  switch ( type() )
3799  {
3802  {
3803  if ( fieldParam->allowMultiple() )
3804  {
3805  mPanel = new QgsProcessingFieldPanelWidget( nullptr, fieldParam );
3806  mPanel->setToolTip( parameterDefinition()->toolTip() );
3807  connect( mPanel, &QgsProcessingFieldPanelWidget::changed, this, [ = ]
3808  {
3809  emit widgetValueHasChanged( this );
3810  } );
3811  return mPanel;
3812  }
3813  else
3814  {
3815  mComboBox = new QgsFieldComboBox();
3816  mComboBox->setAllowEmptyFieldName( fieldParam->flags() & QgsProcessingParameterDefinition::FlagOptional );
3817 
3818  if ( fieldParam->dataType() == QgsProcessingParameterField::Numeric )
3819  mComboBox->setFilters( QgsFieldProxyModel::Numeric );
3820  else if ( fieldParam->dataType() == QgsProcessingParameterField::String )
3821  mComboBox->setFilters( QgsFieldProxyModel::String );
3822  else if ( fieldParam->dataType() == QgsProcessingParameterField::DateTime )
3824 
3825  mComboBox->setToolTip( parameterDefinition()->toolTip() );
3826  connect( mComboBox, &QgsFieldComboBox::fieldChanged, this, [ = ]( const QString & )
3827  {
3828  emit widgetValueHasChanged( this );
3829  } );
3830  return mComboBox;
3831  }
3832  }
3833 
3835  {
3836  mLineEdit = new QLineEdit();
3837  mLineEdit->setToolTip( QObject::tr( "Name of field (separate field names with ; for multiple field parameters)" ) );
3838  connect( mLineEdit, &QLineEdit::textChanged, this, [ = ]
3839  {
3840  emit widgetValueHasChanged( this );
3841  } );
3842  return mLineEdit;
3843  }
3844 
3845  }
3846  return nullptr;
3847 }
3848 
3849 void QgsProcessingFieldWidgetWrapper::postInitialize( const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
3850 {
3852  switch ( type() )
3853  {
3856  {
3857  for ( const QgsAbstractProcessingParameterWidgetWrapper *wrapper : wrappers )
3858  {
3859  if ( wrapper->parameterDefinition()->name() == static_cast< const QgsProcessingParameterField * >( parameterDefinition() )->parentLayerParameterName() )
3860  {
3861  setParentLayerWrapperValue( wrapper );
3863  {
3864  setParentLayerWrapperValue( wrapper );
3865  } );
3866  break;
3867  }
3868  }
3869  break;
3870  }
3871 
3873  break;
3874  }
3875 }
3876 
3877 void QgsProcessingFieldWidgetWrapper::setParentLayerWrapperValue( const QgsAbstractProcessingParameterWidgetWrapper *parentWrapper )
3878 {
3879  // evaluate value to layer
3880  QgsProcessingContext *context = nullptr;
3881  std::unique_ptr< QgsProcessingContext > tmpContext;
3882  if ( mProcessingContextGenerator )
3883  context = mProcessingContextGenerator->processingContext();
3884 
3885  if ( !context )
3886  {
3887  tmpContext = qgis::make_unique< QgsProcessingContext >();
3888  context = tmpContext.get();
3889  }
3890 
3891  QVariant value = parentWrapper->parameterValue();
3892 
3893  if ( value.canConvert<QgsProcessingFeatureSourceDefinition>() )
3894  {
3895  // input is a QgsProcessingFeatureSourceDefinition - source from it.
3896  // this is normally discouraged, and algorithms should NEVER do this -- but in this case we can make
3897  // certain assumptions due to the fact that we're calling this outside of algorithm/model execution and all sources
3898  // should be real map layers at this stage
3899  QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( value );
3900  value = fromVar.source;
3901  }
3902  QgsVectorLayer *layer = QgsProcessingParameters::parameterAsVectorLayer( parentWrapper->parameterDefinition(), value, *context );
3903  if ( layer && layer->isValid() )
3904  {
3905  // need to grab ownership of layer if required - otherwise layer may be deleted when context
3906  // goes out of scope
3907  std::unique_ptr< QgsMapLayer > ownedLayer( context->takeResultLayer( layer->id() ) );
3908  if ( ownedLayer && ownedLayer->type() == QgsMapLayerType::VectorLayer )
3909  {
3910  mParentLayer.reset( qobject_cast< QgsVectorLayer * >( ownedLayer.release() ) );
3911  layer = mParentLayer.get();
3912  }
3913  else
3914  {
3915  // don't need ownership of this layer - it wasn't owned by context (so e.g. is owned by the project)
3916  }
3917 
3918  if ( mComboBox )
3919  mComboBox->setLayer( layer );
3920  else if ( mPanel )
3921  mPanel->setFields( filterFields( layer->fields() ) );
3922  }
3923  else
3924  {
3925  std::unique_ptr< QgsProcessingFeatureSource > source( QgsProcessingParameters::parameterAsSource( parentWrapper->parameterDefinition(), value, *context ) );
3926  if ( source )
3927  {
3928  const QgsFields fields = source->fields();
3929  if ( mComboBox )
3930  mComboBox->setFields( fields );
3931  else if ( mPanel )
3932  mPanel->setFields( filterFields( fields ) );
3933  }
3934  else
3935  {
3936  if ( mComboBox )
3937  mComboBox->setLayer( nullptr );
3938  else if ( mPanel )
3939  mPanel->setFields( QgsFields() );
3940 
3941  if ( value.isValid() && widgetContext().messageBar() )
3942  {
3943  widgetContext().messageBar()->clearWidgets();
3944  widgetContext().messageBar()->pushMessage( QString(), QObject::tr( "Could not load selected layer/table. Dependent field could not be populated" ),
3945  Qgis::Warning, 5 );
3946  }
3947  }
3948  return;
3949  }
3950 
3951  const QgsProcessingParameterField *fieldParam = static_cast< const QgsProcessingParameterField * >( parameterDefinition() );
3952  if ( mPanel && fieldParam->defaultToAllFields() )
3953  {
3954  QVariantList val;
3955  val.reserve( mPanel->fields().size() );
3956  for ( const QgsField &field : mPanel->fields() )
3957  val << field.name();
3958  setWidgetValue( val, *context );
3959  }
3960  else if ( fieldParam->defaultValue().isValid() )
3961  setWidgetValue( parameterDefinition()->defaultValue(), *context );
3962 }
3963 
3964 void QgsProcessingFieldWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
3965 {
3966  if ( mComboBox )
3967  {
3968  if ( !value.isValid() )
3969  mComboBox->setField( QString() );
3970  else
3971  {
3972  const QString v = QgsProcessingParameters::parameterAsString( parameterDefinition(), value, context );
3973  mComboBox->setField( v );
3974  }
3975  }
3976  else if ( mPanel )
3977  {
3978  QVariantList opts;
3979  if ( value.isValid() )
3980  {
3981  const QStringList v = QgsProcessingParameters::parameterAsFields( parameterDefinition(), value, context );
3982  opts.reserve( v.size() );
3983  for ( const QString &i : v )
3984  opts << i;
3985  }
3986  if ( mPanel )
3987  mPanel->setValue( opts );
3988  }
3989  else if ( mLineEdit )
3990  {
3991  const QgsProcessingParameterField *fieldParam = static_cast< const QgsProcessingParameterField * >( parameterDefinition() );
3992  if ( fieldParam->allowMultiple() )
3993  {
3994  const QStringList v = QgsProcessingParameters::parameterAsFields( parameterDefinition(), value, context );
3995  mLineEdit->setText( v.join( ';' ) );
3996  }
3997  else
3998  {
3999  mLineEdit->setText( QgsProcessingParameters::parameterAsString( parameterDefinition(), value, context ) );
4000  }
4001  }
4002 }
4003 
4004 QVariant QgsProcessingFieldWidgetWrapper::widgetValue() const
4005 {
4006  if ( mComboBox )
4007  return mComboBox->currentField();
4008  else if ( mPanel )
4009  return mPanel->value();
4010  else if ( mLineEdit )
4011  {
4012  const QgsProcessingParameterField *fieldParam = static_cast< const QgsProcessingParameterField * >( parameterDefinition() );
4013  if ( fieldParam->allowMultiple() )
4014  {
4015  return mLineEdit->text().split( ';' );
4016  }
4017  else
4018  return mLineEdit->text();
4019  }
4020  else
4021  return QVariant();
4022 }
4023 
4024 QStringList QgsProcessingFieldWidgetWrapper::compatibleParameterTypes() const
4025 {
4026  return QStringList()
4029 }
4030 
4031 QStringList QgsProcessingFieldWidgetWrapper::compatibleOutputTypes() const
4032 {
4033  return QStringList()
4035 }
4036 
4037 QString QgsProcessingFieldWidgetWrapper::modelerExpressionFormatString() const
4038 {
4039  return tr( "selected field names as an array of names, or semicolon separated string of options (e.g. 'fid;place_name')" );
4040 }
4041 
4042 const QgsVectorLayer *QgsProcessingFieldWidgetWrapper::linkedVectorLayer() const
4043 {
4044  if ( mComboBox && mComboBox->layer() )
4045  return mComboBox->layer();
4046 
4048 }
4049 
4050 QgsFields QgsProcessingFieldWidgetWrapper::filterFields( const QgsFields &fields ) const
4051 {
4052  const QgsProcessingParameterField *fieldParam = static_cast< const QgsProcessingParameterField * >( parameterDefinition() );
4053  QgsFields res;
4054  for ( const QgsField &f : fields )
4055  {
4056  switch ( fieldParam->dataType() )
4057  {
4059  res.append( f );
4060  break;
4061 
4063  if ( f.isNumeric() )
4064  res.append( f );
4065  break;
4066 
4068  if ( f.type() == QVariant::String )
4069  res.append( f );
4070  break;
4071 
4073  if ( f.type() == QVariant::Date || f.type() == QVariant::Time || f.type() == QVariant::DateTime )
4074  res.append( f );
4075  break;
4076  }
4077  }
4078 
4079  return res;
4080 }
4081 
4082 QString QgsProcessingFieldWidgetWrapper::parameterType() const
4083 {
4085 }
4086 
4087 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingFieldWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
4088 {
4089  return new QgsProcessingFieldWidgetWrapper( parameter, type );
4090 }
4091 
4092 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingFieldWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
4093 {
4094  return new QgsProcessingFieldParameterDefinitionWidget( context, widgetContext, definition, algorithm );
4095 }
4096 
4097 //
4098 // QgsProcessingMapThemeWidgetWrapper
4099 //
4100 
4101 
4102 QgsProcessingMapThemeParameterDefinitionWidget::QgsProcessingMapThemeParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
4103  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
4104 {
4105  QVBoxLayout *vlayout = new QVBoxLayout();
4106  vlayout->setMargin( 0 );
4107  vlayout->setContentsMargins( 0, 0, 0, 0 );
4108 
4109  vlayout->addWidget( new QLabel( tr( "Default value" ) ) );
4110 
4111  mDefaultComboBox = new QComboBox();
4112  mDefaultComboBox->addItem( QString(), QVariant( -1 ) );
4113 
4114  const QStringList mapThemes = widgetContext.project() ? widgetContext.project()->mapThemeCollection()->mapThemes() : QgsProject::instance()->mapThemeCollection()->mapThemes();
4115  for ( const QString &theme : mapThemes )
4116  {
4117  mDefaultComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "/mActionShowAllLayers.svg" ) ), theme, theme );
4118  }
4119  mDefaultComboBox->setEditable( true );
4120 
4121  if ( const QgsProcessingParameterMapTheme *themeParam = dynamic_cast<const QgsProcessingParameterMapTheme *>( definition ) )
4122  {
4123  if ( themeParam->defaultValue().isValid() )
4124  mDefaultComboBox->setCurrentText( QgsProcessingParameters::parameterAsString( themeParam, themeParam->defaultValue(), context ) );
4125  else
4126  mDefaultComboBox->setCurrentIndex( mDefaultComboBox->findData( -1 ) );
4127  }
4128  else
4129  mDefaultComboBox->setCurrentIndex( mDefaultComboBox->findData( -1 ) );
4130 
4131  vlayout->addWidget( mDefaultComboBox );
4132 
4133  setLayout( vlayout );
4134 }
4135 
4136 QgsProcessingParameterDefinition *QgsProcessingMapThemeParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
4137 {
4138  QVariant defaultVal;
4139  if ( mDefaultComboBox->currentText().isEmpty() )
4140  defaultVal = QVariant();
4141  else
4142  defaultVal = mDefaultComboBox->currentText();
4143  auto param = qgis::make_unique< QgsProcessingParameterMapTheme>( name, description, defaultVal );
4144  param->setFlags( flags );
4145  return param.release();
4146 }
4147 
4148 
4149 QgsProcessingMapThemeWidgetWrapper::QgsProcessingMapThemeWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
4150  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
4151 {
4152 
4153 }
4154 
4155 QWidget *QgsProcessingMapThemeWidgetWrapper::createWidget()
4156 {
4157  const QgsProcessingParameterMapTheme *themeParam = dynamic_cast< const QgsProcessingParameterMapTheme *>( parameterDefinition() );
4158 
4159  mComboBox = new QComboBox();
4160 
4162  mComboBox->addItem( tr( "[Not selected]" ), QVariant( -1 ) );
4163 
4164  const QStringList mapThemes = widgetContext().project() ? widgetContext().project()->mapThemeCollection()->mapThemes() : QgsProject::instance()->mapThemeCollection()->mapThemes();
4165  for ( const QString &theme : mapThemes )
4166  {
4167  mComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "/mActionShowAllLayers.svg" ) ), theme, theme );
4168  }
4169 
4170  switch ( type() )
4171  {
4174  break;
4175 
4177  mComboBox->setEditable( true );
4178  break;
4179  }
4180 
4181  mComboBox->setToolTip( parameterDefinition()->toolTip() );
4182  connect( mComboBox, qgis::overload<int>::of( &QComboBox::currentIndexChanged ), this, [ = ]( int )
4183  {
4184  emit widgetValueHasChanged( this );
4185  } );
4186 
4187  return mComboBox;
4188 }
4189 
4190 void QgsProcessingMapThemeWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
4191 {
4192  const QString v = QgsProcessingParameters::parameterAsString( parameterDefinition(), value, context );
4193 
4194  if ( !value.isValid() )
4195  mComboBox->setCurrentIndex( mComboBox->findData( QVariant( -1 ) ) );
4196  else
4197  {
4198  if ( mComboBox->isEditable() && mComboBox->findData( v ) == -1 )
4199  {
4200  const QString prev = mComboBox->currentText();
4201  mComboBox->setCurrentText( v );
4202  if ( prev != v )
4203  emit widgetValueHasChanged( this );
4204  }
4205  else
4206  mComboBox->setCurrentIndex( mComboBox->findData( v ) );
4207  }
4208 }
4209 
4210 QVariant QgsProcessingMapThemeWidgetWrapper::widgetValue() const
4211 {
4212  if ( mComboBox )
4213  return mComboBox->currentData().toInt() == -1 ? QVariant() :
4214  !mComboBox->currentData().isValid() && mComboBox->isEditable() ? mComboBox->currentText().isEmpty() ? QVariant() : QVariant( mComboBox->currentText() )
4215  : mComboBox->currentData();
4216  else
4217  return QVariant();
4218 }
4219 
4220 QStringList QgsProcessingMapThemeWidgetWrapper::compatibleParameterTypes() const
4221 {
4222  return QStringList()
4225 }
4226 
4227 QStringList QgsProcessingMapThemeWidgetWrapper::compatibleOutputTypes() const
4228 {
4229  return QStringList()
4231 }
4232 
4233 QString QgsProcessingMapThemeWidgetWrapper::modelerExpressionFormatString() const
4234 {
4235  return tr( "map theme as a string value (e.g. 'base maps')" );
4236 }
4237 
4238 QString QgsProcessingMapThemeWidgetWrapper::parameterType() const
4239 {
4241 }
4242 
4243 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingMapThemeWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
4244 {
4245  return new QgsProcessingMapThemeWidgetWrapper( parameter, type );
4246 }
4247 
4248 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingMapThemeWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
4249 {
4250  return new QgsProcessingMapThemeParameterDefinitionWidget( context, widgetContext, definition, algorithm );
4251 }
4252 
4253 
4254 
4255 //
4256 // QgsProcessingDateTimeWidgetWrapper
4257 //
4258 
4259 
4260 QgsProcessingDateTimeParameterDefinitionWidget::QgsProcessingDateTimeParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
4261  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
4262 {
4263  QVBoxLayout *vlayout = new QVBoxLayout();
4264  vlayout->setMargin( 0 );
4265  vlayout->setContentsMargins( 0, 0, 0, 0 );
4266 
4267  vlayout->addWidget( new QLabel( tr( "Type" ) ) );
4268 
4269  mTypeComboBox = new QComboBox();
4270  mTypeComboBox->addItem( tr( "Date and Time" ), QgsProcessingParameterDateTime::DateTime );
4271  mTypeComboBox->addItem( tr( "Date" ), QgsProcessingParameterDateTime::Date );
4272  mTypeComboBox->addItem( tr( "Time" ), QgsProcessingParameterDateTime::Time );
4273  if ( const QgsProcessingParameterDateTime *datetimeParam = dynamic_cast<const QgsProcessingParameterDateTime *>( definition ) )
4274  mTypeComboBox->setCurrentIndex( mTypeComboBox->findData( datetimeParam->dataType() ) );
4275  else
4276  mTypeComboBox->setCurrentIndex( 0 );
4277  vlayout->addWidget( mTypeComboBox );
4278 
4279  setLayout( vlayout );
4280 }
4281 
4282 QgsProcessingParameterDefinition *QgsProcessingDateTimeParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
4283 {
4284  auto param = qgis::make_unique< QgsProcessingParameterDateTime >( name, description );
4285  param->setDataType( static_cast< QgsProcessingParameterDateTime::Type >( mTypeComboBox->currentData().toInt() ) );
4286  param->setFlags( flags );
4287  return param.release();
4288 }
4289 
4290 
4291 QgsProcessingDateTimeWidgetWrapper::QgsProcessingDateTimeWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
4292  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
4293 {
4294 
4295 }
4296 
4297 QWidget *QgsProcessingDateTimeWidgetWrapper::createWidget()
4298 {
4299  const QgsProcessingParameterDateTime *dateTimeParam = dynamic_cast< const QgsProcessingParameterDateTime *>( parameterDefinition() );
4300 
4301  QgsDateTimeEdit *widget = nullptr;
4302  switch ( dateTimeParam->dataType() )
4303  {
4305  mDateTimeEdit = new QgsDateTimeEdit();
4306  widget = mDateTimeEdit;
4307  break;
4308 
4310  mDateEdit = new QgsDateEdit();
4311  widget = mDateEdit;
4312  break;
4313 
4315  mTimeEdit = new QgsTimeEdit();
4316  widget = mTimeEdit;
4317  break;
4318  }
4319 
4320  if ( dateTimeParam->flags() & QgsProcessingParameterDefinition::FlagOptional )
4321  {
4322  widget->setNullRepresentation( tr( "[Not selected]" ) );
4323  widget->setAllowNull( true );
4324  }
4325  else
4326  {
4327  widget->setAllowNull( false );
4328  }
4329  widget->setToolTip( parameterDefinition()->toolTip() );
4330 
4331  if ( mDateTimeEdit )
4332  {
4333  connect( mDateTimeEdit, &QgsDateTimeEdit::valueChanged, this, [ = ]( const QDateTime & )
4334  {
4335  emit widgetValueHasChanged( this );
4336  } );
4337  }
4338  else if ( mDateEdit )
4339  {
4340  connect( mDateEdit, &QgsDateEdit::dateValueChanged, this, [ = ]( const QDate & )
4341  {
4342  emit widgetValueHasChanged( this );
4343  } );
4344  }
4345  else if ( mTimeEdit )
4346  {
4347  connect( mTimeEdit, &QgsTimeEdit::timeValueChanged, this, [ = ]( const QTime & )
4348  {
4349  emit widgetValueHasChanged( this );
4350  } );
4351  }
4352 
4353  return widget;
4354 }
4355 
4356 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingDateTimeWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
4357 {
4358  return new QgsProcessingDateTimeParameterDefinitionWidget( context, widgetContext, definition, algorithm );
4359 }
4360 
4361 void QgsProcessingDateTimeWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
4362 {
4363  if ( mDateTimeEdit )
4364  {
4365  mDateTimeEdit->setDateTime( QgsProcessingParameters::parameterAsDateTime( parameterDefinition(), value, context ) );
4366  }
4367  else if ( mDateEdit )
4368  {
4369  mDateEdit->setDate( QgsProcessingParameters::parameterAsDate( parameterDefinition(), value, context ) );
4370  }
4371  else if ( mTimeEdit )
4372  {
4373  mTimeEdit->setTime( QgsProcessingParameters::parameterAsTime( parameterDefinition(), value, context ) );
4374  }
4375 }
4376 
4377 QVariant QgsProcessingDateTimeWidgetWrapper::widgetValue() const
4378 {
4379  if ( mDateTimeEdit )
4380  return !mDateTimeEdit->dateTime().isNull() && mDateTimeEdit->dateTime().isValid() ? QVariant( mDateTimeEdit->dateTime() ) : QVariant();
4381  else if ( mDateEdit )
4382  return !mDateEdit->date().isNull() && mDateEdit->date().isValid() ? QVariant( mDateEdit->date() ) : QVariant();
4383  else if ( mTimeEdit )
4384  return !mTimeEdit->time().isNull() && mTimeEdit->time().isValid() ? QVariant( mTimeEdit->time() ) : QVariant();
4385  else
4386  return QVariant();
4387 }
4388 
4389 QStringList QgsProcessingDateTimeWidgetWrapper::compatibleParameterTypes() const
4390 {
4391  return QStringList()
4394 }
4395 
4396 QStringList QgsProcessingDateTimeWidgetWrapper::compatibleOutputTypes() const
4397 {
4398  return QStringList()
4400 }
4401 
4402 QString QgsProcessingDateTimeWidgetWrapper::modelerExpressionFormatString() const
4403 {
4404  const QgsProcessingParameterDateTime *dateTimeParam = dynamic_cast< const QgsProcessingParameterDateTime *>( parameterDefinition() );
4405  if ( dateTimeParam )
4406  {
4407  switch ( dateTimeParam->dataType() )
4408  {
4410  return tr( "datetime value, or a ISO string representation of a datetime" );
4411 
4413  return tr( "date value, or a ISO string representation of a date" );
4414 
4416  return tr( "time value, or a ISO string representation of a time" );
4417  }
4418  }
4419  return QString();
4420 }
4421 
4422 QString QgsProcessingDateTimeWidgetWrapper::parameterType() const
4423 {
4425 }
4426 
4427 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingDateTimeWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
4428 {
4429  return new QgsProcessingDateTimeWidgetWrapper( parameter, type );
4430 }
4431 
4432 
4433 
4434 //
4435 // QgsProcessingProviderConnectionWidgetWrapper
4436 //
4437 
4438 QgsProcessingProviderConnectionParameterDefinitionWidget::QgsProcessingProviderConnectionParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
4439  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
4440 {
4441  const QgsProcessingParameterProviderConnection *connectionParam = dynamic_cast< const QgsProcessingParameterProviderConnection *>( definition );
4442 
4443  QVBoxLayout *vlayout = new QVBoxLayout();
4444  vlayout->setMargin( 0 );
4445  vlayout->setContentsMargins( 0, 0, 0, 0 );
4446 
4447  vlayout->addWidget( new QLabel( tr( "Provider" ) ) );
4448  mProviderComboBox = new QComboBox();
4449  mProviderComboBox->addItem( QObject::tr( "Postgres" ), QStringLiteral( "postgres" ) );
4450  mProviderComboBox->addItem( QObject::tr( "GeoPackage" ), QStringLiteral( "ogr" ) );
4451  mProviderComboBox->addItem( QObject::tr( "Spatialite" ), QStringLiteral( "spatialite" ) );
4452 
4453  vlayout->addWidget( mProviderComboBox );
4454 
4455  vlayout->addWidget( new QLabel( tr( "Default value" ) ) );
4456 
4457  mDefaultEdit = new QLineEdit();
4458  vlayout->addWidget( mDefaultEdit );
4459  setLayout( vlayout );
4460 
4461  if ( connectionParam )
4462  {
4463  mProviderComboBox->setCurrentIndex( mProviderComboBox->findData( connectionParam->providerId() ) );
4464  mDefaultEdit->setText( connectionParam->defaultValue().toString() );
4465  }
4466 }
4467 
4468 QgsProcessingParameterDefinition *QgsProcessingProviderConnectionParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
4469 {
4470  QVariant defaultVal;
4471  if ( mDefaultEdit->text().isEmpty() )
4472  defaultVal = QVariant();
4473  else
4474  defaultVal = mDefaultEdit->text();
4475  auto param = qgis::make_unique< QgsProcessingParameterProviderConnection>( name, description, mProviderComboBox->currentData().toString(), defaultVal );
4476  param->setFlags( flags );
4477  return param.release();
4478 }
4479 
4480 
4481 QgsProcessingProviderConnectionWidgetWrapper::QgsProcessingProviderConnectionWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
4482  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
4483 {
4484 
4485 }
4486 
4487 QWidget *QgsProcessingProviderConnectionWidgetWrapper::createWidget()
4488 {
4489  const QgsProcessingParameterProviderConnection *connectionParam = dynamic_cast< const QgsProcessingParameterProviderConnection *>( parameterDefinition() );
4490 
4491  mProviderComboBox = new QgsProviderConnectionComboBox( connectionParam->providerId() );
4492  if ( connectionParam->flags() & QgsProcessingParameterDefinition::FlagOptional )
4493  mProviderComboBox->setAllowEmptyConnection( true );
4494 
4495  switch ( type() )
4496  {
4499  break;
4501  mProviderComboBox->setEditable( true );
4502  break;
4503  }
4504 
4505  mProviderComboBox->setToolTip( parameterDefinition()->toolTip() );
4506  connect( mProviderComboBox, &QgsProviderConnectionComboBox::currentTextChanged, this, [ = ]( const QString & )
4507  {
4508  if ( mBlockSignals )
4509  return;
4510 
4511  emit widgetValueHasChanged( this );
4512  } );
4513 
4514  return mProviderComboBox;
4515 }
4516 
4517 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingProviderConnectionWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
4518 {
4519  return new QgsProcessingProviderConnectionParameterDefinitionWidget( context, widgetContext, definition, algorithm );
4520 }
4521 
4522 void QgsProcessingProviderConnectionWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
4523 {
4524  const QString v = QgsProcessingParameters::parameterAsConnectionName( parameterDefinition(), value, context );
4525 
4526  if ( !value.isValid() )
4527  mProviderComboBox->setCurrentIndex( -1 );
4528  else
4529  {
4530  if ( mProviderComboBox->isEditable() )
4531  {
4532  const QString prev = mProviderComboBox->currentText();
4533  mBlockSignals++;
4534  mProviderComboBox->setConnection( v );
4535  mProviderComboBox->setCurrentText( v );
4536 
4537  mBlockSignals--;
4538  if ( prev != v )
4539  emit widgetValueHasChanged( this );
4540  }
4541  else
4542  mProviderComboBox->setConnection( v );
4543  }
4544 }
4545 
4546 QVariant QgsProcessingProviderConnectionWidgetWrapper::widgetValue() const
4547 {
4548  if ( mProviderComboBox )
4549  if ( mProviderComboBox->isEditable() )
4550  return mProviderComboBox->currentText().isEmpty() ? QVariant() : QVariant( mProviderComboBox->currentText() );
4551  else
4552  return mProviderComboBox->currentConnection().isEmpty() ? QVariant() : QVariant( mProviderComboBox->currentConnection() );
4553  else
4554  return QVariant();
4555 }
4556 
4557 QStringList QgsProcessingProviderConnectionWidgetWrapper::compatibleParameterTypes() const
4558 {
4559  return QStringList()
4563 }
4564 
4565 QStringList QgsProcessingProviderConnectionWidgetWrapper::compatibleOutputTypes() const
4566 {
4567  return QStringList()
4569 }
4570 
4571 QString QgsProcessingProviderConnectionWidgetWrapper::modelerExpressionFormatString() const
4572 {
4573  return tr( "connection name as a string value" );
4574 }
4575 
4576 QString QgsProcessingProviderConnectionWidgetWrapper::parameterType() const
4577 {
4579 }
4580 
4581 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingProviderConnectionWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
4582 {
4583  return new QgsProcessingProviderConnectionWidgetWrapper( parameter, type );
4584 }
4585 
4586 
4587 
4588 
4589 //
4590 // QgsProcessingDatabaseSchemaWidgetWrapper
4591 //
4592 
4593 QgsProcessingDatabaseSchemaParameterDefinitionWidget::QgsProcessingDatabaseSchemaParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
4594  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
4595 {
4596  const QgsProcessingParameterDatabaseSchema *schemaParam = dynamic_cast< const QgsProcessingParameterDatabaseSchema *>( definition );
4597 
4598  QVBoxLayout *vlayout = new QVBoxLayout();
4599  vlayout->setMargin( 0 );
4600  vlayout->setContentsMargins( 0, 0, 0, 0 );
4601 
4602  mConnectionParamComboBox = new QComboBox();
4603  QString initialConnection;
4604  if ( schemaParam )
4605  {
4606  initialConnection = schemaParam->parentConnectionParameterName();
4607  }
4608 
4609  if ( widgetContext.model() )
4610  {
4611  // populate combo box with other model input choices
4612  const QMap<QString, QgsProcessingModelParameter> components = widgetContext.model()->parameterComponents();
4613  for ( auto it = components.constBegin(); it != components.constEnd(); ++it )
4614  {
4615  if ( definition && it->parameterName() == definition->name() )
4616  continue;
4617 
4618  if ( !dynamic_cast< const QgsProcessingParameterProviderConnection * >( widgetContext.model()->parameterDefinition( it->parameterName() ) ) )
4619  continue;
4620 
4621  mConnectionParamComboBox->addItem( it->parameterName(), it->parameterName() );
4622  if ( !initialConnection.isEmpty() && initialConnection == it->parameterName() )
4623  {
4624  mConnectionParamComboBox->setCurrentIndex( mConnectionParamComboBox->count() - 1 );
4625  }
4626  }
4627  }
4628 
4629  if ( mConnectionParamComboBox->count() == 0 && !initialConnection.isEmpty() )
4630  {
4631  // if no candidates found, we just add the existing one as a placeholder
4632  mConnectionParamComboBox->addItem( initialConnection, initialConnection );
4633  mConnectionParamComboBox->setCurrentIndex( mConnectionParamComboBox->count() - 1 );
4634  }
4635 
4636  vlayout->addWidget( new QLabel( tr( "Provider connection parameter" ) ) );
4637  vlayout->addWidget( mConnectionParamComboBox );
4638 
4639  vlayout->addWidget( new QLabel( tr( "Default value" ) ) );
4640 
4641  mDefaultEdit = new QLineEdit();
4642  vlayout->addWidget( mDefaultEdit );
4643  setLayout( vlayout );
4644 
4645  if ( schemaParam )
4646  {
4647  mDefaultEdit->setText( schemaParam->defaultValue().toString() );
4648  }
4649 }
4650 
4651 QgsProcessingParameterDefinition *QgsProcessingDatabaseSchemaParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
4652 {
4653  QVariant defaultVal;
4654  if ( mDefaultEdit->text().isEmpty() )
4655  defaultVal = QVariant();
4656  else
4657  defaultVal = mDefaultEdit->text();
4658  auto param = qgis::make_unique< QgsProcessingParameterDatabaseSchema>( name, description, mConnectionParamComboBox->currentData().toString(), defaultVal );
4659  param->setFlags( flags );
4660  return param.release();
4661 }
4662 
4663 
4664 QgsProcessingDatabaseSchemaWidgetWrapper::QgsProcessingDatabaseSchemaWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
4665  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
4666 {
4667 
4668 }
4669 
4670 QWidget *QgsProcessingDatabaseSchemaWidgetWrapper::createWidget()
4671 {
4672  const QgsProcessingParameterDatabaseSchema *schemaParam = dynamic_cast< const QgsProcessingParameterDatabaseSchema *>( parameterDefinition() );
4673 
4674  mSchemaComboBox = new QgsDatabaseSchemaComboBox( QString(), QString() );
4676  mSchemaComboBox->setAllowEmptySchema( true );
4677 
4678  switch ( type() )
4679  {
4682  break;
4684  mSchemaComboBox->comboBox()->setEditable( true );
4685  break;
4686  }
4687 
4688  mSchemaComboBox->setToolTip( parameterDefinition()->toolTip() );
4689  connect( mSchemaComboBox->comboBox(), &QComboBox::currentTextChanged, this, [ = ]( const QString & )
4690  {
4691  if ( mBlockSignals )
4692  return;
4693 
4694  emit widgetValueHasChanged( this );
4695  } );
4696 
4697  return mSchemaComboBox;
4698 }
4699 
4700 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingDatabaseSchemaWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
4701 {
4702  return new QgsProcessingDatabaseSchemaParameterDefinitionWidget( context, widgetContext, definition, algorithm );
4703 }
4704 
4705 void QgsProcessingDatabaseSchemaWidgetWrapper::setParentConnectionWrapperValue( const QgsAbstractProcessingParameterWidgetWrapper *parentWrapper )
4706 {
4707  // evaluate value to connection
4708  QgsProcessingContext *context = nullptr;
4709  std::unique_ptr< QgsProcessingContext > tmpContext;
4710  if ( mProcessingContextGenerator )
4711  context = mProcessingContextGenerator->processingContext();
4712 
4713  if ( !context )
4714  {
4715  tmpContext = qgis::make_unique< QgsProcessingContext >();
4716  context = tmpContext.get();
4717  }
4718 
4719  const QVariant value = parentWrapper->parameterValue();
4720  const QString connection = value.isValid() ? QgsProcessingParameters::parameterAsConnectionName( parentWrapper->parameterDefinition(), value, *context ) : QString();
4721 
4722  if ( mSchemaComboBox )
4723  mSchemaComboBox->setConnectionName( connection, dynamic_cast< const QgsProcessingParameterProviderConnection * >( parentWrapper->parameterDefinition() )->providerId() );
4724 
4725  const QgsProcessingParameterDatabaseSchema *schemaParam = static_cast< const QgsProcessingParameterDatabaseSchema * >( parameterDefinition() );
4726  if ( schemaParam->defaultValue().isValid() )
4727  setWidgetValue( parameterDefinition()->defaultValue(), *context );
4728 }
4729 
4730 void QgsProcessingDatabaseSchemaWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
4731 {
4732  const QString v = QgsProcessingParameters::parameterAsSchema( parameterDefinition(), value, context );
4733 
4734  if ( !value.isValid() )
4735  mSchemaComboBox->comboBox()->setCurrentIndex( -1 );
4736  else
4737  {
4738  if ( mSchemaComboBox->comboBox()->isEditable() )
4739  {
4740  const QString prev = mSchemaComboBox->comboBox()->currentText();
4741  mBlockSignals++;
4742  mSchemaComboBox->setSchema( v );
4743  mSchemaComboBox->comboBox()->setCurrentText( v );
4744 
4745  mBlockSignals--;
4746  if ( prev != v )
4747  emit widgetValueHasChanged( this );
4748  }
4749  else
4750  mSchemaComboBox->setSchema( v );
4751  }
4752 }
4753 
4754 QVariant QgsProcessingDatabaseSchemaWidgetWrapper::widgetValue() const
4755 {
4756  if ( mSchemaComboBox )
4757  if ( mSchemaComboBox->comboBox()->isEditable() )
4758  return mSchemaComboBox->comboBox()->currentText().isEmpty() ? QVariant() : QVariant( mSchemaComboBox->comboBox()->currentText() );
4759  else
4760  return mSchemaComboBox->currentSchema().isEmpty() ? QVariant() : QVariant( mSchemaComboBox->currentSchema() );
4761  else
4762  return QVariant();
4763 }
4764 
4765 QStringList QgsProcessingDatabaseSchemaWidgetWrapper::compatibleParameterTypes() const
4766 {
4767  return QStringList()
4771 }
4772 
4773 QStringList QgsProcessingDatabaseSchemaWidgetWrapper::compatibleOutputTypes() const
4774 {
4775  return QStringList()
4777 }
4778 
4779 QString QgsProcessingDatabaseSchemaWidgetWrapper::modelerExpressionFormatString() const
4780 {
4781  return tr( "database schema name as a string value" );
4782 }
4783 
4784 QString QgsProcessingDatabaseSchemaWidgetWrapper::parameterType() const
4785 {
4787 }
4788 
4789 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingDatabaseSchemaWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
4790 {
4791  return new QgsProcessingDatabaseSchemaWidgetWrapper( parameter, type );
4792 }
4793 
4794 void QgsProcessingDatabaseSchemaWidgetWrapper::postInitialize( const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
4795 {
4797  switch ( type() )
4798  {
4801  {
4802  for ( const QgsAbstractProcessingParameterWidgetWrapper *wrapper : wrappers )
4803  {
4804  if ( wrapper->parameterDefinition()->name() == static_cast< const QgsProcessingParameterDatabaseSchema * >( parameterDefinition() )->parentConnectionParameterName() )
4805  {
4806  setParentConnectionWrapperValue( wrapper );
4808  {
4809  setParentConnectionWrapperValue( wrapper );
4810  } );
4811  break;
4812  }
4813  }
4814  break;
4815  }
4816 
4818  break;
4819  }
4820 }
4821 
4822 
4823 
4824 //
4825 // QgsProcessingDatabaseTableWidgetWrapper
4826 //
4827 
4828 QgsProcessingDatabaseTableParameterDefinitionWidget::QgsProcessingDatabaseTableParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
4829  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
4830 {
4831  const QgsProcessingParameterDatabaseTable *tableParam = dynamic_cast< const QgsProcessingParameterDatabaseTable *>( definition );
4832 
4833  QVBoxLayout *vlayout = new QVBoxLayout();
4834  vlayout->setMargin( 0 );
4835  vlayout->setContentsMargins( 0, 0, 0, 0 );
4836 
4837  mConnectionParamComboBox = new QComboBox();
4838  mSchemaParamComboBox = new QComboBox();
4839  QString initialConnection;
4840  QString initialSchema;
4841  if ( tableParam )
4842  {
4843  initialConnection = tableParam->parentConnectionParameterName();
4844  initialSchema = tableParam->parentSchemaParameterName();
4845  }
4846 
4847  if ( widgetContext.model() )
4848  {
4849  // populate combo box with other model input choices
4850  const QMap<QString, QgsProcessingModelParameter> components = widgetContext.model()->parameterComponents();
4851  for ( auto it = components.constBegin(); it != components.constEnd(); ++it )
4852  {
4853  if ( definition && it->parameterName() == definition->name() )
4854  continue;
4855 
4856  if ( dynamic_cast< const QgsProcessingParameterProviderConnection * >( widgetContext.model()->parameterDefinition( it->parameterName() ) ) )
4857  {
4858  mConnectionParamComboBox->addItem( it->parameterName(), it->parameterName() );
4859  if ( !initialConnection.isEmpty() && initialConnection == it->parameterName() )
4860  {
4861  mConnectionParamComboBox->setCurrentIndex( mConnectionParamComboBox->count() - 1 );
4862  }
4863  }
4864  else if ( dynamic_cast< const QgsProcessingParameterDatabaseSchema * >( widgetContext.model()->parameterDefinition( it->parameterName() ) ) )
4865  {
4866  mSchemaParamComboBox->addItem( it->parameterName(), it->parameterName() );
4867  if ( !initialConnection.isEmpty() && initialConnection == it->parameterName() )
4868  {
4869  mSchemaParamComboBox->setCurrentIndex( mSchemaParamComboBox->count() - 1 );
4870  }
4871  }
4872  }
4873  }
4874 
4875  if ( mConnectionParamComboBox->count() == 0 && !initialConnection.isEmpty() )
4876  {
4877  // if no candidates found, we just add the existing one as a placeholder
4878  mConnectionParamComboBox->addItem( initialConnection, initialConnection );
4879  mConnectionParamComboBox->setCurrentIndex( mConnectionParamComboBox->count() - 1 );
4880  }
4881 
4882  if ( mSchemaParamComboBox->count() == 0 && !initialSchema.isEmpty() )
4883  {
4884  // if no candidates found, we just add the existing one as a placeholder
4885  mSchemaParamComboBox->addItem( initialSchema, initialSchema );
4886  mSchemaParamComboBox->setCurrentIndex( mSchemaParamComboBox->count() - 1 );
4887  }
4888 
4889  vlayout->addWidget( new QLabel( tr( "Provider connection parameter" ) ) );
4890  vlayout->addWidget( mConnectionParamComboBox );
4891 
4892  vlayout->addWidget( new QLabel( tr( "Database schema parameter" ) ) );
4893  vlayout->addWidget( mSchemaParamComboBox );
4894 
4895  vlayout->addWidget( new QLabel( tr( "Default value" ) ) );
4896 
4897  mDefaultEdit = new QLineEdit();
4898  vlayout->addWidget( mDefaultEdit );
4899  setLayout( vlayout );
4900 
4901  if ( tableParam )
4902  {
4903  mDefaultEdit->setText( tableParam->defaultValue().toString() );
4904  }
4905 }
4906 
4907 QgsProcessingParameterDefinition *QgsProcessingDatabaseTableParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
4908 {
4909  QVariant defaultVal;
4910  if ( mDefaultEdit->text().isEmpty() )
4911  defaultVal = QVariant();
4912  else
4913  defaultVal = mDefaultEdit->text();
4914  auto param = qgis::make_unique< QgsProcessingParameterDatabaseTable>( name, description,
4915  mConnectionParamComboBox->currentData().toString(),
4916  mSchemaParamComboBox->currentData().toString(),
4917  defaultVal );
4918  param->setFlags( flags );
4919  return param.release();
4920 }
4921 
4922 
4923 QgsProcessingDatabaseTableWidgetWrapper::QgsProcessingDatabaseTableWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
4924  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
4925 {
4926 
4927 }
4928 
4929 QWidget *QgsProcessingDatabaseTableWidgetWrapper::createWidget()
4930 {
4931  const QgsProcessingParameterDatabaseTable *tableParam = dynamic_cast< const QgsProcessingParameterDatabaseTable *>( parameterDefinition() );
4932 
4933  mTableComboBox = new QgsDatabaseTableComboBox( QString(), QString() );
4935  mTableComboBox->setAllowEmptyTable( true );
4936 
4937  if ( type() == QgsProcessingGui::Modeler || tableParam->allowNewTableNames() )
4938  mTableComboBox->comboBox()->setEditable( true );
4939 
4940  mTableComboBox->setToolTip( parameterDefinition()->toolTip() );
4941  connect( mTableComboBox->comboBox(), &QComboBox::currentTextChanged, this, [ = ]( const QString & )
4942  {
4943  if ( mBlockSignals )
4944  return;
4945 
4946  emit widgetValueHasChanged( this );
4947  } );
4948 
4949  return mTableComboBox;
4950 }
4951 
4952 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingDatabaseTableWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
4953 {
4954  return new QgsProcessingDatabaseTableParameterDefinitionWidget( context, widgetContext, definition, algorithm );
4955 }
4956 
4957 void QgsProcessingDatabaseTableWidgetWrapper::setParentConnectionWrapperValue( const QgsAbstractProcessingParameterWidgetWrapper *parentWrapper )
4958 {
4959  // evaluate value to connection
4960  QgsProcessingContext *context = nullptr;
4961  std::unique_ptr< QgsProcessingContext > tmpContext;
4962  if ( mProcessingContextGenerator )
4963  context = mProcessingContextGenerator->processingContext();
4964 
4965  if ( !context )
4966  {
4967  tmpContext = qgis::make_unique< QgsProcessingContext >();
4968  context = tmpContext.get();
4969  }
4970 
4971  QVariant value = parentWrapper->parameterValue();
4972  mConnection = value.isValid() ? QgsProcessingParameters::parameterAsConnectionName( parentWrapper->parameterDefinition(), value, *context ) : QString();
4973  mProvider = dynamic_cast< const QgsProcessingParameterProviderConnection * >( parentWrapper->parameterDefinition() )->providerId();
4974  if ( mTableComboBox && !mSchema.isEmpty() )
4975  {
4976  mTableComboBox->setSchema( mSchema );
4977  mTableComboBox->setConnectionName( mConnection, mProvider );
4978 
4979  const QgsProcessingParameterDatabaseTable *tableParam = static_cast< const QgsProcessingParameterDatabaseTable * >( parameterDefinition() );
4980  if ( tableParam->defaultValue().isValid() )
4981  setWidgetValue( parameterDefinition()->defaultValue(), *context );
4982  }
4983 }
4984 
4985 void QgsProcessingDatabaseTableWidgetWrapper::setParentSchemaWrapperValue( const QgsAbstractProcessingParameterWidgetWrapper *parentWrapper )
4986 {
4987  // evaluate value to schema
4988  QgsProcessingContext *context = nullptr;
4989  std::unique_ptr< QgsProcessingContext > tmpContext;
4990  if ( mProcessingContextGenerator )
4991  context = mProcessingContextGenerator->processingContext();
4992 
4993  if ( !context )
4994  {
4995  tmpContext = qgis::make_unique< QgsProcessingContext >();
4996  context = tmpContext.get();
4997  }
4998 
4999  QVariant value = parentWrapper->parameterValue();
5000  mSchema = value.isValid() ? QgsProcessingParameters::parameterAsSchema( parentWrapper->parameterDefinition(), value, *context ) : QString();
5001 
5002  if ( mTableComboBox && !mSchema.isEmpty() && !mConnection.isEmpty() )
5003  {
5004  mTableComboBox->setSchema( mSchema );
5005  mTableComboBox->setConnectionName( mConnection, mProvider );
5006 
5007  const QgsProcessingParameterDatabaseTable *tableParam = static_cast< const QgsProcessingParameterDatabaseTable * >( parameterDefinition() );
5008  if ( tableParam->defaultValue().isValid() )
5009  setWidgetValue( parameterDefinition()->defaultValue(), *context );
5010  }
5011 
5012 }
5013 
5014 void QgsProcessingDatabaseTableWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
5015 {
5016  const QString v = QgsProcessingParameters::parameterAsDatabaseTableName( parameterDefinition(), value, context );
5017 
5018  if ( !value.isValid() )
5019  mTableComboBox->comboBox()->setCurrentIndex( -1 );
5020  else
5021  {
5022  if ( mTableComboBox->comboBox()->isEditable() )
5023  {
5024  const QString prev = mTableComboBox->comboBox()->currentText();
5025  mBlockSignals++;
5026  mTableComboBox->setTable( v );
5027  mTableComboBox->comboBox()->setCurrentText( v );
5028 
5029  mBlockSignals--;
5030  if ( prev != v )
5031  emit widgetValueHasChanged( this );
5032  }
5033  else
5034  mTableComboBox->setTable( v );
5035  }
5036 }
5037 
5038 QVariant QgsProcessingDatabaseTableWidgetWrapper::widgetValue() const
5039 {
5040  if ( mTableComboBox )
5041  if ( mTableComboBox->comboBox()->isEditable() )
5042  return mTableComboBox->comboBox()->currentText().isEmpty() ? QVariant() : QVariant( mTableComboBox->comboBox()->currentText() );
5043  else
5044  return mTableComboBox->currentTable().isEmpty() ? QVariant() : QVariant( mTableComboBox->currentTable() );
5045  else
5046  return QVariant();
5047 }
5048 
5049 QStringList QgsProcessingDatabaseTableWidgetWrapper::compatibleParameterTypes() const
5050 {
5051  return QStringList()
5055 }
5056 
5057 QStringList QgsProcessingDatabaseTableWidgetWrapper::compatibleOutputTypes() const
5058 {
5059  return QStringList()
5061 }
5062 
5063 QString QgsProcessingDatabaseTableWidgetWrapper::modelerExpressionFormatString() const
5064 {
5065  return tr( "database table name as a string value" );
5066 }
5067 
5068 QString QgsProcessingDatabaseTableWidgetWrapper::parameterType() const
5069 {
5071 }
5072 
5073 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingDatabaseTableWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
5074 {
5075  return new QgsProcessingDatabaseTableWidgetWrapper( parameter, type );
5076 }
5077 
5078 void QgsProcessingDatabaseTableWidgetWrapper::postInitialize( const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
5079 {
5081  switch ( type() )
5082  {
5085  {
5086  for ( const QgsAbstractProcessingParameterWidgetWrapper *wrapper : wrappers )
5087  {
5088  if ( wrapper->parameterDefinition()->name() == static_cast< const QgsProcessingParameterDatabaseTable * >( parameterDefinition() )->parentConnectionParameterName() )
5089  {
5090  setParentConnectionWrapperValue( wrapper );
5092  {
5093  setParentConnectionWrapperValue( wrapper );
5094  } );
5095  }
5096  else if ( wrapper->parameterDefinition()->name() == static_cast< const QgsProcessingParameterDatabaseTable * >( parameterDefinition() )->parentSchemaParameterName() )
5097  {
5098  setParentSchemaWrapperValue( wrapper );
5100  {
5101  setParentSchemaWrapperValue( wrapper );
5102  } );
5103  }
5104  }
5105  break;
5106  }
5107 
5109  break;
5110  }
5111 }
5112 
5113 
5114 //
5115 // QgsProcessingExtentWidgetWrapper
5116 //
5117 
5118 QgsProcessingExtentParameterDefinitionWidget::QgsProcessingExtentParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
5119  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
5120 {
5121  QVBoxLayout *vlayout = new QVBoxLayout();
5122  vlayout->setMargin( 0 );
5123  vlayout->setContentsMargins( 0, 0, 0, 0 );
5124 
5125  vlayout->addWidget( new QLabel( tr( "Default value" ) ) );
5126 
5127  mDefaultWidget = new QgsExtentWidget();
5128  mDefaultWidget->setNullValueAllowed( true, tr( "Not set" ) );
5129  if ( const QgsProcessingParameterExtent *extentParam = dynamic_cast<const QgsProcessingParameterExtent *>( definition ) )
5130  {
5131  if ( extentParam->defaultValue().isValid() )
5132  {
5133  QgsRectangle rect = QgsProcessingParameters::parameterAsExtent( extentParam, extentParam->defaultValue(), context );
5134  QgsCoordinateReferenceSystem crs = QgsProcessingParameters::parameterAsExtentCrs( extentParam, extentParam->defaultValue(), context );
5135  mDefaultWidget->setCurrentExtent( rect, crs );
5136  mDefaultWidget->setOutputExtentFromCurrent();
5137  }
5138  else
5139  {
5140  mDefaultWidget->clear();
5141  }
5142  }
5143 
5144  vlayout->addWidget( mDefaultWidget );
5145  setLayout( vlayout );
5146 }
5147 
5148 QgsProcessingParameterDefinition *QgsProcessingExtentParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
5149 {
5150  const QString defaultVal = mDefaultWidget->isValid() ? QStringLiteral( "%1,%2,%3,%4%5" ).arg(
5151  QString::number( mDefaultWidget->outputExtent().xMinimum(), 'f', 9 ),
5152  QString::number( mDefaultWidget->outputExtent().xMaximum(), 'f', 9 ),
5153  QString::number( mDefaultWidget->outputExtent().yMinimum(), 'f', 9 ),
5154  QString::number( mDefaultWidget->outputExtent().yMaximum(), 'f', 9 ),
5155  mDefaultWidget->outputCrs().isValid() ? QStringLiteral( " [%1]" ).arg( mDefaultWidget->outputCrs().authid() ) : QString()
5156  ) : QString();
5157  auto param = qgis::make_unique< QgsProcessingParameterExtent >( name, description, !defaultVal.isEmpty() ? QVariant( defaultVal ) : QVariant() );
5158  param->setFlags( flags );
5159  return param.release();
5160 }
5161 
5162 
5163 
5164 QgsProcessingExtentWidgetWrapper::QgsProcessingExtentWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
5165  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
5166 {
5167 
5168 }
5169 
5170 QWidget *QgsProcessingExtentWidgetWrapper::createWidget()
5171 {
5172  const QgsProcessingParameterExtent *extentParam = dynamic_cast< const QgsProcessingParameterExtent *>( parameterDefinition() );
5173  switch ( type() )
5174  {
5178  {
5179  mExtentWidget = new QgsExtentWidget( nullptr );
5180  if ( widgetContext().mapCanvas() )
5181  mExtentWidget->setMapCanvas( widgetContext().mapCanvas() );
5182 
5184  mExtentWidget->setNullValueAllowed( true, tr( "Not set" ) );
5185 
5186  mExtentWidget->setToolTip( parameterDefinition()->toolTip() );
5187 
5188  connect( mExtentWidget, &QgsExtentWidget::extentChanged, this, [ = ]
5189  {
5190  emit widgetValueHasChanged( this );
5191  } );
5192 
5193  if ( mDialog && type() != QgsProcessingGui::Modeler )
5194  setDialog( mDialog ); // setup connections to panel - dialog was previously set before the widget was created
5195 
5196  return mExtentWidget;
5197  }
5198  }
5199  return nullptr;
5200 }
5201 
5202 void QgsProcessingExtentWidgetWrapper::setWidgetContext( const QgsProcessingParameterWidgetContext &context )
5203 {
5205  if ( mExtentWidget && context.mapCanvas() && type() != QgsProcessingGui::Modeler )
5206  mExtentWidget->setMapCanvas( context.mapCanvas() );
5207 }
5208 
5209 void QgsProcessingExtentWidgetWrapper::setDialog( QDialog *dialog )
5210 {
5211  mDialog = dialog;
5212  if ( mExtentWidget && mDialog && type() != QgsProcessingGui::Modeler )
5213  {
5214  connect( mExtentWidget, &QgsExtentWidget::toggleDialogVisibility, mDialog, [ = ]( bool visible )
5215  {
5216  if ( !visible )
5217  mDialog->showMinimized();
5218  else
5219  {
5220  mDialog->showNormal();
5221  mDialog->raise();
5222  mDialog->activateWindow();
5223  }
5224  } );
5225  }
5227 }
5228 
5229 void QgsProcessingExtentWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
5230 {
5231  if ( mExtentWidget )
5232  {
5233  if ( !value.isValid() || ( value.type() == QVariant::String && value.toString().isEmpty() ) )
5234  mExtentWidget->clear();
5235  else
5236  {
5237  QgsRectangle r = QgsProcessingParameters::parameterAsExtent( parameterDefinition(), value, context );
5238  QgsCoordinateReferenceSystem crs = QgsProcessingParameters::parameterAsPointCrs( parameterDefinition(), value, context );
5239  mExtentWidget->setCurrentExtent( r, crs );
5240  mExtentWidget->setOutputExtentFromCurrent();
5241  }
5242  }
5243 }
5244 
5245 QVariant QgsProcessingExtentWidgetWrapper::widgetValue() const
5246 {
5247  if ( mExtentWidget )
5248  {
5249  const QString val = mExtentWidget->isValid() ? QStringLiteral( "%1,%2,%3,%4%5" ).arg(
5250  QString::number( mExtentWidget->outputExtent().xMinimum(), 'f', 9 ),
5251  QString::number( mExtentWidget->outputExtent().xMaximum(), 'f', 9 ),
5252  QString::number( mExtentWidget->outputExtent().yMinimum(), 'f', 9 ),
5253  QString::number( mExtentWidget->outputExtent().yMaximum(), 'f', 9 ),
5254  mExtentWidget->outputCrs().isValid() ? QStringLiteral( " [%1]" ).arg( mExtentWidget->outputCrs().authid() ) : QString()
5255  ) : QString();
5256 
5257  return val.isEmpty() ? QVariant() : QVariant( val );
5258  }
5259  else
5260  return QVariant();
5261 }
5262 
5263 QStringList QgsProcessingExtentWidgetWrapper::compatibleParameterTypes() const
5264 {
5265  return QStringList()
5273 
5274 }
5275 
5276 QStringList QgsProcessingExtentWidgetWrapper::compatibleOutputTypes() const
5277 {
5278  return QStringList()
5283 }
5284 
5285 QString QgsProcessingExtentWidgetWrapper::modelerExpressionFormatString() const
5286 {
5287  return tr( "string of the format 'x min,x max,y min,y max' or a geometry value (bounding box is used)" );
5288 }
5289 
5290 QString QgsProcessingExtentWidgetWrapper::parameterType() const
5291 {
5293 }
5294 
5295 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingExtentWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
5296 {
5297  return new QgsProcessingExtentWidgetWrapper( parameter, type );
5298 }
5299 
5300 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingExtentWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
5301 {
5302  return new QgsProcessingExtentParameterDefinitionWidget( context, widgetContext, definition, algorithm );
5303 }
5304 
5305 
5306 
5307 //
5308 // QgsProcessingMapLayerWidgetWrapper
5309 //
5310 
5311 QgsProcessingMapLayerParameterDefinitionWidget::QgsProcessingMapLayerParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
5312  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
5313 {
5314  QVBoxLayout *vlayout = new QVBoxLayout();
5315  vlayout->setMargin( 0 );
5316  vlayout->setContentsMargins( 0, 0, 0, 0 );
5317 
5318  vlayout->addWidget( new QLabel( tr( "Layer type" ) ) );
5319  mLayerTypeComboBox = new QgsCheckableComboBox();
5320  mLayerTypeComboBox->addItem( tr( "Any Map Layer" ), QgsProcessing::TypeMapLayer );
5321  mLayerTypeComboBox->addItem( tr( "Vector (Point)" ), QgsProcessing::TypeVectorPoint );
5322  mLayerTypeComboBox->addItem( tr( "Vector (Line)" ), QgsProcessing::TypeVectorLine );
5323  mLayerTypeComboBox->addItem( tr( "Vector (Polygon)" ), QgsProcessing::TypeVectorPolygon );
5324  mLayerTypeComboBox->addItem( tr( "Vector (Any Geometry Type)" ), QgsProcessing::TypeVectorAnyGeometry );
5325  mLayerTypeComboBox->addItem( tr( "Raster" ), QgsProcessing::TypeRaster );
5326  mLayerTypeComboBox->addItem( tr( "Mesh" ), QgsProcessing::TypeMesh );
5327 
5328  if ( const QgsProcessingParameterMapLayer *layerParam = dynamic_cast<const QgsProcessingParameterMapLayer *>( definition ) )
5329  {
5330  for ( int i : layerParam->dataTypes() )
5331  {
5332  mLayerTypeComboBox->setItemCheckState( mLayerTypeComboBox->findData( i ), Qt::Checked );
5333  }
5334  }
5335 
5336  vlayout->addWidget( mLayerTypeComboBox );
5337 
5338  setLayout( vlayout );
5339 }
5340 
5341 QgsProcessingParameterDefinition *QgsProcessingMapLayerParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
5342 {
5343  QList< int > dataTypes;
5344  for ( const QVariant &v : mLayerTypeComboBox->checkedItemsData() )
5345  dataTypes << v.toInt();
5346 
5347  auto param = qgis::make_unique< QgsProcessingParameterMapLayer >( name, description );
5348  param->setDataTypes( dataTypes );
5349  param->setFlags( flags );
5350  return param.release();
5351 }
5352 
5353 QgsProcessingMapLayerWidgetWrapper::QgsProcessingMapLayerWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
5354  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
5355 {
5356 
5357 }
5358 
5359 QWidget *QgsProcessingMapLayerWidgetWrapper::createWidget()
5360 {
5361  mComboBox = new QgsProcessingMapLayerComboBox( parameterDefinition(), type() );
5362 
5363  switch ( type() )
5364  {
5367  break;
5369  mComboBox->setEditable( true );
5370  break;
5371  }
5372 
5373  mComboBox->setToolTip( parameterDefinition()->toolTip() );
5374 
5375  connect( mComboBox, &QgsProcessingMapLayerComboBox::valueChanged, this, [ = ]()
5376  {
5377  if ( mBlockSignals )
5378  return;
5379 
5380  emit widgetValueHasChanged( this );
5381  } );
5382 
5383  setWidgetContext( widgetContext() );
5384  return mComboBox;
5385 }
5386 
5387 void QgsProcessingMapLayerWidgetWrapper::setWidgetContext( const QgsProcessingParameterWidgetContext &context )
5388 {
5390  if ( mComboBox )
5391  {
5392  mComboBox->setWidgetContext( context );
5393 
5394  if ( !( parameterDefinition()->flags() & QgsProcessingParameterDefinition::FlagOptional ) )
5395  {
5396  // non optional parameter -- if no default value set, default to active layer
5397  if ( !parameterDefinition()->defaultValue().isValid() )
5398  mComboBox->setLayer( context.activeLayer() );
5399  }
5400  }
5401 }
5402 
5403 void QgsProcessingMapLayerWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
5404 {
5405  if ( mComboBox )
5406  mComboBox->setValue( value, context );
5407 }
5408 
5409 QVariant QgsProcessingMapLayerWidgetWrapper::widgetValue() const
5410 {
5411  return mComboBox ? mComboBox->value() : QVariant();
5412 }
5413 
5414 QStringList QgsProcessingMapLayerWidgetWrapper::compatibleParameterTypes() const
5415 {
5416  return QStringList()
5423 }
5424 
5425 QStringList QgsProcessingMapLayerWidgetWrapper::compatibleOutputTypes() const
5426 {
5427  return QStringList()
5433 }
5434 
5435 QString QgsProcessingMapLayerWidgetWrapper::modelerExpressionFormatString() const
5436 {
5437  return tr( "path to a map layer" );
5438 }
5439 
5440 QString QgsProcessingMapLayerWidgetWrapper::parameterType() const
5441 {
5443 }
5444 
5445 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingMapLayerWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
5446 {
5447  return new QgsProcessingMapLayerWidgetWrapper( parameter, type );
5448 }
5449 
5450 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingMapLayerWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
5451 {
5452  return new QgsProcessingMapLayerParameterDefinitionWidget( context, widgetContext, definition, algorithm );
5453 }
5454 
5455 
5456 //
5457 // QgsProcessingRasterLayerWidgetWrapper
5458 //
5459 
5460 QgsProcessingRasterLayerWidgetWrapper::QgsProcessingRasterLayerWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
5461  : QgsProcessingMapLayerWidgetWrapper( parameter, type, parent )
5462 {
5463 
5464 }
5465 
5466 QStringList QgsProcessingRasterLayerWidgetWrapper::compatibleParameterTypes() const
5467 {
5468  return QStringList()
5473 }
5474 
5475 QStringList QgsProcessingRasterLayerWidgetWrapper::compatibleOutputTypes() const
5476 {
5477  return QStringList()
5483 }
5484 
5485 QString QgsProcessingRasterLayerWidgetWrapper::modelerExpressionFormatString() const
5486 {
5487  return tr( "path to a raster layer" );
5488 }
5489 
5490 QString QgsProcessingRasterLayerWidgetWrapper::parameterType() const
5491 {
5493 }
5494 
5495 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingRasterLayerWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
5496 {
5497  return new QgsProcessingRasterLayerWidgetWrapper( parameter, type );
5498 }
5499 
5500 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingRasterLayerWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
5501 {
5502  Q_UNUSED( context );
5503  Q_UNUSED( widgetContext );
5504  Q_UNUSED( definition );
5505  Q_UNUSED( algorithm );
5506 
5507  return nullptr;
5508 }
5509 
5510 
5511 //
5512 // QgsProcessingVectorLayerWidgetWrapper
5513 //
5514 
5515 QgsProcessingVectorLayerParameterDefinitionWidget::QgsProcessingVectorLayerParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
5516  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
5517 {
5518  QVBoxLayout *vlayout = new QVBoxLayout();
5519  vlayout->setMargin( 0 );
5520  vlayout->setContentsMargins( 0, 0, 0, 0 );
5521 
5522  vlayout->addWidget( new QLabel( tr( "Geometry type" ) ) );
5523  mGeometryTypeComboBox = new QgsCheckableComboBox();
5524  mGeometryTypeComboBox->addItem( tr( "Geometry Not Required" ), QgsProcessing::TypeVector );
5525  mGeometryTypeComboBox->addItem( tr( "Point" ), QgsProcessing::TypeVectorPoint );
5526  mGeometryTypeComboBox->addItem( tr( "Line" ), QgsProcessing::TypeVectorLine );
5527  mGeometryTypeComboBox->addItem( tr( "Polygon" ), QgsProcessing::TypeVectorPolygon );
5528  mGeometryTypeComboBox->addItem( tr( "Any Geometry Type" ), QgsProcessing::TypeVectorAnyGeometry );
5529 
5530  if ( const QgsProcessingParameterVectorLayer *vectorParam = dynamic_cast<const QgsProcessingParameterVectorLayer *>( definition ) )
5531  {
5532  for ( int i : vectorParam->dataTypes() )
5533  {
5534  mGeometryTypeComboBox->setItemCheckState( mGeometryTypeComboBox->findData( i ), Qt::Checked );
5535  }
5536  }
5537 
5538  vlayout->addWidget( mGeometryTypeComboBox );
5539 
5540  setLayout( vlayout );
5541 }
5542 
5543 QgsProcessingParameterDefinition *QgsProcessingVectorLayerParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
5544 {
5545  QList< int > dataTypes;
5546  for ( const QVariant &v : mGeometryTypeComboBox->checkedItemsData() )
5547  dataTypes << v.toInt();
5548 
5549  auto param = qgis::make_unique< QgsProcessingParameterVectorLayer >( name, description, dataTypes );
5550  param->setFlags( flags );
5551  return param.release();
5552 }
5553 
5554 
5555 QgsProcessingVectorLayerWidgetWrapper::QgsProcessingVectorLayerWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
5556  : QgsProcessingMapLayerWidgetWrapper( parameter, type, parent )
5557 {
5558 
5559 }
5560 
5561 QStringList QgsProcessingVectorLayerWidgetWrapper::compatibleParameterTypes() const
5562 {
5563  return QStringList()
5568 }
5569 
5570 QStringList QgsProcessingVectorLayerWidgetWrapper::compatibleOutputTypes() const
5571 {
5572  return QStringList()
5578 }
5579 
5580 QString QgsProcessingVectorLayerWidgetWrapper::modelerExpressionFormatString() const
5581 {
5582  return tr( "path to a vector layer" );
5583 }
5584 
5585 QList<int> QgsProcessingVectorLayerWidgetWrapper::compatibleDataTypes( const QgsProcessingParameterDefinition *parameter ) const
5586 {
5587  if ( const QgsProcessingParameterVectorLayer *param = dynamic_cast< const QgsProcessingParameterVectorLayer *>( parameter ) )
5588  return param->dataTypes();
5589  else
5590  return QList< int >();
5591 }
5592 
5593 QString QgsProcessingVectorLayerWidgetWrapper::parameterType() const
5594 {
5596 }
5597 
5598 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingVectorLayerWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
5599 {
5600  return new QgsProcessingVectorLayerWidgetWrapper( parameter, type );
5601 }
5602 
5603 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingVectorLayerWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
5604 {
5605  return new QgsProcessingVectorLayerParameterDefinitionWidget( context, widgetContext, definition, algorithm );
5606 }
5607 
5608 
5609 
5610 //
5611 // QgsProcessingFeatureSourceLayerWidgetWrapper
5612 //
5613 
5614 QgsProcessingFeatureSourceParameterDefinitionWidget::QgsProcessingFeatureSourceParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
5615  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
5616 {
5617  QVBoxLayout *vlayout = new QVBoxLayout();
5618  vlayout->setMargin( 0 );
5619  vlayout->setContentsMargins( 0, 0, 0, 0 );
5620 
5621  vlayout->addWidget( new QLabel( tr( "Geometry type" ) ) );
5622  mGeometryTypeComboBox = new QgsCheckableComboBox();
5623  mGeometryTypeComboBox->addItem( tr( "Geometry Not Required" ), QgsProcessing::TypeVector );
5624  mGeometryTypeComboBox->addItem( tr( "Point" ), QgsProcessing::TypeVectorPoint );
5625  mGeometryTypeComboBox->addItem( tr( "Line" ), QgsProcessing::TypeVectorLine );
5626  mGeometryTypeComboBox->addItem( tr( "Polygon" ), QgsProcessing::TypeVectorPolygon );
5627  mGeometryTypeComboBox->addItem( tr( "Any Geometry Type" ), QgsProcessing::TypeVectorAnyGeometry );
5628 
5629  if ( const QgsProcessingParameterFeatureSource *sourceParam = dynamic_cast<const QgsProcessingParameterFeatureSource *>( definition ) )
5630  {
5631  for ( int i : sourceParam->dataTypes() )
5632  {
5633  mGeometryTypeComboBox->setItemCheckState( mGeometryTypeComboBox->findData( i ), Qt::Checked );
5634  }
5635  }
5636  else
5637  {
5638  mGeometryTypeComboBox->setItemCheckState( mGeometryTypeComboBox->findData( QgsProcessing::TypeVectorAnyGeometry ), Qt::Checked );
5639  }
5640 
5641  vlayout->addWidget( mGeometryTypeComboBox );
5642 
5643  setLayout( vlayout );
5644 }
5645 
5646 QgsProcessingParameterDefinition *QgsProcessingFeatureSourceParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
5647 {
5648  QList< int > dataTypes;
5649  for ( const QVariant &v : mGeometryTypeComboBox->checkedItemsData() )
5650  dataTypes << v.toInt();
5651 
5652  auto param = qgis::make_unique< QgsProcessingParameterFeatureSource >( name, description, dataTypes );
5653  param->setFlags( flags );
5654  return param.release();
5655 }
5656 
5657 QgsProcessingFeatureSourceWidgetWrapper::QgsProcessingFeatureSourceWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
5658  : QgsProcessingMapLayerWidgetWrapper( parameter, type, parent )
5659 {
5660 
5661 }
5662 
5663 QStringList QgsProcessingFeatureSourceWidgetWrapper::compatibleParameterTypes() const
5664 {
5665  return QStringList()
5671 }
5672 
5673 QStringList QgsProcessingFeatureSourceWidgetWrapper::compatibleOutputTypes() const
5674 {
5675  return QStringList()
5681 }
5682 
5683 QString QgsProcessingFeatureSourceWidgetWrapper::modelerExpressionFormatString() const
5684 {
5685  return tr( "path to a vector layer" );
5686 }
5687 
5688 QList<int> QgsProcessingFeatureSourceWidgetWrapper::compatibleDataTypes( const QgsProcessingParameterDefinition *parameter ) const
5689 {
5690  if ( const QgsProcessingParameterFeatureSource *param = dynamic_cast< const QgsProcessingParameterFeatureSource *>( parameter ) )
5691  return param->dataTypes();
5692  else
5693  return QList< int >();
5694 }
5695 
5696 QString QgsProcessingFeatureSourceWidgetWrapper::parameterType() const
5697 {
5699 }
5700 
5701 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingFeatureSourceWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
5702 {
5703  return new QgsProcessingFeatureSourceWidgetWrapper( parameter, type );
5704 }
5705 
5706 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingFeatureSourceWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
5707 {
5708  return new QgsProcessingFeatureSourceParameterDefinitionWidget( context, widgetContext, definition, algorithm );
5709 }
5710 
5711 //
5712 // QgsProcessingMeshLayerWidgetWrapper
5713 //
5714 
5715 QgsProcessingMeshLayerWidgetWrapper::QgsProcessingMeshLayerWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
5716  : QgsProcessingMapLayerWidgetWrapper( parameter, type, parent )
5717 {
5718 
5719 }
5720 
5721 QStringList QgsProcessingMeshLayerWidgetWrapper::compatibleParameterTypes() const
5722 {
5723  return QStringList()
5728 }
5729 
5730 QStringList QgsProcessingMeshLayerWidgetWrapper::compatibleOutputTypes() const
5731 {
5732  return QStringList()
5734  // TODO << QgsProcessingOutputMeshLayer::typeName()
5738 }
5739 
5740 QString QgsProcessingMeshLayerWidgetWrapper::modelerExpressionFormatString() const
5741 {
5742  return tr( "path to a mesh layer" );
5743 }
5744 
5745 QString QgsProcessingMeshLayerWidgetWrapper::parameterType() const
5746 {
5748 }
5749 
5750 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingMeshLayerWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
5751 {
5752  return new QgsProcessingMeshLayerWidgetWrapper( parameter, type );
5753 }
5754 
5755 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingMeshLayerWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
5756 {
5757  Q_UNUSED( context );
5758  Q_UNUSED( widgetContext );
5759  Q_UNUSED( definition );
5760  Q_UNUSED( algorithm );
5761 
5762  return nullptr;
5763 }
5764 
5765 
5766 
5767 //
5768 // QgsProcessingRasterBandPanelWidget
5769 //
5770 
5771 QgsProcessingRasterBandPanelWidget::QgsProcessingRasterBandPanelWidget( QWidget *parent, const QgsProcessingParameterBand *param )
5772  : QWidget( parent )
5773  , mParam( param )
5774 {
5775  QHBoxLayout *hl = new QHBoxLayout();
5776  hl->setMargin( 0 );
5777  hl->setContentsMargins( 0, 0, 0, 0 );
5778 
5779  mLineEdit = new QLineEdit();
5780  mLineEdit->setEnabled( false );
5781  hl->addWidget( mLineEdit, 1 );
5782 
5783  mToolButton = new QToolButton();
5784  mToolButton->setText( QString( QChar( 0x2026 ) ) );
5785  hl->addWidget( mToolButton );
5786 
5787  setLayout( hl );
5788 
5789  if ( mParam )
5790  {
5791  mLineEdit->setText( tr( "%1 bands selected" ).arg( 0 ) );
5792  }
5793 
5794  connect( mToolButton, &QToolButton::clicked, this, &QgsProcessingRasterBandPanelWidget::showDialog );
5795 }
5796 
5797 void QgsProcessingRasterBandPanelWidget::setBands( const QList< int > &bands )
5798 {
5799  mBands = bands;
5800 }
5801 
5802 void QgsProcessingRasterBandPanelWidget::setBandNames( const QHash<int, QString> &names )
5803 {
5804  mBandNames = names;
5805 }
5806 
5807 void QgsProcessingRasterBandPanelWidget::setValue( const QVariant &value )
5808 {
5809  if ( value.isValid() )
5810  mValue = value.type() == QVariant::List ? value.toList() : QVariantList() << value;
5811  else
5812  mValue.clear();
5813 
5814  updateSummaryText();
5815  emit changed();
5816 }
5817 
5818 void QgsProcessingRasterBandPanelWidget::showDialog()
5819 {
5820  QVariantList availableOptions;
5821  QStringList fieldNames;
5822  availableOptions.reserve( mBands.size() );
5823  for ( int band : qgis::as_const( mBands ) )
5824  {
5825  availableOptions << band;
5826  }
5827 
5829  if ( panel && panel->dockMode() )
5830  {
5831  QgsProcessingMultipleSelectionPanelWidget *widget = new QgsProcessingMultipleSelectionPanelWidget( availableOptions, mValue );
5832  widget->setPanelTitle( mParam->description() );
5833 
5834  widget->setValueFormatter( [this]( const QVariant & v ) -> QString
5835  {
5836  int band = v.toInt();
5837  return mBandNames.contains( band ) ? mBandNames.value( band ) : v.toString();
5838  } );
5839 
5840  connect( widget, &QgsProcessingMultipleSelectionPanelWidget::selectionChanged, this, [ = ]()
5841  {
5842  setValue( widget->selectedOptions() );
5843  } );
5844  connect( widget, &QgsProcessingMultipleSelectionPanelWidget::acceptClicked, widget, &QgsPanelWidget::acceptPanel );
5845  panel->openPanel( widget );
5846  }
5847  else
5848  {
5849  QgsProcessingMultipleSelectionDialog dlg( availableOptions, mValue, this, nullptr );
5850 
5851  dlg.setValueFormatter( [this]( const QVariant & v ) -> QString
5852  {
5853  int band = v.toInt();
5854  return mBandNames.contains( band ) ? mBandNames.value( band ) : v.toString();
5855  } );
5856  if ( dlg.exec() )
5857  {
5858  setValue( dlg.selectedOptions() );
5859  }
5860  }
5861 }
5862 
5863 void QgsProcessingRasterBandPanelWidget::updateSummaryText()
5864 {
5865  if ( mParam )
5866  mLineEdit->setText( tr( "%1 bands selected" ).arg( mValue.count() ) );
5867 }
5868 
5869 
5870 
5871 //
5872 // QgsProcessingBandWidgetWrapper
5873 //
5874 
5875 QgsProcessingBandParameterDefinitionWidget::QgsProcessingBandParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
5876  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
5877 {
5878  QVBoxLayout *vlayout = new QVBoxLayout();
5879  vlayout->setMargin( 0 );
5880  vlayout->setContentsMargins( 0, 0, 0, 0 );
5881 
5882  vlayout->addWidget( new QLabel( tr( "Default value" ) ) );
5883 
5884  mDefaultLineEdit = new QLineEdit();
5885  mDefaultLineEdit->setToolTip( tr( "Band number (separate bands with ; for multiple band parameters)" ) );
5886  if ( const QgsProcessingParameterBand *bandParam = dynamic_cast<const QgsProcessingParameterBand *>( definition ) )
5887  {
5888  const QList< int > bands = QgsProcessingParameters::parameterAsInts( bandParam, bandParam->defaultValue(), context );
5889  QStringList defVal;
5890  for ( int b : bands )
5891  {
5892  defVal << QString::number( b );
5893  }
5894 
5895  mDefaultLineEdit->setText( defVal.join( ';' ) );
5896  }
5897  vlayout->addWidget( mDefaultLineEdit );
5898 
5899  vlayout->addWidget( new QLabel( tr( "Parent layer" ) ) );
5900  mParentLayerComboBox = new QComboBox();
5901 
5902  QString initialParent;
5903  if ( const QgsProcessingParameterBand *bandParam = dynamic_cast<const QgsProcessingParameterBand *>( definition ) )
5904  initialParent = bandParam->parentLayerParameterName();
5905 
5906  if ( widgetContext.model() )
5907  {
5908  // populate combo box with other model input choices
5909  const QMap<QString, QgsProcessingModelParameter> components = widgetContext.model()->parameterComponents();
5910  for ( auto it = components.constBegin(); it != components.constEnd(); ++it )
5911  {
5912  if ( const QgsProcessingParameterRasterLayer *definition = dynamic_cast< const QgsProcessingParameterRasterLayer * >( widgetContext.model()->parameterDefinition( it.value().parameterName() ) ) )
5913  {
5914  mParentLayerComboBox-> addItem( definition->description(), definition->name() );
5915  if ( !initialParent.isEmpty() && initialParent == definition->name() )
5916  {
5917  mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
5918  }
5919  }
5920  }
5921  }
5922 
5923  if ( mParentLayerComboBox->count() == 0 && !initialParent.isEmpty() )
5924  {
5925  // if no parent candidates found, we just add the existing one as a placeholder
5926  mParentLayerComboBox->addItem( initialParent, initialParent );
5927  mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
5928  }
5929 
5930  vlayout->addWidget( mParentLayerComboBox );
5931 
5932  mAllowMultipleCheckBox = new QCheckBox( tr( "Allow multiple" ) );
5933  if ( const QgsProcessingParameterBand *bandParam = dynamic_cast<const QgsProcessingParameterBand *>( definition ) )
5934  mAllowMultipleCheckBox->setChecked( bandParam->allowMultiple() );
5935 
5936  vlayout->addWidget( mAllowMultipleCheckBox );
5937  setLayout( vlayout );
5938 }
5939 
5940 QgsProcessingParameterDefinition *QgsProcessingBandParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
5941 {
5942  auto param = qgis::make_unique< QgsProcessingParameterBand >( name, description, mDefaultLineEdit->text().split( ';' ), mParentLayerComboBox->currentData().toString(), false, mAllowMultipleCheckBox->isChecked() );
5943  param->setFlags( flags );
5944  return param.release();
5945 }
5946 
5947 QgsProcessingBandWidgetWrapper::QgsProcessingBandWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
5948  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
5949 {
5950 
5951 }
5952 
5953 QWidget *QgsProcessingBandWidgetWrapper::createWidget()
5954 {
5955  const QgsProcessingParameterBand *bandParam = dynamic_cast< const QgsProcessingParameterBand *>( parameterDefinition() );
5956  switch ( type() )
5957  {
5960  {
5961  if ( bandParam->allowMultiple() )
5962  {
5963  mPanel = new QgsProcessingRasterBandPanelWidget( nullptr, bandParam );
5964  mPanel->setToolTip( parameterDefinition()->toolTip() );
5965  connect( mPanel, &QgsProcessingRasterBandPanelWidget::changed, this, [ = ]
5966  {
5967  emit widgetValueHasChanged( this );
5968  } );
5969  return mPanel;
5970  }
5971  else
5972  {
5973  mComboBox = new QgsRasterBandComboBox();
5974  mComboBox->setShowNotSetOption( bandParam->flags() & QgsProcessingParameterDefinition::FlagOptional );
5975 
5976  mComboBox->setToolTip( parameterDefinition()->toolTip() );
5977  connect( mComboBox, &QgsRasterBandComboBox::bandChanged, this, [ = ]( int )
5978  {
5979  emit widgetValueHasChanged( this );
5980  } );
5981  return mComboBox;
5982  }
5983  }
5984 
5986  {
5987  mLineEdit = new QLineEdit();
5988  mLineEdit->setToolTip( QObject::tr( "Band number (separate bands with ; for multiple band parameters)" ) );
5989  connect( mLineEdit, &QLineEdit::textChanged, this, [ = ]
5990  {
5991  emit widgetValueHasChanged( this );
5992  } );
5993  return mLineEdit;
5994  }
5995 
5996  }
5997  return nullptr;
5998 }
5999 
6000 void QgsProcessingBandWidgetWrapper::postInitialize( const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
6001 {
6003  switch ( type() )
6004  {
6007  {
6008  for ( const QgsAbstractProcessingParameterWidgetWrapper *wrapper : wrappers )
6009  {
6010  if ( wrapper->parameterDefinition()->name() == static_cast< const QgsProcessingParameterBand * >( parameterDefinition() )->parentLayerParameterName() )
6011  {
6012  setParentLayerWrapperValue( wrapper );
6014  {
6015  setParentLayerWrapperValue( wrapper );
6016  } );
6017  break;
6018  }
6019  }
6020  break;
6021  }
6022 
6024  break;
6025  }
6026 }
6027 
6028 void QgsProcessingBandWidgetWrapper::setParentLayerWrapperValue( const QgsAbstractProcessingParameterWidgetWrapper *parentWrapper )
6029 {
6030  // evaluate value to layer
6031  QgsProcessingContext *context = nullptr;
6032  std::unique_ptr< QgsProcessingContext > tmpContext;
6033  if ( mProcessingContextGenerator )
6034  context = mProcessingContextGenerator->processingContext();
6035 
6036  if ( !context )
6037  {
6038  tmpContext = qgis::make_unique< QgsProcessingContext >();
6039  context = tmpContext.get();
6040  }
6041 
6042  QVariant value = parentWrapper->parameterValue();
6043 
6044  QgsRasterLayer *layer = QgsProcessingParameters::parameterAsRasterLayer( parentWrapper->parameterDefinition(), value, *context );
6045  if ( layer && layer->isValid() )
6046  {
6047  // need to grab ownership of layer if required - otherwise layer may be deleted when context
6048  // goes out of scope
6049  std::unique_ptr< QgsMapLayer > ownedLayer( context->takeResultLayer( layer->id() ) );
6050  if ( ownedLayer && ownedLayer->type() == QgsMapLayerType::RasterLayer )
6051  {
6052  mParentLayer.reset( qobject_cast< QgsRasterLayer * >( ownedLayer.release() ) );
6053  layer = mParentLayer.get();
6054  }
6055  else
6056  {
6057  // don't need ownership of this layer - it wasn't owned by context (so e.g. is owned by the project)
6058  }
6059 
6060  if ( mComboBox )
6061  mComboBox->setLayer( layer );
6062  else if ( mPanel )
6063  {
6064  QgsRasterDataProvider *provider = layer->dataProvider();
6065  if ( provider && layer->isValid() )
6066  {
6067  //fill available bands
6068  int nBands = provider->bandCount();
6069  QList< int > bands;
6070  QHash< int, QString > bandNames;
6071  for ( int i = 1; i <= nBands; ++i )
6072  {
6073  bandNames.insert( i, QgsRasterBandComboBox::displayBandName( provider, i ) );
6074  bands << i;
6075  }
6076  mPanel->setBands( bands );
6077  mPanel->setBandNames( bandNames );
6078  }
6079  }
6080  }
6081  else
6082  {
6083  if ( mComboBox )
6084  mComboBox->setLayer( nullptr );
6085  else if ( mPanel )
6086  mPanel->setBands( QList< int >() );
6087 
6088  if ( value.isValid() && widgetContext().messageBar() )
6089  {
6090  widgetContext().messageBar()->clearWidgets();
6091  widgetContext().messageBar()->pushMessage( QString(), QObject::tr( "Could not load selected layer/table. Dependent bands could not be populated" ),
6092  Qgis::Warning, 5 );
6093  }
6094  }
6095 
6096  if ( parameterDefinition()->defaultValue().isValid() )
6097  setWidgetValue( parameterDefinition()->defaultValue(), *context );
6098 }
6099 
6100 void QgsProcessingBandWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
6101 {
6102  if ( mComboBox )
6103  {
6104  if ( !value.isValid() )
6105  mComboBox->setBand( -1 );
6106  else
6107  {
6108  const int v = QgsProcessingParameters::parameterAsInt( parameterDefinition(), value, context );
6109  mComboBox->setBand( v );
6110  }
6111  }
6112  else if ( mPanel )
6113  {
6114  QVariantList opts;
6115  if ( value.isValid() )
6116  {
6117  const QList< int > v = QgsProcessingParameters::parameterAsInts( parameterDefinition(), value, context );
6118  opts.reserve( v.size() );
6119  for ( int i : v )
6120  opts << i;
6121  }
6122  if ( mPanel )
6123  mPanel->setValue( value.isValid() ? opts : QVariant() );
6124  }
6125  else if ( mLineEdit )
6126  {
6127  const QgsProcessingParameterBand *bandParam = static_cast< const QgsProcessingParameterBand * >( parameterDefinition() );
6128  if ( bandParam->allowMultiple() )
6129  {
6130  const QList< int > v = QgsProcessingParameters::parameterAsInts( parameterDefinition(), value, context );
6131  QStringList opts;
6132  opts.reserve( v.size() );
6133  for ( int i : v )
6134  opts << QString::number( i );
6135  mLineEdit->setText( value.isValid() && !opts.empty() ? opts.join( ';' ) : QString() );
6136  }
6137  else
6138  {
6139  if ( value.isValid() )
6140  mLineEdit->setText( QString::number( QgsProcessingParameters::parameterAsInt( parameterDefinition(), value, context ) ) );
6141  else
6142  mLineEdit->clear();
6143  }
6144  }
6145 }
6146 
6147 QVariant QgsProcessingBandWidgetWrapper::widgetValue() const
6148 {
6149  if ( mComboBox )
6150  return mComboBox->currentBand() == -1 ? QVariant() : mComboBox->currentBand();
6151  else if ( mPanel )
6152  return !mPanel->value().toList().isEmpty() ? mPanel->value() : QVariant();
6153  else if ( mLineEdit )
6154  {
6155  const QgsProcessingParameterBand *bandParam = static_cast< const QgsProcessingParameterBand * >( parameterDefinition() );
6156  if ( bandParam->allowMultiple() )
6157  {
6158  const QStringList parts = mLineEdit->text().split( ';', QString::SkipEmptyParts );
6159  QVariantList res;
6160  res.reserve( parts.count() );
6161  for ( const QString &s : parts )
6162  {
6163  bool ok = false;
6164  int band = s.toInt( &ok );
6165  if ( ok )
6166  res << band;
6167  }
6168  return res.isEmpty() ? QVariant() : res;
6169  }
6170  else
6171  {
6172  return mLineEdit->text().isEmpty() ? QVariant() : mLineEdit->text();
6173  }
6174  }
6175  else
6176  return QVariant();
6177 }
6178 
6179 QStringList QgsProcessingBandWidgetWrapper::compatibleParameterTypes() const
6180 {
6181  return QStringList()
6184 }
6185 
6186 QStringList QgsProcessingBandWidgetWrapper::compatibleOutputTypes() const
6187 {
6188  return QStringList()
6190 }
6191 
6192 QString QgsProcessingBandWidgetWrapper::modelerExpressionFormatString() const
6193 {
6194  return tr( "selected band numbers as an array of numbers, or semicolon separated string of options (e.g. '1;3')" );
6195 }
6196 
6197 QString QgsProcessingBandWidgetWrapper::parameterType() const
6198 {
6200 }
6201 
6202 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingBandWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
6203 {
6204  return new QgsProcessingBandWidgetWrapper( parameter, type );
6205 }
6206 
6207 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingBandWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
6208 {
6209  return new QgsProcessingBandParameterDefinitionWidget( context, widgetContext, definition, algorithm );
6210 }
6211 
6212 
6213 
6214 //
6215 // QgsProcessingMultipleLayerPanelWidget
6216 //
6217 
6218 QgsProcessingMultipleLayerPanelWidget::QgsProcessingMultipleLayerPanelWidget( QWidget *parent, const QgsProcessingParameterMultipleLayers *param )
6219  : QWidget( parent )
6220  , mParam( param )
6221 {
6222  QHBoxLayout *hl = new QHBoxLayout();
6223  hl->setMargin( 0 );
6224  hl->setContentsMargins( 0, 0, 0, 0 );
6225 
6226  mLineEdit = new QLineEdit();
6227  mLineEdit->setEnabled( false );
6228  hl->addWidget( mLineEdit, 1 );
6229 
6230  mToolButton = new QToolButton();
6231  mToolButton->setText( QString( QChar( 0x2026 ) ) );
6232  hl->addWidget( mToolButton );
6233 
6234  setLayout( hl );
6235 
6236  if ( mParam )
6237  {
6238  mLineEdit->setText( tr( "%1 inputs selected" ).arg( 0 ) );
6239  }
6240 
6241  connect( mToolButton, &QToolButton::clicked, this, &QgsProcessingMultipleLayerPanelWidget::showDialog );
6242 }
6243 
6244 void QgsProcessingMultipleLayerPanelWidget::setValue( const QVariant &value )
6245 {
6246  if ( value.isValid() )
6247  mValue = value.type() == QVariant::List ? value.toList() : QVariantList() << value;
6248  else
6249  mValue.clear();
6250 
6251  updateSummaryText();
6252  emit changed();
6253 }
6254 
6255 void QgsProcessingMultipleLayerPanelWidget::setProject( QgsProject *project )
6256 {
6257  mProject = project;
6258 }
6259 
6260 void QgsProcessingMultipleLayerPanelWidget::setModel( QgsProcessingModelAlgorithm *model, const QString &modelChildAlgorithmID )
6261 {
6262  mModel = model;
6263  if ( !model )
6264  return;
6265 
6266  switch ( mParam->layerType() )
6267  {
6269  mModelSources = model->availableSourcesForChild( modelChildAlgorithmID, QStringList() << QgsProcessingParameterFile::typeName(),
6270  QStringList() << QgsProcessingOutputFile::typeName() );
6271  break;
6272 
6274  {
6275  mModelSources = model->availableSourcesForChild( modelChildAlgorithmID, QStringList() << QgsProcessingParameterRasterLayer::typeName()
6278  QStringList() << QgsProcessingOutputFile::typeName()
6281  break;
6282  }
6283 
6285  {
6286  mModelSources = model->availableSourcesForChild( modelChildAlgorithmID, QStringList() << QgsProcessingParameterMeshLayer::typeName()
6289  QStringList() << QgsProcessingOutputFile::typeName()
6291  break;
6292  }
6293 
6295  {
6296  mModelSources = model->availableSourcesForChild( modelChildAlgorithmID, QStringList() << QgsProcessingParameterFeatureSource::typeName()
6300  QStringList() << QgsProcessingOutputFile::typeName()
6303  QList< int >() << QgsProcessing::TypeVector );
6304  break;
6305  }
6306 
6308  {
6309  mModelSources = model->availableSourcesForChild( modelChildAlgorithmID, QStringList() << QgsProcessingParameterFeatureSource::typeName()
6313  QStringList() << QgsProcessingOutputFile::typeName()
6316  break;
6317  }
6318 
6320  {
6321  mModelSources = model->availableSourcesForChild( modelChildAlgorithmID, QStringList() << QgsProcessingParameterFeatureSource::typeName()
6325  QStringList() << QgsProcessingOutputFile::typeName()
6329  break;
6330  }
6331 
6333  {
6334  mModelSources = model->availableSourcesForChild( modelChildAlgorithmID, QStringList() << QgsProcessingParameterFeatureSource::typeName()
6338  QStringList() << QgsProcessingOutputFile::typeName()
6342  break;
6343  }
6344 
6346  {
6347  mModelSources = model->availableSourcesForChild( modelChildAlgorithmID, QStringList() << QgsProcessingParameterFeatureSource::typeName()
6351  QStringList() << QgsProcessingOutputFile::typeName()
6355  break;
6356  }
6357 
6359  {
6360  mModelSources = model->availableSourcesForChild( modelChildAlgorithmID, QStringList() << QgsProcessingParameterFeatureSource::typeName()
6366  QStringList() << QgsProcessingOutputFile::typeName()
6369  // << QgsProcessingOutputMeshLayer::typeName()
6371  break;
6372  }
6373  }
6374 }
6375 
6376 void QgsProcessingMultipleLayerPanelWidget::showDialog()
6377 {
6379  if ( panel && panel->dockMode() )
6380  {
6381  QgsProcessingMultipleInputPanelWidget *widget = new QgsProcessingMultipleInputPanelWidget( mParam, mValue, mModelSources, mModel );
6382  widget->setPanelTitle( mParam->description() );
6383  widget->setProject( mProject );
6384  connect( widget, &QgsProcessingMultipleSelectionPanelWidget::selectionChanged, this, [ = ]()
6385  {
6386  setValue( widget->selectedOptions() );
6387  } );
6388  connect( widget, &QgsProcessingMultipleSelectionPanelWidget::acceptClicked, widget, &QgsPanelWidget::acceptPanel );
6389  panel->openPanel( widget );
6390  }
6391  else
6392  {
6393  QgsProcessingMultipleInputDialog dlg( mParam, mValue, mModelSources, mModel, this, nullptr );
6394  dlg.setProject( mProject );
6395  if ( dlg.exec() )
6396  {
6397  setValue( dlg.selectedOptions() );
6398  }
6399  }
6400 }
6401 
6402 void QgsProcessingMultipleLayerPanelWidget::updateSummaryText()
6403 {
6404  if ( mParam )
6405  mLineEdit->setText( tr( "%1 inputs selected" ).arg( mValue.count() ) );
6406 }
6407 
6408 //
6409 // QgsProcessingMultipleLayerWidgetWrapper
6410 //
6411 
6412 QgsProcessingMultipleLayerParameterDefinitionWidget::QgsProcessingMultipleLayerParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
6413  : QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
6414 {
6415  QVBoxLayout *vlayout = new QVBoxLayout();
6416  vlayout->setMargin( 0 );
6417  vlayout->setContentsMargins( 0, 0, 0, 0 );
6418 
6419  vlayout->addWidget( new QLabel( tr( "Allowed layer type" ) ) );
6420  mLayerTypeComboBox = new QComboBox();
6421  mLayerTypeComboBox->addItem( tr( "Any Map Layer" ), QgsProcessing::TypeMapLayer );
6422  mLayerTypeComboBox->addItem( tr( "Vector (No Geometry Required)" ), QgsProcessing::TypeVector );
6423  mLayerTypeComboBox->addItem( tr( "Vector (Point)" ), QgsProcessing::TypeVectorPoint );
6424  mLayerTypeComboBox->addItem( tr( "Vector (Line)" ), QgsProcessing::TypeVectorLine );
6425  mLayerTypeComboBox->addItem( tr( "Vector (Polygon)" ), QgsProcessing::TypeVectorPolygon );
6426  mLayerTypeComboBox->addItem( tr( "Any Geometry Type" ), QgsProcessing::TypeVectorAnyGeometry );
6427  mLayerTypeComboBox->addItem( tr( "Raster" ), QgsProcessing::TypeRaster );
6428  mLayerTypeComboBox->addItem( tr( "File" ), QgsProcessing::TypeFile );
6429  mLayerTypeComboBox->addItem( tr( "Mesh" ), QgsProcessing::TypeMesh );
6430  if ( const QgsProcessingParameterMultipleLayers *layersParam = dynamic_cast<const QgsProcessingParameterMultipleLayers *>( definition ) )
6431  mLayerTypeComboBox->setCurrentIndex( mLayerTypeComboBox->findData( layersParam->layerType() ) );
6432 
6433  vlayout->addWidget( mLayerTypeComboBox );
6434  setLayout( vlayout );
6435 }
6436 
6437 QgsProcessingParameterDefinition *QgsProcessingMultipleLayerParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
6438 {
6439  auto param = qgis::make_unique< QgsProcessingParameterMultipleLayers >( name, description, static_cast< QgsProcessing::SourceType >( mLayerTypeComboBox->currentData().toInt() ) );
6440  param->setFlags( flags );
6441  return param.release();
6442 }
6443 
6444 QgsProcessingMultipleLayerWidgetWrapper::QgsProcessingMultipleLayerWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
6445  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
6446 {
6447 
6448 }
6449 
6450 QWidget *QgsProcessingMultipleLayerWidgetWrapper::createWidget()
6451 {
6452  const QgsProcessingParameterMultipleLayers *layerParam = dynamic_cast< const QgsProcessingParameterMultipleLayers *>( parameterDefinition() );
6453 
6454  mPanel = new QgsProcessingMultipleLayerPanelWidget( nullptr, layerParam );
6455  mPanel->setToolTip( parameterDefinition()->toolTip() );
6456  mPanel->setProject( widgetContext().project() );
6457  mPanel->setModel( widgetContext().model(), widgetContext().modelChildAlgorithmId() );
6458  connect( mPanel, &QgsProcessingMultipleLayerPanelWidget::changed, this, [ = ]
6459  {
6460  emit widgetValueHasChanged( this );
6461  } );
6462  return mPanel;
6463 }
6464 
6465 void QgsProcessingMultipleLayerWidgetWrapper::setWidgetContext( const QgsProcessingParameterWidgetContext &context )
6466 {
6468  if ( mPanel )
6469  {
6470  mPanel->setProject( context.project() );
6471  mPanel->setModel( widgetContext().model(), widgetContext().modelChildAlgorithmId() );
6472  }
6473 }
6474 
6475 void QgsProcessingMultipleLayerWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
6476 {
6477  if ( mPanel )
6478  {
6479  QVariantList opts;
6480  if ( value.isValid() )
6481  {
6482  const QList< QgsMapLayer * > v = QgsProcessingParameters::parameterAsLayerList( parameterDefinition(), value, context );
6483  opts.reserve( v.size() );
6484  for ( const QgsMapLayer *l : v )
6485  opts << l->source();
6486  }
6487 
6488  for ( const QVariant &v : value.toList() )
6489  {
6490  if ( v.canConvert< QgsProcessingModelChildParameterSource >() )
6491  {
6492  const QgsProcessingModelChildParameterSource source = v.value< QgsProcessingModelChildParameterSource >();
6493  opts << QVariant::fromValue( source );
6494  }
6495  }
6496 
6497  if ( mPanel )
6498  mPanel->setValue( value.isValid() ? opts : QVariant() );
6499  }
6500 }
6501 
6502 QVariant QgsProcessingMultipleLayerWidgetWrapper::widgetValue() const
6503 {
6504  if ( mPanel )
6505  return !mPanel->value().toList().isEmpty() ? mPanel->value() : QVariant();
6506  else
6507  return QVariant();
6508 }
6509 
6510 QStringList QgsProcessingMultipleLayerWidgetWrapper::compatibleParameterTypes() const
6511 {
6512  return QStringList()
6520 }
6521 
6522 QStringList QgsProcessingMultipleLayerWidgetWrapper::compatibleOutputTypes() const
6523 {
6524  return QStringList()
6531 }
6532 
6533 QString QgsProcessingMultipleLayerWidgetWrapper::modelerExpressionFormatString() const
6534 {
6535  return tr( "an array of layer paths, or semicolon separated string of layer paths" );
6536 }
6537 
6538 QString QgsProcessingMultipleLayerWidgetWrapper::parameterType() const
6539 {
6541 }
6542 
6543 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingMultipleLayerWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
6544 {
6545  return new QgsProcessingMultipleLayerWidgetWrapper( parameter, type );
6546 }
6547 
6548 QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingMultipleLayerWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
6549 {
6550  return new QgsProcessingMultipleLayerParameterDefinitionWidget( context, widgetContext, definition, algorithm );
6551 }
6552 
6553 
6554 //
6555 // QgsProcessingOutputWidgetWrapper
6556 //
6557 
6558 QgsProcessingOutputWidgetWrapper::QgsProcessingOutputWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
6559  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
6560 {
6561 
6562 }
6563 
6564 QWidget *QgsProcessingOutputWidgetWrapper::createWidget()
6565 {
6566  const QgsProcessingDestinationParameter *destParam = dynamic_cast< const QgsProcessingDestinationParameter * >( parameterDefinition() );
6567  switch ( type() )
6568  {
6571  {
6572  mOutputWidget = new QgsProcessingLayerOutputDestinationWidget( destParam, false );
6573  if ( mProcessingContextGenerator )
6574  mOutputWidget->setContext( mProcessingContextGenerator->processingContext() );
6575  if ( mParametersGenerator )
6576  mOutputWidget->registerProcessingParametersGenerator( mParametersGenerator );
6577  mOutputWidget->setToolTip( parameterDefinition()->toolTip() );
6578 
6579  connect( mOutputWidget, &QgsProcessingLayerOutputDestinationWidget::destinationChanged, this, [ = ]()
6580  {
6581  if ( mBlockSignals )
6582  return;
6583 
6584  emit widgetValueHasChanged( this );
6585  } );
6586 
6587  if ( type() == QgsProcessingGui::Standard
6591  mOutputWidget->addOpenAfterRunningOption();
6592 
6593  return mOutputWidget;
6594  }
6596  break;
6597  }
6598 
6599  return nullptr;
6600 }
6601 
6602 
6603 void QgsProcessingOutputWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext & )
6604 {
6605  if ( mOutputWidget )
6606  mOutputWidget->setValue( value );
6607 }
6608 
6609 QVariant QgsProcessingOutputWidgetWrapper::widgetValue() const
6610 {
6611  if ( mOutputWidget )
6612  return mOutputWidget->value();
6613 
6614  return QVariant();
6615 }
6616 
6617 QVariantMap QgsProcessingOutputWidgetWrapper::customProperties() const
6618 {
6619  QVariantMap res;
6620  if ( mOutputWidget )
6621  res.insert( QStringLiteral( "OPEN_AFTER_RUNNING" ), mOutputWidget->openAfterRunning() );
6622  return res;
6623 }
6624 
6625 QStringList QgsProcessingOutputWidgetWrapper::compatibleParameterTypes() const
6626 {
6627  return QStringList()
6634 }
6635 
6636 QStringList QgsProcessingOutputWidgetWrapper::compatibleOutputTypes() const
6637 {
6638  return QStringList()
6642 }
6643 
6644 //
6645 // QgsProcessingFeatureSinkWidgetWrapper
6646 //
6647 
6648 QgsProcessingFeatureSinkWidgetWrapper::QgsProcessingFeatureSinkWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
6649  : QgsProcessingOutputWidgetWrapper( parameter, type, parent )
6650 {
6651 
6652 }
6653 
6654 QString QgsProcessingFeatureSinkWidgetWrapper::parameterType() const
6655 {
6657 }
6658 
6659 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingFeatureSinkWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
6660 {
6661  return new QgsProcessingFeatureSinkWidgetWrapper( parameter, type );
6662 }
6663 
6664 QString QgsProcessingFeatureSinkWidgetWrapper::modelerExpressionFormatString() const
6665 {
6666  return tr( "path to layer destination" );
6667 }
6668 
6669 //
6670 // QgsProcessingFeatureSinkWidgetWrapper
6671 //
6672 
6673 QgsProcessingVectorDestinationWidgetWrapper::QgsProcessingVectorDestinationWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
6674  : QgsProcessingOutputWidgetWrapper( parameter, type, parent )
6675 {
6676 
6677 }
6678 
6679 QString QgsProcessingVectorDestinationWidgetWrapper::parameterType() const
6680 {
6682 }
6683 
6684 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingVectorDestinationWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
6685 {
6686  return new QgsProcessingVectorDestinationWidgetWrapper( parameter, type );
6687 }
6688 
6689 QString QgsProcessingVectorDestinationWidgetWrapper::modelerExpressionFormatString() const
6690 {
6691  return tr( "path to layer destination" );
6692 }
6693 
6694 //
6695 // QgsProcessingFeatureSinkWidgetWrapper
6696 //
6697 
6698 QgsProcessingRasterDestinationWidgetWrapper::QgsProcessingRasterDestinationWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
6699  : QgsProcessingOutputWidgetWrapper( parameter, type, parent )
6700 {
6701 
6702 }
6703 
6704 QString QgsProcessingRasterDestinationWidgetWrapper::parameterType() const
6705 {
6707 }
6708 
6709 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingRasterDestinationWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
6710 {
6711  return new QgsProcessingRasterDestinationWidgetWrapper( parameter, type );
6712 }
6713 
6714 QString QgsProcessingRasterDestinationWidgetWrapper::modelerExpressionFormatString() const
6715 {
6716  return tr( "path to layer destination" );
6717 }
6718 
6719 //
6720 // QgsProcessingFileDestinationWidgetWrapper
6721 //
6722 
6723 QgsProcessingFileDestinationWidgetWrapper::QgsProcessingFileDestinationWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
6724  : QgsProcessingOutputWidgetWrapper( parameter, type, parent )
6725 {
6726 
6727 }
6728 
6729 QString QgsProcessingFileDestinationWidgetWrapper::parameterType() const
6730 {
6732 }
6733 
6734 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingFileDestinationWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
6735 {
6736  return new QgsProcessingFileDestinationWidgetWrapper( parameter, type );
6737 }
6738 
6739 QString QgsProcessingFileDestinationWidgetWrapper::modelerExpressionFormatString() const
6740 {
6741  return tr( "path to file destination" );
6742 }
6743 
6744 //
6745 // QgsProcessingFolderDestinationWidgetWrapper
6746 //
6747 
6748 QgsProcessingFolderDestinationWidgetWrapper::QgsProcessingFolderDestinationWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
6749  : QgsProcessingOutputWidgetWrapper( parameter, type, parent )
6750 {
6751 
6752 }
6753 
6754 QString QgsProcessingFolderDestinationWidgetWrapper::parameterType() const
6755 {
6757 }
6758 
6759 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingFolderDestinationWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
6760 {
6761  return new QgsProcessingFolderDestinationWidgetWrapper( parameter, type );
6762 }
6763 
6764 QString QgsProcessingFolderDestinationWidgetWrapper::modelerExpressionFormatString() const
6765 {
6766  return tr( "path to folder destination" );
6767 }
6768 
QgsFieldProxyModel::Numeric
@ Numeric
All numeric fields.
Definition: qgsfieldproxymodel.h:45
QgsProcessingParameterMatrix
Definition: qgsprocessingparameters.h:1670
qgscolorbutton.h
QgsDateTimeEdit
The QgsDateTimeEdit class is a QDateTimeEdit with the capability of setting/reading null date/times.
Definition: qgsdatetimeedit.h:36
QgsProcessingParameterWidgetContext::activeLayer
QgsMapLayer * activeLayer() const
Returns the current active layer.
Definition: qgsprocessingwidgetwrapper.cpp:84
QgsProcessingParameterWidgetContext
Definition: qgsprocessingwidgetwrapper.h:99
QgsFieldProxyModel::Time
@ Time
Time fields.
Definition: qgsfieldproxymodel.h:47
QgsRasterBandComboBox::bandChanged
void bandChanged(int band)
Emitted when the currently selected band changes.
QgsFileWidget::fileChanged
void fileChanged(const QString &path)
Emitted whenever the current file or directory path is changed.
QgsProcessingParameterDatabaseSchema::parentConnectionParameterName
QString parentConnectionParameterName() const
Returns the name of the parent connection parameter, or an empty string if this is not set.
Definition: qgsprocessingparameters.cpp:7155
QgsProcessingParameters::parameterAsMatrix
static QVariantList parameterAsMatrix(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a matrix/table of values.
Definition: qgsprocessingparameters.cpp:1441
QgsLayoutItemComboBox
The QgsLayoutItemComboBox class is a combo box which displays items of a matching type from a layout.
Definition: qgslayoutitemcombobox.h:34
QgsCoordinateOperationWidget
Definition: qgscoordinateoperationwidget.h:33
QgsProcessingParameterDistance::defaultUnit
QgsUnitTypes::DistanceUnit defaultUnit() const
Returns the default distance unit for the parameter.
Definition: qgsprocessingparameters.h:1984
QgsProcessingParameterNumber::Double
@ Double
Double/float values.
Definition: qgsprocessingparameters.h:1846
QgsProcessingParameterField::String
@ String
Accepts string fields.
Definition: qgsprocessingparameters.h:2504
QgsProcessingParameterField::DataType
DataType
Field data types.
Definition: qgsprocessingparameters.h:2500
QgsProcessingParameterProviderConnection::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:3635
QgsPointXY::y
double y
Definition: qgspointxy.h:48
qgsprocessingmatrixmodelerwidget.h
QgsMapThemeCollection::mapThemes
QStringList mapThemes
Definition: qgsmapthemecollection.h:48
qgsprojectionselectionwidget.h
QgsProcessingParameters::parameterAsCrs
static QgsCoordinateReferenceSystem parameterAsCrs(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a coordinate reference system.
Definition: qgsprocessingparameters.cpp:955
QgsLayoutComboBox
The QgsLayoutComboBox class is a combo box which displays available layouts from a QgsLayoutManager.
Definition: qgslayoutcombobox.h:30
QgsProcessingParameters::parameterAsConnectionName
static QString parameterAsConnectionName(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a connection name string.
Definition: qgsprocessingparameters.cpp:1850
QgsProcessingParameterRasterDestination::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:2962
QgsProcessingParameterEnum::allowMultiple
bool allowMultiple() const
Returns true if the parameter allows multiple selected values.
Definition: qgsprocessingparameters.cpp:3844
qgsdoublespinbox.h
QgsProcessingParameterField::Numeric
@ Numeric
Accepts numeric fields.
Definition: qgsprocessingparameters.h:2503
QgsApplication::getThemeIcon
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
Definition: qgsapplication.cpp:605
QgsProcessingParameterDatabaseTable::parentConnectionParameterName
QString parentConnectionParameterName() const
Returns the name of the parent connection parameter, or an empty string if this is not set.
Definition: qgsprocessingparameters.cpp:7295
QgsFieldProxyModel::DateTime
@ DateTime
Datetime fieldss.
Definition: qgsfieldproxymodel.h:49
QgsLayoutItemRegistry::ItemType
ItemType
Item types.
Definition: qgslayoutitemregistry.h:306
QgsProcessingParameters::parameterAsEnums
static QList< int > parameterAsEnums(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to list of enum values.
Definition: qgsprocessingparameters.cpp:445
qgsrasterbandcombobox.h
qgscoordinateoperationwidget.h
qgsmapcanvas.h
QgsProcessingParameterNumber
Definition: qgsprocessingparameters.h:1838
QgsMapLayerType::VectorLayer
@ VectorLayer
qgsprocessingmaplayercombobox.h
qgsmapthemecollection.h
QgsFieldProxyModel::Date
@ Date
Date or datetime fields.
Definition: qgsfieldproxymodel.h:46
QgsFields::isEmpty
bool isEmpty() const
Checks whether the container is empty.
Definition: qgsfields.cpp:128
QgsUnitTypes::DistanceUnknownUnit
@ DistanceUnknownUnit
Unknown distance unit.
Definition: qgsunittypes.h:78
QgsProcessingParameterDefinition::description
QString description() const
Returns the description for the parameter.
Definition: qgsprocessingparameters.h:470
QgsMapLayer::isValid
bool isValid() const
Returns the status of the layer.
Definition: qgsmaplayer.cpp:656
QgsPanelWidget::findParentPanel
static QgsPanelWidget * findParentPanel(QWidget *widget)
Traces through the parents of a widget to find if it is contained within a QgsPanelWidget widget.
Definition: qgspanelwidget.cpp:49
QgsProcessingParameterWidgetContext::mapCanvas
QgsMapCanvas * mapCanvas() const
Returns the map canvas associated with the widget.
Definition: qgsprocessingwidgetwrapper.cpp:39
algorithm
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into allowing algorithms to be written in pure substantial changes are required in order to port existing x Processing algorithms for QGIS x The most significant changes are outlined not GeoAlgorithm For algorithms which operate on features one by consider subclassing the QgsProcessingFeatureBasedAlgorithm class This class allows much of the boilerplate code for looping over features from a vector layer to be bypassed and instead requires implementation of a processFeature method Ensure that your algorithm(or algorithm 's parent class) implements the new pure virtual createInstance(self) call
QgsProcessingParameters::parameterAsDatabaseTableName
static QString parameterAsDatabaseTableName(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a database table name.
Definition: qgsprocessingparameters.cpp:1880
QgsMapCanvas::mapSettings
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
Definition: qgsmapcanvas.cpp:390
QgsProcessingParameterDatabaseTable::parentSchemaParameterName
QString parentSchemaParameterName() const
Returns the name of the parent schema parameter, or an empty string if this is not set.
Definition: qgsprocessingparameters.cpp:7305
QgsProcessingContext::takeResultLayer
QgsMapLayer * takeResultLayer(const QString &id)
Takes the result map layer with matching id from the context and transfers ownership of it back to th...
Definition: qgsprocessingcontext.cpp:108
QgsMapMouseEvent::snapPoint
QgsPointXY snapPoint()
snapPoint will snap the points using the map canvas snapping utils configuration
Definition: qgsmapmouseevent.cpp:43
crs
const QgsCoordinateReferenceSystem & crs
Definition: qgswfsgetfeature.cpp:105
QgsProcessingParameters::parameterAsFields
static QStringList parameterAsFields(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a list of fields.
Definition: qgsprocessingparameters.cpp:1695
QgsApplication::getThemeCursor
static QCursor getThemeCursor(Cursor cursor)
Helper to get a theme cursor.
Definition: qgsapplication.cpp:635
QgsProcessingParameterDefinition::flags
Flags flags() const
Returns any flags associated with the parameter.
Definition: qgsprocessingparameters.h:496
QgsProcessingParameterDefinition::metadata
QVariantMap metadata() const
Returns the parameter's freeform metadata.
Definition: qgsprocessingparameters.h:556
QgsUnitTypes::unitType
static Q_INVOKABLE QgsUnitTypes::DistanceUnitType unitType(QgsUnitTypes::DistanceUnit unit)
Returns the type for a distance unit.
Definition: qgsunittypes.cpp:73
QgsProcessingParameterFile::Folder
@ Folder
Parameter is a folder.
Definition: qgsprocessingparameters.h:1575
QgsProcessingParameterMapTheme
Definition: qgsprocessingparameters.h:3460
Qgis::Warning
@ Warning
Definition: qgis.h:104
QgsCoordinateOperationWidget::OperationDetails
Coordinate operation details.
Definition: qgscoordinateoperationwidget.h:39
QgsProcessingParameterFile::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:1591
QgsProcessing::TypeVectorPolygon
@ TypeVectorPolygon
Vector polygon layers.
Definition: qgsprocessing.h:50
QgsProjectionSelectionWidget::crsChanged
void crsChanged(const QgsCoordinateReferenceSystem &)
Emitted when the selected CRS is changed.
QgsFields
Definition: qgsfields.h:44
QgsAbstractProcessingParameterWidgetWrapper::setWidgetContext
virtual void setWidgetContext(const QgsProcessingParameterWidgetContext &context)
Sets the context in which the Processing parameter widget is shown, e.g., the parent model algorithm,...
Definition: qgsprocessingwidgetwrapper.cpp:121
QgsDateEdit::dateValueChanged
void dateValueChanged(const QDate &date)
Signal emitted whenever the date changes.
QgsMapCanvas
Definition: qgsmapcanvas.h:83
QgsPanelWidget::openPanel
void openPanel(QgsPanelWidget *panel)
Open a panel or dialog depending on dock mode setting If dock mode is true this method will emit the ...
Definition: qgspanelwidget.cpp:79
QgsMapTool::deactivate
virtual void deactivate()
called when map tool is being deactivated
Definition: qgsmaptool.cpp:99
QgsProcessingParameters::parameterAsExtentCrs
static QgsCoordinateReferenceSystem parameterAsExtentCrs(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Returns the coordinate reference system associated with an extent parameter value.
Definition: qgsprocessingparameters.cpp:1219
qgslayoutmanager.h
QgsProcessingParameterLayoutItem::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:3231
qgsfilterlineedit.h
QgsFileWidget::GetFile
@ GetFile
Select a single file.
Definition: qgsfilewidget.h:66
QgsDatumTransformDialog
Definition: qgsdatumtransformdialog.h:34
QgsProcessingParameters::parameterAsDate
static QDate parameterAsDate(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static date value.
Definition: qgsprocessingparameters.cpp:343
QgsFilterLineEdit
Definition: qgsfilterlineedit.h:39
QgsProviderConnectionComboBox
The QgsProviderConnectionComboBox class is a combo box which displays the list of connections registe...
Definition: qgsproviderconnectioncombobox.h:49
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:458
QgsProcessingParameterVectorDestination::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:2887
QgsProjectionSelectionWidget
A widget for selecting a projection.
Definition: qgsprojectionselectionwidget.h:38
QgsProcessingParameterMultipleLayers::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:1770
QgsProcessingParameterFile::fileFilter
QString fileFilter() const
Returns the file filter string for file destinations compatible with this parameter.
Definition: qgsprocessingparameters.cpp:2865
QgsProcessingParameterDefinition
Definition: qgsprocessingparameters.h:330
QgsProcessing::TypeVectorLine
@ TypeVectorLine
Vector line layers.
Definition: qgsprocessing.h:49
QgsSettings
Definition: qgssettings.h:61
QgsProcessingParameterFeatureSource
Definition: qgsprocessingparameters.h:2612
QgsProcessingParameterMapLayer
Definition: qgsprocessingparameters.h:2456
FALLTHROUGH
#define FALLTHROUGH
Definition: qgis.h:783
QgsDatabaseSchemaComboBox
The QgsDatabaseSchemaComboBox class is a combo box which displays the list of schemas for a specific ...
Definition: qgsdatabaseschemacombobox.h:50
QgsFields::append
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Appends a field. The field must have unique name, otherwise it is rejected (returns false)
Definition: qgsfields.cpp:59
QgsProcessingOutputBoolean::typeName
static QString typeName()
Returns the type name for the output class.
Definition: qgsprocessingoutputs.h:351
QgsProcessingOutputMultipleLayers::typeName
static QString typeName()
Returns the type name for the output class.
Definition: qgsprocessingoutputs.h:260
QgsUnitTypes::DistanceUnit
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:67
QgsProcessingParameterLayout::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:3191
QgsProcessing::TypeVectorPoint
@ TypeVectorPoint
Vector point layers.
Definition: qgsprocessing.h:48
QgsAbstractProcessingParameterWidgetWrapper
Definition: qgsprocessingwidgetwrapper.h:266
QgsProcessingParameterField::defaultToAllFields
bool defaultToAllFields() const
Returns whether a parameter which allows multiple selections (see allowMultiple()) should automatical...
Definition: qgsprocessingparameters.cpp:4552
QgsProcessingParameterMultipleLayers
Definition: qgsprocessingparameters.h:1756
QgsProcessingParameters::parameterAsSchema
static QString parameterAsSchema(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a database schema name.
Definition: qgsprocessingparameters.cpp:1865
QgsProcessingParameters::parameterAsRasterLayer
static QgsRasterLayer * parameterAsRasterLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a raster layer.
Definition: qgsprocessingparameters.cpp:815
QgsProcessingFeatureSourceDefinition::source
QgsProperty source
Source definition.
Definition: qgsprocessingparameters.h:117
QgsUnitTypes::DistanceKilometers
@ DistanceKilometers
Kilometers.
Definition: qgsunittypes.h:70
qgsextentwidget.h
QgsPanelWidget::dockMode
bool dockMode()
Returns the dock mode state.
Definition: qgspanelwidget.h:83
QgsRectangle
Definition: qgsrectangle.h:41
QgsProcessingParameterField::allowMultiple
bool allowMultiple() const
Returns whether multiple field selections are permitted.
Definition: qgsprocessingparameters.cpp:4542
qgsprocessingenummodelerwidget.h
QgsProcessingOutputFolder::typeName
static QString typeName()
Returns the type name for the output class.
Definition: qgsprocessingoutputs.h:374
QgsProcessingParameterMeshLayer::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:2437
qgssnapindicator.h
QgsProcessingParameterCoordinateOperation::destinationCrs
QVariant destinationCrs() const
Returns the static destination CRS, or an invalid value if this is not set.
Definition: qgsprocessingparameters.h:3432
QgsProcessingParameterDatabaseTable::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:3763
QgsProject
Definition: qgsproject.h:92
QgsSnapIndicator
Definition: qgssnapindicator.h:32
QgsProcessingGui::Standard
@ Standard
Standard algorithm dialog.
Definition: qgsprocessinggui.h:40
QgsProcessingParameterRange::dataType
QgsProcessingParameterNumber::Type dataType() const
Returns the acceptable data type for the range.
Definition: qgsprocessingparameters.cpp:3587
QgsProcessingParameterNumber::dataType
Type dataType() const
Returns the acceptable data type for the parameter.
Definition: qgsprocessingparameters.cpp:3460
QgsProcessingParameterBand::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:3118
QgsProcessingOutputRasterLayer::typeName
static QString typeName()
Returns the type name for the output class.
Definition: qgsprocessingoutputs.h:229
QgsFields::toList
QList< QgsField > toList() const
Utility function to return a list of QgsField instances.
Definition: qgsfields.cpp:212
QgsColorButton::colorChanged
void colorChanged(const QColor &color)
Emitted whenever a new color is set for the button.
QgsProcessingParameterColor
Definition: qgsprocessingparameters.h:3290
QgsProcessingParameterFeatureSink::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:2789
QgsLayoutManagerProxyModel::FilterPrintLayouts
@ FilterPrintLayouts
Includes print layouts.
Definition: qgslayoutmanager.h:247
qgsdatabasetablecombobox.h
QgsProcessingParameterDatabaseTable
Definition: qgsprocessingparameters.h:3740
QgsProcessingParameterFile::File
@ File
Parameter is a single file.
Definition: qgsprocessingparameters.h:1574
qgsscalewidget.h
QgsProcessingParameters::parameterAsRange
static QList< double > parameterAsRange(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a range of values.
Definition: qgsprocessingparameters.cpp:1629
QgsProcessingDestinationParameter
Definition: qgsprocessingparameters.h:2652
qgsapplication.h
QgsMapTool
Definition: qgsmaptool.h:63
QgsAuthConfigSelect::selectedConfigIdChanged
void selectedConfigIdChanged(const QString &authcfg)
Emitted when authentication config is changed or missing.
QgsMessageBar::clearWidgets
bool clearWidgets()
Removes all items from the bar.
Definition: qgsmessagebar.cpp:181
QgsProcessingParameters::parameterAsLayerList
static QList< QgsMapLayer * > parameterAsLayerList(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a list of map layers.
Definition: qgsprocessingparameters.cpp:1480
QgsProcessingParameterEnum::options
QStringList options() const
Returns the list of acceptable options for the parameter.
Definition: qgsprocessingparameters.cpp:3834
QgsVectorLayer::fields
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Definition: qgsvectorlayer.cpp:3280
QgsProcessingFeatureSourceDefinition
Definition: qgsprocessingparameters.h:55
QgsUnitTypes::fromUnitToUnitFactor
static Q_INVOKABLE double fromUnitToUnitFactor(QgsUnitTypes::DistanceUnit fromUnit, QgsUnitTypes::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
Definition: qgsunittypes.cpp:352
qgsfieldcombobox.h
QgsProcessingParameterColor::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:3306
QgsDateEdit
The QgsDateEdit class is a QDateEdit widget with the capability of setting/reading null dates.
Definition: qgsdatetimeedit.h:272
QgsProcessingParameterScale
Definition: qgsprocessingparameters.h:2014
QgsMapMouseEvent::mapPointMatch
QgsPointLocator::Match mapPointMatch() const
Returns the matching data from the most recently snapped point.
Definition: qgsmapmouseevent.h:97
qgscheckablecombobox.h
QgsProcessingParameterRange
Definition: qgsprocessingparameters.h:2048
QgsCoordinateOperationWidget::OperationDetails::proj
QString proj
Proj coordinate operation description, for Proj >= 6.0 builds only.
Definition: qgscoordinateoperationwidget.h:48
QgsProcessingParameterWidgetContext::project
QgsProject * project() const
Returns the project associated with the widget.
Definition: qgsprocessingwidgetwrapper.cpp:69
QgsFieldProxyModel::String
@ String
String fields.
Definition: qgsfieldproxymodel.h:41
QgsProcessingParameterRange::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:2063
QgsPrintLayout
Print layout, a QgsLayout subclass for static or atlas-based layouts.
Definition: qgsprintlayout.h:30
QgsProcessing::TypeMapLayer
@ TypeMapLayer
Any map layer type (raster or vector or mesh)
Definition: qgsprocessing.h:46
QgsExtentWidget::extentChanged
void extentChanged(const QgsRectangle &r)
Emitted when the widget's extent is changed.
QgsPanelWidget
Base class for any widget that can be shown as a inline panel.
Definition: qgspanelwidget.h:29
QgsProcessingParameters::parameterAsExtent
static QgsRectangle parameterAsExtent(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QgsCoordinateReferenceSystem &crs=QgsCoordinateReferenceSystem())
Evaluates the parameter with matching definition to a rectangular extent.
Definition: qgsprocessingparameters.cpp:971
QgsRasterBandComboBox
Definition: qgsrasterbandcombobox.h:33
QgsFileWidget::GetDirectory
@ GetDirectory
Select a directory.
Definition: qgsfilewidget.h:67
QgsProcessing::TypeVector
@ TypeVector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
Definition: qgsprocessing.h:53
QgsProcessingParameterAuthConfig::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:2275
QgsProcessingOutputMapLayer::typeName
static QString typeName()
Returns the type name for the output class.
Definition: qgsprocessingoutputs.h:167
QgsUnitTypes::DistanceDegrees
@ DistanceDegrees
Degrees, for planar geographic CRS distance measurements.
Definition: qgsunittypes.h:75
QgsProcessingParameterBand::allowMultiple
bool allowMultiple() const
Returns whether multiple band selections are permitted.
Definition: qgsprocessingparameters.cpp:5899
QgsProcessingParameterDateTime::DateTime
@ DateTime
Datetime values.
Definition: qgsprocessingparameters.h:3510
QgsProcessingParameterCrs
Definition: qgsprocessingparameters.h:1470
QgsProcessingParameterRasterLayer::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:2114
QgsProcessingParameterPoint::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:1548
QgsExtentWidget::toggleDialogVisibility
void toggleDialogVisibility(bool visible)
Emitted when the parent dialog visibility must be changed (e.g.
QgsProcessingParameterExtent::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:1515
QgsProcessingParameters::parameterAsVectorLayer
static QgsVectorLayer * parameterAsVectorLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a vector layer.
Definition: qgsprocessingparameters.cpp:945
QgsProcessingParameters::parameterAsPoint
static QgsPointXY parameterAsPoint(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QgsCoordinateReferenceSystem &crs=QgsCoordinateReferenceSystem())
Evaluates the parameter with matching definition to a point.
Definition: qgsprocessingparameters.cpp:1301
QgsProcessingParameters::parameterAsDateTime
static QDateTime parameterAsDateTime(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static datetime value.
Definition: qgsprocessingparameters.cpp:306
QgsProcessingContext
Definition: qgsprocessingcontext.h:43
QgsProcessing::TypeMesh
@ TypeMesh
Mesh layers.
Definition: qgsprocessing.h:54
qgsspinbox.h
qgsdatetimeedit.h
QgsUnitTypes::toString
static Q_INVOKABLE QString toString(QgsUnitTypes::DistanceUnit unit)
Returns a translated string representing a distance unit.
Definition: qgsunittypes.cpp:199
qgsDoubleNear
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:315
QgsProcessingParameterFile::extension
QString extension() const
Returns any specified file extension for the parameter.
Definition: qgsprocessingparameters.h:1617
QgsProcessing::TypeRaster
@ TypeRaster
Raster layers.
Definition: qgsprocessing.h:51
qgsRound
double qgsRound(double number, int places)
Returns a double number, rounded (as close as possible) to the specified number of places.
Definition: qgis.h:363
QgsProcessingParameterDefinition::name
QString name() const
Returns the name of the parameter.
Definition: qgsprocessingparameters.h:456
QgsProcessingParameterField::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:2521
QgsPanelWidget::acceptPanel
void acceptPanel()
Accept the panel.
Definition: qgspanelwidget.cpp:107
QgsFieldExpressionWidget::fieldChanged
void fieldChanged(const QString &fieldName)
Emitted when the currently selected field changes.
QgsProcessingGui::Batch
@ Batch
Batch processing dialog.
Definition: qgsprocessinggui.h:41
QgsMapLayerType::RasterLayer
@ RasterLayer
QgsProcessingParameterLayoutItem
Definition: qgsprocessingparameters.h:3216
QgsProcessingParameterField::setDataType
void setDataType(DataType type)
Sets the acceptable data type for the field.
Definition: qgsprocessingparameters.cpp:4537
QgsProcessing::TypeVectorAnyGeometry
@ TypeVectorAnyGeometry
Any vector layer with geometry.
Definition: qgsprocessing.h:47
QgsProcessingParameterNumber::maximum
double maximum() const
Returns the maximum value acceptable by the parameter.
Definition: qgsprocessingparameters.cpp:3450
QgsProcessingParameters::parameterAsInts
static QList< int > parameterAsInts(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a list of integer values.
Definition: qgsprocessingparameters.cpp:249
QgsProcessingParameterString
Definition: qgsprocessingparameters.h:2202
QgsUnitTypes::Standard
@ Standard
Unit is a standard measurement unit.
Definition: qgsunittypes.h:87
QgsDateTimeEdit::setNullRepresentation
void setNullRepresentation(const QString &null)
Sets the widget's null representation, which defaults to QgsApplication::nullRepresentation().
Definition: qgsdatetimeedit.cpp:235
QgsProcessingParameterField::DateTime
@ DateTime
Accepts datetime fields.
Definition: qgsprocessingparameters.h:2505
QgsProcessingParameterExtent
Definition: qgsprocessingparameters.h:1502
QgsProcessingParameterString::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:2216
qgsprocessingoutputdestinationwidget.h
QgsProcessingParameterEnum::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:2149
QgsUnitTypes::DistanceFeet
@ DistanceFeet
Imperial feet.
Definition: qgsunittypes.h:71
QgsCoordinateReferenceSystem::isValid
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
Definition: qgscoordinatereferencesystem.cpp:902
QgsProcessingParameterProviderConnection::providerId
QString providerId() const
Returns the ID of the provider associated with the connections.
Definition: qgsprocessingparameters.h:3649
QgsProcessingParameterRasterLayer
Definition: qgsprocessingparameters.h:2101
QgsFieldComboBox
The QgsFieldComboBox is a combo box which displays the list of fields of a given layer....
Definition: qgsfieldcombobox.h:38
QgsUnitTypes::DistanceMeters
@ DistanceMeters
Meters.
Definition: qgsunittypes.h:69
QgsProcessingParameters::parameterAsLayout
static QgsPrintLayout * parameterAsLayout(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a print layout.
Definition: qgsprocessingparameters.cpp:1753
QgsProcessingParameters::parameterAsPointCrs
static QgsCoordinateReferenceSystem parameterAsPointCrs(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Returns the coordinate reference system associated with an point parameter value.
Definition: qgsprocessingparameters.cpp:1385
QgsMapLayer::id
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
Definition: qgsmaplayer.cpp:148
QgsProcessingParameterProviderConnection
Definition: qgsprocessingparameters.h:3619
QgsProcessingGui::Modeler
@ Modeler
Modeler dialog.
Definition: qgsprocessinggui.h:42
QgsScaleWidget
Definition: qgsscalewidget.h:34
QgsDateTimeEdit::valueChanged
void valueChanged(const QDateTime &date)
Signal emitted whenever the value changes.
qgsmessagebar.h
QgsAbstractProcessingParameterWidgetWrapper::widgetValueHasChanged
void widgetValueHasChanged(QgsAbstractProcessingParameterWidgetWrapper *wrapper)
Emitted whenever the parameter value (as defined by the wrapped widget) is changed.
QgsProcessingContext::transformContext
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
Definition: qgsprocessingcontext.h:135
qgsprocessingwidgetwrapperimpl.h
QgsAbstractProcessingParameterWidgetWrapper::linkedVectorLayer
virtual const QgsVectorLayer * linkedVectorLayer() const
Returns the optional vector layer associated with this widget wrapper, or nullptr if no vector layer ...
Definition: qgsprocessingwidgetwrapper.cpp:246
QgsProcessingOutputVectorLayer::typeName
static QString typeName()
Returns the type name for the output class.
Definition: qgsprocessingoutputs.h:191
QgsProcessingParameterFile
Definition: qgsprocessingparameters.h:1567
QgsSettings::setValue
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
Definition: qgssettings.cpp:289
QgsProject::mapThemeCollection
QgsMapThemeCollection mapThemeCollection
Definition: qgsproject.h:101
QgsProcessingParameterVectorLayer
Definition: qgsprocessingparameters.h:2382
QgsLayoutItem
Base class for graphical items within a QgsLayout.
Definition: qgslayoutitem.h:112
QgsProcessingParameterFeatureSource::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:2626
QgsRasterLayer
Definition: qgsrasterlayer.h:72
QgsExtentWidget
Definition: qgsextentwidget.h:50
QgsProcessingParameterDatabaseTable::allowNewTableNames
bool allowNewTableNames() const
Returns true if the parameter allows users to enter names for a new (non-existing) tables.
Definition: qgsprocessingparameters.cpp:7355
QgsMasterLayoutInterface::name
virtual QString name() const =0
Returns the layout's name.
QgsProcessingAbstractParameterDefinitionWidget
Abstract base class for widgets which allow users to specify the properties of a Processing parameter...
Definition: qgsprocessingparameterdefinitionwidget.h:43
QgsProcessingParameterFolderDestination::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:3083
QgsProcessingParameterNumber::Integer
@ Integer
Integer values.
Definition: qgsprocessingparameters.h:1845
qgsproviderconnectioncombobox.h
QgsProcessingParameterDateTime::Time
@ Time
Time values.
Definition: qgsprocessingparameters.h:3512
QgsProjectionSelectionWidget::CrsNotSet
@ CrsNotSet
Not set (hidden by default)
Definition: qgsprojectionselectionwidget.h:53
QgsCoordinateReferenceSystem
Definition: qgscoordinatereferencesystem.h:206
QgsProcessingParameterLayout
Definition: qgsprocessingparameters.h:3178
QgsTimeEdit::timeValueChanged
void timeValueChanged(const QTime &time)
Signal emitted whenever the time changes.
QgsProcessingParameterDatabaseSchema
Definition: qgsprocessingparameters.h:3678
QgsProcessingParameterDistance
Definition: qgsprocessingparameters.h:1941
QgsDateTimeEdit::setAllowNull
void setAllowNull(bool allowNull)
Determines if the widget allows setting null date/time.
Definition: qgsdatetimeedit.cpp:61
QgsProcessingParameterExpression::parentLayerParameterName
QString parentLayerParameterName() const
Returns the name of the parent layer parameter, or an empty string if this is not set.
Definition: qgsprocessingparameters.cpp:4104
QgsProcessingParameterPoint
Definition: qgsprocessingparameters.h:1535
QgsProcessingParameterLayoutItem::itemType
int itemType() const
Returns the acceptable item type, or -1 if any item type is allowed.
Definition: qgsprocessingparameters.cpp:6357
QgsSpinBox
The QgsSpinBox is a spin box with a clear button that will set the value to the defined clear value....
Definition: qgsspinbox.h:42
QgsPointLocator::Match
Definition: qgspointlocator.h:184
QgsPointXY
Definition: qgspointxy.h:43
QgsTimeEdit
The QgsTimeEdit class is a QTimeEdit widget with the capability of setting/reading null date/times.
Definition: qgsdatetimeedit.h:226
QgsMapSettings::destinationCrs
QgsCoordinateReferenceSystem destinationCrs() const
returns CRS of destination coordinate reference system
Definition: qgsmapsettings.cpp:317
QgsDatabaseTableComboBox
The QgsDatabaseTableComboBox class is a combo box which displays the list of tables for a specific da...
Definition: qgsdatabasetablecombobox.h:50
QgsProcessingParameterFileDestination::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:3024
qgsprocessingoutputs.h
QgsAbstractProcessingParameterWidgetWrapper::createLabel
virtual QLabel * createLabel()
Creates a new label to accompany widgets created by the wrapper.
Definition: qgsprocessingwidgetwrapper.cpp:225
qgsprocessingparameters.h
qgslayoutitemcombobox.h
QgsProcessingParameterNumber::minimum
double minimum() const
Returns the minimum value acceptable by the parameter.
Definition: qgsprocessingparameters.cpp:3440
QgsMapMouseEvent
Definition: qgsmapmouseevent.h:35
QgsProcessingParameterDateTime::dataType
Type dataType() const
Returns the acceptable data type for the parameter.
Definition: qgsprocessingparameters.cpp:6920
QgsLayoutItem::uuid
virtual QString uuid() const
Returns the item identification string.
Definition: qgslayoutitem.h:340
QgsProcessingOutputString::typeName
static QString typeName()
Returns the type name for the output class.
Definition: qgsprocessingoutputs.h:328
QgsProcessingParameterBoolean
Definition: qgsprocessingparameters.h:1439
qgslayoutcombobox.h
QgsCoordinateReferenceSystem::mapUnits
QgsUnitTypes::DistanceUnit mapUnits
Definition: qgscoordinatereferencesystem.h:210
QgsProcessingGui::WidgetType
WidgetType
Types of dialogs which Processing widgets can be created for.
Definition: qgsprocessinggui.h:38
QgsProcessingParameterDateTime
Definition: qgsprocessingparameters.h:3503
QgsProcessingAlgorithm
Definition: qgsprocessingalgorithm.h:51
c
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
Definition: porting_processing.dox:1
qgsexpressionlineedit.h
QgsVectorLayer
Definition: qgsvectorlayer.h:385
QgsProcessingParameterExpression
Definition: qgsprocessingparameters.h:2294
QgsProcessingParameterExpression::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:2308
QgsMapLayer
Definition: qgsmaplayer.h:81
QgsProcessingParameterMapTheme::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:3473
QgsAbstractProcessingParameterWidgetWrapper::setDialog
virtual void setDialog(QDialog *dialog)
Sets the parent dialog in which the wrapper is shown.
Definition: qgsprocessingwidgetwrapper.cpp:306
QgsProcessingParameterDistance::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:1958
QgsProcessingUtils::variantToCrs
static QgsCoordinateReferenceSystem variantToCrs(const QVariant &value, QgsProcessingContext &context, const QVariant &fallbackValue=QVariant())
Converts a variant value to a coordinate reference system.
Definition: qgsprocessingutils.cpp:424
QgsPointXY::x
double x
Definition: qgspointxy.h:47
QgsAbstractProcessingParameterWidgetWrapper::parameterValue
QVariant parameterValue() const
Returns the current value of the parameter.
Definition: qgsprocessingwidgetwrapper.cpp:202
qgsprintlayout.h
QgsProcessingParameterMatrix::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:1685
qgssettings.h
QgsColorButton
Definition: qgscolorbutton.h:35
QgsProcessingParameterDateTime::Type
Type
Datetime data type.
Definition: qgsprocessingparameters.h:3508
QgsProcessingParameterBoolean::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:1452
QgsProcessing::TypeFile
@ TypeFile
Files (i.e. non map layer sources, such as text files)
Definition: qgsprocessing.h:52
QgsExpressionLineEdit
The QgsExpressionLineEdit widget includes a line edit for entering expressions together with a button...
Definition: qgsexpressionlineedit.h:48
QgsUnitTypes::DistanceYards
@ DistanceYards
Imperial yards.
Definition: qgsunittypes.h:73
QgsProcessingParameters::parameterAsLayoutItem
static QgsLayoutItem * parameterAsLayoutItem(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, QgsPrintLayout *layout)
Evaluates the parameter with matching definition to a print layout item, taken from the specified lay...
Definition: qgsprocessingparameters.cpp:1777
QgsScaleWidget::scaleChanged
void scaleChanged(double scale)
Emitted when user has finished editing/selecting a new scale.
qgsdatumtransformdialog.h
QgsDoubleSpinBox
The QgsSpinBox is a spin box with a clear button that will set the value to the defined clear value....
Definition: qgsdoublespinbox.h:42
QgsProcessingParameterBand
Definition: qgsprocessingparameters.h:3103
qgsprocessingcontext.h
qgsprocessingmatrixparameterdialog.h
QgsUnitTypes::DistanceMiles
@ DistanceMiles
Terrestrial miles.
Definition: qgsunittypes.h:74
QgsCheckableComboBox
Definition: qgscheckablecombobox.h:123
QgsLayoutItemComboBox::itemChanged
void itemChanged(QgsLayoutItem *item)
Emitted whenever the currently selected item changes.
QgsLayoutComboBox::layoutChanged
void layoutChanged(QgsMasterLayoutInterface *layout)
Emitted whenever the currently selected layout changes.
QgsProcessingParameterWidgetContext::model
QgsProcessingModelAlgorithm * model() const
Returns the model which the parameter widget is associated with.
Definition: qgsprocessingwidgetwrapper.cpp:94
qgsfieldexpressionwidget.h
QgsProcessingParameterVectorLayer::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:2398
QgsProcessingParameterScale::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:2028
qgsfilewidget.h
QgsProcessingParameterCoordinateOperation::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:3369
QgsRasterInterface::bandCount
virtual int bandCount() const =0
Gets number of bands.
QgsProcessingParameters::parameterAsExpression
static QString parameterAsExpression(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to an expression.
Definition: qgsprocessingparameters.cpp:152
QgsProcessingOutputNumber::typeName
static QString typeName()
Returns the type name for the output class.
Definition: qgsprocessingoutputs.h:306
QgsProcessingParameters::parameterAsColor
static QColor parameterAsColor(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Returns the color associated with an point parameter value, or an invalid color if the parameter was ...
Definition: qgsprocessingparameters.cpp:1803
QgsProcessingParameterDefinition::type
virtual QString type() const =0
Unique parameter type name.
QgsMasterLayoutInterface
Interface for master layout type objects, such as print layouts and reports.
Definition: qgsmasterlayoutinterface.h:42
QgsProcessingParameterEnum
Definition: qgsprocessingparameters.h:2134
qgsprocessingmultipleselectiondialog.h
QgsProcessingParameterDefinition::FlagOptional
@ FlagOptional
Parameter is optional.
Definition: qgsprocessingparameters.h:421
QgsProcessingParameterCoordinateOperation
Definition: qgsprocessingparameters.h:3354
QgsProcessingParameterDefinition::defaultValue
QVariant defaultValue() const
Returns the default value for the parameter.
Definition: qgsprocessingparameters.h:483
qgsauthconfigselect.h
QgsProcessingParameterField::Any
@ Any
Accepts any field.
Definition: qgsprocessingparameters.h:2502
QgsProcessingParameterNumber::Type
Type
Numeric data type.
Definition: qgsprocessingparameters.h:1843
qgsmapmouseevent.h
QgsAbstractProcessingParameterWidgetWrapper::parameterDefinition
const QgsProcessingParameterDefinition * parameterDefinition() const
Returns the parameter definition associated with this wrapper.
Definition: qgsprocessingwidgetwrapper.cpp:182
QgsProcessingParameterField::dataType
DataType dataType() const
Returns the acceptable data type for the field.
Definition: qgsprocessingparameters.cpp:4532
QgsProcessingParameters::parameterAsEnum
static int parameterAsEnum(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a enum value.
Definition: qgsprocessingparameters.cpp:423
QgsFieldExpressionWidget
The QgsFieldExpressionWidget class reates a widget to choose fields and edit expressions It contains ...
Definition: qgsfieldexpressionwidget.h:46
QgsProcessingParameterFile::behavior
Behavior behavior() const
Returns the parameter behavior (e.g.
Definition: qgsprocessingparameters.h:1602
QgsFileWidget
The QgsFileWidget class creates a widget for selecting a file or a folder.
Definition: qgsfilewidget.h:36
QgsProcessingParameterNumber::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:1863
QgsProcessing::SourceType
SourceType
Data source types enum.
Definition: qgsprocessing.h:44
QgsProcessingParameterCoordinateOperation::sourceCrs
QVariant sourceCrs() const
Returns the static source CRS, or an invalid value if this is not set.
Definition: qgsprocessingparameters.h:3418
QgsProcessingParameterDateTime::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:3529
QgsExpressionLineEdit::expressionChanged
void expressionChanged(const QString &expression)
Emitted when the expression is changed.
QgsProcessingParameterField
Definition: qgsprocessingparameters.h:2495
QgsRasterDataProvider
Definition: qgsrasterdataprovider.h:88
QgsProcessingParameterCrs::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:1483
QgsProcessingParameters::parameterAsTime
static QTime parameterAsTime(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static time value.
Definition: qgsprocessingparameters.cpp:380
qgsproject.h
QgsProcessingParameterDateTime::Date
@ Date
Date values.
Definition: qgsprocessingparameters.h:3511
QgsMessageBar::pushMessage
void pushMessage(const QString &text, Qgis::MessageLevel level=Qgis::Info, int duration=5)
A convenience method for pushing a message with the specified text to the bar.
Definition: qgsmessagebar.cpp:379
QgsProcessingParameters::parameterAsDouble
static double parameterAsDouble(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static double value.
Definition: qgsprocessingparameters.cpp:180
QgsRasterLayer::dataProvider
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
Definition: qgsrasterlayer.cpp:233
QgsFieldComboBox::fieldChanged
void fieldChanged(const QString &fieldName)
Emitted when the currently selected field changes.
QgsProcessingParameters::parameterAsInt
static int parameterAsInt(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static integer value.
Definition: qgsprocessingparameters.cpp:207
QgsProcessingParameters::parameterAsSource
static QgsProcessingFeatureSource * parameterAsSource(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a feature source.
Definition: qgsprocessingparameters.cpp:650
QgsProcessingParameterMapLayer::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:2470
QgsProcessingParameterFile::Behavior
Behavior
Parameter behavior.
Definition: qgsprocessingparameters.h:1572
QgsProcessingParameterDatabaseSchema::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:3696
QgsProcessingParameterColor::opacityEnabled
bool opacityEnabled() const
Returns true if the parameter allows opacity control.
Definition: qgsprocessingparameters.cpp:6479
QgsRasterBandComboBox::displayBandName
static QString displayBandName(QgsRasterDataProvider *provider, int band)
Returns a user-friendly band name for the specified band.
Definition: qgsrasterbandcombobox.cpp:164
QgsProcessingParameterWidgetContext::messageBar
QgsMessageBar * messageBar() const
Returns the message bar associated with the widget.
Definition: qgsprocessingwidgetwrapper.cpp:49
QgsProcessingParameterDefinition::setFlags
void setFlags(Flags flags)
Sets the flags associated with the parameter.
Definition: qgsprocessingparameters.h:502
QgsProcessingParameters::parameterAsBool
static bool parameterAsBool(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static boolean value.
Definition: qgsprocessingparameters.cpp:514
QgsAbstractProcessingParameterWidgetWrapper::postInitialize
virtual void postInitialize(const QList< QgsAbstractProcessingParameterWidgetWrapper * > &wrappers)
Called after all wrappers have been created within a particular dialog or context,...
Definition: qgsprocessingwidgetwrapper.cpp:253
QgsCoordinateOperationWidget::operationChanged
void operationChanged()
Emitted when the operation selected in the dialog is changed.
QgsProcessingParameters::parameterAsString
static QString parameterAsString(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static string value.
Definition: qgsprocessingparameters.cpp:120
qgsdatabaseschemacombobox.h
QgsField
Definition: qgsfield.h:49
QgsProcessingOutputFile::typeName
static QString typeName()
Returns the type name for the output class.
Definition: qgsprocessingoutputs.h:397