QGIS API Documentation  3.20.0-Odense (decaadbb31)
qgsprocessingparameters.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsprocessingparameters.cpp
3  ---------------------------
4  begin : April 2017
5  copyright : (C) 2017 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
19 #include "qgsprocessingprovider.h"
20 #include "qgsprocessingcontext.h"
21 #include "qgsprocessingutils.h"
22 #include "qgsprocessingalgorithm.h"
24 #include "qgsprocessingoutputs.h"
25 #include "qgssettings.h"
26 #include "qgsvectorfilewriter.h"
27 #include "qgsreferencedgeometry.h"
28 #include "qgsprocessingregistry.h"
30 #include "qgsrasterfilewriter.h"
31 #include "qgsvectorlayer.h"
32 #include "qgsmeshlayer.h"
33 #include "qgsapplication.h"
34 #include "qgslayoutmanager.h"
35 #include "qgsprintlayout.h"
36 #include "qgssymbollayerutils.h"
37 #include "qgsfileutils.h"
38 #include "qgsproviderregistry.h"
39 #include <functional>
40 #include <QRegularExpression>
41 
42 
44 {
45  QVariantMap map;
46  map.insert( QStringLiteral( "source" ), source.toVariant() );
47  map.insert( QStringLiteral( "selected_only" ), selectedFeaturesOnly );
48  map.insert( QStringLiteral( "feature_limit" ), featureLimit );
49  map.insert( QStringLiteral( "flags" ), static_cast< int >( flags ) );
50  map.insert( QStringLiteral( "geometry_check" ), static_cast< int >( geometryCheck ) );
51  return map;
52 }
53 
55 {
56  source.loadVariant( map.value( QStringLiteral( "source" ) ) );
57  selectedFeaturesOnly = map.value( QStringLiteral( "selected_only" ), false ).toBool();
58  featureLimit = map.value( QStringLiteral( "feature_limit" ), -1 ).toLongLong();
59  flags = static_cast< Flags >( map.value( QStringLiteral( "flags" ), 0 ).toInt() );
60  geometryCheck = static_cast< QgsFeatureRequest::InvalidGeometryCheck >( map.value( QStringLiteral( "geometry_check" ), QgsFeatureRequest::GeometryAbortOnInvalid ).toInt() );
61  return true;
62 }
63 
64 
65 //
66 // QgsProcessingOutputLayerDefinition
67 //
68 
70 {
71  mUseRemapping = true;
72  mRemappingDefinition = definition;
73 }
74 
76 {
77  QVariantMap map;
78  map.insert( QStringLiteral( "sink" ), sink.toVariant() );
79  map.insert( QStringLiteral( "create_options" ), createOptions );
80  if ( mUseRemapping )
81  map.insert( QStringLiteral( "remapping" ), QVariant::fromValue( mRemappingDefinition ) );
82  return map;
83 }
84 
86 {
87  sink.loadVariant( map.value( QStringLiteral( "sink" ) ) );
88  createOptions = map.value( QStringLiteral( "create_options" ) ).toMap();
89  if ( map.contains( QStringLiteral( "remapping" ) ) )
90  {
91  mUseRemapping = true;
92  mRemappingDefinition = map.value( QStringLiteral( "remapping" ) ).value< QgsRemappingSinkDefinition >();
93  }
94  else
95  {
96  mUseRemapping = false;
97  }
98  return true;
99 }
100 
102 {
104  && mUseRemapping == other.mUseRemapping && mRemappingDefinition == other.mRemappingDefinition;
105 }
106 
108 {
109  return !( *this == other );
110 }
111 
112 bool QgsProcessingParameters::isDynamic( const QVariantMap &parameters, const QString &name )
113 {
114  QVariant val = parameters.value( name );
115  if ( val.canConvert<QgsProperty>() )
116  return val.value< QgsProperty >().propertyType() != QgsProperty::StaticProperty;
117  else
118  return false;
119 }
120 
121 QString QgsProcessingParameters::parameterAsString( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
122 {
123  if ( !definition )
124  return QString();
125 
126  return parameterAsString( definition, parameters.value( definition->name() ), context );
127 }
128 
129 QString QgsProcessingParameters::parameterAsString( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
130 {
131  if ( !definition )
132  return QString();
133 
134  QVariant val = value;
135  if ( val.canConvert<QgsProperty>() )
136  return val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
137 
138  if ( !val.isValid() )
139  {
140  // fall back to default
141  val = definition->defaultValue();
142  }
143 
144  if ( val == QgsProcessing::TEMPORARY_OUTPUT )
145  {
146  if ( const QgsProcessingDestinationParameter *destParam = dynamic_cast< const QgsProcessingDestinationParameter * >( definition ) )
147  return destParam->generateTemporaryDestination();
148  }
149 
150  return val.toString();
151 }
152 
153 QString QgsProcessingParameters::parameterAsExpression( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
154 {
155  if ( !definition )
156  return QString();
157 
158  return parameterAsExpression( definition, parameters.value( definition->name() ), context );
159 }
160 
161 QString QgsProcessingParameters::parameterAsExpression( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
162 {
163  if ( !definition )
164  return QString();
165 
166  QVariant val = value;
167  if ( val.canConvert<QgsProperty>() )
168  return val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
169 
170  if ( val.isValid() && !val.toString().isEmpty() )
171  {
172  QgsExpression e( val.toString() );
173  if ( e.isValid() )
174  return val.toString();
175  }
176 
177  // fall back to default
178  return definition->defaultValue().toString();
179 }
180 
181 double QgsProcessingParameters::parameterAsDouble( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
182 {
183  if ( !definition )
184  return 0;
185 
186  return parameterAsDouble( definition, parameters.value( definition->name() ), context );
187 }
188 
189 double QgsProcessingParameters::parameterAsDouble( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
190 {
191  if ( !definition )
192  return 0;
193 
194  QVariant val = value;
195  if ( val.canConvert<QgsProperty>() )
196  return val.value< QgsProperty >().valueAsDouble( context.expressionContext(), definition->defaultValue().toDouble() );
197 
198  bool ok = false;
199  double res = val.toDouble( &ok );
200  if ( ok )
201  return res;
202 
203  // fall back to default
204  val = definition->defaultValue();
205  return val.toDouble();
206 }
207 
208 int QgsProcessingParameters::parameterAsInt( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
209 {
210  if ( !definition )
211  return 0;
212 
213  return parameterAsInt( definition, parameters.value( definition->name() ), context );
214 }
215 
216 int QgsProcessingParameters::parameterAsInt( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
217 {
218  if ( !definition )
219  return 0;
220 
221  QVariant val = value;
222  if ( val.canConvert<QgsProperty>() )
223  return val.value< QgsProperty >().valueAsInt( context.expressionContext(), definition->defaultValue().toInt() );
224 
225  bool ok = false;
226  double dbl = val.toDouble( &ok );
227  if ( !ok )
228  {
229  // fall back to default
230  val = definition->defaultValue();
231  dbl = val.toDouble( &ok );
232  }
233 
234  //String representations of doubles in QVariant will not convert to int
235  //work around this by first converting to double, and then checking whether the double is convertible to int
236  if ( ok )
237  {
238  double round = std::round( dbl );
239  if ( round > std::numeric_limits<int>::max() || round < -std::numeric_limits<int>::max() )
240  {
241  //double too large to fit in int
242  return 0;
243  }
244  return static_cast< int >( std::round( dbl ) );
245  }
246 
247  return val.toInt();
248 }
249 
250 QList< int > QgsProcessingParameters::parameterAsInts( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
251 {
252  if ( !definition )
253  return QList< int >();
254 
255  return parameterAsInts( definition, parameters.value( definition->name() ), context );
256 }
257 
258 QList< int > QgsProcessingParameters::parameterAsInts( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
259 {
260  if ( !definition )
261  return QList< int >();
262 
263  QList< int > resultList;
264  QVariant val = value;
265  if ( val.isValid() )
266  {
267  if ( val.canConvert<QgsProperty>() )
268  resultList << val.value< QgsProperty >().valueAsInt( context.expressionContext(), definition->defaultValue().toInt() );
269  else if ( val.type() == QVariant::List )
270  {
271  QVariantList list = val.toList();
272  for ( auto it = list.constBegin(); it != list.constEnd(); ++it )
273  resultList << it->toInt();
274  }
275  else
276  {
277  QStringList parts = val.toString().split( ';' );
278  for ( auto it = parts.constBegin(); it != parts.constEnd(); ++it )
279  resultList << it->toInt();
280  }
281  }
282 
283  if ( resultList.isEmpty() )
284  {
285  // check default
286  if ( definition->defaultValue().isValid() )
287  {
288  if ( definition->defaultValue().type() == QVariant::List )
289  {
290  QVariantList list = definition->defaultValue().toList();
291  for ( auto it = list.constBegin(); it != list.constEnd(); ++it )
292  resultList << it->toInt();
293  }
294  else
295  {
296  QStringList parts = definition->defaultValue().toString().split( ';' );
297  for ( auto it = parts.constBegin(); it != parts.constEnd(); ++it )
298  resultList << it->toInt();
299  }
300  }
301  }
302 
303  return resultList;
304 }
305 
306 QDateTime QgsProcessingParameters::parameterAsDateTime( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
307 {
308  if ( !definition )
309  return QDateTime();
310 
311  return parameterAsDateTime( definition, parameters.value( definition->name() ), context );
312 }
313 
314 QDateTime QgsProcessingParameters::parameterAsDateTime( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
315 {
316  if ( !definition )
317  return QDateTime();
318 
319  QVariant val = value;
320  if ( val.canConvert<QgsProperty>() )
321  val = val.value< QgsProperty >().value( context.expressionContext(), definition->defaultValue() );
322 
323  QDateTime d = val.toDateTime();
324  if ( !d.isValid() && val.type() == QVariant::String )
325  {
326  d = QDateTime::fromString( val.toString() );
327  }
328 
329  if ( !d.isValid() )
330  {
331  // fall back to default
332  val = definition->defaultValue();
333  d = val.toDateTime();
334  }
335  if ( !d.isValid() && val.type() == QVariant::String )
336  {
337  d = QDateTime::fromString( val.toString() );
338  }
339 
340  return d;
341 }
342 
343 QDate QgsProcessingParameters::parameterAsDate( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
344 {
345  if ( !definition )
346  return QDate();
347 
348  return parameterAsDate( definition, parameters.value( definition->name() ), context );
349 }
350 
351 QDate QgsProcessingParameters::parameterAsDate( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
352 {
353  if ( !definition )
354  return QDate();
355 
356  QVariant val = value;
357  if ( val.canConvert<QgsProperty>() )
358  val = val.value< QgsProperty >().value( context.expressionContext(), definition->defaultValue() );
359 
360  QDate d = val.toDate();
361  if ( !d.isValid() && val.type() == QVariant::String )
362  {
363  d = QDate::fromString( val.toString() );
364  }
365 
366  if ( !d.isValid() )
367  {
368  // fall back to default
369  val = definition->defaultValue();
370  d = val.toDate();
371  }
372  if ( !d.isValid() && val.type() == QVariant::String )
373  {
374  d = QDate::fromString( val.toString() );
375  }
376 
377  return d;
378 }
379 
380 QTime QgsProcessingParameters::parameterAsTime( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
381 {
382  if ( !definition )
383  return QTime();
384 
385  return parameterAsTime( definition, parameters.value( definition->name() ), context );
386 }
387 
388 QTime QgsProcessingParameters::parameterAsTime( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
389 {
390  if ( !definition )
391  return QTime();
392 
393  QVariant val = value;
394  if ( val.canConvert<QgsProperty>() )
395  val = val.value< QgsProperty >().value( context.expressionContext(), definition->defaultValue() );
396 
397  QTime d;
398 
399  if ( val.type() == QVariant::DateTime )
400  d = val.toDateTime().time();
401  else
402  d = val.toTime();
403 
404  if ( !d.isValid() && val.type() == QVariant::String )
405  {
406  d = QTime::fromString( val.toString() );
407  }
408 
409  if ( !d.isValid() )
410  {
411  // fall back to default
412  val = definition->defaultValue();
413  d = val.toTime();
414  }
415  if ( !d.isValid() && val.type() == QVariant::String )
416  {
417  d = QTime::fromString( val.toString() );
418  }
419 
420  return d;
421 }
422 
423 int QgsProcessingParameters::parameterAsEnum( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
424 {
425  if ( !definition )
426  return 0;
427 
428  return parameterAsEnum( definition, parameters.value( definition->name() ), context );
429 }
430 
431 int QgsProcessingParameters::parameterAsEnum( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
432 {
433  if ( !definition )
434  return 0;
435 
436  int val = parameterAsInt( definition, value, context );
437  const QgsProcessingParameterEnum *enumDef = dynamic_cast< const QgsProcessingParameterEnum *>( definition );
438  if ( enumDef && val >= enumDef->options().size() )
439  {
440  return enumDef->defaultValue().toInt();
441  }
442  return val;
443 }
444 
445 QList<int> QgsProcessingParameters::parameterAsEnums( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
446 {
447  if ( !definition )
448  return QList<int>();
449 
450  return parameterAsEnums( definition, parameters.value( definition->name() ), context );
451 }
452 
453 QList<int> QgsProcessingParameters::parameterAsEnums( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
454 {
455  if ( !definition )
456  return QList<int>();
457 
458  QVariantList resultList;
459  QVariant val = value;
460  if ( val.canConvert<QgsProperty>() )
461  resultList << val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
462  else if ( val.type() == QVariant::List )
463  {
464  const auto constToList = val.toList();
465  for ( const QVariant &var : constToList )
466  resultList << var;
467  }
468  else if ( val.type() == QVariant::String )
469  {
470  const auto constSplit = val.toString().split( ',' );
471  for ( const QString &var : constSplit )
472  resultList << var;
473  }
474  else
475  resultList << val;
476 
477  if ( resultList.isEmpty() )
478  return QList< int >();
479 
480  if ( ( !val.isValid() || !resultList.at( 0 ).isValid() ) && definition )
481  {
482  resultList.clear();
483  // check default
484  if ( definition->defaultValue().type() == QVariant::List )
485  {
486  const auto constToList = definition->defaultValue().toList();
487  for ( const QVariant &var : constToList )
488  resultList << var;
489  }
490  else if ( definition->defaultValue().type() == QVariant::String )
491  {
492  const auto constSplit = definition->defaultValue().toString().split( ',' );
493  for ( const QString &var : constSplit )
494  resultList << var;
495  }
496  else
497  resultList << definition->defaultValue();
498  }
499 
500  QList< int > result;
501  const QgsProcessingParameterEnum *enumDef = dynamic_cast< const QgsProcessingParameterEnum *>( definition );
502  const auto constResultList = resultList;
503  for ( const QVariant &var : constResultList )
504  {
505  int resInt = var.toInt();
506  if ( !enumDef || resInt < enumDef->options().size() )
507  {
508  result << resInt;
509  }
510  }
511  return result;
512 }
513 
514 QString QgsProcessingParameters::parameterAsEnumString( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
515 {
516  if ( !definition )
517  return QString();
518 
519  return parameterAsEnumString( definition, parameters.value( definition->name() ), context );
520 }
521 
522 QString QgsProcessingParameters::parameterAsEnumString( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
523 {
524  if ( !definition )
525  return QString();
526 
527  QString enumText = parameterAsString( definition, value, context );
528  const QgsProcessingParameterEnum *enumDef = dynamic_cast< const QgsProcessingParameterEnum *>( definition );
529  if ( enumText.isEmpty() || !enumDef->options().contains( enumText ) )
530  enumText = definition->defaultValue().toString();
531 
532  return enumText;
533 }
534 
535 QStringList QgsProcessingParameters::parameterAsEnumStrings( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
536 {
537  if ( !definition )
538  return QStringList();
539 
540  return parameterAsEnumStrings( definition, parameters.value( definition->name() ), context );
541 }
542 
543 QStringList QgsProcessingParameters::parameterAsEnumStrings( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
544 {
545  if ( !definition )
546  return QStringList();
547 
548  QVariant val = value;
549 
550  QStringList enumValues;
551 
552  std::function< void( const QVariant &var ) > processVariant;
553  processVariant = [ &enumValues, &context, &definition, &processVariant ]( const QVariant & var )
554  {
555  if ( var.type() == QVariant::List )
556  {
557  const auto constToList = var.toList();
558  for ( const QVariant &listVar : constToList )
559  {
560  processVariant( listVar );
561  }
562  }
563  else if ( var.type() == QVariant::StringList )
564  {
565  const auto constToStringList = var.toStringList();
566  for ( const QString &s : constToStringList )
567  {
568  processVariant( s );
569  }
570  }
571  else if ( var.canConvert<QgsProperty>() )
572  processVariant( var.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() ) );
573  else
574  {
575  const QStringList parts = var.toString().split( ',' );
576  for ( const QString &s : parts )
577  {
578  enumValues << s;
579  }
580  }
581  };
582 
583  processVariant( val );
584 
585  const QgsProcessingParameterEnum *enumDef = dynamic_cast< const QgsProcessingParameterEnum *>( definition );
586  // check that values are valid enum values. The resulting set will be empty
587  // if all values are present in the enumDef->options(), otherwise it will contain
588  // values which are invalid
589 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
590  QSet<QString> subtraction = enumValues.toSet().subtract( enumDef->options().toSet() );
591 #else
592  const QStringList options = enumDef->options();
593  QSet<QString> subtraction = QSet<QString>( enumValues.begin(), enumValues.end() ).subtract( QSet<QString>( options.begin(), options.end() ) );
594 #endif
595 
596  if ( enumValues.isEmpty() || !subtraction.isEmpty() )
597  {
598  enumValues.clear();
599  processVariant( definition->defaultValue() );
600  }
601 
602  return enumValues;
603 }
604 
605 bool QgsProcessingParameters::parameterAsBool( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
606 {
607  if ( !definition )
608  return false;
609 
610  return parameterAsBool( definition, parameters.value( definition->name() ), context );
611 }
612 
613 bool QgsProcessingParameters::parameterAsBoolean( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
614 {
615  if ( !definition )
616  return false;
617 
618  return parameterAsBoolean( definition, parameters.value( definition->name() ), context );
619 }
620 
621 bool QgsProcessingParameters::parameterAsBool( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
622 {
623  if ( !definition )
624  return false;
625 
626  QVariant def = definition->defaultValue();
627 
628  QVariant val = value;
629  if ( val.canConvert<QgsProperty>() )
630  return val.value< QgsProperty >().valueAsBool( context.expressionContext(), def.toBool() );
631  else if ( val.isValid() )
632  return val.toBool();
633  else
634  return def.toBool();
635 }
636 
637 bool QgsProcessingParameters::parameterAsBoolean( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
638 {
639  if ( !definition )
640  return false;
641 
642  QVariant def = definition->defaultValue();
643 
644  QVariant val = value;
645  if ( val.canConvert<QgsProperty>() )
646  return val.value< QgsProperty >().valueAsBool( context.expressionContext(), def.toBool() );
647  else if ( val.isValid() )
648  return val.toBool();
649  else
650  return def.toBool();
651 }
652 
653 QgsFeatureSink *QgsProcessingParameters::parameterAsSink( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsFields &fields,
655  QgsProcessingContext &context, QString &destinationIdentifier, QgsFeatureSink::SinkFlags sinkFlags,
656  const QVariantMap &createOptions, const QStringList &datasourceOptions, const QStringList &layerOptions )
657 {
658  QVariant val;
659  if ( definition )
660  {
661  val = parameters.value( definition->name() );
662  }
663 
664  return parameterAsSink( definition, val, fields, geometryType, crs, context, destinationIdentifier, sinkFlags, createOptions, datasourceOptions, layerOptions );
665 }
666 
667 QgsFeatureSink *QgsProcessingParameters::parameterAsSink( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, QgsProcessingContext &context, QString &destinationIdentifier, QgsFeatureSink::SinkFlags sinkFlags, const QVariantMap &createOptions, const QStringList &datasourceOptions, const QStringList &layerOptions )
668 {
669  QVariantMap options = createOptions;
670  QVariant val = value;
671 
672  QgsProject *destinationProject = nullptr;
673  QString destName;
674  QgsRemappingSinkDefinition remapDefinition;
675  bool useRemapDefinition = false;
676  if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
677  {
678  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
679  QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
680  destinationProject = fromVar.destinationProject;
681  options = fromVar.createOptions;
682 
683  val = fromVar.sink;
684  destName = fromVar.destinationName;
685  if ( fromVar.useRemapping() )
686  {
687  useRemapDefinition = true;
688  remapDefinition = fromVar.remappingDefinition();
689  }
690  }
691 
692  QString dest;
693  if ( definition && val.canConvert<QgsProperty>() )
694  {
695  dest = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
696  }
697  else if ( !val.isValid() || val.toString().isEmpty() )
698  {
699  if ( definition && definition->flags() & QgsProcessingParameterDefinition::FlagOptional && !definition->defaultValue().isValid() )
700  {
701  // unset, optional sink, no default => no sink
702  return nullptr;
703  }
704  // fall back to default
705  if ( !definition )
706  {
707  throw QgsProcessingException( QObject::tr( "No parameter definition for the sink" ) );
708  }
709  dest = definition->defaultValue().toString();
710  }
711  else
712  {
713  dest = val.toString();
714  }
715  if ( dest == QgsProcessing::TEMPORARY_OUTPUT )
716  {
717  if ( const QgsProcessingDestinationParameter *destParam = dynamic_cast< const QgsProcessingDestinationParameter * >( definition ) )
718  dest = destParam->generateTemporaryDestination();
719  }
720 
721  if ( dest.isEmpty() )
722  return nullptr;
723 
724  std::unique_ptr< QgsFeatureSink > sink( QgsProcessingUtils::createFeatureSink( dest, context, fields, geometryType, crs, options, datasourceOptions, layerOptions, sinkFlags, useRemapDefinition ? &remapDefinition : nullptr ) );
725  destinationIdentifier = dest;
726 
727  if ( destinationProject )
728  {
729  if ( destName.isEmpty() && definition )
730  {
731  destName = definition->description();
732  }
733  QString outputName;
734  if ( definition )
735  outputName = definition->name();
736  context.addLayerToLoadOnCompletion( destinationIdentifier, QgsProcessingContext::LayerDetails( destName, destinationProject, outputName, QgsProcessingUtils::LayerHint::Vector ) );
737  }
738 
739  return sink.release();
740 }
741 
743 {
744  if ( !definition )
745  return nullptr;
746 
747  return parameterAsSource( definition, parameters.value( definition->name() ), context );
748 }
749 
751 {
752  if ( !definition )
753  return nullptr;
754 
755  return QgsProcessingUtils::variantToSource( value, context, definition->defaultValue() );
756 }
757 
758 QString parameterAsCompatibleSourceLayerPathInternal( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingFeedback *feedback, QString *layerName )
759 {
760  if ( !definition )
761  return QString();
762 
763  QVariant val = parameters.value( definition->name() );
764 
765  bool selectedFeaturesOnly = false;
766  long long featureLimit = -1;
767  if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
768  {
769  // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
770  QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
771  selectedFeaturesOnly = fromVar.selectedFeaturesOnly;
772  featureLimit = fromVar.featureLimit;
773  val = fromVar.source;
774  }
775  else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
776  {
777  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
778  QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
779  val = fromVar.sink;
780  }
781 
782  if ( val.canConvert<QgsProperty>() )
783  {
784  val = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
785  }
786 
787  QgsVectorLayer *vl = nullptr;
788  vl = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( val ) );
789 
790  if ( !vl )
791  {
792  QString layerRef;
793  if ( val.canConvert<QgsProperty>() )
794  {
795  layerRef = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
796  }
797  else if ( !val.isValid() || val.toString().isEmpty() )
798  {
799  // fall back to default
800  val = definition->defaultValue();
801 
802  // default value may be a vector layer
803  vl = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( val ) );
804  if ( !vl )
805  layerRef = definition->defaultValue().toString();
806  }
807  else
808  {
809  layerRef = val.toString();
810  }
811 
812  if ( !vl )
813  {
814  if ( layerRef.isEmpty() )
815  return QString();
816 
817  vl = qobject_cast< QgsVectorLayer *>( QgsProcessingUtils::mapLayerFromString( layerRef, context, true, QgsProcessingUtils::LayerHint::Vector ) );
818  }
819  }
820 
821  if ( !vl )
822  return QString();
823 
824  if ( layerName )
825  return QgsProcessingUtils::convertToCompatibleFormatAndLayerName( vl, selectedFeaturesOnly, definition->name(),
826  compatibleFormats, preferredFormat, context, feedback, *layerName, featureLimit );
827  else
828  return QgsProcessingUtils::convertToCompatibleFormat( vl, selectedFeaturesOnly, definition->name(),
829  compatibleFormats, preferredFormat, context, feedback, featureLimit );
830 }
831 
832 QString QgsProcessingParameters::parameterAsCompatibleSourceLayerPath( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingFeedback *feedback )
833 {
834  return parameterAsCompatibleSourceLayerPathInternal( definition, parameters, context, compatibleFormats, preferredFormat, feedback, nullptr );
835 }
836 
837 QString QgsProcessingParameters::parameterAsCompatibleSourceLayerPathAndLayerName( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingFeedback *feedback, QString *layerName )
838 {
839  QString *destLayer = layerName;
840  QString tmp;
841  if ( destLayer )
842  destLayer->clear();
843  else
844  destLayer = &tmp;
845 
846  return parameterAsCompatibleSourceLayerPathInternal( definition, parameters, context, compatibleFormats, preferredFormat, feedback, destLayer );
847 }
848 
850 {
851  if ( !definition )
852  return nullptr;
853 
854  return parameterAsLayer( definition, parameters.value( definition->name() ), context, layerHint );
855 }
856 
858 {
859  if ( !definition )
860  return nullptr;
861 
862  QVariant val = value;
863  if ( val.canConvert<QgsProperty>() )
864  {
865  val = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
866  }
867 
868  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
869  {
870  return layer;
871  }
872 
873  if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
874  {
875  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
876  QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
877  val = fromVar.sink;
878  }
879 
880  if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
881  {
882  val = val.value< QgsProperty >().staticValue();
883  }
884 
885  if ( !val.isValid() || val.toString().isEmpty() )
886  {
887  // fall back to default
888  val = definition->defaultValue();
889  }
890 
891  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
892  {
893  return layer;
894  }
895 
896  QString layerRef = val.toString();
897  if ( layerRef.isEmpty() )
898  layerRef = definition->defaultValue().toString();
899 
900  if ( layerRef.isEmpty() )
901  return nullptr;
902 
903  return QgsProcessingUtils::mapLayerFromString( layerRef, context, true, layerHint );
904 }
905 
907 {
908  return qobject_cast< QgsRasterLayer *>( parameterAsLayer( definition, parameters, context, QgsProcessingUtils::LayerHint::Raster ) );
909 }
910 
912 {
913  return qobject_cast< QgsRasterLayer *>( parameterAsLayer( definition, value, context, QgsProcessingUtils::LayerHint::Raster ) );
914 }
915 
917 {
918  return qobject_cast< QgsMeshLayer *>( parameterAsLayer( definition, parameters, context, QgsProcessingUtils::LayerHint::Mesh ) );
919 }
920 
922 {
923  return qobject_cast< QgsMeshLayer *>( parameterAsLayer( definition, value, context, QgsProcessingUtils::LayerHint::Mesh ) );
924 }
925 
926 QString QgsProcessingParameters::parameterAsOutputLayer( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
927 {
928  QVariant val;
929  if ( definition )
930  {
931  val = parameters.value( definition->name() );
932  }
933  return parameterAsOutputLayer( definition, val, context );
934 }
935 
937 {
938  QVariant val = value;
939 
940  QgsProject *destinationProject = nullptr;
941  QString destName;
942  if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
943  {
944  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
945  QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
946  destinationProject = fromVar.destinationProject;
947  val = fromVar.sink;
948  destName = fromVar.destinationName;
949  }
950 
951  QString dest;
952  if ( definition && val.canConvert<QgsProperty>() )
953  {
954  dest = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
955  }
956  else if ( definition && ( !val.isValid() || val.toString().isEmpty() ) )
957  {
958  // fall back to default
959  dest = definition->defaultValue().toString();
960  }
961  else
962  {
963  dest = val.toString();
964  }
965  if ( dest == QgsProcessing::TEMPORARY_OUTPUT )
966  {
967  if ( const QgsProcessingDestinationParameter *destParam = dynamic_cast< const QgsProcessingDestinationParameter * >( definition ) )
968  dest = destParam->generateTemporaryDestination();
969  }
970 
971  if ( destinationProject )
972  {
973  QString outputName;
974  if ( destName.isEmpty() && definition )
975  {
976  destName = definition->description();
977  }
978  if ( definition )
979  outputName = definition->name();
980 
982  if ( definition && definition->type() == QgsProcessingParameterVectorDestination::typeName() )
984  else if ( definition && definition->type() == QgsProcessingParameterRasterDestination::typeName() )
986 
987  context.addLayerToLoadOnCompletion( dest, QgsProcessingContext::LayerDetails( destName, destinationProject, outputName, layerTypeHint ) );
988  }
989 
990  return dest;
991 }
992 
993 QString QgsProcessingParameters::parameterAsFileOutput( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
994 {
995  QVariant val;
996  if ( definition )
997  {
998  val = parameters.value( definition->name() );
999  }
1000  return parameterAsFileOutput( definition, val, context );
1001 }
1002 
1004 {
1005  QVariant val = value;
1006 
1007  if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
1008  {
1009  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
1010  QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
1011  val = fromVar.sink;
1012  }
1013 
1014  QString dest;
1015  if ( definition && val.canConvert<QgsProperty>() )
1016  {
1017  dest = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1018  }
1019  else if ( definition && ( !val.isValid() || val.toString().isEmpty() ) )
1020  {
1021  // fall back to default
1022  dest = definition->defaultValue().toString();
1023  }
1024  else
1025  {
1026  dest = val.toString();
1027  }
1028  if ( dest == QgsProcessing::TEMPORARY_OUTPUT )
1029  {
1030  if ( const QgsProcessingDestinationParameter *destParam = dynamic_cast< const QgsProcessingDestinationParameter * >( definition ) )
1031  dest = destParam->generateTemporaryDestination();
1032  }
1033  return dest;
1034 }
1035 
1037 {
1038  return qobject_cast< QgsVectorLayer *>( parameterAsLayer( definition, parameters, context, QgsProcessingUtils::LayerHint::Vector ) );
1039 }
1040 
1042 {
1043  return qobject_cast< QgsVectorLayer *>( parameterAsLayer( definition, value, context, QgsProcessingUtils::LayerHint::Vector ) );
1044 }
1045 
1047 {
1048  if ( !definition )
1050 
1051  return parameterAsCrs( definition, parameters.value( definition->name() ), context );
1052 }
1053 
1055 {
1056  if ( !definition )
1058 
1059  return QgsProcessingUtils::variantToCrs( value, context, definition->defaultValue() );
1060 }
1061 
1064 {
1065  if ( !definition )
1066  return QgsRectangle();
1067 
1068  return parameterAsExtent( definition, parameters.value( definition->name() ), context, crs );
1069 }
1070 
1072 {
1073  if ( !definition )
1074  return QgsRectangle();
1075 
1076  QVariant val = value;
1077 
1078  if ( val.canConvert< QgsRectangle >() )
1079  {
1080  return val.value<QgsRectangle>();
1081  }
1082  if ( val.canConvert< QgsGeometry >() )
1083  {
1084  const QgsGeometry geom = val.value<QgsGeometry>();
1085  if ( !geom.isNull() )
1086  return geom.boundingBox();
1087  }
1088  if ( val.canConvert< QgsReferencedRectangle >() )
1089  {
1091  if ( crs.isValid() && rr.crs().isValid() && crs != rr.crs() )
1092  {
1093  QgsCoordinateTransform ct( rr.crs(), crs, context.project() );
1094  try
1095  {
1096  return ct.transformBoundingBox( rr );
1097  }
1098  catch ( QgsCsException & )
1099  {
1100  QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
1101  }
1102  }
1103  return rr;
1104  }
1105 
1106  if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
1107  {
1108  // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
1109  QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
1110  val = fromVar.source;
1111  }
1112  else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
1113  {
1114  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
1115  QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
1116  val = fromVar.sink;
1117  }
1118 
1119  if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
1120  {
1121  val = val.value< QgsProperty >().staticValue();
1122  }
1123 
1124  // maybe parameter is a direct layer value?
1125  QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) );
1126 
1127  QString rectText;
1128  if ( val.canConvert<QgsProperty>() )
1129  rectText = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1130  else
1131  rectText = val.toString();
1132 
1133  if ( rectText.isEmpty() && !layer )
1134  return QgsRectangle();
1135 
1136  QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?),\\s*(.*?),\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
1137  QRegularExpressionMatch match = rx.match( rectText );
1138  if ( match.hasMatch() )
1139  {
1140  bool xMinOk = false;
1141  double xMin = match.captured( 1 ).toDouble( &xMinOk );
1142  bool xMaxOk = false;
1143  double xMax = match.captured( 2 ).toDouble( &xMaxOk );
1144  bool yMinOk = false;
1145  double yMin = match.captured( 3 ).toDouble( &yMinOk );
1146  bool yMaxOk = false;
1147  double yMax = match.captured( 4 ).toDouble( &yMaxOk );
1148  if ( xMinOk && xMaxOk && yMinOk && yMaxOk )
1149  {
1150  QgsRectangle rect( xMin, yMin, xMax, yMax );
1151  QgsCoordinateReferenceSystem rectCrs( match.captured( 5 ) );
1152  if ( crs.isValid() && rectCrs.isValid() && crs != rectCrs )
1153  {
1154  QgsCoordinateTransform ct( rectCrs, crs, context.project() );
1155  try
1156  {
1157  return ct.transformBoundingBox( rect );
1158  }
1159  catch ( QgsCsException & )
1160  {
1161  QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
1162  }
1163  }
1164  return rect;
1165  }
1166  }
1167 
1168  // try as layer extent
1169  if ( !layer )
1170  layer = QgsProcessingUtils::mapLayerFromString( rectText, context );
1171 
1172  if ( layer )
1173  {
1174  QgsRectangle rect = layer->extent();
1175  if ( crs.isValid() && layer->crs().isValid() && crs != layer->crs() )
1176  {
1177  QgsCoordinateTransform ct( layer->crs(), crs, context.project() );
1178  try
1179  {
1180  return ct.transformBoundingBox( rect );
1181  }
1182  catch ( QgsCsException & )
1183  {
1184  QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
1185  }
1186  }
1187  return rect;
1188  }
1189  return QgsRectangle();
1190 }
1191 
1193 {
1194  if ( !definition )
1195  return QgsGeometry();
1196 
1197  QVariant val = parameters.value( definition->name() );
1198 
1199  if ( val.canConvert< QgsReferencedRectangle >() )
1200  {
1203  if ( crs.isValid() && rr.crs().isValid() && crs != rr.crs() )
1204  {
1205  g = g.densifyByCount( 20 );
1206  QgsCoordinateTransform ct( rr.crs(), crs, context.project() );
1207  try
1208  {
1209  g.transform( ct );
1210  }
1211  catch ( QgsCsException & )
1212  {
1213  QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
1214  }
1215  return g;
1216  }
1217  }
1218 
1219  if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
1220  {
1221  // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
1222  QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
1223  val = fromVar.source;
1224  }
1225  else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
1226  {
1227  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
1228  QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
1229  val = fromVar.sink;
1230  }
1231 
1232  if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
1233  {
1234  val = val.value< QgsProperty >().staticValue();
1235  }
1236 
1237  QString rectText;
1238  if ( val.canConvert<QgsProperty>() )
1239  rectText = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1240  else
1241  rectText = val.toString();
1242 
1243  if ( !rectText.isEmpty() )
1244  {
1245  QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?),\\s*(.*?),\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
1246  QRegularExpressionMatch match = rx.match( rectText );
1247  if ( match.hasMatch() )
1248  {
1249  bool xMinOk = false;
1250  double xMin = match.captured( 1 ).toDouble( &xMinOk );
1251  bool xMaxOk = false;
1252  double xMax = match.captured( 2 ).toDouble( &xMaxOk );
1253  bool yMinOk = false;
1254  double yMin = match.captured( 3 ).toDouble( &yMinOk );
1255  bool yMaxOk = false;
1256  double yMax = match.captured( 4 ).toDouble( &yMaxOk );
1257  if ( xMinOk && xMaxOk && yMinOk && yMaxOk )
1258  {
1259  QgsRectangle rect( xMin, yMin, xMax, yMax );
1260  QgsCoordinateReferenceSystem rectCrs( match.captured( 5 ) );
1261  QgsGeometry g = QgsGeometry::fromRect( rect );
1262  if ( crs.isValid() && rectCrs.isValid() && crs != rectCrs )
1263  {
1264  g = g.densifyByCount( 20 );
1265  QgsCoordinateTransform ct( rectCrs, crs, context.project() );
1266  try
1267  {
1268  g.transform( ct );
1269  }
1270  catch ( QgsCsException & )
1271  {
1272  QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
1273  }
1274  return g;
1275  }
1276  }
1277  }
1278  }
1279 
1280  // try as layer extent
1281 
1282  // maybe parameter is a direct layer value?
1283  QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) );
1284  if ( !layer )
1285  layer = QgsProcessingUtils::mapLayerFromString( rectText, context );
1286 
1287  if ( layer )
1288  {
1289  QgsRectangle rect = layer->extent();
1290  QgsGeometry g = QgsGeometry::fromRect( rect );
1291  if ( crs.isValid() && layer->crs().isValid() && crs != layer->crs() )
1292  {
1293  g = g.densifyByCount( 20 );
1294  QgsCoordinateTransform ct( layer->crs(), crs, context.project() );
1295  try
1296  {
1297  g.transform( ct );
1298  }
1299  catch ( QgsCsException & )
1300  {
1301  QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
1302  }
1303  }
1304  return g;
1305  }
1306 
1307  return QgsGeometry::fromRect( parameterAsExtent( definition, parameters, context, crs ) );
1308 }
1309 
1311 {
1312  QVariant val = parameters.value( definition->name() );
1313  return parameterAsExtentCrs( definition, val, context );
1314 }
1315 
1317 {
1318  QVariant val = value;
1319  if ( val.canConvert< QgsReferencedRectangle >() )
1320  {
1322  if ( rr.crs().isValid() )
1323  {
1324  return rr.crs();
1325  }
1326  }
1327 
1328  if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
1329  {
1330  // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
1331  QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
1332  val = fromVar.source;
1333  }
1334  else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
1335  {
1336  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
1337  QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
1338  val = fromVar.sink;
1339  }
1340 
1341  if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
1342  {
1343  val = val.value< QgsProperty >().staticValue();
1344  }
1345 
1346  QString valueAsString;
1347  if ( val.canConvert<QgsProperty>() )
1348  valueAsString = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1349  else
1350  valueAsString = val.toString();
1351 
1352  QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?),\\s*(.*?),\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
1353 
1354  QRegularExpressionMatch match = rx.match( valueAsString );
1355  if ( match.hasMatch() )
1356  {
1357  QgsCoordinateReferenceSystem crs( match.captured( 5 ) );
1358  if ( crs.isValid() )
1359  return crs;
1360  }
1361 
1362  if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
1363  {
1364  // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
1365  QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
1366  val = fromVar.source;
1367  }
1368  else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
1369  {
1370  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
1371  QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
1372  val = fromVar.sink;
1373  }
1374 
1375  if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
1376  {
1377  val = val.value< QgsProperty >().staticValue();
1378  }
1379 
1380  // try as layer crs
1381  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
1382  return layer->crs();
1383  else if ( QgsMapLayer *layer = QgsProcessingUtils::mapLayerFromString( valueAsString, context ) )
1384  return layer->crs();
1385 
1386  if ( auto *lProject = context.project() )
1387  return lProject->crs();
1388  else
1390 }
1391 
1393 {
1394  if ( !definition )
1395  return QgsPointXY();
1396 
1397  return parameterAsPoint( definition, parameters.value( definition->name() ), context, crs );
1398 }
1399 
1401 {
1402  if ( !definition )
1403  return QgsPointXY();
1404 
1405  QVariant val = value;
1406  if ( val.canConvert< QgsPointXY >() )
1407  {
1408  return val.value<QgsPointXY>();
1409  }
1410  if ( val.canConvert< QgsGeometry >() )
1411  {
1412  const QgsGeometry geom = val.value<QgsGeometry>();
1413  if ( !geom.isNull() )
1414  return geom.centroid().asPoint();
1415  }
1416  if ( val.canConvert< QgsReferencedPointXY >() )
1417  {
1418  QgsReferencedPointXY rp = val.value<QgsReferencedPointXY>();
1419  if ( crs.isValid() && rp.crs().isValid() && crs != rp.crs() )
1420  {
1421  QgsCoordinateTransform ct( rp.crs(), crs, context.project() );
1422  try
1423  {
1424  return ct.transform( rp );
1425  }
1426  catch ( QgsCsException & )
1427  {
1428  QgsMessageLog::logMessage( QObject::tr( "Error transforming point geometry" ) );
1429  }
1430  }
1431  return rp;
1432  }
1433 
1434  QString pointText = parameterAsString( definition, value, context );
1435  if ( pointText.isEmpty() )
1436  pointText = definition->defaultValue().toString();
1437 
1438  if ( pointText.isEmpty() )
1439  return QgsPointXY();
1440 
1441  QRegularExpression rx( QStringLiteral( "^\\s*\\(?\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*\\)?\\s*$" ) );
1442 
1443  QString valueAsString = parameterAsString( definition, value, context );
1444  QRegularExpressionMatch match = rx.match( valueAsString );
1445  if ( match.hasMatch() )
1446  {
1447  bool xOk = false;
1448  double x = match.captured( 1 ).toDouble( &xOk );
1449  bool yOk = false;
1450  double y = match.captured( 2 ).toDouble( &yOk );
1451 
1452  if ( xOk && yOk )
1453  {
1454  QgsPointXY pt( x, y );
1455 
1456  QgsCoordinateReferenceSystem pointCrs( match.captured( 3 ) );
1457  if ( crs.isValid() && pointCrs.isValid() && crs != pointCrs )
1458  {
1459  QgsCoordinateTransform ct( pointCrs, crs, context.project() );
1460  try
1461  {
1462  return ct.transform( pt );
1463  }
1464  catch ( QgsCsException & )
1465  {
1466  QgsMessageLog::logMessage( QObject::tr( "Error transforming point geometry" ) );
1467  }
1468  }
1469  return pt;
1470  }
1471  }
1472 
1473  return QgsPointXY();
1474 }
1475 
1477 {
1478  QVariant val = parameters.value( definition->name() );
1479  return parameterAsPointCrs( definition, val, context );
1480 }
1481 
1483 {
1484  if ( value.canConvert< QgsReferencedPointXY >() )
1485  {
1486  QgsReferencedPointXY rr = value.value<QgsReferencedPointXY>();
1487  if ( rr.crs().isValid() )
1488  {
1489  return rr.crs();
1490  }
1491  }
1492 
1493  QRegularExpression rx( QStringLiteral( "^\\s*\\(?\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*\\)?\\s*$" ) );
1494 
1495  QString valueAsString = parameterAsString( definition, value, context );
1496  QRegularExpressionMatch match = rx.match( valueAsString );
1497  if ( match.hasMatch() )
1498  {
1499  QgsCoordinateReferenceSystem crs( match.captured( 3 ) );
1500  if ( crs.isValid() )
1501  return crs;
1502  }
1503 
1504  if ( auto *lProject = context.project() )
1505  return lProject->crs();
1506  else
1508 }
1509 
1511 {
1512  if ( !definition )
1513  return QgsGeometry();
1514 
1515  return parameterAsGeometry( definition, parameters.value( definition->name() ), context, crs );
1516 }
1517 
1519 {
1520  if ( !definition )
1521  return QgsGeometry();
1522 
1523  QVariant val = value;
1524  if ( val.canConvert< QgsGeometry >() )
1525  {
1526  return val.value<QgsGeometry>();
1527  }
1528 
1529  if ( val.canConvert< QgsPointXY >() )
1530  {
1531  return QgsGeometry::fromPointXY( val.value<QgsPointXY>() );
1532  }
1533 
1534  if ( val.canConvert< QgsRectangle >() )
1535  {
1536  return QgsGeometry::fromRect( val.value<QgsRectangle>() );
1537  }
1538 
1539  if ( val.canConvert< QgsReferencedPointXY >() )
1540  {
1541  QgsReferencedPointXY rp = val.value<QgsReferencedPointXY>();
1542  if ( crs.isValid() && rp.crs().isValid() && crs != rp.crs() )
1543  {
1544  QgsCoordinateTransform ct( rp.crs(), crs, context.project() );
1545  try
1546  {
1547  return QgsGeometry::fromPointXY( ct.transform( rp ) );
1548  }
1549  catch ( QgsCsException & )
1550  {
1551  QgsMessageLog::logMessage( QObject::tr( "Error transforming point geometry" ) );
1552  }
1553  }
1554  return QgsGeometry::fromPointXY( rp );
1555  }
1556 
1557  if ( val.canConvert< QgsReferencedRectangle >() )
1558  {
1561  if ( crs.isValid() && rr.crs().isValid() && crs != rr.crs() )
1562  {
1563  g = g.densifyByCount( 20 );
1564  QgsCoordinateTransform ct( rr.crs(), crs, context.project() );
1565  try
1566  {
1567  g.transform( ct );
1568  }
1569  catch ( QgsCsException & )
1570  {
1571  QgsMessageLog::logMessage( QObject::tr( "Error transforming rectangle geometry" ) );
1572  }
1573  }
1574  return g;
1575  }
1576 
1577  if ( val.canConvert< QgsReferencedGeometry >() )
1578  {
1579  QgsReferencedGeometry rg = val.value<QgsReferencedGeometry>();
1580  if ( crs.isValid() && rg.crs().isValid() && crs != rg.crs() )
1581  {
1582  QgsCoordinateTransform ct( rg.crs(), crs, context.project() );
1583  try
1584  {
1585  rg.transform( ct );
1586  }
1587  catch ( QgsCsException & )
1588  {
1589  QgsMessageLog::logMessage( QObject::tr( "Error transforming geometry" ) );
1590  }
1591  }
1592  return rg;
1593  }
1594 
1595  QString valueAsString = parameterAsString( definition, value, context );
1596  if ( valueAsString.isEmpty() )
1597  valueAsString = definition->defaultValue().toString();
1598 
1599  if ( valueAsString.isEmpty() )
1600  return QgsGeometry();
1601 
1602  QRegularExpression rx( QStringLiteral( "^\\s*(?:CRS=(.*);)?(.*?)$" ) );
1603 
1604  QRegularExpressionMatch match = rx.match( valueAsString );
1605  if ( match.hasMatch() )
1606  {
1607  QgsGeometry g = QgsGeometry::fromWkt( match.captured( 2 ) );
1608  if ( !g.isNull() )
1609  {
1610  QgsCoordinateReferenceSystem geomCrs( match.captured( 1 ) );
1611  if ( crs.isValid() && geomCrs.isValid() && crs != geomCrs )
1612  {
1613  QgsCoordinateTransform ct( geomCrs, crs, context.project() );
1614  try
1615  {
1616  g.transform( ct );
1617  }
1618  catch ( QgsCsException & )
1619  {
1620  QgsMessageLog::logMessage( QObject::tr( "Error transforming geometry" ) );
1621  }
1622  }
1623  return g;
1624  }
1625  }
1626 
1627  return QgsGeometry();
1628 }
1629 
1631 {
1632  QVariant val = parameters.value( definition->name() );
1633  return parameterAsGeometryCrs( definition, val, context );
1634 }
1635 
1637 {
1638  if ( value.canConvert< QgsReferencedGeometry >() )
1639  {
1640  QgsReferencedGeometry rg = value.value<QgsReferencedGeometry>();
1641  if ( rg.crs().isValid() )
1642  {
1643  return rg.crs();
1644  }
1645  }
1646 
1647  if ( value.canConvert< QgsReferencedPointXY >() )
1648  {
1649  QgsReferencedPointXY rp = value.value<QgsReferencedPointXY>();
1650  if ( rp.crs().isValid() )
1651  {
1652  return rp.crs();
1653  }
1654  }
1655 
1656  if ( value.canConvert< QgsReferencedRectangle >() )
1657  {
1658  QgsReferencedRectangle rr = value.value<QgsReferencedRectangle>();
1659  if ( rr.crs().isValid() )
1660  {
1661  return rr.crs();
1662  }
1663  }
1664 
1665  // Match against EWKT
1666  QRegularExpression rx( QStringLiteral( "^\\s*(?:CRS=(.*);)?(.*?)$" ) );
1667 
1668  QString valueAsString = parameterAsString( definition, value, context );
1669  QRegularExpressionMatch match = rx.match( valueAsString );
1670  if ( match.hasMatch() )
1671  {
1672  QgsCoordinateReferenceSystem crs( match.captured( 1 ) );
1673  if ( crs.isValid() )
1674  return crs;
1675  }
1676 
1677  if ( auto *lProject = context.project() )
1678  return lProject->crs();
1679  else
1681 }
1682 
1683 QString QgsProcessingParameters::parameterAsFile( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1684 {
1685  if ( !definition )
1686  return QString();
1687 
1688  QString fileText = parameterAsString( definition, parameters, context );
1689  if ( fileText.isEmpty() )
1690  fileText = definition->defaultValue().toString();
1691  return fileText;
1692 }
1693 
1694 QString QgsProcessingParameters::parameterAsFile( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1695 {
1696  if ( !definition )
1697  return QString();
1698 
1699  QString fileText = parameterAsString( definition, value, context );
1700  if ( fileText.isEmpty() )
1701  fileText = definition->defaultValue().toString();
1702  return fileText;
1703 }
1704 
1705 QVariantList QgsProcessingParameters::parameterAsMatrix( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1706 {
1707  if ( !definition )
1708  return QVariantList();
1709 
1710  return parameterAsMatrix( definition, parameters.value( definition->name() ), context );
1711 }
1712 
1713 QVariantList QgsProcessingParameters::parameterAsMatrix( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1714 {
1715  if ( !definition )
1716  return QVariantList();
1717 
1718  QString resultString;
1719  QVariant val = value;
1720  if ( val.canConvert<QgsProperty>() )
1721  resultString = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1722  else if ( val.type() == QVariant::List )
1723  return val.toList();
1724  else
1725  resultString = val.toString();
1726 
1727  if ( resultString.isEmpty() )
1728  {
1729  // check default
1730  if ( definition->defaultValue().type() == QVariant::List )
1731  return definition->defaultValue().toList();
1732  else
1733  resultString = definition->defaultValue().toString();
1734  }
1735 
1736  QVariantList result;
1737  const auto constSplit = resultString.split( ',' );
1738  for ( const QString &s : constSplit )
1739  result << s;
1740 
1741  return result;
1742 }
1743 
1744 QList<QgsMapLayer *> QgsProcessingParameters::parameterAsLayerList( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1745 {
1746  if ( !definition )
1747  return QList<QgsMapLayer *>();
1748 
1749  return parameterAsLayerList( definition, parameters.value( definition->name() ), context );
1750 }
1751 
1752 QList<QgsMapLayer *> QgsProcessingParameters::parameterAsLayerList( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1753 {
1754  if ( !definition )
1755  return QList<QgsMapLayer *>();
1756 
1757  QVariant val = value;
1758  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
1759  {
1760  return QList<QgsMapLayer *>() << layer;
1761  }
1762 
1763  QList<QgsMapLayer *> layers;
1764 
1765  std::function< void( const QVariant &var ) > processVariant;
1766  processVariant = [ &layers, &context, &definition, &processVariant ]( const QVariant & var )
1767  {
1768  if ( var.type() == QVariant::List )
1769  {
1770  const auto constToList = var.toList();
1771  for ( const QVariant &listVar : constToList )
1772  {
1773  processVariant( listVar );
1774  }
1775  }
1776  else if ( var.type() == QVariant::StringList )
1777  {
1778  const auto constToStringList = var.toStringList();
1779  for ( const QString &s : constToStringList )
1780  {
1781  processVariant( s );
1782  }
1783  }
1784  else if ( var.canConvert<QgsProperty>() )
1785  processVariant( var.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() ) );
1786  else if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
1787  {
1788  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
1789  QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
1790  QVariant sink = fromVar.sink;
1791  if ( sink.canConvert<QgsProperty>() )
1792  {
1793  processVariant( sink.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() ) );
1794  }
1795  }
1796  else if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( var ) ) )
1797  {
1798  layers << layer;
1799  }
1800  else
1801  {
1802  QgsMapLayer *alayer = QgsProcessingUtils::mapLayerFromString( var.toString(), context );
1803  if ( alayer )
1804  layers << alayer;
1805  }
1806  };
1807 
1808  processVariant( val );
1809 
1810  if ( layers.isEmpty() )
1811  {
1812  // check default
1813  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( definition->defaultValue() ) ) )
1814  {
1815  layers << layer;
1816  }
1817  else if ( definition->defaultValue().type() == QVariant::List )
1818  {
1819  const auto constToList = definition->defaultValue().toList();
1820  for ( const QVariant &var : constToList )
1821  {
1822  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( var ) ) )
1823  {
1824  layers << layer;
1825  }
1826  else
1827  {
1828  processVariant( var );
1829  }
1830  }
1831  }
1832  else
1833  processVariant( definition->defaultValue() );
1834  }
1835 
1836  return layers;
1837 }
1838 
1839 QStringList QgsProcessingParameters::parameterAsFileList( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1840 {
1841  if ( !definition )
1842  return QStringList();
1843 
1844  QVariant val = value;
1845 
1846  QStringList files;
1847 
1848  std::function< void( const QVariant &var ) > processVariant;
1849  processVariant = [ &files, &context, &definition, &processVariant ]( const QVariant & var )
1850  {
1851  if ( var.type() == QVariant::List )
1852  {
1853  const auto constToList = var.toList();
1854  for ( const QVariant &listVar : constToList )
1855  {
1856  processVariant( listVar );
1857  }
1858  }
1859  else if ( var.type() == QVariant::StringList )
1860  {
1861  const auto constToStringList = var.toStringList();
1862  for ( const QString &s : constToStringList )
1863  {
1864  processVariant( s );
1865  }
1866  }
1867  else if ( var.canConvert<QgsProperty>() )
1868  processVariant( var.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() ) );
1869  else
1870  {
1871  files << var.toString();
1872  }
1873  };
1874 
1875  processVariant( val );
1876 
1877  if ( files.isEmpty() )
1878  {
1879  processVariant( definition->defaultValue() );
1880  }
1881 
1882  return files;
1883 }
1884 
1885 QStringList QgsProcessingParameters::parameterAsFileList( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1886 {
1887  if ( !definition )
1888  return QStringList();
1889 
1890  return parameterAsFileList( definition, parameters.value( definition->name() ), context );
1891 }
1892 
1893 QList<double> QgsProcessingParameters::parameterAsRange( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1894 {
1895  if ( !definition )
1896  return QList<double>();
1897 
1898  return parameterAsRange( definition, parameters.value( definition->name() ), context );
1899 }
1900 
1901 QList<double> QgsProcessingParameters::parameterAsRange( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1902 {
1903  if ( !definition )
1904  return QList<double>();
1905 
1906  QStringList resultStringList;
1907  QVariant val = value;
1908 
1909  if ( val.canConvert<QgsProperty>() )
1910  resultStringList << val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1911  else if ( val.type() == QVariant::List )
1912  {
1913  const auto constToList = val.toList();
1914  for ( const QVariant &var : constToList )
1915  resultStringList << var.toString();
1916  }
1917  else
1918  resultStringList << val.toString();
1919 
1920  if ( ( resultStringList.isEmpty() || ( resultStringList.size() == 1 && resultStringList.at( 0 ).isEmpty() ) ) )
1921  {
1922  resultStringList.clear();
1923  // check default
1924  if ( definition->defaultValue().type() == QVariant::List )
1925  {
1926  const auto constToList = definition->defaultValue().toList();
1927  for ( const QVariant &var : constToList )
1928  resultStringList << var.toString();
1929  }
1930  else
1931  resultStringList << definition->defaultValue().toString();
1932  }
1933 
1934  if ( resultStringList.size() == 1 )
1935  {
1936  resultStringList = resultStringList.at( 0 ).split( ',' );
1937  }
1938 
1939  if ( resultStringList.size() < 2 )
1940  return QList< double >() << std::numeric_limits<double>::quiet_NaN() << std::numeric_limits<double>::quiet_NaN() ;
1941 
1942  QList< double > result;
1943  bool ok = false;
1944  double n = resultStringList.at( 0 ).toDouble( &ok );
1945  if ( ok )
1946  result << n;
1947  else
1948  result << std::numeric_limits<double>::quiet_NaN() ;
1949  ok = false;
1950  n = resultStringList.at( 1 ).toDouble( &ok );
1951  if ( ok )
1952  result << n;
1953  else
1954  result << std::numeric_limits<double>::quiet_NaN() ;
1955 
1956  return result;
1957 }
1958 
1959 QStringList QgsProcessingParameters::parameterAsFields( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1960 {
1961  if ( !definition )
1962  return QStringList();
1963 
1964  QStringList resultStringList;
1965  return parameterAsFields( definition, parameters.value( definition->name() ), context );
1966 }
1967 
1968 QStringList QgsProcessingParameters::parameterAsFields( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1969 {
1970  if ( !definition )
1971  return QStringList();
1972 
1973  QStringList resultStringList;
1974  QVariant val = value;
1975  if ( val.isValid() )
1976  {
1977  if ( val.canConvert<QgsProperty>() )
1978  resultStringList << val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1979  else if ( val.type() == QVariant::List )
1980  {
1981  const auto constToList = val.toList();
1982  for ( const QVariant &var : constToList )
1983  resultStringList << var.toString();
1984  }
1985  else if ( val.type() == QVariant::StringList )
1986  {
1987  resultStringList = val.toStringList();
1988  }
1989  else
1990  resultStringList.append( val.toString().split( ';' ) );
1991  }
1992 
1993  if ( ( resultStringList.isEmpty() || resultStringList.at( 0 ).isEmpty() ) )
1994  {
1995  resultStringList.clear();
1996  // check default
1997  if ( definition->defaultValue().isValid() )
1998  {
1999  if ( definition->defaultValue().type() == QVariant::List )
2000  {
2001  const auto constToList = definition->defaultValue().toList();
2002  for ( const QVariant &var : constToList )
2003  resultStringList << var.toString();
2004  }
2005  else if ( definition->defaultValue().type() == QVariant::StringList )
2006  {
2007  resultStringList = definition->defaultValue().toStringList();
2008  }
2009  else
2010  resultStringList.append( definition->defaultValue().toString().split( ';' ) );
2011  }
2012  }
2013 
2014  return resultStringList;
2015 }
2016 
2018 {
2019  if ( !definition )
2020  return nullptr;
2021 
2022  return parameterAsLayout( definition, parameters.value( definition->name() ), context );
2023 }
2024 
2026 {
2027  const QString layoutName = parameterAsString( definition, value, context );
2028  if ( layoutName.isEmpty() )
2029  return nullptr;
2030 
2031  if ( !context.project() )
2032  return nullptr;
2033 
2034  QgsMasterLayoutInterface *l = context.project()->layoutManager()->layoutByName( layoutName );
2036  return static_cast< QgsPrintLayout * >( l );
2037  else
2038  return nullptr;
2039 }
2040 
2042 {
2043  if ( !definition )
2044  return nullptr;
2045 
2046  return parameterAsLayoutItem( definition, parameters.value( definition->name() ), context, layout );
2047 }
2048 
2050 {
2051  if ( !layout )
2052  return nullptr;
2053 
2054  const QString id = parameterAsString( definition, value, context );
2055  if ( id.isEmpty() )
2056  return nullptr;
2057 
2058  // prefer matching by uuid, since it's guaranteed to be unique.
2059  if ( QgsLayoutItem *item = layout->itemByUuid( id ) )
2060  return item;
2061  else if ( QgsLayoutItem *item = layout->itemById( id ) )
2062  return item;
2063  else
2064  return nullptr;
2065 }
2066 
2067 QColor QgsProcessingParameters::parameterAsColor( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
2068 {
2069  if ( !definition )
2070  return QColor();
2071 
2072  return parameterAsColor( definition, parameters.value( definition->name() ), context );
2073 }
2074 
2076 {
2077  if ( !definition )
2078  return QColor();
2079 
2080  QVariant val = value;
2081  if ( val.canConvert<QgsProperty>() )
2082  {
2083  val = val.value< QgsProperty >().value( context.expressionContext(), definition->defaultValue() );
2084  }
2085  if ( val.type() == QVariant::Color )
2086  {
2087  QColor c = val.value< QColor >();
2088  if ( const QgsProcessingParameterColor *colorParam = dynamic_cast< const QgsProcessingParameterColor * >( definition ) )
2089  if ( !colorParam->opacityEnabled() )
2090  c.setAlpha( 255 );
2091  return c;
2092  }
2093 
2094  QString colorText = parameterAsString( definition, value, context );
2095  if ( colorText.isEmpty() && !( definition->flags() & QgsProcessingParameterDefinition::FlagOptional ) )
2096  {
2097  if ( definition->defaultValue().type() == QVariant::Color )
2098  return definition->defaultValue().value< QColor >();
2099  else
2100  colorText = definition->defaultValue().toString();
2101  }
2102 
2103  if ( colorText.isEmpty() )
2104  return QColor();
2105 
2106  bool containsAlpha = false;
2107  QColor c = QgsSymbolLayerUtils::parseColorWithAlpha( colorText, containsAlpha );
2108  if ( const QgsProcessingParameterColor *colorParam = dynamic_cast< const QgsProcessingParameterColor * >( definition ) )
2109  if ( c.isValid() && !colorParam->opacityEnabled() )
2110  c.setAlpha( 255 );
2111  return c;
2112 }
2113 
2114 QString QgsProcessingParameters::parameterAsConnectionName( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
2115 {
2116  if ( !definition )
2117  return QString();
2118 
2119  return parameterAsConnectionName( definition, parameters.value( definition->name() ), context );
2120 }
2121 
2122 QString QgsProcessingParameters::parameterAsConnectionName( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
2123 {
2124  // for now it's just treated identical to strings, but in future we may want flexibility to amend this
2125  // (hence the new method)
2126  return parameterAsString( definition, value, context );
2127 }
2128 
2129 QString QgsProcessingParameters::parameterAsSchema( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
2130 {
2131  if ( !definition )
2132  return QString();
2133 
2134  return parameterAsSchema( definition, parameters.value( definition->name() ), context );
2135 }
2136 
2137 QString QgsProcessingParameters::parameterAsSchema( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
2138 {
2139  // for now it's just treated identical to strings, but in future we may want flexibility to amend this (e.g. if we want to embed connection details into the schema
2140  // parameter values, such as via a delimiter separated string)
2141  return parameterAsString( definition, value, context );
2142 }
2143 
2144 QString QgsProcessingParameters::parameterAsDatabaseTableName( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
2145 {
2146  if ( !definition )
2147  return QString();
2148 
2149  return parameterAsDatabaseTableName( definition, parameters.value( definition->name() ), context );
2150 }
2151 
2153 {
2154  // for now it's just treated identical to strings, but in future we may want flexibility to amend this (e.g. if we want to embed connection details into the table name
2155  // parameter values, such as via a delimiter separated string)
2156  return parameterAsString( definition, value, context );
2157 }
2158 
2160 {
2161  QString type = map.value( QStringLiteral( "parameter_type" ) ).toString();
2162  QString name = map.value( QStringLiteral( "name" ) ).toString();
2163  std::unique_ptr< QgsProcessingParameterDefinition > def;
2164 
2165  // probably all these hardcoded values aren't required anymore, and we could
2166  // always resort to the registry lookup...
2167  // TODO: confirm
2169  def.reset( new QgsProcessingParameterBoolean( name ) );
2170  else if ( type == QgsProcessingParameterCrs::typeName() )
2171  def.reset( new QgsProcessingParameterCrs( name ) );
2172  else if ( type == QgsProcessingParameterMapLayer::typeName() )
2173  def.reset( new QgsProcessingParameterMapLayer( name ) );
2174  else if ( type == QgsProcessingParameterExtent::typeName() )
2175  def.reset( new QgsProcessingParameterExtent( name ) );
2176  else if ( type == QgsProcessingParameterPoint::typeName() )
2177  def.reset( new QgsProcessingParameterPoint( name ) );
2178  else if ( type == QgsProcessingParameterFile::typeName() )
2179  def.reset( new QgsProcessingParameterFile( name ) );
2180  else if ( type == QgsProcessingParameterMatrix::typeName() )
2181  def.reset( new QgsProcessingParameterMatrix( name ) );
2183  def.reset( new QgsProcessingParameterMultipleLayers( name ) );
2184  else if ( type == QgsProcessingParameterNumber::typeName() )
2185  def.reset( new QgsProcessingParameterNumber( name ) );
2186  else if ( type == QgsProcessingParameterRange::typeName() )
2187  def.reset( new QgsProcessingParameterRange( name ) );
2188  else if ( type == QgsProcessingParameterRasterLayer::typeName() )
2189  def.reset( new QgsProcessingParameterRasterLayer( name ) );
2190  else if ( type == QgsProcessingParameterEnum::typeName() )
2191  def.reset( new QgsProcessingParameterEnum( name ) );
2192  else if ( type == QgsProcessingParameterString::typeName() )
2193  def.reset( new QgsProcessingParameterString( name ) );
2194  else if ( type == QgsProcessingParameterAuthConfig::typeName() )
2195  def.reset( new QgsProcessingParameterAuthConfig( name ) );
2196  else if ( type == QgsProcessingParameterExpression::typeName() )
2197  def.reset( new QgsProcessingParameterExpression( name ) );
2198  else if ( type == QgsProcessingParameterVectorLayer::typeName() )
2199  def.reset( new QgsProcessingParameterVectorLayer( name ) );
2200  else if ( type == QgsProcessingParameterField::typeName() )
2201  def.reset( new QgsProcessingParameterField( name ) );
2202  else if ( type == QgsProcessingParameterFeatureSource::typeName() )
2203  def.reset( new QgsProcessingParameterFeatureSource( name ) );
2204  else if ( type == QgsProcessingParameterFeatureSink::typeName() )
2205  def.reset( new QgsProcessingParameterFeatureSink( name ) );
2207  def.reset( new QgsProcessingParameterVectorDestination( name ) );
2209  def.reset( new QgsProcessingParameterRasterDestination( name ) );
2211  def.reset( new QgsProcessingParameterFileDestination( name ) );
2213  def.reset( new QgsProcessingParameterFolderDestination( name ) );
2214  else if ( type == QgsProcessingParameterBand::typeName() )
2215  def.reset( new QgsProcessingParameterBand( name ) );
2216  else if ( type == QgsProcessingParameterMeshLayer::typeName() )
2217  def.reset( new QgsProcessingParameterMeshLayer( name ) );
2218  else if ( type == QgsProcessingParameterLayout::typeName() )
2219  def.reset( new QgsProcessingParameterLayout( name ) );
2220  else if ( type == QgsProcessingParameterLayoutItem::typeName() )
2221  def.reset( new QgsProcessingParameterLayoutItem( name ) );
2222  else if ( type == QgsProcessingParameterColor::typeName() )
2223  def.reset( new QgsProcessingParameterColor( name ) );
2225  def.reset( new QgsProcessingParameterCoordinateOperation( name ) );
2226  else
2227  {
2229  if ( paramType )
2230  def.reset( paramType->create( name ) );
2231  }
2232 
2233  if ( !def )
2234  return nullptr;
2235 
2236  def->fromVariantMap( map );
2237  return def.release();
2238 }
2239 
2240 QString QgsProcessingParameters::descriptionFromName( const QString &name )
2241 {
2242  QString desc = name;
2243  desc.replace( '_', ' ' );
2244  return desc;
2245 }
2246 
2248 {
2249  bool isOptional = false;
2250  QString name;
2251  QString definition;
2252  QString type;
2253  if ( !parseScriptCodeParameterOptions( code, isOptional, name, type, definition ) )
2254  return nullptr;
2255 
2256  QString description = descriptionFromName( name );
2257 
2258  if ( type == QLatin1String( "boolean" ) )
2259  return QgsProcessingParameterBoolean::fromScriptCode( name, description, isOptional, definition );
2260  else if ( type == QLatin1String( "crs" ) )
2261  return QgsProcessingParameterCrs::fromScriptCode( name, description, isOptional, definition );
2262  else if ( type == QLatin1String( "layer" ) )
2263  return QgsProcessingParameterMapLayer::fromScriptCode( name, description, isOptional, definition );
2264  else if ( type == QLatin1String( "extent" ) )
2265  return QgsProcessingParameterExtent::fromScriptCode( name, description, isOptional, definition );
2266  else if ( type == QLatin1String( "point" ) )
2267  return QgsProcessingParameterPoint::fromScriptCode( name, description, isOptional, definition );
2268  else if ( type == QLatin1String( "geometry" ) )
2269  return QgsProcessingParameterGeometry::fromScriptCode( name, description, isOptional, definition );
2270  else if ( type == QLatin1String( "file" ) )
2271  return QgsProcessingParameterFile::fromScriptCode( name, description, isOptional, definition, QgsProcessingParameterFile::File );
2272  else if ( type == QLatin1String( "folder" ) )
2273  return QgsProcessingParameterFile::fromScriptCode( name, description, isOptional, definition, QgsProcessingParameterFile::Folder );
2274  else if ( type == QLatin1String( "matrix" ) )
2275  return QgsProcessingParameterMatrix::fromScriptCode( name, description, isOptional, definition );
2276  else if ( type == QLatin1String( "multiple" ) )
2277  return QgsProcessingParameterMultipleLayers::fromScriptCode( name, description, isOptional, definition );
2278  else if ( type == QLatin1String( "number" ) )
2279  return QgsProcessingParameterNumber::fromScriptCode( name, description, isOptional, definition );
2280  else if ( type == QLatin1String( "distance" ) )
2281  return QgsProcessingParameterDistance::fromScriptCode( name, description, isOptional, definition );
2282  else if ( type == QLatin1String( "scale" ) )
2283  return QgsProcessingParameterScale::fromScriptCode( name, description, isOptional, definition );
2284  else if ( type == QLatin1String( "range" ) )
2285  return QgsProcessingParameterRange::fromScriptCode( name, description, isOptional, definition );
2286  else if ( type == QLatin1String( "raster" ) )
2287  return QgsProcessingParameterRasterLayer::fromScriptCode( name, description, isOptional, definition );
2288  else if ( type == QLatin1String( "enum" ) )
2289  return QgsProcessingParameterEnum::fromScriptCode( name, description, isOptional, definition );
2290  else if ( type == QLatin1String( "string" ) )
2291  return QgsProcessingParameterString::fromScriptCode( name, description, isOptional, definition );
2292  else if ( type == QLatin1String( "authcfg" ) )
2293  return QgsProcessingParameterAuthConfig::fromScriptCode( name, description, isOptional, definition );
2294  else if ( type == QLatin1String( "expression" ) )
2295  return QgsProcessingParameterExpression::fromScriptCode( name, description, isOptional, definition );
2296  else if ( type == QLatin1String( "field" ) )
2297  return QgsProcessingParameterField::fromScriptCode( name, description, isOptional, definition );
2298  else if ( type == QLatin1String( "vector" ) )
2299  return QgsProcessingParameterVectorLayer::fromScriptCode( name, description, isOptional, definition );
2300  else if ( type == QLatin1String( "source" ) )
2301  return QgsProcessingParameterFeatureSource::fromScriptCode( name, description, isOptional, definition );
2302  else if ( type == QLatin1String( "sink" ) )
2303  return QgsProcessingParameterFeatureSink::fromScriptCode( name, description, isOptional, definition );
2304  else if ( type == QLatin1String( "vectordestination" ) )
2305  return QgsProcessingParameterVectorDestination::fromScriptCode( name, description, isOptional, definition );
2306  else if ( type == QLatin1String( "rasterdestination" ) )
2307  return QgsProcessingParameterRasterDestination::fromScriptCode( name, description, isOptional, definition );
2308  else if ( type == QLatin1String( "filedestination" ) )
2309  return QgsProcessingParameterFileDestination::fromScriptCode( name, description, isOptional, definition );
2310  else if ( type == QLatin1String( "folderdestination" ) )
2311  return QgsProcessingParameterFolderDestination::fromScriptCode( name, description, isOptional, definition );
2312  else if ( type == QLatin1String( "band" ) )
2313  return QgsProcessingParameterBand::fromScriptCode( name, description, isOptional, definition );
2314  else if ( type == QLatin1String( "mesh" ) )
2315  return QgsProcessingParameterMeshLayer::fromScriptCode( name, description, isOptional, definition );
2316  else if ( type == QLatin1String( "layout" ) )
2317  return QgsProcessingParameterLayout::fromScriptCode( name, description, isOptional, definition );
2318  else if ( type == QLatin1String( "layoutitem" ) )
2319  return QgsProcessingParameterLayoutItem::fromScriptCode( name, description, isOptional, definition );
2320  else if ( type == QLatin1String( "color" ) )
2321  return QgsProcessingParameterColor::fromScriptCode( name, description, isOptional, definition );
2322  else if ( type == QLatin1String( "coordinateoperation" ) )
2323  return QgsProcessingParameterCoordinateOperation::fromScriptCode( name, description, isOptional, definition );
2324  else if ( type == QLatin1String( "maptheme" ) )
2325  return QgsProcessingParameterMapTheme::fromScriptCode( name, description, isOptional, definition );
2326  else if ( type == QLatin1String( "datetime" ) )
2327  return QgsProcessingParameterDateTime::fromScriptCode( name, description, isOptional, definition );
2328  else if ( type == QLatin1String( "providerconnection" ) )
2329  return QgsProcessingParameterProviderConnection::fromScriptCode( name, description, isOptional, definition );
2330  else if ( type == QLatin1String( "databaseschema" ) )
2331  return QgsProcessingParameterDatabaseSchema::fromScriptCode( name, description, isOptional, definition );
2332  else if ( type == QLatin1String( "databasetable" ) )
2333  return QgsProcessingParameterDatabaseTable::fromScriptCode( name, description, isOptional, definition );
2334 
2335  return nullptr;
2336 }
2337 
2338 bool QgsProcessingParameters::parseScriptCodeParameterOptions( const QString &code, bool &isOptional, QString &name, QString &type, QString &definition )
2339 {
2340  QRegularExpression re( QStringLiteral( "(?:#*)(.*?)=\\s*(.*)" ) );
2341  QRegularExpressionMatch m = re.match( code );
2342  if ( !m.hasMatch() )
2343  return false;
2344 
2345  name = m.captured( 1 );
2346  QString tokens = m.captured( 2 );
2347  if ( tokens.startsWith( QLatin1String( "optional" ), Qt::CaseInsensitive ) )
2348  {
2349  isOptional = true;
2350  tokens.remove( 0, 8 ); // length "optional" = 8
2351  }
2352  else
2353  {
2354  isOptional = false;
2355  }
2356 
2357  tokens = tokens.trimmed();
2358 
2359  QRegularExpression re2( QStringLiteral( "(.*?)\\s+(.*)" ) );
2360  m = re2.match( tokens );
2361  if ( !m.hasMatch() )
2362  {
2363  type = tokens.toLower().trimmed();
2364  definition.clear();
2365  }
2366  else
2367  {
2368  type = m.captured( 1 ).toLower().trimmed();
2369  definition = m.captured( 2 );
2370  }
2371  return true;
2372 }
2373 
2374 //
2375 // QgsProcessingParameterDefinition
2376 //
2377 
2378 QgsProcessingParameterDefinition::QgsProcessingParameterDefinition( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, const QString &help )
2379  : mName( name )
2380  , mDescription( description )
2381  , mHelp( help )
2382  , mDefault( defaultValue )
2383  , mFlags( optional ? FlagOptional : 0 )
2384 {}
2385 
2387 {
2388  if ( !input.isValid() && !mDefault.isValid() )
2389  return mFlags & FlagOptional;
2390 
2391  if ( ( input.type() == QVariant::String && input.toString().isEmpty() )
2392  || ( !input.isValid() && mDefault.type() == QVariant::String && mDefault.toString().isEmpty() ) )
2393  return mFlags & FlagOptional;
2394 
2395  return true;
2396 }
2397 
2399 {
2400  if ( !value.isValid() )
2401  return QStringLiteral( "None" );
2402 
2403  if ( value.canConvert<QgsProperty>() )
2404  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
2405 
2406  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
2407 }
2408 
2410 {
2411  return QString();
2412 }
2413 
2415 {
2416  QString code = QStringLiteral( "##%1=" ).arg( mName );
2417  if ( mFlags & FlagOptional )
2418  code += QLatin1String( "optional " );
2419  code += type() + ' ';
2420  code += mDefault.toString();
2421  return code.trimmed();
2422 }
2423 
2425 {
2426  // base class method is probably not much use
2427  if ( QgsProcessingParameterType *t = QgsApplication::processingRegistry()->parameterType( type() ) )
2428  {
2429  switch ( outputType )
2430  {
2432  {
2433  QString code = t->className() + QStringLiteral( "('%1', '%2'" ).arg( name(), description() );
2434  if ( mFlags & FlagOptional )
2435  code += QLatin1String( ", optional=True" );
2436 
2438  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
2439  return code;
2440  }
2441  }
2442  }
2443 
2444  // oh well, we tried
2445  return QString();
2446 }
2447 
2449 {
2450  QVariantMap map;
2451  map.insert( QStringLiteral( "parameter_type" ), type() );
2452  map.insert( QStringLiteral( "name" ), mName );
2453  map.insert( QStringLiteral( "description" ), mDescription );
2454  map.insert( QStringLiteral( "help" ), mHelp );
2455  map.insert( QStringLiteral( "default" ), mDefault );
2456  map.insert( QStringLiteral( "defaultGui" ), mGuiDefault );
2457  map.insert( QStringLiteral( "flags" ), static_cast< int >( mFlags ) );
2458  map.insert( QStringLiteral( "metadata" ), mMetadata );
2459  return map;
2460 }
2461 
2463 {
2464  mName = map.value( QStringLiteral( "name" ) ).toString();
2465  mDescription = map.value( QStringLiteral( "description" ) ).toString();
2466  mHelp = map.value( QStringLiteral( "help" ) ).toString();
2467  mDefault = map.value( QStringLiteral( "default" ) );
2468  mGuiDefault = map.value( QStringLiteral( "defaultGui" ) );
2469  mFlags = static_cast< Flags >( map.value( QStringLiteral( "flags" ) ).toInt() );
2470  mMetadata = map.value( QStringLiteral( "metadata" ) ).toMap();
2471  return true;
2472 }
2473 
2475 {
2476  return mAlgorithm;
2477 }
2478 
2480 {
2481  return mAlgorithm ? mAlgorithm->provider() : nullptr;
2482 }
2483 
2485 {
2486  QString text = QStringLiteral( "<p><b>%1</b></p>" ).arg( description() );
2487  if ( !help().isEmpty() )
2488  {
2489  text += QStringLiteral( "<p>%1</p>" ).arg( help() );
2490  }
2491  text += QStringLiteral( "<p>%1</p>" ).arg( QObject::tr( "Python identifier: ‘%1’" ).arg( QStringLiteral( "<i>%1</i>" ).arg( name() ) ) );
2492  return text;
2493 }
2494 
2495 QgsProcessingParameterBoolean::QgsProcessingParameterBoolean( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
2496  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2497 {}
2498 
2500 {
2501  return new QgsProcessingParameterBoolean( *this );
2502 }
2503 
2505 {
2506  if ( !val.isValid() )
2507  return QStringLiteral( "None" );
2508 
2509  if ( val.canConvert<QgsProperty>() )
2510  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
2511  return val.toBool() ? QStringLiteral( "True" ) : QStringLiteral( "False" );
2512 }
2513 
2515 {
2516  QString code = QStringLiteral( "##%1=" ).arg( mName );
2517  if ( mFlags & FlagOptional )
2518  code += QLatin1String( "optional " );
2519  code += type() + ' ';
2520  code += mDefault.toBool() ? QStringLiteral( "true" ) : QStringLiteral( "false" );
2521  return code.trimmed();
2522 }
2523 
2524 QgsProcessingParameterBoolean *QgsProcessingParameterBoolean::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
2525 {
2526  return new QgsProcessingParameterBoolean( name, description, definition.toLower().trimmed() != QStringLiteral( "false" ), isOptional );
2527 }
2528 
2529 QgsProcessingParameterCrs::QgsProcessingParameterCrs( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
2530  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2531 {
2532 
2533 }
2534 
2536 {
2537  return new QgsProcessingParameterCrs( *this );
2538 }
2539 
2541 {
2542  if ( !input.isValid() )
2543  return mFlags & FlagOptional;
2544 
2545  if ( input.canConvert<QgsCoordinateReferenceSystem>() )
2546  {
2547  return true;
2548  }
2549  else if ( input.canConvert<QgsProcessingFeatureSourceDefinition>() )
2550  {
2551  return true;
2552  }
2553  else if ( input.canConvert<QgsProcessingOutputLayerDefinition>() )
2554  {
2555  return true;
2556  }
2557 
2558  if ( input.canConvert<QgsProperty>() )
2559  {
2560  return true;
2561  }
2562 
2563  // direct map layer value
2564  if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
2565  return true;
2566 
2567  if ( input.type() != QVariant::String || input.toString().isEmpty() )
2568  return mFlags & FlagOptional;
2569 
2570  return true;
2571 }
2572 
2573 QString QgsProcessingParameterCrs::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
2574 {
2575  if ( !value.isValid() )
2576  return QStringLiteral( "None" );
2577 
2578  if ( value.canConvert<QgsCoordinateReferenceSystem>() )
2579  {
2580  if ( !value.value< QgsCoordinateReferenceSystem >().isValid() )
2581  return QStringLiteral( "QgsCoordinateReferenceSystem()" );
2582  else
2583  return QStringLiteral( "QgsCoordinateReferenceSystem('%1')" ).arg( value.value< QgsCoordinateReferenceSystem >().authid() );
2584  }
2585 
2586  if ( value.canConvert<QgsProperty>() )
2587  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
2588 
2589  QVariantMap p;
2590  p.insert( name(), value );
2591  QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
2592  if ( layer )
2594 
2596 }
2597 
2598 QgsProcessingParameterCrs *QgsProcessingParameterCrs::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
2599 {
2600  return new QgsProcessingParameterCrs( name, description, definition.compare( QLatin1String( "none" ), Qt::CaseInsensitive ) == 0 ? QVariant() : definition, isOptional );
2601 }
2602 
2603 QgsProcessingParameterMapLayer::QgsProcessingParameterMapLayer( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, const QList<int> &types )
2604  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2606 {
2607 
2608 }
2609 
2611 {
2612  return new QgsProcessingParameterMapLayer( *this );
2613 }
2614 
2616 {
2617  if ( !input.isValid() )
2618  return mFlags & FlagOptional;
2619 
2620  if ( input.canConvert<QgsProperty>() )
2621  {
2622  return true;
2623  }
2624 
2625  if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
2626  {
2627  return true;
2628  }
2629 
2630  if ( input.type() != QVariant::String || input.toString().isEmpty() )
2631  return mFlags & FlagOptional;
2632 
2633  if ( !context )
2634  {
2635  // that's as far as we can get without a context
2636  return true;
2637  }
2638 
2639  // try to load as layer
2640  if ( QgsProcessingUtils::mapLayerFromString( input.toString(), *context ) )
2641  return true;
2642 
2643  return false;
2644 }
2645 
2647 {
2648  if ( !val.isValid() )
2649  return QStringLiteral( "None" );
2650 
2651  if ( val.canConvert<QgsProperty>() )
2652  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
2653 
2654  QVariantMap p;
2655  p.insert( name(), val );
2656  QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
2658  : QgsProcessingUtils::stringToPythonLiteral( val.toString() );
2659 }
2660 
2662 {
2663  QStringList vectors = QgsProviderRegistry::instance()->fileVectorFilters().split( QStringLiteral( ";;" ) );
2664  QStringList rasters = QgsProviderRegistry::instance()->fileRasterFilters().split( QStringLiteral( ";;" ) );
2665  for ( const QString &raster : rasters )
2666  {
2667  if ( !vectors.contains( raster ) )
2668  vectors << raster;
2669  }
2670  QStringList meshFilters = QgsProviderRegistry::instance()->fileMeshFilters().split( QStringLiteral( ";;" ) );
2671  for ( const QString &mesh : meshFilters )
2672  {
2673  if ( !vectors.contains( mesh ) )
2674  vectors << mesh;
2675  }
2676  vectors.removeAll( QObject::tr( "All files (*.*)" ) );
2677  std::sort( vectors.begin(), vectors.end() );
2678 
2679  return QObject::tr( "All files (*.*)" ) + QStringLiteral( ";;" ) + vectors.join( QLatin1String( ";;" ) );
2680 }
2681 
2683 {
2684  return createAllMapLayerFileFilter();
2685 }
2686 
2688 {
2689  QString code = QStringLiteral( "##%1=" ).arg( mName );
2690  if ( mFlags & FlagOptional )
2691  code += QLatin1String( "optional " );
2692  code += QLatin1String( "layer " );
2693 
2694  for ( int type : mDataTypes )
2695  {
2696  switch ( type )
2697  {
2699  code += QLatin1String( "hasgeometry " );
2700  break;
2701 
2703  code += QLatin1String( "point " );
2704  break;
2705 
2707  code += QLatin1String( "line " );
2708  break;
2709 
2711  code += QLatin1String( "polygon " );
2712  break;
2713 
2715  code += QLatin1String( "raster " );
2716  break;
2717 
2719  code += QLatin1String( "mesh " );
2720  break;
2721  }
2722  }
2723 
2724  code += mDefault.toString();
2725  return code.trimmed();
2726 }
2727 
2728 QgsProcessingParameterMapLayer *QgsProcessingParameterMapLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
2729 {
2730  QList< int > types;
2731  QString def = definition;
2732  while ( true )
2733  {
2734  if ( def.startsWith( QLatin1String( "hasgeometry" ), Qt::CaseInsensitive ) )
2735  {
2737  def = def.mid( 12 );
2738  continue;
2739  }
2740  else if ( def.startsWith( QLatin1String( "point" ), Qt::CaseInsensitive ) )
2741  {
2743  def = def.mid( 6 );
2744  continue;
2745  }
2746  else if ( def.startsWith( QLatin1String( "line" ), Qt::CaseInsensitive ) )
2747  {
2749  def = def.mid( 5 );
2750  continue;
2751  }
2752  else if ( def.startsWith( QLatin1String( "polygon" ), Qt::CaseInsensitive ) )
2753  {
2755  def = def.mid( 8 );
2756  continue;
2757  }
2758  else if ( def.startsWith( QLatin1String( "raster" ), Qt::CaseInsensitive ) )
2759  {
2760  types << QgsProcessing::TypeRaster;
2761  def = def.mid( 7 );
2762  continue;
2763  }
2764  else if ( def.startsWith( QLatin1String( "mesh" ), Qt::CaseInsensitive ) )
2765  {
2766  types << QgsProcessing::TypeMesh;
2767  def = def.mid( 5 );
2768  continue;
2769  }
2770  break;
2771  }
2772 
2773  return new QgsProcessingParameterMapLayer( name, description, def, isOptional, types );
2774 }
2775 
2777 {
2778  switch ( outputType )
2779  {
2781  {
2782  QString code = QStringLiteral( "QgsProcessingParameterMapLayer('%1', '%2'" ).arg( name(), description() );
2783  if ( mFlags & FlagOptional )
2784  code += QLatin1String( ", optional=True" );
2785 
2787  code += QStringLiteral( ", defaultValue=%1" ).arg( valueAsPythonString( mDefault, c ) );
2788 
2789  if ( !mDataTypes.empty() )
2790  {
2791  QStringList options;
2792  options.reserve( mDataTypes.size() );
2793  for ( int t : mDataTypes )
2794  options << QStringLiteral( "QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( static_cast< QgsProcessing::SourceType >( t ) ) );
2795  code += QStringLiteral( ", types=[%1])" ).arg( options.join( ',' ) );
2796  }
2797  else
2798  {
2799  code += QLatin1Char( ')' );
2800  }
2801 
2802  return code;
2803  }
2804  }
2805  return QString();
2806 }
2807 
2809 {
2811  QVariantList types;
2812  for ( int type : mDataTypes )
2813  {
2814  types << type;
2815  }
2816  map.insert( QStringLiteral( "data_types" ), types );
2817  return map;
2818 }
2819 
2821 {
2823  mDataTypes.clear();
2824  const QVariantList values = map.value( QStringLiteral( "data_types" ) ).toList();
2825  for ( const QVariant &val : values )
2826  {
2827  mDataTypes << val.toInt();
2828  }
2829  return true;
2830 }
2831 
2832 QgsProcessingParameterExtent::QgsProcessingParameterExtent( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
2833  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2834 {
2835 
2836 }
2837 
2839 {
2840  return new QgsProcessingParameterExtent( *this );
2841 }
2842 
2844 {
2845  if ( !input.isValid() )
2846  return mFlags & FlagOptional;
2847 
2848  if ( input.canConvert<QgsProcessingFeatureSourceDefinition>() )
2849  {
2850  return true;
2851  }
2852  else if ( input.canConvert<QgsProcessingOutputLayerDefinition>() )
2853  {
2854  return true;
2855  }
2856 
2857  if ( input.canConvert<QgsProperty>() )
2858  {
2859  return true;
2860  }
2861 
2862  if ( input.canConvert< QgsRectangle >() )
2863  {
2864  QgsRectangle r = input.value<QgsRectangle>();
2865  return !r.isNull();
2866  }
2867  if ( input.canConvert< QgsGeometry >() )
2868  {
2869  return true;
2870  }
2871  if ( input.canConvert< QgsReferencedRectangle >() )
2872  {
2874  return !r.isNull();
2875  }
2876 
2877  // direct map layer value
2878  if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
2879  return true;
2880 
2881  if ( input.type() != QVariant::String || input.toString().isEmpty() )
2882  return mFlags & FlagOptional;
2883 
2884  if ( !context )
2885  {
2886  // that's as far as we can get without a context
2887  return true;
2888  }
2889 
2890  QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?)\\s*,\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
2891  QRegularExpressionMatch match = rx.match( input.toString() );
2892  if ( match.hasMatch() )
2893  {
2894  bool xMinOk = false;
2895  ( void )match.captured( 1 ).toDouble( &xMinOk );
2896  bool xMaxOk = false;
2897  ( void )match.captured( 2 ).toDouble( &xMaxOk );
2898  bool yMinOk = false;
2899  ( void )match.captured( 3 ).toDouble( &yMinOk );
2900  bool yMaxOk = false;
2901  ( void )match.captured( 4 ).toDouble( &yMaxOk );
2902  if ( xMinOk && xMaxOk && yMinOk && yMaxOk )
2903  return true;
2904  }
2905 
2906  // try as layer extent
2907  return QgsProcessingUtils::mapLayerFromString( input.toString(), *context );
2908 }
2909 
2910 QString QgsProcessingParameterExtent::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
2911 {
2912  if ( !value.isValid() )
2913  return QStringLiteral( "None" );
2914 
2915  if ( value.canConvert<QgsProperty>() )
2916  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
2917 
2918  if ( value.canConvert< QgsRectangle >() )
2919  {
2920  QgsRectangle r = value.value<QgsRectangle>();
2921  return QStringLiteral( "'%1, %3, %2, %4'" ).arg( qgsDoubleToString( r.xMinimum() ),
2922  qgsDoubleToString( r.yMinimum() ),
2923  qgsDoubleToString( r.xMaximum() ),
2924  qgsDoubleToString( r.yMaximum() ) );
2925  }
2926  else if ( value.canConvert< QgsReferencedRectangle >() )
2927  {
2929  return QStringLiteral( "'%1, %3, %2, %4 [%5]'" ).arg( qgsDoubleToString( r.xMinimum() ),
2930  qgsDoubleToString( r.yMinimum() ),
2931  qgsDoubleToString( r.xMaximum() ),
2932  qgsDoubleToString( r.yMaximum() ), r.crs().authid() );
2933  }
2934  else if ( value.canConvert< QgsGeometry >() )
2935  {
2936  const QgsGeometry g = value.value<QgsGeometry>();
2937  if ( !g.isNull() )
2938  {
2939  const QString wkt = g.asWkt();
2940  return QStringLiteral( "QgsGeometry.fromWkt('%1')" ).arg( wkt );
2941  }
2942  }
2943 
2944  QVariantMap p;
2945  p.insert( name(), value );
2946  QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
2947  if ( layer )
2949 
2951 }
2952 
2953 QgsProcessingParameterExtent *QgsProcessingParameterExtent::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
2954 {
2955  return new QgsProcessingParameterExtent( name, description, definition, isOptional );
2956 }
2957 
2958 QgsProcessingParameterPoint::QgsProcessingParameterPoint( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
2959  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2960 {
2961 
2962 }
2963 
2965 {
2966  return new QgsProcessingParameterPoint( *this );
2967 }
2968 
2970 {
2971  if ( !input.isValid() )
2972  return mFlags & FlagOptional;
2973 
2974  if ( input.canConvert<QgsProperty>() )
2975  {
2976  return true;
2977  }
2978 
2979  if ( input.canConvert< QgsPointXY >() )
2980  {
2981  return true;
2982  }
2983  if ( input.canConvert< QgsReferencedPointXY >() )
2984  {
2985  return true;
2986  }
2987  if ( input.canConvert< QgsGeometry >() )
2988  {
2989  return true;
2990  }
2991 
2992  if ( input.type() == QVariant::String )
2993  {
2994  if ( input.toString().isEmpty() )
2995  return mFlags & FlagOptional;
2996  }
2997 
2998  QRegularExpression rx( QStringLiteral( "^\\s*\\(?\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*\\)?\\s*$" ) );
2999 
3000  QRegularExpressionMatch match = rx.match( input.toString() );
3001  if ( match.hasMatch() )
3002  {
3003  bool xOk = false;
3004  ( void )match.captured( 1 ).toDouble( &xOk );
3005  bool yOk = false;
3006  ( void )match.captured( 2 ).toDouble( &yOk );
3007  return xOk && yOk;
3008  }
3009  else
3010  return false;
3011 }
3012 
3013 QString QgsProcessingParameterPoint::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
3014 {
3015  if ( !value.isValid() )
3016  return QStringLiteral( "None" );
3017 
3018  if ( value.canConvert<QgsProperty>() )
3019  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
3020 
3021  if ( value.canConvert< QgsPointXY >() )
3022  {
3023  QgsPointXY r = value.value<QgsPointXY>();
3024  return QStringLiteral( "'%1,%2'" ).arg( qgsDoubleToString( r.x() ),
3025  qgsDoubleToString( r.y() ) );
3026  }
3027  else if ( value.canConvert< QgsReferencedPointXY >() )
3028  {
3029  QgsReferencedPointXY r = value.value<QgsReferencedPointXY>();
3030  return QStringLiteral( "'%1,%2 [%3]'" ).arg( qgsDoubleToString( r.x() ),
3031  qgsDoubleToString( r.y() ),
3032  r.crs().authid() );
3033  }
3034  else if ( value.canConvert< QgsGeometry >() )
3035  {
3036  const QgsGeometry g = value.value<QgsGeometry>();
3037  if ( !g.isNull() )
3038  {
3039  const QString wkt = g.asWkt();
3040  return QStringLiteral( "QgsGeometry.fromWkt('%1')" ).arg( wkt );
3041  }
3042  }
3043 
3045 }
3046 
3047 QgsProcessingParameterPoint *QgsProcessingParameterPoint::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3048 {
3049  return new QgsProcessingParameterPoint( name, description, definition, isOptional );
3050 }
3051 
3052 QgsProcessingParameterGeometry::QgsProcessingParameterGeometry( const QString &name, const QString &description,
3053  const QVariant &defaultValue, bool optional, const QList<int> &geometryTypes, bool allowMultipart )
3054  : QgsProcessingParameterDefinition( name, description, defaultValue, optional ),
3055  mGeomTypes( geometryTypes ),
3056  mAllowMultipart( allowMultipart )
3057 {
3058 
3059 }
3060 
3062 {
3063  return new QgsProcessingParameterGeometry( *this );
3064 }
3065 
3067 {
3068  if ( !input.isValid() )
3069  return mFlags & FlagOptional;
3070 
3071  if ( input.canConvert<QgsProperty>() )
3072  {
3073  return true;
3074  }
3075 
3076  bool anyTypeAllowed = mGeomTypes.isEmpty() || mGeomTypes.contains( QgsWkbTypes::UnknownGeometry );
3077 
3078  if ( input.canConvert< QgsGeometry >() )
3079  {
3080  return ( anyTypeAllowed || mGeomTypes.contains( input.value<QgsGeometry>().type() ) ) &&
3081  ( mAllowMultipart || !input.value<QgsGeometry>().isMultipart() );
3082  }
3083 
3084  if ( input.canConvert< QgsReferencedGeometry >() )
3085  {
3086  return ( anyTypeAllowed || mGeomTypes.contains( input.value<QgsReferencedGeometry>().type() ) ) &&
3087  ( mAllowMultipart || !input.value<QgsReferencedGeometry>().isMultipart() );
3088  }
3089 
3090  if ( input.canConvert< QgsPointXY >() )
3091  {
3092  return anyTypeAllowed || mGeomTypes.contains( QgsWkbTypes::PointGeometry );
3093  }
3094 
3095  if ( input.canConvert< QgsRectangle >() )
3096  {
3097  return anyTypeAllowed || mGeomTypes.contains( QgsWkbTypes::PolygonGeometry );
3098  }
3099 
3100  if ( input.canConvert< QgsReferencedPointXY >() )
3101  {
3102  return anyTypeAllowed || mGeomTypes.contains( QgsWkbTypes::PointGeometry );
3103  }
3104 
3105  if ( input.canConvert< QgsReferencedRectangle >() )
3106  {
3107  return anyTypeAllowed || mGeomTypes.contains( QgsWkbTypes::PolygonGeometry );
3108  }
3109 
3110  if ( input.type() == QVariant::String )
3111  {
3112  if ( input.toString().isEmpty() )
3113  return mFlags & FlagOptional;
3114  }
3115 
3116  // Match against EWKT
3117  QRegularExpression rx( QStringLiteral( "^\\s*(?:CRS=(.*);)?(.*?)$" ) );
3118 
3119  QRegularExpressionMatch match = rx.match( input.toString() );
3120  if ( match.hasMatch() )
3121  {
3122  QgsGeometry g = QgsGeometry::fromWkt( match.captured( 2 ) );
3123  if ( ! g.isNull() )
3124  {
3125  return ( anyTypeAllowed || mGeomTypes.contains( g.type() ) ) && ( mAllowMultipart || !g.isMultipart() );
3126  }
3127  else
3128  {
3129  QgsMessageLog::logMessage( QObject::tr( "Error creating geometry: \"%1\"" ).arg( g.lastError() ), QObject::tr( "Processing" ) );
3130  }
3131  }
3132  return false;
3133 }
3134 
3135 QString QgsProcessingParameterGeometry::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
3136 {
3138  {
3139  if ( !crs.isValid() )
3141  else
3142  return QgsProcessingUtils::stringToPythonLiteral( QStringLiteral( "CRS=%1;%2" ).arg( crs.authid().isEmpty() ? crs.toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ) : crs.authid(), g.asWkt() ) );
3143  };
3144 
3145  if ( !value.isValid() )
3146  return QStringLiteral( "None" );
3147 
3148  if ( value.canConvert<QgsProperty>() )
3149  return QStringLiteral( "QgsProperty.fromExpression(%1)" ).arg( QgsProcessingUtils::stringToPythonLiteral( value.value< QgsProperty >().asExpression() ) );
3150 
3151  if ( value.canConvert< QgsGeometry >() )
3152  {
3153  const QgsGeometry g = value.value<QgsGeometry>();
3154  if ( !g.isNull() )
3155  return asPythonString( g );
3156  }
3157 
3158  if ( value.canConvert< QgsReferencedGeometry >() )
3159  {
3160  const QgsReferencedGeometry g = value.value<QgsReferencedGeometry>();
3161  if ( !g.isNull() )
3162  return asPythonString( g, g.crs() );
3163  }
3164 
3165  if ( value.canConvert< QgsPointXY >() )
3166  {
3167  const QgsGeometry g = QgsGeometry::fromPointXY( value.value<QgsPointXY>() );
3168  if ( !g.isNull() )
3169  return asPythonString( g );
3170  }
3171 
3172  if ( value.canConvert< QgsReferencedPointXY >() )
3173  {
3175  if ( !g.isNull() )
3176  return asPythonString( g, g.crs() );
3177  }
3178 
3179  if ( value.canConvert< QgsRectangle >() )
3180  {
3181  const QgsGeometry g = QgsGeometry::fromRect( value.value<QgsRectangle>() );
3182  if ( !g.isNull() )
3183  return asPythonString( g );
3184  }
3185 
3186  if ( value.canConvert< QgsReferencedRectangle >() )
3187  {
3189  if ( !g.isNull() )
3190  return asPythonString( g, g.crs() );
3191  }
3192 
3194 }
3195 
3197 {
3198  QString code = QStringLiteral( "##%1=" ).arg( mName );
3199  if ( mFlags & FlagOptional )
3200  code += QLatin1String( "optional " );
3201  code += type() + ' ';
3202 
3203  for ( int type : mGeomTypes )
3204  {
3205  switch ( static_cast<QgsWkbTypes::GeometryType>( type ) )
3206  {
3208  code += QLatin1String( "point " );
3209  break;
3210 
3212  code += QLatin1String( "line " );
3213  break;
3214 
3216  code += QLatin1String( "polygon " );
3217  break;
3218 
3219  default:
3220  code += QLatin1String( "unknown " );
3221  break;
3222  }
3223  }
3224 
3225  code += mDefault.toString();
3226  return code.trimmed();
3227 }
3228 
3230 {
3231  switch ( outputType )
3232  {
3234  {
3235  QString code = QStringLiteral( "QgsProcessingParameterGeometry('%1', '%2'" ).arg( name(), description() );
3236  if ( mFlags & FlagOptional )
3237  code += QLatin1String( ", optional=True" );
3238 
3239  if ( !mGeomTypes.empty() )
3240  {
3241  auto geomTypeToString = []( QgsWkbTypes::GeometryType t ) -> QString
3242  {
3243  switch ( t )
3244  {
3246  return QStringLiteral( "PointGeometry" );
3247 
3249  return QStringLiteral( "LineGeometry" );
3250 
3252  return QStringLiteral( "PolygonGeometry" );
3253 
3255  return QStringLiteral( "UnknownGeometry" );
3256 
3258  return QStringLiteral( "NullGeometry" );
3259  }
3260  return QString();
3261  };
3262 
3263  QStringList options;
3264  options.reserve( mGeomTypes.size() );
3265  for ( int type : mGeomTypes )
3266  {
3267  options << QStringLiteral( " QgsWkbTypes.%1" ).arg( geomTypeToString( static_cast<QgsWkbTypes::GeometryType>( type ) ) );
3268  }
3269  code += QStringLiteral( ", geometryTypes=[%1 ]" ).arg( options.join( ',' ) );
3270  }
3271 
3272  if ( ! mAllowMultipart )
3273  {
3274  code += QLatin1String( ", allowMultipart=False" );
3275  }
3276 
3278  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
3279  return code;
3280  }
3281  }
3282  return QString();
3283 }
3284 
3286 {
3288  QVariantList types;
3289  for ( int type : mGeomTypes )
3290  {
3291  types << type;
3292  }
3293  map.insert( QStringLiteral( "geometrytypes" ), types );
3294  map.insert( QStringLiteral( "multipart" ), mAllowMultipart );
3295  return map;
3296 }
3297 
3299 {
3301  mGeomTypes.clear();
3302  const QVariantList values = map.value( QStringLiteral( "geometrytypes" ) ).toList();
3303  for ( const QVariant &val : values )
3304  {
3305  mGeomTypes << val.toInt();
3306  }
3307  mAllowMultipart = map.value( QStringLiteral( "multipart" ) ).toBool();
3308  return true;
3309 }
3310 
3311 QgsProcessingParameterGeometry *QgsProcessingParameterGeometry::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3312 {
3313  return new QgsProcessingParameterGeometry( name, description, definition, isOptional );
3314 }
3315 
3316 QgsProcessingParameterFile::QgsProcessingParameterFile( const QString &name, const QString &description, Behavior behavior, const QString &extension, const QVariant &defaultValue, bool optional, const QString &fileFilter )
3317  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3318  , mBehavior( behavior )
3319  , mExtension( fileFilter.isEmpty() ? extension : QString() )
3320  , mFileFilter( fileFilter.isEmpty() && extension.isEmpty() ? QObject::tr( "All files (*.*)" ) : fileFilter )
3321 {
3322 
3323 }
3324 
3326 {
3327  return new QgsProcessingParameterFile( *this );
3328 }
3329 
3331 {
3332  if ( !input.isValid() )
3333  return mFlags & FlagOptional;
3334 
3335  if ( input.canConvert<QgsProperty>() )
3336  {
3337  return true;
3338  }
3339 
3340  QString string = input.toString().trimmed();
3341 
3342  if ( input.type() != QVariant::String || string.isEmpty() )
3343  return mFlags & FlagOptional;
3344 
3345  switch ( mBehavior )
3346  {
3347  case File:
3348  {
3349  if ( !mExtension.isEmpty() )
3350  {
3351  return string.endsWith( mExtension, Qt::CaseInsensitive );
3352  }
3353  else if ( !mFileFilter.isEmpty() )
3354  {
3355  const QString test = QgsFileUtils::addExtensionFromFilter( string, mFileFilter );
3356  return test == string;
3357  }
3358  else
3359  {
3360  return true;
3361  }
3362  }
3363 
3364  case Folder:
3365  return true;
3366  }
3367  return true;
3368 }
3369 
3371 {
3372  QString code = QStringLiteral( "##%1=" ).arg( mName );
3373  if ( mFlags & FlagOptional )
3374  code += QLatin1String( "optional " );
3375  code += ( mBehavior == File ? QStringLiteral( "file" ) : QStringLiteral( "folder" ) ) + ' ';
3376  code += mDefault.toString();
3377  return code.trimmed();
3378 }
3379 
3381 {
3382  switch ( outputType )
3383  {
3385  {
3386 
3387  QString code = QStringLiteral( "QgsProcessingParameterFile('%1', '%2'" ).arg( name(), description() );
3388  if ( mFlags & FlagOptional )
3389  code += QLatin1String( ", optional=True" );
3390  code += QStringLiteral( ", behavior=%1" ).arg( mBehavior == File ? QStringLiteral( "QgsProcessingParameterFile.File" ) : QStringLiteral( "QgsProcessingParameterFile.Folder" ) );
3391  if ( !mExtension.isEmpty() )
3392  code += QStringLiteral( ", extension='%1'" ).arg( mExtension );
3393  if ( !mFileFilter.isEmpty() )
3394  code += QStringLiteral( ", fileFilter='%1'" ).arg( mFileFilter );
3396  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
3397  return code;
3398  }
3399  }
3400  return QString();
3401 }
3402 
3404 {
3405  switch ( mBehavior )
3406  {
3407  case File:
3408  {
3409  if ( !mFileFilter.isEmpty() )
3410  return mFileFilter != QObject::tr( "All files (*.*)" ) ? mFileFilter + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" ) : mFileFilter;
3411  else if ( !mExtension.isEmpty() )
3412  return QObject::tr( "%1 files" ).arg( mExtension.toUpper() ) + QStringLiteral( " (*." ) + mExtension.toLower() + QStringLiteral( ");;" ) + QObject::tr( "All files (*.*)" );
3413  else
3414  return QObject::tr( "All files (*.*)" );
3415  }
3416 
3417  case Folder:
3418  return QString();
3419  }
3420  return QString();
3421 }
3422 
3423 void QgsProcessingParameterFile::setExtension( const QString &extension )
3424 {
3425  mExtension = extension;
3426  mFileFilter.clear();
3427 }
3428 
3430 {
3431  return mFileFilter;
3432 }
3433 
3434 void QgsProcessingParameterFile::setFileFilter( const QString &filter )
3435 {
3436  mFileFilter = filter;
3437  mExtension.clear();
3438 }
3439 
3441 {
3443  map.insert( QStringLiteral( "behavior" ), mBehavior );
3444  map.insert( QStringLiteral( "extension" ), mExtension );
3445  map.insert( QStringLiteral( "filefilter" ), mFileFilter );
3446  return map;
3447 }
3448 
3449 bool QgsProcessingParameterFile::fromVariantMap( const QVariantMap &map )
3450 {
3452  mBehavior = static_cast< Behavior >( map.value( QStringLiteral( "behavior" ) ).toInt() );
3453  mExtension = map.value( QStringLiteral( "extension" ) ).toString();
3454  mFileFilter = map.value( QStringLiteral( "filefilter" ) ).toString();
3455  return true;
3456 }
3457 
3458 QgsProcessingParameterFile *QgsProcessingParameterFile::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition, QgsProcessingParameterFile::Behavior behavior )
3459 {
3460  return new QgsProcessingParameterFile( name, description, behavior, QString(), definition, isOptional );
3461 }
3462 
3463 QgsProcessingParameterMatrix::QgsProcessingParameterMatrix( const QString &name, const QString &description, int numberRows, bool fixedNumberRows, const QStringList &headers, const QVariant &defaultValue, bool optional )
3464  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3465  , mHeaders( headers )
3466  , mNumberRows( numberRows )
3467  , mFixedNumberRows( fixedNumberRows )
3468 {
3469 
3470 }
3471 
3473 {
3474  return new QgsProcessingParameterMatrix( *this );
3475 }
3476 
3478 {
3479  if ( !input.isValid() )
3480  return mFlags & FlagOptional;
3481 
3482  if ( input.type() == QVariant::String )
3483  {
3484  if ( input.toString().isEmpty() )
3485  return mFlags & FlagOptional;
3486  return true;
3487  }
3488  else if ( input.type() == QVariant::List )
3489  {
3490  if ( input.toList().isEmpty() )
3491  return mFlags & FlagOptional;
3492  return true;
3493  }
3494  else if ( input.type() == QVariant::Double || input.type() == QVariant::Int )
3495  {
3496  return true;
3497  }
3498 
3499  return false;
3500 }
3501 
3502 QString QgsProcessingParameterMatrix::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
3503 {
3504  if ( !value.isValid() )
3505  return QStringLiteral( "None" );
3506 
3507  if ( value.canConvert<QgsProperty>() )
3508  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
3509 
3510  QVariantMap p;
3511  p.insert( name(), value );
3512  QVariantList list = QgsProcessingParameters::parameterAsMatrix( this, p, context );
3513 
3514  QStringList parts;
3515  const auto constList = list;
3516  for ( const QVariant &v : constList )
3517  {
3518  if ( v.type() == QVariant::List )
3519  {
3520  QStringList parts2;
3521  const auto constToList = v.toList();
3522  for ( const QVariant &v2 : constToList )
3523  {
3524  if ( v2.isNull() || !v2.isValid() )
3525  parts2 << QStringLiteral( "None" );
3526  else if ( v2.toString().isEmpty() )
3527  parts2 << QStringLiteral( "''" );
3528  else
3529  parts2 << v2.toString();
3530  }
3531  parts << parts2.join( ',' ).prepend( '[' ).append( ']' );
3532  }
3533  else
3534  {
3535  if ( v.isNull() || !v.isValid() )
3536  parts << QStringLiteral( "None" );
3537  else if ( v.toString().isEmpty() )
3538  parts << QStringLiteral( "''" );
3539  else
3540  parts << v.toString();
3541  }
3542  }
3543 
3544  return parts.join( ',' ).prepend( '[' ).append( ']' );
3545 }
3546 
3548 {
3549  switch ( outputType )
3550  {
3552  {
3553  QString code = QStringLiteral( "QgsProcessingParameterMatrix('%1', '%2'" ).arg( name(), description() );
3554  if ( mFlags & FlagOptional )
3555  code += QLatin1String( ", optional=True" );
3556  code += QStringLiteral( ", numberRows=" ).arg( mNumberRows );
3557  code += QStringLiteral( ", hasFixedNumberRows=" ).arg( mFixedNumberRows ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
3558 
3559  QStringList headers;
3560  headers.reserve( mHeaders.size() );
3561  for ( const QString &h : mHeaders )
3563  code += QStringLiteral( ", headers=[%1]" ).arg( headers.join( ',' ) );
3564 
3566  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
3567  return code;
3568  }
3569  }
3570  return QString();
3571 }
3572 
3574 {
3575  return mHeaders;
3576 }
3577 
3578 void QgsProcessingParameterMatrix::setHeaders( const QStringList &headers )
3579 {
3580  mHeaders = headers;
3581 }
3582 
3584 {
3585  return mNumberRows;
3586 }
3587 
3589 {
3590  mNumberRows = numberRows;
3591 }
3592 
3594 {
3595  return mFixedNumberRows;
3596 }
3597 
3599 {
3600  mFixedNumberRows = fixedNumberRows;
3601 }
3602 
3604 {
3606  map.insert( QStringLiteral( "headers" ), mHeaders );
3607  map.insert( QStringLiteral( "rows" ), mNumberRows );
3608  map.insert( QStringLiteral( "fixed_number_rows" ), mFixedNumberRows );
3609  return map;
3610 }
3611 
3612 bool QgsProcessingParameterMatrix::fromVariantMap( const QVariantMap &map )
3613 {
3615  mHeaders = map.value( QStringLiteral( "headers" ) ).toStringList();
3616  mNumberRows = map.value( QStringLiteral( "rows" ) ).toInt();
3617  mFixedNumberRows = map.value( QStringLiteral( "fixed_number_rows" ) ).toBool();
3618  return true;
3619 }
3620 
3621 QgsProcessingParameterMatrix *QgsProcessingParameterMatrix::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3622 {
3623  return new QgsProcessingParameterMatrix( name, description, 0, false, QStringList(), definition.isEmpty() ? QVariant() : definition, isOptional );
3624 }
3625 
3626 QgsProcessingParameterMultipleLayers::QgsProcessingParameterMultipleLayers( const QString &name, const QString &description, QgsProcessing::SourceType layerType, const QVariant &defaultValue, bool optional )
3627  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3628  , mLayerType( layerType )
3629 {
3630 
3631 }
3632 
3634 {
3635  return new QgsProcessingParameterMultipleLayers( *this );
3636 }
3637 
3639 {
3640  if ( !input.isValid() )
3641  return mFlags & FlagOptional;
3642 
3643  if ( mLayerType != QgsProcessing::TypeFile )
3644  {
3645  if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
3646  {
3647  return true;
3648  }
3649  }
3650 
3651  if ( input.type() == QVariant::String )
3652  {
3653  if ( input.toString().isEmpty() )
3654  return mFlags & FlagOptional;
3655 
3656  if ( mMinimumNumberInputs > 1 )
3657  return false;
3658 
3659  if ( !context )
3660  return true;
3661 
3662  if ( mLayerType != QgsProcessing::TypeFile )
3663  return QgsProcessingUtils::mapLayerFromString( input.toString(), *context );
3664  else
3665  return true;
3666  }
3667  else if ( input.type() == QVariant::List )
3668  {
3669  if ( input.toList().count() < mMinimumNumberInputs )
3670  return mFlags & FlagOptional;
3671 
3672  if ( mMinimumNumberInputs > input.toList().count() )
3673  return false;
3674 
3675  if ( !context )
3676  return true;
3677 
3678  if ( mLayerType != QgsProcessing::TypeFile )
3679  {
3680  const auto constToList = input.toList();
3681  for ( const QVariant &v : constToList )
3682  {
3683  if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( v ) ) )
3684  continue;
3685 
3686  if ( !QgsProcessingUtils::mapLayerFromString( v.toString(), *context ) )
3687  return false;
3688  }
3689  }
3690  return true;
3691  }
3692  else if ( input.type() == QVariant::StringList )
3693  {
3694  if ( input.toStringList().count() < mMinimumNumberInputs )
3695  return mFlags & FlagOptional;
3696 
3697  if ( mMinimumNumberInputs > input.toStringList().count() )
3698  return false;
3699 
3700  if ( !context )
3701  return true;
3702 
3703  if ( mLayerType != QgsProcessing::TypeFile )
3704  {
3705  const auto constToStringList = input.toStringList();
3706  for ( const QString &v : constToStringList )
3707  {
3708  if ( !QgsProcessingUtils::mapLayerFromString( v, *context ) )
3709  return false;
3710  }
3711  }
3712  return true;
3713  }
3714  return false;
3715 }
3716 
3718 {
3719  if ( !value.isValid() )
3720  return QStringLiteral( "None" );
3721 
3722  if ( value.canConvert<QgsProperty>() )
3723  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
3724 
3725  if ( mLayerType == QgsProcessing::TypeFile )
3726  {
3727  QStringList parts;
3728  if ( value.type() == QVariant::StringList )
3729  {
3730  const QStringList list = value.toStringList();
3731  parts.reserve( list.count() );
3732  for ( const QString &v : list )
3734  }
3735  else if ( value.type() == QVariant::List )
3736  {
3737  const QVariantList list = value.toList();
3738  parts.reserve( list.count() );
3739  for ( const QVariant &v : list )
3740  parts << QgsProcessingUtils::stringToPythonLiteral( v.toString() );
3741  }
3742  if ( !parts.isEmpty() )
3743  return parts.join( ',' ).prepend( '[' ).append( ']' );
3744  }
3745  else
3746  {
3747  QVariantMap p;
3748  p.insert( name(), value );
3749  const QList<QgsMapLayer *> list = QgsProcessingParameters::parameterAsLayerList( this, p, context );
3750  if ( !list.isEmpty() )
3751  {
3752  QStringList parts;
3753  parts.reserve( list.count() );
3754  for ( const QgsMapLayer *layer : list )
3755  {
3757  }
3758  return parts.join( ',' ).prepend( '[' ).append( ']' );
3759  }
3760  }
3761 
3763 }
3764 
3766 {
3767  QString code = QStringLiteral( "##%1=" ).arg( mName );
3768  if ( mFlags & FlagOptional )
3769  code += QLatin1String( "optional " );
3770  switch ( mLayerType )
3771  {
3773  code += QLatin1String( "multiple raster" );
3774  break;
3775 
3777  code += QLatin1String( "multiple file" );
3778  break;
3779 
3780  default:
3781  code += QLatin1String( "multiple vector" );
3782  break;
3783  }
3784  code += ' ';
3785  if ( mDefault.type() == QVariant::List )
3786  {
3787  QStringList parts;
3788  const auto constToList = mDefault.toList();
3789  for ( const QVariant &var : constToList )
3790  {
3791  parts << var.toString();
3792  }
3793  code += parts.join( ',' );
3794  }
3795  else if ( mDefault.type() == QVariant::StringList )
3796  {
3797  code += mDefault.toStringList().join( ',' );
3798  }
3799  else
3800  {
3801  code += mDefault.toString();
3802  }
3803  return code.trimmed();
3804 }
3805 
3807 {
3808  switch ( outputType )
3809  {
3811  {
3812  QString code = QStringLiteral( "QgsProcessingParameterMultipleLayers('%1', '%2'" ).arg( name(), description() );
3813  if ( mFlags & FlagOptional )
3814  code += QLatin1String( ", optional=True" );
3815 
3816  QString layerType = QStringLiteral( "QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( mLayerType ) );
3817 
3818  code += QStringLiteral( ", layerType=%1" ).arg( layerType );
3820  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
3821  return code;
3822  }
3823  }
3824  return QString();
3825 }
3826 
3828 {
3829  QStringList exts;
3830  switch ( mLayerType )
3831  {
3833  return QObject::tr( "All files (*.*)" );
3834 
3836  return QgsProviderRegistry::instance()->fileRasterFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
3837 
3843  return QgsProviderRegistry::instance()->fileVectorFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
3844 
3846  return QgsProviderRegistry::instance()->fileMeshFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
3847 
3849  return createAllMapLayerFileFilter();
3850  }
3851  return QString();
3852 }
3853 
3855 {
3856  return mLayerType;
3857 }
3858 
3860 {
3861  mLayerType = type;
3862 }
3863 
3865 {
3866  return mMinimumNumberInputs;
3867 }
3868 
3870 {
3871  if ( mMinimumNumberInputs >= 1 || !( flags() & QgsProcessingParameterDefinition::FlagOptional ) )
3872  mMinimumNumberInputs = minimumNumberInputs;
3873 }
3874 
3876 {
3878  map.insert( QStringLiteral( "layer_type" ), mLayerType );
3879  map.insert( QStringLiteral( "min_inputs" ), mMinimumNumberInputs );
3880  return map;
3881 }
3882 
3884 {
3886  mLayerType = static_cast< QgsProcessing::SourceType >( map.value( QStringLiteral( "layer_type" ) ).toInt() );
3887  mMinimumNumberInputs = map.value( QStringLiteral( "min_inputs" ) ).toInt();
3888  return true;
3889 }
3890 
3891 QgsProcessingParameterMultipleLayers *QgsProcessingParameterMultipleLayers::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3892 {
3893  QString type = definition;
3894  QString defaultVal;
3895  QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*)" ) );
3896  QRegularExpressionMatch m = re.match( definition );
3897  if ( m.hasMatch() )
3898  {
3899  type = m.captured( 1 ).toLower().trimmed();
3900  defaultVal = m.captured( 2 );
3901  }
3903  if ( type == QLatin1String( "vector" ) )
3905  else if ( type == QLatin1String( "raster" ) )
3907  else if ( type == QLatin1String( "file" ) )
3909  return new QgsProcessingParameterMultipleLayers( name, description, layerType, defaultVal.isEmpty() ? QVariant() : defaultVal, isOptional );
3910 }
3911 
3912 QgsProcessingParameterNumber::QgsProcessingParameterNumber( const QString &name, const QString &description, Type type, const QVariant &defaultValue, bool optional, double minValue, double maxValue )
3913  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3914  , mMin( minValue )
3915  , mMax( maxValue )
3916  , mDataType( type )
3917 {
3918  if ( mMin >= mMax )
3919  {
3920  QgsMessageLog::logMessage( QObject::tr( "Invalid number parameter \"%1\": min value %2 is >= max value %3!" ).arg( name ).arg( mMin ).arg( mMax ), QObject::tr( "Processing" ) );
3921  }
3922 }
3923 
3925 {
3926  return new QgsProcessingParameterNumber( *this );
3927 }
3928 
3930 {
3931  QVariant input = value;
3932  if ( !input.isValid() )
3933  {
3934  if ( !defaultValue().isValid() )
3935  return mFlags & FlagOptional;
3936 
3937  input = defaultValue();
3938  }
3939 
3940  if ( input.canConvert<QgsProperty>() )
3941  {
3942  return true;
3943  }
3944 
3945  bool ok = false;
3946  double res = input.toDouble( &ok );
3947  if ( !ok )
3948  return mFlags & FlagOptional;
3949 
3950  return !( res < mMin || res > mMax );
3951 }
3952 
3954 {
3955  if ( !value.isValid() )
3956  return QStringLiteral( "None" );
3957 
3958  if ( value.canConvert<QgsProperty>() )
3959  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
3960 
3961  return value.toString();
3962 }
3963 
3965 {
3967  QStringList parts;
3968  if ( mMin > std::numeric_limits<double>::lowest() + 1 )
3969  parts << QObject::tr( "Minimum value: %1" ).arg( mMin );
3970  if ( mMax < std::numeric_limits<double>::max() )
3971  parts << QObject::tr( "Maximum value: %1" ).arg( mMax );
3972  if ( mDefault.isValid() )
3973  parts << QObject::tr( "Default value: %1" ).arg( mDataType == Integer ? mDefault.toInt() : mDefault.toDouble() );
3974  QString extra = parts.join( QLatin1String( "<br />" ) );
3975  if ( !extra.isEmpty() )
3976  text += QStringLiteral( "<p>%1</p>" ).arg( extra );
3977  return text;
3978 }
3979 
3981 {
3982  switch ( outputType )
3983  {
3985  {
3986  QString code = QStringLiteral( "QgsProcessingParameterNumber('%1', '%2'" ).arg( name(), description() );
3987  if ( mFlags & FlagOptional )
3988  code += QLatin1String( ", optional=True" );
3989 
3990  code += QStringLiteral( ", type=%1" ).arg( mDataType == Integer ? QStringLiteral( "QgsProcessingParameterNumber.Integer" ) : QStringLiteral( "QgsProcessingParameterNumber.Double" ) );
3991 
3992  if ( mMin != std::numeric_limits<double>::lowest() + 1 )
3993  code += QStringLiteral( ", minValue=%1" ).arg( mMin );
3994  if ( mMax != std::numeric_limits<double>::max() )
3995  code += QStringLiteral( ", maxValue=%1" ).arg( mMax );
3997  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
3998  return code;
3999  }
4000  }
4001  return QString();
4002 }
4003 
4005 {
4006  return mMin;
4007 }
4008 
4010 {
4011  mMin = min;
4012 }
4013 
4015 {
4016  return mMax;
4017 }
4018 
4020 {
4021  mMax = max;
4022 }
4023 
4025 {
4026  return mDataType;
4027 }
4028 
4030 {
4031  mDataType = dataType;
4032 }
4033 
4035 {
4037  map.insert( QStringLiteral( "min" ), mMin );
4038  map.insert( QStringLiteral( "max" ), mMax );
4039  map.insert( QStringLiteral( "data_type" ), mDataType );
4040  return map;
4041 }
4042 
4043 bool QgsProcessingParameterNumber::fromVariantMap( const QVariantMap &map )
4044 {
4046  mMin = map.value( QStringLiteral( "min" ) ).toDouble();
4047  mMax = map.value( QStringLiteral( "max" ) ).toDouble();
4048  mDataType = static_cast< Type >( map.value( QStringLiteral( "data_type" ) ).toInt() );
4049  return true;
4050 }
4051 
4052 QgsProcessingParameterNumber *QgsProcessingParameterNumber::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4053 {
4054  return new QgsProcessingParameterNumber( name, description, Double, definition.isEmpty() ? QVariant()
4055  : ( definition.toLower().trimmed() == QLatin1String( "none" ) ? QVariant() : definition ), isOptional );
4056 }
4057 
4058 QgsProcessingParameterRange::QgsProcessingParameterRange( const QString &name, const QString &description, QgsProcessingParameterNumber::Type type, const QVariant &defaultValue, bool optional )
4059  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4060  , mDataType( type )
4061 {
4062 
4063 }
4064 
4066 {
4067  return new QgsProcessingParameterRange( *this );
4068 }
4069 
4071 {
4072  if ( !input.isValid() )
4073  return mFlags & FlagOptional;
4074 
4075  if ( input.canConvert<QgsProperty>() )
4076  {
4077  return true;
4078  }
4079 
4080  if ( input.type() == QVariant::String )
4081  {
4082  QStringList list = input.toString().split( ',' );
4083  if ( list.count() != 2 )
4084  return mFlags & FlagOptional;
4085  bool ok = false;
4086  list.at( 0 ).toDouble( &ok );
4087  bool ok2 = false;
4088  list.at( 1 ).toDouble( &ok2 );
4089  if ( !ok || !ok2 )
4090  return mFlags & FlagOptional;
4091  return true;
4092  }
4093  else if ( input.type() == QVariant::List )
4094  {
4095  if ( input.toList().count() != 2 )
4096  return mFlags & FlagOptional;
4097 
4098  bool ok = false;
4099  input.toList().at( 0 ).toDouble( &ok );
4100  bool ok2 = false;
4101  input.toList().at( 1 ).toDouble( &ok2 );
4102  if ( !ok || !ok2 )
4103  return mFlags & FlagOptional;
4104  return true;
4105  }
4106 
4107  return false;
4108 }
4109 
4110 QString QgsProcessingParameterRange::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
4111 {
4112  if ( !value.isValid() )
4113  return QStringLiteral( "None" );
4114 
4115  if ( value.canConvert<QgsProperty>() )
4116  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4117 
4118  QVariantMap p;
4119  p.insert( name(), value );
4120  QList< double > parts = QgsProcessingParameters::parameterAsRange( this, p, context );
4121 
4122  QStringList stringParts;
4123  const auto constParts = parts;
4124  for ( double v : constParts )
4125  {
4126  stringParts << QString::number( v );
4127  }
4128  return stringParts.join( ',' ).prepend( '[' ).append( ']' );
4129 }
4130 
4132 {
4133  switch ( outputType )
4134  {
4136  {
4137  QString code = QStringLiteral( "QgsProcessingParameterRange('%1', '%2'" ).arg( name(), description() );
4138  if ( mFlags & FlagOptional )
4139  code += QLatin1String( ", optional=True" );
4140 
4141  code += QStringLiteral( ", type=%1" ).arg( mDataType == QgsProcessingParameterNumber::Integer ? QStringLiteral( "QgsProcessingParameterNumber.Integer" ) : QStringLiteral( "QgsProcessingParameterNumber.Double" ) );
4142 
4144  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4145  return code;
4146  }
4147  }
4148  return QString();
4149 }
4150 
4152 {
4153  return mDataType;
4154 }
4155 
4157 {
4158  mDataType = dataType;
4159 }
4160 
4162 {
4164  map.insert( QStringLiteral( "data_type" ), mDataType );
4165  return map;
4166 }
4167 
4168 bool QgsProcessingParameterRange::fromVariantMap( const QVariantMap &map )
4169 {
4171  mDataType = static_cast< QgsProcessingParameterNumber::Type >( map.value( QStringLiteral( "data_type" ) ).toInt() );
4172  return true;
4173 }
4174 
4175 QgsProcessingParameterRange *QgsProcessingParameterRange::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4176 {
4177  return new QgsProcessingParameterRange( name, description, QgsProcessingParameterNumber::Double, definition.isEmpty() ? QVariant()
4178  : ( definition.toLower().trimmed() == QLatin1String( "none" ) ? QVariant() : definition ), isOptional );
4179 }
4180 
4181 QgsProcessingParameterRasterLayer::QgsProcessingParameterRasterLayer( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
4182  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4183 {
4184 
4185 }
4186 
4188 {
4189  return new QgsProcessingParameterRasterLayer( *this );
4190 }
4191 
4193 {
4194  if ( !input.isValid() )
4195  return mFlags & FlagOptional;
4196 
4197  if ( input.canConvert<QgsProperty>() )
4198  {
4199  return true;
4200  }
4201 
4202  if ( qobject_cast< QgsRasterLayer * >( qvariant_cast<QObject *>( input ) ) )
4203  return true;
4204 
4205  if ( input.type() != QVariant::String || input.toString().isEmpty() )
4206  return mFlags & FlagOptional;
4207 
4208  if ( !context )
4209  {
4210  // that's as far as we can get without a context
4211  return true;
4212  }
4213 
4214  // try to load as layer
4215  if ( QgsProcessingUtils::mapLayerFromString( input.toString(), *context, true, QgsProcessingUtils::LayerHint::Raster ) )
4216  return true;
4217 
4218  return false;
4219 }
4220 
4222 {
4223  if ( !val.isValid() )
4224  return QStringLiteral( "None" );
4225 
4226  if ( val.canConvert<QgsProperty>() )
4227  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
4228 
4229  QVariantMap p;
4230  p.insert( name(), val );
4233  : QgsProcessingUtils::stringToPythonLiteral( val.toString() );
4234 }
4235 
4237 {
4238  return QgsProviderRegistry::instance()->fileRasterFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
4239 }
4240 
4241 QgsProcessingParameterRasterLayer *QgsProcessingParameterRasterLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4242 {
4243  return new QgsProcessingParameterRasterLayer( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
4244 }
4245 
4246 QgsProcessingParameterEnum::QgsProcessingParameterEnum( const QString &name, const QString &description, const QStringList &options, bool allowMultiple, const QVariant &defaultValue, bool optional, bool usesStaticStrings )
4247  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4248  , mOptions( options )
4249  , mAllowMultiple( allowMultiple )
4250  , mUsesStaticStrings( usesStaticStrings )
4251 {
4252 
4253 }
4254 
4256 {
4257  return new QgsProcessingParameterEnum( *this );
4258 }
4259 
4261 {
4262  QVariant input = value;
4263  if ( !input.isValid() )
4264  {
4265  if ( !defaultValue().isValid() )
4266  return mFlags & FlagOptional;
4267 
4268  input = defaultValue();
4269  }
4270 
4271  if ( input.canConvert<QgsProperty>() )
4272  {
4273  return true;
4274  }
4275 
4276  if ( mUsesStaticStrings )
4277  {
4278  if ( input.type() == QVariant::List )
4279  {
4280  if ( !mAllowMultiple )
4281  return false;
4282 
4283  const QVariantList values = input.toList();
4284  if ( values.empty() && !( mFlags & FlagOptional ) )
4285  return false;
4286 
4287  for ( const QVariant &val : values )
4288  {
4289  if ( !mOptions.contains( val.toString() ) )
4290  return false;
4291  }
4292 
4293  return true;
4294  }
4295  else if ( input.type() == QVariant::StringList )
4296  {
4297  if ( !mAllowMultiple )
4298  return false;
4299 
4300  const QStringList values = input.toStringList();
4301 
4302  if ( values.empty() && !( mFlags & FlagOptional ) )
4303  return false;
4304 
4305  if ( values.count() > 1 && !mAllowMultiple )
4306  return false;
4307 
4308  for ( const QString &val : values )
4309  {
4310  if ( !mOptions.contains( val ) )
4311  return false;
4312  }
4313  return true;
4314  }
4315  else if ( input.type() == QVariant::String )
4316  {
4317  QStringList parts = input.toString().split( ',' );
4318  if ( parts.count() > 1 && !mAllowMultiple )
4319  return false;
4320 
4321  const auto constParts = parts;
4322  for ( const QString &part : constParts )
4323  {
4324  if ( !mOptions.contains( part ) )
4325  return false;
4326  }
4327  return true;
4328  }
4329  }
4330  else
4331  {
4332  if ( input.type() == QVariant::List )
4333  {
4334  if ( !mAllowMultiple )
4335  return false;
4336 
4337  const QVariantList values = input.toList();
4338  if ( values.empty() && !( mFlags & FlagOptional ) )
4339  return false;
4340 
4341  for ( const QVariant &val : values )
4342  {
4343  bool ok = false;
4344  int res = val.toInt( &ok );
4345  if ( !ok )
4346  return false;
4347  else if ( res < 0 || res >= mOptions.count() )
4348  return false;
4349  }
4350 
4351  return true;
4352  }
4353  else if ( input.type() == QVariant::String )
4354  {
4355  QStringList parts = input.toString().split( ',' );
4356  if ( parts.count() > 1 && !mAllowMultiple )
4357  return false;
4358 
4359  const auto constParts = parts;
4360  for ( const QString &part : constParts )
4361  {
4362  bool ok = false;
4363  int res = part.toInt( &ok );
4364  if ( !ok )
4365  return false;
4366  else if ( res < 0 || res >= mOptions.count() )
4367  return false;
4368  }
4369  return true;
4370  }
4371  else if ( input.type() == QVariant::Int || input.type() == QVariant::Double )
4372  {
4373  bool ok = false;
4374  int res = input.toInt( &ok );
4375  if ( !ok )
4376  return false;
4377  else if ( res >= 0 && res < mOptions.count() )
4378  return true;
4379  }
4380  }
4381 
4382  return false;
4383 }
4384 
4386 {
4387  if ( !value.isValid() )
4388  return QStringLiteral( "None" );
4389 
4390  if ( value.canConvert<QgsProperty>() )
4391  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4392 
4393  if ( mUsesStaticStrings )
4394  {
4395  if ( value.type() == QVariant::StringList )
4396  {
4397  QStringList parts;
4398  const QStringList constList = value.toStringList();
4399  for ( const QString &val : constList )
4400  {
4402  }
4403  return parts.join( ',' ).prepend( '[' ).append( ']' );
4404  }
4405  else if ( value.type() == QVariant::String )
4406  {
4407  QStringList parts;
4408  const QStringList constList = value.toString().split( ',' );
4409  if ( constList.count() > 1 )
4410  {
4411  for ( const QString &val : constList )
4412  {
4414  }
4415  return parts.join( ',' ).prepend( '[' ).append( ']' );
4416  }
4417  }
4418 
4419  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
4420  }
4421  else
4422  {
4423  if ( value.type() == QVariant::List )
4424  {
4425  QStringList parts;
4426  const auto constToList = value.toList();
4427  for ( const QVariant &val : constToList )
4428  {
4429  parts << QString::number( static_cast< int >( val.toDouble() ) );
4430  }
4431  return parts.join( ',' ).prepend( '[' ).append( ']' );
4432  }
4433  else if ( value.type() == QVariant::String )
4434  {
4435  QStringList parts = value.toString().split( ',' );
4436  if ( parts.count() > 1 )
4437  {
4438  return parts.join( ',' ).prepend( '[' ).append( ']' );
4439  }
4440  }
4441 
4442  return QString::number( static_cast< int >( value.toDouble() ) );
4443  }
4444 }
4445 
4447 {
4448  if ( !value.isValid() )
4449  return QString();
4450 
4451  if ( value.canConvert<QgsProperty>() )
4452  return QString();
4453 
4454  if ( mUsesStaticStrings )
4455  {
4456  return QString();
4457  }
4458  else
4459  {
4460  if ( value.type() == QVariant::List )
4461  {
4462  QStringList parts;
4463  const QVariantList toList = value.toList();
4464  parts.reserve( toList.size() );
4465  for ( const QVariant &val : toList )
4466  {
4467  parts << mOptions.value( static_cast< int >( val.toDouble() ) );
4468  }
4469  return parts.join( ',' );
4470  }
4471  else if ( value.type() == QVariant::String )
4472  {
4473  const QStringList parts = value.toString().split( ',' );
4474  QStringList comments;
4475  if ( parts.count() > 1 )
4476  {
4477  for ( const QString &part : parts )
4478  {
4479  bool ok = false;
4480  int val = part.toInt( &ok );
4481  if ( ok )
4482  comments << mOptions.value( val );
4483  }
4484  return comments.join( ',' );
4485  }
4486  }
4487 
4488  return mOptions.value( static_cast< int >( value.toDouble() ) );
4489  }
4490 }
4491 
4493 {
4494  QString code = QStringLiteral( "##%1=" ).arg( mName );
4495  if ( mFlags & FlagOptional )
4496  code += QLatin1String( "optional " );
4497  code += QLatin1String( "enum " );
4498 
4499  if ( mAllowMultiple )
4500  code += QLatin1String( "multiple " );
4501 
4502  if ( mUsesStaticStrings )
4503  code += QLatin1String( "static " );
4504 
4505  code += mOptions.join( ';' ) + ' ';
4506 
4507  code += mDefault.toString();
4508  return code.trimmed();
4509 }
4510 
4512 {
4513  switch ( outputType )
4514  {
4516  {
4517  QString code = QStringLiteral( "QgsProcessingParameterEnum('%1', '%2'" ).arg( name(), description() );
4518  if ( mFlags & FlagOptional )
4519  code += QLatin1String( ", optional=True" );
4520 
4521  QStringList options;
4522  options.reserve( mOptions.size() );
4523  for ( const QString &o : mOptions )
4525  code += QStringLiteral( ", options=[%1]" ).arg( options.join( ',' ) );
4526 
4527  code += QStringLiteral( ", allowMultiple=%1" ).arg( mAllowMultiple ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
4528 
4529  code += QStringLiteral( ", usesStaticStrings=%1" ).arg( mUsesStaticStrings ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
4530 
4532  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4533 
4534  return code;
4535  }
4536  }
4537  return QString();
4538 }
4539 
4541 {
4542  return mOptions;
4543 }
4544 
4545 void QgsProcessingParameterEnum::setOptions( const QStringList &options )
4546 {
4547  mOptions = options;
4548 }
4549 
4551 {
4552  return mAllowMultiple;
4553 }
4554 
4556 {
4557  mAllowMultiple = allowMultiple;
4558 }
4559 
4561 {
4562  return mUsesStaticStrings;
4563 }
4564 
4566 {
4567  mUsesStaticStrings = usesStaticStrings;
4568 }
4569 
4571 {
4573  map.insert( QStringLiteral( "options" ), mOptions );
4574  map.insert( QStringLiteral( "allow_multiple" ), mAllowMultiple );
4575  map.insert( QStringLiteral( "uses_static_strings" ), mUsesStaticStrings );
4576  return map;
4577 }
4578 
4579 bool QgsProcessingParameterEnum::fromVariantMap( const QVariantMap &map )
4580 {
4582  mOptions = map.value( QStringLiteral( "options" ) ).toStringList();
4583  mAllowMultiple = map.value( QStringLiteral( "allow_multiple" ) ).toBool();
4584  mUsesStaticStrings = map.value( QStringLiteral( "uses_static_strings" ) ).toBool();
4585  return true;
4586 }
4587 
4588 QgsProcessingParameterEnum *QgsProcessingParameterEnum::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4589 {
4590  QString defaultVal;
4591  QString def = definition;
4592 
4593  bool multiple = false;
4594  if ( def.startsWith( QLatin1String( "multiple" ), Qt::CaseInsensitive ) )
4595  {
4596  multiple = true;
4597  def = def.mid( 9 );
4598  }
4599 
4600  bool staticStrings = false;
4601  if ( def.startsWith( QLatin1String( "static" ), Qt::CaseInsensitive ) )
4602  {
4603  staticStrings = true;
4604  def = def.mid( 7 );
4605  }
4606 
4607  QRegularExpression re( QStringLiteral( "(.*)\\s+(.*?)$" ) );
4608  QRegularExpressionMatch m = re.match( def );
4609  QString values = def;
4610  if ( m.hasMatch() )
4611  {
4612  values = m.captured( 1 ).trimmed();
4613  defaultVal = m.captured( 2 );
4614  }
4615 
4616  return new QgsProcessingParameterEnum( name, description, values.split( ';' ), multiple, defaultVal.isEmpty() ? QVariant() : defaultVal, isOptional, staticStrings );
4617 }
4618 
4619 QgsProcessingParameterString::QgsProcessingParameterString( const QString &name, const QString &description, const QVariant &defaultValue, bool multiLine, bool optional )
4620  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4621  , mMultiLine( multiLine )
4622 {
4623 
4624 }
4625 
4627 {
4628  return new QgsProcessingParameterString( *this );
4629 }
4630 
4632 {
4633  if ( !value.isValid() || value.isNull() )
4634  return QStringLiteral( "None" );
4635 
4636  if ( value.canConvert<QgsProperty>() )
4637  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4638 
4639  QString s = value.toString();
4641 }
4642 
4644 {
4645  QString code = QStringLiteral( "##%1=" ).arg( mName );
4646  if ( mFlags & FlagOptional )
4647  code += QLatin1String( "optional " );
4648  code += QLatin1String( "string " );
4649 
4650  if ( mMultiLine )
4651  code += QLatin1String( "long " );
4652 
4653  code += mDefault.toString();
4654  return code.trimmed();
4655 }
4656 
4658 {
4659  switch ( outputType )
4660  {
4662  {
4663  QString code = QStringLiteral( "QgsProcessingParameterString('%1', '%2'" ).arg( name(), description() );
4664  if ( mFlags & FlagOptional )
4665  code += QLatin1String( ", optional=True" );
4666  code += QStringLiteral( ", multiLine=%1" ).arg( mMultiLine ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
4667 
4669  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4670  return code;
4671  }
4672  }
4673  return QString();
4674 }
4675 
4677 {
4678  return mMultiLine;
4679 }
4680 
4682 {
4683  mMultiLine = multiLine;
4684 }
4685 
4687 {
4689  map.insert( QStringLiteral( "multiline" ), mMultiLine );
4690  return map;
4691 }
4692 
4693 bool QgsProcessingParameterString::fromVariantMap( const QVariantMap &map )
4694 {
4696  mMultiLine = map.value( QStringLiteral( "multiline" ) ).toBool();
4697  return true;
4698 }
4699 
4700 QgsProcessingParameterString *QgsProcessingParameterString::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4701 {
4702  QString def = definition;
4703  bool multiLine = false;
4704  if ( def.startsWith( QLatin1String( "long" ), Qt::CaseInsensitive ) )
4705  {
4706  multiLine = true;
4707  def = def.mid( 5 );
4708  }
4709 
4710  if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
4711  def = def.mid( 1 );
4712  if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
4713  def.chop( 1 );
4714 
4715  QVariant defaultValue = def;
4716  if ( def == QLatin1String( "None" ) )
4717  defaultValue = QVariant();
4718 
4720 }
4721 
4722 //
4723 // QgsProcessingParameterAuthConfig
4724 //
4725 
4726 QgsProcessingParameterAuthConfig::QgsProcessingParameterAuthConfig( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
4727  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4728 {
4729 
4730 }
4731 
4733 {
4734  return new QgsProcessingParameterAuthConfig( *this );
4735 }
4736 
4738 {
4739  if ( !value.isValid() )
4740  return QStringLiteral( "None" );
4741 
4742  QString s = value.toString();
4744 }
4745 
4747 {
4748  QString code = QStringLiteral( "##%1=" ).arg( mName );
4749  if ( mFlags & FlagOptional )
4750  code += QLatin1String( "optional " );
4751  code += QLatin1String( "authcfg " );
4752 
4753  code += mDefault.toString();
4754  return code.trimmed();
4755 }
4756 
4757 QgsProcessingParameterAuthConfig *QgsProcessingParameterAuthConfig::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4758 {
4759  QString def = definition;
4760 
4761  if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
4762  def = def.mid( 1 );
4763  if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
4764  def.chop( 1 );
4765 
4766  QVariant defaultValue = def;
4767  if ( def == QLatin1String( "None" ) )
4768  defaultValue = QVariant();
4769 
4770  return new QgsProcessingParameterAuthConfig( name, description, defaultValue, isOptional );
4771 }
4772 
4773 
4774 //
4775 // QgsProcessingParameterExpression
4776 //
4777 
4778 QgsProcessingParameterExpression::QgsProcessingParameterExpression( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayerParameterName, bool optional )
4779  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4780  , mParentLayerParameterName( parentLayerParameterName )
4781 {
4782 
4783 }
4784 
4786 {
4787  return new QgsProcessingParameterExpression( *this );
4788 }
4789 
4791 {
4792  if ( !value.isValid() )
4793  return QStringLiteral( "None" );
4794 
4795  if ( value.canConvert<QgsProperty>() )
4796  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4797 
4798  QString s = value.toString();
4800 }
4801 
4803 {
4804  QStringList depends;
4805  if ( !mParentLayerParameterName.isEmpty() )
4806  depends << mParentLayerParameterName;
4807  return depends;
4808 }
4809 
4811 {
4812  switch ( outputType )
4813  {
4815  {
4816  QString code = QStringLiteral( "QgsProcessingParameterExpression('%1', '%2'" ).arg( name(), description() );
4817  if ( mFlags & FlagOptional )
4818  code += QLatin1String( ", optional=True" );
4819 
4820  code += QStringLiteral( ", parentLayerParameterName='%1'" ).arg( mParentLayerParameterName );
4821 
4823  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4824  return code;
4825  }
4826  }
4827  return QString();
4828 }
4829 
4831 {
4832  return mParentLayerParameterName;
4833 }
4834 
4835 void QgsProcessingParameterExpression::setParentLayerParameterName( const QString &parentLayerParameterName )
4836 {
4837  mParentLayerParameterName = parentLayerParameterName;
4838 }
4839 
4841 {
4843  map.insert( QStringLiteral( "parent_layer" ), mParentLayerParameterName );
4844  return map;
4845 }
4846 
4848 {
4850  mParentLayerParameterName = map.value( QStringLiteral( "parent_layer" ) ).toString();
4851  return true;
4852 }
4853 
4854 QgsProcessingParameterExpression *QgsProcessingParameterExpression::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4855 {
4856  return new QgsProcessingParameterExpression( name, description, definition, QString(), isOptional );
4857 }
4858 
4859 QgsProcessingParameterVectorLayer::QgsProcessingParameterVectorLayer( const QString &name, const QString &description, const QList<int> &types, const QVariant &defaultValue, bool optional )
4860  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4862 {
4863 
4864 }
4865 
4867 {
4868  return new QgsProcessingParameterVectorLayer( *this );
4869 }
4870 
4872 {
4873  if ( !v.isValid() )
4874  return mFlags & FlagOptional;
4875 
4876  QVariant var = v;
4877 
4878  if ( var.canConvert<QgsProperty>() )
4879  {
4880  QgsProperty p = var.value< QgsProperty >();
4882  {
4883  var = p.staticValue();
4884  }
4885  else
4886  {
4887  return true;
4888  }
4889  }
4890 
4891  if ( qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( var ) ) )
4892  return true;
4893 
4894  if ( var.type() != QVariant::String || var.toString().isEmpty() )
4895  return mFlags & FlagOptional;
4896 
4897  if ( !context )
4898  {
4899  // that's as far as we can get without a context
4900  return true;
4901  }
4902 
4903  // try to load as layer
4904  if ( QgsProcessingUtils::mapLayerFromString( var.toString(), *context, true, QgsProcessingUtils::LayerHint::Vector ) )
4905  return true;
4906 
4907  return false;
4908 }
4909 
4911 {
4912  if ( !val.isValid() )
4913  return QStringLiteral( "None" );
4914 
4915  if ( val.canConvert<QgsProperty>() )
4916  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
4917 
4918  QVariantMap p;
4919  p.insert( name(), val );
4922  : QgsProcessingUtils::stringToPythonLiteral( val.toString() );
4923 }
4924 
4926 {
4927  switch ( outputType )
4928  {
4930  {
4931  QString code = QStringLiteral( "QgsProcessingParameterVectorLayer('%1', '%2'" ).arg( name(), description() );
4932  if ( mFlags & FlagOptional )
4933  code += QLatin1String( ", optional=True" );
4934 
4935  if ( !mDataTypes.empty() )
4936  {
4937  QStringList options;
4938  for ( int t : mDataTypes )
4939  options << QStringLiteral( "QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( static_cast< QgsProcessing::SourceType >( t ) ) );
4940  code += QStringLiteral( ", types=[%1]" ).arg( options.join( ',' ) );
4941  }
4942 
4944  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4945  return code;
4946  }
4947  }
4948  return QString();
4949 }
4950 
4952 {
4953  return QgsProviderRegistry::instance()->fileVectorFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
4954 }
4955 
4957 {
4958  return mDataTypes;
4959 }
4960 
4962 {
4963  mDataTypes = types;
4964 }
4965 
4967 {
4969  QVariantList types;
4970  for ( int type : mDataTypes )
4971  {
4972  types << type;
4973  }
4974  map.insert( QStringLiteral( "data_types" ), types );
4975  return map;
4976 }
4977 
4979 {
4981  mDataTypes.clear();
4982  const QVariantList values = map.value( QStringLiteral( "data_types" ) ).toList();
4983  for ( const QVariant &val : values )
4984  {
4985  mDataTypes << val.toInt();
4986  }
4987  return true;
4988 }
4989 
4990 QgsProcessingParameterVectorLayer *QgsProcessingParameterVectorLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4991 {
4992  return new QgsProcessingParameterVectorLayer( name, description, QList< int>(), definition.isEmpty() ? QVariant() : definition, isOptional );
4993 }
4994 
4996  const QString &description,
4997  const QVariant &defaultValue,
4998  bool optional )
4999  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5000 {
5001 
5002 }
5003 
5005 {
5006  return new QgsProcessingParameterMeshLayer( *this );
5007 }
5008 
5010 {
5011  if ( !v.isValid() )
5012  return mFlags & FlagOptional;
5013 
5014  QVariant var = v;
5015 
5016  if ( var.canConvert<QgsProperty>() )
5017  {
5018  QgsProperty p = var.value< QgsProperty >();
5020  {
5021  var = p.staticValue();
5022  }
5023  else
5024  {
5025  return true;
5026  }
5027  }
5028 
5029  if ( qobject_cast< QgsMeshLayer * >( qvariant_cast<QObject *>( var ) ) )
5030  return true;
5031 
5032  if ( var.type() != QVariant::String || var.toString().isEmpty() )
5033  return mFlags & FlagOptional;
5034 
5035  if ( !context )
5036  {
5037  // that's as far as we can get without a context
5038  return true;
5039  }
5040 
5041  // try to load as layer
5042  if ( QgsProcessingUtils::mapLayerFromString( var.toString(), *context, true, QgsProcessingUtils::LayerHint::Mesh ) )
5043  return true;
5044 
5045  return false;
5046 }
5047 
5049 {
5050  if ( !val.isValid() )
5051  return QStringLiteral( "None" );
5052 
5053  if ( val.canConvert<QgsProperty>() )
5054  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
5055 
5056  QVariantMap p;
5057  p.insert( name(), val );
5058  QgsMeshLayer *layer = QgsProcessingParameters::parameterAsMeshLayer( this, p, context );
5060  : QgsProcessingUtils::stringToPythonLiteral( val.toString() );
5061 }
5062 
5064 {
5065  return QgsProviderRegistry::instance()->fileMeshFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
5066 }
5067 
5068 QgsProcessingParameterMeshLayer *QgsProcessingParameterMeshLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5069 {
5070  return new QgsProcessingParameterMeshLayer( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
5071 }
5072 
5073 QgsProcessingParameterField::QgsProcessingParameterField( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayerParameterName, DataType type, bool allowMultiple, bool optional, bool defaultToAllFields )
5074  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5075  , mParentLayerParameterName( parentLayerParameterName )
5076  , mDataType( type )
5077  , mAllowMultiple( allowMultiple )
5078  , mDefaultToAllFields( defaultToAllFields )
5079 {
5080 
5081 }
5082 
5083 
5085 {
5086  return new QgsProcessingParameterField( *this );
5087 }
5088 
5090 {
5091  if ( !input.isValid() )
5092  return mFlags & FlagOptional;
5093 
5094  if ( input.canConvert<QgsProperty>() )
5095  {
5096  return true;
5097  }
5098 
5099  if ( input.type() == QVariant::List || input.type() == QVariant::StringList )
5100  {
5101  if ( !mAllowMultiple )
5102  return false;
5103 
5104  if ( input.toList().isEmpty() && !( mFlags & FlagOptional ) )
5105  return false;
5106  }
5107  else if ( input.type() == QVariant::String )
5108  {
5109  if ( input.toString().isEmpty() )
5110  return mFlags & FlagOptional;
5111 
5112  QStringList parts = input.toString().split( ';' );
5113  if ( parts.count() > 1 && !mAllowMultiple )
5114  return false;
5115  }
5116  else
5117  {
5118  if ( input.toString().isEmpty() )
5119  return mFlags & FlagOptional;
5120  }
5121  return true;
5122 }
5123 
5125 {
5126  if ( !value.isValid() )
5127  return QStringLiteral( "None" );
5128 
5129  if ( value.canConvert<QgsProperty>() )
5130  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
5131 
5132  if ( value.type() == QVariant::List )
5133  {
5134  QStringList parts;
5135  const auto constToList = value.toList();
5136  for ( const QVariant &val : constToList )
5137  {
5138  parts << QgsProcessingUtils::stringToPythonLiteral( val.toString() );
5139  }
5140  return parts.join( ',' ).prepend( '[' ).append( ']' );
5141  }
5142  else if ( value.type() == QVariant::StringList )
5143  {
5144  QStringList parts;
5145  const auto constToStringList = value.toStringList();
5146  for ( QString s : constToStringList )
5147  {
5149  }
5150  return parts.join( ',' ).prepend( '[' ).append( ']' );
5151  }
5152 
5153  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
5154 }
5155 
5157 {
5158  QString code = QStringLiteral( "##%1=" ).arg( mName );
5159  if ( mFlags & FlagOptional )
5160  code += QLatin1String( "optional " );
5161  code += QLatin1String( "field " );
5162 
5163  switch ( mDataType )
5164  {
5165  case Numeric:
5166  code += QLatin1String( "numeric " );
5167  break;
5168 
5169  case String:
5170  code += QLatin1String( "string " );
5171  break;
5172 
5173  case DateTime:
5174  code += QLatin1String( "datetime " );
5175  break;
5176 
5177  case Any:
5178  break;
5179  }
5180 
5181  if ( mAllowMultiple )
5182  code += QLatin1String( "multiple " );
5183 
5184  if ( mDefaultToAllFields )
5185  code += QLatin1String( "default_to_all_fields " );
5186 
5187  code += mParentLayerParameterName + ' ';
5188 
5189  code += mDefault.toString();
5190  return code.trimmed();
5191 }
5192 
5194 {
5195  switch ( outputType )
5196  {
5198  {
5199  QString code = QStringLiteral( "QgsProcessingParameterField('%1', '%2'" ).arg( name(), description() );
5200  if ( mFlags & FlagOptional )
5201  code += QLatin1String( ", optional=True" );
5202 
5203  QString dataType;
5204  switch ( mDataType )
5205  {
5206  case Any:
5207  dataType = QStringLiteral( "QgsProcessingParameterField.Any" );
5208  break;
5209 
5210  case Numeric:
5211  dataType = QStringLiteral( "QgsProcessingParameterField.Numeric" );
5212  break;
5213 
5214  case String:
5215  dataType = QStringLiteral( "QgsProcessingParameterField.String" );
5216  break;
5217 
5218  case DateTime:
5219  dataType = QStringLiteral( "QgsProcessingParameterField.DateTime" );
5220  break;
5221  }
5222  code += QStringLiteral( ", type=%1" ).arg( dataType );
5223 
5224  code += QStringLiteral( ", parentLayerParameterName='%1'" ).arg( mParentLayerParameterName );
5225  code += QStringLiteral( ", allowMultiple=%1" ).arg( mAllowMultiple ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
5227  code += QStringLiteral( ", defaultValue=%1" ).arg( valueAsPythonString( mDefault, c ) );
5228 
5229  if ( mDefaultToAllFields )
5230  code += QLatin1String( ", defaultToAllFields=True" );
5231 
5232  code += ')';
5233 
5234  return code;
5235  }
5236  }
5237  return QString();
5238 }
5239 
5241 {
5242  QStringList depends;
5243  if ( !mParentLayerParameterName.isEmpty() )
5244  depends << mParentLayerParameterName;
5245  return depends;
5246 }
5247 
5249 {
5250  return mParentLayerParameterName;
5251 }
5252 
5253 void QgsProcessingParameterField::setParentLayerParameterName( const QString &parentLayerParameterName )
5254 {
5255  mParentLayerParameterName = parentLayerParameterName;
5256 }
5257 
5259 {
5260  return mDataType;
5261 }
5262 
5264 {
5265  mDataType = dataType;
5266 }
5267 
5269 {
5270  return mAllowMultiple;
5271 }
5272 
5274 {
5275  mAllowMultiple = allowMultiple;
5276 }
5277 
5279 {
5280  return mDefaultToAllFields;
5281 }
5282 
5284 {
5285  mDefaultToAllFields = enabled;
5286 }
5287 
5289 {
5291  map.insert( QStringLiteral( "parent_layer" ), mParentLayerParameterName );
5292  map.insert( QStringLiteral( "data_type" ), mDataType );
5293  map.insert( QStringLiteral( "allow_multiple" ), mAllowMultiple );
5294  map.insert( QStringLiteral( "default_to_all_fields" ), mDefaultToAllFields );
5295  return map;
5296 }
5297 
5298 bool QgsProcessingParameterField::fromVariantMap( const QVariantMap &map )
5299 {
5301  mParentLayerParameterName = map.value( QStringLiteral( "parent_layer" ) ).toString();
5302  mDataType = static_cast< DataType >( map.value( QStringLiteral( "data_type" ) ).toInt() );
5303  mAllowMultiple = map.value( QStringLiteral( "allow_multiple" ) ).toBool();
5304  mDefaultToAllFields = map.value( QStringLiteral( "default_to_all_fields" ) ).toBool();
5305  return true;
5306 }
5307 
5308 QgsProcessingParameterField *QgsProcessingParameterField::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5309 {
5310  QString parent;
5311  DataType type = Any;
5312  bool allowMultiple = false;
5313  bool defaultToAllFields = false;
5314  QString def = definition;
5315 
5316  if ( def.startsWith( QLatin1String( "numeric " ), Qt::CaseInsensitive ) )
5317  {
5318  type = Numeric;
5319  def = def.mid( 8 );
5320  }
5321  else if ( def.startsWith( QLatin1String( "string " ), Qt::CaseInsensitive ) )
5322  {
5323  type = String;
5324  def = def.mid( 7 );
5325  }
5326  else if ( def.startsWith( QLatin1String( "datetime " ), Qt::CaseInsensitive ) )
5327  {
5328  type = DateTime;
5329  def = def.mid( 9 );
5330  }
5331 
5332  if ( def.startsWith( QLatin1String( "multiple" ), Qt::CaseInsensitive ) )
5333  {
5334  allowMultiple = true;
5335  def = def.mid( 8 ).trimmed();
5336  }
5337 
5338  if ( def.startsWith( QLatin1String( "default_to_all_fields" ), Qt::CaseInsensitive ) )
5339  {
5340  defaultToAllFields = true;
5341  def = def.mid( 21 ).trimmed();
5342  }
5343 
5344  QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*)$" ) );
5345  QRegularExpressionMatch m = re.match( def );
5346  if ( m.hasMatch() )
5347  {
5348  parent = m.captured( 1 ).trimmed();
5349  def = m.captured( 2 );
5350  }
5351  else
5352  {
5353  parent = def;
5354  def.clear();
5355  }
5356 
5357  return new QgsProcessingParameterField( name, description, def.isEmpty() ? QVariant() : def, parent, type, allowMultiple, isOptional, defaultToAllFields );
5358 }
5359 
5360 QgsProcessingParameterFeatureSource::QgsProcessingParameterFeatureSource( const QString &name, const QString &description, const QList<int> &types, const QVariant &defaultValue, bool optional )
5361  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5363 {
5364 
5365 }
5366 
5368 {
5369  return new QgsProcessingParameterFeatureSource( *this );
5370 }
5371 
5373 {
5374  QVariant var = input;
5375  if ( !var.isValid() )
5376  return mFlags & FlagOptional;
5377 
5378  if ( var.canConvert<QgsProcessingFeatureSourceDefinition>() )
5379  {
5380  QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( var );
5381  var = fromVar.source;
5382  }
5383  else if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
5384  {
5385  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
5386  QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
5387  var = fromVar.sink;
5388  }
5389 
5390  if ( var.canConvert<QgsProperty>() )
5391  {
5392  QgsProperty p = var.value< QgsProperty >();
5394  {
5395  var = p.staticValue();
5396  }
5397  else
5398  {
5399  return true;
5400  }
5401  }
5402  if ( qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( input ) ) )
5403  {
5404  return true;
5405  }
5406 
5407  if ( var.type() != QVariant::String || var.toString().isEmpty() )
5408  return mFlags & FlagOptional;
5409 
5410  if ( !context )
5411  {
5412  // that's as far as we can get without a context
5413  return true;
5414  }
5415 
5416  // try to load as layer
5417  if ( QgsProcessingUtils::mapLayerFromString( var.toString(), *context, true, QgsProcessingUtils::LayerHint::Vector ) )
5418  return true;
5419 
5420  return false;
5421 }
5422 
5424 {
5425  if ( !value.isValid() )
5426  return QStringLiteral( "None" );
5427 
5428  if ( value.canConvert<QgsProperty>() )
5429  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
5430 
5431  if ( value.canConvert<QgsProcessingFeatureSourceDefinition>() )
5432  {
5433  QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( value );
5434  QString geometryCheckString;
5435  switch ( fromVar.geometryCheck )
5436  {
5438  geometryCheckString = QStringLiteral( "QgsFeatureRequest.GeometryNoCheck" );
5439  break;
5440 
5442  geometryCheckString = QStringLiteral( "QgsFeatureRequest.GeometrySkipInvalid" );
5443  break;
5444 
5446  geometryCheckString = QStringLiteral( "QgsFeatureRequest.GeometryAbortOnInvalid" );
5447  break;
5448  }
5449 
5450  QStringList flags;
5451  QString flagString;
5452  if ( fromVar.flags & QgsProcessingFeatureSourceDefinition::Flag::FlagOverrideDefaultGeometryCheck )
5453  flags << QStringLiteral( "QgsProcessingFeatureSourceDefinition.FlagOverrideDefaultGeometryCheck" );
5454  if ( fromVar.flags & QgsProcessingFeatureSourceDefinition::Flag::FlagCreateIndividualOutputPerInputFeature )
5455  flags << QStringLiteral( "QgsProcessingFeatureSourceDefinition.FlagCreateIndividualOutputPerInputFeature" );
5456  if ( !flags.empty() )
5457  flagString = flags.join( QLatin1String( " | " ) );
5458 
5459  if ( fromVar.source.propertyType() == QgsProperty::StaticProperty )
5460  {
5461  QString layerString = fromVar.source.staticValue().toString();
5462  // prefer to use layer source instead of id if possible (since it's persistent)
5463  if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( QgsProcessingUtils::mapLayerFromString( layerString, context, true, QgsProcessingUtils::LayerHint::Vector ) ) )
5464  layerString = layer->source();
5465 
5466  if ( fromVar.selectedFeaturesOnly || fromVar.featureLimit != -1 || fromVar.flags )
5467  {
5468  return QStringLiteral( "QgsProcessingFeatureSourceDefinition('%1', selectedFeaturesOnly=%2, featureLimit=%3%4, geometryCheck=%5)" ).arg( layerString,
5469  fromVar.selectedFeaturesOnly ? QStringLiteral( "True" ) : QStringLiteral( "False" ),
5470  QString::number( fromVar.featureLimit ),
5471  flagString.isEmpty() ? QString() : ( QStringLiteral( ", flags=%1" ).arg( flagString ) ),
5472  geometryCheckString );
5473  }
5474  else
5475  {
5476  return QgsProcessingUtils::stringToPythonLiteral( layerString );
5477  }
5478  }
5479  else
5480  {
5481  if ( fromVar.selectedFeaturesOnly || fromVar.featureLimit != -1 || fromVar.flags )
5482  {
5483  return QStringLiteral( "QgsProcessingFeatureSourceDefinition(QgsProperty.fromExpression('%1'), selectedFeaturesOnly=%2, featureLimit=%3%4, geometryCheck=%5)" )
5484  .arg( fromVar.source.asExpression(),
5485  fromVar.selectedFeaturesOnly ? QStringLiteral( "True" ) : QStringLiteral( "False" ),
5486  QString::number( fromVar.featureLimit ),
5487  flagString.isEmpty() ? QString() : ( QStringLiteral( ", flags=%1" ).arg( flagString ) ),
5488  geometryCheckString );
5489  }
5490  else
5491  {
5492  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.source.asExpression() );
5493  }
5494  }
5495  }
5496  else if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( value ) ) )
5497  {
5498  return QgsProcessingUtils::stringToPythonLiteral( layer->source() );
5499  }
5500 
5501  QString layerString = value.toString();
5502 
5503  // prefer to use layer source if possible (since it's persistent)
5504  if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( QgsProcessingUtils::mapLayerFromString( layerString, context, true, QgsProcessingUtils::LayerHint::Vector ) ) )
5505  layerString = layer->providerType() != QLatin1String( "ogr" ) && layer->providerType() != QLatin1String( "gdal" ) && layer->providerType() != QLatin1String( "mdal" ) ? QgsProcessingUtils::encodeProviderKeyAndUri( layer->providerType(), layer->source() ) : layer->source();
5506 
5507  return QgsProcessingUtils::stringToPythonLiteral( layerString );
5508 }
5509 
5511 {
5512  QString code = QStringLiteral( "##%1=" ).arg( mName );
5513  if ( mFlags & FlagOptional )
5514  code += QLatin1String( "optional " );
5515  code += QLatin1String( "source " );
5516 
5517  for ( int type : mDataTypes )
5518  {
5519  switch ( type )
5520  {
5522  code += QLatin1String( "point " );
5523  break;
5524 
5526  code += QLatin1String( "line " );
5527  break;
5528 
5530  code += QLatin1String( "polygon " );
5531  break;
5532 
5533  }
5534  }
5535 
5536  code += mDefault.toString();
5537  return code.trimmed();
5538 }
5539 
5541 {
5542  switch ( outputType )
5543  {
5545  {
5546  QString code = QStringLiteral( "QgsProcessingParameterFeatureSource('%1', '%2'" ).arg( name(), description() );
5547  if ( mFlags & FlagOptional )
5548  code += QLatin1String( ", optional=True" );
5549 
5550  if ( !mDataTypes.empty() )
5551  {
5552  QStringList options;
5553  options.reserve( mDataTypes.size() );
5554  for ( int t : mDataTypes )
5555  options << QStringLiteral( "QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( static_cast< QgsProcessing::SourceType >( t ) ) );
5556  code += QStringLiteral( ", types=[%1]" ).arg( options.join( ',' ) );
5557  }
5558 
5560  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
5561  return code;
5562  }
5563  }
5564  return QString();
5565 }
5566 
5568 {
5569  return QgsProviderRegistry::instance()->fileVectorFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
5570 }
5571 
5573  : mDataTypes( types )
5574 {
5575 
5576 }
5577 
5579 {
5581  QVariantList types;
5582  for ( int type : mDataTypes )
5583  {
5584  types << type;
5585  }
5586  map.insert( QStringLiteral( "data_types" ), types );
5587  return map;
5588 }
5589 
5591 {
5593  mDataTypes.clear();
5594  const QVariantList values = map.value( QStringLiteral( "data_types" ) ).toList();
5595  for ( const QVariant &val : values )
5596  {
5597  mDataTypes << val.toInt();
5598  }
5599  return true;
5600 }
5601 
5602 QgsProcessingParameterFeatureSource *QgsProcessingParameterFeatureSource::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5603 {
5604  QList< int > types;
5605  QString def = definition;
5606  while ( true )
5607  {
5608  if ( def.startsWith( QLatin1String( "point" ), Qt::CaseInsensitive ) )
5609  {
5611  def = def.mid( 6 );
5612  continue;
5613  }
5614  else if ( def.startsWith( QLatin1String( "line" ), Qt::CaseInsensitive ) )
5615  {
5617  def = def.mid( 5 );
5618  continue;
5619  }
5620  else if ( def.startsWith( QLatin1String( "polygon" ), Qt::CaseInsensitive ) )
5621  {
5623  def = def.mid( 8 );
5624  continue;
5625  }
5626  break;
5627  }
5628 
5629  return new QgsProcessingParameterFeatureSource( name, description, types, def, isOptional );
5630 }
5631 
5632 QgsProcessingParameterFeatureSink::QgsProcessingParameterFeatureSink( const QString &name, const QString &description, QgsProcessing::SourceType type, const QVariant &defaultValue, bool optional, bool createByDefault, bool supportsAppend )
5633  : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
5634  , mDataType( type )
5635  , mSupportsAppend( supportsAppend )
5636 {
5637 }
5638 
5640 {
5641  return new QgsProcessingParameterFeatureSink( *this );
5642 }
5643 
5645 {
5646  QVariant var = input;
5647  if ( !var.isValid() )
5648  return mFlags & FlagOptional;
5649 
5650  if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
5651  {
5652  QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
5653  var = fromVar.sink;
5654  }
5655 
5656  if ( var.canConvert<QgsProperty>() )
5657  {
5658  QgsProperty p = var.value< QgsProperty >();
5660  {
5661  var = p.staticValue();
5662  }
5663  else
5664  {
5665  return true;
5666  }
5667  }
5668 
5669  if ( var.type() != QVariant::String )
5670  return false;
5671 
5672  if ( var.toString().isEmpty() )
5673  return mFlags & FlagOptional;
5674 
5675  return true;
5676 }
5677 
5679 {
5680  if ( !value.isValid() )
5681  return QStringLiteral( "None" );
5682 
5683  if ( value.canConvert<QgsProperty>() )
5684  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
5685 
5686  if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
5687  {
5688  QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
5689  if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
5690  {
5691  return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
5692  }
5693  else
5694  {
5695  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
5696  }
5697  }
5698 
5699  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
5700 }
5701 
5703 {
5704  QString code = QStringLiteral( "##%1=" ).arg( mName );
5705  if ( mFlags & FlagOptional )
5706  code += QLatin1String( "optional " );
5707  code += QLatin1String( "sink " );
5708 
5709  switch ( mDataType )
5710  {
5712  code += QLatin1String( "point " );
5713  break;
5714 
5716  code += QLatin1String( "line " );
5717  break;
5718 
5720  code += QLatin1String( "polygon " );
5721  break;
5722 
5724  code += QLatin1String( "table " );
5725  break;
5726 
5727  default:
5728  break;
5729  }
5730 
5731  code += mDefault.toString();
5732  return code.trimmed();
5733 }
5734 
5736 {
5737  return new QgsProcessingOutputVectorLayer( name(), description(), mDataType );
5738 }
5739 
5741 {
5742  if ( auto *lOriginalProvider = originalProvider() )
5743  {
5744  return lOriginalProvider->defaultVectorFileExtension( hasGeometry() );
5745  }
5746  else if ( QgsProcessingProvider *p = provider() )
5747  {
5748  return p->defaultVectorFileExtension( hasGeometry() );
5749  }
5750  else
5751  {
5752  if ( hasGeometry() )
5753  {
5755  }
5756  else
5757  {
5758  return QStringLiteral( "dbf" );
5759  }
5760  }
5761 }
5762 
5764 {
5765  switch ( outputType )
5766  {
5768  {
5769  QString code = QStringLiteral( "QgsProcessingParameterFeatureSink('%1', '%2'" ).arg( name(), description() );
5770  if ( mFlags & FlagOptional )
5771  code += QLatin1String( ", optional=True" );
5772 
5773  code += QStringLiteral( ", type=QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( mDataType ) );
5774 
5775  code += QStringLiteral( ", createByDefault=%1" ).arg( createByDefault() ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
5776  if ( mSupportsAppend )
5777  code += QLatin1String( ", supportsAppend=True" );
5778 
5780  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
5781  return code;
5782  }
5783  }
5784  return QString();
5785 }
5786 
5788 {
5789  const QStringList exts = supportedOutputVectorLayerExtensions();
5790  QStringList filters;
5791  for ( const QString &ext : exts )
5792  {
5793  filters << QObject::tr( "%1 files (*.%2)" ).arg( ext.toUpper(), ext.toLower() );
5794  }
5795  return filters.join( QLatin1String( ";;" ) ) + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
5796 
5797 }
5798 
5800 {
5801  if ( auto *lOriginalProvider = originalProvider() )
5802  {
5803  if ( hasGeometry() )
5804  return lOriginalProvider->supportedOutputVectorLayerExtensions();
5805  else
5806  return lOriginalProvider->supportedOutputTableExtensions();
5807  }
5808  else if ( QgsProcessingProvider *p = provider() )
5809  {
5810  if ( hasGeometry() )
5811  return p->supportedOutputVectorLayerExtensions();
5812  else
5813  return p->supportedOutputTableExtensions();
5814  }
5815  else
5816  {
5818  }
5819 }
5820 
5822 {
5823  return mDataType;
5824 }
5825 
5827 {
5828  switch ( mDataType )
5829  {
5835  return true;
5836 
5841  return false;
5842  }
5843  return true;
5844 }
5845 
5847 {
5848  mDataType = type;
5849 }
5850 
5852 {
5854  map.insert( QStringLiteral( "data_type" ), mDataType );
5855  map.insert( QStringLiteral( "supports_append" ), mSupportsAppend );
5856  return map;
5857 }
5858 
5860 {
5862  mDataType = static_cast< QgsProcessing::SourceType >( map.value( QStringLiteral( "data_type" ) ).toInt() );
5863  mSupportsAppend = map.value( QStringLiteral( "supports_append" ), false ).toBool();
5864  return true;
5865 }
5866 
5868 {
5870  return QStringLiteral( "memory:%1" ).arg( description() );
5871  else
5873 }
5874 
5875 QgsProcessingParameterFeatureSink *QgsProcessingParameterFeatureSink::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5876 {
5878  QString def = definition;
5879  if ( def.startsWith( QLatin1String( "point" ), Qt::CaseInsensitive ) )
5880  {
5882  def = def.mid( 6 );
5883  }
5884  else if ( def.startsWith( QLatin1String( "line" ), Qt::CaseInsensitive ) )
5885  {
5887  def = def.mid( 5 );
5888  }
5889  else if ( def.startsWith( QLatin1String( "polygon" ), Qt::CaseInsensitive ) )
5890  {
5892  def = def.mid( 8 );
5893  }
5894  else if ( def.startsWith( QLatin1String( "table" ), Qt::CaseInsensitive ) )
5895  {
5897  def = def.mid( 6 );
5898  }
5899 
5900  return new QgsProcessingParameterFeatureSink( name, description, type, definition, isOptional );
5901 }
5902 
5904 {
5905  return mSupportsAppend;
5906 }
5907 
5909 {
5910  mSupportsAppend = supportsAppend;
5911 }
5912 
5913 QgsProcessingParameterRasterDestination::QgsProcessingParameterRasterDestination( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, bool createByDefault )
5914  : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
5915 {
5916 }
5917 
5919 {
5920  return new QgsProcessingParameterRasterDestination( *this );
5921 }
5922 
5924 {
5925  QVariant var = input;
5926  if ( !var.isValid() )
5927  return mFlags & FlagOptional;
5928 
5929  if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
5930  {
5931  QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
5932  var = fromVar.sink;
5933  }
5934 
5935  if ( var.canConvert<QgsProperty>() )
5936  {
5937  QgsProperty p = var.value< QgsProperty >();
5939  {
5940  var = p.staticValue();
5941  }
5942  else
5943  {
5944  return true;
5945  }
5946  }
5947 
5948  if ( var.type() != QVariant::String )
5949  return false;
5950 
5951  if ( var.toString().isEmpty() )
5952  return mFlags & FlagOptional;
5953 
5954  return true;
5955 }
5956 
5958 {
5959  if ( !value.isValid() )
5960  return QStringLiteral( "None" );
5961 
5962  if ( value.canConvert<QgsProperty>() )
5963  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
5964 
5965  if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
5966  {
5967  QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
5968  if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
5969  {
5970  return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
5971  }
5972  else
5973  {
5974  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
5975  }
5976  }
5977 
5978  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
5979 }
5980 
5982 {
5983  return new QgsProcessingOutputRasterLayer( name(), description() );
5984 }
5985 
5987 {
5988  if ( auto *lOriginalProvider = originalProvider() )
5989  {
5990  return lOriginalProvider->defaultRasterFileExtension();
5991  }
5992  else if ( QgsProcessingProvider *p = provider() )
5993  {
5994  return p->defaultRasterFileExtension();
5995  }
5996  else
5997  {
5999  }
6000 }
6001 
6003 {
6004  const QStringList exts = supportedOutputRasterLayerExtensions();
6005  QStringList filters;
6006  for ( const QString &ext : exts )
6007  {
6008  filters << QObject::tr( "%1 files (*.%2)" ).arg( ext.toUpper(), ext.toLower() );
6009  }
6010  return filters.join( QLatin1String( ";;" ) ) + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
6011 }
6012 
6014 {
6015  if ( auto *lOriginalProvider = originalProvider() )
6016  {
6017  return lOriginalProvider->supportedOutputRasterLayerExtensions();
6018  }
6019  else if ( QgsProcessingProvider *p = provider() )
6020  {
6021  return p->supportedOutputRasterLayerExtensions();
6022  }
6023  else
6024  {
6026  }
6027 }
6028 
6029 QgsProcessingParameterRasterDestination *QgsProcessingParameterRasterDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6030 {
6031  return new QgsProcessingParameterRasterDestination( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
6032 }
6033 
6034 
6035 QgsProcessingParameterFileDestination::QgsProcessingParameterFileDestination( const QString &name, const QString &description, const QString &fileFilter, const QVariant &defaultValue, bool optional, bool createByDefault )
6036  : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
6037  , mFileFilter( fileFilter.isEmpty() ? QObject::tr( "All files (*.*)" ) : fileFilter )
6038 {
6039 
6040 }
6041 
6043 {
6044  return new QgsProcessingParameterFileDestination( *this );
6045 }
6046 
6048 {
6049  QVariant var = input;
6050  if ( !var.isValid() )
6051  return mFlags & FlagOptional;
6052 
6053  if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
6054  {
6055  QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
6056  var = fromVar.sink;
6057  }
6058 
6059  if ( var.canConvert<QgsProperty>() )
6060  {
6061  QgsProperty p = var.value< QgsProperty >();
6063  {
6064  var = p.staticValue();
6065  }
6066  else
6067  {
6068  return true;
6069  }
6070  }
6071 
6072  if ( var.type() != QVariant::String )
6073  return false;
6074 
6075  if ( var.toString().isEmpty() )
6076  return mFlags & FlagOptional;
6077 
6078  // possible enhancement - check that value is compatible with file filter?
6079 
6080  return true;
6081 }
6082 
6084 {
6085  if ( !value.isValid() )
6086  return QStringLiteral( "None" );
6087 
6088  if ( value.canConvert<QgsProperty>() )
6089  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
6090 
6091  if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
6092  {
6093  QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
6094  if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
6095  {
6096  return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
6097  }
6098  else
6099  {
6100  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
6101  }
6102  }
6103 
6104  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
6105 }
6106 
6108 {
6109  if ( !mFileFilter.isEmpty() && mFileFilter.contains( QStringLiteral( "htm" ), Qt::CaseInsensitive ) )
6110  {
6111  return new QgsProcessingOutputHtml( name(), description() );
6112  }
6113  else
6114  {
6115  return new QgsProcessingOutputFile( name(), description() );
6116  }
6117 }
6118 
6120 {
6121  if ( mFileFilter.isEmpty() || mFileFilter == QObject::tr( "All files (*.*)" ) )
6122  return QStringLiteral( "file" );
6123 
6124  // get first extension from filter
6125  QRegularExpression rx( QStringLiteral( ".*?\\(\\*\\.([a-zA-Z0-9._]+).*" ) );
6126  QRegularExpressionMatch match = rx.match( mFileFilter );
6127  if ( !match.hasMatch() )
6128  return QStringLiteral( "file" );
6129 
6130  return match.captured( 1 );
6131 }
6132 
6134 {
6135  switch ( outputType )
6136  {
6138  {
6139  QString code = QStringLiteral( "QgsProcessingParameterFileDestination('%1', '%2'" ).arg( name(), description() );
6140  if ( mFlags & FlagOptional )
6141  code += QLatin1String( ", optional=True" );
6142 
6143  code += QStringLiteral( ", fileFilter=%1" ).arg( QgsProcessingUtils::stringToPythonLiteral( mFileFilter ) );
6144 
6145  code += QStringLiteral( ", createByDefault=%1" ).arg( createByDefault() ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
6146 
6148  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
6149  return code;
6150  }
6151  }
6152  return QString();
6153 }
6154 
6156 {
6157  return ( fileFilter().isEmpty() ? QString() : fileFilter() + QStringLiteral( ";;" ) ) + QObject::tr( "All files (*.*)" );
6158 }
6159 
6161 {
6162  return mFileFilter;
6163 }
6164 
6166 {
6167  mFileFilter = fileFilter;
6168 }
6169 
6171 {
6173  map.insert( QStringLiteral( "file_filter" ), mFileFilter );
6174  return map;
6175 }
6176 
6178 {
6180  mFileFilter = map.value( QStringLiteral( "file_filter" ) ).toString();
6181  return true;
6182 
6183 }
6184 
6185 QgsProcessingParameterFileDestination *QgsProcessingParameterFileDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6186 {
6187  return new QgsProcessingParameterFileDestination( name, description, QString(), definition.isEmpty() ? QVariant() : definition, isOptional );
6188 }
6189 
6190 QgsProcessingParameterFolderDestination::QgsProcessingParameterFolderDestination( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, bool createByDefault )
6191  : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
6192 {}
6193 
6195 {
6196  return new QgsProcessingParameterFolderDestination( *this );
6197 }
6198 
6200 {
6201  QVariant var = input;
6202  if ( !var.isValid() )
6203  return mFlags & FlagOptional;
6204 
6205  if ( var.canConvert<QgsProperty>() )
6206  {
6207  QgsProperty p = var.value< QgsProperty >();
6209  {
6210  var = p.staticValue();
6211  }
6212  else
6213  {
6214  return true;
6215  }
6216  }
6217 
6218  if ( var.type() != QVariant::String )
6219  return false;
6220 
6221  if ( var.toString().isEmpty() )
6222  return mFlags & FlagOptional;
6223 
6224  return true;
6225 }
6226 
6228 {
6229  return new QgsProcessingOutputFolder( name(), description() );
6230 }
6231 
6233 {
6234  return QString();
6235 }
6236 
6237 QgsProcessingParameterFolderDestination *QgsProcessingParameterFolderDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6238 {
6239  return new QgsProcessingParameterFolderDestination( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
6240 }
6241 
6242 QgsProcessingDestinationParameter::QgsProcessingDestinationParameter( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, bool createByDefault )
6243  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
6244  , mCreateByDefault( createByDefault )
6245 {
6246 
6247 }
6248 
6250 {
6252  map.insert( QStringLiteral( "supports_non_file_outputs" ), mSupportsNonFileBasedOutputs );
6253  map.insert( QStringLiteral( "create_by_default" ), mCreateByDefault );
6254  return map;
6255 }
6256 
6258 {
6260  mSupportsNonFileBasedOutputs = map.value( QStringLiteral( "supports_non_file_outputs" ) ).toBool();
6261  mCreateByDefault = map.value( QStringLiteral( "create_by_default" ), QStringLiteral( "1" ) ).toBool();
6262  return true;
6263 }
6264 
6266 {
6267  switch ( outputType )
6268  {
6270  {
6271  // base class method is probably not much use
6272  if ( QgsProcessingParameterType *t = QgsApplication::processingRegistry()->parameterType( type() ) )
6273  {
6274  QString code = t->className() + QStringLiteral( "('%1', '%2'" ).arg( name(), description() );
6275  if ( mFlags & FlagOptional )
6276  code += QLatin1String( ", optional=True" );
6277 
6278  code += QStringLiteral( ", createByDefault=%1" ).arg( mCreateByDefault ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
6279 
6281  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
6282  return code;
6283  }
6284  break;
6285  }
6286  }
6287  // oh well, we tried
6288  return QString();
6289 }
6290 
6292 {
6293  return QObject::tr( "Default extension" ) + QStringLiteral( " (*." ) + defaultFileExtension() + ')';
6294 }
6295 
6297 {
6298  // sanitize name to avoid multiple . in the filename. E.g. when name() contain
6299  // backend command name having a "." inside as in case of grass commands
6300  QRegularExpression rx( QStringLiteral( "[.]" ) );
6301  QString sanitizedName = name();
6302  sanitizedName.replace( rx, QStringLiteral( "_" ) );
6303 
6304  if ( defaultFileExtension().isEmpty() )
6305  {
6306  return QgsProcessingUtils::generateTempFilename( sanitizedName );
6307  }
6308  else
6309  {
6310  return QgsProcessingUtils::generateTempFilename( sanitizedName + '.' + defaultFileExtension() );
6311  }
6312 }
6313 
6314 bool QgsProcessingDestinationParameter::isSupportedOutputValue( const QVariant &value, QgsProcessingContext &context, QString &error ) const
6315 {
6316  if ( auto *lOriginalProvider = originalProvider() )
6317  return lOriginalProvider->isSupportedOutputValue( value, this, context, error );
6318  else if ( provider() )
6319  return provider()->isSupportedOutputValue( value, this, context, error );
6320 
6321  return true;
6322 }
6323 
6325 {
6326  return mCreateByDefault;
6327 }
6328 
6330 {
6331  mCreateByDefault = createByDefault;
6332 }
6333 
6334 QgsProcessingParameterVectorDestination::QgsProcessingParameterVectorDestination( const QString &name, const QString &description, QgsProcessing::SourceType type, const QVariant &defaultValue, bool optional, bool createByDefault )
6335  : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
6336  , mDataType( type )
6337 {
6338 
6339 }
6340 
6342 {
6343  return new QgsProcessingParameterVectorDestination( *this );
6344 }
6345 
6347 {
6348  QVariant var = input;
6349  if ( !var.isValid() )
6350  return mFlags & FlagOptional;
6351 
6352  if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
6353  {
6354  QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
6355  var = fromVar.sink;
6356  }
6357 
6358  if ( var.canConvert<QgsProperty>() )
6359  {
6360  QgsProperty p = var.value< QgsProperty >();
6362  {
6363  var = p.staticValue();
6364  }
6365  else
6366  {
6367  return true;
6368  }
6369  }
6370 
6371  if ( var.type() != QVariant::String )
6372  return false;
6373 
6374  if ( var.toString().isEmpty() )
6375  return mFlags & FlagOptional;
6376 
6377  return true;
6378 }
6379 
6381 {
6382  if ( !value.isValid() )
6383  return QStringLiteral( "None" );
6384 
6385  if ( value.canConvert<QgsProperty>() )
6386  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
6387 
6388  if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
6389  {
6390  QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
6391  if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
6392  {
6393  return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
6394  }
6395  else
6396  {
6397  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
6398  }
6399  }
6400 
6401  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
6402 }
6403 
6405 {
6406  QString code = QStringLiteral( "##%1=" ).arg( mName );
6407  if ( mFlags & FlagOptional )
6408  code += QLatin1String( "optional " );
6409  code += QLatin1String( "vectorDestination " );
6410 
6411  switch ( mDataType )
6412  {
6414  code += QLatin1String( "point " );
6415  break;
6416 
6418  code += QLatin1String( "line " );
6419  break;
6420 
6422  code += QLatin1String( "polygon " );
6423  break;
6424 
6425  default:
6426  break;
6427  }
6428 
6429  code += mDefault.toString();
6430  return code.trimmed();
6431 }
6432 
6434 {
6435  return new QgsProcessingOutputVectorLayer( name(), description(), mDataType );
6436 }
6437 
6439 {
6440  if ( auto *lOriginalProvider = originalProvider() )
6441  {
6442  return lOriginalProvider->defaultVectorFileExtension( hasGeometry() );
6443  }
6444  else if ( QgsProcessingProvider *p = provider() )
6445  {
6446  return p->defaultVectorFileExtension( hasGeometry() );
6447  }
6448  else
6449  {
6450  if ( hasGeometry() )
6451  {
6453  }
6454  else
6455  {
6456  return QStringLiteral( "dbf" );
6457  }
6458  }
6459 }
6460 
6462 {
6463  switch ( outputType )
6464  {
6466  {
6467  QString code = QStringLiteral( "QgsProcessingParameterVectorDestination('%1', '%2'" ).arg( name(), description() );
6468  if ( mFlags & FlagOptional )
6469  code += QLatin1String( ", optional=True" );
6470 
6471  code += QStringLiteral( ", type=QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( mDataType ) );
6472 
6473  code += QStringLiteral( ", createByDefault=%1" ).arg( createByDefault() ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
6474 
6476  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
6477  return code;
6478  }
6479  }
6480  return QString();
6481 }
6482 
6484 {
6485  const QStringList exts = supportedOutputVectorLayerExtensions();
6486  QStringList filters;
6487  for ( const QString &ext : exts )
6488  {
6489  filters << QObject::tr( "%1 files (*.%2)" ).arg( ext.toUpper(), ext.toLower() );
6490  }
6491  return filters.join( QLatin1String( ";;" ) ) + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
6492 }
6493 
6495 {
6496  if ( auto *lOriginalProvider = originalProvider() )
6497  {
6498  if ( hasGeometry() )
6499  return lOriginalProvider->supportedOutputVectorLayerExtensions();
6500  else
6501  return lOriginalProvider->supportedOutputTableExtensions();
6502  }
6503  else if ( QgsProcessingProvider *p = provider() )
6504  {
6505  if ( hasGeometry() )
6506  return p->supportedOutputVectorLayerExtensions();
6507  else
6508  return p->supportedOutputTableExtensions();
6509  }
6510  else
6511  {
6513  }
6514 }
6515 
6517 {
6518  return mDataType;
6519 }
6520 
6522 {
6523  switch ( mDataType )
6524  {
6530  return true;
6531 
6536  return false;
6537  }
6538  return true;
6539 }
6540 
6542 {
6543  mDataType = type;
6544 }
6545 
6547 {
6549  map.insert( QStringLiteral( "data_type" ), mDataType );
6550  return map;
6551 }
6552 
6554 {
6556  mDataType = static_cast< QgsProcessing::SourceType >( map.value( QStringLiteral( "data_type" ) ).toInt() );
6557  return true;
6558 }
6559 
6560 QgsProcessingParameterVectorDestination *QgsProcessingParameterVectorDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6561 {
6563  QString def = definition;
6564  if ( def.startsWith( QLatin1String( "point" ), Qt::CaseInsensitive ) )
6565  {
6567  def = def.mid( 6 );
6568  }
6569  else if ( def.startsWith( QLatin1String( "line" ), Qt::CaseInsensitive ) )
6570  {
6572  def = def.mid( 5 );
6573  }
6574  else if ( def.startsWith( QLatin1String( "polygon" ), Qt::CaseInsensitive ) )
6575  {
6577  def = def.mid( 8 );
6578  }
6579 
6580  return new QgsProcessingParameterVectorDestination( name, description, type, definition, isOptional );
6581 }
6582 
6583 QgsProcessingParameterBand::QgsProcessingParameterBand( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayerParameterName, bool optional, bool allowMultiple )
6584  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
6585  , mParentLayerParameterName( parentLayerParameterName )
6586  , mAllowMultiple( allowMultiple )
6587 {
6588 
6589 }
6590 
6592 {
6593  return new QgsProcessingParameterBand( *this );
6594 }
6595 
6597 {
6598  if ( !input.isValid() )
6599  return mFlags & FlagOptional;
6600 
6601  if ( input.canConvert<QgsProperty>() )
6602  {
6603  return true;
6604  }
6605 
6606  if ( input.type() == QVariant::List || input.type() == QVariant::StringList )
6607  {
6608  if ( !mAllowMultiple )
6609  return false;
6610 
6611  if ( input.toList().isEmpty() && !( mFlags & FlagOptional ) )
6612  return false;
6613  }
6614  else
6615  {
6616  bool ok = false;
6617  double res = input.toInt( &ok );
6618  Q_UNUSED( res )
6619  if ( !ok )
6620  return mFlags & FlagOptional;
6621  }
6622  return true;
6623 }
6624 
6626 {
6627  return mAllowMultiple;
6628 }
6629 
6631 {
6632  mAllowMultiple = allowMultiple;
6633 }
6634 
6636 {
6637  if ( !value.isValid() )
6638  return QStringLiteral( "None" );
6639 
6640  if ( value.canConvert<QgsProperty>() )
6641  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
6642 
6643  if ( value.type() == QVariant::List )
6644  {
6645  QStringList parts;
6646  QVariantList values = value.toList();
6647  for ( auto it = values.constBegin(); it != values.constEnd(); ++it )
6648  {
6649  parts << QString::number( static_cast< int >( it->toDouble() ) );
6650  }
6651  return parts.join( ',' ).prepend( '[' ).append( ']' );
6652  }
6653  else if ( value.type() == QVariant::StringList )
6654  {
6655  QStringList parts;
6656  QStringList values = value.toStringList();
6657  for ( auto it = values.constBegin(); it != values.constEnd(); ++it )
6658  {
6659  parts << QString::number( static_cast< int >( it->toDouble() ) );
6660  }
6661  return parts.join( ',' ).prepend( '[' ).append( ']' );
6662  }
6663 
6664  return value.toString();
6665 }
6666 
6668 {
6669  QString code = QStringLiteral( "##%1=" ).arg( mName );
6670  if ( mFlags & FlagOptional )
6671  code += QLatin1String( "optional " );
6672  code += QLatin1String( "band " );
6673 
6674  if ( mAllowMultiple )
6675  code += QLatin1String( "multiple " );
6676 
6677  code += mParentLayerParameterName + ' ';
6678 
6679  code += mDefault.toString();
6680  return code.trimmed();
6681 }
6682 
6684 {
6685  QStringList depends;
6686  if ( !mParentLayerParameterName.isEmpty() )
6687  depends << mParentLayerParameterName;
6688  return depends;
6689 }
6690 
6692 {
6693  switch ( outputType )
6694  {
6696  {
6697  QString code = QStringLiteral( "QgsProcessingParameterBand('%1', '%2'" ).arg( name(), description() );
6698  if ( mFlags & FlagOptional )
6699  code += QLatin1String( ", optional=True" );
6700 
6701  code += QStringLiteral( ", parentLayerParameterName='%1'" ).arg( mParentLayerParameterName );
6702  code += QStringLiteral( ", allowMultiple=%1" ).arg( mAllowMultiple ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
6703 
6705  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
6706  return code;
6707  }
6708  }
6709  return QString();
6710 }
6711 
6713 {
6714  return mParentLayerParameterName;
6715 }
6716 
6717 void QgsProcessingParameterBand::setParentLayerParameterName( const QString &parentLayerParameterName )
6718 {
6719  mParentLayerParameterName = parentLayerParameterName;
6720 }
6721 
6723 {
6725  map.insert( QStringLiteral( "parent_layer" ), mParentLayerParameterName );
6726  map.insert( QStringLiteral( "allow_multiple" ), mAllowMultiple );
6727  return map;
6728 }
6729 
6730 bool QgsProcessingParameterBand::fromVariantMap( const QVariantMap &map )
6731 {
6733  mParentLayerParameterName = map.value( QStringLiteral( "parent_layer" ) ).toString();
6734  mAllowMultiple = map.value( QStringLiteral( "allow_multiple" ) ).toBool();
6735  return true;
6736 }
6737 
6738 QgsProcessingParameterBand *QgsProcessingParameterBand::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6739 {
6740  QString parent;
6741  QString def = definition;
6742  bool allowMultiple = false;
6743 
6744  if ( def.startsWith( QLatin1String( "multiple" ), Qt::CaseInsensitive ) )
6745  {
6746  allowMultiple = true;
6747  def = def.mid( 8 ).trimmed();
6748  }
6749 
6750  QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*)$" ) );
6751  QRegularExpressionMatch m = re.match( def );
6752  if ( m.hasMatch() )
6753  {
6754  parent = m.captured( 1 ).trimmed();
6755  def = m.captured( 2 );
6756  }
6757  else
6758  {
6759  parent = def;
6760  def.clear();
6761  }
6762 
6763  return new QgsProcessingParameterBand( name, description, def.isEmpty() ? QVariant() : def, parent, isOptional, allowMultiple );
6764 }
6765 
6766 //
6767 // QgsProcessingParameterDistance
6768 //
6769 
6770 QgsProcessingParameterDistance::QgsProcessingParameterDistance( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentParameterName, bool optional, double minValue, double maxValue )
6771  : QgsProcessingParameterNumber( name, description, Double, defaultValue, optional, minValue, maxValue )
6772  , mParentParameterName( parentParameterName )
6773 {
6774 
6775 }
6776 
6778 {
6779  return new QgsProcessingParameterDistance( *this );
6780 }
6781 
6783 {
6784  return typeName();
6785 }
6786 
6788 {
6789  QStringList depends;
6790  if ( !mParentParameterName.isEmpty() )
6791  depends << mParentParameterName;
6792  return depends;
6793 }
6794 
6796 {
6797  switch ( outputType )
6798  {
6800  {
6801  QString code = QStringLiteral( "QgsProcessingParameterDistance('%1', '%2'" ).arg( name(), description() );
6802  if ( mFlags & FlagOptional )
6803  code += QLatin1String( ", optional=True" );
6804 
6805  code += QStringLiteral( ", parentParameterName='%1'" ).arg( mParentParameterName );
6806 
6807  if ( minimum() != std::numeric_limits<double>::lowest() + 1 )
6808  code += QStringLiteral( ", minValue=%1" ).arg( minimum() );
6809  if ( maximum() != std::numeric_limits<double>::max() )
6810  code += QStringLiteral( ", maxValue=%1" ).arg( maximum() );
6812  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
6813  return code;
6814  }
6815  }
6816  return QString();
6817 }
6818 
6820 {
6821  return mParentParameterName;
6822 }
6823 
6824 void QgsProcessingParameterDistance::setParentParameterName( const QString &parentParameterName )
6825 {
6826  mParentParameterName = parentParameterName;
6827 }
6828 
6830 {
6831  QVariantMap map = QgsProcessingParameterNumber::toVariantMap();
6832  map.insert( QStringLiteral( "parent" ), mParentParameterName );
6833  map.insert( QStringLiteral( "default_unit" ), static_cast< int >( mDefaultUnit ) );
6834  return map;
6835 }
6836 
6838 {
6840  mParentParameterName = map.value( QStringLiteral( "parent" ) ).toString();
6841  mDefaultUnit = static_cast< QgsUnitTypes::DistanceUnit>( map.value( QStringLiteral( "default_unit" ), QgsUnitTypes::DistanceUnknownUnit ).toInt() );
6842  return true;
6843 }
6844 
6845 
6846 //
6847 // QgsProcessingParameterScale
6848 //
6849 
6850 QgsProcessingParameterScale::QgsProcessingParameterScale( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
6851  : QgsProcessingParameterNumber( name, description, Double, defaultValue, optional )
6852 {
6853 
6854 }
6855 
6857 {
6858  return new QgsProcessingParameterScale( *this );
6859 }
6860 
6862 {
6863  return typeName();
6864 }
6865 
6867 {
6868  switch ( outputType )
6869  {
6871  {
6872  QString code = QStringLiteral( "QgsProcessingParameterScale('%1', '%2'" ).arg( name(), description() );
6873  if ( mFlags & FlagOptional )
6874  code += QLatin1String( ", optional=True" );
6876  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
6877  return code;
6878  }
6879  }
6880  return QString();
6881 }
6882 
6883 QgsProcessingParameterScale *QgsProcessingParameterScale::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6884 {
6885  return new QgsProcessingParameterScale( name, description, definition.isEmpty() ? QVariant()
6886  : ( definition.toLower().trimmed() == QLatin1String( "none" ) ? QVariant() : definition ), isOptional );
6887 }
6888 
6889 
6890 //
6891 // QgsProcessingParameterLayout
6892 //
6893 
6894 QgsProcessingParameterLayout::QgsProcessingParameterLayout( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
6895  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
6896 {}
6897 
6899 {
6900  return new QgsProcessingParameterLayout( *this );
6901 }
6902 
6904 {
6905  if ( !value.isValid() || value.isNull() )
6906  return QStringLiteral( "None" );
6907 
6908  if ( value.canConvert<QgsProperty>() )
6909  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
6910 
6911  QString s = value.toString();
6913 }
6914 
6916 {
6917  QString code = QStringLiteral( "##%1=" ).arg( mName );
6918  if ( mFlags & FlagOptional )
6919  code += QLatin1String( "optional " );
6920  code += QLatin1String( "layout " );
6921 
6922  code += mDefault.toString();
6923  return code.trimmed();
6924 }
6925 
6927 {
6928  switch ( outputType )
6929  {
6931  {
6932  QString code = QStringLiteral( "QgsProcessingParameterLayout('%1', '%2'" ).arg( name(), description() );
6933  if ( mFlags & FlagOptional )
6934  code += QLatin1String( ", optional=True" );
6936  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
6937  return code;
6938  }
6939  }
6940  return QString();
6941 }
6942 
6943 QgsProcessingParameterLayout *QgsProcessingParameterLayout::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6944 {
6945  QString def = definition;
6946 
6947  if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
6948  def = def.mid( 1 );
6949  if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
6950  def.chop( 1 );
6951 
6952  QVariant defaultValue = def;
6953  if ( def == QLatin1String( "None" ) )
6954  defaultValue = QVariant();
6955 
6956  return new QgsProcessingParameterLayout( name, description, defaultValue, isOptional );
6957 }
6958 
6959 
6960 //
6961 // QString mParentLayerParameterName;
6962 //
6963 
6964 QgsProcessingParameterLayoutItem::QgsProcessingParameterLayoutItem( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayoutParameterName, int itemType, bool optional )
6965  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
6966  , mParentLayoutParameterName( parentLayoutParameterName )
6967  , mItemType( itemType )
6968 {
6969 
6970 }
6971 
6973 {
6974  return new QgsProcessingParameterLayoutItem( *this );
6975 }
6976 
6978 {
6979  if ( !value.isValid() || value.isNull() )
6980  return QStringLiteral( "None" );
6981 
6982  if ( value.canConvert<QgsProperty>() )
6983  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
6984 
6985  QString s = value.toString();
6987 }
6988 
6990 {
6991  QString code = QStringLiteral( "##%1=" ).arg( mName );
6992  if ( mFlags & FlagOptional )
6993  code += QLatin1String( "optional " );
6994  code += QLatin1String( "layoutitem " );
6995  if ( mItemType >= 0 )
6996  code += QString::number( mItemType ) + ' ';
6997 
6998  code += mParentLayoutParameterName + ' ';
6999 
7000  code += mDefault.toString();
7001  return code.trimmed();
7002 }
7003 
7005 {
7006  switch ( outputType )
7007  {
7009  {
7010  QString code = QStringLiteral( "QgsProcessingParameterLayoutItem('%1', '%2'" ).arg( name(), description() );
7011  if ( mFlags & FlagOptional )
7012  code += QLatin1String( ", optional=True" );
7013 
7014  if ( mItemType >= 0 )
7015  code += QStringLiteral( ", itemType=%1" ).arg( mItemType );
7016 
7017  code += QStringLiteral( ", parentLayoutParameterName='%1'" ).arg( mParentLayoutParameterName );
7018 
7020  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7021  return code;
7022  }
7023  }
7024  return QString();
7025 }
7026 
7028 {
7030  map.insert( QStringLiteral( "parent_layout" ), mParentLayoutParameterName );
7031  map.insert( QStringLiteral( "item_type" ), mItemType );
7032  return map;
7033 }
7034 
7036 {
7038  mParentLayoutParameterName = map.value( QStringLiteral( "parent_layout" ) ).toString();
7039  mItemType = map.value( QStringLiteral( "item_type" ) ).toInt();
7040  return true;
7041 }
7042 
7044 {
7045  QStringList depends;
7046  if ( !mParentLayoutParameterName.isEmpty() )
7047  depends << mParentLayoutParameterName;
7048  return depends;
7049 }
7050 
7051 QgsProcessingParameterLayoutItem *QgsProcessingParameterLayoutItem::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7052 {
7053  QString parent;
7054  QString def = definition;
7055  int itemType = -1;
7056  QRegularExpression re( QStringLiteral( "(\\d+)?\\s*(.*?)\\s+(.*)$" ) );
7057  QRegularExpressionMatch m = re.match( def );
7058  if ( m.hasMatch() )
7059  {
7060  itemType = m.captured( 1 ).trimmed().isEmpty() ? -1 : m.captured( 1 ).trimmed().toInt();
7061  parent = m.captured( 2 ).trimmed().isEmpty() ? m.captured( 3 ).trimmed() : m.captured( 2 ).trimmed();
7062  def = !m.captured( 2 ).trimmed().isEmpty() ? m.captured( 3 ) : QString();
7063  }
7064  else
7065  {
7066  parent = def;
7067  def.clear();
7068  }
7069 
7070  return new QgsProcessingParameterLayoutItem( name, description, def.isEmpty() ? QVariant() : def, parent, itemType, isOptional );
7071 }
7072 
7074 {
7075  return mParentLayoutParameterName;
7076 }
7077 
7079 {
7080  mParentLayoutParameterName = name;
7081 }
7082 
7084 {
7085  return mItemType;
7086 }
7087 
7089 {
7090  mItemType = type;
7091 }
7092 
7093 //
7094 // QgsProcessingParameterColor
7095 //
7096 
7097 QgsProcessingParameterColor::QgsProcessingParameterColor( const QString &name, const QString &description, const QVariant &defaultValue, bool opacityEnabled, bool optional )
7098  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
7099  , mAllowOpacity( opacityEnabled )
7100 {
7101 
7102 }
7103 
7105 {
7106  return new QgsProcessingParameterColor( *this );
7107 }
7108 
7110 {
7111  if ( !value.isValid() || value.isNull() )
7112  return QStringLiteral( "None" );
7113 
7114  if ( value.canConvert<QgsProperty>() )
7115  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
7116 
7117  if ( value.canConvert< QColor >() && !value.value< QColor >().isValid() )
7118  return QStringLiteral( "QColor()" );
7119 
7120  if ( value.canConvert< QColor >() )
7121  {
7122  QColor c = value.value< QColor >();
7123  if ( !mAllowOpacity || c.alpha() == 255 )
7124  return QStringLiteral( "QColor(%1, %2, %3)" ).arg( c.red() ).arg( c.green() ).arg( c.blue() );
7125  else
7126  return QStringLiteral( "QColor(%1, %2, %3, %4)" ).arg( c.red() ).arg( c.green() ).arg( c.blue() ).arg( c.alpha() );
7127  }
7128 
7129  QString s = value.toString();
7131 }
7132 
7134 {
7135  QString code = QStringLiteral( "##%1=" ).arg( mName );
7136  if ( mFlags & FlagOptional )
7137  code += QLatin1String( "optional " );
7138  code += QLatin1String( "color " );
7139 
7140  if ( mAllowOpacity )
7141  code += QLatin1String( "withopacity " );
7142 
7143  code += mDefault.toString();
7144  return code.trimmed();
7145 }
7146 
7148 {
7149  switch ( outputType )
7150  {
7152  {
7153  QString code = QStringLiteral( "QgsProcessingParameterColor('%1', '%2'" ).arg( name(), description() );
7154  if ( mFlags & FlagOptional )
7155  code += QLatin1String( ", optional=True" );
7156 
7157  code += QStringLiteral( ", opacityEnabled=%1" ).arg( mAllowOpacity ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
7158 
7160  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7161  return code;
7162  }
7163  }
7164  return QString();
7165 }
7166 
7168 {
7169  if ( !input.isValid() && ( mDefault.isValid() && ( !mDefault.toString().isEmpty() || mDefault.value< QColor >().isValid() ) ) )
7170  return true;
7171 
7172  if ( !input.isValid() )
7173  return mFlags & FlagOptional;
7174 
7175  if ( input.type() == QVariant::Color )
7176  {
7177  return true;
7178  }
7179  else if ( input.canConvert<QgsProperty>() )
7180  {
7181  return true;
7182  }
7183 
7184  if ( input.type() != QVariant::String || input.toString().isEmpty() )
7185  return mFlags & FlagOptional;
7186 
7187  bool containsAlpha = false;
7188  return QgsSymbolLayerUtils::parseColorWithAlpha( input.toString(), containsAlpha ).isValid();
7189 }
7190 
7192 {
7194  map.insert( QStringLiteral( "opacityEnabled" ), mAllowOpacity );
7195  return map;
7196 }
7197 
7198 bool QgsProcessingParameterColor::fromVariantMap( const QVariantMap &map )
7199 {
7201  mAllowOpacity = map.value( QStringLiteral( "opacityEnabled" ) ).toBool();
7202  return true;
7203 }
7204 
7206 {
7207  return mAllowOpacity;
7208 }
7209 
7211 {
7212  mAllowOpacity = enabled;
7213 }
7214 
7215 QgsProcessingParameterColor *QgsProcessingParameterColor::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7216 {
7217  QString def = definition;
7218 
7219  bool allowOpacity = false;
7220  if ( def.startsWith( QLatin1String( "withopacity" ), Qt::CaseInsensitive ) )
7221  {
7222  allowOpacity = true;
7223  def = def.mid( 12 );
7224  }
7225 
7226  if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
7227  def = def.mid( 1 );
7228  if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
7229  def.chop( 1 );
7230 
7231  QVariant defaultValue = def;
7232  if ( def == QLatin1String( "None" ) )
7233  defaultValue = QVariant();
7234 
7235  return new QgsProcessingParameterColor( name, description, defaultValue, allowOpacity, isOptional );
7236 }
7237 
7238 //
7239 // QgsProcessingParameterCoordinateOperation
7240 //
7241 QgsProcessingParameterCoordinateOperation::QgsProcessingParameterCoordinateOperation( const QString &name, const QString &description, const QVariant &defaultValue, const QString &sourceCrsParameterName, const QString &destinationCrsParameterName, const QVariant &staticSourceCrs, const QVariant &staticDestinationCrs, bool optional )
7242  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
7243  , mSourceParameterName( sourceCrsParameterName )
7244  , mDestParameterName( destinationCrsParameterName )
7245  , mSourceCrs( staticSourceCrs )
7246  , mDestCrs( staticDestinationCrs )
7247 {
7248 
7249 }
7250 
7252 {
7253  return new QgsProcessingParameterCoordinateOperation( * this );
7254 }
7255 
7257 {
7258  if ( !value.isValid() || value.isNull() )
7259  return QStringLiteral( "None" );
7260 
7261  if ( value.canConvert<QgsCoordinateReferenceSystem>() )
7262  {
7263  if ( !value.value< QgsCoordinateReferenceSystem >().isValid() )
7264  return QStringLiteral( "QgsCoordinateReferenceSystem()" );
7265  else
7266  return QStringLiteral( "QgsCoordinateReferenceSystem('%1')" ).arg( value.value< QgsCoordinateReferenceSystem >().authid() );
7267  }
7268 
7269  if ( value.canConvert<QgsProperty>() )
7270  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
7271 
7272  QVariantMap p;
7273  p.insert( name(), value );
7274  QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
7275  if ( layer )
7277 
7278  QString s = value.toString();
7280 }
7281 
7283 {
7284  QString code = QStringLiteral( "##%1=" ).arg( mName );
7285  if ( mFlags & FlagOptional )
7286  code += QLatin1String( "optional " );
7287  code += QLatin1String( "coordinateoperation " );
7288 
7289  code += mDefault.toString();
7290  return code.trimmed();
7291 }
7292 
7294 {
7295  switch ( outputType )
7296  {
7298  {
7300  QString code = QStringLiteral( "QgsProcessingParameterCoordinateOperation('%1', '%2'" ).arg( name(), description() );
7301  if ( mFlags & FlagOptional )
7302  code += QLatin1String( ", optional=True" );
7303  if ( !mSourceParameterName.isEmpty() )
7304  code += QStringLiteral( ", sourceCrsParameterName=%1" ).arg( valueAsPythonString( mSourceParameterName, c ) );
7305  if ( !mDestParameterName.isEmpty() )
7306  code += QStringLiteral( ", destinationCrsParameterName=%1" ).arg( valueAsPythonString( mDestParameterName, c ) );
7307 
7308  if ( mSourceCrs.isValid() )
7309  code += QStringLiteral( ", staticSourceCrs=%1" ).arg( valueAsPythonString( mSourceCrs, c ) );
7310  if ( mDestCrs.isValid() )
7311  code += QStringLiteral( ", staticDestinationCrs=%1" ).arg( valueAsPythonString( mDestCrs, c ) );
7312 
7313  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7314  return code;
7315  }
7316  }
7317  return QString();
7318 }
7319 
7321 {
7322  QStringList res;
7323  if ( !mSourceParameterName.isEmpty() )
7324  res << mSourceParameterName;
7325  if ( !mDestParameterName.isEmpty() )
7326  res << mDestParameterName;
7327  return res;
7328 }
7329 
7331 {
7333  map.insert( QStringLiteral( "source_crs_parameter_name" ), mSourceParameterName );
7334  map.insert( QStringLiteral( "dest_crs_parameter_name" ), mDestParameterName );
7335  map.insert( QStringLiteral( "static_source_crs" ), mSourceCrs );
7336  map.insert( QStringLiteral( "static_dest_crs" ), mDestCrs );
7337  return map;
7338 }
7339 
7341 {
7343  mSourceParameterName = map.value( QStringLiteral( "source_crs_parameter_name" ) ).toString();
7344  mDestParameterName = map.value( QStringLiteral( "dest_crs_parameter_name" ) ).toString();
7345  mSourceCrs = map.value( QStringLiteral( "static_source_crs" ) );
7346  mDestCrs = map.value( QStringLiteral( "static_dest_crs" ) );
7347  return true;
7348 }
7349 
7350 QgsProcessingParameterCoordinateOperation *QgsProcessingParameterCoordinateOperation::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7351 {
7352  QString def = definition;
7353 
7354  if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
7355  def = def.mid( 1 );
7356  if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
7357  def.chop( 1 );
7358 
7359  QVariant defaultValue = def;
7360  if ( def == QLatin1String( "None" ) )
7361  defaultValue = QVariant();
7362 
7363  return new QgsProcessingParameterCoordinateOperation( name, description, defaultValue, QString(), QString(), QVariant(), QVariant(), isOptional );
7364 }
7365 
7366 
7367 //
7368 // QgsProcessingParameterMapTheme
7369 //
7370 
7371 QgsProcessingParameterMapTheme::QgsProcessingParameterMapTheme( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
7372  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
7373 {
7374 
7375 }
7376 
7377 
7379 {
7380  return new QgsProcessingParameterMapTheme( *this );
7381 }
7382 
7384 {
7385  if ( !input.isValid() && !mDefault.isValid() )
7386  return mFlags & FlagOptional;
7387 
7388  if ( ( input.type() == QVariant::String && input.toString().isEmpty() )
7389  || ( !input.isValid() && mDefault.type() == QVariant::String && mDefault.toString().isEmpty() ) )
7390  return mFlags & FlagOptional;
7391 
7392  return true;
7393 }
7394 
7396 {
7397  if ( !value.isValid() )
7398  return QStringLiteral( "None" );
7399 
7400  if ( value.canConvert<QgsProperty>() )
7401  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
7402 
7403  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
7404 }
7405 
7407 {
7408  QString code = QStringLiteral( "##%1=" ).arg( mName );
7409  if ( mFlags & FlagOptional )
7410  code += QLatin1String( "optional " );
7411  code += QLatin1String( "maptheme " );
7412 
7413  code += mDefault.toString();
7414  return code.trimmed();
7415 }
7416 
7418 {
7419  switch ( outputType )
7420  {
7422  {
7423  QString code = QStringLiteral( "QgsProcessingParameterMapTheme('%1', '%2'" ).arg( name(), description() );
7424  if ( mFlags & FlagOptional )
7425  code += QLatin1String( ", optional=True" );
7426 
7428  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7429 
7430  return code;
7431  }
7432  }
7433  return QString();
7434 }
7435 
7437 {
7439  return map;
7440 }
7441 
7443 {
7445  return true;
7446 }
7447 
7448 QgsProcessingParameterMapTheme *QgsProcessingParameterMapTheme::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7449 {
7450  QString parent;
7451 
7452  QString def = definition;
7453  if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
7454  def = def.mid( 1 );
7455  if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
7456  def.chop( 1 );
7457 
7458  QVariant defaultValue = def;
7459 
7460  if ( defaultValue == QLatin1String( "None" ) || defaultValue.toString().isEmpty() )
7461  defaultValue = QVariant();
7462 
7463  return new QgsProcessingParameterMapTheme( name, description, defaultValue, isOptional );
7464 }
7465 
7466 
7467 //
7468 // QgsProcessingParameterDateTime
7469 //
7470 
7471 QgsProcessingParameterDateTime::QgsProcessingParameterDateTime( const QString &name, const QString &description, Type type, const QVariant &defaultValue, bool optional, const QDateTime &minValue, const QDateTime &maxValue )
7472  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
7473  , mMin( minValue )
7474  , mMax( maxValue )
7475  , mDataType( type )
7476 {
7477  if ( mMin.isValid() && mMax.isValid() && mMin >= mMax )
7478  {
7479  QgsMessageLog::logMessage( QObject::tr( "Invalid datetime parameter \"%1\": min value %2 is >= max value %3!" ).arg( name, mMin.toString(), mMax.toString() ), QObject::tr( "Processing" ) );
7480  }
7481 }
7482 
7484 {
7485  return new QgsProcessingParameterDateTime( *this );
7486 }
7487 
7489 {
7490  QVariant input = value;
7491  if ( !input.isValid() )
7492  {
7493  if ( !defaultValue().isValid() )
7494  return mFlags & FlagOptional;
7495 
7496  input = defaultValue();
7497  }
7498 
7499  if ( input.canConvert<QgsProperty>() )
7500  {
7501  return true;
7502  }
7503 
7504  if ( input.type() != QVariant::DateTime && input.type() != QVariant::Date && input.type() != QVariant::Time && input.type() != QVariant::String )
7505  return false;
7506 
7507  if ( ( input.type() == QVariant::DateTime || input.type() == QVariant::Date ) && mDataType == Time )
7508  return false;
7509 
7510  if ( input.type() == QVariant::String )
7511  {
7512  QString s = input.toString();
7513  if ( s.isEmpty() )
7514  return mFlags & FlagOptional;
7515 
7516  input = QDateTime::fromString( s, Qt::ISODate );
7517  if ( mDataType == Time )
7518  {
7519  if ( !input.toDateTime().isValid() )
7520  input = QTime::fromString( s );
7521  else
7522  input = input.toDateTime().time();
7523  }
7524  }
7525 
7526  if ( mDataType != Time )
7527  {
7528  QDateTime res = input.toDateTime();
7529  return res.isValid() && ( res >= mMin || !mMin.isValid() ) && ( res <= mMax || !mMax.isValid() );
7530  }
7531  else
7532  {
7533  QTime res = input.toTime();
7534  return res.isValid() && ( res >= mMin.time() || !mMin.isValid() ) && ( res <= mMax.time() || !mMax.isValid() );
7535  }
7536 }
7537 
7539 {
7540  if ( !value.isValid() )
7541  return QStringLiteral( "None" );
7542 
7543  if ( value.canConvert<QgsProperty>() )
7544  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
7545 
7546  if ( value.type() == QVariant::DateTime )
7547  {
7548  const QDateTime dt = value.toDateTime();
7549  if ( !dt.isValid() )
7550  return QStringLiteral( "QDateTime()" );
7551  else
7552  return QStringLiteral( "QDateTime(QDate(%1, %2, %3), QTime(%4, %5, %6))" ).arg( dt.date().year() )
7553  .arg( dt.date().month() )
7554  .arg( dt.date().day() )
7555  .arg( dt.time().hour() )
7556  .arg( dt.time().minute() )
7557  .arg( dt.time().second() );
7558  }
7559  else if ( value.type() == QVariant::Date )
7560  {
7561  const QDate dt = value.toDate();
7562  if ( !dt.isValid() )
7563  return QStringLiteral( "QDate()" );
7564  else
7565  return QStringLiteral( "QDate(%1, %2, %3)" ).arg( dt.year() )
7566  .arg( dt.month() )
7567  .arg( dt.day() );
7568  }
7569  else if ( value.type() == QVariant::Time )
7570  {
7571  const QTime dt = value.toTime();
7572  if ( !dt.isValid() )
7573  return QStringLiteral( "QTime()" );
7574  else
7575  return QStringLiteral( "QTime(%4, %5, %6)" )
7576  .arg( dt.hour() )
7577  .arg( dt.minute() )
7578  .arg( dt.second() );
7579  }
7580  return value.toString();
7581 }
7582 
7584 {
7586  QStringList parts;
7587  if ( mMin.isValid() )
7588  parts << QObject::tr( "Minimum value: %1" ).arg( mMin.toString( Qt::ISODate ) );
7589  if ( mMax.isValid() )
7590  parts << QObject::tr( "Maximum value: %1" ).arg( mMax.toString( Qt::ISODate ) );
7591  if ( mDefault.isValid() )
7592  parts << QObject::tr( "Default value: %1" ).arg( mDataType == DateTime ? mDefault.toDateTime().toString( Qt::ISODate ) :
7593  ( mDataType == Date ? mDefault.toDate().toString( Qt::ISODate ) : mDefault.toTime( ).toString() ) );
7594  QString extra = parts.join( QLatin1String( "<br />" ) );
7595  if ( !extra.isEmpty() )
7596  text += QStringLiteral( "<p>%1</p>" ).arg( extra );
7597  return text;
7598 }
7599 
7601 {
7602  switch ( outputType )
7603  {
7605  {
7606  QString code = QStringLiteral( "QgsProcessingParameterDateTime('%1', '%2'" ).arg( name(), description() );
7607  if ( mFlags & FlagOptional )
7608  code += QLatin1String( ", optional=True" );
7609 
7610  code += QStringLiteral( ", type=%1" ).arg( mDataType == DateTime ? QStringLiteral( "QgsProcessingParameterDateTime.DateTime" )
7611  : mDataType == Date ? QStringLiteral( "QgsProcessingParameterDateTime.Date" )
7612  : QStringLiteral( "QgsProcessingParameterDateTime.Time" ) );
7613 
7615  if ( mMin.isValid() )
7616  code += QStringLiteral( ", minValue=%1" ).arg( valueAsPythonString( mMin, c ) );
7617  if ( mMax.isValid() )
7618  code += QStringLiteral( ", maxValue=%1" ).arg( valueAsPythonString( mMax, c ) );
7619  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7620  return code;
7621  }
7622  }
7623  return QString();
7624 }
7625 
7627 {
7628  return mMin;
7629 }
7630 
7632 {
7633  mMin = min;
7634 }
7635 
7637 {
7638  return mMax;
7639 }
7640 
7642 {
7643  mMax = max;
7644 }
7645 
7647 {
7648  return mDataType;
7649 }
7650 
7652 {
7653  mDataType = dataType;
7654 }
7655 
7657 {
7659  map.insert( QStringLiteral( "min" ), mMin );
7660  map.insert( QStringLiteral( "max" ), mMax );
7661  map.insert( QStringLiteral( "data_type" ), mDataType );
7662  return map;
7663 }
7664 
7666 {
7668  mMin = map.value( QStringLiteral( "min" ) ).toDateTime();
7669  mMax = map.value( QStringLiteral( "max" ) ).toDateTime();
7670  mDataType = static_cast< Type >( map.value( QStringLiteral( "data_type" ) ).toInt() );
7671  return true;
7672 }
7673 
7674 QgsProcessingParameterDateTime *QgsProcessingParameterDateTime::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7675 {
7676  return new QgsProcessingParameterDateTime( name, description, DateTime, definition.isEmpty() ? QVariant()
7677  : ( definition.toLower().trimmed() == QLatin1String( "none" ) ? QVariant() : definition ), isOptional );
7678 }
7679 
7680 
7681 
7682 //
7683 // QgsProcessingParameterProviderConnection
7684 //
7685 
7686 QgsProcessingParameterProviderConnection::QgsProcessingParameterProviderConnection( const QString &name, const QString &description, const QString &provider, const QVariant &defaultValue, bool optional )
7687  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
7688  , mProviderId( provider )
7689 {
7690 
7691 }
7692 
7693 
7695 {
7696  return new QgsProcessingParameterProviderConnection( *this );
7697 }
7698 
7700 {
7701  if ( !input.isValid() && !mDefault.isValid() )
7702  return mFlags & FlagOptional;
7703 
7704  if ( ( input.type() == QVariant::String && input.toString().isEmpty() )
7705  || ( !input.isValid() && mDefault.type() == QVariant::String && mDefault.toString().isEmpty() ) )
7706  return mFlags & FlagOptional;
7707 
7708  return true;
7709 }
7710 
7712 {
7713  if ( !value.isValid() )
7714  return QStringLiteral( "None" );
7715 
7716  if ( value.canConvert<QgsProperty>() )
7717  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
7718 
7719  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
7720 }
7721 
7723 {
7724  QString code = QStringLiteral( "##%1=" ).arg( mName );
7725  if ( mFlags & FlagOptional )
7726  code += QLatin1String( "optional " );
7727  code += QLatin1String( "providerconnection " );
7728  code += mProviderId + ' ';
7729 
7730  code += mDefault.toString();
7731  return code.trimmed();
7732 }
7733 
7735 {
7736  switch ( outputType )
7737  {
7739  {
7740  QString code = QStringLiteral( "QgsProcessingParameterProviderConnection('%1', '%2', '%3'" ).arg( name(), description(), mProviderId );
7741  if ( mFlags & FlagOptional )
7742  code += QLatin1String( ", optional=True" );
7743 
7745  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7746 
7747  return code;
7748  }
7749  }
7750  return QString();
7751 }
7752 
7754 {
7756  map.insert( QStringLiteral( "provider" ), mProviderId );
7757  return map;
7758 }
7759 
7761 {
7763  mProviderId = map.value( QStringLiteral( "provider" ) ).toString();
7764  return true;
7765 }
7766 
7767 QgsProcessingParameterProviderConnection *QgsProcessingParameterProviderConnection::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7768 {
7769  QString parent;
7770 
7771  QString def = definition;
7772  QString provider;
7773  if ( def.contains( ' ' ) )
7774  {
7775  provider = def.left( def.indexOf( ' ' ) );
7776  def = def.mid( def.indexOf( ' ' ) + 1 );
7777  }
7778  else
7779  {
7780  provider = def;
7781  def.clear();
7782  }
7783 
7784  if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
7785  def = def.mid( 1 );
7786  if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
7787  def.chop( 1 );
7788 
7789  QVariant defaultValue = def;
7790 
7791  if ( defaultValue == QLatin1String( "None" ) || defaultValue.toString().isEmpty() )
7792  defaultValue = QVariant();
7793 
7795 }
7796 
7797 
7798 //
7799 // QgsProcessingParameterDatabaseSchema
7800 //
7801 
7802 QgsProcessingParameterDatabaseSchema::QgsProcessingParameterDatabaseSchema( const QString &name, const QString &description, const QString &parentLayerParameterName, const QVariant &defaultValue, bool optional )
7803  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
7804  , mParentConnectionParameterName( parentLayerParameterName )
7805 {
7806 
7807 }
7808 
7809 
7811 {
7812  return new QgsProcessingParameterDatabaseSchema( *this );
7813 }
7814 
7816 {
7817  if ( !input.isValid() && !mDefault.isValid() )
7818  return mFlags & FlagOptional;
7819 
7820  if ( ( input.type() == QVariant::String && input.toString().isEmpty() )
7821  || ( !input.isValid() && mDefault.type() == QVariant::String && mDefault.toString().isEmpty() ) )
7822  return mFlags & FlagOptional;
7823 
7824  return true;
7825 }
7826 
7828 {
7829  if ( !value.isValid() )
7830  return QStringLiteral( "None" );
7831 
7832  if ( value.canConvert<QgsProperty>() )
7833  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
7834 
7835  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
7836 }
7837 
7839 {
7840  QString code = QStringLiteral( "##%1=" ).arg( mName );
7841  if ( mFlags & FlagOptional )
7842  code += QLatin1String( "optional " );
7843  code += QLatin1String( "databaseschema " );
7844 
7845  code += mParentConnectionParameterName + ' ';
7846 
7847  code += mDefault.toString();
7848  return code.trimmed();
7849 }
7850 
7852 {
7853  switch ( outputType )
7854  {
7856  {
7857  QString code = QStringLiteral( "QgsProcessingParameterDatabaseSchema('%1', '%2'" ).arg( name(), description() );
7858  if ( mFlags & FlagOptional )
7859  code += QLatin1String( ", optional=True" );
7860 
7861  code += QStringLiteral( ", connectionParameterName='%1'" ).arg( mParentConnectionParameterName );
7863  code += QStringLiteral( ", defaultValue=%1" ).arg( valueAsPythonString( mDefault, c ) );
7864 
7865  code += ')';
7866 
7867  return code;
7868  }
7869  }
7870  return QString();
7871 }
7872 
7874 {
7875  QStringList depends;
7876  if ( !mParentConnectionParameterName.isEmpty() )
7877  depends << mParentConnectionParameterName;
7878  return depends;
7879 }
7880 
7882 {
7883  return mParentConnectionParameterName;
7884 }
7885 
7887 {
7888  mParentConnectionParameterName = name;
7889 }
7890 
7892 {
7894  map.insert( QStringLiteral( "mParentConnectionParameterName" ), mParentConnectionParameterName );
7895  return map;
7896 }
7897 
7899 {
7901  mParentConnectionParameterName = map.value( QStringLiteral( "mParentConnectionParameterName" ) ).toString();
7902  return true;
7903 }
7904 
7905 QgsProcessingParameterDatabaseSchema *QgsProcessingParameterDatabaseSchema::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7906 {
7907  QString parent;
7908  QString def = definition;
7909 
7910  QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*)$" ) );
7911  QRegularExpressionMatch m = re.match( def );
7912  if ( m.hasMatch() )
7913  {
7914  parent = m.captured( 1 ).trimmed();
7915  def = m.captured( 2 );
7916  }
7917  else
7918  {
7919  parent = def;
7920  def.clear();
7921  }
7922 
7923  return new QgsProcessingParameterDatabaseSchema( name, description, parent, def.isEmpty() ? QVariant() : def, isOptional );
7924 }
7925 
7926 //
7927 // QgsProcessingParameterDatabaseTable
7928 //
7929 
7930 QgsProcessingParameterDatabaseTable::QgsProcessingParameterDatabaseTable( const QString &name, const QString &description,
7931  const QString &connectionParameterName,
7932  const QString &schemaParameterName,
7933  const QVariant &defaultValue, bool optional, bool allowNewTableNames )
7934  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
7935  , mParentConnectionParameterName( connectionParameterName )
7936  , mParentSchemaParameterName( schemaParameterName )
7937  , mAllowNewTableNames( allowNewTableNames )
7938 {
7939 
7940 }
7941 
7942 
7944 {
7945  return new QgsProcessingParameterDatabaseTable( *this );
7946 }
7947 
7949 {
7950  if ( !input.isValid() && !mDefault.isValid() )
7951  return mFlags & FlagOptional;
7952 
7953  if ( ( input.type() == QVariant::String && input.toString().isEmpty() )
7954  || ( !input.isValid() && mDefault.type() == QVariant::String && mDefault.toString().isEmpty() ) )
7955  return mFlags & FlagOptional;
7956 
7957  return true;
7958 }
7959 
7961 {
7962  if ( !value.isValid() )
7963  return QStringLiteral( "None" );
7964 
7965  if ( value.canConvert<QgsProperty>() )
7966  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
7967 
7968  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
7969 }
7970 
7972 {
7973  QString code = QStringLiteral( "##%1=" ).arg( mName );
7974  if ( mFlags & FlagOptional )
7975  code += QLatin1String( "optional " );
7976  code += QLatin1String( "databasetable " );
7977 
7978  code += ( mParentConnectionParameterName.isEmpty() ? QStringLiteral( "none" ) : mParentConnectionParameterName ) + ' ';
7979  code += ( mParentSchemaParameterName.isEmpty() ? QStringLiteral( "none" ) : mParentSchemaParameterName ) + ' ';
7980 
7981  code += mDefault.toString();
7982  return code.trimmed();
7983 }
7984 
7986 {
7987  switch ( outputType )
7988  {
7990  {
7991  QString code = QStringLiteral( "QgsProcessingParameterDatabaseTable('%1', '%2'" ).arg( name(), description() );
7992  if ( mFlags & FlagOptional )
7993  code += QLatin1String( ", optional=True" );
7994 
7995  if ( mAllowNewTableNames )
7996  code += QLatin1String( ", allowNewTableNames=True" );
7997 
7998  code += QStringLiteral( ", connectionParameterName='%1'" ).arg( mParentConnectionParameterName );
7999  code += QStringLiteral( ", schemaParameterName='%1'" ).arg( mParentSchemaParameterName );
8001  code += QStringLiteral( ", defaultValue=%1" ).arg( valueAsPythonString( mDefault, c ) );
8002 
8003  code += ')';
8004 
8005  return code;
8006  }
8007  }
8008  return QString();
8009 }
8010 
8012 {
8013  QStringList depends;
8014  if ( !mParentConnectionParameterName.isEmpty() )
8015  depends << mParentConnectionParameterName;
8016  if ( !mParentSchemaParameterName.isEmpty() )
8017  depends << mParentSchemaParameterName;
8018  return depends;
8019 }
8020 
8022 {
8023  return mParentConnectionParameterName;
8024 }
8025 
8027 {
8028  mParentConnectionParameterName = name;
8029 }
8030 
8032 {
8033  return mParentSchemaParameterName;
8034 }
8035 
8037 {
8038  mParentSchemaParameterName = name;
8039 }
8040 
8042 {
8044  map.insert( QStringLiteral( "mParentConnectionParameterName" ), mParentConnectionParameterName );
8045  map.insert( QStringLiteral( "mParentSchemaParameterName" ), mParentSchemaParameterName );
8046  map.insert( QStringLiteral( "mAllowNewTableNames" ), mAllowNewTableNames );
8047  return map;
8048 }
8049 
8051 {
8053  mParentConnectionParameterName = map.value( QStringLiteral( "mParentConnectionParameterName" ) ).toString();
8054  mParentSchemaParameterName = map.value( QStringLiteral( "mParentSchemaParameterName" ) ).toString();
8055  mAllowNewTableNames = map.value( QStringLiteral( "mAllowNewTableNames" ), false ).toBool();
8056  return true;
8057 }
8058 
8059 QgsProcessingParameterDatabaseTable *QgsProcessingParameterDatabaseTable::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
8060 {
8061  QString connection;
8062  QString schema;
8063  QString def = definition;
8064 
8065  QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*+)\\b\\s*(.*)$" ) );
8066  QRegularExpressionMatch m = re.match( def );
8067  if ( m.hasMatch() )
8068  {
8069  connection = m.captured( 1 ).trimmed();
8070  if ( connection == QLatin1String( "none" ) )
8071  connection.clear();
8072  schema = m.captured( 2 ).trimmed();
8073  if ( schema == QLatin1String( "none" ) )
8074  schema.clear();
8075  def = m.captured( 3 );
8076  }
8077 
8078  return new QgsProcessingParameterDatabaseTable( name, description, connection, schema, def.isEmpty() ? QVariant() : def, isOptional );
8079 }
8080 
8082 {
8083  return mAllowNewTableNames;
8084 }
8085 
8087 {
8088  mAllowNewTableNames = allowNewTableNames;
8089 }
static QgsProcessingRegistry * processingRegistry()
Returns the application's processing registry, used for managing processing providers,...
static QgsApplication * instance()
Returns the singleton instance of the QgsApplication.
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
QString authid() const
Returns the authority identifier for the CRS.
@ WKT_PREFERRED
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
QString toWkt(WktVariant variant=WKT1_GDAL, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
Class for doing transforms between two map coordinate systems.
QgsPointXY transform(const QgsPointXY &point, TransformDirection direction=ForwardTransform) const SIP_THROW(QgsCsException)
Transform the point from the source CRS to the destination CRS.
QgsRectangle transformBoundingBox(const QgsRectangle &rectangle, TransformDirection direction=ForwardTransform, bool handle180Crossover=false) const SIP_THROW(QgsCsException)
Transforms a rectangle from the source CRS to the destination CRS.
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:66
Class for parsing and evaluation of expressions (formerly called "search strings").
bool isValid() const
Checks if this expression is valid.
InvalidGeometryCheck
Handling of features with invalid geometries.
@ GeometryNoCheck
No invalid geometry checking.
@ GeometryAbortOnInvalid
Close iterator on encountering any features with invalid geometry. This requires a slow geometry vali...
@ GeometrySkipInvalid
Skip any features with invalid geometry. This requires a slow geometry validity check for every featu...
An interface for objects which accept features via addFeature(s) methods.
Container of fields for a vector layer.
Definition: qgsfields.h:45
static QString addExtensionFromFilter(const QString &fileName, const QString &filter)
Ensures that a fileName ends with an extension from the specified filter string.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsGeometry densifyByCount(int extraNodesPerSegment) const
Returns a copy of the geometry which has been densified by adding the specified number of extra nodes...
Q_GADGET bool isNull
Definition: qgsgeometry.h:126
static QgsGeometry fromRect(const QgsRectangle &rect) SIP_HOLDGIL
Creates a new geometry from a QgsRectangle.
bool isMultipart() const SIP_HOLDGIL
Returns true if WKB of the geometry is of WKBMulti* type.
static QgsGeometry fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
static QgsGeometry fromPointXY(const QgsPointXY &point) SIP_HOLDGIL
Creates a new geometry from a QgsPointXY object.
QgsWkbTypes::GeometryType type
Definition: qgsgeometry.h:127
QgsGeometry centroid() const
Returns the center of mass of a geometry.
QString lastError() const SIP_HOLDGIL
Returns an error string referring to the last error encountered either when this geometry was created...
OperationResult transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection direction=QgsCoordinateTransform::ForwardTransform, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
QString asWkt(int precision=17) const
Exports the geometry to WKT.
Base class for graphical items within a QgsLayout.
QgsMasterLayoutInterface * layoutByName(const QString &name) const
Returns the layout with a matching name, or nullptr if no matching layouts were found.
QgsLayoutItem * itemById(const QString &id) const
Returns a layout item given its id.
Definition: qgslayout.cpp:266
QgsLayoutItem * itemByUuid(const QString &uuid, bool includeTemplateUuids=false) const
Returns the layout item with matching uuid unique identifier, or nullptr if a matching item could not...
Definition: qgslayout.cpp:238
Base class for all map layer types.
Definition: qgsmaplayer.h:70
virtual QgsRectangle extent() const
Returns the extent of the layer.
QString source() const
Returns the source for the layer.
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:76
Interface for master layout type objects, such as print layouts and reports.
virtual QgsMasterLayoutInterface::Type layoutType() const =0
Returns the master layout type.
@ PrintLayout
Individual print layout (QgsPrintLayout)
Represents a mesh layer supporting display of data on structured or unstructured meshes.
Definition: qgsmeshlayer.h:95
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
A class to represent a 2D point.
Definition: qgspointxy.h:59
double y
Definition: qgspointxy.h:63
Q_GADGET double x
Definition: qgspointxy.h:62
Print layout, a QgsLayout subclass for static or atlas-based layouts.
Abstract base class for processing algorithms.
QgsProcessingProvider * provider() const
Returns the provider to which this algorithm belongs.
Details for layers to load into projects.
Contains information about the context in which a processing algorithm is executed.
QgsExpressionContext & expressionContext()
Returns the expression context.
QgsProject * project() const
Returns the project in which the algorithm is being executed.
void addLayerToLoadOnCompletion(const QString &layer, const QgsProcessingContext::LayerDetails &details)
Adds a layer to load (by ID or datasource) into the canvas upon completion of the algorithm or model.
Base class for all parameter definitions which represent file or layer destinations,...
virtual QString defaultFileExtension() const =0
Returns the default file extension for destination file paths associated with this parameter.
void setCreateByDefault(bool createByDefault)
Sets whether the destination should be created by default.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
virtual QString generateTemporaryDestination() const
Generates a temporary destination value for this parameter.
bool supportsNonFileBasedOutput() const
Returns true if the destination parameter supports non filed-based outputs, such as memory layers or ...
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
bool createByDefault() const
Returns true if the destination should be created by default.
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
virtual bool isSupportedOutputValue(const QVariant &value, QgsProcessingContext &context, QString &error) const
Tests whether a value is a supported value for this parameter.
QgsProcessingProvider * originalProvider() const
Original (source) provider which this parameter has been derived from.
QgsProcessingDestinationParameter(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, bool createByDefault=true)
Constructor for QgsProcessingDestinationParameter.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
Custom exception class for processing related exceptions.
Definition: qgsexception.h:83
Encapsulates settings relating to a feature source input to a processing algorithm.
bool loadVariant(const QVariantMap &map)
Loads this source definition from a QVariantMap, wrapped in a QVariant.
Flags flags
Flags which dictate source behavior.
bool selectedFeaturesOnly
true if only selected features in the source should be used by algorithms.
QgsFeatureRequest::InvalidGeometryCheck geometryCheck
Geometry check method to apply to this source.
long long featureLimit
If set to a value > 0, places a limit on the maximum number of features which will be read from the s...
QVariant toVariant() const
Saves this source definition to a QVariantMap, wrapped in a QVariant.
QgsFeatureSource subclass which proxies methods to an underlying QgsFeatureSource,...
Base class for providing feedback from a processing algorithm.
Base class for the definition of processing outputs.
A file output for processing algorithms.
A folder output for processing algorithms.
A HTML file output for processing algorithms.
Encapsulates settings relating to a feature sink or output raster layer for a processing algorithm.
bool loadVariant(const QVariantMap &map)
Loads this output layer definition from a QVariantMap, wrapped in a QVariant.
bool operator!=(const QgsProcessingOutputLayerDefinition &other) const
QgsProject * destinationProject
Destination project.
bool operator==(const QgsProcessingOutputLayerDefinition &other) const
QgsProperty sink
Sink/layer definition.
bool useRemapping() const
Returns true if the output uses a remapping definition.
QgsRemappingSinkDefinition remappingDefinition() const
Returns the output remapping definition, if useRemapping() is true.
QVariant toVariant() const
Saves this output layer definition to a QVariantMap, wrapped in a QVariant.
QString destinationName
Name to use for sink if it's to be loaded into a destination project.
QVariantMap createOptions
Map of optional sink/layer creation options, which are passed to the underlying provider when creatin...
void setRemappingDefinition(const QgsRemappingSinkDefinition &definition)
Sets the remapping definition to use when adding features to the output layer.
A raster layer output for processing algorithms.
A vector layer output for processing algorithms.
A string parameter for authentication configuration ID values.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QgsProcessingParameterAuthConfig(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterAuthConfig.
static QString typeName()
Returns the type name for the parameter class.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
static QgsProcessingParameterAuthConfig * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
A raster band parameter for Processing algorithms.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
void setAllowMultiple(bool allowMultiple)
Sets whether multiple band selections are permitted.
void setParentLayerParameterName(const QString &parentLayerParameterName)
Sets the name of the parent layer parameter.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QString parentLayerParameterName() const
Returns the name of the parent layer parameter, or an empty string if this is not set.
QgsProcessingParameterBand(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), const QString &parentLayerParameterName=QString(), bool optional=false, bool allowMultiple=false)
Constructor for QgsProcessingParameterBand.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
static QgsProcessingParameterBand * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
static QString typeName()
Returns the type name for the parameter class.
bool allowMultiple() const
Returns whether multiple band selections are permitted.
A boolean parameter for processing algorithms.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QString type() const override
Unique parameter type name.
static QString typeName()
Returns the type name for the parameter class.
static QgsProcessingParameterBoolean * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QgsProcessingParameterBoolean(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterBoolean.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
A color parameter for processing algorithms.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
static QgsProcessingParameterColor * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
bool opacityEnabled() const
Returns true if the parameter allows opacity control.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
void setOpacityEnabled(bool enabled)
Sets whether the parameter allows opacity control.
QgsProcessingParameterColor(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool opacityEnabled=true, bool optional=false)
Constructor for QgsProcessingParameterColor.
static QString typeName()
Returns the type name for the parameter class.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
A coordinate operation parameter for processing algorithms, for selection between available coordinat...
static QString typeName()
Returns the type name for the parameter class.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
static QgsProcessingParameterCoordinateOperation * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QgsProcessingParameterCoordinateOperation(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), const QString &sourceCrsParameterName=QString(), const QString &destinationCrsParameterName=QString(), const QVariant &staticSourceCrs=QVariant(), const QVariant &staticDestinationCrs=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterCoordinateOperation.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
A coordinate reference system parameter for processing algorithms.
QgsProcessingParameterCrs(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterCrs.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
static QString typeName()
Returns the type name for the parameter class.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
static QgsProcessingParameterCrs * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
A database schema parameter for processing algorithms, allowing users to select from existing schemas...
void setParentConnectionParameterName(const QString &name)
Sets the name of the parent connection parameter.
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QgsProcessingParameterDatabaseSchema(const QString &name, const QString &description, const QString &connectionParameterName=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterDatabaseSchema.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
static QgsProcessingParameterDatabaseSchema * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QString parentConnectionParameterName() const
Returns the name of the parent connection parameter, or an empty string if this is not set.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
A database table name parameter for processing algorithms, allowing users to select from existing dat...
QgsProcessingParameterDatabaseTable(const QString &name, const QString &description, const QString &connectionParameterName=QString(), const QString &schemaParameterName=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, bool allowNewTableNames=false)
Constructor for QgsProcessingParameterDatabaseTable.
void setParentSchemaParameterName(const QString &name)
Sets the name of the parent schema parameter.
QString parentConnectionParameterName() const
Returns the name of the parent connection parameter, or an empty string if this is not set.
QString parentSchemaParameterName() const
Returns the name of the parent schema parameter, or an empty string if this is not set.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
static QgsProcessingParameterDatabaseTable * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
bool allowNewTableNames() const
Returns true if the parameter allows users to enter names for a new (non-existing) tables.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
void setAllowNewTableNames(bool allowed)
Sets whether the parameter allows users to enter names for a new (non-existing) tables.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
void setParentConnectionParameterName(const QString &name)
Sets the name of the parent connection parameter.
A datetime (or pure date or time) parameter for processing algorithms.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
void setMaximum(const QDateTime &maximum)
Sets the maximum value acceptable by the parameter.
static QgsProcessingParameterDateTime * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QDateTime minimum() const
Returns the minimum value acceptable by the parameter.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QString toolTip() const override
Returns a formatted tooltip for use with the parameter, which gives helpful information like paramete...
void setMinimum(const QDateTime &minimum)
Sets the minimum value acceptable by the parameter.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QDateTime maximum() const
Returns the maximum value acceptable by the parameter.
QgsProcessingParameterDateTime(const QString &name, const QString &description=QString(), Type type=DateTime, const QVariant &defaultValue=QVariant(), bool optional=false, const QDateTime &minValue=QDateTime(), const QDateTime &maxValue=QDateTime())
Constructor for QgsProcessingParameterDateTime.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
Type dataType() const
Returns the acceptable data type for the parameter.
void setDataType(Type type)
Sets the acceptable data type for the parameter.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
Base class for the definition of processing parameters.
QgsProcessingAlgorithm * mAlgorithm
Pointer to algorithm which owns this parameter.
QVariant defaultValue() const
Returns the default value for the parameter.
QString help() const
Returns the help for the parameter.
virtual QString asScriptCode() const
Returns the parameter definition encoded in a string which can be used within a Processing script.
virtual QString toolTip() const
Returns a formatted tooltip for use with the parameter, which gives helpful information like paramete...
QgsProcessingAlgorithm * algorithm() const
Returns a pointer to the algorithm which owns this parameter.
QgsProcessingProvider * provider() const
Returns a pointer to the provider for the algorithm which owns this parameter.
virtual QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QString description() const
Returns the description for the parameter.
QgsProcessingParameterDefinition(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, const QString &help=QString())
Constructor for QgsProcessingParameterDefinition.
QVariantMap mMetadata
Freeform metadata for parameter. Mostly used by widget wrappers to customize their appearance and beh...
QString mDescription
Parameter description.
virtual QString type() const =0
Unique parameter type name.
Flags flags() const
Returns any flags associated with the parameter.
virtual QVariantMap toVariantMap() const
Saves this parameter to a QVariantMap.
QString name() const
Returns the name of the parameter.
QVariant mDefault
Default value for parameter.
QVariant mGuiDefault
Default value for parameter in GUI.
virtual QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
virtual bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const
Checks whether the specified input value is acceptable for the parameter.
virtual bool fromVariantMap(const QVariantMap &map)
Restores this parameter to a QVariantMap.
virtual QString valueAsPythonComment(const QVariant &value, QgsProcessingContext &context) const
Returns a Python comment explaining a parameter value, or an empty string if no comment is required.
A double numeric parameter for distance values.
void setParentParameterName(const QString &parentParameterName)
Sets the name of the parent layer parameter.
static QString typeName()
Returns the type name for the parameter class.
QString parentParameterName() const
Returns the name of the parent parameter, or an empty string if this is not set.
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QgsProcessingParameterDistance * clone() const override
Creates a clone of the parameter definition.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QString type() const override
Unique parameter type name.
QgsProcessingParameterDistance(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), const QString &parentParameterName=QString(), bool optional=false, double minValue=std::numeric_limits< double >::lowest()+1, double maxValue=std::numeric_limits< double >::max())
Constructor for QgsProcessingParameterDistance.
An enum based parameter for processing algorithms, allowing for selection from predefined values.
void setUsesStaticStrings(bool usesStaticStrings)
Sets whether the parameter uses static (non-translated) string values for its enumeration choice list...
static QgsProcessingParameterEnum * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
bool allowMultiple() const
Returns true if the parameter allows multiple selected values.
QStringList options() const
Returns the list of acceptable options for the parameter.
QgsProcessingParameterEnum(const QString &name, const QString &description=QString(), const QStringList &options=QStringList(), bool allowMultiple=false, const QVariant &defaultValue=QVariant(), bool optional=false, bool usesStaticStrings=false)
Constructor for QgsProcessingParameterEnum.
void setOptions(const QStringList &options)
Sets the list of acceptable options for the parameter.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
bool usesStaticStrings() const
Returns true if the parameter uses static (non-translated) string values for its enumeration choice l...
QString valueAsPythonComment(const QVariant &value, QgsProcessingContext &context) const override
Returns a Python comment explaining a parameter value, or an empty string if no comment is required.
void setAllowMultiple(bool allowMultiple)
Sets whether the parameter allows multiple selected values.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
static QString typeName()
Returns the type name for the parameter class.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
An expression parameter for processing algorithms.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
static QgsProcessingParameterExpression * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
QgsProcessingParameterExpression(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), const QString &parentLayerParameterName=QString(), bool optional=false)
Constructor for QgsProcessingParameterExpression.
void setParentLayerParameterName(const QString &parentLayerParameterName)
Sets the name of the parent layer parameter.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString parentLayerParameterName() const
Returns the name of the parent layer parameter, or an empty string if this is not set.
static QString typeName()
Returns the type name for the parameter class.
A rectangular map extent parameter for processing algorithms.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QgsProcessingParameterExtent(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterExtent.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
static QString typeName()
Returns the type name for the parameter class.
static QgsProcessingParameterExtent * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
A feature sink output for processing algorithms.
QString generateTemporaryDestination() const override
Generates a temporary destination value for this parameter.
static QgsProcessingParameterFeatureSink * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QgsProcessingOutputDefinition * toOutputDefinition() const override
Returns a new QgsProcessingOutputDefinition corresponding to the definition of the destination parame...
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
bool hasGeometry() const
Returns true if sink is likely to include geometries.
QString type() const override
Unique parameter type name.
QgsProcessing::SourceType dataType() const
Returns the layer type for sinks associated with the parameter.
virtual QStringList supportedOutputVectorLayerExtensions() const
Returns a list of the vector format file extensions supported by this parameter.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
void setSupportsAppend(bool supportsAppend)
Sets whether the sink supports appending features to an existing table.
QgsProcessingParameterFeatureSink(const QString &name, const QString &description=QString(), QgsProcessing::SourceType type=QgsProcessing::TypeVectorAnyGeometry, const QVariant &defaultValue=QVariant(), bool optional=false, bool createByDefault=true, bool supportsAppend=false)
Constructor for QgsProcessingParameterFeatureSink.
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
QString defaultFileExtension() const override
Returns the default file extension for destination file paths associated with this parameter.
void setDataType(QgsProcessing::SourceType type)
Sets the layer type for the sinks associated with the parameter.
bool supportsAppend() const
Returns true if the sink supports appending features to an existing table.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
static QString typeName()
Returns the type name for the parameter class.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
An input feature source (such as vector layers) parameter for processing algorithms.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QgsProcessingParameterFeatureSource(const QString &name, const QString &description=QString(), const QList< int > &types=QList< int >(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterFeatureSource.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
static QString typeName()
Returns the type name for the parameter class.
QString type() const override
Unique parameter type name.
static QgsProcessingParameterFeatureSource * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
A vector layer or feature source field parameter for processing algorithms.
QgsProcessingParameterField(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), const QString &parentLayerParameterName=QString(), DataType type=Any, bool allowMultiple=false, bool optional=false, bool defaultToAllFields=false)
Constructor for QgsProcessingParameterField.
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
QString parentLayerParameterName() const
Returns the name of the parent layer parameter, or an empty string if this is not set.
void setDataType(DataType type)
Sets the acceptable data type for the field.
void setParentLayerParameterName(const QString &parentLayerParameterName)
Sets the name of the parent layer parameter.
bool allowMultiple() const
Returns whether multiple field selections are permitted.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString type() const override
Unique parameter type name.
bool defaultToAllFields() const
Returns whether a parameter which allows multiple selections (see allowMultiple()) should automatical...
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
static QString typeName()
Returns the type name for the parameter class.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
void setAllowMultiple(bool allowMultiple)
Sets whether multiple field selections are permitted.
@ DateTime
Accepts datetime fields.
@ Numeric
Accepts numeric fields.
DataType dataType() const
Returns the acceptable data type for the field.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
void setDefaultToAllFields(bool enabled)
Sets whether a parameter which allows multiple selections (see allowMultiple()) should automatically ...
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
static QgsProcessingParameterField * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
A generic file based destination parameter, for specifying the destination path for a file (non-map l...
static QgsProcessingParameterFileDestination * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QgsProcessingOutputDefinition * toOutputDefinition() const override
Returns a new QgsProcessingOutputDefinition corresponding to the definition of the destination parame...
QString defaultFileExtension() const override
Returns the default file extension for destination file paths associated with this parameter.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QgsProcessingParameterFileDestination(const QString &name, const QString &description=QString(), const QString &fileFilter=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, bool createByDefault=true)
Constructor for QgsProcessingParameterFileDestination.
static QString typeName()
Returns the type name for the parameter class.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QString fileFilter() const
Returns the file filter string for file destinations compatible with this parameter.
void setFileFilter(const QString &filter)
Sets the file filter string for file destinations compatible with this parameter.
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
An input file or folder parameter for processing algorithms.
QString extension() const
Returns any specified file extension for the parameter.
void setExtension(const QString &extension)
Sets a file extension for the parameter.
static QString typeName()
Returns the type name for the parameter class.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
void setFileFilter(const QString &filter)
Sets the file filter string for file destinations compatible with this parameter.
static QgsProcessingParameterFile * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition, Behavior behavior=File)
Creates a new parameter using the definition from a script code.
@ File
Parameter is a single file.
Behavior behavior() const
Returns the parameter behavior (e.g.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString fileFilter() const
Returns the file filter string for file destinations compatible with this parameter.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QgsProcessingParameterFile(const QString &name, const QString &description=QString(), Behavior behavior=File, const QString &extension=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, const QString &fileFilter=QString())
Constructor for QgsProcessingParameterFile.
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
A folder destination parameter, for specifying the destination path for a folder created by the algor...
QgsProcessingOutputDefinition * toOutputDefinition() const override
Returns a new QgsProcessingOutputDefinition corresponding to the definition of the destination parame...
static QgsProcessingParameterFolderDestination * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QString defaultFileExtension() const override
Returns the default file extension for destination file paths associated with this parameter.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
static QString typeName()
Returns the type name for the parameter class.
QgsProcessingParameterFolderDestination(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, bool createByDefault=true)
Constructor for QgsProcessingParameterFolderDestination.
A geometry parameter for processing algorithms.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString type() const override
Unique parameter type name.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QgsProcessingParameterGeometry(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, const QList< int > &geometryTypes=QList< int >(), bool allowMultipart=true)
Constructor for QgsProcessingParameterGeometry.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
static QgsProcessingParameterGeometry * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
A print layout item parameter, allowing users to select a particular item from a print layout.
QString type() const override
Unique parameter type name.
static QgsProcessingParameterLayoutItem * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QgsProcessingParameterLayoutItem(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), const QString &parentLayoutParameterName=QString(), int itemType=-1, bool optional=false)
Constructor for QgsProcessingParameterLayoutItem.
void setParentLayoutParameterName(const QString &name)
Sets the name of the parent layout parameter.
QString parentLayoutParameterName() const
Returns the name of the parent layout parameter, or an empty string if this is not set.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
static QString typeName()
Returns the type name for the parameter class.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
int itemType() const
Returns the acceptable item type, or -1 if any item type is allowed.
void setItemType(int type)
Sets the acceptable item type, or -1 if any item type is allowed.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
A print layout parameter, allowing users to select a print layout.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
static QgsProcessingParameterLayout * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
QgsProcessingParameterLayout(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterLayout.
static QString typeName()
Returns the type name for the parameter class.
Can be inherited by parameters which require limits to their acceptable data types.
void setDataTypes(const QList< int > &types)
Sets the geometry types for sources acceptable by the parameter.
QgsProcessingParameterLimitedDataTypes(const QList< int > &types=QList< int >())
Constructor for QgsProcessingParameterLimitedDataTypes, with a list of acceptable data types.
QList< int > mDataTypes
List of acceptable data types for the parameter.
QList< int > dataTypes() const
Returns the geometry types for sources acceptable by the parameter.
A map layer parameter for processing algorithms.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
static QgsProcessingParameterMapLayer * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QString type() const override
Unique parameter type name.
QgsProcessingParameterMapLayer(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, const QList< int > &types=QList< int >())
Constructor for QgsProcessingParameterMapLayer.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
static QString typeName()
Returns the type name for the parameter class.
A map theme parameter for processing algorithms, allowing users to select an existing map theme from ...
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
static QgsProcessingParameterMapTheme * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QgsProcessingParameterMapTheme(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterMapTheme.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
A table (matrix) parameter for processing algorithms.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QStringList headers() const
Returns a list of column headers (if set).
void setHeaders(const QStringList &headers)
Sets the list of column headers.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
void setHasFixedNumberRows(bool hasFixedNumberRows)
Sets whether the table has a fixed number of rows.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
void setNumberRows(int rows)
Sets the fixed number of rows in the table.
int numberRows() const
Returns the fixed number of rows in the table.
static QgsProcessingParameterMatrix * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
static QString typeName()
Returns the type name for the parameter class.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QgsProcessingParameterMatrix(const QString &name, const QString &description=QString(), int numberRows=3, bool hasFixedNumberRows=false, const QStringList &headers=QStringList(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterMatrix.
bool hasFixedNumberRows() const
Returns whether the table has a fixed number of rows.
A mesh layer parameter for processing algorithms.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QgsProcessingParameterMeshLayer(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterMeshLayer.
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
static QgsProcessingParameterMeshLayer * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
static QString typeName()
Returns the type name for the parameter class.
A parameter for processing algorithms which accepts multiple map layers.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
void setMinimumNumberInputs(int minimum)
Sets the minimum number of layers required for the parameter.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
QgsProcessingParameterMultipleLayers(const QString &name, const QString &description=QString(), QgsProcessing::SourceType layerType=QgsProcessing::TypeVectorAnyGeometry, const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterMultipleLayers.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
static QString typeName()
Returns the type name for the parameter class.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
void setLayerType(QgsProcessing::SourceType type)
Sets the layer type for layers acceptable by the parameter.
static QgsProcessingParameterMultipleLayers * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QgsProcessing::SourceType layerType() const
Returns the layer type for layers acceptable by the parameter.
QString type() const override
Unique parameter type name.
int minimumNumberInputs() const
Returns the minimum number of layers required for the parameter.
A numeric parameter for processing algorithms.
double minimum() const
Returns the minimum value acceptable by the parameter.
static QgsProcessingParameterNumber * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
void setMinimum(double minimum)
Sets the minimum value acceptable by the parameter.
void setMaximum(double maximum)
Sets the maximum value acceptable by the parameter.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
double maximum() const
Returns the maximum value acceptable by the parameter.
QgsProcessingParameterNumber(const QString &name, const QString &description=QString(), Type type=Integer, const QVariant &defaultValue=QVariant(), bool optional=false, double minValue=std::numeric_limits< double >::lowest()+1, double maxValue=std::numeric_limits< double >::max())
Constructor for QgsProcessingParameterNumber.
void setDataType(Type type)
Sets the acceptable data type for the parameter.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
Type dataType() const
Returns the acceptable data type for the parameter.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString toolTip() const override
Returns a formatted tooltip for use with the parameter, which gives helpful information like paramete...
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
static QString typeName()
Returns the type name for the parameter class.
A point parameter for processing algorithms.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
static QgsProcessingParameterPoint * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QgsProcessingParameterPoint(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterPoint.
static QString typeName()
Returns the type name for the parameter class.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
A data provider connection parameter for processing algorithms, allowing users to select from availab...
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QgsProcessingParameterProviderConnection(const QString &name, const QString &description, const QString &provider, const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterProviderConnection, for the specified provider type.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
static QgsProcessingParameterProviderConnection * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
A numeric range parameter for processing algorithms.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QgsProcessingParameterNumber::Type dataType() const
Returns the acceptable data type for the range.
static QString typeName()
Returns the type name for the parameter class.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
void setDataType(QgsProcessingParameterNumber::Type dataType)
Sets the acceptable data type for the range.
QgsProcessingParameterRange(const QString &name, const QString &description=QString(), QgsProcessingParameterNumber::Type type=QgsProcessingParameterNumber::Integer, const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterRange.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
static QgsProcessingParameterRange * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
A raster layer destination parameter, for specifying the destination path for a raster layer created ...
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QgsProcessingOutputDefinition * toOutputDefinition() const override
Returns a new QgsProcessingOutputDefinition corresponding to the definition of the destination parame...
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
QgsProcessingParameterRasterDestination(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, bool createByDefault=true)
Constructor for QgsProcessingParameterRasterDestination.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
static QgsProcessingParameterRasterDestination * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QString defaultFileExtension() const override
Returns the default file extension for destination file paths associated with this parameter.
virtual QStringList supportedOutputRasterLayerExtensions() const
Returns a list of the raster format file extensions supported for this parameter.
static QString typeName()
Returns the type name for the parameter class.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
A raster layer parameter for processing algorithms.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
static QgsProcessingParameterRasterLayer * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
static QString typeName()
Returns the type name for the parameter class.
QgsProcessingParameterRasterLayer(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterRasterLayer.
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
A double numeric parameter for map scale values.
QString type() const override
Unique parameter type name.
static QString typeName()
Returns the type name for the parameter class.
static QgsProcessingParameterScale * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QgsProcessingParameterScale * clone() const override
Creates a clone of the parameter definition.
QgsProcessingParameterScale(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterScale.
A string parameter for processing algorithms.
static QString typeName()
Returns the type name for the parameter class.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
void setMultiLine(bool multiLine)
Sets whether the parameter allows multiline strings.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
static QgsProcessingParameterString * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
bool multiLine() const
Returns true if the parameter allows multiline strings.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QgsProcessingParameterString(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool multiLine=false, bool optional=false)
Constructor for QgsProcessingParameterString.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
Makes metadata of processing parameters available.
virtual QgsProcessingParameterDefinition * create(const QString &name) const =0
Creates a new parameter of this type.
A vector layer destination parameter, for specifying the destination path for a vector layer created ...
QString defaultFileExtension() const override
Returns the default file extension for destination file paths associated with this parameter.
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
QgsProcessing::SourceType dataType() const
Returns the layer type for this created vector layer.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QString type() const override
Unique parameter type name.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
static QString typeName()
Returns the type name for the parameter class.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
void setDataType(QgsProcessing::SourceType type)
Sets the layer type for the created vector layer.
QgsProcessingParameterVectorDestination(const QString &name, const QString &description=QString(), QgsProcessing::SourceType type=QgsProcessing::TypeVectorAnyGeometry, const QVariant &defaultValue=QVariant(), bool optional=false, bool createByDefault=true)
Constructor for QgsProcessingParameterVectorDestination.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
virtual QStringList supportedOutputVectorLayerExtensions() const
Returns a list of the vector format file extensions supported by this parameter.
bool hasGeometry() const
Returns true if the created layer is likely to include geometries.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
static QgsProcessingParameterVectorDestination * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QgsProcessingOutputDefinition * toOutputDefinition() const override
Returns a new QgsProcessingOutputDefinition corresponding to the definition of the destination parame...
A vector layer (with or without geometry) parameter for processing algorithms.
static QgsProcessingParameterVectorLayer * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString type() const override
Unique parameter type name.
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QgsProcessingParameterVectorLayer(const QString &name, const QString &description=QString(), const QList< int > &types=QList< int >(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterVectorLayer.
static QString typeName()
Returns the type name for the parameter class.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
static QList< QgsMapLayer * > parameterAsLayerList(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a list of map layers.
static QString descriptionFromName(const QString &name)
Creates an autogenerated parameter description from a parameter name.
static int parameterAsEnum(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a enum value.
static double parameterAsDouble(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static double value.
static QgsPointXY parameterAsPoint(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QgsCoordinateReferenceSystem &crs=QgsCoordinateReferenceSystem())
Evaluates the parameter with matching definition to a point.
static QString parameterAsOutputLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a output layer destination.
static QgsPrintLayout * parameterAsLayout(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a print layout.
static QTime parameterAsTime(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static time value.
static QgsProcessingParameterDefinition * parameterFromVariantMap(const QVariantMap &map)
Creates a new QgsProcessingParameterDefinition using the configuration from a supplied variant map.
static QgsRectangle parameterAsExtent(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QgsCoordinateReferenceSystem &crs=QgsCoordinateReferenceSystem())
Evaluates the parameter with matching definition to a rectangular extent.
static QgsCoordinateReferenceSystem parameterAsGeometryCrs(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Returns the coordinate reference system associated with a geometry parameter value.
static QString parameterAsEnumString(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static enum string.
static QList< double > parameterAsRange(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a range of values.
static QgsMapLayer * parameterAsLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingUtils::LayerHint layerHint=QgsProcessingUtils::LayerHint::UnknownType)
Evaluates the parameter with matching definition to a map layer.
static QList< int > parameterAsInts(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a list of integer values.
static QString parameterAsConnectionName(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a connection name string.
static QgsProcessingFeatureSource * parameterAsSource(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a feature source.
static QString parameterAsFileOutput(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a file based output destination.
static QgsFeatureSink * parameterAsSink(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, QgsProcessingContext &context, QString &destinationIdentifier, QgsFeatureSink::SinkFlags sinkFlags=QgsFeatureSink::SinkFlags(), const QVariantMap &createOptions=QVariantMap(), const QStringList &datasourceOptions=QStringList(), const QStringList &layerOptions=QStringList())
Evaluates the parameter with matching definition to a feature sink.
static bool parameterAsBoolean(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static boolean value.
static QgsCoordinateReferenceSystem parameterAsPointCrs(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Returns the coordinate reference system associated with an point parameter value.
static QgsLayoutItem * parameterAsLayoutItem(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, QgsPrintLayout *layout)
Evaluates the parameter with matching definition to a print layout item, taken from the specified lay...
static bool parameterAsBool(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static boolean value.
static QString parameterAsCompatibleSourceLayerPathAndLayerName(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QStringList &compatibleFormats, const QString &preferredFormat=QString("shp"), QgsProcessingFeedback *feedback=nullptr, QString *layerName=nullptr)
Evaluates the parameter with matching definition to a source vector layer file path and layer name of...
static QgsMeshLayer * parameterAsMeshLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition and value to a mesh layer.
static QString parameterAsCompatibleSourceLayerPath(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QStringList &compatibleFormats, const QString &preferredFormat=QString("shp"), QgsProcessingFeedback *feedback=nullptr)
Evaluates the parameter with matching definition to a source vector layer file path of compatible for...
static QgsProcessingParameterDefinition * parameterFromScriptCode(const QString &code)
Creates a new QgsProcessingParameterDefinition using the configuration from a supplied script code st...
static QColor parameterAsColor(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Returns the color associated with an point parameter value, or an invalid color if the parameter was ...
static QgsVectorLayer * parameterAsVectorLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a vector layer.
static int parameterAsInt(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static integer value.
static QString parameterAsDatabaseTableName(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a database table name.
static QString parameterAsSchema(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a database schema name.
static QgsGeometry parameterAsGeometry(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QgsCoordinateReferenceSystem &crs=QgsCoordinateReferenceSystem())
Evaluates the parameter with matching definition to a geometry.
static QString parameterAsExpression(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to an expression.
static QString parameterAsString(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static string value.
static QgsRasterLayer * parameterAsRasterLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a raster layer.
static QList< int > parameterAsEnums(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to list of enum values.
static QStringList parameterAsEnumStrings(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to list of static enum strings.
static QgsGeometry parameterAsExtentGeometry(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QgsCoordinateReferenceSystem &crs=QgsCoordinateReferenceSystem())
Evaluates the parameter with matching definition to a rectangular extent, and returns a geometry cove...
static QStringList parameterAsFileList(const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a list of files (for QgsProcessingParameterMultip...
static bool isDynamic(const QVariantMap &parameters, const QString &name)
Returns true if the parameter with matching name is a dynamic parameter, and must be evaluated once f...
static QStringList parameterAsFields(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a list of fields.
static QgsCoordinateReferenceSystem parameterAsExtentCrs(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Returns the coordinate reference system associated with an extent parameter value.
static QDateTime parameterAsDateTime(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static datetime value.
static QString parameterAsFile(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a file/folder name.
static QDate parameterAsDate(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static date value.
static QVariantList parameterAsMatrix(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a matrix/table of values.
static QgsCoordinateReferenceSystem parameterAsCrs(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a coordinate reference system.
Abstract base class for processing providers.
virtual bool isSupportedOutputValue(const QVariant &outputValue, const QgsProcessingDestinationParameter *parameter, QgsProcessingContext &context, QString &error) const
Returns true if the specified outputValue is of a supported file format for the given destination par...
QgsProcessingParameterType * parameterType(const QString &id) const
Returns the parameter type registered for id.
static QString convertToCompatibleFormat(const QgsVectorLayer *layer, bool selectedFeaturesOnly, const QString &baseName, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingContext &context, QgsProcessingFeedback *feedback, long long featureLimit=-1)
Converts a source vector layer to a file path of a vector layer of compatible format.
static QString stringToPythonLiteral(const QString &string)
Converts a string to a Python string literal.
static QString defaultVectorExtension()
Returns the default vector extension to use, in the absence of all other constraints (e....
static QString normalizeLayerSource(const QString &source)
Normalizes a layer source string for safe comparison across different operating system environments.
static QgsFeatureSink * createFeatureSink(QString &destination, QgsProcessingContext &context, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, const QVariantMap &createOptions=QVariantMap(), const QStringList &datasourceOptions=QStringList(), const QStringList &layerOptions=QStringList(), QgsFeatureSink::SinkFlags sinkFlags=QgsFeatureSink::SinkFlags(), QgsRemappingSinkDefinition *remappingDefinition=nullptr)
Creates a feature sink ready for adding features.
static QString encodeProviderKeyAndUri(const QString &providerKey, const QString &uri)
Encodes a provider key and layer uri to a single string, for use with decodeProviderKeyAndUri()
LayerHint
Layer type hints.
@ Vector
Vector layer type.
@ Mesh
Mesh layer type, since QGIS 3.6.
@ Raster
Raster layer type.
@ UnknownType
Unknown layer type.
static QString generateTempFilename(const QString &basename)
Returns a temporary filename for a given file, putting it into a temporary folder (creating that fold...
static QgsProcessingFeatureSource * variantToSource(const QVariant &value, QgsProcessingContext &context, const QVariant &fallbackValue=QVariant())
Converts a variant value to a new feature source.
static QString convertToCompatibleFormatAndLayerName(const QgsVectorLayer *layer, bool selectedFeaturesOnly, const QString &baseName, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingContext &context, QgsProcessingFeedback *feedback, QString &layerName, long long featureLimit=-1)
Converts a source vector layer to a file path and layer name of a vector layer of compatible format.
static QgsCoordinateReferenceSystem variantToCrs(const QVariant &value, QgsProcessingContext &context, const QVariant &fallbackValue=QVariant())
Converts a variant value to a coordinate reference system.
static QgsMapLayer * mapLayerFromString(const QString &string, QgsProcessingContext &context, bool allowLoadingNewLayers=true, QgsProcessingUtils::LayerHint typeHint=QgsProcessingUtils::LayerHint::UnknownType)
Interprets a string as a map layer within the supplied context.
static QString defaultRasterExtension()
Returns the default raster extension to use, in the absence of all other constraints (e....
static const QString TEMPORARY_OUTPUT
Constant used to indicate that a Processing algorithm output should be a temporary layer/file.
PythonOutputType
Available Python output types.
Definition: qgsprocessing.h:60
@ PythonQgsProcessingAlgorithmSubclass
Full Python QgsProcessingAlgorithm subclass.
Definition: qgsprocessing.h:61
SourceType
Data source types enum.
Definition: qgsprocessing.h:46
@ TypeVectorLine
Vector line layers.
Definition: qgsprocessing.h:50
@ TypeMapLayer
Any map layer type (raster or vector or mesh)
Definition: qgsprocessing.h:47
@ TypeVectorPolygon
Vector polygon layers.
Definition: qgsprocessing.h:51
@ TypeFile
Files (i.e. non map layer sources, such as text files)
Definition: qgsprocessing.h:53
@ TypeMesh
Mesh layers.
Definition: qgsprocessing.h:55
@ TypeVector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
Definition: qgsprocessing.h:54
@ TypeRaster
Raster layers.
Definition: qgsprocessing.h:52
@ TypeVectorPoint
Vector point layers.
Definition: qgsprocessing.h:49
@ TypeVectorAnyGeometry
Any vector layer with geometry.
Definition: qgsprocessing.h:48
static QString sourceTypeToString(SourceType type)
Converts a source type to a string representation.
Definition: qgsprocessing.h:69
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:99
const QgsLayoutManager * layoutManager() const
Returns the project's layout manager, which manages print layouts, atlases and reports within the pro...
A store for object properties.
Definition: qgsproperty.h:232
@ StaticProperty
Static property (QgsStaticProperty)
Definition: qgsproperty.h:239
QString asExpression() const
Returns an expression string representing the state of the property, or an empty string if the proper...
QString valueAsString(const QgsExpressionContext &context, const QString &defaultString=QString(), bool *ok=nullptr) const
Calculates the current value of the property and interprets it as a string.
QVariant value(const QgsExpressionContext &context, const QVariant &defaultValue=QVariant(), bool *ok=nullptr) const
Calculates the current value of the property, including any transforms which are set for the property...
QVariant toVariant() const
Saves this property to a QVariantMap, wrapped in a QVariant.
bool loadVariant(const QVariant &property)
Loads this property from a QVariantMap, wrapped in a QVariant.
QVariant staticValue() const
Returns the current static value for the property.
Type propertyType() const
Returns the property type.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
QString fileVectorFilters() const
Returns a file filter string for supported vector files.
QString fileRasterFilters() const
Returns a file filter string for supported raster files.
QString fileMeshFilters() const
Returns a file filter string for supported mesh files.
static QStringList supportedFormatExtensions(RasterFormatOptions options=SortRecommended)
Returns a list of file extensions for supported formats.
Represents a raster layer.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:193
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:183
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:188
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:198
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
Definition: qgsrectangle.h:479
QgsCoordinateReferenceSystem crs() const
Returns the associated coordinate reference system, or an invalid CRS if no reference system is set.
A QgsGeometry with associated coordinate reference system.
static QgsReferencedGeometry fromReferencedPointXY(const QgsReferencedPointXY &point)
Construct a new QgsReferencedGeometry from referenced point.
static QgsReferencedGeometry fromReferencedRect(const QgsReferencedRectangle &rectangle)
Construct a new QgsReferencedGeometry from referenced rectangle.
A QgsPointXY with associated coordinate reference system.
A QgsRectangle with associated coordinate reference system.
Defines the parameters used to remap features when creating a QgsRemappingProxyFeatureSink.
static QColor parseColorWithAlpha(const QString &colorStr, bool &containsAlpha, bool strictEval=false)
Attempts to parse a string as a color using a variety of common formats, including hex codes,...
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:68
@ DistanceUnknownUnit
Unknown distance unit.
Definition: qgsunittypes.h:78
static QStringList supportedFormatExtensions(VectorFormatOptions options=SortRecommended)
Returns a list of file extensions for supported formats, e.g "shp", "gpkg".
Represents a vector layer which manages a vector based data sets.
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:141
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:70
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:550
QString parameterAsCompatibleSourceLayerPathInternal(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingFeedback *feedback, QString *layerName)
QString createAllMapLayerFileFilter()
const QgsCoordinateReferenceSystem & crs