19#include "moc_qgsprocessingwidgetwrapperimpl.cpp"
81#include <QPlainTextEdit>
82#include <QRadioButton>
83#include <QButtonGroup>
97 QVBoxLayout *vlayout =
new QVBoxLayout();
98 vlayout->setContentsMargins( 0, 0, 0, 0 );
100 mDefaultCheckBox =
new QCheckBox( tr(
"Checked" ) );
104 mDefaultCheckBox->setChecked(
false );
105 vlayout->addWidget( mDefaultCheckBox );
106 setLayout( vlayout );
111 auto param = std::make_unique<QgsProcessingParameterBoolean>( name, description, mDefaultCheckBox->isChecked() );
112 param->setFlags( flags );
113 return param.release();
122QWidget *QgsProcessingBooleanWidgetWrapper::createWidget()
128 QString description = parameterDefinition()->description();
130 description = QObject::tr(
"%1 [optional]" ).arg( description );
132 mCheckBox =
new QCheckBox( description );
133 mCheckBox->setToolTip( parameterDefinition()->toolTip() );
135 connect( mCheckBox, &QCheckBox::toggled,
this, [=] {
136 emit widgetValueHasChanged(
this );
144 mComboBox =
new QComboBox();
145 mComboBox->addItem( tr(
"Yes" ),
true );
146 mComboBox->addItem( tr(
"No" ),
false );
147 mComboBox->setToolTip( parameterDefinition()->toolTip() );
149 connect( mComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, [=] {
150 emit widgetValueHasChanged(
this );
159QLabel *QgsProcessingBooleanWidgetWrapper::createLabel()
168void QgsProcessingBooleanWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
175 mCheckBox->setChecked( v );
183 mComboBox->setCurrentIndex( mComboBox->findData( v ) );
189QVariant QgsProcessingBooleanWidgetWrapper::widgetValue()
const
194 return mCheckBox->isChecked();
198 return mComboBox->currentData();
203QStringList QgsProcessingBooleanWidgetWrapper::compatibleParameterTypes()
const
227QStringList QgsProcessingBooleanWidgetWrapper::compatibleOutputTypes()
const
239QString QgsProcessingBooleanWidgetWrapper::parameterType()
const
246 return new QgsProcessingBooleanWidgetWrapper( parameter, type );
251 return new QgsProcessingBooleanParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
262 QVBoxLayout *vlayout =
new QVBoxLayout();
263 vlayout->setContentsMargins( 0, 0, 0, 0 );
265 vlayout->addWidget(
new QLabel( tr(
"Default value" ) ) );
270 mCrsSelector->setShowAccuracyWarnings(
true );
277 vlayout->addWidget( mCrsSelector );
278 setLayout( vlayout );
283 auto param = std::make_unique<QgsProcessingParameterCrs>( name, description, mCrsSelector->crs().authid() );
284 param->setFlags( flags );
285 return param.release();
293QWidget *QgsProcessingCrsWidgetWrapper::createWidget()
295 Q_ASSERT( mProjectionSelectionWidget ==
nullptr );
297 mProjectionSelectionWidget->setToolTip( parameterDefinition()->toolTip() );
305 emit widgetValueHasChanged(
this );
313 return mProjectionSelectionWidget;
318 QWidget *w =
new QWidget();
319 w->setToolTip( parameterDefinition()->toolTip() );
321 QVBoxLayout *vl =
new QVBoxLayout();
322 vl->setContentsMargins( 0, 0, 0, 0 );
325 mUseProjectCrsCheckBox =
new QCheckBox( tr(
"Use project CRS" ) );
326 mUseProjectCrsCheckBox->setToolTip( tr(
"Always use the current project CRS when running the model" ) );
327 vl->addWidget( mUseProjectCrsCheckBox );
328 connect( mUseProjectCrsCheckBox, &QCheckBox::toggled, mProjectionSelectionWidget, &QgsProjectionSelectionWidget::setDisabled );
329 connect( mUseProjectCrsCheckBox, &QCheckBox::toggled,
this, [=] {
330 emit widgetValueHasChanged(
this );
333 vl->addWidget( mProjectionSelectionWidget );
341void QgsProcessingCrsWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
343 if ( mUseProjectCrsCheckBox )
345 if ( value.toString().compare( QLatin1String(
"ProjectCrs" ), Qt::CaseInsensitive ) == 0 )
347 mUseProjectCrsCheckBox->setChecked(
true );
352 mUseProjectCrsCheckBox->setChecked(
false );
357 if ( mProjectionSelectionWidget )
358 mProjectionSelectionWidget->setCrs( v );
361QVariant QgsProcessingCrsWidgetWrapper::widgetValue()
const
363 if ( mUseProjectCrsCheckBox && mUseProjectCrsCheckBox->isChecked() )
364 return QStringLiteral(
"ProjectCrs" );
365 else if ( mProjectionSelectionWidget )
366 return mProjectionSelectionWidget->crs().isValid() ? mProjectionSelectionWidget->crs() : QVariant();
371QStringList QgsProcessingCrsWidgetWrapper::compatibleParameterTypes()
const
385QStringList QgsProcessingCrsWidgetWrapper::compatibleOutputTypes()
const
394QString QgsProcessingCrsWidgetWrapper::modelerExpressionFormatString()
const
396 return tr(
"string as EPSG code, WKT or PROJ format, or a string identifying a map layer" );
399QString QgsProcessingCrsWidgetWrapper::parameterType()
const
406 return new QgsProcessingCrsWidgetWrapper( parameter, type );
411 return new QgsProcessingCrsParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
423 QVBoxLayout *vlayout =
new QVBoxLayout();
424 vlayout->setContentsMargins( 0, 0, 0, 0 );
426 vlayout->addWidget(
new QLabel( tr(
"Default value" ) ) );
428 mDefaultLineEdit =
new QLineEdit();
431 vlayout->addWidget( mDefaultLineEdit );
433 mMultiLineCheckBox =
new QCheckBox( tr(
"Multiline input" ) );
435 mMultiLineCheckBox->setChecked( stringParam->multiLine() );
436 vlayout->addWidget( mMultiLineCheckBox );
438 setLayout( vlayout );
443 auto param = std::make_unique<QgsProcessingParameterString>( name, description, mDefaultLineEdit->text(), mMultiLineCheckBox->isChecked() );
444 param->setFlags( flags );
445 return param.release();
454QWidget *QgsProcessingStringWidgetWrapper::createWidget()
456 const QVariantMap metadata = parameterDefinition()->metadata();
457 const QVariant valueHintsVariant = metadata.value( QStringLiteral(
"widget_wrapper" ) ).toMap().value( QStringLiteral(
"value_hints" ) );
459 if ( valueHintsVariant.isValid() )
461 const QVariantList valueList = valueHintsVariant.toList();
462 mComboBox =
new QComboBox();
463 mComboBox->setToolTip( parameterDefinition()->toolTip() );
467 mComboBox->addItem( QString() );
469 for (
const QVariant &entry : valueList )
471 mComboBox->addItem( entry.toString(), entry.toString() );
473 mComboBox->setCurrentIndex( 0 );
475 connect( mComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, [=](
int ) {
476 emit widgetValueHasChanged(
this );
489 mPlainTextEdit =
new QPlainTextEdit();
490 mPlainTextEdit->setToolTip( parameterDefinition()->toolTip() );
492 connect( mPlainTextEdit, &QPlainTextEdit::textChanged,
this, [=] {
493 emit widgetValueHasChanged(
this );
495 return mPlainTextEdit;
499 mLineEdit =
new QLineEdit();
500 mLineEdit->setToolTip( parameterDefinition()->toolTip() );
502 connect( mLineEdit, &QLineEdit::textChanged,
this, [=] {
503 emit widgetValueHasChanged(
this );
511 mLineEdit =
new QLineEdit();
512 mLineEdit->setToolTip( parameterDefinition()->toolTip() );
514 connect( mLineEdit, &QLineEdit::textChanged,
this, [=] {
515 emit widgetValueHasChanged(
this );
525void QgsProcessingStringWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
529 mLineEdit->setText( v );
530 if ( mPlainTextEdit )
531 mPlainTextEdit->setPlainText( v );
535 if ( !value.isValid() )
536 index = mComboBox->findData( QVariant() );
538 index = mComboBox->findData( v );
541 mComboBox->setCurrentIndex( index );
543 mComboBox->setCurrentIndex( 0 );
547QVariant QgsProcessingStringWidgetWrapper::widgetValue()
const
550 return mLineEdit->text();
551 else if ( mPlainTextEdit )
552 return mPlainTextEdit->toPlainText();
553 else if ( mComboBox )
554 return mComboBox->currentData();
559QStringList QgsProcessingStringWidgetWrapper::compatibleParameterTypes()
const
577QStringList QgsProcessingStringWidgetWrapper::compatibleOutputTypes()
const
586QString QgsProcessingStringWidgetWrapper::parameterType()
const
593 return new QgsProcessingStringWidgetWrapper( parameter, type );
598 return new QgsProcessingStringParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
611QWidget *QgsProcessingAuthConfigWidgetWrapper::createWidget()
620 mAuthConfigSelect->setToolTip( parameterDefinition()->toolTip() );
623 emit widgetValueHasChanged(
this );
625 return mAuthConfigSelect;
631void QgsProcessingAuthConfigWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
634 if ( mAuthConfigSelect )
635 mAuthConfigSelect->setConfigId( v );
638QVariant QgsProcessingAuthConfigWidgetWrapper::widgetValue()
const
640 if ( mAuthConfigSelect )
641 return mAuthConfigSelect->configId();
646QStringList QgsProcessingAuthConfigWidgetWrapper::compatibleParameterTypes()
const
654QStringList QgsProcessingAuthConfigWidgetWrapper::compatibleOutputTypes()
const
660QString QgsProcessingAuthConfigWidgetWrapper::parameterType()
const
667 return new QgsProcessingAuthConfigWidgetWrapper( parameter, type );
677 QVBoxLayout *vlayout =
new QVBoxLayout();
678 vlayout->setContentsMargins( 0, 0, 0, 0 );
680 vlayout->addWidget(
new QLabel( tr(
"Number type" ) ) );
682 mTypeComboBox =
new QComboBox();
685 vlayout->addWidget( mTypeComboBox );
687 vlayout->addWidget(
new QLabel( tr(
"Minimum value" ) ) );
688 mMinLineEdit =
new QLineEdit();
689 vlayout->addWidget( mMinLineEdit );
691 vlayout->addWidget(
new QLabel( tr(
"Maximum value" ) ) );
692 mMaxLineEdit =
new QLineEdit();
693 vlayout->addWidget( mMaxLineEdit );
695 vlayout->addWidget(
new QLabel( tr(
"Default value" ) ) );
696 mDefaultLineEdit =
new QLineEdit();
697 vlayout->addWidget( mDefaultLineEdit );
701 mTypeComboBox->setCurrentIndex( mTypeComboBox->findData(
static_cast<int>( numberParam->dataType() ) ) );
703 if ( !
qgsDoubleNear( numberParam->maximum(), std::numeric_limits<double>::max() ) )
705 mMaxLineEdit->setText( QLocale().toString( numberParam->maximum() ) );
709 mMaxLineEdit->clear();
712 if ( !
qgsDoubleNear( numberParam->minimum(), std::numeric_limits<double>::lowest() ) )
714 mMinLineEdit->setText( QLocale().toString( numberParam->minimum() ) );
718 mMinLineEdit->clear();
721 mDefaultLineEdit->setText( numberParam->defaultValueForGui().toString() );
724 setLayout( vlayout );
733 auto param = std::make_unique<QgsProcessingParameterNumber>( name, description, dataType, ok ? val : QVariant() );
735 if ( !mMinLineEdit->text().trimmed().isEmpty() )
740 param->setMinimum( val );
744 if ( !mMaxLineEdit->text().trimmed().isEmpty() )
749 param->setMaximum( val );
753 param->setFlags( flags );
754 return param.release();
762QWidget *QgsProcessingNumericWidgetWrapper::createWidget()
765 const QVariantMap metadata = numberDef->
metadata();
766 const int decimals = metadata.value( QStringLiteral(
"widget_wrapper" ) ).toMap().value( QStringLiteral(
"decimals" ), 6 ).toInt();
774 QAbstractSpinBox *spinBox =
nullptr;
779 mDoubleSpinBox->setExpressionsEnabled(
true );
780 mDoubleSpinBox->setDecimals( decimals );
785 double singleStep = calculateStep( numberDef->
minimum(), numberDef->
maximum() );
786 singleStep = std::max( singleStep, std::pow( 10, -decimals ) );
787 mDoubleSpinBox->setSingleStep( singleStep );
790 spinBox = mDoubleSpinBox;
795 mSpinBox->setExpressionsEnabled(
true );
799 spinBox->setToolTip( parameterDefinition()->toolTip() );
801 double max = 999999999;
806 double min = -999999999;
811 if ( mDoubleSpinBox )
813 mDoubleSpinBox->setMinimum( min );
814 mDoubleSpinBox->setMaximum( max );
818 mSpinBox->setMinimum(
static_cast<int>( min ) );
819 mSpinBox->setMaximum(
static_cast<int>( max ) );
824 mAllowingNull =
true;
825 if ( mDoubleSpinBox )
827 mDoubleSpinBox->setShowClearButton(
true );
828 const double min = mDoubleSpinBox->minimum() - mDoubleSpinBox->singleStep();
829 mDoubleSpinBox->setMinimum( min );
830 mDoubleSpinBox->setValue( min );
834 mSpinBox->setShowClearButton(
true );
835 const int min = mSpinBox->minimum() - 1;
836 mSpinBox->setMinimum( min );
837 mSpinBox->setValue( min );
839 spinBox->setSpecialValueText( tr(
"Not set" ) );
847 if ( mDoubleSpinBox )
851 mDoubleSpinBox->setClearValue( defaultVal );
857 mSpinBox->setClearValue( intVal );
863 if ( mDoubleSpinBox )
864 mDoubleSpinBox->setClearValue( numberDef->
minimum() );
866 mSpinBox->setClearValue(
static_cast<int>( numberDef->
minimum() ) );
871 if ( mDoubleSpinBox )
873 mDoubleSpinBox->setValue( 0 );
874 mDoubleSpinBox->setClearValue( 0 );
878 mSpinBox->setValue( 0 );
879 mSpinBox->setClearValue( 0 );
884 if ( mDoubleSpinBox )
885 connect( mDoubleSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, [=] { emit widgetValueHasChanged(
this ); } );
887 connect( mSpinBox, qOverload<int>( &QgsSpinBox::valueChanged ),
this, [=] { emit widgetValueHasChanged(
this ); } );
895void QgsProcessingNumericWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
897 if ( mDoubleSpinBox )
899 if ( mAllowingNull && !value.isValid() )
900 mDoubleSpinBox->clear();
904 mDoubleSpinBox->setValue( v );
909 if ( mAllowingNull && !value.isValid() )
914 mSpinBox->setValue( v );
919QVariant QgsProcessingNumericWidgetWrapper::widgetValue()
const
921 if ( mDoubleSpinBox )
923 if ( mAllowingNull &&
qgsDoubleNear( mDoubleSpinBox->value(), mDoubleSpinBox->minimum() ) )
926 return mDoubleSpinBox->value();
930 if ( mAllowingNull && mSpinBox->value() == mSpinBox->minimum() )
933 return mSpinBox->value();
939QStringList QgsProcessingNumericWidgetWrapper::compatibleParameterTypes()
const
950QStringList QgsProcessingNumericWidgetWrapper::compatibleOutputTypes()
const
957double QgsProcessingNumericWidgetWrapper::calculateStep(
const double minimum,
const double maximum )
959 const double valueRange = maximum - minimum;
960 if ( valueRange <= 1.0 )
962 const double step = valueRange / 10.0;
964 return qgsRound( step, -std::floor( std::log( step ) ) );
972QString QgsProcessingNumericWidgetWrapper::parameterType()
const
979 return new QgsProcessingNumericWidgetWrapper( parameter, type );
984 return new QgsProcessingNumberParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
994 QVBoxLayout *vlayout =
new QVBoxLayout();
995 vlayout->setContentsMargins( 0, 0, 0, 0 );
997 vlayout->addWidget(
new QLabel( tr(
"Linked input" ) ) );
999 mParentLayerComboBox =
new QComboBox();
1001 QString initialParent;
1003 initialParent = distParam->parentParameterName();
1005 if (
auto *lModel = widgetContext.
model() )
1008 const QMap<QString, QgsProcessingModelParameter> components = lModel->parameterComponents();
1009 for (
auto it = components.constBegin(); it != components.constEnd(); ++it )
1013 mParentLayerComboBox->addItem( definition->
description(), definition->
name() );
1014 if ( !initialParent.isEmpty() && initialParent == definition->
name() )
1016 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
1021 mParentLayerComboBox->addItem( definition->
description(), definition->
name() );
1022 if ( !initialParent.isEmpty() && initialParent == definition->
name() )
1024 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
1029 mParentLayerComboBox->addItem( definition->
description(), definition->
name() );
1030 if ( !initialParent.isEmpty() && initialParent == definition->
name() )
1032 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
1037 mParentLayerComboBox->addItem( definition->
description(), definition->
name() );
1038 if ( !initialParent.isEmpty() && initialParent == definition->
name() )
1040 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
1046 if ( mParentLayerComboBox->count() == 0 && !initialParent.isEmpty() )
1049 mParentLayerComboBox->addItem( initialParent, initialParent );
1050 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
1053 vlayout->addWidget( mParentLayerComboBox );
1055 vlayout->addWidget(
new QLabel( tr(
"Minimum value" ) ) );
1056 mMinLineEdit =
new QLineEdit();
1057 vlayout->addWidget( mMinLineEdit );
1059 vlayout->addWidget(
new QLabel( tr(
"Maximum value" ) ) );
1060 mMaxLineEdit =
new QLineEdit();
1061 vlayout->addWidget( mMaxLineEdit );
1063 vlayout->addWidget(
new QLabel( tr(
"Default value" ) ) );
1064 mDefaultLineEdit =
new QLineEdit();
1065 vlayout->addWidget( mDefaultLineEdit );
1069 mMinLineEdit->setText( QLocale().toString( distParam->minimum() ) );
1070 mMaxLineEdit->setText( QLocale().toString( distParam->maximum() ) );
1071 mDefaultLineEdit->setText( distParam->defaultValueForGui().toString() );
1074 setLayout( vlayout );
1082 auto param = std::make_unique<QgsProcessingParameterDistance>( name, description, ok ? val : QVariant(), mParentLayerComboBox->currentData().toString() );
1087 param->setMinimum( val );
1093 param->setMaximum( val );
1096 param->setFlags( flags );
1097 return param.release();
1101 : QgsProcessingNumericWidgetWrapper( parameter, type, parent )
1105QString QgsProcessingDistanceWidgetWrapper::parameterType()
const
1112 return new QgsProcessingDistanceWidgetWrapper( parameter, type );
1115QWidget *QgsProcessingDistanceWidgetWrapper::createWidget()
1119 QWidget *spin = QgsProcessingNumericWidgetWrapper::createWidget();
1124 mLabel =
new QLabel();
1125 mUnitsCombo =
new QComboBox();
1137 const int labelMargin =
static_cast<int>( std::round( mUnitsCombo->fontMetrics().horizontalAdvance(
'X' ) ) );
1138 QHBoxLayout *layout =
new QHBoxLayout();
1139 layout->addWidget( spin, 1 );
1140 layout->insertSpacing( 1, labelMargin / 2 );
1141 layout->insertWidget( 2, mLabel );
1142 layout->insertWidget( 3, mUnitsCombo );
1147 mWarningLabel =
new QWidget();
1148 QHBoxLayout *warningLayout =
new QHBoxLayout();
1149 warningLayout->setContentsMargins( 0, 0, 0, 0 );
1150 QLabel *warning =
new QLabel();
1152 const int size =
static_cast<int>( std::max( 24.0, spin->minimumSize().height() * 0.5 ) );
1153 warning->setPixmap( icon.pixmap( icon.actualSize( QSize( size, size ) ) ) );
1154 warning->setToolTip( tr(
"Distance is in geographic degrees. Consider reprojecting to a projected local coordinate system for accurate results." ) );
1155 warningLayout->insertSpacing( 0, labelMargin / 2 );
1156 warningLayout->insertWidget( 1, warning );
1157 mWarningLabel->setLayout( warningLayout );
1158 layout->insertWidget( 4, mWarningLabel );
1160 QWidget *w =
new QWidget();
1161 layout->setContentsMargins( 0, 0, 0, 0 );
1162 w->setLayout( layout );
1176void QgsProcessingDistanceWidgetWrapper::postInitialize(
const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
1178 QgsProcessingNumericWidgetWrapper::postInitialize( wrappers );
1185 if ( wrapper->parameterDefinition()->name() ==
static_cast<const QgsProcessingParameterDistance *
>( parameterDefinition() )->parentParameterName() )
1187 setUnitParameterValue( wrapper->parameterValue(), wrapper );
1189 setUnitParameterValue( wrapper->parameterValue(), wrapper );
1209 std::unique_ptr<QgsProcessingContext> tmpContext;
1210 if ( mProcessingContextGenerator )
1211 context = mProcessingContextGenerator->processingContext();
1215 tmpContext = std::make_unique<QgsProcessingContext>();
1216 context = tmpContext.get();
1235 mUnitsCombo->hide();
1240 mUnitsCombo->setCurrentIndex( mUnitsCombo->findData(
static_cast<int>( units ) ) );
1241 mUnitsCombo->show();
1248QVariant QgsProcessingDistanceWidgetWrapper::widgetValue()
const
1250 const QVariant val = QgsProcessingNumericWidgetWrapper::widgetValue();
1251 if ( val.userType() == QMetaType::Type::Double && mUnitsCombo && mUnitsCombo->isVisible() )
1264 return new QgsProcessingDistanceParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
1275 QVBoxLayout *vlayout =
new QVBoxLayout();
1276 vlayout->setContentsMargins( 0, 0, 0, 0 );
1278 vlayout->addWidget(
new QLabel( tr(
"Linked input" ) ) );
1280 mParentLayerComboBox =
new QComboBox();
1282 QString initialParent;
1284 initialParent = areaParam->parentParameterName();
1286 if (
auto *lModel = widgetContext.
model() )
1289 const QMap<QString, QgsProcessingModelParameter> components = lModel->parameterComponents();
1290 for (
auto it = components.constBegin(); it != components.constEnd(); ++it )
1294 mParentLayerComboBox->addItem( definition->
description(), definition->
name() );
1295 if ( !initialParent.isEmpty() && initialParent == definition->
name() )
1297 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
1302 mParentLayerComboBox->addItem( definition->
description(), definition->
name() );
1303 if ( !initialParent.isEmpty() && initialParent == definition->
name() )
1305 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
1310 mParentLayerComboBox->addItem( definition->
description(), definition->
name() );
1311 if ( !initialParent.isEmpty() && initialParent == definition->
name() )
1313 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
1318 mParentLayerComboBox->addItem( definition->
description(), definition->
name() );
1319 if ( !initialParent.isEmpty() && initialParent == definition->
name() )
1321 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
1327 if ( mParentLayerComboBox->count() == 0 && !initialParent.isEmpty() )
1330 mParentLayerComboBox->addItem( initialParent, initialParent );
1331 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
1334 vlayout->addWidget( mParentLayerComboBox );
1336 vlayout->addWidget(
new QLabel( tr(
"Minimum value" ) ) );
1337 mMinLineEdit =
new QLineEdit();
1338 vlayout->addWidget( mMinLineEdit );
1340 vlayout->addWidget(
new QLabel( tr(
"Maximum value" ) ) );
1341 mMaxLineEdit =
new QLineEdit();
1342 vlayout->addWidget( mMaxLineEdit );
1344 vlayout->addWidget(
new QLabel( tr(
"Default value" ) ) );
1345 mDefaultLineEdit =
new QLineEdit();
1346 vlayout->addWidget( mDefaultLineEdit );
1350 mMinLineEdit->setText( QLocale().toString( areaParam->minimum() ) );
1351 mMaxLineEdit->setText( QLocale().toString( areaParam->maximum() ) );
1352 mDefaultLineEdit->setText( areaParam->defaultValueForGui().toString() );
1355 setLayout( vlayout );
1363 auto param = std::make_unique<QgsProcessingParameterArea>( name, description, ok ? val : QVariant(), mParentLayerComboBox->currentData().toString() );
1368 param->setMinimum( val );
1374 param->setMaximum( val );
1377 param->setFlags( flags );
1378 return param.release();
1387 : QgsProcessingNumericWidgetWrapper( parameter, type, parent )
1391QString QgsProcessingAreaWidgetWrapper::parameterType()
const
1398 return new QgsProcessingAreaWidgetWrapper( parameter, type );
1401QWidget *QgsProcessingAreaWidgetWrapper::createWidget()
1405 QWidget *spin = QgsProcessingNumericWidgetWrapper::createWidget();
1410 mLabel =
new QLabel();
1411 mUnitsCombo =
new QComboBox();
1426 const int labelMargin =
static_cast<int>( std::round( mUnitsCombo->fontMetrics().horizontalAdvance(
'X' ) ) );
1427 QHBoxLayout *layout =
new QHBoxLayout();
1428 layout->addWidget( spin, 1 );
1429 layout->insertSpacing( 1, labelMargin / 2 );
1430 layout->insertWidget( 2, mLabel );
1431 layout->insertWidget( 3, mUnitsCombo );
1436 mWarningLabel =
new QWidget();
1437 QHBoxLayout *warningLayout =
new QHBoxLayout();
1438 warningLayout->setContentsMargins( 0, 0, 0, 0 );
1439 QLabel *warning =
new QLabel();
1441 const int size =
static_cast<int>( std::max( 24.0, spin->minimumSize().height() * 0.5 ) );
1442 warning->setPixmap( icon.pixmap( icon.actualSize( QSize( size, size ) ) ) );
1443 warning->setToolTip( tr(
"Area is in geographic degrees. Consider reprojecting to a projected local coordinate system for accurate results." ) );
1444 warningLayout->insertSpacing( 0, labelMargin / 2 );
1445 warningLayout->insertWidget( 1, warning );
1446 mWarningLabel->setLayout( warningLayout );
1447 layout->insertWidget( 4, mWarningLabel );
1449 QWidget *w =
new QWidget();
1450 layout->setContentsMargins( 0, 0, 0, 0 );
1451 w->setLayout( layout );
1465void QgsProcessingAreaWidgetWrapper::postInitialize(
const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
1467 QgsProcessingNumericWidgetWrapper::postInitialize( wrappers );
1498 std::unique_ptr<QgsProcessingContext> tmpContext;
1499 if ( mProcessingContextGenerator )
1500 context = mProcessingContextGenerator->processingContext();
1504 tmpContext = std::make_unique<QgsProcessingContext>();
1505 context = tmpContext.get();
1519void QgsProcessingAreaWidgetWrapper::setUnits(
Qgis::AreaUnit units )
1524 mUnitsCombo->hide();
1529 mUnitsCombo->setCurrentIndex( mUnitsCombo->findData( QVariant::fromValue( units ) ) );
1530 mUnitsCombo->show();
1537QVariant QgsProcessingAreaWidgetWrapper::widgetValue()
const
1539 const QVariant val = QgsProcessingNumericWidgetWrapper::widgetValue();
1540 if ( val.userType() == QMetaType::Type::Double && mUnitsCombo && mUnitsCombo->isVisible() )
1553 return new QgsProcessingAreaParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
1564 QVBoxLayout *vlayout =
new QVBoxLayout();
1565 vlayout->setContentsMargins( 0, 0, 0, 0 );
1567 vlayout->addWidget(
new QLabel( tr(
"Linked input" ) ) );
1569 mParentLayerComboBox =
new QComboBox();
1571 QString initialParent;
1573 initialParent = volumeParam->parentParameterName();
1575 if (
auto *lModel = widgetContext.
model() )
1578 const QMap<QString, QgsProcessingModelParameter> components = lModel->parameterComponents();
1579 for (
auto it = components.constBegin(); it != components.constEnd(); ++it )
1583 mParentLayerComboBox->addItem( definition->
description(), definition->
name() );
1584 if ( !initialParent.isEmpty() && initialParent == definition->
name() )
1586 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
1591 mParentLayerComboBox->addItem( definition->
description(), definition->
name() );
1592 if ( !initialParent.isEmpty() && initialParent == definition->
name() )
1594 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
1599 mParentLayerComboBox->addItem( definition->
description(), definition->
name() );
1600 if ( !initialParent.isEmpty() && initialParent == definition->
name() )
1602 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
1607 mParentLayerComboBox->addItem( definition->
description(), definition->
name() );
1608 if ( !initialParent.isEmpty() && initialParent == definition->
name() )
1610 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
1616 if ( mParentLayerComboBox->count() == 0 && !initialParent.isEmpty() )
1619 mParentLayerComboBox->addItem( initialParent, initialParent );
1620 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
1623 vlayout->addWidget( mParentLayerComboBox );
1625 vlayout->addWidget(
new QLabel( tr(
"Minimum value" ) ) );
1626 mMinLineEdit =
new QLineEdit();
1627 vlayout->addWidget( mMinLineEdit );
1629 vlayout->addWidget(
new QLabel( tr(
"Maximum value" ) ) );
1630 mMaxLineEdit =
new QLineEdit();
1631 vlayout->addWidget( mMaxLineEdit );
1633 vlayout->addWidget(
new QLabel( tr(
"Default value" ) ) );
1634 mDefaultLineEdit =
new QLineEdit();
1635 vlayout->addWidget( mDefaultLineEdit );
1639 mMinLineEdit->setText( QLocale().toString( volumeParam->minimum() ) );
1640 mMaxLineEdit->setText( QLocale().toString( volumeParam->maximum() ) );
1641 mDefaultLineEdit->setText( volumeParam->defaultValueForGui().toString() );
1644 setLayout( vlayout );
1652 auto param = std::make_unique<QgsProcessingParameterVolume>( name, description, ok ? val : QVariant(), mParentLayerComboBox->currentData().toString() );
1657 param->setMinimum( val );
1663 param->setMaximum( val );
1666 param->setFlags( flags );
1667 return param.release();
1676 : QgsProcessingNumericWidgetWrapper( parameter, type, parent )
1680QString QgsProcessingVolumeWidgetWrapper::parameterType()
const
1687 return new QgsProcessingVolumeWidgetWrapper( parameter, type );
1690QWidget *QgsProcessingVolumeWidgetWrapper::createWidget()
1694 QWidget *spin = QgsProcessingNumericWidgetWrapper::createWidget();
1699 mLabel =
new QLabel();
1700 mUnitsCombo =
new QComboBox();
1713 const int labelMargin =
static_cast<int>( std::round( mUnitsCombo->fontMetrics().horizontalAdvance(
'X' ) ) );
1714 QHBoxLayout *layout =
new QHBoxLayout();
1715 layout->addWidget( spin, 1 );
1716 layout->insertSpacing( 1, labelMargin / 2 );
1717 layout->insertWidget( 2, mLabel );
1718 layout->insertWidget( 3, mUnitsCombo );
1723 mWarningLabel =
new QWidget();
1724 QHBoxLayout *warningLayout =
new QHBoxLayout();
1725 warningLayout->setContentsMargins( 0, 0, 0, 0 );
1726 QLabel *warning =
new QLabel();
1728 const int size =
static_cast<int>( std::max( 24.0, spin->minimumSize().height() * 0.5 ) );
1729 warning->setPixmap( icon.pixmap( icon.actualSize( QSize( size, size ) ) ) );
1730 warning->setToolTip( tr(
"Volume is in geographic degrees. Consider reprojecting to a projected local coordinate system for accurate results." ) );
1731 warningLayout->insertSpacing( 0, labelMargin / 2 );
1732 warningLayout->insertWidget( 1, warning );
1733 mWarningLabel->setLayout( warningLayout );
1734 layout->insertWidget( 4, mWarningLabel );
1736 QWidget *w =
new QWidget();
1737 layout->setContentsMargins( 0, 0, 0, 0 );
1738 w->setLayout( layout );
1752void QgsProcessingVolumeWidgetWrapper::postInitialize(
const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
1754 QgsProcessingNumericWidgetWrapper::postInitialize( wrappers );
1785 std::unique_ptr<QgsProcessingContext> tmpContext;
1786 if ( mProcessingContextGenerator )
1787 context = mProcessingContextGenerator->processingContext();
1791 tmpContext = std::make_unique<QgsProcessingContext>();
1792 context = tmpContext.get();
1811 mUnitsCombo->hide();
1816 mUnitsCombo->setCurrentIndex( mUnitsCombo->findData( QVariant::fromValue( units ) ) );
1817 mUnitsCombo->show();
1824QVariant QgsProcessingVolumeWidgetWrapper::widgetValue()
const
1826 const QVariant val = QgsProcessingNumericWidgetWrapper::widgetValue();
1827 if ( val.userType() == QMetaType::Type::Double && mUnitsCombo && mUnitsCombo->isVisible() )
1840 return new QgsProcessingVolumeParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
1851 QVBoxLayout *vlayout =
new QVBoxLayout();
1852 vlayout->setContentsMargins( 0, 0, 0, 0 );
1854 vlayout->addWidget(
new QLabel( tr(
"Minimum value" ) ) );
1855 mMinLineEdit =
new QLineEdit();
1856 vlayout->addWidget( mMinLineEdit );
1858 vlayout->addWidget(
new QLabel( tr(
"Maximum value" ) ) );
1859 mMaxLineEdit =
new QLineEdit();
1860 vlayout->addWidget( mMaxLineEdit );
1862 vlayout->addWidget(
new QLabel( tr(
"Default value" ) ) );
1863 mDefaultLineEdit =
new QLineEdit();
1864 vlayout->addWidget( mDefaultLineEdit );
1866 vlayout->addWidget(
new QLabel( tr(
"Default unit type" ) ) );
1868 mUnitsCombo =
new QComboBox();
1878 vlayout->addWidget( mUnitsCombo );
1882 mMinLineEdit->setText( QLocale().toString( durationParam->minimum() ) );
1883 mMaxLineEdit->setText( QLocale().toString( durationParam->maximum() ) );
1884 mDefaultLineEdit->setText( durationParam->defaultValueForGui().toString() );
1885 mUnitsCombo->setCurrentIndex( mUnitsCombo->findData(
static_cast<int>( durationParam->defaultUnit() ) ) );
1888 setLayout( vlayout );
1896 auto param = std::make_unique<QgsProcessingParameterDuration>( name, description, ok ? val : QVariant() );
1901 param->setMinimum( val );
1907 param->setMaximum( val );
1910 param->setDefaultUnit(
static_cast<Qgis::TemporalUnit>( mUnitsCombo->currentData().toInt() ) );
1912 param->setFlags( flags );
1913 return param.release();
1917 : QgsProcessingNumericWidgetWrapper( parameter, type, parent )
1921QString QgsProcessingDurationWidgetWrapper::parameterType()
const
1928 return new QgsProcessingDurationWidgetWrapper( parameter, type );
1931QWidget *QgsProcessingDurationWidgetWrapper::createWidget()
1935 QWidget *spin = QgsProcessingNumericWidgetWrapper::createWidget();
1940 mUnitsCombo =
new QComboBox();
1952 QHBoxLayout *layout =
new QHBoxLayout();
1953 layout->addWidget( spin, 1 );
1954 layout->insertWidget( 1, mUnitsCombo );
1956 QWidget *w =
new QWidget();
1957 layout->setContentsMargins( 0, 0, 0, 0 );
1958 w->setLayout( layout );
1960 mUnitsCombo->setCurrentIndex( mUnitsCombo->findData(
static_cast<int>( durationDef->
defaultUnit() ) ) );
1961 mUnitsCombo->show();
1973QLabel *QgsProcessingDurationWidgetWrapper::createLabel()
1985QVariant QgsProcessingDurationWidgetWrapper::widgetValue()
const
1987 const QVariant val = QgsProcessingNumericWidgetWrapper::widgetValue();
1988 if ( val.userType() == QMetaType::Type::Double && mUnitsCombo )
1999void QgsProcessingDurationWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
2005 QgsProcessingNumericWidgetWrapper::setWidgetValue( val, context );
2009 QgsProcessingNumericWidgetWrapper::setWidgetValue( value, context );
2015 return new QgsProcessingDurationParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
2025 QVBoxLayout *vlayout =
new QVBoxLayout();
2026 vlayout->setContentsMargins( 0, 0, 0, 0 );
2028 vlayout->addWidget(
new QLabel( tr(
"Default value" ) ) );
2030 mDefaultLineEdit =
new QLineEdit();
2034 mDefaultLineEdit->setText( scaleParam->defaultValueForGui().toString() );
2037 vlayout->addWidget( mDefaultLineEdit );
2039 setLayout( vlayout );
2045 double val = mDefaultLineEdit->text().toDouble( &ok );
2046 auto param = std::make_unique<QgsProcessingParameterScale>( name, description, ok ? val : QVariant() );
2048 return param.release();
2052 : QgsProcessingNumericWidgetWrapper( parameter, type, parent )
2056QString QgsProcessingScaleWidgetWrapper::parameterType()
const
2063 return new QgsProcessingScaleWidgetWrapper( parameter, type );
2066QWidget *QgsProcessingScaleWidgetWrapper::createWidget()
2078 mScaleWidget->setAllowNull(
true );
2080 mScaleWidget->setMapCanvas( widgetContext().mapCanvas() );
2081 mScaleWidget->setShowCurrentScaleButton(
true );
2083 mScaleWidget->setToolTip( parameterDefinition()->toolTip() );
2085 emit widgetValueHasChanged(
this );
2087 return mScaleWidget;
2096 mScaleWidget->setMapCanvas( context.
mapCanvas() );
2101QVariant QgsProcessingScaleWidgetWrapper::widgetValue()
const
2103 return mScaleWidget && !mScaleWidget->isNull() ? QVariant( mScaleWidget->scale() ) : QVariant();
2106void QgsProcessingScaleWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
2110 if ( mScaleWidget->allowNull() && !value.isValid() )
2111 mScaleWidget->setNull();
2115 mScaleWidget->setScale( v );
2122 return new QgsProcessingScaleParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
2133 QVBoxLayout *vlayout =
new QVBoxLayout();
2134 vlayout->setContentsMargins( 0, 0, 0, 0 );
2136 vlayout->addWidget(
new QLabel( tr(
"Number type" ) ) );
2138 mTypeComboBox =
new QComboBox();
2141 vlayout->addWidget( mTypeComboBox );
2143 vlayout->addWidget(
new QLabel( tr(
"Minimum value" ) ) );
2144 mMinLineEdit =
new QLineEdit();
2145 vlayout->addWidget( mMinLineEdit );
2147 vlayout->addWidget(
new QLabel( tr(
"Maximum value" ) ) );
2148 mMaxLineEdit =
new QLineEdit();
2149 vlayout->addWidget( mMaxLineEdit );
2153 mTypeComboBox->setCurrentIndex( mTypeComboBox->findData(
static_cast<int>( rangeParam->dataType() ) ) );
2155 mMinLineEdit->setText( QLocale().toString( range.at( 0 ) ) );
2156 mMaxLineEdit->setText( QLocale().toString( range.at( 1 ) ) );
2159 setLayout( vlayout );
2164 QString defaultValue;
2165 if ( mMinLineEdit->text().isEmpty() )
2167 defaultValue = QStringLiteral(
"None" );
2175 defaultValue = QStringLiteral(
"None" );
2179 if ( mMaxLineEdit->text().isEmpty() )
2181 defaultValue += QLatin1String(
",None" );
2187 defaultValue += QStringLiteral(
",%1" ).arg( ok ? QString::number( val ) : QLatin1String(
"None" ) );
2191 auto param = std::make_unique<QgsProcessingParameterRange>( name, description, dataType, defaultValue );
2192 param->setFlags( flags );
2193 return param.release();
2202QWidget *QgsProcessingRangeWidgetWrapper::createWidget()
2211 QHBoxLayout *layout =
new QHBoxLayout();
2216 mMinSpinBox->setExpressionsEnabled(
true );
2217 mMinSpinBox->setShowClearButton(
false );
2218 mMaxSpinBox->setExpressionsEnabled(
true );
2219 mMaxSpinBox->setShowClearButton(
false );
2221 QLabel *minLabel =
new QLabel( tr(
"Min" ) );
2222 layout->addWidget( minLabel );
2223 layout->addWidget( mMinSpinBox, 1 );
2225 QLabel *maxLabel =
new QLabel( tr(
"Max" ) );
2226 layout->addWidget( maxLabel );
2227 layout->addWidget( mMaxSpinBox, 1 );
2229 QWidget *w =
new QWidget();
2230 layout->setContentsMargins( 0, 0, 0, 0 );
2231 w->setLayout( layout );
2235 mMinSpinBox->setDecimals( 6 );
2236 mMaxSpinBox->setDecimals( 6 );
2240 mMinSpinBox->setDecimals( 0 );
2241 mMaxSpinBox->setDecimals( 0 );
2244 mMinSpinBox->setMinimum( -99999999.999999 );
2245 mMaxSpinBox->setMinimum( -99999999.999999 );
2246 mMinSpinBox->setMaximum( 99999999.999999 );
2247 mMaxSpinBox->setMaximum( 99999999.999999 );
2251 mAllowingNull =
true;
2253 const double min = mMinSpinBox->minimum() - 1;
2254 mMinSpinBox->setMinimum( min );
2255 mMaxSpinBox->setMinimum( min );
2256 mMinSpinBox->setValue( min );
2257 mMaxSpinBox->setValue( min );
2259 mMinSpinBox->setShowClearButton(
true );
2260 mMaxSpinBox->setShowClearButton(
true );
2261 mMinSpinBox->setSpecialValueText( tr(
"Not set" ) );
2262 mMaxSpinBox->setSpecialValueText( tr(
"Not set" ) );
2265 w->setToolTip( parameterDefinition()->toolTip() );
2267 connect( mMinSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, [=](
const double v ) {
2268 mBlockChangedSignal++;
2269 if ( !mAllowingNull && v > mMaxSpinBox->value() )
2270 mMaxSpinBox->setValue( v );
2271 mBlockChangedSignal--;
2273 if ( !mBlockChangedSignal )
2274 emit widgetValueHasChanged(
this );
2276 connect( mMaxSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, [=](
const double v ) {
2277 mBlockChangedSignal++;
2278 if ( !mAllowingNull && v < mMinSpinBox->value() )
2279 mMinSpinBox->setValue( v );
2280 mBlockChangedSignal--;
2282 if ( !mBlockChangedSignal )
2283 emit widgetValueHasChanged(
this );
2292void QgsProcessingRangeWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
2295 if ( mAllowingNull && v.empty() )
2297 mMinSpinBox->clear();
2298 mMaxSpinBox->clear();
2305 if ( mAllowingNull )
2307 mBlockChangedSignal++;
2308 if ( std::isnan( v.at( 0 ) ) )
2309 mMinSpinBox->clear();
2311 mMinSpinBox->setValue( v.at( 0 ) );
2313 if ( v.count() >= 2 )
2315 if ( std::isnan( v.at( 1 ) ) )
2316 mMaxSpinBox->clear();
2318 mMaxSpinBox->setValue( v.at( 1 ) );
2320 mBlockChangedSignal--;
2324 mBlockChangedSignal++;
2325 mMinSpinBox->setValue( v.at( 0 ) );
2326 if ( v.count() >= 2 )
2327 mMaxSpinBox->setValue( v.at( 1 ) );
2328 mBlockChangedSignal--;
2332 if ( !mBlockChangedSignal )
2333 emit widgetValueHasChanged(
this );
2336QVariant QgsProcessingRangeWidgetWrapper::widgetValue()
const
2338 if ( mAllowingNull )
2341 if (
qgsDoubleNear( mMinSpinBox->value(), mMinSpinBox->minimum() ) )
2342 value = QStringLiteral(
"None" );
2344 value = QString::number( mMinSpinBox->value() );
2346 if (
qgsDoubleNear( mMaxSpinBox->value(), mMaxSpinBox->minimum() ) )
2347 value += QLatin1String(
",None" );
2349 value += QStringLiteral(
",%1" ).arg( mMaxSpinBox->value() );
2354 return QStringLiteral(
"%1,%2" ).arg( mMinSpinBox->value() ).arg( mMaxSpinBox->value() );
2357QStringList QgsProcessingRangeWidgetWrapper::compatibleParameterTypes()
const
2359 return QStringList()
2364QStringList QgsProcessingRangeWidgetWrapper::compatibleOutputTypes()
const
2370QString QgsProcessingRangeWidgetWrapper::modelerExpressionFormatString()
const
2372 return tr(
"string as two comma delimited floats, e.g. '1,10'" );
2375QString QgsProcessingRangeWidgetWrapper::parameterType()
const
2382 return new QgsProcessingRangeWidgetWrapper( parameter, type );
2387 return new QgsProcessingRangeParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
2398 QVBoxLayout *vlayout =
new QVBoxLayout();
2399 vlayout->setContentsMargins( 0, 0, 0, 0 );
2401 mMatrixWidget =
new QgsProcessingMatrixModelerWidget();
2404 mMatrixWidget->setValue( matrixParam->headers(), matrixParam->defaultValueForGui() );
2405 mMatrixWidget->setFixedRows( matrixParam->hasFixedNumberRows() );
2407 vlayout->addWidget( mMatrixWidget );
2408 setLayout( vlayout );
2413 auto param = std::make_unique<QgsProcessingParameterMatrix>( name, description, 1, mMatrixWidget->fixedRows(), mMatrixWidget->headers(), mMatrixWidget->value() );
2414 param->setFlags( flags );
2415 return param.release();
2424QWidget *QgsProcessingMatrixWidgetWrapper::createWidget()
2426 mMatrixWidget =
new QgsProcessingMatrixParameterPanel(
nullptr,
dynamic_cast<const QgsProcessingParameterMatrix *
>( parameterDefinition() ) );
2427 mMatrixWidget->setToolTip( parameterDefinition()->toolTip() );
2429 connect( mMatrixWidget, &QgsProcessingMatrixParameterPanel::changed,
this, [=] {
2430 emit widgetValueHasChanged(
this );
2439 return mMatrixWidget;
2445void QgsProcessingMatrixWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
2448 if ( mMatrixWidget )
2449 mMatrixWidget->setValue( v );
2452QVariant QgsProcessingMatrixWidgetWrapper::widgetValue()
const
2454 if ( mMatrixWidget )
2455 return mMatrixWidget->value().isEmpty() ? QVariant() : mMatrixWidget->value();
2460QStringList QgsProcessingMatrixWidgetWrapper::compatibleParameterTypes()
const
2462 return QStringList()
2466QStringList QgsProcessingMatrixWidgetWrapper::compatibleOutputTypes()
const
2468 return QStringList();
2471QString QgsProcessingMatrixWidgetWrapper::modelerExpressionFormatString()
const
2473 return tr(
"comma delimited string of values, or an array of values" );
2476QString QgsProcessingMatrixWidgetWrapper::parameterType()
const
2483 return new QgsProcessingMatrixWidgetWrapper( parameter, type );
2488 return new QgsProcessingMatrixParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
2500 QVBoxLayout *vlayout =
new QVBoxLayout();
2501 vlayout->setContentsMargins( 0, 0, 0, 0 );
2503 vlayout->addWidget(
new QLabel( tr(
"Type" ) ) );
2505 mTypeComboBox =
new QComboBox();
2509 mTypeComboBox->setCurrentIndex( mTypeComboBox->findData(
static_cast<int>( fileParam->behavior() ) ) );
2511 mTypeComboBox->setCurrentIndex( 0 );
2512 vlayout->addWidget( mTypeComboBox );
2514 vlayout->addWidget(
new QLabel( tr(
"File filter" ) ) );
2516 mFilterComboBox =
new QComboBox();
2517 mFilterComboBox->setEditable(
true );
2519 mFilterComboBox->addItem( tr(
"All Files (*.*)" ) );
2520 mFilterComboBox->addItem( tr(
"CSV Files (*.csv)" ) );
2521 mFilterComboBox->addItem( tr(
"HTML Files (*.html *.htm)" ) );
2522 mFilterComboBox->addItem( tr(
"Text Files (*.txt)" ) );
2524 mFilterComboBox->setCurrentText( fileParam->fileFilter() );
2526 mFilterComboBox->setCurrentIndex( 0 );
2527 vlayout->addWidget( mFilterComboBox );
2529 vlayout->addWidget(
new QLabel( tr(
"Default value" ) ) );
2532 mDefaultFileWidget->lineEdit()->setShowClearButton(
true );
2536 mDefaultFileWidget->setFilePath( fileParam->defaultValueForGui().toString() );
2540 vlayout->addWidget( mDefaultFileWidget );
2542 connect( mTypeComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, [=] {
2550 setLayout( vlayout );
2555 auto param = std::make_unique<QgsProcessingParameterFile>( name, description );
2558 param->setFileFilter( mFilterComboBox->currentText() );
2559 if ( !mDefaultFileWidget->filePath().isEmpty() )
2560 param->setDefaultValue( mDefaultFileWidget->filePath() );
2561 param->setFlags( flags );
2562 return param.release();
2571QWidget *QgsProcessingFileWidgetWrapper::createWidget()
2581 mFileWidget->setToolTip( parameterDefinition()->toolTip() );
2582 mFileWidget->setDialogTitle( parameterDefinition()->description() );
2584 mFileWidget->setDefaultRoot(
QgsSettings().value( QStringLiteral(
"/Processing/LastInputPath" ), QDir::homePath() ).toString() );
2591 mFileWidget->setFilter( fileParam->
fileFilter() );
2592 else if ( !fileParam->
extension().isEmpty() )
2593 mFileWidget->setFilter( tr(
"%1 files" ).arg( fileParam->
extension().toUpper() ) + QStringLiteral(
" (*." ) + fileParam->
extension().toLower() +
')' );
2602 QgsSettings().
setValue( QStringLiteral(
"/Processing/LastInputPath" ), QFileInfo( path ).canonicalPath() );
2603 emit widgetValueHasChanged(
this );
2611void QgsProcessingFileWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
2615 mFileWidget->setFilePath( v );
2618QVariant QgsProcessingFileWidgetWrapper::widgetValue()
const
2621 return mFileWidget->filePath();
2626QStringList QgsProcessingFileWidgetWrapper::compatibleParameterTypes()
const
2628 return QStringList()
2633QStringList QgsProcessingFileWidgetWrapper::compatibleOutputTypes()
const
2644QString QgsProcessingFileWidgetWrapper::modelerExpressionFormatString()
const
2646 return tr(
"string representing a path to a file or folder" );
2649QString QgsProcessingFileWidgetWrapper::parameterType()
const
2656 return new QgsProcessingFileWidgetWrapper( parameter, type );
2661 return new QgsProcessingFileParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
2672 QVBoxLayout *vlayout =
new QVBoxLayout();
2673 vlayout->setContentsMargins( 0, 0, 0, 0 );
2674 vlayout->addWidget(
new QLabel( tr(
"Default value" ) ) );
2677 mDefaultQgisLineEdit->registerExpressionContextGenerator(
this );
2679 mDefaultPointCloudLineEdit =
new QgsProcessingPointCloudExpressionLineEdit();
2680 mDefaultRasterCalculatorLineEdit =
new QgsProcessingRasterCalculatorExpressionLineEdit();
2682 QStackedWidget *stackedWidget =
new QStackedWidget();
2683 stackedWidget->addWidget( mDefaultQgisLineEdit );
2684 stackedWidget->addWidget( mDefaultPointCloudLineEdit );
2685 stackedWidget->addWidget( mDefaultRasterCalculatorLineEdit );
2686 vlayout->addWidget( stackedWidget );
2691 mDefaultQgisLineEdit->setExpression( expr );
2692 mDefaultPointCloudLineEdit->setExpression( expr );
2695 vlayout->addWidget(
new QLabel( tr(
"Parent layer" ) ) );
2697 mParentLayerComboBox =
new QComboBox();
2698 vlayout->addWidget( mParentLayerComboBox );
2700 vlayout->addWidget(
new QLabel( tr(
"Expression type" ) ) );
2701 mExpressionTypeComboBox =
new QComboBox();
2706 connect( mExpressionTypeComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, [=](
int ) {
2707 mParentLayerComboBox->clear();
2708 mParentLayerComboBox->addItem( tr(
"None" ), QVariant() );
2710 stackedWidget->setCurrentIndex( mExpressionTypeComboBox->currentIndex() > 0 ? mExpressionTypeComboBox->currentIndex() : 0 );
2712 QString initialParent;
2714 initialParent = expParam->parentLayerParameterName();
2718 if ( QgsProcessingModelAlgorithm *model = widgetContext.
model() )
2721 const QMap<QString, QgsProcessingModelParameter> components = model->parameterComponents();
2722 for (
auto it = components.constBegin(); it != components.constEnd(); ++it )
2729 mParentLayerComboBox->addItem( definition->
description(), definition->
name() );
2730 if ( !initialParent.isEmpty() && initialParent == definition->
name() )
2732 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
2737 mParentLayerComboBox->addItem( definition->
description(), definition->
name() );
2738 if ( !initialParent.isEmpty() && initialParent == definition->
name() )
2740 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
2747 mParentLayerComboBox->addItem( definition->
description(), definition->
name() );
2748 if ( !initialParent.isEmpty() && initialParent == definition->
name() )
2750 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
2761 mParentLayerComboBox->addItem( definition->
description(), definition->
name() );
2762 if ( !initialParent.isEmpty() && initialParent == definition->
name() )
2764 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
2772 if ( mParentLayerComboBox->count() == 1 && !initialParent.isEmpty() )
2775 mParentLayerComboBox->addItem( initialParent, initialParent );
2776 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
2780 mExpressionTypeComboBox->setCurrentIndex( -1 );
2782 mExpressionTypeComboBox->setCurrentIndex( mExpressionTypeComboBox->findData(
static_cast<int>( expParam->expressionType() ) ) );
2784 mExpressionTypeComboBox->setCurrentIndex( 0 );
2786 vlayout->addWidget( mExpressionTypeComboBox );
2788 setLayout( vlayout );
2795 switch ( expressionType )
2798 expression = mDefaultQgisLineEdit->expression();
2801 expression = mDefaultPointCloudLineEdit->expression();
2804 expression = mDefaultRasterCalculatorLineEdit->expression();
2807 auto param = std::make_unique<QgsProcessingParameterExpression>( name, description, expression, mParentLayerComboBox->currentData().toString(),
false, expressionType );
2808 param->setFlags( flags );
2809 return param.release();
2817QWidget *QgsProcessingExpressionWidgetWrapper::createWidget()
2829 mExpLineEdit->setToolTip( parameterDefinition()->toolTip() );
2830 mExpLineEdit->setExpressionDialogTitle( parameterDefinition()->description() );
2831 mExpLineEdit->registerExpressionContextGenerator(
this );
2833 emit widgetValueHasChanged(
this );
2835 return mExpLineEdit;
2841 mPointCloudExpLineEdit =
new QgsProcessingPointCloudExpressionLineEdit();
2842 mPointCloudExpLineEdit->setToolTip( parameterDefinition()->toolTip() );
2843 connect( mPointCloudExpLineEdit, &QgsProcessingPointCloudExpressionLineEdit::expressionChanged,
this, [=](
const QString & ) {
2844 emit widgetValueHasChanged(
this );
2846 return mPointCloudExpLineEdit;
2851 mRasterCalculatorExpLineEdit =
new QgsProcessingRasterCalculatorExpressionLineEdit();
2852 mRasterCalculatorExpLineEdit->setToolTip( parameterDefinition()->toolTip() );
2855 mRasterCalculatorExpLineEdit->setLayers( QVariantList() <<
"A" <<
"B" <<
"C" <<
"D" <<
"E" <<
"F" <<
"G" );
2857 connect( mRasterCalculatorExpLineEdit, &QgsProcessingRasterCalculatorExpressionLineEdit::expressionChanged,
this, [=](
const QString & ) {
2858 emit widgetValueHasChanged(
this );
2860 return mRasterCalculatorExpLineEdit;
2864 if ( expParam->
metadata().value( QStringLiteral(
"inlineEditor" ) ).toBool() )
2867 mExpBuilderWidget->setToolTip( parameterDefinition()->toolTip() );
2868 mExpBuilderWidget->init( createExpressionContext() );
2870 Q_UNUSED( changed );
2871 emit widgetValueHasChanged(
this );
2873 return mExpBuilderWidget;
2878 mFieldExpWidget->setToolTip( parameterDefinition()->toolTip() );
2879 mFieldExpWidget->setExpressionDialogTitle( parameterDefinition()->description() );
2880 mFieldExpWidget->registerExpressionContextGenerator(
this );
2882 mFieldExpWidget->setAllowEmptyFieldName(
true );
2885 emit widgetValueHasChanged(
this );
2887 return mFieldExpWidget;
2895void QgsProcessingExpressionWidgetWrapper::postInitialize(
const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
2907 setParentLayerWrapperValue( wrapper );
2909 setParentLayerWrapperValue( wrapper );
2925 if ( mExpBuilderWidget )
2928 mExpBuilderWidget->setExpressionContext( createExpressionContext() );
2936 std::unique_ptr<QgsProcessingContext> tmpContext;
2937 if ( mProcessingContextGenerator )
2938 context = mProcessingContextGenerator->processingContext();
2942 tmpContext = std::make_unique<QgsProcessingContext>();
2943 context = tmpContext.get();
2953 if ( val.userType() == qMetaTypeId<QgsProcessingFeatureSourceDefinition>() )
2963 if ( mFieldExpWidget )
2964 mFieldExpWidget->setLayer(
nullptr );
2965 else if ( mExpBuilderWidget )
2966 mExpBuilderWidget->setLayer(
nullptr );
2967 else if ( mExpLineEdit )
2968 mExpLineEdit->setLayer(
nullptr );
2974 std::unique_ptr<QgsMapLayer> ownedLayer( context->
takeResultLayer( layer->
id() ) );
2977 mParentLayer.reset( ownedLayer.release() );
2985 if ( mFieldExpWidget )
2986 mFieldExpWidget->setLayer( layer );
2987 if ( mExpBuilderWidget )
2988 mExpBuilderWidget->setLayer( layer );
2989 else if ( mExpLineEdit )
2990 mExpLineEdit->setLayer( layer );
2999 if ( mPointCloudExpLineEdit )
3000 mPointCloudExpLineEdit->setLayer(
nullptr );
3006 std::unique_ptr<QgsMapLayer> ownedLayer( context->
takeResultLayer( layer->
id() ) );
3009 mParentLayer.reset( ownedLayer.release() );
3017 if ( mPointCloudExpLineEdit )
3018 mPointCloudExpLineEdit->setLayer( layer );
3025 if ( layers.isEmpty() )
3027 if ( mRasterCalculatorExpLineEdit )
3029 mRasterCalculatorExpLineEdit->setLayers( val.userType() == QMetaType::Type::QVariantList ? val.toList() : QVariantList() << val );
3034 if ( mRasterCalculatorExpLineEdit )
3036 QVariantList layersList;
3039 layersList << layer->
name();
3041 mRasterCalculatorExpLineEdit->setLayers( layersList );
3049void QgsProcessingExpressionWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
3052 if ( mFieldExpWidget )
3053 mFieldExpWidget->setExpression( v );
3054 else if ( mExpBuilderWidget )
3055 mExpBuilderWidget->setExpressionText( v );
3056 else if ( mExpLineEdit )
3057 mExpLineEdit->setExpression( v );
3058 else if ( mPointCloudExpLineEdit )
3059 mPointCloudExpLineEdit->setExpression( v );
3060 else if ( mRasterCalculatorExpLineEdit )
3061 mRasterCalculatorExpLineEdit->setExpression( v );
3064QVariant QgsProcessingExpressionWidgetWrapper::widgetValue()
const
3066 if ( mFieldExpWidget )
3067 return mFieldExpWidget->expression();
3068 if ( mExpBuilderWidget )
3069 return mExpBuilderWidget->expressionText();
3070 else if ( mExpLineEdit )
3071 return mExpLineEdit->expression();
3072 else if ( mPointCloudExpLineEdit )
3073 return mPointCloudExpLineEdit->expression();
3074 else if ( mRasterCalculatorExpLineEdit )
3075 return mRasterCalculatorExpLineEdit->expression();
3080QStringList QgsProcessingExpressionWidgetWrapper::compatibleParameterTypes()
const
3082 return QStringList()
3093QStringList QgsProcessingExpressionWidgetWrapper::compatibleOutputTypes()
const
3095 return QStringList()
3101QString QgsProcessingExpressionWidgetWrapper::modelerExpressionFormatString()
const
3103 return tr(
"string representation of an expression" );
3106const QgsVectorLayer *QgsProcessingExpressionWidgetWrapper::linkedVectorLayer()
const
3108 if ( mFieldExpWidget && mFieldExpWidget->layer() )
3109 return mFieldExpWidget->layer();
3111 if ( mExpBuilderWidget && mExpBuilderWidget->layer() )
3112 return mExpBuilderWidget->layer();
3117QString QgsProcessingExpressionWidgetWrapper::parameterType()
const
3124 return new QgsProcessingExpressionWidgetWrapper( parameter, type );
3129 return new QgsProcessingExpressionParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
3141 QHBoxLayout *hl =
new QHBoxLayout();
3142 hl->setContentsMargins( 0, 0, 0, 0 );
3144 mLineEdit =
new QLineEdit();
3145 mLineEdit->setEnabled(
false );
3146 hl->addWidget( mLineEdit, 1 );
3148 mToolButton =
new QToolButton();
3149 mToolButton->setText( QString( QChar( 0x2026 ) ) );
3150 hl->addWidget( mToolButton );
3156 mLineEdit->setText( tr(
"%1 options selected" ).arg( 0 ) );
3159 connect( mToolButton, &QToolButton::clicked,
this, &QgsProcessingEnumPanelWidget::showDialog );
3162void QgsProcessingEnumPanelWidget::setValue(
const QVariant &value )
3164 if ( value.isValid() )
3166 mValue = value.userType() == QMetaType::Type::QVariantList ? value.toList() : QVariantList() << value;
3168 if ( mParam->usesStaticStrings() && mValue.count() == 1 && mValue.at( 0 ).toString().isEmpty() )
3174 updateSummaryText();
3178void QgsProcessingEnumPanelWidget::showDialog()
3180 QVariantList availableOptions;
3183 availableOptions.reserve( mParam->options().size() );
3185 if ( mParam->usesStaticStrings() )
3187 for ( QString o : mParam->options() )
3189 availableOptions << o;
3194 for (
int i = 0; i < mParam->options().count(); ++i )
3195 availableOptions << i;
3199 const QStringList options = mParam ? mParam->options() : QStringList();
3203 QgsProcessingMultipleSelectionPanelWidget *widget =
new QgsProcessingMultipleSelectionPanelWidget( availableOptions, mValue );
3204 widget->setPanelTitle( mParam->description() );
3206 if ( mParam->usesStaticStrings() )
3208 widget->setValueFormatter( [options](
const QVariant &v ) -> QString {
3209 const QString i = v.toString();
3210 return options.contains( i ) ? i : QString();
3215 widget->setValueFormatter( [options](
const QVariant &v ) -> QString {
3216 const int i = v.toInt();
3217 return options.size() > i ? options.at( i ) : QString();
3221 connect( widget, &QgsProcessingMultipleSelectionPanelWidget::selectionChanged,
this, [=]() {
3222 setValue( widget->selectedOptions() );
3229 QgsProcessingMultipleSelectionDialog dlg( availableOptions, mValue,
this, Qt::WindowFlags() );
3231 dlg.setValueFormatter( [options](
const QVariant &v ) -> QString {
3232 const int i = v.toInt();
3233 return options.size() > i ? options.at( i ) : QString();
3237 setValue( dlg.selectedOptions() );
3242void QgsProcessingEnumPanelWidget::updateSummaryText()
3247 if ( mValue.empty() )
3249 mLineEdit->setText( tr(
"%1 options selected" ).arg( 0 ) );
3254 values.reserve( mValue.size() );
3255 if ( mParam->usesStaticStrings() )
3257 for (
const QVariant &val : std::as_const( mValue ) )
3259 values << val.toString();
3264 const QStringList options = mParam->options();
3265 for (
const QVariant &val : std::as_const( mValue ) )
3267 const int i = val.toInt();
3268 values << ( options.size() > i ? options.at( i ) : QString() );
3272 const QString concatenated = values.join( tr(
"," ) );
3273 if ( concatenated.length() < 100 )
3274 mLineEdit->setText( concatenated );
3276 mLineEdit->setText( tr(
"%n option(s) selected",
nullptr, mValue.count() ) );
3284QgsProcessingEnumCheckboxPanelWidget::QgsProcessingEnumCheckboxPanelWidget( QWidget *parent,
const QgsProcessingParameterEnum *param,
int columns )
3287 , mButtonGroup( new QButtonGroup( this ) )
3288 , mColumns( columns )
3290 mButtonGroup->setExclusive( !mParam->allowMultiple() );
3292 QGridLayout *l =
new QGridLayout();
3293 l->setContentsMargins( 0, 0, 0, 0 );
3295 int rows =
static_cast<int>( std::ceil( mParam->options().count() /
static_cast<double>( mColumns ) ) );
3296 for (
int i = 0; i < mParam->options().count(); ++i )
3298 QAbstractButton *button =
nullptr;
3299 if ( mParam->allowMultiple() )
3300 button =
new QCheckBox( mParam->options().at( i ) );
3302 button =
new QRadioButton( mParam->options().at( i ) );
3304 connect( button, &QAbstractButton::toggled,
this, [=] {
3305 if ( !mBlockChangedSignal )
3309 mButtons.insert( i, button );
3311 mButtonGroup->addButton( button, i );
3312 l->addWidget( button, i % rows, i / rows );
3314 l->addItem(
new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, mColumns );
3317 if ( mParam->allowMultiple() )
3319 setContextMenuPolicy( Qt::CustomContextMenu );
3320 connect(
this, &QWidget::customContextMenuRequested,
this, &QgsProcessingEnumCheckboxPanelWidget::showPopupMenu );
3324QVariant QgsProcessingEnumCheckboxPanelWidget::value()
const
3326 if ( mParam->allowMultiple() )
3329 for (
auto it = mButtons.constBegin(); it != mButtons.constEnd(); ++it )
3331 if ( it.value()->isChecked() )
3332 value.append( mParam->usesStaticStrings() ? mParam->options().at( it.key().toInt() ) : it.key() );
3338 if ( mParam->usesStaticStrings() )
3339 return mButtonGroup->checkedId() >= 0 ? mParam->options().at( mButtonGroup->checkedId() ) : QVariant();
3341 return mButtonGroup->checkedId() >= 0 ? mButtonGroup->checkedId() : QVariant();
3345void QgsProcessingEnumCheckboxPanelWidget::setValue(
const QVariant &value )
3347 mBlockChangedSignal =
true;
3348 if ( mParam->allowMultiple() )
3350 QVariantList selected;
3351 if ( value.isValid() )
3352 selected = value.userType() == QMetaType::Type::QVariantList ? value.toList() : QVariantList() << value;
3353 for (
auto it = mButtons.constBegin(); it != mButtons.constEnd(); ++it )
3355 QVariant v = mParam->usesStaticStrings() ? mParam->options().at( it.key().toInt() ) : it.key();
3356 it.value()->setChecked( selected.contains( v ) );
3362 if ( v.userType() == QMetaType::Type::QVariantList )
3363 v = v.toList().value( 0 );
3365 v = mParam->usesStaticStrings() ? mParam->options().indexOf( v.toString() ) : v;
3366 if ( mButtons.contains( v ) )
3367 mButtons.value( v )->setChecked(
true );
3369 mBlockChangedSignal =
false;
3373void QgsProcessingEnumCheckboxPanelWidget::showPopupMenu()
3376 QAction *selectAllAction =
new QAction( tr(
"Select All" ), &popupMenu );
3377 connect( selectAllAction, &QAction::triggered,
this, &QgsProcessingEnumCheckboxPanelWidget::selectAll );
3378 QAction *clearAllAction =
new QAction( tr(
"Clear Selection" ), &popupMenu );
3379 connect( clearAllAction, &QAction::triggered,
this, &QgsProcessingEnumCheckboxPanelWidget::deselectAll );
3380 popupMenu.addAction( selectAllAction );
3381 popupMenu.addAction( clearAllAction );
3382 popupMenu.exec( QCursor::pos() );
3385void QgsProcessingEnumCheckboxPanelWidget::selectAll()
3387 mBlockChangedSignal =
true;
3388 for (
auto it = mButtons.constBegin(); it != mButtons.constEnd(); ++it )
3389 it.value()->setChecked(
true );
3390 mBlockChangedSignal =
false;
3394void QgsProcessingEnumCheckboxPanelWidget::deselectAll()
3396 mBlockChangedSignal =
true;
3397 for (
auto it = mButtons.constBegin(); it != mButtons.constEnd(); ++it )
3398 it.value()->setChecked(
false );
3399 mBlockChangedSignal =
false;
3411 QVBoxLayout *vlayout =
new QVBoxLayout();
3412 vlayout->setContentsMargins( 0, 0, 0, 0 );
3414 mEnumWidget =
new QgsProcessingEnumModelerWidget();
3417 mEnumWidget->setAllowMultiple( enumParam->allowMultiple() );
3418 mEnumWidget->setOptions( enumParam->options() );
3419 mEnumWidget->setDefaultOptions( enumParam->defaultValueForGui() );
3421 vlayout->addWidget( mEnumWidget );
3422 setLayout( vlayout );
3427 auto param = std::make_unique<QgsProcessingParameterEnum>( name, description, mEnumWidget->options(), mEnumWidget->allowMultiple(), mEnumWidget->defaultOptions() );
3429 return param.release();
3438QWidget *QgsProcessingEnumWidgetWrapper::createWidget()
3446 if ( expParam->
metadata().value( QStringLiteral(
"widget_wrapper" ) ).toMap().value( QStringLiteral(
"useCheckBoxes" ),
false ).toBool() )
3448 const int columns = expParam->
metadata().value( QStringLiteral(
"widget_wrapper" ) ).toMap().value( QStringLiteral(
"columns" ), 2 ).toInt();
3449 mCheckboxPanel =
new QgsProcessingEnumCheckboxPanelWidget(
nullptr, expParam, columns );
3450 mCheckboxPanel->setToolTip( parameterDefinition()->toolTip() );
3451 connect( mCheckboxPanel, &QgsProcessingEnumCheckboxPanelWidget::changed,
this, [=] {
3452 emit widgetValueHasChanged(
this );
3454 return mCheckboxPanel;
3463 mPanel =
new QgsProcessingEnumPanelWidget(
nullptr, expParam );
3464 mPanel->setToolTip( parameterDefinition()->toolTip() );
3465 connect( mPanel, &QgsProcessingEnumPanelWidget::changed,
this, [=] {
3466 emit widgetValueHasChanged(
this );
3472 mComboBox =
new QComboBox();
3475 mComboBox->addItem( tr(
"[Not selected]" ), QVariant() );
3476 const QStringList options = expParam->
options();
3477 const QVariantList iconList = expParam->
metadata().value( QStringLiteral(
"widget_wrapper" ) ).toMap().value( QStringLiteral(
"icons" ) ).toList();
3478 for (
int i = 0; i < options.count(); ++i )
3480 const QIcon icon = iconList.value( i ).value<QIcon>();
3483 mComboBox->addItem( icon, options.at( i ), options.at( i ) );
3485 mComboBox->addItem( icon, options.at( i ), i );
3488 mComboBox->setToolTip( parameterDefinition()->toolTip() );
3489 mComboBox->setSizeAdjustPolicy( QComboBox::AdjustToMinimumContentsLengthWithIcon );
3490 connect( mComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, [=](
int ) {
3491 emit widgetValueHasChanged(
this );
3500void QgsProcessingEnumWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
3504 if ( !value.isValid() )
3505 mComboBox->setCurrentIndex( mComboBox->findData( QVariant() ) );
3512 mComboBox->setCurrentIndex( mComboBox->findData( v ) );
3517 mComboBox->setCurrentIndex( mComboBox->findData( v ) );
3521 else if ( mPanel || mCheckboxPanel )
3524 if ( value.isValid() )
3530 opts.reserve( v.size() );
3531 for ( QString i : v )
3537 opts.reserve( v.size() );
3543 mPanel->setValue( opts );
3544 else if ( mCheckboxPanel )
3545 mCheckboxPanel->setValue( opts );
3549QVariant QgsProcessingEnumWidgetWrapper::widgetValue()
const
3552 return mComboBox->currentData();
3554 return mPanel->value();
3555 else if ( mCheckboxPanel )
3556 return mCheckboxPanel->value();
3561QStringList QgsProcessingEnumWidgetWrapper::compatibleParameterTypes()
const
3563 return QStringList()
3569QStringList QgsProcessingEnumWidgetWrapper::compatibleOutputTypes()
const
3571 return QStringList()
3577QString QgsProcessingEnumWidgetWrapper::modelerExpressionFormatString()
const
3579 return tr(
"selected option index (starting from 0), array of indices, or comma separated string of options (e.g. '1,3')" );
3582QString QgsProcessingEnumWidgetWrapper::parameterType()
const
3589 return new QgsProcessingEnumWidgetWrapper( parameter, type );
3594 return new QgsProcessingEnumParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
3606QWidget *QgsProcessingLayoutWidgetWrapper::createWidget()
3615 mComboBox =
new QgsLayoutComboBox(
nullptr, widgetContext().project() ? widgetContext().project()->layoutManager() : nullptr );
3620 mComboBox->setToolTip( parameterDefinition()->toolTip() );
3622 emit widgetValueHasChanged(
this );
3629 mPlainComboBox =
new QComboBox();
3630 mPlainComboBox->setEditable(
true );
3631 mPlainComboBox->setToolTip( tr(
"Name of an existing print layout" ) );
3632 if ( widgetContext().project() )
3636 mPlainComboBox->addItem( layout->name() );
3639 connect( mPlainComboBox, &QComboBox::currentTextChanged,
this, [=](
const QString & ) {
3640 emit widgetValueHasChanged(
this );
3642 return mPlainComboBox;
3648void QgsProcessingLayoutWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
3652 if ( !value.isValid() )
3653 mComboBox->setCurrentLayout(
nullptr );
3657 mComboBox->setCurrentLayout( l );
3659 mComboBox->setCurrentLayout(
nullptr );
3662 else if ( mPlainComboBox )
3665 mPlainComboBox->setCurrentText( v );
3669QVariant QgsProcessingLayoutWidgetWrapper::widgetValue()
const
3674 return l ? l->
name() : QVariant();
3676 else if ( mPlainComboBox )
3677 return mPlainComboBox->currentText().isEmpty() ? QVariant() : mPlainComboBox->currentText();
3685 if ( mPlainComboBox && context.
project() )
3689 mPlainComboBox->addItem( layout->name() );
3693QStringList QgsProcessingLayoutWidgetWrapper::compatibleParameterTypes()
const
3695 return QStringList()
3700QStringList QgsProcessingLayoutWidgetWrapper::compatibleOutputTypes()
const
3702 return QStringList()
3707QString QgsProcessingLayoutWidgetWrapper::modelerExpressionFormatString()
const
3709 return tr(
"string representing the name of an existing print layout" );
3712QString QgsProcessingLayoutWidgetWrapper::parameterType()
const
3719 return new QgsProcessingLayoutWidgetWrapper( parameter, type );
3731 QVBoxLayout *vlayout =
new QVBoxLayout();
3732 vlayout->setContentsMargins( 0, 0, 0, 0 );
3734 vlayout->addWidget(
new QLabel( tr(
"Parent layout" ) ) );
3736 mParentLayoutComboBox =
new QComboBox();
3737 QString initialParent;
3739 initialParent = itemParam->parentLayoutParameterName();
3741 if (
auto *lModel = widgetContext.
model() )
3744 const QMap<QString, QgsProcessingModelParameter> components = lModel->parameterComponents();
3745 for (
auto it = components.constBegin(); it != components.constEnd(); ++it )
3749 mParentLayoutComboBox->addItem( definition->
description(), definition->
name() );
3750 if ( !initialParent.isEmpty() && initialParent == definition->
name() )
3752 mParentLayoutComboBox->setCurrentIndex( mParentLayoutComboBox->count() - 1 );
3758 if ( mParentLayoutComboBox->count() == 0 && !initialParent.isEmpty() )
3761 mParentLayoutComboBox->addItem( initialParent, initialParent );
3762 mParentLayoutComboBox->setCurrentIndex( mParentLayoutComboBox->count() - 1 );
3765 vlayout->addWidget( mParentLayoutComboBox );
3766 setLayout( vlayout );
3770 auto param = std::make_unique<QgsProcessingParameterLayoutItem>( name, description, QVariant(), mParentLayoutComboBox->currentData().toString() );
3772 return param.release();
3781QWidget *QgsProcessingLayoutItemWidgetWrapper::createWidget()
3792 mComboBox->setAllowEmptyItem(
true );
3793 if ( layoutParam->
itemType() >= 0 )
3796 mComboBox->setToolTip( parameterDefinition()->toolTip() );
3798 emit widgetValueHasChanged(
this );
3805 mLineEdit =
new QLineEdit();
3806 mLineEdit->setToolTip( tr(
"UUID or ID of an existing print layout item" ) );
3807 connect( mLineEdit, &QLineEdit::textChanged,
this, [=](
const QString & ) {
3808 emit widgetValueHasChanged(
this );
3816void QgsProcessingLayoutItemWidgetWrapper::postInitialize(
const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
3843void QgsProcessingLayoutItemWidgetWrapper::setLayoutParameterValue(
const QVariant &value )
3849 std::unique_ptr<QgsProcessingContext> tmpContext;
3850 if ( mProcessingContextGenerator )
3851 context = mProcessingContextGenerator->processingContext();
3855 tmpContext = std::make_unique<QgsProcessingContext>();
3856 context = tmpContext.get();
3860 setLayout( layout );
3863void QgsProcessingLayoutItemWidgetWrapper::setLayout(
QgsPrintLayout *layout )
3866 mComboBox->setCurrentLayout( layout );
3869void QgsProcessingLayoutItemWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
3873 if ( !value.isValid() )
3874 mComboBox->setItem(
nullptr );
3878 mComboBox->setItem( item );
3881 else if ( mLineEdit )
3884 mLineEdit->setText( v );
3888QVariant QgsProcessingLayoutItemWidgetWrapper::widgetValue()
const
3893 return i ? i->
uuid() : QVariant();
3895 else if ( mLineEdit )
3896 return mLineEdit->text().isEmpty() ? QVariant() : mLineEdit->text();
3901QStringList QgsProcessingLayoutItemWidgetWrapper::compatibleParameterTypes()
const
3903 return QStringList()
3908QStringList QgsProcessingLayoutItemWidgetWrapper::compatibleOutputTypes()
const
3910 return QStringList()
3915QString QgsProcessingLayoutItemWidgetWrapper::modelerExpressionFormatString()
const
3917 return tr(
"string representing the UUID or ID of an existing print layout item" );
3920QString QgsProcessingLayoutItemWidgetWrapper::parameterType()
const
3927 return new QgsProcessingLayoutItemWidgetWrapper( parameter, type );
3932 return new QgsProcessingLayoutItemParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
3939QgsProcessingPointMapTool::QgsProcessingPointMapTool(
QgsMapCanvas *canvas )
3946QgsProcessingPointMapTool::~QgsProcessingPointMapTool() =
default;
3948void QgsProcessingPointMapTool::deactivate()
3962 if ( e->button() == Qt::LeftButton )
3965 emit clicked( point );
3970void QgsProcessingPointMapTool::keyPressEvent( QKeyEvent *e )
3972 if ( e->key() == Qt::Key_Escape )
3985QgsProcessingPointPanel::QgsProcessingPointPanel( QWidget *parent )
3988 QHBoxLayout *l =
new QHBoxLayout();
3989 l->setContentsMargins( 0, 0, 0, 0 );
3991 mLineEdit->setShowClearButton(
false );
3992 l->addWidget( mLineEdit, 1 );
3993 mButton =
new QToolButton();
3994 mButton->setText( QString( QChar( 0x2026 ) ) );
3995 l->addWidget( mButton );
3998 connect( mLineEdit, &QLineEdit::textChanged,
this, &QgsProcessingPointPanel::changed );
3999 connect( mLineEdit, &QLineEdit::textChanged,
this, &QgsProcessingPointPanel::textChanged );
4000 connect( mButton, &QToolButton::clicked,
this, &QgsProcessingPointPanel::selectOnCanvas );
4001 mButton->setVisible(
false );
4004void QgsProcessingPointPanel::setMapCanvas(
QgsMapCanvas *canvas )
4007 if ( mAllowSelectOnCanvas )
4009 mButton->setVisible(
true );
4012 mTool = std::make_unique<QgsProcessingPointMapTool>( mCanvas );
4013 connect( mTool.get(), &QgsProcessingPointMapTool::clicked,
this, &QgsProcessingPointPanel::updatePoint );
4014 connect( mTool.get(), &QgsProcessingPointMapTool::complete,
this, &QgsProcessingPointPanel::pointPicked );
4018void QgsProcessingPointPanel::setAllowNull(
bool allowNull )
4020 mLineEdit->setShowClearButton( allowNull );
4023void QgsProcessingPointPanel::setShowPointOnCanvas(
bool show )
4025 if ( mShowPointOnCanvas == show )
4028 mShowPointOnCanvas = show;
4029 if ( mShowPointOnCanvas )
4035 mMapPointRubberBand.reset();
4039void QgsProcessingPointPanel::setAllowSelectOnCanvas(
bool allow )
4041 mAllowSelectOnCanvas = allow;
4042 mButton->setVisible( mAllowSelectOnCanvas &&
static_cast<bool>( mTool ) );
4045QVariant QgsProcessingPointPanel::value()
const
4047 return mLineEdit->showClearButton() && mLineEdit->text().trimmed().isEmpty() ? QVariant() : QVariant( mLineEdit->text() );
4050void QgsProcessingPointPanel::clear()
4058 QString newText = QStringLiteral(
"%1,%2" )
4059 .arg( QString::number( point.
x(),
'f' ), QString::number( point.
y(),
'f' ) );
4062 if ( mCrs.isValid() )
4064 newText += QStringLiteral(
" [%1]" ).arg( mCrs.authid() );
4066 mLineEdit->setText( newText );
4070void QgsProcessingPointPanel::showEvent( QShowEvent * )
4075 if ( QWidget *parentWindow = window() )
4077 setAllowSelectOnCanvas( !parentWindow->isModal() );
4083void QgsProcessingPointPanel::selectOnCanvas()
4088 mPrevTool = mCanvas->mapTool();
4089 mCanvas->setMapTool( mTool.get() );
4091 emit toggleDialogVisibility(
false );
4094void QgsProcessingPointPanel::updatePoint(
const QgsPointXY &point )
4096 setValue( point, mCanvas->mapSettings().destinationCrs() );
4099void QgsProcessingPointPanel::pointPicked()
4104 mCanvas->setMapTool( mPrevTool );
4106 emit toggleDialogVisibility(
true );
4109void QgsProcessingPointPanel::textChanged(
const QString &text )
4111 const thread_local QRegularExpression rx( QStringLiteral(
"^\\s*\\(?\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*\\)?\\s*$" ) );
4113 const QRegularExpressionMatch match = rx.match( text );
4114 if ( match.hasMatch() )
4117 const double x = match.captured( 1 ).toDouble( &xOk );
4119 const double y = match.captured( 2 ).toDouble( &yOk );
4126 if ( pointCrs.isValid() )
4144void QgsProcessingPointPanel::updateRubberBand()
4146 if ( !mShowPointOnCanvas || !mCanvas )
4149 if ( mPoint.isEmpty() )
4151 mMapPointRubberBand.reset();
4155 if ( !mMapPointRubberBand )
4158 mMapPointRubberBand->setZValue( 1000 );
4161 const double scaleFactor = mCanvas->fontMetrics().xHeight() * .4;
4162 mMapPointRubberBand->setWidth( scaleFactor );
4163 mMapPointRubberBand->setIconSize( scaleFactor * 5 );
4165 mMapPointRubberBand->setSecondaryStrokeColor( QColor( 255, 255, 255, 100 ) );
4166 mMapPointRubberBand->setColor( QColor( 200, 0, 200 ) );
4180 QVBoxLayout *vlayout =
new QVBoxLayout();
4181 vlayout->setContentsMargins( 0, 0, 0, 0 );
4183 vlayout->addWidget(
new QLabel( tr(
"Default value" ) ) );
4185 mDefaultLineEdit =
new QLineEdit();
4186 mDefaultLineEdit->setToolTip( tr(
"Point as 'x,y'" ) );
4187 mDefaultLineEdit->setPlaceholderText( tr(
"Point as 'x,y'" ) );
4191 mDefaultLineEdit->setText( QStringLiteral(
"%1,%2" ).arg( QString::number( point.
x(),
'f' ), QString::number( point.
y(),
'f' ) ) );
4194 vlayout->addWidget( mDefaultLineEdit );
4195 setLayout( vlayout );
4200 auto param = std::make_unique<QgsProcessingParameterPoint>( name, description, mDefaultLineEdit->text() );
4202 return param.release();
4210QWidget *QgsProcessingPointWidgetWrapper::createWidget()
4218 mPanel =
new QgsProcessingPointPanel(
nullptr );
4219 if ( widgetContext().mapCanvas() )
4220 mPanel->setMapCanvas( widgetContext().mapCanvas() );
4223 mPanel->setAllowNull(
true );
4226 mPanel->setShowPointOnCanvas(
true );
4228 mPanel->setToolTip( parameterDefinition()->toolTip() );
4230 connect( mPanel, &QgsProcessingPointPanel::changed,
this, [=] {
4231 emit widgetValueHasChanged(
this );
4235 setDialog( mDialog );
4241 mLineEdit =
new QLineEdit();
4242 mLineEdit->setToolTip( tr(
"Point as 'x,y'" ) );
4243 connect( mLineEdit, &QLineEdit::textChanged,
this, [=](
const QString & ) {
4244 emit widgetValueHasChanged(
this );
4256 mPanel->setMapCanvas( context.
mapCanvas() );
4259void QgsProcessingPointWidgetWrapper::setDialog( QDialog *dialog )
4264 connect( mPanel, &QgsProcessingPointPanel::toggleDialogVisibility, mDialog, [=](
bool visible ) {
4266 mDialog->showMinimized();
4269 mDialog->showNormal();
4271 mDialog->activateWindow();
4278void QgsProcessingPointWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
4282 if ( !value.isValid() || ( value.userType() == QMetaType::Type::QString && value.toString().isEmpty() ) )
4288 mPanel->setValue( p,
crs );
4291 else if ( mLineEdit )
4294 mLineEdit->setText( v );
4298QVariant QgsProcessingPointWidgetWrapper::widgetValue()
const
4302 return mPanel->value();
4304 else if ( mLineEdit )
4305 return mLineEdit->text().isEmpty() ? QVariant() : mLineEdit->text();
4310QStringList QgsProcessingPointWidgetWrapper::compatibleParameterTypes()
const
4312 return QStringList()
4317QStringList QgsProcessingPointWidgetWrapper::compatibleOutputTypes()
const
4319 return QStringList()
4324QString QgsProcessingPointWidgetWrapper::modelerExpressionFormatString()
const
4326 return tr(
"string of the format 'x,y' or a geometry value (centroid is used)" );
4329QString QgsProcessingPointWidgetWrapper::parameterType()
const
4336 return new QgsProcessingPointWidgetWrapper( parameter, type );
4341 return new QgsProcessingPointParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
4353 QVBoxLayout *vlayout =
new QVBoxLayout();
4354 vlayout->setContentsMargins( 0, 0, 0, 0 );
4356 vlayout->addWidget(
new QLabel( tr(
"Default value" ) ) );
4368 vlayout->addWidget( mGeometryWidget );
4369 setLayout( vlayout );
4375 auto param = std::make_unique<QgsProcessingParameterGeometry>( name, description, geometry.
isEmpty() ? QVariant() : geometry.asWkt() );
4377 return param.release();
4385QWidget *QgsProcessingGeometryWidgetWrapper::createWidget()
4394 mGeometryWidget->setToolTip( parameterDefinition()->toolTip() );
4396 emit widgetValueHasChanged(
this );
4398 return mGeometryWidget;
4404void QgsProcessingGeometryWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
4406 if ( mGeometryWidget )
4415 mGeometryWidget->clearGeometry();
4420QVariant QgsProcessingGeometryWidgetWrapper::widgetValue()
const
4422 if ( mGeometryWidget )
4425 return geometry.
isEmpty() ? QVariant() : geometry.asWkt();
4433QStringList QgsProcessingGeometryWidgetWrapper::compatibleParameterTypes()
const
4435 return QStringList()
4442QStringList QgsProcessingGeometryWidgetWrapper::compatibleOutputTypes()
const
4444 return QStringList()
4449QString QgsProcessingGeometryWidgetWrapper::modelerExpressionFormatString()
const
4451 return tr(
"string in the Well-Known-Text format or a geometry value" );
4454QString QgsProcessingGeometryWidgetWrapper::parameterType()
const
4461 return new QgsProcessingGeometryWidgetWrapper( parameter, type );
4466 return new QgsProcessingGeometryParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
4478 QVBoxLayout *vlayout =
new QVBoxLayout();
4479 vlayout->setContentsMargins( 0, 0, 0, 0 );
4481 vlayout->addWidget(
new QLabel( tr(
"Default value" ) ) );
4484 mDefaultColorButton->setShowNull(
true );
4485 mAllowOpacity =
new QCheckBox( tr(
"Allow opacity control" ) );
4491 mDefaultColorButton->setToNull();
4493 mDefaultColorButton->setColor(
c );
4494 mAllowOpacity->setChecked( colorParam->opacityEnabled() );
4498 mDefaultColorButton->setToNull();
4499 mAllowOpacity->setChecked(
true );
4502 vlayout->addWidget( mDefaultColorButton );
4503 vlayout->addWidget( mAllowOpacity );
4504 setLayout( vlayout );
4509 auto param = std::make_unique<QgsProcessingParameterColor>( name, description, mDefaultColorButton->color(), mAllowOpacity->isChecked() );
4511 return param.release();
4519QWidget *QgsProcessingColorWidgetWrapper::createWidget()
4529 mColorButton->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
4532 mColorButton->setShowNull(
true );
4535 mColorButton->setToolTip( parameterDefinition()->toolTip() );
4536 mColorButton->setColorDialogTitle( parameterDefinition()->description() );
4543 emit widgetValueHasChanged(
this );
4546 return mColorButton;
4552void QgsProcessingColorWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
4556 if ( !value.isValid() || ( value.userType() == QMetaType::Type::QString && value.toString().isEmpty() )
4557 || ( value.userType() == QMetaType::Type::QColor && !value.value<QColor>().isValid() ) )
4558 mColorButton->setToNull();
4562 if ( !
c.isValid() && mColorButton->showNull() )
4563 mColorButton->setToNull();
4565 mColorButton->setColor(
c );
4570QVariant QgsProcessingColorWidgetWrapper::widgetValue()
const
4573 return mColorButton->isNull() ? QVariant() : mColorButton->color();
4578QStringList QgsProcessingColorWidgetWrapper::compatibleParameterTypes()
const
4580 return QStringList()
4585QStringList QgsProcessingColorWidgetWrapper::compatibleOutputTypes()
const
4587 return QStringList()
4592QString QgsProcessingColorWidgetWrapper::modelerExpressionFormatString()
const
4594 return tr(
"color style string, e.g. #ff0000 or 255,0,0" );
4597QString QgsProcessingColorWidgetWrapper::parameterType()
const
4604 return new QgsProcessingColorWidgetWrapper( parameter, type );
4609 return new QgsProcessingColorParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
4620 QVBoxLayout *vlayout =
new QVBoxLayout();
4621 vlayout->setContentsMargins( 0, 0, 0, 0 );
4623 vlayout->addWidget(
new QLabel( tr(
"Default value" ) ) );
4625 mDefaultLineEdit =
new QLineEdit();
4628 vlayout->addWidget( mDefaultLineEdit );
4630 mSourceParamComboBox =
new QComboBox();
4631 mDestParamComboBox =
new QComboBox();
4632 QString initialSource;
4633 QString initialDest;
4638 initialSource = itemParam->sourceCrsParameterName();
4639 initialDest = itemParam->destinationCrsParameterName();
4644 mSourceParamComboBox->addItem( QString(), QString() );
4645 mDestParamComboBox->addItem( QString(), QString() );
4646 if (
auto *lModel = widgetContext.
model() )
4649 const QMap<QString, QgsProcessingModelParameter> components = lModel->parameterComponents();
4650 for (
auto it = components.constBegin(); it != components.constEnd(); ++it )
4652 if ( definition && it->parameterName() == definition->
name() )
4656 mSourceParamComboBox->addItem( it->parameterName(), it->parameterName() );
4657 mDestParamComboBox->addItem( it->parameterName(), it->parameterName() );
4658 if ( !initialSource.isEmpty() && initialSource == it->parameterName() )
4660 mSourceParamComboBox->setCurrentIndex( mSourceParamComboBox->count() - 1 );
4662 if ( !initialDest.isEmpty() && initialDest == it->parameterName() )
4664 mDestParamComboBox->setCurrentIndex( mDestParamComboBox->count() - 1 );
4669 if ( mSourceParamComboBox->count() == 1 && !initialSource.isEmpty() )
4672 mSourceParamComboBox->addItem( initialSource, initialSource );
4673 mSourceParamComboBox->setCurrentIndex( mSourceParamComboBox->count() - 1 );
4675 if ( mDestParamComboBox->count() == 1 && !initialDest.isEmpty() )
4678 mDestParamComboBox->addItem( initialDest, initialDest );
4679 mDestParamComboBox->setCurrentIndex( mDestParamComboBox->count() - 1 );
4682 vlayout->addWidget(
new QLabel( tr(
"Source CRS parameter" ) ) );
4683 vlayout->addWidget( mSourceParamComboBox );
4684 vlayout->addWidget(
new QLabel( tr(
"Destination CRS parameter" ) ) );
4685 vlayout->addWidget( mDestParamComboBox );
4689 mStaticSourceWidget->setCrs( sourceCrs );
4692 mStaticDestWidget->setCrs( destCrs );
4694 vlayout->addWidget(
new QLabel( tr(
"Static source CRS" ) ) );
4695 vlayout->addWidget( mStaticSourceWidget );
4696 vlayout->addWidget(
new QLabel( tr(
"Static destination CRS" ) ) );
4697 vlayout->addWidget( mStaticDestWidget );
4699 setLayout( vlayout );
4704 auto param = std::make_unique<QgsProcessingParameterCoordinateOperation>( name, description, mDefaultLineEdit->text(), mSourceParamComboBox->currentText(), mDestParamComboBox->currentText(), mStaticSourceWidget->crs().isValid() ? QVariant::fromValue( mStaticSourceWidget->crs() ) : QVariant(), mStaticDestWidget->
crs().isValid() ? QVariant::fromValue( mStaticDestWidget->
crs() ) : QVariant() );
4706 return param.release();
4714QWidget *QgsProcessingCoordinateOperationWidgetWrapper::createWidget()
4725 mOperationWidget->setShowMakeDefault(
false );
4726 mOperationWidget->setShowFallbackOption(
false );
4727 mOperationWidget->setToolTip( parameterDefinition()->toolTip() );
4728 mOperationWidget->setSourceCrs( mSourceCrs );
4729 mOperationWidget->setDestinationCrs( mDestCrs );
4730 mOperationWidget->setMapCanvas( mCanvas );
4735 mOperationWidget->setSelectedOperation( deets );
4739 emit widgetValueHasChanged(
this );
4742 return mOperationWidget;
4748 mLineEdit =
new QLineEdit();
4749 QHBoxLayout *layout =
new QHBoxLayout();
4750 layout->addWidget( mLineEdit, 1 );
4751 connect( mLineEdit, &QLineEdit::textChanged,
this, [=] {
4752 emit widgetValueHasChanged(
this );
4755 QToolButton *button =
new QToolButton();
4756 button->setText( QString( QChar( 0x2026 ) ) );
4757 connect( button, &QToolButton::clicked,
this, [=] {
4758 QgsDatumTransformDialog dlg( mSourceCrs, mDestCrs,
false,
false,
false, qMakePair( -1, -1 ), button, Qt::WindowFlags(), mLineEdit->text(), mCanvas );
4761 mLineEdit->setText( dlg.selectedDatumTransform().proj );
4762 emit widgetValueHasChanged(
this );
4765 layout->addWidget( button );
4767 QWidget *w =
new QWidget();
4768 layout->setContentsMargins( 0, 0, 0, 0 );
4769 w->setLayout( layout );
4776void QgsProcessingCoordinateOperationWidgetWrapper::postInitialize(
const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
4812 if ( mOperationWidget )
4813 mOperationWidget->setMapCanvas( context.
mapCanvas() );
4816void QgsProcessingCoordinateOperationWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext & )
4818 if ( mOperationWidget )
4820 if ( !value.isValid() || ( value.userType() == QMetaType::Type::QString ) )
4823 deets.
proj = value.toString();
4824 mOperationWidget->setSelectedOperation( deets );
4829 if ( !value.isValid() || ( value.userType() == QMetaType::Type::QString ) )
4831 mLineEdit->setText( value.toString() );
4836QVariant QgsProcessingCoordinateOperationWidgetWrapper::widgetValue()
const
4838 if ( mOperationWidget )
4839 return mOperationWidget->selectedOperation().proj;
4840 else if ( mLineEdit )
4841 return mLineEdit->text();
4846QStringList QgsProcessingCoordinateOperationWidgetWrapper::compatibleParameterTypes()
const
4848 return QStringList()
4853QStringList QgsProcessingCoordinateOperationWidgetWrapper::compatibleOutputTypes()
const
4855 return QStringList()
4860QString QgsProcessingCoordinateOperationWidgetWrapper::modelerExpressionFormatString()
const
4862 return tr(
"Proj coordinate operation string, e.g. '+proj=pipeline +step +inv...'" );
4865void QgsProcessingCoordinateOperationWidgetWrapper::setSourceCrsParameterValue(
const QVariant &value )
4868 std::unique_ptr<QgsProcessingContext> tmpContext;
4869 if ( mProcessingContextGenerator )
4870 context = mProcessingContextGenerator->processingContext();
4874 tmpContext = std::make_unique<QgsProcessingContext>();
4875 context = tmpContext.get();
4879 if ( mOperationWidget )
4881 mOperationWidget->setSourceCrs( mSourceCrs );
4882 mOperationWidget->setSelectedOperationUsingContext( context->
transformContext() );
4886void QgsProcessingCoordinateOperationWidgetWrapper::setDestinationCrsParameterValue(
const QVariant &value )
4889 std::unique_ptr<QgsProcessingContext> tmpContext;
4890 if ( mProcessingContextGenerator )
4891 context = mProcessingContextGenerator->processingContext();
4895 tmpContext = std::make_unique<QgsProcessingContext>();
4896 context = tmpContext.get();
4900 if ( mOperationWidget )
4902 mOperationWidget->setDestinationCrs( mDestCrs );
4903 mOperationWidget->setSelectedOperationUsingContext( context->
transformContext() );
4907QString QgsProcessingCoordinateOperationWidgetWrapper::parameterType()
const
4914 return new QgsProcessingCoordinateOperationWidgetWrapper( parameter, type );
4919 return new QgsProcessingCoordinateOperationParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
4931 QHBoxLayout *hl =
new QHBoxLayout();
4932 hl->setContentsMargins( 0, 0, 0, 0 );
4934 mLineEdit =
new QLineEdit();
4935 mLineEdit->setEnabled(
false );
4936 hl->addWidget( mLineEdit, 1 );
4938 mToolButton =
new QToolButton();
4939 mToolButton->setText( QString( QChar( 0x2026 ) ) );
4940 hl->addWidget( mToolButton );
4946 mLineEdit->setText( tr(
"%n field(s) selected",
nullptr, 0 ) );
4949 connect( mToolButton, &QToolButton::clicked,
this, &QgsProcessingFieldPanelWidget::showDialog );
4952void QgsProcessingFieldPanelWidget::setFields(
const QgsFields &fields )
4957void QgsProcessingFieldPanelWidget::setValue(
const QVariant &value )
4959 if ( value.isValid() )
4960 mValue = value.userType() == QMetaType::Type::QVariantList ? value.
toList() : QVariantList() << value;
4964 updateSummaryText();
4968void QgsProcessingFieldPanelWidget::showDialog()
4970 QVariantList availableOptions;
4971 availableOptions.reserve( mFields.size() );
4972 for (
const QgsField &field : std::as_const( mFields ) )
4974 availableOptions << field.name();
4980 QgsProcessingMultipleSelectionPanelWidget *widget =
new QgsProcessingMultipleSelectionPanelWidget( availableOptions, mValue );
4981 widget->setPanelTitle( mParam->description() );
4983 widget->setValueFormatter( [](
const QVariant &v ) -> QString {
4984 return v.toString();
4987 connect( widget, &QgsProcessingMultipleSelectionPanelWidget::selectionChanged,
this, [=]() {
4988 setValue( widget->selectedOptions() );
4995 QgsProcessingMultipleSelectionDialog dlg( availableOptions, mValue,
this, Qt::WindowFlags() );
4997 dlg.setValueFormatter( [](
const QVariant &v ) -> QString {
4998 return v.toString();
5002 setValue( dlg.selectedOptions() );
5007void QgsProcessingFieldPanelWidget::updateSummaryText()
5012 if ( mValue.empty() )
5014 mLineEdit->setText( tr(
"%n field(s) selected",
nullptr, 0 ) );
5019 values.reserve( mValue.size() );
5020 for (
const QVariant &val : std::as_const( mValue ) )
5022 values << val.toString();
5025 const QString concatenated = values.join( tr(
"," ) );
5026 if ( concatenated.length() < 100 )
5027 mLineEdit->setText( concatenated );
5029 mLineEdit->setText( tr(
"%n field(s) selected",
nullptr, mValue.count() ) );
5041 QVBoxLayout *vlayout =
new QVBoxLayout();
5042 vlayout->setContentsMargins( 0, 0, 0, 0 );
5044 vlayout->addWidget(
new QLabel( tr(
"Parent layer" ) ) );
5045 mParentLayerComboBox =
new QComboBox();
5047 QString initialParent;
5049 initialParent = fieldParam->parentLayerParameterName();
5051 if (
auto *lModel = widgetContext.
model() )
5054 const QMap<QString, QgsProcessingModelParameter> components = lModel->parameterComponents();
5055 for (
auto it = components.constBegin(); it != components.constEnd(); ++it )
5059 mParentLayerComboBox->addItem( definition->
description(), definition->
name() );
5060 if ( !initialParent.isEmpty() && initialParent == definition->
name() )
5062 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
5067 mParentLayerComboBox->addItem( definition->
description(), definition->
name() );
5068 if ( !initialParent.isEmpty() && initialParent == definition->
name() )
5070 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
5077 mParentLayerComboBox->addItem( definition->
description(), definition->
name() );
5078 if ( !initialParent.isEmpty() && initialParent == definition->
name() )
5080 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
5087 if ( mParentLayerComboBox->count() == 0 && !initialParent.isEmpty() )
5090 mParentLayerComboBox->addItem( initialParent, initialParent );
5091 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
5094 vlayout->addWidget( mParentLayerComboBox );
5096 vlayout->addWidget(
new QLabel( tr(
"Allowed data type" ) ) );
5097 mDataTypeComboBox =
new QComboBox();
5105 mDataTypeComboBox->setCurrentIndex( mDataTypeComboBox->findData(
static_cast<int>( fieldParam->dataType() ) ) );
5107 vlayout->addWidget( mDataTypeComboBox );
5109 mAllowMultipleCheckBox =
new QCheckBox( tr(
"Accept multiple fields" ) );
5111 mAllowMultipleCheckBox->setChecked( fieldParam->allowMultiple() );
5113 vlayout->addWidget( mAllowMultipleCheckBox );
5115 mDefaultToAllCheckBox =
new QCheckBox( tr(
"Select all fields by default" ) );
5116 mDefaultToAllCheckBox->setEnabled( mAllowMultipleCheckBox->isChecked() );
5118 mDefaultToAllCheckBox->setChecked( fieldParam->defaultToAllFields() );
5120 vlayout->addWidget( mDefaultToAllCheckBox );
5122 connect( mAllowMultipleCheckBox, &QCheckBox::stateChanged,
this, [=] {
5123 mDefaultToAllCheckBox->setEnabled( mAllowMultipleCheckBox->isChecked() );
5126 vlayout->addWidget(
new QLabel( tr(
"Default value" ) ) );
5128 mDefaultLineEdit =
new QLineEdit();
5129 mDefaultLineEdit->setToolTip( tr(
"Default field name, or ; separated list of field names for multiple field parameters" ) );
5133 mDefaultLineEdit->setText( fields.join(
';' ) );
5135 vlayout->addWidget( mDefaultLineEdit );
5137 setLayout( vlayout );
5144 QVariant defaultValue;
5145 if ( !mDefaultLineEdit->text().trimmed().isEmpty() )
5147 defaultValue = mDefaultLineEdit->text();
5149 auto param = std::make_unique<QgsProcessingParameterField>( name, description, defaultValue, mParentLayerComboBox->currentData().toString(), dataType, mAllowMultipleCheckBox->isChecked(),
false, mDefaultToAllCheckBox->isChecked() );
5151 return param.release();
5159QWidget *QgsProcessingFieldWidgetWrapper::createWidget()
5169 mPanel =
new QgsProcessingFieldPanelWidget(
nullptr, fieldParam );
5170 mPanel->setToolTip( parameterDefinition()->toolTip() );
5171 connect( mPanel, &QgsProcessingFieldPanelWidget::changed,
this, [=] {
5172 emit widgetValueHasChanged(
this );
5192 mComboBox->setToolTip( parameterDefinition()->toolTip() );
5194 emit widgetValueHasChanged(
this );
5202 mLineEdit =
new QLineEdit();
5203 mLineEdit->setToolTip( QObject::tr(
"Name of field (separate field names with ; for multiple field parameters)" ) );
5204 connect( mLineEdit, &QLineEdit::textChanged,
this, [=] {
5205 emit widgetValueHasChanged(
this );
5213void QgsProcessingFieldWidgetWrapper::postInitialize(
const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
5225 setParentLayerWrapperValue( wrapper );
5227 setParentLayerWrapperValue( wrapper );
5244 std::unique_ptr<QgsProcessingContext> tmpContext;
5245 if ( mProcessingContextGenerator )
5246 context = mProcessingContextGenerator->processingContext();
5250 tmpContext = std::make_unique<QgsProcessingContext>();
5251 context = tmpContext.get();
5256 if ( value.userType() == qMetaTypeId<QgsProcessingFeatureSourceDefinition>() )
5266 bool valueSet =
false;
5270 if ( layers.count() > 1 )
5272 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layers.at( 0 ) );
5274 const QList<QgsMapLayer *> remainingLayers = layers.mid( 1 );
5280 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
5281 if ( !vlayer || !vlayer->
isValid() )
5287 for (
int fieldIdx = fields.
count() - 1; fieldIdx >= 0; fieldIdx-- )
5290 fields.
remove( fieldIdx );
5295 mComboBox->setFields( fields );
5297 mPanel->setFields( filterFields( fields ) );
5303 if ( !valueSet && !layers.isEmpty() && layers.at( 0 )->isValid() )
5305 QgsVectorLayer *layer = qobject_cast<QgsVectorLayer *>( layers.at( 0 ) );
5309 std::unique_ptr<QgsMapLayer> ownedLayer( context->
takeResultLayer( layer->
id() ) );
5312 mParentLayer.reset( qobject_cast<QgsVectorLayer *>( ownedLayer.release() ) );
5313 layer = mParentLayer.get();
5321 mComboBox->setLayer( layer );
5323 mPanel->setFields( filterFields( layer->
fields() ) );
5333 const QgsFields fields = source->fields();
5335 mComboBox->setFields( fields );
5337 mPanel->setFields( filterFields( fields ) );
5346 mComboBox->setLayer(
nullptr );
5350 if ( value.isValid() && widgetContext().messageBar() )
5362 val.reserve( mPanel->fields().size() );
5363 for (
const QgsField &field : mPanel->fields() )
5364 val << field.name();
5365 setWidgetValue( val, *context );
5368 setWidgetValue( parameterDefinition()->defaultValueForGui(), *context );
5371void QgsProcessingFieldWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
5375 if ( !value.isValid() )
5376 mComboBox->setField( QString() );
5380 mComboBox->setField( v );
5386 if ( value.isValid() )
5389 opts.reserve( v.size() );
5390 for (
const QString &i : v )
5394 mPanel->setValue( opts );
5396 else if ( mLineEdit )
5402 mLineEdit->setText( v.join(
';' ) );
5411QVariant QgsProcessingFieldWidgetWrapper::widgetValue()
const
5414 return mComboBox->currentField();
5416 return mPanel->value();
5417 else if ( mLineEdit )
5422 return mLineEdit->text().split(
';' );
5425 return mLineEdit->text();
5431QStringList QgsProcessingFieldWidgetWrapper::compatibleParameterTypes()
const
5433 return QStringList()
5438QStringList QgsProcessingFieldWidgetWrapper::compatibleOutputTypes()
const
5440 return QStringList()
5445QString QgsProcessingFieldWidgetWrapper::modelerExpressionFormatString()
const
5447 return tr(
"selected field names as an array of names, or semicolon separated string of options (e.g. 'fid;place_name')" );
5450const QgsVectorLayer *QgsProcessingFieldWidgetWrapper::linkedVectorLayer()
const
5452 if ( mComboBox && mComboBox->layer() )
5453 return mComboBox->layer();
5458QgsFields QgsProcessingFieldWidgetWrapper::filterFields(
const QgsFields &fields )
const
5471 if ( f.isNumeric() )
5476 if ( f.type() == QMetaType::Type::QString )
5481 if ( f.type() == QMetaType::Type::QDate || f.type() == QMetaType::Type::QTime || f.type() == QMetaType::Type::QDateTime )
5486 if ( f.type() == QMetaType::Type::QByteArray )
5491 if ( f.type() == QMetaType::Type::Bool )
5500QString QgsProcessingFieldWidgetWrapper::parameterType()
const
5507 return new QgsProcessingFieldWidgetWrapper( parameter, type );
5512 return new QgsProcessingFieldParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
5523 QVBoxLayout *vlayout =
new QVBoxLayout();
5524 vlayout->setContentsMargins( 0, 0, 0, 0 );
5526 vlayout->addWidget(
new QLabel( tr(
"Default value" ) ) );
5528 mDefaultComboBox =
new QComboBox();
5529 mDefaultComboBox->addItem( QString(), QVariant( -1 ) );
5532 for (
const QString &theme : mapThemes )
5536 mDefaultComboBox->setEditable(
true );
5540 if ( themeParam->defaultValueForGui().isValid() )
5543 mDefaultComboBox->setCurrentIndex( mDefaultComboBox->findData( -1 ) );
5546 mDefaultComboBox->setCurrentIndex( mDefaultComboBox->findData( -1 ) );
5548 vlayout->addWidget( mDefaultComboBox );
5550 setLayout( vlayout );
5555 QVariant defaultVal;
5556 if ( mDefaultComboBox->currentText().isEmpty() )
5557 defaultVal = QVariant();
5559 defaultVal = mDefaultComboBox->currentText();
5560 auto param = std::make_unique<QgsProcessingParameterMapTheme>( name, description, defaultVal );
5562 return param.release();
5571QWidget *QgsProcessingMapThemeWidgetWrapper::createWidget()
5575 mComboBox =
new QComboBox();
5578 mComboBox->addItem( tr(
"[Not selected]" ), QVariant( -1 ) );
5581 for (
const QString &theme : mapThemes )
5593 mComboBox->setEditable(
true );
5597 mComboBox->setToolTip( parameterDefinition()->toolTip() );
5598 connect( mComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, [=](
int ) {
5599 emit widgetValueHasChanged(
this );
5605void QgsProcessingMapThemeWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
5609 if ( !value.isValid() )
5610 mComboBox->setCurrentIndex( mComboBox->findData( QVariant( -1 ) ) );
5613 if ( mComboBox->isEditable() && mComboBox->findData( v ) == -1 )
5615 const QString prev = mComboBox->currentText();
5616 mComboBox->setCurrentText( v );
5618 emit widgetValueHasChanged(
this );
5621 mComboBox->setCurrentIndex( mComboBox->findData( v ) );
5625QVariant QgsProcessingMapThemeWidgetWrapper::widgetValue()
const
5628 return mComboBox->currentData().toInt() == -1 ? QVariant() : !mComboBox->currentData().isValid() && mComboBox->isEditable() ? mComboBox->currentText().isEmpty() ? QVariant() : QVariant( mComboBox->currentText() )
5629 : mComboBox->currentData();
5634QStringList QgsProcessingMapThemeWidgetWrapper::compatibleParameterTypes()
const
5636 return QStringList()
5641QStringList QgsProcessingMapThemeWidgetWrapper::compatibleOutputTypes()
const
5643 return QStringList()
5648QString QgsProcessingMapThemeWidgetWrapper::modelerExpressionFormatString()
const
5650 return tr(
"map theme as a string value (e.g. 'base maps')" );
5653QString QgsProcessingMapThemeWidgetWrapper::parameterType()
const
5660 return new QgsProcessingMapThemeWidgetWrapper( parameter, type );
5665 return new QgsProcessingMapThemeParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
5677 QVBoxLayout *vlayout =
new QVBoxLayout();
5678 vlayout->setContentsMargins( 0, 0, 0, 0 );
5680 vlayout->addWidget(
new QLabel( tr(
"Type" ) ) );
5682 mTypeComboBox =
new QComboBox();
5687 mTypeComboBox->setCurrentIndex( mTypeComboBox->findData(
static_cast<int>( datetimeParam->dataType() ) ) );
5689 mTypeComboBox->setCurrentIndex( 0 );
5690 vlayout->addWidget( mTypeComboBox );
5692 setLayout( vlayout );
5697 auto param = std::make_unique<QgsProcessingParameterDateTime>( name, description );
5700 return param.release();
5709QWidget *QgsProcessingDateTimeWidgetWrapper::createWidget()
5714 switch ( dateTimeParam->
dataType() )
5718 widget = mDateTimeEdit;
5741 widget->setToolTip( parameterDefinition()->toolTip() );
5743 if ( mDateTimeEdit )
5746 emit widgetValueHasChanged(
this );
5749 else if ( mDateEdit )
5752 emit widgetValueHasChanged(
this );
5755 else if ( mTimeEdit )
5758 emit widgetValueHasChanged(
this );
5767 return new QgsProcessingDateTimeParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
5770void QgsProcessingDateTimeWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
5772 if ( mDateTimeEdit )
5776 else if ( mDateEdit )