QGIS API Documentation  3.24.2-Tisler (13c1a02865)
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 "qgspointcloudlayer.h"
34 #include "qgsannotationlayer.h"
35 #include "qgsapplication.h"
36 #include "qgslayoutmanager.h"
37 #include "qgsprintlayout.h"
38 #include "qgssymbollayerutils.h"
39 #include "qgsfileutils.h"
40 #include "qgsproviderregistry.h"
41 #include <functional>
42 #include <QRegularExpression>
43 
44 
46 {
47  QVariantMap map;
48  map.insert( QStringLiteral( "source" ), source.toVariant() );
49  map.insert( QStringLiteral( "selected_only" ), selectedFeaturesOnly );
50  map.insert( QStringLiteral( "feature_limit" ), featureLimit );
51  map.insert( QStringLiteral( "flags" ), static_cast< int >( flags ) );
52  map.insert( QStringLiteral( "geometry_check" ), static_cast< int >( geometryCheck ) );
53  return map;
54 }
55 
57 {
58  source.loadVariant( map.value( QStringLiteral( "source" ) ) );
59  selectedFeaturesOnly = map.value( QStringLiteral( "selected_only" ), false ).toBool();
60  featureLimit = map.value( QStringLiteral( "feature_limit" ), -1 ).toLongLong();
61  flags = static_cast< Flags >( map.value( QStringLiteral( "flags" ), 0 ).toInt() );
62  geometryCheck = static_cast< QgsFeatureRequest::InvalidGeometryCheck >( map.value( QStringLiteral( "geometry_check" ), QgsFeatureRequest::GeometryAbortOnInvalid ).toInt() );
63  return true;
64 }
65 
66 
67 //
68 // QgsProcessingOutputLayerDefinition
69 //
70 
72 {
73  mUseRemapping = true;
74  mRemappingDefinition = definition;
75 }
76 
78 {
79  QVariantMap map;
80  map.insert( QStringLiteral( "sink" ), sink.toVariant() );
81  map.insert( QStringLiteral( "create_options" ), createOptions );
82  if ( mUseRemapping )
83  map.insert( QStringLiteral( "remapping" ), QVariant::fromValue( mRemappingDefinition ) );
84  return map;
85 }
86 
88 {
89  sink.loadVariant( map.value( QStringLiteral( "sink" ) ) );
90  createOptions = map.value( QStringLiteral( "create_options" ) ).toMap();
91  if ( map.contains( QStringLiteral( "remapping" ) ) )
92  {
93  mUseRemapping = true;
94  mRemappingDefinition = map.value( QStringLiteral( "remapping" ) ).value< QgsRemappingSinkDefinition >();
95  }
96  else
97  {
98  mUseRemapping = false;
99  }
100  return true;
101 }
102 
104 {
106  && mUseRemapping == other.mUseRemapping && mRemappingDefinition == other.mRemappingDefinition;
107 }
108 
110 {
111  return !( *this == other );
112 }
113 
114 bool QgsProcessingParameters::isDynamic( const QVariantMap &parameters, const QString &name )
115 {
116  const QVariant val = parameters.value( name );
117  if ( val.canConvert<QgsProperty>() )
118  return val.value< QgsProperty >().propertyType() != QgsProperty::StaticProperty;
119  else
120  return false;
121 }
122 
123 QString QgsProcessingParameters::parameterAsString( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
124 {
125  if ( !definition )
126  return QString();
127 
128  return parameterAsString( definition, parameters.value( definition->name() ), context );
129 }
130 
131 QString QgsProcessingParameters::parameterAsString( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
132 {
133  if ( !definition )
134  return QString();
135 
136  QVariant val = value;
137  if ( val.canConvert<QgsProperty>() )
138  return val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
139 
140  if ( !val.isValid() )
141  {
142  // fall back to default
143  val = definition->defaultValue();
144  }
145 
146  if ( val == QgsProcessing::TEMPORARY_OUTPUT )
147  {
148  if ( const QgsProcessingDestinationParameter *destParam = dynamic_cast< const QgsProcessingDestinationParameter * >( definition ) )
149  return destParam->generateTemporaryDestination();
150  }
151 
152  return val.toString();
153 }
154 
155 QString QgsProcessingParameters::parameterAsExpression( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
156 {
157  if ( !definition )
158  return QString();
159 
160  return parameterAsExpression( definition, parameters.value( definition->name() ), context );
161 }
162 
163 QString QgsProcessingParameters::parameterAsExpression( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
164 {
165  if ( !definition )
166  return QString();
167 
168  const QVariant val = value;
169  if ( val.canConvert<QgsProperty>() )
170  return val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
171 
172  if ( val.isValid() && !val.toString().isEmpty() )
173  {
174  const QgsExpression e( val.toString() );
175  if ( e.isValid() )
176  return val.toString();
177  }
178 
179  // fall back to default
180  return definition->defaultValue().toString();
181 }
182 
183 double QgsProcessingParameters::parameterAsDouble( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
184 {
185  if ( !definition )
186  return 0;
187 
188  return parameterAsDouble( definition, parameters.value( definition->name() ), context );
189 }
190 
191 double QgsProcessingParameters::parameterAsDouble( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
192 {
193  if ( !definition )
194  return 0;
195 
196  QVariant val = value;
197  if ( val.canConvert<QgsProperty>() )
198  return val.value< QgsProperty >().valueAsDouble( context.expressionContext(), definition->defaultValue().toDouble() );
199 
200  bool ok = false;
201  const double res = val.toDouble( &ok );
202  if ( ok )
203  return res;
204 
205  // fall back to default
206  val = definition->defaultValue();
207  return val.toDouble();
208 }
209 
210 int QgsProcessingParameters::parameterAsInt( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
211 {
212  if ( !definition )
213  return 0;
214 
215  return parameterAsInt( definition, parameters.value( definition->name() ), context );
216 }
217 
218 int QgsProcessingParameters::parameterAsInt( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
219 {
220  if ( !definition )
221  return 0;
222 
223  QVariant val = value;
224  if ( val.canConvert<QgsProperty>() )
225  return val.value< QgsProperty >().valueAsInt( context.expressionContext(), definition->defaultValue().toInt() );
226 
227  bool ok = false;
228  double dbl = val.toDouble( &ok );
229  if ( !ok )
230  {
231  // fall back to default
232  val = definition->defaultValue();
233  dbl = val.toDouble( &ok );
234  }
235 
236  //String representations of doubles in QVariant will not convert to int
237  //work around this by first converting to double, and then checking whether the double is convertible to int
238  if ( ok )
239  {
240  const double round = std::round( dbl );
241  if ( round > std::numeric_limits<int>::max() || round < -std::numeric_limits<int>::max() )
242  {
243  //double too large to fit in int
244  return 0;
245  }
246  return static_cast< int >( std::round( dbl ) );
247  }
248 
249  return val.toInt();
250 }
251 
252 QList< int > QgsProcessingParameters::parameterAsInts( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
253 {
254  if ( !definition )
255  return QList< int >();
256 
257  return parameterAsInts( definition, parameters.value( definition->name() ), context );
258 }
259 
260 QList< int > QgsProcessingParameters::parameterAsInts( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
261 {
262  if ( !definition )
263  return QList< int >();
264 
265  QList< int > resultList;
266  const QVariant val = value;
267  if ( val.isValid() )
268  {
269  if ( val.canConvert<QgsProperty>() )
270  resultList << val.value< QgsProperty >().valueAsInt( context.expressionContext(), definition->defaultValue().toInt() );
271  else if ( val.type() == QVariant::List )
272  {
273  const QVariantList list = val.toList();
274  for ( auto it = list.constBegin(); it != list.constEnd(); ++it )
275  resultList << it->toInt();
276  }
277  else
278  {
279  const QStringList parts = val.toString().split( ';' );
280  for ( auto it = parts.constBegin(); it != parts.constEnd(); ++it )
281  resultList << it->toInt();
282  }
283  }
284 
285  if ( resultList.isEmpty() )
286  {
287  // check default
288  if ( definition->defaultValue().isValid() )
289  {
290  if ( definition->defaultValue().type() == QVariant::List )
291  {
292  const QVariantList list = definition->defaultValue().toList();
293  for ( auto it = list.constBegin(); it != list.constEnd(); ++it )
294  resultList << it->toInt();
295  }
296  else
297  {
298  const QStringList parts = definition->defaultValue().toString().split( ';' );
299  for ( auto it = parts.constBegin(); it != parts.constEnd(); ++it )
300  resultList << it->toInt();
301  }
302  }
303  }
304 
305  return resultList;
306 }
307 
308 QDateTime QgsProcessingParameters::parameterAsDateTime( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
309 {
310  if ( !definition )
311  return QDateTime();
312 
313  return parameterAsDateTime( definition, parameters.value( definition->name() ), context );
314 }
315 
316 QDateTime QgsProcessingParameters::parameterAsDateTime( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
317 {
318  if ( !definition )
319  return QDateTime();
320 
321  QVariant val = value;
322  if ( val.canConvert<QgsProperty>() )
323  val = val.value< QgsProperty >().value( context.expressionContext(), definition->defaultValue() );
324 
325  QDateTime d = val.toDateTime();
326  if ( !d.isValid() && val.type() == QVariant::String )
327  {
328  d = QDateTime::fromString( val.toString() );
329  }
330 
331  if ( !d.isValid() )
332  {
333  // fall back to default
334  val = definition->defaultValue();
335  d = val.toDateTime();
336  }
337  if ( !d.isValid() && val.type() == QVariant::String )
338  {
339  d = QDateTime::fromString( val.toString() );
340  }
341 
342  return d;
343 }
344 
345 QDate QgsProcessingParameters::parameterAsDate( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
346 {
347  if ( !definition )
348  return QDate();
349 
350  return parameterAsDate( definition, parameters.value( definition->name() ), context );
351 }
352 
353 QDate QgsProcessingParameters::parameterAsDate( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
354 {
355  if ( !definition )
356  return QDate();
357 
358  QVariant val = value;
359  if ( val.canConvert<QgsProperty>() )
360  val = val.value< QgsProperty >().value( context.expressionContext(), definition->defaultValue() );
361 
362  QDate d = val.toDate();
363  if ( !d.isValid() && val.type() == QVariant::String )
364  {
365  d = QDate::fromString( val.toString() );
366  }
367 
368  if ( !d.isValid() )
369  {
370  // fall back to default
371  val = definition->defaultValue();
372  d = val.toDate();
373  }
374  if ( !d.isValid() && val.type() == QVariant::String )
375  {
376  d = QDate::fromString( val.toString() );
377  }
378 
379  return d;
380 }
381 
382 QTime QgsProcessingParameters::parameterAsTime( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
383 {
384  if ( !definition )
385  return QTime();
386 
387  return parameterAsTime( definition, parameters.value( definition->name() ), context );
388 }
389 
390 QTime QgsProcessingParameters::parameterAsTime( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
391 {
392  if ( !definition )
393  return QTime();
394 
395  QVariant val = value;
396  if ( val.canConvert<QgsProperty>() )
397  val = val.value< QgsProperty >().value( context.expressionContext(), definition->defaultValue() );
398 
399  QTime d;
400 
401  if ( val.type() == QVariant::DateTime )
402  d = val.toDateTime().time();
403  else
404  d = val.toTime();
405 
406  if ( !d.isValid() && val.type() == QVariant::String )
407  {
408  d = QTime::fromString( val.toString() );
409  }
410 
411  if ( !d.isValid() )
412  {
413  // fall back to default
414  val = definition->defaultValue();
415  d = val.toTime();
416  }
417  if ( !d.isValid() && val.type() == QVariant::String )
418  {
419  d = QTime::fromString( val.toString() );
420  }
421 
422  return d;
423 }
424 
425 int QgsProcessingParameters::parameterAsEnum( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
426 {
427  if ( !definition )
428  return 0;
429 
430  return parameterAsEnum( definition, parameters.value( definition->name() ), context );
431 }
432 
433 int QgsProcessingParameters::parameterAsEnum( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
434 {
435  if ( !definition )
436  return 0;
437 
438  const int val = parameterAsInt( definition, value, context );
439  const QgsProcessingParameterEnum *enumDef = dynamic_cast< const QgsProcessingParameterEnum *>( definition );
440  if ( enumDef && val >= enumDef->options().size() )
441  {
442  return enumDef->defaultValue().toInt();
443  }
444  return val;
445 }
446 
447 QList<int> QgsProcessingParameters::parameterAsEnums( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
448 {
449  if ( !definition )
450  return QList<int>();
451 
452  return parameterAsEnums( definition, parameters.value( definition->name() ), context );
453 }
454 
455 QList<int> QgsProcessingParameters::parameterAsEnums( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
456 {
457  if ( !definition )
458  return QList<int>();
459 
460  QVariantList resultList;
461  const QVariant val = value;
462  if ( val.canConvert<QgsProperty>() )
463  resultList << val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
464  else if ( val.type() == QVariant::List )
465  {
466  const auto constToList = val.toList();
467  for ( const QVariant &var : constToList )
468  resultList << var;
469  }
470  else if ( val.type() == QVariant::String )
471  {
472  const auto constSplit = val.toString().split( ',' );
473  for ( const QString &var : constSplit )
474  resultList << var;
475  }
476  else
477  resultList << val;
478 
479  if ( resultList.isEmpty() )
480  return QList< int >();
481 
482  if ( ( !val.isValid() || !resultList.at( 0 ).isValid() ) && definition )
483  {
484  resultList.clear();
485  // check default
486  if ( definition->defaultValue().type() == QVariant::List )
487  {
488  const auto constToList = definition->defaultValue().toList();
489  for ( const QVariant &var : constToList )
490  resultList << var;
491  }
492  else if ( definition->defaultValue().type() == QVariant::String )
493  {
494  const auto constSplit = definition->defaultValue().toString().split( ',' );
495  for ( const QString &var : constSplit )
496  resultList << var;
497  }
498  else
499  resultList << definition->defaultValue();
500  }
501 
502  QList< int > result;
503  const QgsProcessingParameterEnum *enumDef = dynamic_cast< const QgsProcessingParameterEnum *>( definition );
504  const auto constResultList = resultList;
505  for ( const QVariant &var : constResultList )
506  {
507  const int resInt = var.toInt();
508  if ( !enumDef || resInt < enumDef->options().size() )
509  {
510  result << resInt;
511  }
512  }
513  return result;
514 }
515 
516 QString QgsProcessingParameters::parameterAsEnumString( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
517 {
518  if ( !definition )
519  return QString();
520 
521  return parameterAsEnumString( definition, parameters.value( definition->name() ), context );
522 }
523 
524 QString QgsProcessingParameters::parameterAsEnumString( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
525 {
526  if ( !definition )
527  return QString();
528 
529  QString enumText = parameterAsString( definition, value, context );
530  const QgsProcessingParameterEnum *enumDef = dynamic_cast< const QgsProcessingParameterEnum *>( definition );
531  if ( enumText.isEmpty() || !enumDef->options().contains( enumText ) )
532  enumText = definition->defaultValue().toString();
533 
534  return enumText;
535 }
536 
537 QStringList QgsProcessingParameters::parameterAsEnumStrings( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
538 {
539  if ( !definition )
540  return QStringList();
541 
542  return parameterAsEnumStrings( definition, parameters.value( definition->name() ), context );
543 }
544 
545 QStringList QgsProcessingParameters::parameterAsEnumStrings( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
546 {
547  if ( !definition )
548  return QStringList();
549 
550  const QVariant val = value;
551 
552  QStringList enumValues;
553 
554  std::function< void( const QVariant &var ) > processVariant;
555  processVariant = [ &enumValues, &context, &definition, &processVariant ]( const QVariant & var )
556  {
557  if ( var.type() == QVariant::List )
558  {
559  const auto constToList = var.toList();
560  for ( const QVariant &listVar : constToList )
561  {
562  processVariant( listVar );
563  }
564  }
565  else if ( var.type() == QVariant::StringList )
566  {
567  const auto constToStringList = var.toStringList();
568  for ( const QString &s : constToStringList )
569  {
570  processVariant( s );
571  }
572  }
573  else if ( var.canConvert<QgsProperty>() )
574  processVariant( var.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() ) );
575  else
576  {
577  const QStringList parts = var.toString().split( ',' );
578  for ( const QString &s : parts )
579  {
580  enumValues << s;
581  }
582  }
583  };
584 
585  processVariant( val );
586 
587  const QgsProcessingParameterEnum *enumDef = dynamic_cast< const QgsProcessingParameterEnum *>( definition );
588  // check that values are valid enum values. The resulting set will be empty
589  // if all values are present in the enumDef->options(), otherwise it will contain
590  // values which are invalid
591 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
592  QSet<QString> subtraction = enumValues.toSet().subtract( enumDef->options().toSet() );
593 #else
594  const QStringList options = enumDef->options();
595  const QSet<QString> subtraction = QSet<QString>( enumValues.begin(), enumValues.end() ).subtract( QSet<QString>( options.begin(), options.end() ) );
596 #endif
597 
598  if ( enumValues.isEmpty() || !subtraction.isEmpty() )
599  {
600  enumValues.clear();
601  processVariant( definition->defaultValue() );
602  }
603 
604  return enumValues;
605 }
606 
607 bool QgsProcessingParameters::parameterAsBool( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
608 {
609  if ( !definition )
610  return false;
611 
612  return parameterAsBool( definition, parameters.value( definition->name() ), context );
613 }
614 
615 bool QgsProcessingParameters::parameterAsBoolean( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
616 {
617  if ( !definition )
618  return false;
619 
620  return parameterAsBoolean( definition, parameters.value( definition->name() ), context );
621 }
622 
623 bool QgsProcessingParameters::parameterAsBool( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
624 {
625  if ( !definition )
626  return false;
627 
628  const QVariant def = definition->defaultValue();
629 
630  const QVariant val = value;
631  if ( val.canConvert<QgsProperty>() )
632  return val.value< QgsProperty >().valueAsBool( context.expressionContext(), def.toBool() );
633  else if ( val.isValid() )
634  return val.toBool();
635  else
636  return def.toBool();
637 }
638 
639 bool QgsProcessingParameters::parameterAsBoolean( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
640 {
641  if ( !definition )
642  return false;
643 
644  const QVariant def = definition->defaultValue();
645 
646  const QVariant val = value;
647  if ( val.canConvert<QgsProperty>() )
648  return val.value< QgsProperty >().valueAsBool( context.expressionContext(), def.toBool() );
649  else if ( val.isValid() )
650  return val.toBool();
651  else
652  return def.toBool();
653 }
654 
655 QgsFeatureSink *QgsProcessingParameters::parameterAsSink( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsFields &fields,
657  QgsProcessingContext &context, QString &destinationIdentifier, QgsFeatureSink::SinkFlags sinkFlags,
658  const QVariantMap &createOptions, const QStringList &datasourceOptions, const QStringList &layerOptions )
659 {
660  QVariant val;
661  if ( definition )
662  {
663  val = parameters.value( definition->name() );
664  }
665 
666  return parameterAsSink( definition, val, fields, geometryType, crs, context, destinationIdentifier, sinkFlags, createOptions, datasourceOptions, layerOptions );
667 }
668 
669 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 )
670 {
671  QVariantMap options = createOptions;
672  QVariant val = value;
673 
674  QgsProject *destinationProject = nullptr;
675  QString destName;
676  QgsRemappingSinkDefinition remapDefinition;
677  bool useRemapDefinition = false;
678  if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
679  {
680  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
681  const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
682  destinationProject = fromVar.destinationProject;
683  options = fromVar.createOptions;
684 
685  val = fromVar.sink;
686  destName = fromVar.destinationName;
687  if ( fromVar.useRemapping() )
688  {
689  useRemapDefinition = true;
690  remapDefinition = fromVar.remappingDefinition();
691  }
692  }
693 
694  QString dest;
695  if ( definition && val.canConvert<QgsProperty>() )
696  {
697  dest = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
698  }
699  else if ( !val.isValid() || val.toString().isEmpty() )
700  {
701  if ( definition && definition->flags() & QgsProcessingParameterDefinition::FlagOptional && !definition->defaultValue().isValid() )
702  {
703  // unset, optional sink, no default => no sink
704  return nullptr;
705  }
706  // fall back to default
707  if ( !definition )
708  {
709  throw QgsProcessingException( QObject::tr( "No parameter definition for the sink" ) );
710  }
711  dest = definition->defaultValue().toString();
712  }
713  else
714  {
715  dest = val.toString();
716  }
717  if ( dest == QgsProcessing::TEMPORARY_OUTPUT )
718  {
719  if ( const QgsProcessingDestinationParameter *destParam = dynamic_cast< const QgsProcessingDestinationParameter * >( definition ) )
720  dest = destParam->generateTemporaryDestination();
721  }
722 
723  if ( dest.isEmpty() )
724  return nullptr;
725 
726  std::unique_ptr< QgsFeatureSink > sink( QgsProcessingUtils::createFeatureSink( dest, context, fields, geometryType, crs, options, datasourceOptions, layerOptions, sinkFlags, useRemapDefinition ? &remapDefinition : nullptr ) );
727  destinationIdentifier = dest;
728 
729  if ( destinationProject )
730  {
731  if ( destName.isEmpty() && definition )
732  {
733  destName = definition->description();
734  }
735  QString outputName;
736  if ( definition )
737  outputName = definition->name();
738  context.addLayerToLoadOnCompletion( destinationIdentifier, QgsProcessingContext::LayerDetails( destName, destinationProject, outputName, QgsProcessingUtils::LayerHint::Vector ) );
739  }
740 
741  return sink.release();
742 }
743 
745 {
746  if ( !definition )
747  return nullptr;
748 
749  return parameterAsSource( definition, parameters.value( definition->name() ), context );
750 }
751 
753 {
754  if ( !definition )
755  return nullptr;
756 
757  return QgsProcessingUtils::variantToSource( value, context, definition->defaultValue() );
758 }
759 
760 QString parameterAsCompatibleSourceLayerPathInternal( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingFeedback *feedback, QString *layerName )
761 {
762  if ( !definition )
763  return QString();
764 
765  QVariant val = parameters.value( definition->name() );
766 
767  bool selectedFeaturesOnly = false;
768  long long featureLimit = -1;
769  if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
770  {
771  // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
772  const QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
773  selectedFeaturesOnly = fromVar.selectedFeaturesOnly;
774  featureLimit = fromVar.featureLimit;
775  val = fromVar.source;
776  }
777  else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
778  {
779  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
780  const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
781  val = fromVar.sink;
782  }
783 
784  if ( val.canConvert<QgsProperty>() )
785  {
786  val = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
787  }
788 
789  QgsVectorLayer *vl = nullptr;
790  vl = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( val ) );
791 
792  if ( !vl )
793  {
794  QString layerRef;
795  if ( val.canConvert<QgsProperty>() )
796  {
797  layerRef = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
798  }
799  else if ( !val.isValid() || val.toString().isEmpty() )
800  {
801  // fall back to default
802  val = definition->defaultValue();
803 
804  // default value may be a vector layer
805  vl = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( val ) );
806  if ( !vl )
807  layerRef = definition->defaultValue().toString();
808  }
809  else
810  {
811  layerRef = val.toString();
812  }
813 
814  if ( !vl )
815  {
816  if ( layerRef.isEmpty() )
817  return QString();
818 
819  vl = qobject_cast< QgsVectorLayer *>( QgsProcessingUtils::mapLayerFromString( layerRef, context, true, QgsProcessingUtils::LayerHint::Vector ) );
820  }
821  }
822 
823  if ( !vl )
824  return QString();
825 
826  if ( layerName )
827  return QgsProcessingUtils::convertToCompatibleFormatAndLayerName( vl, selectedFeaturesOnly, definition->name(),
828  compatibleFormats, preferredFormat, context, feedback, *layerName, featureLimit );
829  else
830  return QgsProcessingUtils::convertToCompatibleFormat( vl, selectedFeaturesOnly, definition->name(),
831  compatibleFormats, preferredFormat, context, feedback, featureLimit );
832 }
833 
834 QString QgsProcessingParameters::parameterAsCompatibleSourceLayerPath( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingFeedback *feedback )
835 {
836  return parameterAsCompatibleSourceLayerPathInternal( definition, parameters, context, compatibleFormats, preferredFormat, feedback, nullptr );
837 }
838 
839 QString QgsProcessingParameters::parameterAsCompatibleSourceLayerPathAndLayerName( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingFeedback *feedback, QString *layerName )
840 {
841  QString *destLayer = layerName;
842  QString tmp;
843  if ( destLayer )
844  destLayer->clear();
845  else
846  destLayer = &tmp;
847 
848  return parameterAsCompatibleSourceLayerPathInternal( definition, parameters, context, compatibleFormats, preferredFormat, feedback, destLayer );
849 }
850 
852 {
853  if ( !definition )
854  return nullptr;
855 
856  return parameterAsLayer( definition, parameters.value( definition->name() ), context, layerHint );
857 }
858 
860 {
861  if ( !definition )
862  return nullptr;
863 
864  QVariant val = value;
865  if ( val.canConvert<QgsProperty>() )
866  {
867  val = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
868  }
869 
870  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
871  {
872  return layer;
873  }
874 
875  if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
876  {
877  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
878  const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
879  val = fromVar.sink;
880  }
881 
882  if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
883  {
884  val = val.value< QgsProperty >().staticValue();
885  }
886 
887  if ( !val.isValid() || val.toString().isEmpty() )
888  {
889  // fall back to default
890  val = definition->defaultValue();
891  }
892 
893  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
894  {
895  return layer;
896  }
897 
898  QString layerRef = val.toString();
899  if ( layerRef.isEmpty() )
900  layerRef = definition->defaultValue().toString();
901 
902  if ( layerRef.isEmpty() )
903  return nullptr;
904 
905  return QgsProcessingUtils::mapLayerFromString( layerRef, context, true, layerHint );
906 }
907 
909 {
910  return qobject_cast< QgsRasterLayer *>( parameterAsLayer( definition, parameters, context, QgsProcessingUtils::LayerHint::Raster ) );
911 }
912 
914 {
915  return qobject_cast< QgsRasterLayer *>( parameterAsLayer( definition, value, context, QgsProcessingUtils::LayerHint::Raster ) );
916 }
917 
919 {
920  return qobject_cast< QgsMeshLayer *>( parameterAsLayer( definition, parameters, context, QgsProcessingUtils::LayerHint::Mesh ) );
921 }
922 
924 {
925  return qobject_cast< QgsMeshLayer *>( parameterAsLayer( definition, value, context, QgsProcessingUtils::LayerHint::Mesh ) );
926 }
927 
928 QString QgsProcessingParameters::parameterAsOutputLayer( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
929 {
930  QVariant val;
931  if ( definition )
932  {
933  val = parameters.value( definition->name() );
934  }
935  return parameterAsOutputLayer( definition, val, context );
936 }
937 
939 {
940  QVariant val = value;
941 
942  QgsProject *destinationProject = nullptr;
943  QString destName;
944  if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
945  {
946  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
947  const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
948  destinationProject = fromVar.destinationProject;
949  val = fromVar.sink;
950  destName = fromVar.destinationName;
951  }
952 
953  QString dest;
954  if ( definition && val.canConvert<QgsProperty>() )
955  {
956  dest = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
957  }
958  else if ( definition && ( !val.isValid() || val.toString().isEmpty() ) )
959  {
960  // fall back to default
961  dest = definition->defaultValue().toString();
962  }
963  else
964  {
965  dest = val.toString();
966  }
967  if ( dest == QgsProcessing::TEMPORARY_OUTPUT )
968  {
969  if ( const QgsProcessingDestinationParameter *destParam = dynamic_cast< const QgsProcessingDestinationParameter * >( definition ) )
970  dest = destParam->generateTemporaryDestination();
971  }
972 
973  if ( destinationProject )
974  {
975  QString outputName;
976  if ( destName.isEmpty() && definition )
977  {
978  destName = definition->description();
979  }
980  if ( definition )
981  outputName = definition->name();
982 
984  if ( definition && definition->type() == QgsProcessingParameterVectorDestination::typeName() )
986  else if ( definition && definition->type() == QgsProcessingParameterRasterDestination::typeName() )
988  else if ( definition && definition->type() == QgsProcessingParameterPointCloudDestination::typeName() )
990 
991  context.addLayerToLoadOnCompletion( dest, QgsProcessingContext::LayerDetails( destName, destinationProject, outputName, layerTypeHint ) );
992  }
993 
994  return dest;
995 }
996 
997 QString QgsProcessingParameters::parameterAsFileOutput( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
998 {
999  QVariant val;
1000  if ( definition )
1001  {
1002  val = parameters.value( definition->name() );
1003  }
1004  return parameterAsFileOutput( definition, val, context );
1005 }
1006 
1008 {
1009  QVariant val = value;
1010 
1011  if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
1012  {
1013  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
1014  const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
1015  val = fromVar.sink;
1016  }
1017 
1018  QString dest;
1019  if ( definition && val.canConvert<QgsProperty>() )
1020  {
1021  dest = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1022  }
1023  else if ( definition && ( !val.isValid() || val.toString().isEmpty() ) )
1024  {
1025  // fall back to default
1026  dest = definition->defaultValue().toString();
1027  }
1028  else
1029  {
1030  dest = val.toString();
1031  }
1032  if ( dest == QgsProcessing::TEMPORARY_OUTPUT )
1033  {
1034  if ( const QgsProcessingDestinationParameter *destParam = dynamic_cast< const QgsProcessingDestinationParameter * >( definition ) )
1035  dest = destParam->generateTemporaryDestination();
1036  }
1037  return dest;
1038 }
1039 
1041 {
1042  return qobject_cast< QgsVectorLayer *>( parameterAsLayer( definition, parameters, context, QgsProcessingUtils::LayerHint::Vector ) );
1043 }
1044 
1046 {
1047  return qobject_cast< QgsVectorLayer *>( parameterAsLayer( definition, value, context, QgsProcessingUtils::LayerHint::Vector ) );
1048 }
1049 
1051 {
1052  if ( !definition )
1054 
1055  return parameterAsCrs( definition, parameters.value( definition->name() ), context );
1056 }
1057 
1059 {
1060  if ( !definition )
1062 
1063  return QgsProcessingUtils::variantToCrs( value, context, definition->defaultValue() );
1064 }
1065 
1068 {
1069  if ( !definition )
1070  return QgsRectangle();
1071 
1072  return parameterAsExtent( definition, parameters.value( definition->name() ), context, crs );
1073 }
1074 
1076 {
1077  if ( !definition )
1078  return QgsRectangle();
1079 
1080  QVariant val = value;
1081 
1082  if ( val.canConvert< QgsRectangle >() )
1083  {
1084  return val.value<QgsRectangle>();
1085  }
1086  if ( val.canConvert< QgsGeometry >() )
1087  {
1088  const QgsGeometry geom = val.value<QgsGeometry>();
1089  if ( !geom.isNull() )
1090  return geom.boundingBox();
1091  }
1092  if ( val.canConvert< QgsReferencedRectangle >() )
1093  {
1094  const QgsReferencedRectangle rr = val.value<QgsReferencedRectangle>();
1095  if ( crs.isValid() && rr.crs().isValid() && crs != rr.crs() )
1096  {
1097  QgsCoordinateTransform ct( rr.crs(), crs, context.project() );
1099  try
1100  {
1101  return ct.transformBoundingBox( rr );
1102  }
1103  catch ( QgsCsException & )
1104  {
1105  QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
1106  }
1107  }
1108  return rr;
1109  }
1110 
1111  if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
1112  {
1113  // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
1114  const QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
1115  val = fromVar.source;
1116  }
1117  else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
1118  {
1119  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
1120  const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
1121  val = fromVar.sink;
1122  }
1123 
1124  if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
1125  {
1126  val = val.value< QgsProperty >().staticValue();
1127  }
1128 
1129  // maybe parameter is a direct layer value?
1130  QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) );
1131 
1132  QString rectText;
1133  if ( val.canConvert<QgsProperty>() )
1134  rectText = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1135  else
1136  rectText = val.toString();
1137 
1138  if ( rectText.isEmpty() && !layer )
1139  return QgsRectangle();
1140 
1141  const QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?),\\s*(.*?),\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
1142  const QRegularExpressionMatch match = rx.match( rectText );
1143  if ( match.hasMatch() )
1144  {
1145  bool xMinOk = false;
1146  const double xMin = match.captured( 1 ).toDouble( &xMinOk );
1147  bool xMaxOk = false;
1148  const double xMax = match.captured( 2 ).toDouble( &xMaxOk );
1149  bool yMinOk = false;
1150  const double yMin = match.captured( 3 ).toDouble( &yMinOk );
1151  bool yMaxOk = false;
1152  const double yMax = match.captured( 4 ).toDouble( &yMaxOk );
1153  if ( xMinOk && xMaxOk && yMinOk && yMaxOk )
1154  {
1155  const QgsRectangle rect( xMin, yMin, xMax, yMax );
1156  const QgsCoordinateReferenceSystem rectCrs( match.captured( 5 ) );
1157  if ( crs.isValid() && rectCrs.isValid() && crs != rectCrs )
1158  {
1159  QgsCoordinateTransform ct( rectCrs, crs, context.project() );
1161  try
1162  {
1163  return ct.transformBoundingBox( rect );
1164  }
1165  catch ( QgsCsException & )
1166  {
1167  QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
1168  }
1169  }
1170  return rect;
1171  }
1172  }
1173 
1174  // try as layer extent
1175  if ( !layer )
1176  layer = QgsProcessingUtils::mapLayerFromString( rectText, context );
1177 
1178  if ( layer )
1179  {
1180  const QgsRectangle rect = layer->extent();
1181  if ( crs.isValid() && layer->crs().isValid() && crs != layer->crs() )
1182  {
1183  QgsCoordinateTransform ct( layer->crs(), crs, context.project() );
1185  try
1186  {
1187  return ct.transformBoundingBox( rect );
1188  }
1189  catch ( QgsCsException & )
1190  {
1191  QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
1192  }
1193  }
1194  return rect;
1195  }
1196  return QgsRectangle();
1197 }
1198 
1200 {
1201  if ( !definition )
1202  return QgsGeometry();
1203 
1204  QVariant val = parameters.value( definition->name() );
1205 
1206  if ( val.canConvert< QgsReferencedRectangle >() )
1207  {
1208  const QgsReferencedRectangle rr = val.value<QgsReferencedRectangle>();
1210  if ( crs.isValid() && rr.crs().isValid() && crs != rr.crs() )
1211  {
1212  g = g.densifyByCount( 20 );
1213  const QgsCoordinateTransform ct( rr.crs(), crs, context.project() );
1214  try
1215  {
1216  g.transform( ct );
1217  }
1218  catch ( QgsCsException & )
1219  {
1220  QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
1221  }
1222  return g;
1223  }
1224  }
1225 
1226  if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
1227  {
1228  // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
1229  const QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
1230  val = fromVar.source;
1231  }
1232  else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
1233  {
1234  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
1235  const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
1236  val = fromVar.sink;
1237  }
1238 
1239  if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
1240  {
1241  val = val.value< QgsProperty >().staticValue();
1242  }
1243 
1244  QString rectText;
1245  if ( val.canConvert<QgsProperty>() )
1246  rectText = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1247  else
1248  rectText = val.toString();
1249 
1250  if ( !rectText.isEmpty() )
1251  {
1252  const QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?),\\s*(.*?),\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
1253  const QRegularExpressionMatch match = rx.match( rectText );
1254  if ( match.hasMatch() )
1255  {
1256  bool xMinOk = false;
1257  const double xMin = match.captured( 1 ).toDouble( &xMinOk );
1258  bool xMaxOk = false;
1259  const double xMax = match.captured( 2 ).toDouble( &xMaxOk );
1260  bool yMinOk = false;
1261  const double yMin = match.captured( 3 ).toDouble( &yMinOk );
1262  bool yMaxOk = false;
1263  const double yMax = match.captured( 4 ).toDouble( &yMaxOk );
1264  if ( xMinOk && xMaxOk && yMinOk && yMaxOk )
1265  {
1266  const QgsRectangle rect( xMin, yMin, xMax, yMax );
1267  const QgsCoordinateReferenceSystem rectCrs( match.captured( 5 ) );
1268  QgsGeometry g = QgsGeometry::fromRect( rect );
1269  if ( crs.isValid() && rectCrs.isValid() && crs != rectCrs )
1270  {
1271  g = g.densifyByCount( 20 );
1272  const QgsCoordinateTransform ct( rectCrs, crs, context.project() );
1273  try
1274  {
1275  g.transform( ct );
1276  }
1277  catch ( QgsCsException & )
1278  {
1279  QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
1280  }
1281  return g;
1282  }
1283  }
1284  }
1285  }
1286 
1287  // try as layer extent
1288 
1289  // maybe parameter is a direct layer value?
1290  QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) );
1291  if ( !layer )
1292  layer = QgsProcessingUtils::mapLayerFromString( rectText, context );
1293 
1294  if ( layer )
1295  {
1296  const QgsRectangle rect = layer->extent();
1297  QgsGeometry g = QgsGeometry::fromRect( rect );
1298  if ( crs.isValid() && layer->crs().isValid() && crs != layer->crs() )
1299  {
1300  g = g.densifyByCount( 20 );
1301  const QgsCoordinateTransform ct( layer->crs(), crs, context.project() );
1302  try
1303  {
1304  g.transform( ct );
1305  }
1306  catch ( QgsCsException & )
1307  {
1308  QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
1309  }
1310  }
1311  return g;
1312  }
1313 
1314  return QgsGeometry::fromRect( parameterAsExtent( definition, parameters, context, crs ) );
1315 }
1316 
1318 {
1319  const QVariant val = parameters.value( definition->name() );
1320  return parameterAsExtentCrs( definition, val, context );
1321 }
1322 
1324 {
1325  QVariant val = value;
1326  if ( val.canConvert< QgsReferencedRectangle >() )
1327  {
1328  const QgsReferencedRectangle rr = val.value<QgsReferencedRectangle>();
1329  if ( rr.crs().isValid() )
1330  {
1331  return rr.crs();
1332  }
1333  }
1334 
1335  if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
1336  {
1337  // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
1338  const QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
1339  val = fromVar.source;
1340  }
1341  else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
1342  {
1343  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
1344  const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
1345  val = fromVar.sink;
1346  }
1347 
1348  if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
1349  {
1350  val = val.value< QgsProperty >().staticValue();
1351  }
1352 
1353  QString valueAsString;
1354  if ( val.canConvert<QgsProperty>() )
1355  valueAsString = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1356  else
1357  valueAsString = val.toString();
1358 
1359  const QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?),\\s*(.*?),\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
1360 
1361  const QRegularExpressionMatch match = rx.match( valueAsString );
1362  if ( match.hasMatch() )
1363  {
1364  const QgsCoordinateReferenceSystem crs( match.captured( 5 ) );
1365  if ( crs.isValid() )
1366  return crs;
1367  }
1368 
1369  if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
1370  {
1371  // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
1372  const QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
1373  val = fromVar.source;
1374  }
1375  else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
1376  {
1377  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
1378  const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
1379  val = fromVar.sink;
1380  }
1381 
1382  if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
1383  {
1384  val = val.value< QgsProperty >().staticValue();
1385  }
1386 
1387  // try as layer crs
1388  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
1389  return layer->crs();
1390  else if ( QgsMapLayer *layer = QgsProcessingUtils::mapLayerFromString( valueAsString, context ) )
1391  return layer->crs();
1392 
1393  if ( auto *lProject = context.project() )
1394  return lProject->crs();
1395  else
1397 }
1398 
1400 {
1401  if ( !definition )
1402  return QgsPointXY();
1403 
1404  return parameterAsPoint( definition, parameters.value( definition->name() ), context, crs );
1405 }
1406 
1408 {
1409  if ( !definition )
1410  return QgsPointXY();
1411 
1412  const QVariant val = value;
1413  if ( val.canConvert< QgsPointXY >() )
1414  {
1415  return val.value<QgsPointXY>();
1416  }
1417  if ( val.canConvert< QgsGeometry >() )
1418  {
1419  const QgsGeometry geom = val.value<QgsGeometry>();
1420  if ( !geom.isNull() )
1421  return geom.centroid().asPoint();
1422  }
1423  if ( val.canConvert< QgsReferencedPointXY >() )
1424  {
1425  const QgsReferencedPointXY rp = val.value<QgsReferencedPointXY>();
1426  if ( crs.isValid() && rp.crs().isValid() && crs != rp.crs() )
1427  {
1428  const QgsCoordinateTransform ct( rp.crs(), crs, context.project() );
1429  try
1430  {
1431  return ct.transform( rp );
1432  }
1433  catch ( QgsCsException & )
1434  {
1435  QgsMessageLog::logMessage( QObject::tr( "Error transforming point geometry" ) );
1436  }
1437  }
1438  return rp;
1439  }
1440 
1441  QString pointText = parameterAsString( definition, value, context );
1442  if ( pointText.isEmpty() )
1443  pointText = definition->defaultValue().toString();
1444 
1445  if ( pointText.isEmpty() )
1446  return QgsPointXY();
1447 
1448  const QRegularExpression rx( QStringLiteral( "^\\s*\\(?\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*\\)?\\s*$" ) );
1449 
1450  const QString valueAsString = parameterAsString( definition, value, context );
1451  const QRegularExpressionMatch match = rx.match( valueAsString );
1452  if ( match.hasMatch() )
1453  {
1454  bool xOk = false;
1455  const double x = match.captured( 1 ).toDouble( &xOk );
1456  bool yOk = false;
1457  const double y = match.captured( 2 ).toDouble( &yOk );
1458 
1459  if ( xOk && yOk )
1460  {
1461  const QgsPointXY pt( x, y );
1462 
1463  const QgsCoordinateReferenceSystem pointCrs( match.captured( 3 ) );
1464  if ( crs.isValid() && pointCrs.isValid() && crs != pointCrs )
1465  {
1466  const QgsCoordinateTransform ct( pointCrs, crs, context.project() );
1467  try
1468  {
1469  return ct.transform( pt );
1470  }
1471  catch ( QgsCsException & )
1472  {
1473  QgsMessageLog::logMessage( QObject::tr( "Error transforming point geometry" ) );
1474  }
1475  }
1476  return pt;
1477  }
1478  }
1479 
1480  return QgsPointXY();
1481 }
1482 
1484 {
1485  const QVariant val = parameters.value( definition->name() );
1486  return parameterAsPointCrs( definition, val, context );
1487 }
1488 
1490 {
1491  if ( value.canConvert< QgsReferencedPointXY >() )
1492  {
1493  const QgsReferencedPointXY rr = value.value<QgsReferencedPointXY>();
1494  if ( rr.crs().isValid() )
1495  {
1496  return rr.crs();
1497  }
1498  }
1499 
1500  const QRegularExpression rx( QStringLiteral( "^\\s*\\(?\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*\\)?\\s*$" ) );
1501 
1502  const QString valueAsString = parameterAsString( definition, value, context );
1503  const QRegularExpressionMatch match = rx.match( valueAsString );
1504  if ( match.hasMatch() )
1505  {
1506  const QgsCoordinateReferenceSystem crs( match.captured( 3 ) );
1507  if ( crs.isValid() )
1508  return crs;
1509  }
1510 
1511  if ( auto *lProject = context.project() )
1512  return lProject->crs();
1513  else
1515 }
1516 
1518 {
1519  if ( !definition )
1520  return QgsGeometry();
1521 
1522  return parameterAsGeometry( definition, parameters.value( definition->name() ), context, crs );
1523 }
1524 
1526 {
1527  if ( !definition )
1528  return QgsGeometry();
1529 
1530  const QVariant val = value;
1531  if ( val.canConvert< QgsGeometry >() )
1532  {
1533  return val.value<QgsGeometry>();
1534  }
1535 
1536  if ( val.canConvert< QgsPointXY >() )
1537  {
1538  return QgsGeometry::fromPointXY( val.value<QgsPointXY>() );
1539  }
1540 
1541  if ( val.canConvert< QgsRectangle >() )
1542  {
1543  return QgsGeometry::fromRect( val.value<QgsRectangle>() );
1544  }
1545 
1546  if ( val.canConvert< QgsReferencedPointXY >() )
1547  {
1548  const QgsReferencedPointXY rp = val.value<QgsReferencedPointXY>();
1549  if ( crs.isValid() && rp.crs().isValid() && crs != rp.crs() )
1550  {
1551  const QgsCoordinateTransform ct( rp.crs(), crs, context.project() );
1552  try
1553  {
1554  return QgsGeometry::fromPointXY( ct.transform( rp ) );
1555  }
1556  catch ( QgsCsException & )
1557  {
1558  QgsMessageLog::logMessage( QObject::tr( "Error transforming point geometry" ) );
1559  }
1560  }
1561  return QgsGeometry::fromPointXY( rp );
1562  }
1563 
1564  if ( val.canConvert< QgsReferencedRectangle >() )
1565  {
1566  const QgsReferencedRectangle rr = val.value<QgsReferencedRectangle>();
1568  if ( crs.isValid() && rr.crs().isValid() && crs != rr.crs() )
1569  {
1570  g = g.densifyByCount( 20 );
1571  const QgsCoordinateTransform ct( rr.crs(), crs, context.project() );
1572  try
1573  {
1574  g.transform( ct );
1575  }
1576  catch ( QgsCsException & )
1577  {
1578  QgsMessageLog::logMessage( QObject::tr( "Error transforming rectangle geometry" ) );
1579  }
1580  }
1581  return g;
1582  }
1583 
1584  if ( val.canConvert< QgsReferencedGeometry >() )
1585  {
1586  QgsReferencedGeometry rg = val.value<QgsReferencedGeometry>();
1587  if ( crs.isValid() && rg.crs().isValid() && crs != rg.crs() )
1588  {
1589  const QgsCoordinateTransform ct( rg.crs(), crs, context.project() );
1590  try
1591  {
1592  rg.transform( ct );
1593  }
1594  catch ( QgsCsException & )
1595  {
1596  QgsMessageLog::logMessage( QObject::tr( "Error transforming geometry" ) );
1597  }
1598  }
1599  return rg;
1600  }
1601 
1602  QString valueAsString = parameterAsString( definition, value, context );
1603  if ( valueAsString.isEmpty() )
1604  valueAsString = definition->defaultValue().toString();
1605 
1606  if ( valueAsString.isEmpty() )
1607  return QgsGeometry();
1608 
1609  const QRegularExpression rx( QStringLiteral( "^\\s*(?:CRS=(.*);)?(.*?)$" ) );
1610 
1611  const QRegularExpressionMatch match = rx.match( valueAsString );
1612  if ( match.hasMatch() )
1613  {
1614  QgsGeometry g = QgsGeometry::fromWkt( match.captured( 2 ) );
1615  if ( !g.isNull() )
1616  {
1617  const QgsCoordinateReferenceSystem geomCrs( match.captured( 1 ) );
1618  if ( crs.isValid() && geomCrs.isValid() && crs != geomCrs )
1619  {
1620  const QgsCoordinateTransform ct( geomCrs, crs, context.project() );
1621  try
1622  {
1623  g.transform( ct );
1624  }
1625  catch ( QgsCsException & )
1626  {
1627  QgsMessageLog::logMessage( QObject::tr( "Error transforming geometry" ) );
1628  }
1629  }
1630  return g;
1631  }
1632  }
1633 
1634  return QgsGeometry();
1635 }
1636 
1638 {
1639  const QVariant val = parameters.value( definition->name() );
1640  return parameterAsGeometryCrs( definition, val, context );
1641 }
1642 
1644 {
1645  if ( value.canConvert< QgsReferencedGeometry >() )
1646  {
1647  const QgsReferencedGeometry rg = value.value<QgsReferencedGeometry>();
1648  if ( rg.crs().isValid() )
1649  {
1650  return rg.crs();
1651  }
1652  }
1653 
1654  if ( value.canConvert< QgsReferencedPointXY >() )
1655  {
1656  const QgsReferencedPointXY rp = value.value<QgsReferencedPointXY>();
1657  if ( rp.crs().isValid() )
1658  {
1659  return rp.crs();
1660  }
1661  }
1662 
1663  if ( value.canConvert< QgsReferencedRectangle >() )
1664  {
1665  const QgsReferencedRectangle rr = value.value<QgsReferencedRectangle>();
1666  if ( rr.crs().isValid() )
1667  {
1668  return rr.crs();
1669  }
1670  }
1671 
1672  // Match against EWKT
1673  const QRegularExpression rx( QStringLiteral( "^\\s*(?:CRS=(.*);)?(.*?)$" ) );
1674 
1675  const QString valueAsString = parameterAsString( definition, value, context );
1676  const QRegularExpressionMatch match = rx.match( valueAsString );
1677  if ( match.hasMatch() )
1678  {
1679  const QgsCoordinateReferenceSystem crs( match.captured( 1 ) );
1680  if ( crs.isValid() )
1681  return crs;
1682  }
1683 
1684  if ( auto *lProject = context.project() )
1685  return lProject->crs();
1686  else
1688 }
1689 
1690 QString QgsProcessingParameters::parameterAsFile( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1691 {
1692  if ( !definition )
1693  return QString();
1694 
1695  QString fileText = parameterAsString( definition, parameters, context );
1696  if ( fileText.isEmpty() )
1697  fileText = definition->defaultValue().toString();
1698  return fileText;
1699 }
1700 
1701 QString QgsProcessingParameters::parameterAsFile( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1702 {
1703  if ( !definition )
1704  return QString();
1705 
1706  QString fileText = parameterAsString( definition, value, context );
1707  if ( fileText.isEmpty() )
1708  fileText = definition->defaultValue().toString();
1709  return fileText;
1710 }
1711 
1712 QVariantList QgsProcessingParameters::parameterAsMatrix( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1713 {
1714  if ( !definition )
1715  return QVariantList();
1716 
1717  return parameterAsMatrix( definition, parameters.value( definition->name() ), context );
1718 }
1719 
1720 QVariantList QgsProcessingParameters::parameterAsMatrix( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1721 {
1722  if ( !definition )
1723  return QVariantList();
1724 
1725  QString resultString;
1726  const QVariant val = value;
1727  if ( val.canConvert<QgsProperty>() )
1728  resultString = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1729  else if ( val.type() == QVariant::List )
1730  return val.toList();
1731  else
1732  resultString = val.toString();
1733 
1734  if ( resultString.isEmpty() )
1735  {
1736  // check default
1737  if ( definition->defaultValue().type() == QVariant::List )
1738  return definition->defaultValue().toList();
1739  else
1740  resultString = definition->defaultValue().toString();
1741  }
1742 
1743  QVariantList result;
1744  const auto constSplit = resultString.split( ',' );
1745  bool ok;
1746  double number;
1747  for ( const QString &s : constSplit )
1748  {
1749  number = s.toDouble( &ok );
1750  result << ( ok ? QVariant( number ) : s );
1751  }
1752 
1753  return result;
1754 }
1755 
1756 QList<QgsMapLayer *> QgsProcessingParameters::parameterAsLayerList( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1757 {
1758  if ( !definition )
1759  return QList<QgsMapLayer *>();
1760 
1761  return parameterAsLayerList( definition, parameters.value( definition->name() ), context );
1762 }
1763 
1764 QList<QgsMapLayer *> QgsProcessingParameters::parameterAsLayerList( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1765 {
1766  if ( !definition )
1767  return QList<QgsMapLayer *>();
1768 
1769  const QVariant val = value;
1770  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
1771  {
1772  return QList<QgsMapLayer *>() << layer;
1773  }
1774 
1775  QList<QgsMapLayer *> layers;
1776 
1777  std::function< void( const QVariant &var ) > processVariant;
1778  processVariant = [ &layers, &context, &definition, &processVariant ]( const QVariant & var )
1779  {
1780  if ( var.type() == QVariant::List )
1781  {
1782  const auto constToList = var.toList();
1783  for ( const QVariant &listVar : constToList )
1784  {
1785  processVariant( listVar );
1786  }
1787  }
1788  else if ( var.type() == QVariant::StringList )
1789  {
1790  const auto constToStringList = var.toStringList();
1791  for ( const QString &s : constToStringList )
1792  {
1793  processVariant( s );
1794  }
1795  }
1796  else if ( var.canConvert<QgsProperty>() )
1797  processVariant( var.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() ) );
1798  else if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
1799  {
1800  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
1801  const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
1802  const QVariant sink = fromVar.sink;
1803  if ( sink.canConvert<QgsProperty>() )
1804  {
1805  processVariant( sink.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() ) );
1806  }
1807  }
1808  else if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( var ) ) )
1809  {
1810  layers << layer;
1811  }
1812  else
1813  {
1814  QgsMapLayer *alayer = QgsProcessingUtils::mapLayerFromString( var.toString(), context );
1815  if ( alayer )
1816  layers << alayer;
1817  }
1818  };
1819 
1820  processVariant( val );
1821 
1822  if ( layers.isEmpty() )
1823  {
1824  // check default
1825  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( definition->defaultValue() ) ) )
1826  {
1827  layers << layer;
1828  }
1829  else if ( definition->defaultValue().type() == QVariant::List )
1830  {
1831  const auto constToList = definition->defaultValue().toList();
1832  for ( const QVariant &var : constToList )
1833  {
1834  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( var ) ) )
1835  {
1836  layers << layer;
1837  }
1838  else
1839  {
1840  processVariant( var );
1841  }
1842  }
1843  }
1844  else
1845  processVariant( definition->defaultValue() );
1846  }
1847 
1848  return layers;
1849 }
1850 
1851 QStringList QgsProcessingParameters::parameterAsFileList( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1852 {
1853  if ( !definition )
1854  return QStringList();
1855 
1856  const QVariant val = value;
1857 
1858  QStringList files;
1859 
1860  std::function< void( const QVariant &var ) > processVariant;
1861  processVariant = [ &files, &context, &definition, &processVariant ]( const QVariant & var )
1862  {
1863  if ( var.type() == QVariant::List )
1864  {
1865  const auto constToList = var.toList();
1866  for ( const QVariant &listVar : constToList )
1867  {
1868  processVariant( listVar );
1869  }
1870  }
1871  else if ( var.type() == QVariant::StringList )
1872  {
1873  const auto constToStringList = var.toStringList();
1874  for ( const QString &s : constToStringList )
1875  {
1876  processVariant( s );
1877  }
1878  }
1879  else if ( var.canConvert<QgsProperty>() )
1880  processVariant( var.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() ) );
1881  else
1882  {
1883  files << var.toString();
1884  }
1885  };
1886 
1887  processVariant( val );
1888 
1889  if ( files.isEmpty() )
1890  {
1891  processVariant( definition->defaultValue() );
1892  }
1893 
1894  return files;
1895 }
1896 
1897 QStringList QgsProcessingParameters::parameterAsFileList( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1898 {
1899  if ( !definition )
1900  return QStringList();
1901 
1902  return parameterAsFileList( definition, parameters.value( definition->name() ), context );
1903 }
1904 
1905 QList<double> QgsProcessingParameters::parameterAsRange( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1906 {
1907  if ( !definition )
1908  return QList<double>();
1909 
1910  return parameterAsRange( definition, parameters.value( definition->name() ), context );
1911 }
1912 
1913 QList<double> QgsProcessingParameters::parameterAsRange( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1914 {
1915  if ( !definition )
1916  return QList<double>();
1917 
1918  QStringList resultStringList;
1919  const QVariant val = value;
1920 
1921  if ( val.canConvert<QgsProperty>() )
1922  resultStringList << val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1923  else if ( val.type() == QVariant::List )
1924  {
1925  const auto constToList = val.toList();
1926  for ( const QVariant &var : constToList )
1927  resultStringList << var.toString();
1928  }
1929  else
1930  resultStringList << val.toString();
1931 
1932  if ( ( resultStringList.isEmpty() || ( resultStringList.size() == 1 && resultStringList.at( 0 ).isEmpty() ) ) )
1933  {
1934  resultStringList.clear();
1935  // check default
1936  if ( definition->defaultValue().type() == QVariant::List )
1937  {
1938  const auto constToList = definition->defaultValue().toList();
1939  for ( const QVariant &var : constToList )
1940  resultStringList << var.toString();
1941  }
1942  else
1943  resultStringList << definition->defaultValue().toString();
1944  }
1945 
1946  if ( resultStringList.size() == 1 )
1947  {
1948  resultStringList = resultStringList.at( 0 ).split( ',' );
1949  }
1950 
1951  if ( resultStringList.size() < 2 )
1952  return QList< double >() << std::numeric_limits<double>::quiet_NaN() << std::numeric_limits<double>::quiet_NaN() ;
1953 
1954  QList< double > result;
1955  bool ok = false;
1956  double n = resultStringList.at( 0 ).toDouble( &ok );
1957  if ( ok )
1958  result << n;
1959  else
1960  result << std::numeric_limits<double>::quiet_NaN() ;
1961  ok = false;
1962  n = resultStringList.at( 1 ).toDouble( &ok );
1963  if ( ok )
1964  result << n;
1965  else
1966  result << std::numeric_limits<double>::quiet_NaN() ;
1967 
1968  return result;
1969 }
1970 
1971 QStringList QgsProcessingParameters::parameterAsFields( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1972 {
1973  if ( !definition )
1974  return QStringList();
1975 
1976  const QStringList resultStringList;
1977  return parameterAsFields( definition, parameters.value( definition->name() ), context );
1978 }
1979 
1980 QStringList QgsProcessingParameters::parameterAsFields( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1981 {
1982  if ( !definition )
1983  return QStringList();
1984 
1985  QStringList resultStringList;
1986  const QVariant val = value;
1987  if ( val.isValid() )
1988  {
1989  if ( val.canConvert<QgsProperty>() )
1990  resultStringList << val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1991  else if ( val.type() == QVariant::List )
1992  {
1993  const auto constToList = val.toList();
1994  for ( const QVariant &var : constToList )
1995  resultStringList << var.toString();
1996  }
1997  else if ( val.type() == QVariant::StringList )
1998  {
1999  resultStringList = val.toStringList();
2000  }
2001  else
2002  resultStringList.append( val.toString().split( ';' ) );
2003  }
2004 
2005  if ( ( resultStringList.isEmpty() || resultStringList.at( 0 ).isEmpty() ) )
2006  {
2007  resultStringList.clear();
2008  // check default
2009  if ( definition->defaultValue().isValid() )
2010  {
2011  if ( definition->defaultValue().type() == QVariant::List )
2012  {
2013  const auto constToList = definition->defaultValue().toList();
2014  for ( const QVariant &var : constToList )
2015  resultStringList << var.toString();
2016  }
2017  else if ( definition->defaultValue().type() == QVariant::StringList )
2018  {
2019  resultStringList = definition->defaultValue().toStringList();
2020  }
2021  else
2022  resultStringList.append( definition->defaultValue().toString().split( ';' ) );
2023  }
2024  }
2025 
2026  return resultStringList;
2027 }
2028 
2030 {
2031  if ( !definition )
2032  return nullptr;
2033 
2034  return parameterAsLayout( definition, parameters.value( definition->name() ), context );
2035 }
2036 
2038 {
2039  const QString layoutName = parameterAsString( definition, value, context );
2040  if ( layoutName.isEmpty() )
2041  return nullptr;
2042 
2043  if ( !context.project() )
2044  return nullptr;
2045 
2046  QgsMasterLayoutInterface *l = context.project()->layoutManager()->layoutByName( layoutName );
2048  return static_cast< QgsPrintLayout * >( l );
2049  else
2050  return nullptr;
2051 }
2052 
2054 {
2055  if ( !definition )
2056  return nullptr;
2057 
2058  return parameterAsLayoutItem( definition, parameters.value( definition->name() ), context, layout );
2059 }
2060 
2062 {
2063  if ( !layout )
2064  return nullptr;
2065 
2066  const QString id = parameterAsString( definition, value, context );
2067  if ( id.isEmpty() )
2068  return nullptr;
2069 
2070  // prefer matching by uuid, since it's guaranteed to be unique.
2071  if ( QgsLayoutItem *item = layout->itemByUuid( id ) )
2072  return item;
2073  else if ( QgsLayoutItem *item = layout->itemById( id ) )
2074  return item;
2075  else
2076  return nullptr;
2077 }
2078 
2079 QColor QgsProcessingParameters::parameterAsColor( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
2080 {
2081  if ( !definition )
2082  return QColor();
2083 
2084  return parameterAsColor( definition, parameters.value( definition->name() ), context );
2085 }
2086 
2088 {
2089  if ( !definition )
2090  return QColor();
2091 
2092  QVariant val = value;
2093  if ( val.canConvert<QgsProperty>() )
2094  {
2095  val = val.value< QgsProperty >().value( context.expressionContext(), definition->defaultValue() );
2096  }
2097  if ( val.type() == QVariant::Color )
2098  {
2099  QColor c = val.value< QColor >();
2100  if ( const QgsProcessingParameterColor *colorParam = dynamic_cast< const QgsProcessingParameterColor * >( definition ) )
2101  if ( !colorParam->opacityEnabled() )
2102  c.setAlpha( 255 );
2103  return c;
2104  }
2105 
2106  QString colorText = parameterAsString( definition, value, context );
2107  if ( colorText.isEmpty() && !( definition->flags() & QgsProcessingParameterDefinition::FlagOptional ) )
2108  {
2109  if ( definition->defaultValue().type() == QVariant::Color )
2110  return definition->defaultValue().value< QColor >();
2111  else
2112  colorText = definition->defaultValue().toString();
2113  }
2114 
2115  if ( colorText.isEmpty() )
2116  return QColor();
2117 
2118  bool containsAlpha = false;
2119  QColor c = QgsSymbolLayerUtils::parseColorWithAlpha( colorText, containsAlpha );
2120  if ( const QgsProcessingParameterColor *colorParam = dynamic_cast< const QgsProcessingParameterColor * >( definition ) )
2121  if ( c.isValid() && !colorParam->opacityEnabled() )
2122  c.setAlpha( 255 );
2123  return c;
2124 }
2125 
2126 QString QgsProcessingParameters::parameterAsConnectionName( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
2127 {
2128  if ( !definition )
2129  return QString();
2130 
2131  return parameterAsConnectionName( definition, parameters.value( definition->name() ), context );
2132 }
2133 
2134 QString QgsProcessingParameters::parameterAsConnectionName( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
2135 {
2136  // for now it's just treated identical to strings, but in future we may want flexibility to amend this
2137  // (hence the new method)
2138  return parameterAsString( definition, value, context );
2139 }
2140 
2141 QString QgsProcessingParameters::parameterAsSchema( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
2142 {
2143  if ( !definition )
2144  return QString();
2145 
2146  return parameterAsSchema( definition, parameters.value( definition->name() ), context );
2147 }
2148 
2149 QString QgsProcessingParameters::parameterAsSchema( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
2150 {
2151  // 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
2152  // parameter values, such as via a delimiter separated string)
2153  return parameterAsString( definition, value, context );
2154 }
2155 
2156 QString QgsProcessingParameters::parameterAsDatabaseTableName( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
2157 {
2158  if ( !definition )
2159  return QString();
2160 
2161  return parameterAsDatabaseTableName( definition, parameters.value( definition->name() ), context );
2162 }
2163 
2165 {
2166  // 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
2167  // parameter values, such as via a delimiter separated string)
2168  return parameterAsString( definition, value, context );
2169 }
2170 
2172 {
2173  return qobject_cast< QgsPointCloudLayer *>( parameterAsLayer( definition, parameters, context, QgsProcessingUtils::LayerHint::PointCloud ) );
2174 }
2175 
2177 {
2178  return qobject_cast< QgsPointCloudLayer *>( parameterAsLayer( definition, value, context, QgsProcessingUtils::LayerHint::PointCloud ) );
2179 }
2180 
2182 {
2183  return qobject_cast< QgsAnnotationLayer *>( parameterAsLayer( definition, parameters, context, QgsProcessingUtils::LayerHint::Annotation ) );
2184 }
2185 
2187 {
2188  return qobject_cast< QgsAnnotationLayer *>( parameterAsLayer( definition, value, context, QgsProcessingUtils::LayerHint::Annotation ) );
2189 }
2190 
2192 {
2193  const QString type = map.value( QStringLiteral( "parameter_type" ) ).toString();
2194  const QString name = map.value( QStringLiteral( "name" ) ).toString();
2195  std::unique_ptr< QgsProcessingParameterDefinition > def;
2196 
2197  // probably all these hardcoded values aren't required anymore, and we could
2198  // always resort to the registry lookup...
2199  // TODO: confirm
2201  def.reset( new QgsProcessingParameterBoolean( name ) );
2202  else if ( type == QgsProcessingParameterCrs::typeName() )
2203  def.reset( new QgsProcessingParameterCrs( name ) );
2204  else if ( type == QgsProcessingParameterMapLayer::typeName() )
2205  def.reset( new QgsProcessingParameterMapLayer( name ) );
2206  else if ( type == QgsProcessingParameterExtent::typeName() )
2207  def.reset( new QgsProcessingParameterExtent( name ) );
2208  else if ( type == QgsProcessingParameterPoint::typeName() )
2209  def.reset( new QgsProcessingParameterPoint( name ) );
2210  else if ( type == QgsProcessingParameterFile::typeName() )
2211  def.reset( new QgsProcessingParameterFile( name ) );
2212  else if ( type == QgsProcessingParameterMatrix::typeName() )
2213  def.reset( new QgsProcessingParameterMatrix( name ) );
2215  def.reset( new QgsProcessingParameterMultipleLayers( name ) );
2216  else if ( type == QgsProcessingParameterNumber::typeName() )
2217  def.reset( new QgsProcessingParameterNumber( name ) );
2218  else if ( type == QgsProcessingParameterRange::typeName() )
2219  def.reset( new QgsProcessingParameterRange( name ) );
2220  else if ( type == QgsProcessingParameterRasterLayer::typeName() )
2221  def.reset( new QgsProcessingParameterRasterLayer( name ) );
2222  else if ( type == QgsProcessingParameterEnum::typeName() )
2223  def.reset( new QgsProcessingParameterEnum( name ) );
2224  else if ( type == QgsProcessingParameterString::typeName() )
2225  def.reset( new QgsProcessingParameterString( name ) );
2226  else if ( type == QgsProcessingParameterAuthConfig::typeName() )
2227  def.reset( new QgsProcessingParameterAuthConfig( name ) );
2228  else if ( type == QgsProcessingParameterExpression::typeName() )
2229  def.reset( new QgsProcessingParameterExpression( name ) );
2230  else if ( type == QgsProcessingParameterVectorLayer::typeName() )
2231  def.reset( new QgsProcessingParameterVectorLayer( name ) );
2232  else if ( type == QgsProcessingParameterField::typeName() )
2233  def.reset( new QgsProcessingParameterField( name ) );
2234  else if ( type == QgsProcessingParameterFeatureSource::typeName() )
2235  def.reset( new QgsProcessingParameterFeatureSource( name ) );
2236  else if ( type == QgsProcessingParameterFeatureSink::typeName() )
2237  def.reset( new QgsProcessingParameterFeatureSink( name ) );
2239  def.reset( new QgsProcessingParameterVectorDestination( name ) );
2241  def.reset( new QgsProcessingParameterRasterDestination( name ) );
2243  def.reset( new QgsProcessingParameterPointCloudDestination( name ) );
2245  def.reset( new QgsProcessingParameterFileDestination( name ) );
2247  def.reset( new QgsProcessingParameterFolderDestination( name ) );
2248  else if ( type == QgsProcessingParameterBand::typeName() )
2249  def.reset( new QgsProcessingParameterBand( name ) );
2250  else if ( type == QgsProcessingParameterMeshLayer::typeName() )
2251  def.reset( new QgsProcessingParameterMeshLayer( name ) );
2252  else if ( type == QgsProcessingParameterLayout::typeName() )
2253  def.reset( new QgsProcessingParameterLayout( name ) );
2254  else if ( type == QgsProcessingParameterLayoutItem::typeName() )
2255  def.reset( new QgsProcessingParameterLayoutItem( name ) );
2256  else if ( type == QgsProcessingParameterColor::typeName() )
2257  def.reset( new QgsProcessingParameterColor( name ) );
2259  def.reset( new QgsProcessingParameterCoordinateOperation( name ) );
2261  def.reset( new QgsProcessingParameterPointCloudLayer( name ) );
2263  def.reset( new QgsProcessingParameterAnnotationLayer( name ) );
2264  else
2265  {
2267  if ( paramType )
2268  def.reset( paramType->create( name ) );
2269  }
2270 
2271  if ( !def )
2272  return nullptr;
2273 
2274  def->fromVariantMap( map );
2275  return def.release();
2276 }
2277 
2278 QString QgsProcessingParameters::descriptionFromName( const QString &name )
2279 {
2280  QString desc = name;
2281  desc.replace( '_', ' ' );
2282  return desc;
2283 }
2284 
2286 {
2287  bool isOptional = false;
2288  QString name;
2289  QString definition;
2290  QString type;
2291  if ( !parseScriptCodeParameterOptions( code, isOptional, name, type, definition ) )
2292  return nullptr;
2293 
2294  const QString description = descriptionFromName( name );
2295 
2296  if ( type == QLatin1String( "boolean" ) )
2297  return QgsProcessingParameterBoolean::fromScriptCode( name, description, isOptional, definition );
2298  else if ( type == QLatin1String( "crs" ) )
2299  return QgsProcessingParameterCrs::fromScriptCode( name, description, isOptional, definition );
2300  else if ( type == QLatin1String( "layer" ) )
2301  return QgsProcessingParameterMapLayer::fromScriptCode( name, description, isOptional, definition );
2302  else if ( type == QLatin1String( "extent" ) )
2303  return QgsProcessingParameterExtent::fromScriptCode( name, description, isOptional, definition );
2304  else if ( type == QLatin1String( "point" ) )
2305  return QgsProcessingParameterPoint::fromScriptCode( name, description, isOptional, definition );
2306  else if ( type == QLatin1String( "geometry" ) )
2307  return QgsProcessingParameterGeometry::fromScriptCode( name, description, isOptional, definition );
2308  else if ( type == QLatin1String( "file" ) )
2309  return QgsProcessingParameterFile::fromScriptCode( name, description, isOptional, definition, QgsProcessingParameterFile::File );
2310  else if ( type == QLatin1String( "folder" ) )
2311  return QgsProcessingParameterFile::fromScriptCode( name, description, isOptional, definition, QgsProcessingParameterFile::Folder );
2312  else if ( type == QLatin1String( "matrix" ) )
2313  return QgsProcessingParameterMatrix::fromScriptCode( name, description, isOptional, definition );
2314  else if ( type == QLatin1String( "multiple" ) )
2315  return QgsProcessingParameterMultipleLayers::fromScriptCode( name, description, isOptional, definition );
2316  else if ( type == QLatin1String( "number" ) )
2317  return QgsProcessingParameterNumber::fromScriptCode( name, description, isOptional, definition );
2318  else if ( type == QLatin1String( "distance" ) )
2319  return QgsProcessingParameterDistance::fromScriptCode( name, description, isOptional, definition );
2320  else if ( type == QLatin1String( "duration" ) )
2321  return QgsProcessingParameterDuration::fromScriptCode( name, description, isOptional, definition );
2322  else if ( type == QLatin1String( "scale" ) )
2323  return QgsProcessingParameterScale::fromScriptCode( name, description, isOptional, definition );
2324  else if ( type == QLatin1String( "range" ) )
2325  return QgsProcessingParameterRange::fromScriptCode( name, description, isOptional, definition );
2326  else if ( type == QLatin1String( "raster" ) )
2327  return QgsProcessingParameterRasterLayer::fromScriptCode( name, description, isOptional, definition );
2328  else if ( type == QLatin1String( "enum" ) )
2329  return QgsProcessingParameterEnum::fromScriptCode( name, description, isOptional, definition );
2330  else if ( type == QLatin1String( "string" ) )
2331  return QgsProcessingParameterString::fromScriptCode( name, description, isOptional, definition );
2332  else if ( type == QLatin1String( "authcfg" ) )
2333  return QgsProcessingParameterAuthConfig::fromScriptCode( name, description, isOptional, definition );
2334  else if ( type == QLatin1String( "expression" ) )
2335  return QgsProcessingParameterExpression::fromScriptCode( name, description, isOptional, definition );
2336  else if ( type == QLatin1String( "field" ) )
2337  return QgsProcessingParameterField::fromScriptCode( name, description, isOptional, definition );
2338  else if ( type == QLatin1String( "vector" ) )
2339  return QgsProcessingParameterVectorLayer::fromScriptCode( name, description, isOptional, definition );
2340  else if ( type == QLatin1String( "source" ) )
2341  return QgsProcessingParameterFeatureSource::fromScriptCode( name, description, isOptional, definition );
2342  else if ( type == QLatin1String( "sink" ) )
2343  return QgsProcessingParameterFeatureSink::fromScriptCode( name, description, isOptional, definition );
2344  else if ( type == QLatin1String( "vectordestination" ) )
2345  return QgsProcessingParameterVectorDestination::fromScriptCode( name, description, isOptional, definition );
2346  else if ( type == QLatin1String( "rasterdestination" ) )
2347  return QgsProcessingParameterRasterDestination::fromScriptCode( name, description, isOptional, definition );
2348  else if ( type == QLatin1String( "pointclouddestination" ) )
2349  return QgsProcessingParameterPointCloudDestination::fromScriptCode( name, description, isOptional, definition );
2350  else if ( type == QLatin1String( "filedestination" ) )
2351  return QgsProcessingParameterFileDestination::fromScriptCode( name, description, isOptional, definition );
2352  else if ( type == QLatin1String( "folderdestination" ) )
2353  return QgsProcessingParameterFolderDestination::fromScriptCode( name, description, isOptional, definition );
2354  else if ( type == QLatin1String( "band" ) )
2355  return QgsProcessingParameterBand::fromScriptCode( name, description, isOptional, definition );
2356  else if ( type == QLatin1String( "mesh" ) )
2357  return QgsProcessingParameterMeshLayer::fromScriptCode( name, description, isOptional, definition );
2358  else if ( type == QLatin1String( "layout" ) )
2359  return QgsProcessingParameterLayout::fromScriptCode( name, description, isOptional, definition );
2360  else if ( type == QLatin1String( "layoutitem" ) )
2361  return QgsProcessingParameterLayoutItem::fromScriptCode( name, description, isOptional, definition );
2362  else if ( type == QLatin1String( "color" ) )
2363  return QgsProcessingParameterColor::fromScriptCode( name, description, isOptional, definition );
2364  else if ( type == QLatin1String( "coordinateoperation" ) )
2365  return QgsProcessingParameterCoordinateOperation::fromScriptCode( name, description, isOptional, definition );
2366  else if ( type == QLatin1String( "maptheme" ) )
2367  return QgsProcessingParameterMapTheme::fromScriptCode( name, description, isOptional, definition );
2368  else if ( type == QLatin1String( "datetime" ) )
2369  return QgsProcessingParameterDateTime::fromScriptCode( name, description, isOptional, definition );
2370  else if ( type == QLatin1String( "providerconnection" ) )
2371  return QgsProcessingParameterProviderConnection::fromScriptCode( name, description, isOptional, definition );
2372  else if ( type == QLatin1String( "databaseschema" ) )
2373  return QgsProcessingParameterDatabaseSchema::fromScriptCode( name, description, isOptional, definition );
2374  else if ( type == QLatin1String( "databasetable" ) )
2375  return QgsProcessingParameterDatabaseTable::fromScriptCode( name, description, isOptional, definition );
2376  else if ( type == QLatin1String( "pointcloud" ) )
2377  return QgsProcessingParameterPointCloudLayer::fromScriptCode( name, description, isOptional, definition );
2378  else if ( type == QLatin1String( "annotation" ) )
2379  return QgsProcessingParameterAnnotationLayer::fromScriptCode( name, description, isOptional, definition );
2380 
2381  return nullptr;
2382 }
2383 
2384 bool QgsProcessingParameters::parseScriptCodeParameterOptions( const QString &code, bool &isOptional, QString &name, QString &type, QString &definition )
2385 {
2386  const QRegularExpression re( QStringLiteral( "(?:#*)(.*?)=\\s*(.*)" ) );
2387  QRegularExpressionMatch m = re.match( code );
2388  if ( !m.hasMatch() )
2389  return false;
2390 
2391  name = m.captured( 1 );
2392  QString tokens = m.captured( 2 );
2393  if ( tokens.startsWith( QLatin1String( "optional" ), Qt::CaseInsensitive ) )
2394  {
2395  isOptional = true;
2396  tokens.remove( 0, 8 ); // length "optional" = 8
2397  }
2398  else
2399  {
2400  isOptional = false;
2401  }
2402 
2403  tokens = tokens.trimmed();
2404 
2405  const QRegularExpression re2( QStringLiteral( "(.*?)\\s+(.*)" ) );
2406  m = re2.match( tokens );
2407  if ( !m.hasMatch() )
2408  {
2409  type = tokens.toLower().trimmed();
2410  definition.clear();
2411  }
2412  else
2413  {
2414  type = m.captured( 1 ).toLower().trimmed();
2415  definition = m.captured( 2 );
2416  }
2417  return true;
2418 }
2419 
2420 //
2421 // QgsProcessingParameterDefinition
2422 //
2423 
2424 QgsProcessingParameterDefinition::QgsProcessingParameterDefinition( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, const QString &help )
2425  : mName( name )
2426  , mDescription( description )
2427  , mHelp( help )
2428  , mDefault( defaultValue )
2429  , mFlags( optional ? FlagOptional : 0 )
2430 {}
2431 
2433 {
2434  if ( !input.isValid() && !mDefault.isValid() )
2435  return mFlags & FlagOptional;
2436 
2437  if ( ( input.type() == QVariant::String && input.toString().isEmpty() )
2438  || ( !input.isValid() && mDefault.type() == QVariant::String && mDefault.toString().isEmpty() ) )
2439  return mFlags & FlagOptional;
2440 
2441  return true;
2442 }
2443 
2445 {
2446  if ( !value.isValid() )
2447  return QStringLiteral( "None" );
2448 
2449  if ( value.canConvert<QgsProperty>() )
2450  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
2451 
2452  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
2453 }
2454 
2455 QVariant QgsProcessingParameterDefinition::valueAsJsonObject( const QVariant &value, QgsProcessingContext &context ) const
2456 {
2457  if ( !value.isValid() )
2458  return value;
2459 
2460  // dive into map and list types and convert each value
2461  if ( value.type() == QVariant::Type::Map )
2462  {
2463  const QVariantMap sourceMap = value.toMap();
2464  QVariantMap resultMap;
2465  for ( auto it = sourceMap.constBegin(); it != sourceMap.constEnd(); it++ )
2466  {
2467  resultMap[ it.key() ] = valueAsJsonObject( it.value(), context );
2468  }
2469  return resultMap;
2470  }
2471  else if ( value.type() == QVariant::Type::List || value.type() == QVariant::Type::StringList )
2472  {
2473  const QVariantList sourceList = value.toList();
2474  QVariantList resultList;
2475  resultList.reserve( sourceList.size() );
2476  for ( const QVariant &v : sourceList )
2477  {
2478  resultList.push_back( valueAsJsonObject( v, context ) );
2479  }
2480  return resultList;
2481  }
2482  else
2483  {
2484  switch ( value.userType() )
2485  {
2486  // simple types which can be directly represented in JSON -- note that strings are NOT handled here yet!
2487  case QMetaType::Bool:
2488  case QMetaType::Char:
2489  case QMetaType::Int:
2490  case QMetaType::Double:
2491  case QMetaType::Float:
2492  case QMetaType::LongLong:
2493  case QMetaType::ULongLong:
2494  case QMetaType::UInt:
2495  case QMetaType::ULong:
2496  case QMetaType::UShort:
2497  return value;
2498 
2499  default:
2500  break;
2501  }
2502 
2503 
2504  if ( value.userType() == QMetaType::type( "QgsProperty" ) )
2505  {
2506  const QgsProperty prop = value.value< QgsProperty >();
2507  switch ( prop.propertyType() )
2508  {
2510  return QVariant();
2512  return valueAsJsonObject( prop.staticValue(), context );
2513 
2514  // these are not supported for serialization
2517  QgsDebugMsg( QStringLiteral( "could not convert expression/field based property to JSON object" ) );
2518  return QVariant();
2519  }
2520  }
2521 
2522  // value may be a CRS
2523  if ( value.userType() == QMetaType::type( "QgsCoordinateReferenceSystem" ) )
2524  {
2526  if ( !crs.isValid() )
2527  return QString();
2528  else if ( !crs.authid().isEmpty() )
2529  return crs.authid();
2530  else
2532  }
2533  else if ( value.userType() == QMetaType::type( "QgsRectangle" ) )
2534  {
2535  const QgsRectangle r = value.value<QgsRectangle>();
2536  return QStringLiteral( "%1, %3, %2, %4" ).arg( qgsDoubleToString( r.xMinimum() ),
2537  qgsDoubleToString( r.yMinimum() ),
2538  qgsDoubleToString( r.xMaximum() ),
2539  qgsDoubleToString( r.yMaximum() ) );
2540  }
2541  else if ( value.userType() == QMetaType::type( "QgsReferencedRectangle" ) )
2542  {
2543  const QgsReferencedRectangle r = value.value<QgsReferencedRectangle>();
2544  return QStringLiteral( "%1, %3, %2, %4 [%5]" ).arg( qgsDoubleToString( r.xMinimum() ),
2545  qgsDoubleToString( r.yMinimum() ),
2546  qgsDoubleToString( r.xMaximum() ),
2547  qgsDoubleToString( r.yMaximum() ), r.crs().authid() );
2548  }
2549  else if ( value.userType() == QMetaType::type( "QgsGeometry" ) )
2550  {
2551  const QgsGeometry g = value.value<QgsGeometry>();
2552  if ( !g.isNull() )
2553  {
2554  return g.asWkt();
2555  }
2556  else
2557  {
2558  return QString();
2559  }
2560  }
2561  else if ( value.userType() == QMetaType::type( "QgsReferencedGeometry" ) )
2562  {
2563  const QgsReferencedGeometry g = value.value<QgsReferencedGeometry>();
2564  if ( !g.isNull() )
2565  {
2566  if ( !g.crs().isValid() )
2567  return g.asWkt();
2568  else
2569  return QStringLiteral( "CRS=%1;%2" ).arg( g.crs().authid().isEmpty() ? g.crs().toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ) : g.crs().authid(), g.asWkt() );
2570  }
2571  else
2572  {
2573  return QString();
2574  }
2575  }
2576  else if ( value.userType() == QMetaType::type( "QgsPointXY" ) )
2577  {
2578  const QgsPointXY r = value.value<QgsPointXY>();
2579  return QStringLiteral( "%1,%2" ).arg( qgsDoubleToString( r.x() ),
2580  qgsDoubleToString( r.y() ) );
2581  }
2582  else if ( value.userType() == QMetaType::type( "QgsReferencedPointXY" ) )
2583  {
2584  const QgsReferencedPointXY r = value.value<QgsReferencedPointXY>();
2585  return QStringLiteral( "%1,%2 [%3]" ).arg( qgsDoubleToString( r.x() ),
2586  qgsDoubleToString( r.y() ),
2587  r.crs().authid() );
2588  }
2589  else if ( value.userType() == QMetaType::type( "QgsProcessingFeatureSourceDefinition" ) )
2590  {
2591  const QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( value );
2592 
2593  // TODO -- we could consider also serializating the additional properties like invalid feature handling, limits, etc
2594  return valueAsJsonObject( fromVar.source, context );
2595  }
2596  else if ( value.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
2597  {
2598  const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
2599  return valueAsJsonObject( fromVar.sink, context );
2600  }
2601  else if ( value.userType() == QMetaType::type( "QColor" ) )
2602  {
2603  const QColor fromVar = value.value< QColor >();
2604  if ( !fromVar.isValid() )
2605  return QString();
2606 
2607  return QStringLiteral( "rgba( %1, %2, %3, %4 )" ).arg( fromVar.red() ).arg( fromVar.green() ).arg( fromVar.blue() ).arg( QString::number( fromVar.alphaF(), 'f', 2 ) );
2608  }
2609  else if ( value.userType() == QMetaType::type( "QDateTime" ) )
2610  {
2611  const QDateTime fromVar = value.toDateTime();
2612  if ( !fromVar.isValid() )
2613  return QString();
2614 
2615  return fromVar.toString( Qt::ISODate );
2616  }
2617  else if ( value.userType() == QMetaType::type( "QDate" ) )
2618  {
2619  const QDate fromVar = value.toDate();
2620  if ( !fromVar.isValid() )
2621  return QString();
2622 
2623  return fromVar.toString( Qt::ISODate );
2624  }
2625  else if ( value.userType() == QMetaType::type( "QTime" ) )
2626  {
2627  const QTime fromVar = value.toTime();
2628  if ( !fromVar.isValid() )
2629  return QString();
2630 
2631  return fromVar.toString( Qt::ISODate );
2632  }
2633 
2634  // value may be a map layer
2635  QVariantMap p;
2636  p.insert( name(), value );
2637  if ( QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context ) )
2638  {
2639  const QString source = QgsProcessingUtils::normalizeLayerSource( layer->source() );
2640  if ( !source.isEmpty() )
2641  return source;
2642  return layer->id();
2643  }
2644 
2645  // now we handle strings, after any other specific logic has already been applied
2646  if ( value.userType() == QMetaType::QString )
2647  return value;
2648  }
2649 
2650  // unhandled type
2651  Q_ASSERT_X( false, "QgsProcessingParameterDefinition::valueAsJsonObject", QStringLiteral( "unsupported variant type %1" ).arg( QMetaType::typeName( value.userType() ) ).toLocal8Bit() );
2652  return value;
2653 }
2654 
2655 QString QgsProcessingParameterDefinition::valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok ) const
2656 {
2657  ok = true;
2658 
2659  if ( !value.isValid() )
2660  return QString();
2661 
2662  switch ( value.userType() )
2663  {
2664  // simple types which can be directly represented in JSON -- note that strings are NOT handled here yet!
2665  case QMetaType::Bool:
2666  case QMetaType::Char:
2667  case QMetaType::Int:
2668  case QMetaType::Double:
2669  case QMetaType::Float:
2670  case QMetaType::LongLong:
2671  case QMetaType::ULongLong:
2672  case QMetaType::UInt:
2673  case QMetaType::ULong:
2674  case QMetaType::UShort:
2675  return value.toString();
2676 
2677  default:
2678  break;
2679  }
2680 
2681  if ( value.userType() == QMetaType::type( "QgsProperty" ) )
2682  {
2683  const QgsProperty prop = value.value< QgsProperty >();
2684  switch ( prop.propertyType() )
2685  {
2687  return QString();
2689  return valueAsString( prop.staticValue(), context, ok );
2690 
2691  // these are not supported for serialization
2694  QgsDebugMsg( QStringLiteral( "could not convert expression/field based property to string" ) );
2695  return QString();
2696  }
2697  }
2698 
2699  // value may be a CRS
2700  if ( value.userType() == QMetaType::type( "QgsCoordinateReferenceSystem" ) )
2701  {
2703  if ( !crs.isValid() )
2704  return QString();
2705  else if ( !crs.authid().isEmpty() )
2706  return crs.authid();
2707  else
2709  }
2710  else if ( value.userType() == QMetaType::type( "QgsRectangle" ) )
2711  {
2712  const QgsRectangle r = value.value<QgsRectangle>();
2713  return QStringLiteral( "%1, %3, %2, %4" ).arg( qgsDoubleToString( r.xMinimum() ),
2714  qgsDoubleToString( r.yMinimum() ),
2715  qgsDoubleToString( r.xMaximum() ),
2716  qgsDoubleToString( r.yMaximum() ) );
2717  }
2718  else if ( value.userType() == QMetaType::type( "QgsReferencedRectangle" ) )
2719  {
2720  const QgsReferencedRectangle r = value.value<QgsReferencedRectangle>();
2721  return QStringLiteral( "%1, %3, %2, %4 [%5]" ).arg( qgsDoubleToString( r.xMinimum() ),
2722  qgsDoubleToString( r.yMinimum() ),
2723  qgsDoubleToString( r.xMaximum() ),
2724  qgsDoubleToString( r.yMaximum() ), r.crs().authid() );
2725  }
2726  else if ( value.userType() == QMetaType::type( "QgsGeometry" ) )
2727  {
2728  const QgsGeometry g = value.value<QgsGeometry>();
2729  if ( !g.isNull() )
2730  {
2731  return g.asWkt();
2732  }
2733  else
2734  {
2735  return QString();
2736  }
2737  }
2738  else if ( value.userType() == QMetaType::type( "QgsReferencedGeometry" ) )
2739  {
2740  const QgsReferencedGeometry g = value.value<QgsReferencedGeometry>();
2741  if ( !g.isNull() )
2742  {
2743  if ( !g.crs().isValid() )
2744  return g.asWkt();
2745  else
2746  return QStringLiteral( "CRS=%1;%2" ).arg( g.crs().authid().isEmpty() ? g.crs().toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ) : g.crs().authid(), g.asWkt() );
2747  }
2748  else
2749  {
2750  return QString();
2751  }
2752  }
2753  else if ( value.userType() == QMetaType::type( "QgsPointXY" ) )
2754  {
2755  const QgsPointXY r = value.value<QgsPointXY>();
2756  return QStringLiteral( "%1,%2" ).arg( qgsDoubleToString( r.x() ),
2757  qgsDoubleToString( r.y() ) );
2758  }
2759  else if ( value.userType() == QMetaType::type( "QgsReferencedPointXY" ) )
2760  {
2761  const QgsReferencedPointXY r = value.value<QgsReferencedPointXY>();
2762  return QStringLiteral( "%1,%2 [%3]" ).arg( qgsDoubleToString( r.x() ),
2763  qgsDoubleToString( r.y() ),
2764  r.crs().authid() );
2765  }
2766  else if ( value.userType() == QMetaType::type( "QgsProcessingFeatureSourceDefinition" ) )
2767  {
2768  const QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( value );
2769  return valueAsString( fromVar.source, context, ok );
2770  }
2771  else if ( value.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
2772  {
2773  const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
2774  return valueAsString( fromVar.sink, context, ok );
2775  }
2776  else if ( value.userType() == QMetaType::type( "QColor" ) )
2777  {
2778  const QColor fromVar = value.value< QColor >();
2779  if ( !fromVar.isValid() )
2780  return QString();
2781 
2782  return QStringLiteral( "rgba( %1, %2, %3, %4 )" ).arg( fromVar.red() ).arg( fromVar.green() ).arg( fromVar.blue() ).arg( QString::number( fromVar.alphaF(), 'f', 2 ) );
2783  }
2784  else if ( value.userType() == QMetaType::type( "QDateTime" ) )
2785  {
2786  const QDateTime fromVar = value.toDateTime();
2787  if ( !fromVar.isValid() )
2788  return QString();
2789 
2790  return fromVar.toString( Qt::ISODate );
2791  }
2792  else if ( value.userType() == QMetaType::type( "QDate" ) )
2793  {
2794  const QDate fromVar = value.toDate();
2795  if ( !fromVar.isValid() )
2796  return QString();
2797 
2798  return fromVar.toString( Qt::ISODate );
2799  }
2800  else if ( value.userType() == QMetaType::type( "QTime" ) )
2801  {
2802  const QTime fromVar = value.toTime();
2803  if ( !fromVar.isValid() )
2804  return QString();
2805 
2806  return fromVar.toString( Qt::ISODate );
2807  }
2808 
2809  // value may be a map layer
2810  QVariantMap p;
2811  p.insert( name(), value );
2812  if ( QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context ) )
2813  {
2814  const QString source = QgsProcessingUtils::normalizeLayerSource( layer->source() );
2815  if ( !source.isEmpty() )
2816  return source;
2817  return layer->id();
2818  }
2819 
2820  // now we handle strings, after any other specific logic has already been applied
2821  if ( value.userType() == QMetaType::QString )
2822  return value.toString();
2823 
2824  // unhandled type
2825  QgsDebugMsg( QStringLiteral( "unsupported variant type %1" ).arg( QMetaType::typeName( value.userType() ) ) );
2826  ok = false;
2827  return value.toString();
2828 }
2829 
2830 QStringList QgsProcessingParameterDefinition::valueAsStringList( const QVariant &value, QgsProcessingContext &context, bool &ok ) const
2831 {
2832  ok = true;
2833  if ( !value.isValid( ) )
2834  return QStringList();
2835 
2836  if ( value.type() == QVariant::Type::List || value.type() == QVariant::Type::StringList )
2837  {
2838  const QVariantList sourceList = value.toList();
2839  QStringList resultList;
2840  resultList.reserve( sourceList.size() );
2841  for ( const QVariant &v : sourceList )
2842  {
2843  resultList.append( valueAsStringList( v, context, ok ) );
2844  }
2845  return resultList;
2846  }
2847 
2848  const QString res = valueAsString( value, context, ok );
2849  if ( !ok )
2850  return QStringList();
2851 
2852  return {res};
2853 }
2854 
2856 {
2857  return QString();
2858 }
2859 
2861 {
2862  QString code = QStringLiteral( "##%1=" ).arg( mName );
2863  if ( mFlags & FlagOptional )
2864  code += QLatin1String( "optional " );
2865  code += type() + ' ';
2866  code += mDefault.toString();
2867  return code.trimmed();
2868 }
2869 
2871 {
2872  // base class method is probably not much use
2873  if ( QgsProcessingParameterType *t = QgsApplication::processingRegistry()->parameterType( type() ) )
2874  {
2875  switch ( outputType )
2876  {
2878  {
2879  QString code = t->className() + QStringLiteral( "('%1', %2" )
2881  if ( mFlags & FlagOptional )
2882  code += QLatin1String( ", optional=True" );
2883 
2885  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
2886  return code;
2887  }
2888  }
2889  }
2890 
2891  // oh well, we tried
2892  return QString();
2893 }
2894 
2896 {
2897  QVariantMap map;
2898  map.insert( QStringLiteral( "parameter_type" ), type() );
2899  map.insert( QStringLiteral( "name" ), mName );
2900  map.insert( QStringLiteral( "description" ), mDescription );
2901  map.insert( QStringLiteral( "help" ), mHelp );
2902  map.insert( QStringLiteral( "default" ), mDefault );
2903  map.insert( QStringLiteral( "defaultGui" ), mGuiDefault );
2904  map.insert( QStringLiteral( "flags" ), static_cast< int >( mFlags ) );
2905  map.insert( QStringLiteral( "metadata" ), mMetadata );
2906  return map;
2907 }
2908 
2910 {
2911  mName = map.value( QStringLiteral( "name" ) ).toString();
2912  mDescription = map.value( QStringLiteral( "description" ) ).toString();
2913  mHelp = map.value( QStringLiteral( "help" ) ).toString();
2914  mDefault = map.value( QStringLiteral( "default" ) );
2915  mGuiDefault = map.value( QStringLiteral( "defaultGui" ) );
2916  mFlags = static_cast< Flags >( map.value( QStringLiteral( "flags" ) ).toInt() );
2917  mMetadata = map.value( QStringLiteral( "metadata" ) ).toMap();
2918  return true;
2919 }
2920 
2922 {
2923  return mAlgorithm;
2924 }
2925 
2927 {
2928  return mAlgorithm ? mAlgorithm->provider() : nullptr;
2929 }
2930 
2932 {
2933  QString text = QStringLiteral( "<p><b>%1</b></p>" ).arg( description() );
2934  if ( !help().isEmpty() )
2935  {
2936  text += QStringLiteral( "<p>%1</p>" ).arg( help() );
2937  }
2938  text += QStringLiteral( "<p>%1</p>" ).arg( QObject::tr( "Python identifier: ‘%1’" ).arg( QStringLiteral( "<i>%1</i>" ).arg( name() ) ) );
2939  return text;
2940 }
2941 
2942 QgsProcessingParameterBoolean::QgsProcessingParameterBoolean( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
2943  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2944 {}
2945 
2947 {
2948  return new QgsProcessingParameterBoolean( *this );
2949 }
2950 
2952 {
2953  if ( !val.isValid() )
2954  return QStringLiteral( "None" );
2955 
2956  if ( val.canConvert<QgsProperty>() )
2957  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
2958  return val.toBool() ? QStringLiteral( "True" ) : QStringLiteral( "False" );
2959 }
2960 
2962 {
2963  QString code = QStringLiteral( "##%1=" ).arg( mName );
2964  if ( mFlags & FlagOptional )
2965  code += QLatin1String( "optional " );
2966  code += type() + ' ';
2967  code += mDefault.toBool() ? QStringLiteral( "true" ) : QStringLiteral( "false" );
2968  return code.trimmed();
2969 }
2970 
2971 QgsProcessingParameterBoolean *QgsProcessingParameterBoolean::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
2972 {
2973  return new QgsProcessingParameterBoolean( name, description, definition.toLower().trimmed() != QStringLiteral( "false" ), isOptional );
2974 }
2975 
2976 QgsProcessingParameterCrs::QgsProcessingParameterCrs( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
2977  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2978 {
2979 
2980 }
2981 
2983 {
2984  return new QgsProcessingParameterCrs( *this );
2985 }
2986 
2988 {
2989  if ( !input.isValid() )
2990  return mFlags & FlagOptional;
2991 
2992  if ( input.canConvert<QgsCoordinateReferenceSystem>() )
2993  {
2994  return true;
2995  }
2996  else if ( input.canConvert<QgsProcessingFeatureSourceDefinition>() )
2997  {
2998  return true;
2999  }
3000  else if ( input.canConvert<QgsProcessingOutputLayerDefinition>() )
3001  {
3002  return true;
3003  }
3004 
3005  if ( input.canConvert<QgsProperty>() )
3006  {
3007  return true;
3008  }
3009 
3010  // direct map layer value
3011  if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
3012  return true;
3013 
3014  if ( input.type() != QVariant::String || input.toString().isEmpty() )
3015  return mFlags & FlagOptional;
3016 
3017  return true;
3018 }
3019 
3020 QString QgsProcessingParameterCrs::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
3021 {
3022  if ( !value.isValid() )
3023  return QStringLiteral( "None" );
3024 
3025  if ( value.canConvert<QgsCoordinateReferenceSystem>() )
3026  {
3027  if ( !value.value< QgsCoordinateReferenceSystem >().isValid() )
3028  return QStringLiteral( "QgsCoordinateReferenceSystem()" );
3029  else
3030  return QStringLiteral( "QgsCoordinateReferenceSystem('%1')" ).arg( value.value< QgsCoordinateReferenceSystem >().authid() );
3031  }
3032 
3033  if ( value.canConvert<QgsProperty>() )
3034  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
3035 
3036  QVariantMap p;
3037  p.insert( name(), value );
3038  QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
3039  if ( layer )
3041 
3043 }
3044 
3045 QgsProcessingParameterCrs *QgsProcessingParameterCrs::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3046 {
3047  return new QgsProcessingParameterCrs( name, description, definition.compare( QLatin1String( "none" ), Qt::CaseInsensitive ) == 0 ? QVariant() : definition, isOptional );
3048 }
3049 
3050 QgsProcessingParameterMapLayer::QgsProcessingParameterMapLayer( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, const QList<int> &types )
3051  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3053 {
3054 
3055 }
3056 
3058 {
3059  return new QgsProcessingParameterMapLayer( *this );
3060 }
3061 
3063 {
3064  if ( !input.isValid() )
3065  return mFlags & FlagOptional;
3066 
3067  if ( input.canConvert<QgsProperty>() )
3068  {
3069  return true;
3070  }
3071 
3072  if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
3073  {
3074  return true;
3075  }
3076 
3077  if ( input.type() != QVariant::String || input.toString().isEmpty() )
3078  return mFlags & FlagOptional;
3079 
3080  if ( !context )
3081  {
3082  // that's as far as we can get without a context
3083  return true;
3084  }
3085 
3086  // try to load as layer
3087  if ( QgsProcessingUtils::mapLayerFromString( input.toString(), *context ) )
3088  return true;
3089 
3090  return false;
3091 }
3092 
3094 {
3095  if ( !val.isValid() )
3096  return QStringLiteral( "None" );
3097 
3098  if ( val.canConvert<QgsProperty>() )
3099  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
3100 
3101  QVariantMap p;
3102  p.insert( name(), val );
3103  QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
3105  : QgsProcessingUtils::stringToPythonLiteral( val.toString() );
3106 }
3107 
3109 {
3110  QStringList vectors = QgsProviderRegistry::instance()->fileVectorFilters().split( QStringLiteral( ";;" ) );
3111  const QStringList rasters = QgsProviderRegistry::instance()->fileRasterFilters().split( QStringLiteral( ";;" ) );
3112  for ( const QString &raster : rasters )
3113  {
3114  if ( !vectors.contains( raster ) )
3115  vectors << raster;
3116  }
3117  const QStringList meshFilters = QgsProviderRegistry::instance()->fileMeshFilters().split( QStringLiteral( ";;" ) );
3118  for ( const QString &mesh : meshFilters )
3119  {
3120  if ( !vectors.contains( mesh ) )
3121  vectors << mesh;
3122  }
3123  const QStringList pointCloudFilters = QgsProviderRegistry::instance()->filePointCloudFilters().split( QStringLiteral( ";;" ) );
3124  for ( const QString &pointCloud : pointCloudFilters )
3125  {
3126  if ( !vectors.contains( pointCloud ) )
3127  vectors << pointCloud;
3128  }
3129  vectors.removeAll( QObject::tr( "All files (*.*)" ) );
3130  std::sort( vectors.begin(), vectors.end() );
3131 
3132  return QObject::tr( "All files (*.*)" ) + QStringLiteral( ";;" ) + vectors.join( QLatin1String( ";;" ) );
3133 }
3134 
3136 {
3137  return createAllMapLayerFileFilter();
3138 }
3139 
3141 {
3142  QString code = QStringLiteral( "##%1=" ).arg( mName );
3143  if ( mFlags & FlagOptional )
3144  code += QLatin1String( "optional " );
3145  code += QLatin1String( "layer " );
3146 
3147  for ( const int type : mDataTypes )
3148  {
3149  switch ( type )
3150  {
3152  code += QLatin1String( "hasgeometry " );
3153  break;
3154 
3156  code += QLatin1String( "point " );
3157  break;
3158 
3160  code += QLatin1String( "line " );
3161  break;
3162 
3164  code += QLatin1String( "polygon " );
3165  break;
3166 
3168  code += QLatin1String( "raster " );
3169  break;
3170 
3172  code += QLatin1String( "mesh " );
3173  break;
3174 
3176  code += QLatin1String( "plugin " );
3177  break;
3178 
3180  code += QLatin1String( "pointcloud " );
3181  break;
3182 
3184  code += QLatin1String( "annotation " );
3185  break;
3186  }
3187  }
3188 
3189  code += mDefault.toString();
3190  return code.trimmed();
3191 }
3192 
3193 QgsProcessingParameterMapLayer *QgsProcessingParameterMapLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3194 {
3195  QList< int > types;
3196  QString def = definition;
3197  while ( true )
3198  {
3199  if ( def.startsWith( QLatin1String( "hasgeometry" ), Qt::CaseInsensitive ) )
3200  {
3202  def = def.mid( 12 );
3203  continue;
3204  }
3205  else if ( def.startsWith( QLatin1String( "point" ), Qt::CaseInsensitive ) )
3206  {
3208  def = def.mid( 6 );
3209  continue;
3210  }
3211  else if ( def.startsWith( QLatin1String( "line" ), Qt::CaseInsensitive ) )
3212  {
3214  def = def.mid( 5 );
3215  continue;
3216  }
3217  else if ( def.startsWith( QLatin1String( "polygon" ), Qt::CaseInsensitive ) )
3218  {
3220  def = def.mid( 8 );
3221  continue;
3222  }
3223  else if ( def.startsWith( QLatin1String( "raster" ), Qt::CaseInsensitive ) )
3224  {
3225  types << QgsProcessing::TypeRaster;
3226  def = def.mid( 7 );
3227  continue;
3228  }
3229  else if ( def.startsWith( QLatin1String( "mesh" ), Qt::CaseInsensitive ) )
3230  {
3231  types << QgsProcessing::TypeMesh;
3232  def = def.mid( 5 );
3233  continue;
3234  }
3235  else if ( def.startsWith( QLatin1String( "plugin" ), Qt::CaseInsensitive ) )
3236  {
3237  types << QgsProcessing::TypePlugin;
3238  def = def.mid( 7 );
3239  continue;
3240  }
3241  else if ( def.startsWith( QLatin1String( "pointcloud" ), Qt::CaseInsensitive ) )
3242  {
3244  def = def.mid( 11 );
3245  continue;
3246  }
3247  else if ( def.startsWith( QLatin1String( "annotation" ), Qt::CaseInsensitive ) )
3248  {
3250  def = def.mid( 11 );
3251  continue;
3252  }
3253  break;
3254  }
3255 
3256  return new QgsProcessingParameterMapLayer( name, description, def, isOptional, types );
3257 }
3258 
3260 {
3261  switch ( outputType )
3262  {
3264  {
3265  QString code = QStringLiteral( "QgsProcessingParameterMapLayer('%1', %2" )
3267  if ( mFlags & FlagOptional )
3268  code += QLatin1String( ", optional=True" );
3269 
3271  code += QStringLiteral( ", defaultValue=%1" ).arg( valueAsPythonString( mDefault, c ) );
3272 
3273  if ( !mDataTypes.empty() )
3274  {
3275  QStringList options;
3276  options.reserve( mDataTypes.size() );
3277  for ( const int t : mDataTypes )
3278  options << QStringLiteral( "QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( static_cast< QgsProcessing::SourceType >( t ) ) );
3279  code += QStringLiteral( ", types=[%1])" ).arg( options.join( ',' ) );
3280  }
3281  else
3282  {
3283  code += QLatin1Char( ')' );
3284  }
3285 
3286  return code;
3287  }
3288  }
3289  return QString();
3290 }
3291 
3293 {
3295  QVariantList types;
3296  for ( const int type : mDataTypes )
3297  {
3298  types << type;
3299  }
3300  map.insert( QStringLiteral( "data_types" ), types );
3301  return map;
3302 }
3303 
3305 {
3307  mDataTypes.clear();
3308  const QVariantList values = map.value( QStringLiteral( "data_types" ) ).toList();
3309  for ( const QVariant &val : values )
3310  {
3311  mDataTypes << val.toInt();
3312  }
3313  return true;
3314 }
3315 
3316 QgsProcessingParameterExtent::QgsProcessingParameterExtent( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
3317  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3318 {
3319 
3320 }
3321 
3323 {
3324  return new QgsProcessingParameterExtent( *this );
3325 }
3326 
3328 {
3329  if ( !input.isValid() )
3330  return mFlags & FlagOptional;
3331 
3332  if ( input.canConvert<QgsProcessingFeatureSourceDefinition>() )
3333  {
3334  return true;
3335  }
3336  else if ( input.canConvert<QgsProcessingOutputLayerDefinition>() )
3337  {
3338  return true;
3339  }
3340 
3341  if ( input.canConvert<QgsProperty>() )
3342  {
3343  return true;
3344  }
3345 
3346  if ( input.canConvert< QgsRectangle >() )
3347  {
3348  const QgsRectangle r = input.value<QgsRectangle>();
3349  return !r.isNull();
3350  }
3351  if ( input.canConvert< QgsGeometry >() )
3352  {
3353  return true;
3354  }
3355  if ( input.canConvert< QgsReferencedRectangle >() )
3356  {
3357  const QgsReferencedRectangle r = input.value<QgsReferencedRectangle>();
3358  return !r.isNull();
3359  }
3360 
3361  // direct map layer value
3362  if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
3363  return true;
3364 
3365  if ( input.type() != QVariant::String || input.toString().isEmpty() )
3366  return mFlags & FlagOptional;
3367 
3368  if ( !context )
3369  {
3370  // that's as far as we can get without a context
3371  return true;
3372  }
3373 
3374  const QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?)\\s*,\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
3375  const QRegularExpressionMatch match = rx.match( input.toString() );
3376  if ( match.hasMatch() )
3377  {
3378  bool xMinOk = false;
3379  ( void )match.captured( 1 ).toDouble( &xMinOk );
3380  bool xMaxOk = false;
3381  ( void )match.captured( 2 ).toDouble( &xMaxOk );
3382  bool yMinOk = false;
3383  ( void )match.captured( 3 ).toDouble( &yMinOk );
3384  bool yMaxOk = false;
3385  ( void )match.captured( 4 ).toDouble( &yMaxOk );
3386  if ( xMinOk && xMaxOk && yMinOk && yMaxOk )
3387  return true;
3388  }
3389 
3390  // try as layer extent
3391  return QgsProcessingUtils::mapLayerFromString( input.toString(), *context );
3392 }
3393 
3394 QString QgsProcessingParameterExtent::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
3395 {
3396  if ( !value.isValid() )
3397  return QStringLiteral( "None" );
3398 
3399  if ( value.canConvert<QgsProperty>() )
3400  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
3401 
3402  if ( value.canConvert< QgsRectangle >() )
3403  {
3404  const QgsRectangle r = value.value<QgsRectangle>();
3405  return QStringLiteral( "'%1, %3, %2, %4'" ).arg( qgsDoubleToString( r.xMinimum() ),
3406  qgsDoubleToString( r.yMinimum() ),
3407  qgsDoubleToString( r.xMaximum() ),
3408  qgsDoubleToString( r.yMaximum() ) );
3409  }
3410  else if ( value.canConvert< QgsReferencedRectangle >() )
3411  {
3412  const QgsReferencedRectangle r = value.value<QgsReferencedRectangle>();
3413  return QStringLiteral( "'%1, %3, %2, %4 [%5]'" ).arg( qgsDoubleToString( r.xMinimum() ),
3414  qgsDoubleToString( r.yMinimum() ),
3415  qgsDoubleToString( r.xMaximum() ),
3416  qgsDoubleToString( r.yMaximum() ), r.crs().authid() );
3417  }
3418  else if ( value.canConvert< QgsGeometry >() )
3419  {
3420  const QgsGeometry g = value.value<QgsGeometry>();
3421  if ( !g.isNull() )
3422  {
3423  const QString wkt = g.asWkt();
3424  return QStringLiteral( "QgsGeometry.fromWkt('%1')" ).arg( wkt );
3425  }
3426  }
3427 
3428  QVariantMap p;
3429  p.insert( name(), value );
3430  QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
3431  if ( layer )
3433 
3435 }
3436 
3437 QgsProcessingParameterExtent *QgsProcessingParameterExtent::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3438 {
3439  return new QgsProcessingParameterExtent( name, description, definition, isOptional );
3440 }
3441 
3442 QgsProcessingParameterPoint::QgsProcessingParameterPoint( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
3443  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3444 {
3445 
3446 }
3447 
3449 {
3450  return new QgsProcessingParameterPoint( *this );
3451 }
3452 
3454 {
3455  if ( !input.isValid() )
3456  return mFlags & FlagOptional;
3457 
3458  if ( input.canConvert<QgsProperty>() )
3459  {
3460  return true;
3461  }
3462 
3463  if ( input.canConvert< QgsPointXY >() )
3464  {
3465  return true;
3466  }
3467  if ( input.canConvert< QgsReferencedPointXY >() )
3468  {
3469  return true;
3470  }
3471  if ( input.canConvert< QgsGeometry >() )
3472  {
3473  return true;
3474  }
3475 
3476  if ( input.type() == QVariant::String )
3477  {
3478  if ( input.toString().isEmpty() )
3479  return mFlags & FlagOptional;
3480  }
3481 
3482  const QRegularExpression rx( QStringLiteral( "^\\s*\\(?\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*\\)?\\s*$" ) );
3483 
3484  const QRegularExpressionMatch match = rx.match( input.toString() );
3485  if ( match.hasMatch() )
3486  {
3487  bool xOk = false;
3488  ( void )match.captured( 1 ).toDouble( &xOk );
3489  bool yOk = false;
3490  ( void )match.captured( 2 ).toDouble( &yOk );
3491  return xOk && yOk;
3492  }
3493  else
3494  return false;
3495 }
3496 
3497 QString QgsProcessingParameterPoint::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
3498 {
3499  if ( !value.isValid() )
3500  return QStringLiteral( "None" );
3501 
3502  if ( value.canConvert<QgsProperty>() )
3503  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
3504 
3505  if ( value.canConvert< QgsPointXY >() )
3506  {
3507  const QgsPointXY r = value.value<QgsPointXY>();
3508  return QStringLiteral( "'%1,%2'" ).arg( qgsDoubleToString( r.x() ),
3509  qgsDoubleToString( r.y() ) );
3510  }
3511  else if ( value.canConvert< QgsReferencedPointXY >() )
3512  {
3513  const QgsReferencedPointXY r = value.value<QgsReferencedPointXY>();
3514  return QStringLiteral( "'%1,%2 [%3]'" ).arg( qgsDoubleToString( r.x() ),
3515  qgsDoubleToString( r.y() ),
3516  r.crs().authid() );
3517  }
3518  else if ( value.canConvert< QgsGeometry >() )
3519  {
3520  const QgsGeometry g = value.value<QgsGeometry>();
3521  if ( !g.isNull() )
3522  {
3523  const QString wkt = g.asWkt();
3524  return QStringLiteral( "QgsGeometry.fromWkt('%1')" ).arg( wkt );
3525  }
3526  }
3527 
3529 }
3530 
3531 QgsProcessingParameterPoint *QgsProcessingParameterPoint::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3532 {
3533  return new QgsProcessingParameterPoint( name, description, definition, isOptional );
3534 }
3535 
3536 QgsProcessingParameterGeometry::QgsProcessingParameterGeometry( const QString &name, const QString &description,
3537  const QVariant &defaultValue, bool optional, const QList<int> &geometryTypes, bool allowMultipart )
3538  : QgsProcessingParameterDefinition( name, description, defaultValue, optional ),
3539  mGeomTypes( geometryTypes ),
3540  mAllowMultipart( allowMultipart )
3541 {
3542 
3543 }
3544 
3546 {
3547  return new QgsProcessingParameterGeometry( *this );
3548 }
3549 
3551 {
3552  if ( !input.isValid() )
3553  return mFlags & FlagOptional;
3554 
3555  if ( input.canConvert<QgsProperty>() )
3556  {
3557  return true;
3558  }
3559 
3560  const bool anyTypeAllowed = mGeomTypes.isEmpty() || mGeomTypes.contains( QgsWkbTypes::UnknownGeometry );
3561 
3562  if ( input.canConvert< QgsGeometry >() )
3563  {
3564  return ( anyTypeAllowed || mGeomTypes.contains( input.value<QgsGeometry>().type() ) ) &&
3565  ( mAllowMultipart || !input.value<QgsGeometry>().isMultipart() );
3566  }
3567 
3568  if ( input.canConvert< QgsReferencedGeometry >() )
3569  {
3570  return ( anyTypeAllowed || mGeomTypes.contains( input.value<QgsReferencedGeometry>().type() ) ) &&
3571  ( mAllowMultipart || !input.value<QgsReferencedGeometry>().isMultipart() );
3572  }
3573 
3574  if ( input.canConvert< QgsPointXY >() )
3575  {
3576  return anyTypeAllowed || mGeomTypes.contains( QgsWkbTypes::PointGeometry );
3577  }
3578 
3579  if ( input.canConvert< QgsRectangle >() )
3580  {
3581  return anyTypeAllowed || mGeomTypes.contains( QgsWkbTypes::PolygonGeometry );
3582  }
3583 
3584  if ( input.canConvert< QgsReferencedPointXY >() )
3585  {
3586  return anyTypeAllowed || mGeomTypes.contains( QgsWkbTypes::PointGeometry );
3587  }
3588 
3589  if ( input.canConvert< QgsReferencedRectangle >() )
3590  {
3591  return anyTypeAllowed || mGeomTypes.contains( QgsWkbTypes::PolygonGeometry );
3592  }
3593 
3594  if ( input.type() == QVariant::String )
3595  {
3596  if ( input.toString().isEmpty() )
3597  return mFlags & FlagOptional;
3598  }
3599 
3600  // Match against EWKT
3601  const QRegularExpression rx( QStringLiteral( "^\\s*(?:CRS=(.*);)?(.*?)$" ) );
3602 
3603  const QRegularExpressionMatch match = rx.match( input.toString() );
3604  if ( match.hasMatch() )
3605  {
3606  const QgsGeometry g = QgsGeometry::fromWkt( match.captured( 2 ) );
3607  if ( ! g.isNull() )
3608  {
3609  return ( anyTypeAllowed || mGeomTypes.contains( g.type() ) ) && ( mAllowMultipart || !g.isMultipart() );
3610  }
3611  else
3612  {
3613  QgsMessageLog::logMessage( QObject::tr( "Error creating geometry: \"%1\"" ).arg( g.lastError() ), QObject::tr( "Processing" ) );
3614  }
3615  }
3616  return false;
3617 }
3618 
3619 QString QgsProcessingParameterGeometry::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
3620 {
3622  {
3623  if ( !crs.isValid() )
3625  else
3626  return QgsProcessingUtils::stringToPythonLiteral( QStringLiteral( "CRS=%1;%2" ).arg( crs.authid().isEmpty() ? crs.toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ) : crs.authid(), g.asWkt() ) );
3627  };
3628 
3629  if ( !value.isValid() )
3630  return QStringLiteral( "None" );
3631 
3632  if ( value.canConvert<QgsProperty>() )
3633  return QStringLiteral( "QgsProperty.fromExpression(%1)" ).arg( QgsProcessingUtils::stringToPythonLiteral( value.value< QgsProperty >().asExpression() ) );
3634 
3635  if ( value.canConvert< QgsGeometry >() )
3636  {
3637  const QgsGeometry g = value.value<QgsGeometry>();
3638  if ( !g.isNull() )
3639  return asPythonString( g );
3640  }
3641 
3642  if ( value.canConvert< QgsReferencedGeometry >() )
3643  {
3644  const QgsReferencedGeometry g = value.value<QgsReferencedGeometry>();
3645  if ( !g.isNull() )
3646  return asPythonString( g, g.crs() );
3647  }
3648 
3649  if ( value.canConvert< QgsPointXY >() )
3650  {
3651  const QgsGeometry g = QgsGeometry::fromPointXY( value.value<QgsPointXY>() );
3652  if ( !g.isNull() )
3653  return asPythonString( g );
3654  }
3655 
3656  if ( value.canConvert< QgsReferencedPointXY >() )
3657  {
3659  if ( !g.isNull() )
3660  return asPythonString( g, g.crs() );
3661  }
3662 
3663  if ( value.canConvert< QgsRectangle >() )
3664  {
3665  const QgsGeometry g = QgsGeometry::fromRect( value.value<QgsRectangle>() );
3666  if ( !g.isNull() )
3667  return asPythonString( g );
3668  }
3669 
3670  if ( value.canConvert< QgsReferencedRectangle >() )
3671  {
3673  if ( !g.isNull() )
3674  return asPythonString( g, g.crs() );
3675  }
3676 
3678 }
3679 
3681 {
3682  QString code = QStringLiteral( "##%1=" ).arg( mName );
3683  if ( mFlags & FlagOptional )
3684  code += QLatin1String( "optional " );
3685  code += type() + ' ';
3686 
3687  for ( const int type : mGeomTypes )
3688  {
3689  switch ( static_cast<QgsWkbTypes::GeometryType>( type ) )
3690  {
3692  code += QLatin1String( "point " );
3693  break;
3694 
3696  code += QLatin1String( "line " );
3697  break;
3698 
3700  code += QLatin1String( "polygon " );
3701  break;
3702 
3703  default:
3704  code += QLatin1String( "unknown " );
3705  break;
3706  }
3707  }
3708 
3709  code += mDefault.toString();
3710  return code.trimmed();
3711 }
3712 
3714 {
3715  switch ( outputType )
3716  {
3718  {
3719  QString code = QStringLiteral( "QgsProcessingParameterGeometry('%1', %2" )
3721  if ( mFlags & FlagOptional )
3722  code += QLatin1String( ", optional=True" );
3723 
3724  if ( !mGeomTypes.empty() )
3725  {
3726  auto geomTypeToString = []( QgsWkbTypes::GeometryType t ) -> QString
3727  {
3728  switch ( t )
3729  {
3731  return QStringLiteral( "PointGeometry" );
3732 
3734  return QStringLiteral( "LineGeometry" );
3735 
3737  return QStringLiteral( "PolygonGeometry" );
3738 
3740  return QStringLiteral( "UnknownGeometry" );
3741 
3743  return QStringLiteral( "NullGeometry" );
3744  }
3745  return QString();
3746  };
3747 
3748  QStringList options;
3749  options.reserve( mGeomTypes.size() );
3750  for ( const int type : mGeomTypes )
3751  {
3752  options << QStringLiteral( " QgsWkbTypes.%1" ).arg( geomTypeToString( static_cast<QgsWkbTypes::GeometryType>( type ) ) );
3753  }
3754  code += QStringLiteral( ", geometryTypes=[%1 ]" ).arg( options.join( ',' ) );
3755  }
3756 
3757  if ( ! mAllowMultipart )
3758  {
3759  code += QLatin1String( ", allowMultipart=False" );
3760  }
3761 
3763  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
3764  return code;
3765  }
3766  }
3767  return QString();
3768 }
3769 
3771 {
3773  QVariantList types;
3774  for ( const int type : mGeomTypes )
3775  {
3776  types << type;
3777  }
3778  map.insert( QStringLiteral( "geometrytypes" ), types );
3779  map.insert( QStringLiteral( "multipart" ), mAllowMultipart );
3780  return map;
3781 }
3782 
3784 {
3786  mGeomTypes.clear();
3787  const QVariantList values = map.value( QStringLiteral( "geometrytypes" ) ).toList();
3788  for ( const QVariant &val : values )
3789  {
3790  mGeomTypes << val.toInt();
3791  }
3792  mAllowMultipart = map.value( QStringLiteral( "multipart" ) ).toBool();
3793  return true;
3794 }
3795 
3796 QgsProcessingParameterGeometry *QgsProcessingParameterGeometry::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3797 {
3798  return new QgsProcessingParameterGeometry( name, description, definition, isOptional );
3799 }
3800 
3801 QgsProcessingParameterFile::QgsProcessingParameterFile( const QString &name, const QString &description, Behavior behavior, const QString &extension, const QVariant &defaultValue, bool optional, const QString &fileFilter )
3802  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3803  , mBehavior( behavior )
3804  , mExtension( fileFilter.isEmpty() ? extension : QString() )
3805  , mFileFilter( fileFilter.isEmpty() && extension.isEmpty() ? QObject::tr( "All files (*.*)" ) : fileFilter )
3806 {
3807 
3808 }
3809 
3811 {
3812  return new QgsProcessingParameterFile( *this );
3813 }
3814 
3816 {
3817  if ( !input.isValid() )
3818  return mFlags & FlagOptional;
3819 
3820  if ( input.canConvert<QgsProperty>() )
3821  {
3822  return true;
3823  }
3824 
3825  const QString string = input.toString().trimmed();
3826 
3827  if ( input.type() != QVariant::String || string.isEmpty() )
3828  return mFlags & FlagOptional;
3829 
3830  switch ( mBehavior )
3831  {
3832  case File:
3833  {
3834  if ( !mExtension.isEmpty() )
3835  {
3836  return string.endsWith( mExtension, Qt::CaseInsensitive );
3837  }
3838  else if ( !mFileFilter.isEmpty() )
3839  {
3840  return QgsFileUtils::fileMatchesFilter( string, mFileFilter );
3841  }
3842  else
3843  {
3844  return true;
3845  }
3846  }
3847 
3848  case Folder:
3849  return true;
3850  }
3851  return true;
3852 }
3853 
3855 {
3856  QString code = QStringLiteral( "##%1=" ).arg( mName );
3857  if ( mFlags & FlagOptional )
3858  code += QLatin1String( "optional " );
3859  code += ( mBehavior == File ? QStringLiteral( "file" ) : QStringLiteral( "folder" ) ) + ' ';
3860  code += mDefault.toString();
3861  return code.trimmed();
3862 }
3863 
3865 {
3866  switch ( outputType )
3867  {
3869  {
3870 
3871  QString code = QStringLiteral( "QgsProcessingParameterFile('%1', %2" )
3873  if ( mFlags & FlagOptional )
3874  code += QLatin1String( ", optional=True" );
3875  code += QStringLiteral( ", behavior=%1" ).arg( mBehavior == File ? QStringLiteral( "QgsProcessingParameterFile.File" ) : QStringLiteral( "QgsProcessingParameterFile.Folder" ) );
3876  if ( !mExtension.isEmpty() )
3877  code += QStringLiteral( ", extension='%1'" ).arg( mExtension );
3878  if ( !mFileFilter.isEmpty() )
3879  code += QStringLiteral( ", fileFilter='%1'" ).arg( mFileFilter );
3881  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
3882  return code;
3883  }
3884  }
3885  return QString();
3886 }
3887 
3889 {
3890  switch ( mBehavior )
3891  {
3892  case File:
3893  {
3894  if ( !mFileFilter.isEmpty() )
3895  return mFileFilter != QObject::tr( "All files (*.*)" ) ? mFileFilter + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" ) : mFileFilter;
3896  else if ( !mExtension.isEmpty() )
3897  return QObject::tr( "%1 files" ).arg( mExtension.toUpper() ) + QStringLiteral( " (*." ) + mExtension.toLower() + QStringLiteral( ");;" ) + QObject::tr( "All files (*.*)" );
3898  else
3899  return QObject::tr( "All files (*.*)" );
3900  }
3901 
3902  case Folder:
3903  return QString();
3904  }
3905  return QString();
3906 }
3907 
3908 void QgsProcessingParameterFile::setExtension( const QString &extension )
3909 {
3910  mExtension = extension;
3911  mFileFilter.clear();
3912 }
3913 
3915 {
3916  return mFileFilter;
3917 }
3918 
3919 void QgsProcessingParameterFile::setFileFilter( const QString &filter )
3920 {
3921  mFileFilter = filter;
3922  mExtension.clear();
3923 }
3924 
3926 {
3928  map.insert( QStringLiteral( "behavior" ), mBehavior );
3929  map.insert( QStringLiteral( "extension" ), mExtension );
3930  map.insert( QStringLiteral( "filefilter" ), mFileFilter );
3931  return map;
3932 }
3933 
3934 bool QgsProcessingParameterFile::fromVariantMap( const QVariantMap &map )
3935 {
3937  mBehavior = static_cast< Behavior >( map.value( QStringLiteral( "behavior" ) ).toInt() );
3938  mExtension = map.value( QStringLiteral( "extension" ) ).toString();
3939  mFileFilter = map.value( QStringLiteral( "filefilter" ) ).toString();
3940  return true;
3941 }
3942 
3943 QgsProcessingParameterFile *QgsProcessingParameterFile::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition, QgsProcessingParameterFile::Behavior behavior )
3944 {
3945  return new QgsProcessingParameterFile( name, description, behavior, QString(), definition, isOptional );
3946 }
3947 
3948 QgsProcessingParameterMatrix::QgsProcessingParameterMatrix( const QString &name, const QString &description, int numberRows, bool fixedNumberRows, const QStringList &headers, const QVariant &defaultValue, bool optional )
3949  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3950  , mHeaders( headers )
3951  , mNumberRows( numberRows )
3952  , mFixedNumberRows( fixedNumberRows )
3953 {
3954 
3955 }
3956 
3958 {
3959  return new QgsProcessingParameterMatrix( *this );
3960 }
3961 
3963 {
3964  if ( !input.isValid() )
3965  return mFlags & FlagOptional;
3966 
3967  if ( input.type() == QVariant::String )
3968  {
3969  if ( input.toString().isEmpty() )
3970  return mFlags & FlagOptional;
3971  return true;
3972  }
3973  else if ( input.type() == QVariant::List )
3974  {
3975  if ( input.toList().isEmpty() )
3976  return mFlags & FlagOptional;
3977  return true;
3978  }
3979  else if ( input.type() == QVariant::Double || input.type() == QVariant::Int )
3980  {
3981  return true;
3982  }
3983 
3984  return false;
3985 }
3986 
3987 QString QgsProcessingParameterMatrix::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
3988 {
3989  if ( !value.isValid() )
3990  return QStringLiteral( "None" );
3991 
3992  if ( value.canConvert<QgsProperty>() )
3993  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
3994 
3995  QVariantMap p;
3996  p.insert( name(), value );
3997  const QVariantList list = QgsProcessingParameters::parameterAsMatrix( this, p, context );
3998 
4000 }
4001 
4003 {
4004  switch ( outputType )
4005  {
4007  {
4008  QString code = QStringLiteral( "QgsProcessingParameterMatrix('%1', %2" )
4010  if ( mFlags & FlagOptional )
4011  code += QLatin1String( ", optional=True" );
4012  code += QStringLiteral( ", numberRows=%1" ).arg( mNumberRows );
4013  code += QStringLiteral( ", hasFixedNumberRows=%1" ).arg( mFixedNumberRows ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
4014 
4015  QStringList headers;
4016  headers.reserve( mHeaders.size() );
4017  for ( const QString &h : mHeaders )
4019  code += QStringLiteral( ", headers=[%1]" ).arg( headers.join( ',' ) );
4020 
4022  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4023  return code;
4024  }
4025  }
4026  return QString();
4027 }
4028 
4030 {
4031  return mHeaders;
4032 }
4033 
4034 void QgsProcessingParameterMatrix::setHeaders( const QStringList &headers )
4035 {
4036  mHeaders = headers;
4037 }
4038 
4040 {
4041  return mNumberRows;
4042 }
4043 
4045 {
4046  mNumberRows = numberRows;
4047 }
4048 
4050 {
4051  return mFixedNumberRows;
4052 }
4053 
4055 {
4056  mFixedNumberRows = fixedNumberRows;
4057 }
4058 
4060 {
4062  map.insert( QStringLiteral( "headers" ), mHeaders );
4063  map.insert( QStringLiteral( "rows" ), mNumberRows );
4064  map.insert( QStringLiteral( "fixed_number_rows" ), mFixedNumberRows );
4065  return map;
4066 }
4067 
4068 bool QgsProcessingParameterMatrix::fromVariantMap( const QVariantMap &map )
4069 {
4071  mHeaders = map.value( QStringLiteral( "headers" ) ).toStringList();
4072  mNumberRows = map.value( QStringLiteral( "rows" ) ).toInt();
4073  mFixedNumberRows = map.value( QStringLiteral( "fixed_number_rows" ) ).toBool();
4074  return true;
4075 }
4076 
4077 QgsProcessingParameterMatrix *QgsProcessingParameterMatrix::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4078 {
4079  return new QgsProcessingParameterMatrix( name, description, 0, false, QStringList(), definition.isEmpty() ? QVariant() : definition, isOptional );
4080 }
4081 
4082 QgsProcessingParameterMultipleLayers::QgsProcessingParameterMultipleLayers( const QString &name, const QString &description, QgsProcessing::SourceType layerType, const QVariant &defaultValue, bool optional )
4083  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4084  , mLayerType( layerType )
4085 {
4086 
4087 }
4088 
4090 {
4091  return new QgsProcessingParameterMultipleLayers( *this );
4092 }
4093 
4095 {
4096  if ( !input.isValid() )
4097  return mFlags & FlagOptional;
4098 
4099  if ( mLayerType != QgsProcessing::TypeFile )
4100  {
4101  if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
4102  {
4103  return true;
4104  }
4105  }
4106 
4107  if ( input.type() == QVariant::String )
4108  {
4109  if ( input.toString().isEmpty() )
4110  return mFlags & FlagOptional;
4111 
4112  if ( mMinimumNumberInputs > 1 )
4113  return false;
4114 
4115  if ( !context )
4116  return true;
4117 
4118  if ( mLayerType != QgsProcessing::TypeFile )
4119  return QgsProcessingUtils::mapLayerFromString( input.toString(), *context );
4120  else
4121  return true;
4122  }
4123  else if ( input.type() == QVariant::List )
4124  {
4125  if ( input.toList().count() < mMinimumNumberInputs )
4126  return mFlags & FlagOptional;
4127 
4128  if ( mMinimumNumberInputs > input.toList().count() )
4129  return false;
4130 
4131  if ( !context )
4132  return true;
4133 
4134  if ( mLayerType != QgsProcessing::TypeFile )
4135  {
4136  const auto constToList = input.toList();
4137  for ( const QVariant &v : constToList )
4138  {
4139  if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( v ) ) )
4140  continue;
4141 
4142  if ( !QgsProcessingUtils::mapLayerFromString( v.toString(), *context ) )
4143  return false;
4144  }
4145  }
4146  return true;
4147  }
4148  else if ( input.type() == QVariant::StringList )
4149  {
4150  if ( input.toStringList().count() < mMinimumNumberInputs )
4151  return mFlags & FlagOptional;
4152 
4153  if ( mMinimumNumberInputs > input.toStringList().count() )
4154  return false;
4155 
4156  if ( !context )
4157  return true;
4158 
4159  if ( mLayerType != QgsProcessing::TypeFile )
4160  {
4161  const auto constToStringList = input.toStringList();
4162  for ( const QString &v : constToStringList )
4163  {
4164  if ( !QgsProcessingUtils::mapLayerFromString( v, *context ) )
4165  return false;
4166  }
4167  }
4168  return true;
4169  }
4170  return false;
4171 }
4172 
4174 {
4175  if ( !value.isValid() )
4176  return QStringLiteral( "None" );
4177 
4178  if ( value.canConvert<QgsProperty>() )
4179  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4180 
4181  if ( mLayerType == QgsProcessing::TypeFile )
4182  {
4183  QStringList parts;
4184  if ( value.type() == QVariant::StringList )
4185  {
4186  const QStringList list = value.toStringList();
4187  parts.reserve( list.count() );
4188  for ( const QString &v : list )
4190  }
4191  else if ( value.type() == QVariant::List )
4192  {
4193  const QVariantList list = value.toList();
4194  parts.reserve( list.count() );
4195  for ( const QVariant &v : list )
4196  parts << QgsProcessingUtils::stringToPythonLiteral( v.toString() );
4197  }
4198  if ( !parts.isEmpty() )
4199  return parts.join( ',' ).prepend( '[' ).append( ']' );
4200  }
4201  else
4202  {
4203  QVariantMap p;
4204  p.insert( name(), value );
4205  const QList<QgsMapLayer *> list = QgsProcessingParameters::parameterAsLayerList( this, p, context );
4206  if ( !list.isEmpty() )
4207  {
4208  QStringList parts;
4209  parts.reserve( list.count() );
4210  for ( const QgsMapLayer *layer : list )
4211  {
4213  }
4214  return parts.join( ',' ).prepend( '[' ).append( ']' );
4215  }
4216  }
4217 
4219 }
4220 
4222 {
4223  QString code = QStringLiteral( "##%1=" ).arg( mName );
4224  if ( mFlags & FlagOptional )
4225  code += QLatin1String( "optional " );
4226  switch ( mLayerType )
4227  {
4229  code += QLatin1String( "multiple raster" );
4230  break;
4231 
4233  code += QLatin1String( "multiple file" );
4234  break;
4235 
4236  default:
4237  code += QLatin1String( "multiple vector" );
4238  break;
4239  }
4240  code += ' ';
4241  if ( mDefault.type() == QVariant::List )
4242  {
4243  QStringList parts;
4244  const auto constToList = mDefault.toList();
4245  for ( const QVariant &var : constToList )
4246  {
4247  parts << var.toString();
4248  }
4249  code += parts.join( ',' );
4250  }
4251  else if ( mDefault.type() == QVariant::StringList )
4252  {
4253  code += mDefault.toStringList().join( ',' );
4254  }
4255  else
4256  {
4257  code += mDefault.toString();
4258  }
4259  return code.trimmed();
4260 }
4261 
4263 {
4264  switch ( outputType )
4265  {
4267  {
4268  QString code = QStringLiteral( "QgsProcessingParameterMultipleLayers('%1', %2" )
4270  if ( mFlags & FlagOptional )
4271  code += QLatin1String( ", optional=True" );
4272 
4273  const QString layerType = QStringLiteral( "QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( mLayerType ) );
4274 
4275  code += QStringLiteral( ", layerType=%1" ).arg( layerType );
4277  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4278  return code;
4279  }
4280  }
4281  return QString();
4282 }
4283 
4285 {
4286  const QStringList exts;
4287  switch ( mLayerType )
4288  {
4290  return QObject::tr( "All files (*.*)" );
4291 
4293  return QgsProviderRegistry::instance()->fileRasterFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
4294 
4300  return QgsProviderRegistry::instance()->fileVectorFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
4301 
4303  return QgsProviderRegistry::instance()->fileMeshFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
4304 
4306  return QgsProviderRegistry::instance()->filePointCloudFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
4307 
4311  return createAllMapLayerFileFilter();
4312  }
4313  return QString();
4314 }
4315 
4317 {
4318  return mLayerType;
4319 }
4320 
4322 {
4323  mLayerType = type;
4324 }
4325 
4327 {
4328  return mMinimumNumberInputs;
4329 }
4330 
4332 {
4333  if ( mMinimumNumberInputs >= 1 || !( flags() & QgsProcessingParameterDefinition::FlagOptional ) )
4334  mMinimumNumberInputs = minimumNumberInputs;
4335 }
4336 
4338 {
4340  map.insert( QStringLiteral( "layer_type" ), mLayerType );
4341  map.insert( QStringLiteral( "min_inputs" ), mMinimumNumberInputs );
4342  return map;
4343 }
4344 
4346 {
4348  mLayerType = static_cast< QgsProcessing::SourceType >( map.value( QStringLiteral( "layer_type" ) ).toInt() );
4349  mMinimumNumberInputs = map.value( QStringLiteral( "min_inputs" ) ).toInt();
4350  return true;
4351 }
4352 
4353 QgsProcessingParameterMultipleLayers *QgsProcessingParameterMultipleLayers::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4354 {
4355  QString type = definition;
4356  QString defaultVal;
4357  const QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*)" ) );
4358  const QRegularExpressionMatch m = re.match( definition );
4359  if ( m.hasMatch() )
4360  {
4361  type = m.captured( 1 ).toLower().trimmed();
4362  defaultVal = m.captured( 2 );
4363  }
4365  if ( type == QLatin1String( "vector" ) )
4367  else if ( type == QLatin1String( "raster" ) )
4369  else if ( type == QLatin1String( "file" ) )
4371  return new QgsProcessingParameterMultipleLayers( name, description, layerType, defaultVal.isEmpty() ? QVariant() : defaultVal, isOptional );
4372 }
4373 
4374 QgsProcessingParameterNumber::QgsProcessingParameterNumber( const QString &name, const QString &description, Type type, const QVariant &defaultValue, bool optional, double minValue, double maxValue )
4375  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4376  , mMin( minValue )
4377  , mMax( maxValue )
4378  , mDataType( type )
4379 {
4380  if ( mMin >= mMax )
4381  {
4382  QgsMessageLog::logMessage( QObject::tr( "Invalid number parameter \"%1\": min value %2 is >= max value %3!" ).arg( name ).arg( mMin ).arg( mMax ), QObject::tr( "Processing" ) );
4383  }
4384 }
4385 
4387 {
4388  return new QgsProcessingParameterNumber( *this );
4389 }
4390 
4392 {
4393  QVariant input = value;
4394  if ( !input.isValid() )
4395  {
4396  if ( !defaultValue().isValid() )
4397  return mFlags & FlagOptional;
4398 
4399  input = defaultValue();
4400  }
4401 
4402  if ( input.canConvert<QgsProperty>() )
4403  {
4404  return true;
4405  }
4406 
4407  bool ok = false;
4408  const double res = input.toDouble( &ok );
4409  if ( !ok )
4410  return mFlags & FlagOptional;
4411 
4412  return !( res < mMin || res > mMax );
4413 }
4414 
4416 {
4417  if ( !value.isValid() )
4418  return QStringLiteral( "None" );
4419 
4420  if ( value.canConvert<QgsProperty>() )
4421  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4422 
4423  return value.toString();
4424 }
4425 
4427 {
4429  QStringList parts;
4430  if ( mMin > std::numeric_limits<double>::lowest() + 1 )
4431  parts << QObject::tr( "Minimum value: %1" ).arg( mMin );
4432  if ( mMax < std::numeric_limits<double>::max() )
4433  parts << QObject::tr( "Maximum value: %1" ).arg( mMax );
4434  if ( mDefault.isValid() )
4435  parts << QObject::tr( "Default value: %1" ).arg( mDataType == Integer ? mDefault.toInt() : mDefault.toDouble() );
4436  const QString extra = parts.join( QLatin1String( "<br />" ) );
4437  if ( !extra.isEmpty() )
4438  text += QStringLiteral( "<p>%1</p>" ).arg( extra );
4439  return text;
4440 }
4441 
4443 {
4444  switch ( outputType )
4445  {
4447  {
4448  QString code = QStringLiteral( "QgsProcessingParameterNumber('%1', %2" )
4450  if ( mFlags & FlagOptional )
4451  code += QLatin1String( ", optional=True" );
4452 
4453  code += QStringLiteral( ", type=%1" ).arg( mDataType == Integer ? QStringLiteral( "QgsProcessingParameterNumber.Integer" ) : QStringLiteral( "QgsProcessingParameterNumber.Double" ) );
4454 
4455  if ( mMin != std::numeric_limits<double>::lowest() + 1 )
4456  code += QStringLiteral( ", minValue=%1" ).arg( mMin );
4457  if ( mMax != std::numeric_limits<double>::max() )
4458  code += QStringLiteral( ", maxValue=%1" ).arg( mMax );
4460  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4461  return code;
4462  }
4463  }
4464  return QString();
4465 }
4466 
4468 {
4469  return mMin;
4470 }
4471 
4473 {
4474  mMin = min;
4475 }
4476 
4478 {
4479  return mMax;
4480 }
4481 
4483 {
4484  mMax = max;
4485 }
4486 
4488 {
4489  return mDataType;
4490 }
4491 
4493 {
4494  mDataType = dataType;
4495 }
4496 
4498 {
4500  map.insert( QStringLiteral( "min" ), mMin );
4501  map.insert( QStringLiteral( "max" ), mMax );
4502  map.insert( QStringLiteral( "data_type" ), mDataType );
4503  return map;
4504 }
4505 
4506 bool QgsProcessingParameterNumber::fromVariantMap( const QVariantMap &map )
4507 {
4509  mMin = map.value( QStringLiteral( "min" ) ).toDouble();
4510  mMax = map.value( QStringLiteral( "max" ) ).toDouble();
4511  mDataType = static_cast< Type >( map.value( QStringLiteral( "data_type" ) ).toInt() );
4512  return true;
4513 }
4514 
4515 QgsProcessingParameterNumber *QgsProcessingParameterNumber::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4516 {
4517  return new QgsProcessingParameterNumber( name, description, Double, definition.isEmpty() ? QVariant()
4518  : ( definition.toLower().trimmed() == QLatin1String( "none" ) ? QVariant() : definition ), isOptional );
4519 }
4520 
4521 QgsProcessingParameterRange::QgsProcessingParameterRange( const QString &name, const QString &description, QgsProcessingParameterNumber::Type type, const QVariant &defaultValue, bool optional )
4522  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4523  , mDataType( type )
4524 {
4525 
4526 }
4527 
4529 {
4530  return new QgsProcessingParameterRange( *this );
4531 }
4532 
4534 {
4535  if ( !input.isValid() )
4536  return mFlags & FlagOptional;
4537 
4538  if ( input.canConvert<QgsProperty>() )
4539  {
4540  return true;
4541  }
4542 
4543  if ( input.type() == QVariant::String )
4544  {
4545  const QStringList list = input.toString().split( ',' );
4546  if ( list.count() != 2 )
4547  return mFlags & FlagOptional;
4548  bool ok = false;
4549  list.at( 0 ).toDouble( &ok );
4550  bool ok2 = false;
4551  list.at( 1 ).toDouble( &ok2 );
4552  if ( !ok || !ok2 )
4553  return mFlags & FlagOptional;
4554  return true;
4555  }
4556  else if ( input.type() == QVariant::List )
4557  {
4558  if ( input.toList().count() != 2 )
4559  return mFlags & FlagOptional;
4560 
4561  bool ok = false;
4562  input.toList().at( 0 ).toDouble( &ok );
4563  bool ok2 = false;
4564  input.toList().at( 1 ).toDouble( &ok2 );
4565  if ( !ok || !ok2 )
4566  return mFlags & FlagOptional;
4567  return true;
4568  }
4569 
4570  return false;
4571 }
4572 
4573 QString QgsProcessingParameterRange::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
4574 {
4575  if ( !value.isValid() )
4576  return QStringLiteral( "None" );
4577 
4578  if ( value.canConvert<QgsProperty>() )
4579  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4580 
4581  QVariantMap p;
4582  p.insert( name(), value );
4583  const QList< double > parts = QgsProcessingParameters::parameterAsRange( this, p, context );
4584 
4585  QStringList stringParts;
4586  const auto constParts = parts;
4587  for ( const double v : constParts )
4588  {
4589  stringParts << QString::number( v );
4590  }
4591  return stringParts.join( ',' ).prepend( '[' ).append( ']' );
4592 }
4593 
4595 {
4596  switch ( outputType )
4597  {
4599  {
4600  QString code = QStringLiteral( "QgsProcessingParameterRange('%1', %2" )
4602  if ( mFlags & FlagOptional )
4603  code += QLatin1String( ", optional=True" );
4604 
4605  code += QStringLiteral( ", type=%1" ).arg( mDataType == QgsProcessingParameterNumber::Integer ? QStringLiteral( "QgsProcessingParameterNumber.Integer" ) : QStringLiteral( "QgsProcessingParameterNumber.Double" ) );
4606 
4608  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4609  return code;
4610  }
4611  }
4612  return QString();
4613 }
4614 
4616 {
4617  return mDataType;
4618 }
4619 
4621 {
4622  mDataType = dataType;
4623 }
4624 
4626 {
4628  map.insert( QStringLiteral( "data_type" ), mDataType );
4629  return map;
4630 }
4631 
4632 bool QgsProcessingParameterRange::fromVariantMap( const QVariantMap &map )
4633 {
4635  mDataType = static_cast< QgsProcessingParameterNumber::Type >( map.value( QStringLiteral( "data_type" ) ).toInt() );
4636  return true;
4637 }
4638 
4639 QgsProcessingParameterRange *QgsProcessingParameterRange::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4640 {
4641  return new QgsProcessingParameterRange( name, description, QgsProcessingParameterNumber::Double, definition.isEmpty() ? QVariant()
4642  : ( definition.toLower().trimmed() == QLatin1String( "none" ) ? QVariant() : definition ), isOptional );
4643 }
4644 
4645 QgsProcessingParameterRasterLayer::QgsProcessingParameterRasterLayer( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
4646  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4647 {
4648 
4649 }
4650 
4652 {
4653  return new QgsProcessingParameterRasterLayer( *this );
4654 }
4655 
4657 {
4658  if ( !input.isValid() )
4659  return mFlags & FlagOptional;
4660 
4661  if ( input.canConvert<QgsProperty>() )
4662  {
4663  return true;
4664  }
4665 
4666  if ( qobject_cast< QgsRasterLayer * >( qvariant_cast<QObject *>( input ) ) )
4667  return true;
4668 
4669  if ( input.type() != QVariant::String || input.toString().isEmpty() )
4670  return mFlags & FlagOptional;
4671 
4672  if ( !context )
4673  {
4674  // that's as far as we can get without a context
4675  return true;
4676  }
4677 
4678  // try to load as layer
4679  if ( QgsProcessingUtils::mapLayerFromString( input.toString(), *context, true, QgsProcessingUtils::LayerHint::Raster ) )
4680  return true;
4681 
4682  return false;
4683 }
4684 
4686 {
4687  if ( !val.isValid() )
4688  return QStringLiteral( "None" );
4689 
4690  if ( val.canConvert<QgsProperty>() )
4691  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
4692 
4693  QVariantMap p;
4694  p.insert( name(), val );
4697  : QgsProcessingUtils::stringToPythonLiteral( val.toString() );
4698 }
4699 
4701 {
4702  return QgsProviderRegistry::instance()->fileRasterFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
4703 }
4704 
4705 QgsProcessingParameterRasterLayer *QgsProcessingParameterRasterLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4706 {
4707  return new QgsProcessingParameterRasterLayer( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
4708 }
4709 
4710 QgsProcessingParameterEnum::QgsProcessingParameterEnum( const QString &name, const QString &description, const QStringList &options, bool allowMultiple, const QVariant &defaultValue, bool optional, bool usesStaticStrings )
4711  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4712  , mOptions( options )
4713  , mAllowMultiple( allowMultiple )
4714  , mUsesStaticStrings( usesStaticStrings )
4715 {
4716 
4717 }
4718 
4720 {
4721  return new QgsProcessingParameterEnum( *this );
4722 }
4723 
4725 {
4726  QVariant input = value;
4727  if ( !input.isValid() )
4728  {
4729  if ( !defaultValue().isValid() )
4730  return mFlags & FlagOptional;
4731 
4732  input = defaultValue();
4733  }
4734 
4735  if ( input.canConvert<QgsProperty>() )
4736  {
4737  return true;
4738  }
4739 
4740  if ( mUsesStaticStrings )
4741  {
4742  if ( input.type() == QVariant::List )
4743  {
4744  if ( !mAllowMultiple )
4745  return false;
4746 
4747  const QVariantList values = input.toList();
4748  if ( values.empty() && !( mFlags & FlagOptional ) )
4749  return false;
4750 
4751  for ( const QVariant &val : values )
4752  {
4753  if ( !mOptions.contains( val.toString() ) )
4754  return false;
4755  }
4756 
4757  return true;
4758  }
4759  else if ( input.type() == QVariant::StringList )
4760  {
4761  if ( !mAllowMultiple )
4762  return false;
4763 
4764  const QStringList values = input.toStringList();
4765 
4766  if ( values.empty() && !( mFlags & FlagOptional ) )
4767  return false;
4768 
4769  if ( values.count() > 1 && !mAllowMultiple )
4770  return false;
4771 
4772  for ( const QString &val : values )
4773  {
4774  if ( !mOptions.contains( val ) )
4775  return false;
4776  }
4777  return true;
4778  }
4779  else if ( input.type() == QVariant::String )
4780  {
4781  const QStringList parts = input.toString().split( ',' );
4782  if ( parts.count() > 1 && !mAllowMultiple )
4783  return false;
4784 
4785  const auto constParts = parts;
4786  for ( const QString &part : constParts )
4787  {
4788  if ( !mOptions.contains( part ) )
4789  return false;
4790  }
4791  return true;
4792  }
4793  }
4794  else
4795  {
4796  if ( input.type() == QVariant::List )
4797  {
4798  if ( !mAllowMultiple )
4799  return false;
4800 
4801  const QVariantList values = input.toList();
4802  if ( values.empty() && !( mFlags & FlagOptional ) )
4803  return false;
4804 
4805  for ( const QVariant &val : values )
4806  {
4807  bool ok = false;
4808  const int res = val.toInt( &ok );
4809  if ( !ok )
4810  return false;
4811  else if ( res < 0 || res >= mOptions.count() )
4812  return false;
4813  }
4814 
4815  return true;
4816  }
4817  else if ( input.type() == QVariant::String )
4818  {
4819  const QStringList parts = input.toString().split( ',' );
4820  if ( parts.count() > 1 && !mAllowMultiple )
4821  return false;
4822 
4823  const auto constParts = parts;
4824  for ( const QString &part : constParts )
4825  {
4826  bool ok = false;
4827  const int res = part.toInt( &ok );
4828  if ( !ok )
4829  return false;
4830  else if ( res < 0 || res >= mOptions.count() )
4831  return false;
4832  }
4833  return true;
4834  }
4835  else if ( input.type() == QVariant::Int || input.type() == QVariant::Double )
4836  {
4837  bool ok = false;
4838  const int res = input.toInt( &ok );
4839  if ( !ok )
4840  return false;
4841  else if ( res >= 0 && res < mOptions.count() )
4842  return true;
4843  }
4844  }
4845 
4846  return false;
4847 }
4848 
4850 {
4851  if ( !value.isValid() )
4852  return QStringLiteral( "None" );
4853 
4854  if ( value.canConvert<QgsProperty>() )
4855  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4856 
4857  if ( mUsesStaticStrings )
4858  {
4859  if ( value.type() == QVariant::StringList )
4860  {
4861  QStringList parts;
4862  const QStringList constList = value.toStringList();
4863  for ( const QString &val : constList )
4864  {
4866  }
4867  return parts.join( ',' ).prepend( '[' ).append( ']' );
4868  }
4869  else if ( value.type() == QVariant::String )
4870  {
4871  QStringList parts;
4872  const QStringList constList = value.toString().split( ',' );
4873  if ( constList.count() > 1 )
4874  {
4875  for ( const QString &val : constList )
4876  {
4878  }
4879  return parts.join( ',' ).prepend( '[' ).append( ']' );
4880  }
4881  }
4882 
4883  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
4884  }
4885  else
4886  {
4887  if ( value.type() == QVariant::List )
4888  {
4889  QStringList parts;
4890  const auto constToList = value.toList();
4891  for ( const QVariant &val : constToList )
4892  {
4893  parts << QString::number( static_cast< int >( val.toDouble() ) );
4894  }
4895  return parts.join( ',' ).prepend( '[' ).append( ']' );
4896  }
4897  else if ( value.type() == QVariant::String )
4898  {
4899  const QStringList parts = value.toString().split( ',' );
4900  if ( parts.count() > 1 )
4901  {
4902  return parts.join( ',' ).prepend( '[' ).append( ']' );
4903  }
4904  }
4905 
4906  return QString::number( static_cast< int >( value.toDouble() ) );
4907  }
4908 }
4909 
4911 {
4912  if ( !value.isValid() )
4913  return QString();
4914 
4915  if ( value.canConvert<QgsProperty>() )
4916  return QString();
4917 
4918  if ( mUsesStaticStrings )
4919  {
4920  return QString();
4921  }
4922  else
4923  {
4924  if ( value.type() == QVariant::List )
4925  {
4926  QStringList parts;
4927  const QVariantList toList = value.toList();
4928  parts.reserve( toList.size() );
4929  for ( const QVariant &val : toList )
4930  {
4931  parts << mOptions.value( static_cast< int >( val.toDouble() ) );
4932  }
4933  return parts.join( ',' );
4934  }
4935  else if ( value.type() == QVariant::String )
4936  {
4937  const QStringList parts = value.toString().split( ',' );
4938  QStringList comments;
4939  if ( parts.count() > 1 )
4940  {
4941  for ( const QString &part : parts )
4942  {
4943  bool ok = false;
4944  const int val = part.toInt( &ok );
4945  if ( ok )
4946  comments << mOptions.value( val );
4947  }
4948  return comments.join( ',' );
4949  }
4950  }
4951 
4952  return mOptions.value( static_cast< int >( value.toDouble() ) );
4953  }
4954 }
4955 
4957 {
4958  QString code = QStringLiteral( "##%1=" ).arg( mName );
4959  if ( mFlags & FlagOptional )
4960  code += QLatin1String( "optional " );
4961  code += QLatin1String( "enum " );
4962 
4963  if ( mAllowMultiple )
4964  code += QLatin1String( "multiple " );
4965 
4966  if ( mUsesStaticStrings )
4967  code += QLatin1String( "static " );
4968 
4969  code += mOptions.join( ';' ) + ' ';
4970 
4971  code += mDefault.toString();
4972  return code.trimmed();
4973 }
4974 
4976 {
4977  switch ( outputType )
4978  {
4980  {
4981  QString code = QStringLiteral( "QgsProcessingParameterEnum('%1', %2" )
4983  if ( mFlags & FlagOptional )
4984  code += QLatin1String( ", optional=True" );
4985 
4986  QStringList options;
4987  options.reserve( mOptions.size() );
4988  for ( const QString &o : mOptions )
4990  code += QStringLiteral( ", options=[%1]" ).arg( options.join( ',' ) );
4991 
4992  code += QStringLiteral( ", allowMultiple=%1" ).arg( mAllowMultiple ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
4993 
4994  code += QStringLiteral( ", usesStaticStrings=%1" ).arg( mUsesStaticStrings ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
4995 
4997  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4998 
4999  return code;
5000  }
5001  }
5002  return QString();
5003 }
5004 
5006 {
5007  return mOptions;
5008 }
5009 
5010 void QgsProcessingParameterEnum::setOptions( const QStringList &options )
5011 {
5012  mOptions = options;
5013 }
5014 
5016 {
5017  return mAllowMultiple;
5018 }
5019 
5021 {
5022  mAllowMultiple = allowMultiple;
5023 }
5024 
5026 {
5027  return mUsesStaticStrings;
5028 }
5029 
5031 {
5032  mUsesStaticStrings = usesStaticStrings;
5033 }
5034 
5036 {
5038  map.insert( QStringLiteral( "options" ), mOptions );
5039  map.insert( QStringLiteral( "allow_multiple" ), mAllowMultiple );
5040  map.insert( QStringLiteral( "uses_static_strings" ), mUsesStaticStrings );
5041  return map;
5042 }
5043 
5044 bool QgsProcessingParameterEnum::fromVariantMap( const QVariantMap &map )
5045 {
5047  mOptions = map.value( QStringLiteral( "options" ) ).toStringList();
5048  mAllowMultiple = map.value( QStringLiteral( "allow_multiple" ) ).toBool();
5049  mUsesStaticStrings = map.value( QStringLiteral( "uses_static_strings" ) ).toBool();
5050  return true;
5051 }
5052 
5053 QgsProcessingParameterEnum *QgsProcessingParameterEnum::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5054 {
5055  QString defaultVal;
5056  QString def = definition;
5057 
5058  bool multiple = false;
5059  if ( def.startsWith( QLatin1String( "multiple" ), Qt::CaseInsensitive ) )
5060  {
5061  multiple = true;
5062  def = def.mid( 9 );
5063  }
5064 
5065  bool staticStrings = false;
5066  if ( def.startsWith( QLatin1String( "static" ), Qt::CaseInsensitive ) )
5067  {
5068  staticStrings = true;
5069  def = def.mid( 7 );
5070  }
5071 
5072  const QRegularExpression re( QStringLiteral( "(.*)\\s+(.*?)$" ) );
5073  const QRegularExpressionMatch m = re.match( def );
5074  QString values = def;
5075  if ( m.hasMatch() )
5076  {
5077  values = m.captured( 1 ).trimmed();
5078  defaultVal = m.captured( 2 );
5079  }
5080 
5081  return new QgsProcessingParameterEnum( name, description, values.split( ';' ), multiple, defaultVal.isEmpty() ? QVariant() : defaultVal, isOptional, staticStrings );
5082 }
5083 
5084 QgsProcessingParameterString::QgsProcessingParameterString( const QString &name, const QString &description, const QVariant &defaultValue, bool multiLine, bool optional )
5085  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5086  , mMultiLine( multiLine )
5087 {
5088 
5089 }
5090 
5092 {
5093  return new QgsProcessingParameterString( *this );
5094 }
5095 
5097 {
5098  if ( !value.isValid() || value.isNull() )
5099  return QStringLiteral( "None" );
5100 
5101  if ( value.canConvert<QgsProperty>() )
5102  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
5103 
5104  const QString s = value.toString();
5106 }
5107 
5109 {
5110  QString code = QStringLiteral( "##%1=" ).arg( mName );
5111  if ( mFlags & FlagOptional )
5112  code += QLatin1String( "optional " );
5113  code += QLatin1String( "string " );
5114 
5115  if ( mMultiLine )
5116  code += QLatin1String( "long " );
5117 
5118  code += mDefault.toString();
5119  return code.trimmed();
5120 }
5121 
5123 {
5124  switch ( outputType )
5125  {
5127  {
5128  QString code = QStringLiteral( "QgsProcessingParameterString('%1', %2" )
5130  if ( mFlags & FlagOptional )
5131  code += QLatin1String( ", optional=True" );
5132  code += QStringLiteral( ", multiLine=%1" ).arg( mMultiLine ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
5133 
5135  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
5136  return code;
5137  }
5138  }
5139  return QString();
5140 }
5141 
5143 {
5144  return mMultiLine;
5145 }
5146 
5148 {
5149  mMultiLine = multiLine;
5150 }
5151 
5153 {
5155  map.insert( QStringLiteral( "multiline" ), mMultiLine );
5156  return map;
5157 }
5158 
5159 bool QgsProcessingParameterString::fromVariantMap( const QVariantMap &map )
5160 {
5162  mMultiLine = map.value( QStringLiteral( "multiline" ) ).toBool();
5163  return true;
5164 }
5165 
5166 QgsProcessingParameterString *QgsProcessingParameterString::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5167 {
5168  QString def = definition;
5169  bool multiLine = false;
5170  if ( def.startsWith( QLatin1String( "long" ), Qt::CaseInsensitive ) )
5171  {
5172  multiLine = true;
5173  def = def.mid( 5 );
5174  }
5175 
5176  if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
5177  def = def.mid( 1 );
5178  if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
5179  def.chop( 1 );
5180 
5181  QVariant defaultValue = def;
5182  if ( def == QLatin1String( "None" ) )
5183  defaultValue = QVariant();
5184 
5186 }
5187 
5188 //
5189 // QgsProcessingParameterAuthConfig
5190 //
5191 
5192 QgsProcessingParameterAuthConfig::QgsProcessingParameterAuthConfig( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
5193  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5194 {
5195 
5196 }
5197 
5199 {
5200  return new QgsProcessingParameterAuthConfig( *this );
5201 }
5202 
5204 {
5205  if ( !value.isValid() )
5206  return QStringLiteral( "None" );
5207 
5208  const QString s = value.toString();
5210 }
5211 
5213 {
5214  QString code = QStringLiteral( "##%1=" ).arg( mName );
5215  if ( mFlags & FlagOptional )
5216  code += QLatin1String( "optional " );
5217  code += QLatin1String( "authcfg " );
5218 
5219  code += mDefault.toString();
5220  return code.trimmed();
5221 }
5222 
5223 QgsProcessingParameterAuthConfig *QgsProcessingParameterAuthConfig::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5224 {
5225  QString def = definition;
5226 
5227  if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
5228  def = def.mid( 1 );
5229  if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
5230  def.chop( 1 );
5231 
5232  QVariant defaultValue = def;
5233  if ( def == QLatin1String( "None" ) )
5234  defaultValue = QVariant();
5235 
5236  return new QgsProcessingParameterAuthConfig( name, description, defaultValue, isOptional );
5237 }
5238 
5239 
5240 //
5241 // QgsProcessingParameterExpression
5242 //
5243 
5244 QgsProcessingParameterExpression::QgsProcessingParameterExpression( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayerParameterName, bool optional )
5245  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5246  , mParentLayerParameterName( parentLayerParameterName )
5247 {
5248 
5249 }
5250 
5252 {
5253  return new QgsProcessingParameterExpression( *this );
5254 }
5255 
5257 {
5258  if ( !value.isValid() )
5259  return QStringLiteral( "None" );
5260 
5261  if ( value.canConvert<QgsProperty>() )
5262  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
5263 
5264  const QString s = value.toString();
5266 }
5267 
5269 {
5270  QStringList depends;
5271  if ( !mParentLayerParameterName.isEmpty() )
5272  depends << mParentLayerParameterName;
5273  return depends;
5274 }
5275 
5277 {
5278  switch ( outputType )
5279  {
5281  {
5282  QString code = QStringLiteral( "QgsProcessingParameterExpression('%1', %2" )
5284  if ( mFlags & FlagOptional )
5285  code += QLatin1String( ", optional=True" );
5286 
5287  code += QStringLiteral( ", parentLayerParameterName='%1'" ).arg( mParentLayerParameterName );
5288 
5290  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
5291  return code;
5292  }
5293  }
5294  return QString();
5295 }
5296 
5298 {
5299  return mParentLayerParameterName;
5300 }
5301 
5302 void QgsProcessingParameterExpression::setParentLayerParameterName( const QString &parentLayerParameterName )
5303 {
5304  mParentLayerParameterName = parentLayerParameterName;
5305 }
5306 
5308 {
5310  map.insert( QStringLiteral( "parent_layer" ), mParentLayerParameterName );
5311  return map;
5312 }
5313 
5315 {
5317  mParentLayerParameterName = map.value( QStringLiteral( "parent_layer" ) ).toString();
5318  return true;
5319 }
5320 
5321 QgsProcessingParameterExpression *QgsProcessingParameterExpression::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5322 {
5323  return new QgsProcessingParameterExpression( name, description, definition, QString(), isOptional );
5324 }
5325 
5326 QgsProcessingParameterVectorLayer::QgsProcessingParameterVectorLayer( const QString &name, const QString &description, const QList<int> &types, const QVariant &defaultValue, bool optional )
5327  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5329 {
5330 
5331 }
5332 
5334 {
5335  return new QgsProcessingParameterVectorLayer( *this );
5336 }
5337 
5339 {
5340  if ( !v.isValid() )
5341  return mFlags & FlagOptional;
5342 
5343  QVariant var = v;
5344 
5345  if ( var.canConvert<QgsProperty>() )
5346  {
5347  const QgsProperty p = var.value< QgsProperty >();
5349  {
5350  var = p.staticValue();
5351  }
5352  else
5353  {
5354  return true;
5355  }
5356  }
5357 
5358  if ( qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( var ) ) )
5359  return true;
5360 
5361  if ( var.type() != QVariant::String || var.toString().isEmpty() )
5362  return mFlags & FlagOptional;
5363 
5364  if ( !context )
5365  {
5366  // that's as far as we can get without a context
5367  return true;
5368  }
5369 
5370  // try to load as layer
5371  if ( QgsProcessingUtils::mapLayerFromString( var.toString(), *context, true, QgsProcessingUtils::LayerHint::Vector ) )
5372  return true;
5373 
5374  return false;
5375 }
5376 
5378 {
5379  if ( !val.isValid() )
5380  return QStringLiteral( "None" );
5381 
5382  if ( val.canConvert<QgsProperty>() )
5383  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
5384 
5385  QVariantMap p;
5386  p.insert( name(), val );
5389  : QgsProcessingUtils::stringToPythonLiteral( val.toString() );
5390 }
5391 
5393 {
5394  switch ( outputType )
5395  {
5397  {
5398  QString code = QStringLiteral( "QgsProcessingParameterVectorLayer('%1', %2" )
5400  if ( mFlags & FlagOptional )
5401  code += QLatin1String( ", optional=True" );
5402 
5403  if ( !mDataTypes.empty() )
5404  {
5405  QStringList options;
5406  for ( const int t : mDataTypes )
5407  options << QStringLiteral( "QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( static_cast< QgsProcessing::SourceType >( t ) ) );
5408  code += QStringLiteral( ", types=[%1]" ).arg( options.join( ',' ) );
5409  }
5410 
5412  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
5413  return code;
5414  }
5415  }
5416  return QString();
5417 }
5418 
5420 {
5421  return QgsProviderRegistry::instance()->fileVectorFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
5422 }
5423 
5425 {
5426  return mDataTypes;
5427 }
5428 
5430 {
5431  mDataTypes = types;
5432 }
5433 
5435 {
5437  QVariantList types;
5438  for ( const int type : mDataTypes )
5439  {
5440  types << type;
5441  }
5442  map.insert( QStringLiteral( "data_types" ), types );
5443  return map;
5444 }
5445 
5447 {
5449  mDataTypes.clear();
5450  const QVariantList values = map.value( QStringLiteral( "data_types" ) ).toList();
5451  for ( const QVariant &val : values )
5452  {
5453  mDataTypes << val.toInt();
5454  }
5455  return true;
5456 }
5457 
5458 QgsProcessingParameterVectorLayer *QgsProcessingParameterVectorLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5459 {
5460  return new QgsProcessingParameterVectorLayer( name, description, QList< int>(), definition.isEmpty() ? QVariant() : definition, isOptional );
5461 }
5462 
5463 QgsProcessingParameterMeshLayer::QgsProcessingParameterMeshLayer( const QString &name, const QString &description,
5464  const QVariant &defaultValue, bool optional )
5465  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5466 {
5467 
5468 }
5469 
5471 {
5472  return new QgsProcessingParameterMeshLayer( *this );
5473 }
5474 
5476 {
5477  if ( !v.isValid() )
5478  return mFlags & FlagOptional;
5479 
5480  QVariant var = v;
5481 
5482  if ( var.canConvert<QgsProperty>() )
5483  {
5484  const QgsProperty p = var.value< QgsProperty >();
5486  {
5487  var = p.staticValue();
5488  }
5489  else
5490  {
5491  return true;
5492  }
5493  }
5494 
5495  if ( qobject_cast< QgsMeshLayer * >( qvariant_cast<QObject *>( var ) ) )
5496  return true;
5497 
5498  if ( var.type() != QVariant::String || var.toString().isEmpty() )
5499  return mFlags & FlagOptional;
5500 
5501  if ( !context )
5502  {
5503  // that's as far as we can get without a context
5504  return true;
5505  }
5506 
5507  // try to load as layer
5508  if ( QgsProcessingUtils::mapLayerFromString( var.toString(), *context, true, QgsProcessingUtils::LayerHint::Mesh ) )
5509  return true;
5510 
5511  return false;
5512 }
5513 
5515 {
5516  if ( !val.isValid() )
5517  return QStringLiteral( "None" );
5518 
5519  if ( val.canConvert<QgsProperty>() )
5520  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
5521 
5522  QVariantMap p;
5523  p.insert( name(), val );
5524  QgsMeshLayer *layer = QgsProcessingParameters::parameterAsMeshLayer( this, p, context );
5526  : QgsProcessingUtils::stringToPythonLiteral( val.toString() );
5527 }
5528 
5530 {
5531  return QgsProviderRegistry::instance()->fileMeshFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
5532 }
5533 
5534 QgsProcessingParameterMeshLayer *QgsProcessingParameterMeshLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5535 {
5536  return new QgsProcessingParameterMeshLayer( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
5537 }
5538 
5539 QgsProcessingParameterField::QgsProcessingParameterField( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayerParameterName, DataType type, bool allowMultiple, bool optional, bool defaultToAllFields )
5540  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5541  , mParentLayerParameterName( parentLayerParameterName )
5542  , mDataType( type )
5543  , mAllowMultiple( allowMultiple )
5544  , mDefaultToAllFields( defaultToAllFields )
5545 {
5546 
5547 }
5548 
5549 
5551 {
5552  return new QgsProcessingParameterField( *this );
5553 }
5554 
5556 {
5557  if ( !input.isValid() )
5558  return mFlags & FlagOptional;
5559 
5560  if ( input.canConvert<QgsProperty>() )
5561  {
5562  return true;
5563  }
5564 
5565  if ( input.type() == QVariant::List || input.type() == QVariant::StringList )
5566  {
5567  if ( !mAllowMultiple )
5568  return false;
5569 
5570  if ( input.toList().isEmpty() && !( mFlags & FlagOptional ) )
5571  return false;
5572  }
5573  else if ( input.type() == QVariant::String )
5574  {
5575  if ( input.toString().isEmpty() )
5576  return mFlags & FlagOptional;
5577 
5578  const QStringList parts = input.toString().split( ';' );
5579  if ( parts.count() > 1 && !mAllowMultiple )
5580  return false;
5581  }
5582  else
5583  {
5584  if ( input.toString().isEmpty() )
5585  return mFlags & FlagOptional;
5586  }
5587  return true;
5588 }
5589 
5591 {
5592  if ( !value.isValid() )
5593  return QStringLiteral( "None" );
5594 
5595  if ( value.canConvert<QgsProperty>() )
5596  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
5597 
5598  if ( value.type() == QVariant::List )
5599  {
5600  QStringList parts;
5601  const auto constToList = value.toList();
5602  for ( const QVariant &val : constToList )
5603  {
5604  parts << QgsProcessingUtils::stringToPythonLiteral( val.toString() );
5605  }
5606  return parts.join( ',' ).prepend( '[' ).append( ']' );
5607  }
5608  else if ( value.type() == QVariant::StringList )
5609  {
5610  QStringList parts;
5611  const auto constToStringList = value.toStringList();
5612  for ( const QString &s : constToStringList )
5613  {
5615  }
5616  return parts.join( ',' ).prepend( '[' ).append( ']' );
5617  }
5618 
5619  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
5620 }
5621 
5623 {
5624  QString code = QStringLiteral( "##%1=" ).arg( mName );
5625  if ( mFlags & FlagOptional )
5626  code += QLatin1String( "optional " );
5627  code += QLatin1String( "field " );
5628 
5629  switch ( mDataType )
5630  {
5631  case Numeric:
5632  code += QLatin1String( "numeric " );
5633  break;
5634 
5635  case String:
5636  code += QLatin1String( "string " );
5637  break;
5638 
5639  case DateTime:
5640  code += QLatin1String( "datetime " );
5641  break;
5642 
5643  case Any:
5644  break;
5645  }
5646 
5647  if ( mAllowMultiple )
5648  code += QLatin1String( "multiple " );
5649 
5650  if ( mDefaultToAllFields )
5651  code += QLatin1String( "default_to_all_fields " );
5652 
5653  code += mParentLayerParameterName + ' ';
5654 
5655  code += mDefault.toString();
5656  return code.trimmed();
5657 }
5658 
5660 {
5661  switch ( outputType )
5662  {
5664  {
5665  QString code = QStringLiteral( "QgsProcessingParameterField('%1', %2" )
5667  if ( mFlags & FlagOptional )
5668  code += QLatin1String( ", optional=True" );
5669 
5670  QString dataType;
5671  switch ( mDataType )
5672  {
5673  case Any:
5674  dataType = QStringLiteral( "QgsProcessingParameterField.Any" );
5675  break;
5676 
5677  case Numeric:
5678  dataType = QStringLiteral( "QgsProcessingParameterField.Numeric" );
5679  break;
5680 
5681  case String:
5682  dataType = QStringLiteral( "QgsProcessingParameterField.String" );
5683  break;
5684 
5685  case DateTime:
5686  dataType = QStringLiteral( "QgsProcessingParameterField.DateTime" );
5687  break;
5688  }
5689  code += QStringLiteral( ", type=%1" ).arg( dataType );
5690 
5691  code += QStringLiteral( ", parentLayerParameterName='%1'" ).arg( mParentLayerParameterName );
5692  code += QStringLiteral( ", allowMultiple=%1" ).arg( mAllowMultiple ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
5694  code += QStringLiteral( ", defaultValue=%1" ).arg( valueAsPythonString( mDefault, c ) );
5695 
5696  if ( mDefaultToAllFields )
5697  code += QLatin1String( ", defaultToAllFields=True" );
5698 
5699  code += ')';
5700 
5701  return code;
5702  }
5703  }
5704  return QString();
5705 }
5706 
5708 {
5709  QStringList depends;
5710  if ( !mParentLayerParameterName.isEmpty() )
5711  depends << mParentLayerParameterName;
5712  return depends;
5713 }
5714 
5716 {
5717  return mParentLayerParameterName;
5718 }
5719 
5720 void QgsProcessingParameterField::setParentLayerParameterName( const QString &parentLayerParameterName )
5721 {
5722  mParentLayerParameterName = parentLayerParameterName;
5723 }
5724 
5726 {
5727  return mDataType;
5728 }
5729 
5731 {
5732  mDataType = dataType;
5733 }
5734 
5736 {
5737  return mAllowMultiple;
5738 }
5739 
5741 {
5742  mAllowMultiple = allowMultiple;
5743 }
5744 
5746 {
5747  return mDefaultToAllFields;
5748 }
5749 
5751 {
5752  mDefaultToAllFields = enabled;
5753 }
5754 
5756 {
5758  map.insert( QStringLiteral( "parent_layer" ), mParentLayerParameterName );
5759  map.insert( QStringLiteral( "data_type" ), mDataType );
5760  map.insert( QStringLiteral( "allow_multiple" ), mAllowMultiple );
5761  map.insert( QStringLiteral( "default_to_all_fields" ), mDefaultToAllFields );
5762  return map;
5763 }
5764 
5765 bool QgsProcessingParameterField::fromVariantMap( const QVariantMap &map )
5766 {
5768  mParentLayerParameterName = map.value( QStringLiteral( "parent_layer" ) ).toString();
5769  mDataType = static_cast< DataType >( map.value( QStringLiteral( "data_type" ) ).toInt() );
5770  mAllowMultiple = map.value( QStringLiteral( "allow_multiple" ) ).toBool();
5771  mDefaultToAllFields = map.value( QStringLiteral( "default_to_all_fields" ) ).toBool();
5772  return true;
5773 }
5774 
5775 QgsProcessingParameterField *QgsProcessingParameterField::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5776 {
5777  QString parent;
5778  DataType type = Any;
5779  bool allowMultiple = false;
5780  bool defaultToAllFields = false;
5781  QString def = definition;
5782 
5783  if ( def.startsWith( QLatin1String( "numeric " ), Qt::CaseInsensitive ) )
5784  {
5785  type = Numeric;
5786  def = def.mid( 8 );
5787  }
5788  else if ( def.startsWith( QLatin1String( "string " ), Qt::CaseInsensitive ) )
5789  {
5790  type = String;
5791  def = def.mid( 7 );
5792  }
5793  else if ( def.startsWith( QLatin1String( "datetime " ), Qt::CaseInsensitive ) )
5794  {
5795  type = DateTime;
5796  def = def.mid( 9 );
5797  }
5798 
5799  if ( def.startsWith( QLatin1String( "multiple" ), Qt::CaseInsensitive ) )
5800  {
5801  allowMultiple = true;
5802  def = def.mid( 8 ).trimmed();
5803  }
5804 
5805  if ( def.startsWith( QLatin1String( "default_to_all_fields" ), Qt::CaseInsensitive ) )
5806  {
5807  defaultToAllFields = true;
5808  def = def.mid( 21 ).trimmed();
5809  }
5810 
5811  const QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*)$" ) );
5812  const QRegularExpressionMatch m = re.match( def );
5813  if ( m.hasMatch() )
5814  {
5815  parent = m.captured( 1 ).trimmed();
5816  def = m.captured( 2 );
5817  }
5818  else
5819  {
5820  parent = def;
5821  def.clear();
5822  }
5823 
5824  return new QgsProcessingParameterField( name, description, def.isEmpty() ? QVariant() : def, parent, type, allowMultiple, isOptional, defaultToAllFields );
5825 }
5826 
5827 QgsProcessingParameterFeatureSource::QgsProcessingParameterFeatureSource( const QString &name, const QString &description, const QList<int> &types, const QVariant &defaultValue, bool optional )
5828  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5830 {
5831 
5832 }
5833 
5835 {
5836  return new QgsProcessingParameterFeatureSource( *this );
5837 }
5838 
5840 {
5841  QVariant var = input;
5842  if ( !var.isValid() )
5843  return mFlags & FlagOptional;
5844 
5845  if ( var.canConvert<QgsProcessingFeatureSourceDefinition>() )
5846  {
5847  const QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( var );
5848  var = fromVar.source;
5849  }
5850  else if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
5851  {
5852  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
5853  const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
5854  var = fromVar.sink;
5855  }
5856 
5857  if ( var.canConvert<QgsProperty>() )
5858  {
5859  const QgsProperty p = var.value< QgsProperty >();
5861  {
5862  var = p.staticValue();
5863  }
5864  else
5865  {
5866  return true;
5867  }
5868  }
5869  if ( qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( input ) ) )
5870  {
5871  return true;
5872  }
5873 
5874  if ( var.type() != QVariant::String || var.toString().isEmpty() )
5875  return mFlags & FlagOptional;
5876 
5877  if ( !context )
5878  {
5879  // that's as far as we can get without a context
5880  return true;
5881  }
5882 
5883  // try to load as layer
5884  if ( QgsProcessingUtils::mapLayerFromString( var.toString(), *context, true, QgsProcessingUtils::LayerHint::Vector ) )
5885  return true;
5886 
5887  return false;
5888 }
5889 
5891 {
5892  if ( !value.isValid() )
5893  return QStringLiteral( "None" );
5894 
5895  if ( value.canConvert<QgsProperty>() )
5896  return QStringLiteral( "QgsProperty.fromExpression(%1)" ).arg( QgsProcessingUtils::stringToPythonLiteral( value.value< QgsProperty >().asExpression() ) );
5897 
5898  if ( value.canConvert<QgsProcessingFeatureSourceDefinition>() )
5899  {
5900  const QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( value );
5901  QString geometryCheckString;
5902  switch ( fromVar.geometryCheck )
5903  {
5905  geometryCheckString = QStringLiteral( "QgsFeatureRequest.GeometryNoCheck" );
5906  break;
5907 
5909  geometryCheckString = QStringLiteral( "QgsFeatureRequest.GeometrySkipInvalid" );
5910  break;
5911 
5913  geometryCheckString = QStringLiteral( "QgsFeatureRequest.GeometryAbortOnInvalid" );
5914  break;
5915  }
5916 
5917  QStringList flags;
5918  QString flagString;
5919  if ( fromVar.flags & QgsProcessingFeatureSourceDefinition::Flag::FlagOverrideDefaultGeometryCheck )
5920  flags << QStringLiteral( "QgsProcessingFeatureSourceDefinition.FlagOverrideDefaultGeometryCheck" );
5921  if ( fromVar.flags & QgsProcessingFeatureSourceDefinition::Flag::FlagCreateIndividualOutputPerInputFeature )
5922  flags << QStringLiteral( "QgsProcessingFeatureSourceDefinition.FlagCreateIndividualOutputPerInputFeature" );
5923  if ( !flags.empty() )
5924  flagString = flags.join( QLatin1String( " | " ) );
5925 
5926  if ( fromVar.source.propertyType() == QgsProperty::StaticProperty )
5927  {
5928  QString layerString = fromVar.source.staticValue().toString();
5929  // prefer to use layer source instead of id if possible (since it's persistent)
5930  if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( QgsProcessingUtils::mapLayerFromString( layerString, context, true, QgsProcessingUtils::LayerHint::Vector ) ) )
5931  layerString = layer->source();
5932 
5933  if ( fromVar.selectedFeaturesOnly || fromVar.featureLimit != -1 || fromVar.flags )
5934  {
5935  return QStringLiteral( "QgsProcessingFeatureSourceDefinition(%1, selectedFeaturesOnly=%2, featureLimit=%3%4, geometryCheck=%5)" ).arg( QgsProcessingUtils::stringToPythonLiteral( layerString ),
5936  fromVar.selectedFeaturesOnly ? QStringLiteral( "True" ) : QStringLiteral( "False" ),
5937  QString::number( fromVar.featureLimit ),
5938  flagString.isEmpty() ? QString() : ( QStringLiteral( ", flags=%1" ).arg( flagString ) ),
5939  geometryCheckString );
5940  }
5941  else
5942  {
5943  return QgsProcessingUtils::stringToPythonLiteral( layerString );
5944  }
5945  }
5946  else
5947  {
5948  if ( fromVar.selectedFeaturesOnly || fromVar.featureLimit != -1 || fromVar.flags )
5949  {
5950  return QStringLiteral( "QgsProcessingFeatureSourceDefinition(QgsProperty.fromExpression(%1), selectedFeaturesOnly=%2, featureLimit=%3%4, geometryCheck=%5)" )
5952  fromVar.selectedFeaturesOnly ? QStringLiteral( "True" ) : QStringLiteral( "False" ),
5953  QString::number( fromVar.featureLimit ),
5954  flagString.isEmpty() ? QString() : ( QStringLiteral( ", flags=%1" ).arg( flagString ) ),
5955  geometryCheckString );
5956  }
5957  else
5958  {
5959  return QStringLiteral( "QgsProperty.fromExpression(%1)" ).arg( QgsProcessingUtils::stringToPythonLiteral( fromVar.source.asExpression() ) );
5960  }
5961  }
5962  }
5963  else if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( value ) ) )
5964  {
5965  return QgsProcessingUtils::stringToPythonLiteral( layer->source() );
5966  }
5967 
5968  QString layerString = value.toString();
5969 
5970  // prefer to use layer source if possible (since it's persistent)
5971  if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( QgsProcessingUtils::mapLayerFromString( layerString, context, true, QgsProcessingUtils::LayerHint::Vector ) ) )
5972  layerString = layer->providerType() != QLatin1String( "ogr" ) && layer->providerType() != QLatin1String( "gdal" ) && layer->providerType() != QLatin1String( "mdal" ) ? QgsProcessingUtils::encodeProviderKeyAndUri( layer->providerType(), layer->source() ) : layer->source();
5973 
5974  return QgsProcessingUtils::stringToPythonLiteral( layerString );
5975 }
5976 
5978 {
5979  QString code = QStringLiteral( "##%1=" ).arg( mName );
5980  if ( mFlags & FlagOptional )
5981  code += QLatin1String( "optional " );
5982  code += QLatin1String( "source " );
5983 
5984  for ( const int type : mDataTypes )
5985  {
5986  switch ( type )
5987  {
5989  code += QLatin1String( "point " );
5990  break;
5991 
5993  code += QLatin1String( "line " );
5994  break;
5995 
5997  code += QLatin1String( "polygon " );
5998  break;
5999 
6000  }
6001  }
6002 
6003  code += mDefault.toString();
6004  return code.trimmed();
6005 }
6006 
6008 {
6009  switch ( outputType )
6010  {
6012  {
6013  QString code = QStringLiteral( "QgsProcessingParameterFeatureSource('%1', %2" )
6015  if ( mFlags & FlagOptional )
6016  code += QLatin1String( ", optional=True" );
6017 
6018  if ( !mDataTypes.empty() )
6019  {
6020  QStringList options;
6021  options.reserve( mDataTypes.size() );
6022  for ( const int t : mDataTypes )
6023  options << QStringLiteral( "QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( static_cast< QgsProcessing::SourceType >( t ) ) );
6024  code += QStringLiteral( ", types=[%1]" ).arg( options.join( ',' ) );
6025  }
6026 
6028  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
6029  return code;
6030  }
6031  }
6032  return QString();
6033 }
6034 
6036 {
6037  return QgsProviderRegistry::instance()->fileVectorFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
6038 }
6039 
6041  : mDataTypes( types )
6042 {
6043 
6044 }
6045 
6047 {
6049  QVariantList types;
6050  for ( const int type : mDataTypes )
6051  {
6052  types << type;
6053  }
6054  map.insert( QStringLiteral( "data_types" ), types );
6055  return map;
6056 }
6057 
6059 {
6061  mDataTypes.clear();
6062  const QVariantList values = map.value( QStringLiteral( "data_types" ) ).toList();
6063  for ( const QVariant &val : values )
6064  {
6065  mDataTypes << val.toInt();
6066  }
6067  return true;
6068 }
6069 
6070 QgsProcessingParameterFeatureSource *QgsProcessingParameterFeatureSource::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6071 {
6072  QList< int > types;
6073  QString def = definition;
6074  while ( true )
6075  {
6076  if ( def.startsWith( QLatin1String( "point" ), Qt::CaseInsensitive ) )
6077  {
6079  def = def.mid( 6 );
6080  continue;
6081  }
6082  else if ( def.startsWith( QLatin1String( "line" ), Qt::CaseInsensitive ) )
6083  {
6085  def = def.mid( 5 );
6086  continue;
6087  }
6088  else if ( def.startsWith( QLatin1String( "polygon" ), Qt::CaseInsensitive ) )
6089  {
6091  def = def.mid( 8 );
6092  continue;
6093  }
6094  break;
6095  }
6096 
6097  return new QgsProcessingParameterFeatureSource( name, description, types, def, isOptional );
6098 }
6099 
6100 QgsProcessingParameterFeatureSink::QgsProcessingParameterFeatureSink( const QString &name, const QString &description, QgsProcessing::SourceType type, const QVariant &defaultValue, bool optional, bool createByDefault, bool supportsAppend )
6101  : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
6102  , mDataType( type )
6103  , mSupportsAppend( supportsAppend )
6104 {
6105 }
6106 
6108 {
6109  return new QgsProcessingParameterFeatureSink( *this );
6110 }
6111 
6113 {
6114  QVariant var = input;
6115  if ( !var.isValid() )
6116  return mFlags & FlagOptional;
6117 
6118  if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
6119  {
6120  const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
6121  var = fromVar.sink;
6122  }
6123 
6124  if ( var.canConvert<QgsProperty>() )
6125  {
6126  const QgsProperty p = var.value< QgsProperty >();
6128  {
6129  var = p.staticValue();
6130  }
6131  else
6132  {
6133  return true;
6134  }
6135  }
6136 
6137  if ( var.type() != QVariant::String )
6138  return false;
6139 
6140  if ( var.toString().isEmpty() )
6141  return mFlags & FlagOptional;
6142 
6143  return true;
6144 }
6145 
6147 {
6148  if ( !value.isValid() )
6149  return QStringLiteral( "None" );
6150 
6151  if ( value.canConvert<QgsProperty>() )
6152  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
6153 
6154  if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
6155  {
6156  const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
6157  if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
6158  {
6159  return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
6160  }
6161  else
6162  {
6163  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
6164  }
6165  }
6166 
6167  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
6168 }
6169 
6171 {
6172  QString code = QStringLiteral( "##%1=" ).arg( mName );
6173  if ( mFlags & FlagOptional )
6174  code += QLatin1String( "optional " );
6175  code += QLatin1String( "sink " );
6176 
6177  switch ( mDataType )
6178  {
6180  code += QLatin1String( "point " );
6181  break;
6182 
6184  code += QLatin1String( "line " );
6185  break;
6186 
6188  code += QLatin1String( "polygon " );
6189  break;
6190 
6192  code += QLatin1String( "table " );
6193  break;
6194 
6195  default:
6196  break;
6197  }
6198 
6199  code += mDefault.toString();
6200  return code.trimmed();
6201 }
6202 
6204 {
6205  return new QgsProcessingOutputVectorLayer( name(), description(), mDataType );
6206 }
6207 
6209 {
6210  if ( auto *lOriginalProvider = originalProvider() )
6211  {
6212  return lOriginalProvider->defaultVectorFileExtension( hasGeometry() );
6213  }
6214  else if ( QgsProcessingProvider *p = provider() )
6215  {
6216  return p->defaultVectorFileExtension( hasGeometry() );
6217  }
6218  else
6219  {
6220  if ( hasGeometry() )
6221  {
6223  }
6224  else
6225  {
6226  return QStringLiteral( "dbf" );
6227  }
6228  }
6229 }
6230 
6232 {
6233  switch ( outputType )
6234  {
6236  {
6237  QString code = QStringLiteral( "QgsProcessingParameterFeatureSink('%1', %2" )
6239  if ( mFlags & FlagOptional )
6240  code += QLatin1String( ", optional=True" );
6241 
6242  code += QStringLiteral( ", type=QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( mDataType ) );
6243 
6244  code += QStringLiteral( ", createByDefault=%1" ).arg( createByDefault() ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
6245  if ( mSupportsAppend )
6246  code += QLatin1String( ", supportsAppend=True" );
6247 
6249  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
6250  return code;
6251  }
6252  }
6253  return QString();
6254 }
6255 
6257 {
6258  const QStringList exts = supportedOutputVectorLayerExtensions();
6259  QStringList filters;
6260  for ( const QString &ext : exts )
6261  {
6262  filters << QObject::tr( "%1 files (*.%2)" ).arg( ext.toUpper(), ext.toLower() );
6263  }
6264  return filters.join( QLatin1String( ";;" ) ) + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
6265 
6266 }
6267 
6269 {
6270  if ( auto *lOriginalProvider = originalProvider() )
6271  {
6272  if ( hasGeometry() )
6273  return lOriginalProvider->supportedOutputVectorLayerExtensions();
6274  else
6275  return lOriginalProvider->supportedOutputTableExtensions();
6276  }
6277  else if ( QgsProcessingProvider *p = provider() )
6278  {
6279  if ( hasGeometry() )
6280  return p->supportedOutputVectorLayerExtensions();
6281  else
6282  return p->supportedOutputTableExtensions();
6283  }
6284  else
6285  {
6287  }
6288 }
6289 
6291 {
6292  return mDataType;
6293 }
6294 
6296 {
6297  switch ( mDataType )
6298  {
6304  return true;
6305 
6313  return false;
6314  }
6315  return true;
6316 }
6317 
6319 {
6320  mDataType = type;
6321 }
6322 
6324 {
6326  map.insert( QStringLiteral( "data_type" ), mDataType );
6327  map.insert( QStringLiteral( "supports_append" ), mSupportsAppend );
6328  return map;
6329 }
6330 
6332 {
6334  mDataType = static_cast< QgsProcessing::SourceType >( map.value( QStringLiteral( "data_type" ) ).toInt() );
6335  mSupportsAppend = map.value( QStringLiteral( "supports_append" ), false ).toBool();
6336  return true;
6337 }
6338 
6340 {
6342  return QStringLiteral( "memory:%1" ).arg( description() );
6343  else
6345 }
6346 
6347 QgsProcessingParameterFeatureSink *QgsProcessingParameterFeatureSink::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6348 {
6350  QString def = definition;
6351  if ( def.startsWith( QLatin1String( "point" ), Qt::CaseInsensitive ) )
6352  {
6354  def = def.mid( 6 );
6355  }
6356  else if ( def.startsWith( QLatin1String( "line" ), Qt::CaseInsensitive ) )
6357  {
6359  def = def.mid( 5 );
6360  }
6361  else if ( def.startsWith( QLatin1String( "polygon" ), Qt::CaseInsensitive ) )
6362  {
6364  def = def.mid( 8 );
6365  }
6366  else if ( def.startsWith( QLatin1String( "table" ), Qt::CaseInsensitive ) )
6367  {
6369  def = def.mid( 6 );
6370  }
6371 
6372  return new QgsProcessingParameterFeatureSink( name, description, type, definition, isOptional );
6373 }
6374 
6376 {
6377  return mSupportsAppend;
6378 }
6379 
6381 {
6382  mSupportsAppend = supportsAppend;
6383 }
6384 
6385 QgsProcessingParameterRasterDestination::QgsProcessingParameterRasterDestination( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, bool createByDefault )
6386  : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
6387 {
6388 }
6389 
6391 {
6392  return new QgsProcessingParameterRasterDestination( *this );
6393 }
6394 
6396 {
6397  QVariant var = input;
6398  if ( !var.isValid() )
6399  return mFlags & FlagOptional;
6400 
6401  if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
6402  {
6403  const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
6404  var = fromVar.sink;
6405  }
6406 
6407  if ( var.canConvert<QgsProperty>() )
6408  {
6409  const QgsProperty p = var.value< QgsProperty >();
6411  {
6412  var = p.staticValue();
6413  }
6414  else
6415  {
6416  return true;
6417  }
6418  }
6419 
6420  if ( var.type() != QVariant::String )
6421  return false;
6422 
6423  if ( var.toString().isEmpty() )
6424  return mFlags & FlagOptional;
6425 
6426  return true;
6427 }
6428 
6430 {
6431  if ( !value.isValid() )
6432  return QStringLiteral( "None" );
6433 
6434  if ( value.canConvert<QgsProperty>() )
6435  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
6436 
6437  if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
6438  {
6439  const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
6440  if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
6441  {
6442  return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
6443  }
6444  else
6445  {
6446  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
6447  }
6448  }
6449 
6450  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
6451 }
6452 
6454 {
6455  return new QgsProcessingOutputRasterLayer( name(), description() );
6456 }
6457 
6459 {
6460  if ( auto *lOriginalProvider = originalProvider() )
6461  {
6462  return lOriginalProvider->defaultRasterFileExtension();
6463  }
6464  else if ( QgsProcessingProvider *p = provider() )
6465  {
6466  return p->defaultRasterFileExtension();
6467  }
6468  else
6469  {
6471  }
6472 }
6473 
6475 {
6476  const QStringList exts = supportedOutputRasterLayerExtensions();
6477  QStringList filters;
6478  for ( const QString &ext : exts )
6479  {
6480  filters << QObject::tr( "%1 files (*.%2)" ).arg( ext.toUpper(), ext.toLower() );
6481  }
6482  return filters.join( QLatin1String( ";;" ) ) + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
6483 }
6484 
6486 {
6487  if ( auto *lOriginalProvider = originalProvider() )
6488  {
6489  return lOriginalProvider->supportedOutputRasterLayerExtensions();
6490  }
6491  else if ( QgsProcessingProvider *p = provider() )
6492  {
6493  return p->supportedOutputRasterLayerExtensions();
6494  }
6495  else
6496  {
6498  }
6499 }
6500 
6501 QgsProcessingParameterRasterDestination *QgsProcessingParameterRasterDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6502 {
6503  return new QgsProcessingParameterRasterDestination( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
6504 }
6505 
6506 
6507 QgsProcessingParameterFileDestination::QgsProcessingParameterFileDestination( const QString &name, const QString &description, const QString &fileFilter, const QVariant &defaultValue, bool optional, bool createByDefault )
6508  : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
6509  , mFileFilter( fileFilter.isEmpty() ? QObject::tr( "All files (*.*)" ) : fileFilter )
6510 {
6511 
6512 }
6513 
6515 {
6516  return new QgsProcessingParameterFileDestination( *this );
6517 }
6518 
6520 {
6521  QVariant var = input;
6522  if ( !var.isValid() )
6523  return mFlags & FlagOptional;
6524 
6525  if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
6526  {
6527  const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
6528  var = fromVar.sink;
6529  }
6530 
6531  if ( var.canConvert<QgsProperty>() )
6532  {
6533  const QgsProperty p = var.value< QgsProperty >();
6535  {
6536  var = p.staticValue();
6537  }
6538  else
6539  {
6540  return true;
6541  }
6542  }
6543 
6544  if ( var.type() != QVariant::String )
6545  return false;
6546 
6547  if ( var.toString().isEmpty() )
6548  return mFlags & FlagOptional;
6549 
6550  // possible enhancement - check that value is compatible with file filter?
6551 
6552  return true;
6553 }
6554 
6556 {
6557  if ( !value.isValid() )
6558  return QStringLiteral( "None" );
6559 
6560  if ( value.canConvert<QgsProperty>() )
6561  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
6562 
6563  if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
6564  {
6565  const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
6566  if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
6567  {
6568  return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
6569  }
6570  else
6571  {
6572  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
6573  }
6574  }
6575 
6576  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
6577 }
6578 
6580 {
6581  if ( !mFileFilter.isEmpty() && mFileFilter.contains( QStringLiteral( "htm" ), Qt::CaseInsensitive ) )
6582  {
6583  return new QgsProcessingOutputHtml( name(), description() );
6584  }
6585  else
6586  {
6587  return new QgsProcessingOutputFile( name(), description() );
6588  }
6589 }
6590 
6592 {
6593  if ( mFileFilter.isEmpty() || mFileFilter == QObject::tr( "All files (*.*)" ) )
6594  return QStringLiteral( "file" );
6595 
6596  // get first extension from filter
6597  const QRegularExpression rx( QStringLiteral( ".*?\\(\\*\\.([a-zA-Z0-9._]+).*" ) );
6598  const QRegularExpressionMatch match = rx.match( mFileFilter );
6599  if ( !match.hasMatch() )
6600  return QStringLiteral( "file" );
6601 
6602  return match.captured( 1 );
6603 }
6604 
6606 {
6607  switch ( outputType )
6608  {
6610  {
6611  QString code = QStringLiteral( "QgsProcessingParameterFileDestination('%1', %2" )
6613  if ( mFlags & FlagOptional )
6614  code += QLatin1String( ", optional=True" );
6615 
6616  code += QStringLiteral( ", fileFilter=%1" ).arg( QgsProcessingUtils::stringToPythonLiteral( mFileFilter ) );
6617 
6618  code += QStringLiteral( ", createByDefault=%1" ).arg( createByDefault() ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
6619 
6621  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
6622  return code;
6623  }
6624  }
6625  return QString();
6626 }
6627 
6629 {
6630  return ( fileFilter().isEmpty() ? QString() : fileFilter() + QStringLiteral( ";;" ) ) + QObject::tr( "All files (*.*)" );
6631 }
6632 
6634 {
6635  return mFileFilter;
6636 }
6637 
6639 {
6640  mFileFilter = fileFilter;
6641 }
6642 
6644 {
6646  map.insert( QStringLiteral( "file_filter" ), mFileFilter );
6647  return map;
6648 }
6649 
6651 {
6653  mFileFilter = map.value( QStringLiteral( "file_filter" ) ).toString();
6654  return true;
6655 
6656 }
6657 
6658 QgsProcessingParameterFileDestination *QgsProcessingParameterFileDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6659 {
6660  return new QgsProcessingParameterFileDestination( name, description, QString(), definition.isEmpty() ? QVariant() : definition, isOptional );
6661 }
6662 
6663 QgsProcessingParameterFolderDestination::QgsProcessingParameterFolderDestination( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, bool createByDefault )
6664  : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
6665 {}
6666 
6668 {
6669  return new QgsProcessingParameterFolderDestination( *this );
6670 }
6671 
6673 {
6674  QVariant var = input;
6675  if ( !var.isValid() )
6676  return mFlags & FlagOptional;
6677 
6678  if ( var.canConvert<QgsProperty>() )
6679  {
6680  const QgsProperty p = var.value< QgsProperty >();
6682  {
6683  var = p.staticValue();
6684  }
6685  else
6686  {
6687  return true;
6688  }
6689  }
6690 
6691  if ( var.type() != QVariant::String )
6692  return false;
6693 
6694  if ( var.toString().isEmpty() )
6695  return mFlags & FlagOptional;
6696 
6697  return true;
6698 }
6699 
6701 {
6702  return new QgsProcessingOutputFolder( name(), description() );
6703 }
6704 
6706 {
6707  return QString();
6708 }
6709 
6710 QgsProcessingParameterFolderDestination *QgsProcessingParameterFolderDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6711 {
6712  return new QgsProcessingParameterFolderDestination( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
6713 }
6714 
6715 QgsProcessingDestinationParameter::QgsProcessingDestinationParameter( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, bool createByDefault )
6716  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
6717  , mCreateByDefault( createByDefault )
6718 {
6719 
6720 }
6721 
6723 {
6725  map.insert( QStringLiteral( "supports_non_file_outputs" ), mSupportsNonFileBasedOutputs );
6726  map.insert( QStringLiteral( "create_by_default" ), mCreateByDefault );
6727  return map;
6728 }
6729 
6731 {
6733  mSupportsNonFileBasedOutputs = map.value( QStringLiteral( "supports_non_file_outputs" ) ).toBool();
6734  mCreateByDefault = map.value( QStringLiteral( "create_by_default" ), QStringLiteral( "1" ) ).toBool();
6735  return true;
6736 }
6737 
6739 {
6740  switch ( outputType )
6741  {
6743  {
6744  // base class method is probably not much use
6745  if ( QgsProcessingParameterType *t = QgsApplication::processingRegistry()->parameterType( type() ) )
6746  {
6747  QString code = t->className() + QStringLiteral( "('%1', %2" )
6749  if ( mFlags & FlagOptional )
6750  code += QLatin1String( ", optional=True" );
6751 
6752  code += QStringLiteral( ", createByDefault=%1" ).arg( mCreateByDefault ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
6753 
6755  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
6756  return code;
6757  }
6758  break;
6759  }
6760  }
6761  // oh well, we tried
6762  return QString();
6763 }
6764 
6766 {
6767  return QObject::tr( "Default extension" ) + QStringLiteral( " (*." ) + defaultFileExtension() + ')';
6768 }
6769 
6771 {
6772  // sanitize name to avoid multiple . in the filename. E.g. when name() contain
6773  // backend command name having a "." inside as in case of grass commands
6774  const QRegularExpression rx( QStringLiteral( "[.]" ) );
6775  QString sanitizedName = name();
6776  sanitizedName.replace( rx, QStringLiteral( "_" ) );
6777 
6778  if ( defaultFileExtension().isEmpty() )
6779  {
6780  return QgsProcessingUtils::generateTempFilename( sanitizedName );
6781  }
6782  else
6783  {
6784  return QgsProcessingUtils::generateTempFilename( sanitizedName + '.' + defaultFileExtension() );
6785  }
6786 }
6787 
6788 bool QgsProcessingDestinationParameter::isSupportedOutputValue( const QVariant &value, QgsProcessingContext &context, QString &error ) const
6789 {
6790  if ( auto *lOriginalProvider = originalProvider() )
6791  return lOriginalProvider->isSupportedOutputValue( value, this, context, error );
6792  else if ( provider() )
6793  return provider()->isSupportedOutputValue( value, this, context, error );
6794 
6795  return true;
6796 }
6797 
6799 {
6800  return mCreateByDefault;
6801 }
6802 
6804 {
6805  mCreateByDefault = createByDefault;
6806 }
6807 
6808 QgsProcessingParameterVectorDestination::QgsProcessingParameterVectorDestination( const QString &name, const QString &description, QgsProcessing::SourceType type, const QVariant &defaultValue, bool optional, bool createByDefault )
6809  : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
6810  , mDataType( type )
6811 {
6812 
6813 }
6814 
6816 {
6817  return new QgsProcessingParameterVectorDestination( *this );
6818 }
6819 
6821 {
6822  QVariant var = input;
6823  if ( !var.isValid() )
6824  return mFlags & FlagOptional;
6825 
6826  if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
6827  {
6828  const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
6829  var = fromVar.sink;
6830  }
6831 
6832  if ( var.canConvert<QgsProperty>() )
6833  {
6834  const QgsProperty p = var.value< QgsProperty >();
6836  {
6837  var = p.staticValue();
6838  }
6839  else
6840  {
6841  return true;
6842  }
6843  }
6844 
6845  if ( var.type() != QVariant::String )
6846  return false;
6847 
6848  if ( var.toString().isEmpty() )
6849  return mFlags & FlagOptional;
6850 
6851  return true;
6852 }
6853 
6855 {
6856  if ( !value.isValid() )
6857  return QStringLiteral( "None" );
6858 
6859  if ( value.canConvert<QgsProperty>() )
6860  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
6861 
6862  if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
6863  {
6864  const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
6865  if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
6866  {
6867  return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
6868  }
6869  else
6870  {
6871  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
6872  }
6873  }
6874 
6875  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
6876 }
6877 
6879 {
6880  QString code = QStringLiteral( "##%1=" ).arg( mName );
6881  if ( mFlags & FlagOptional )
6882  code += QLatin1String( "optional " );
6883  code += QLatin1String( "vectorDestination " );
6884 
6885  switch ( mDataType )
6886  {
6888  code += QLatin1String( "point " );
6889  break;
6890 
6892  code += QLatin1String( "line " );
6893  break;
6894 
6896  code += QLatin1String( "polygon " );
6897  break;
6898 
6899  default:
6900  break;
6901  }
6902 
6903  code += mDefault.toString();
6904  return code.trimmed();
6905 }
6906 
6908 {
6909  return new QgsProcessingOutputVectorLayer( name(), description(), mDataType );
6910 }
6911 
6913 {
6914  if ( auto *lOriginalProvider = originalProvider() )
6915  {
6916  return lOriginalProvider->defaultVectorFileExtension( hasGeometry() );
6917  }
6918  else if ( QgsProcessingProvider *p = provider() )
6919  {
6920  return p->defaultVectorFileExtension( hasGeometry() );
6921  }
6922  else
6923  {
6924  if ( hasGeometry() )
6925  {
6927  }
6928  else
6929  {
6930  return QStringLiteral( "dbf" );
6931  }
6932  }
6933 }
6934 
6936 {
6937  switch ( outputType )
6938  {
6940  {
6941  QString code = QStringLiteral( "QgsProcessingParameterVectorDestination('%1', %2" )
6943  if ( mFlags & FlagOptional )
6944  code += QLatin1String( ", optional=True" );
6945 
6946  code += QStringLiteral( ", type=QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( mDataType ) );
6947 
6948  code += QStringLiteral( ", createByDefault=%1" ).arg( createByDefault() ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
6949 
6951  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
6952  return code;
6953  }
6954  }
6955  return QString();
6956 }
6957 
6959 {
6960  const QStringList exts = supportedOutputVectorLayerExtensions();
6961  QStringList filters;
6962  for ( const QString &ext : exts )
6963  {
6964  filters << QObject::tr( "%1 files (*.%2)" ).arg( ext.toUpper(), ext.toLower() );
6965  }
6966  return filters.join( QLatin1String( ";;" ) ) + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
6967 }
6968 
6970 {
6971  if ( auto *lOriginalProvider = originalProvider() )
6972  {
6973  if ( hasGeometry() )
6974  return lOriginalProvider->supportedOutputVectorLayerExtensions();
6975  else
6976  return lOriginalProvider->supportedOutputTableExtensions();
6977  }
6978  else if ( QgsProcessingProvider *p = provider() )
6979  {
6980  if ( hasGeometry() )
6981  return p->supportedOutputVectorLayerExtensions();
6982  else
6983  return p->supportedOutputTableExtensions();
6984  }
6985  else
6986  {
6988  }
6989 }
6990 
6992 {
6993  return mDataType;
6994 }
6995 
6997 {
6998  switch ( mDataType )
6999  {
7005  return true;
7006 
7014  return false;
7015  }
7016  return true;
7017 }
7018 
7020 {
7021  mDataType = type;
7022 }
7023 
7025 {
7027  map.insert( QStringLiteral( "data_type" ), mDataType );
7028  return map;
7029 }
7030 
7032 {
7034  mDataType = static_cast< QgsProcessing::SourceType >( map.value( QStringLiteral( "data_type" ) ).toInt() );
7035  return true;
7036 }
7037 
7038 QgsProcessingParameterVectorDestination *QgsProcessingParameterVectorDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7039 {
7041  QString def = definition;
7042  if ( def.startsWith( QLatin1String( "point" ), Qt::CaseInsensitive ) )
7043  {
7045  def = def.mid( 6 );
7046  }
7047  else if ( def.startsWith( QLatin1String( "line" ), Qt::CaseInsensitive ) )
7048  {
7050  def = def.mid( 5 );
7051  }
7052  else if ( def.startsWith( QLatin1String( "polygon" ), Qt::CaseInsensitive ) )
7053  {
7055  def = def.mid( 8 );
7056  }
7057 
7058  return new QgsProcessingParameterVectorDestination( name, description, type, definition, isOptional );
7059 }
7060 
7061 QgsProcessingParameterBand::QgsProcessingParameterBand( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayerParameterName, bool optional, bool allowMultiple )
7062  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
7063  , mParentLayerParameterName( parentLayerParameterName )
7064  , mAllowMultiple( allowMultiple )
7065 {
7066 
7067 }
7068 
7070 {
7071  return new QgsProcessingParameterBand( *this );
7072 }
7073 
7075 {
7076  if ( !input.isValid() )
7077  return mFlags & FlagOptional;
7078 
7079  if ( input.canConvert<QgsProperty>() )
7080  {
7081  return true;
7082  }
7083 
7084  if ( input.type() == QVariant::List || input.type() == QVariant::StringList )
7085  {
7086  if ( !mAllowMultiple )
7087  return false;
7088 
7089  if ( input.toList().isEmpty() && !( mFlags & FlagOptional ) )
7090  return false;
7091  }
7092  else
7093  {
7094  bool ok = false;
7095  const double res = input.toInt( &ok );
7096  Q_UNUSED( res )
7097  if ( !ok )
7098  return mFlags & FlagOptional;
7099  }
7100  return true;
7101 }
7102 
7104 {
7105  return mAllowMultiple;
7106 }
7107 
7109 {
7110  mAllowMultiple = allowMultiple;
7111 }
7112 
7114 {
7115  if ( !value.isValid() )
7116  return QStringLiteral( "None" );
7117 
7118  if ( value.canConvert<QgsProperty>() )
7119  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
7120 
7121  if ( value.type() == QVariant::List )
7122  {
7123  QStringList parts;
7124  const QVariantList values = value.toList();
7125  for ( auto it = values.constBegin(); it != values.constEnd(); ++it )
7126  {
7127  parts << QString::number( static_cast< int >( it->toDouble() ) );
7128  }
7129  return parts.join( ',' ).prepend( '[' ).append( ']' );
7130  }
7131  else if ( value.type() == QVariant::StringList )
7132  {
7133  QStringList parts;
7134  const QStringList values = value.toStringList();
7135  for ( auto it = values.constBegin(); it != values.constEnd(); ++it )
7136  {
7137  parts << QString::number( static_cast< int >( it->toDouble() ) );
7138  }
7139  return parts.join( ',' ).prepend( '[' ).append( ']' );
7140  }
7141 
7142  return value.toString();
7143 }
7144 
7146 {
7147  QString code = QStringLiteral( "##%1=" ).arg( mName );
7148  if ( mFlags & FlagOptional )
7149  code += QLatin1String( "optional " );
7150  code += QLatin1String( "band " );
7151 
7152  if ( mAllowMultiple )
7153  code += QLatin1String( "multiple " );
7154 
7155  code += mParentLayerParameterName + ' ';
7156 
7157  code += mDefault.toString();
7158  return code.trimmed();
7159 }
7160 
7162 {
7163  QStringList depends;
7164  if ( !mParentLayerParameterName.isEmpty() )
7165  depends << mParentLayerParameterName;
7166  return depends;
7167 }
7168 
7170 {
7171  switch ( outputType )
7172  {
7174  {
7175  QString code = QStringLiteral( "QgsProcessingParameterBand('%1', %2" )
7177  if ( mFlags & FlagOptional )
7178  code += QLatin1String( ", optional=True" );
7179 
7180  code += QStringLiteral( ", parentLayerParameterName='%1'" ).arg( mParentLayerParameterName );
7181  code += QStringLiteral( ", allowMultiple=%1" ).arg( mAllowMultiple ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
7182 
7184  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7185  return code;
7186  }
7187  }
7188  return QString();
7189 }
7190 
7192 {
7193  return mParentLayerParameterName;
7194 }
7195 
7196 void QgsProcessingParameterBand::setParentLayerParameterName( const QString &parentLayerParameterName )
7197 {
7198  mParentLayerParameterName = parentLayerParameterName;
7199 }
7200 
7202 {
7204  map.insert( QStringLiteral( "parent_layer" ), mParentLayerParameterName );
7205  map.insert( QStringLiteral( "allow_multiple" ), mAllowMultiple );
7206  return map;
7207 }
7208 
7209 bool QgsProcessingParameterBand::fromVariantMap( const QVariantMap &map )
7210 {
7212  mParentLayerParameterName = map.value( QStringLiteral( "parent_layer" ) ).toString();
7213  mAllowMultiple = map.value( QStringLiteral( "allow_multiple" ) ).toBool();
7214  return true;
7215 }
7216 
7217 QgsProcessingParameterBand *QgsProcessingParameterBand::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7218 {
7219  QString parent;
7220  QString def = definition;
7221  bool allowMultiple = false;
7222 
7223  if ( def.startsWith( QLatin1String( "multiple" ), Qt::CaseInsensitive ) )
7224  {
7225  allowMultiple = true;
7226  def = def.mid( 8 ).trimmed();
7227  }
7228 
7229  const QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*)$" ) );
7230  const QRegularExpressionMatch m = re.match( def );
7231  if ( m.hasMatch() )
7232  {
7233  parent = m.captured( 1 ).trimmed();
7234  def = m.captured( 2 );
7235  }
7236  else
7237  {
7238  parent = def;
7239  def.clear();
7240  }
7241 
7242  return new QgsProcessingParameterBand( name, description, def.isEmpty() ? QVariant() : def, parent, isOptional, allowMultiple );
7243 }
7244 
7245 //
7246 // QgsProcessingParameterDistance
7247 //
7248 
7249 QgsProcessingParameterDistance::QgsProcessingParameterDistance( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentParameterName, bool optional, double minValue, double maxValue )
7250  : QgsProcessingParameterNumber( name, description, Double, defaultValue, optional, minValue, maxValue )
7251  , mParentParameterName( parentParameterName )
7252 {
7253 
7254 }
7255 
7257 {
7258  return new QgsProcessingParameterDistance( *this );
7259 }
7260 
7262 {
7263  return typeName();
7264 }
7265 
7267 {
7268  QStringList depends;
7269  if ( !mParentParameterName.isEmpty() )
7270  depends << mParentParameterName;
7271  return depends;
7272 }
7273 
7275 {
7276  switch ( outputType )
7277  {
7279  {
7280  QString code = QStringLiteral( "QgsProcessingParameterDistance('%1', %2" )
7282  if ( mFlags & FlagOptional )
7283  code += QLatin1String( ", optional=True" );
7284 
7285  code += QStringLiteral( ", parentParameterName='%1'" ).arg( mParentParameterName );
7286 
7287  if ( minimum() != std::numeric_limits<double>::lowest() + 1 )
7288  code += QStringLiteral( ", minValue=%1" ).arg( minimum() );
7289  if ( maximum() != std::numeric_limits<double>::max() )
7290  code += QStringLiteral( ", maxValue=%1" ).arg( maximum() );
7292  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7293  return code;
7294  }
7295  }
7296  return QString();
7297 }
7298 
7300 {
7301  return mParentParameterName;
7302 }
7303 
7304 void QgsProcessingParameterDistance::setParentParameterName( const QString &parentParameterName )
7305 {
7306  mParentParameterName = parentParameterName;
7307 }
7308 
7310 {
7311  QVariantMap map = QgsProcessingParameterNumber::toVariantMap();
7312  map.insert( QStringLiteral( "parent" ), mParentParameterName );
7313  map.insert( QStringLiteral( "default_unit" ), static_cast< int >( mDefaultUnit ) );
7314  return map;
7315 }
7316 
7318 {
7320  mParentParameterName = map.value( QStringLiteral( "parent" ) ).toString();
7321  mDefaultUnit = static_cast< QgsUnitTypes::DistanceUnit>( map.value( QStringLiteral( "default_unit" ), QgsUnitTypes::DistanceUnknownUnit ).toInt() );
7322  return true;
7323 }
7324 
7325 
7326 //
7327 // QgsProcessingParameterDuration
7328 //
7329 
7330 QgsProcessingParameterDuration::QgsProcessingParameterDuration( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, double minValue, double maxValue )
7331  : QgsProcessingParameterNumber( name, description, Double, defaultValue, optional, minValue, maxValue )
7332 {
7333 }
7334 
7336 {
7337  return new QgsProcessingParameterDuration( *this );
7338 }
7339 
7341 {
7342  return typeName();
7343 }
7344 
7346 {
7347  switch ( outputType )
7348  {
7350  {
7351  QString code = QStringLiteral( "QgsProcessingParameterDuration('%1', %2" )
7353  if ( mFlags & FlagOptional )
7354  code += QLatin1String( ", optional=True" );
7355 
7356  if ( minimum() != std::numeric_limits<double>::lowest() + 1 )
7357  code += QStringLiteral( ", minValue=%1" ).arg( minimum() );
7358  if ( maximum() != std::numeric_limits<double>::max() )
7359  code += QStringLiteral( ", maxValue=%1" ).arg( maximum() );
7361  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7362  return code;
7363  }
7364  }
7365  return QString();
7366 }
7367 
7369 {
7370  QVariantMap map = QgsProcessingParameterNumber::toVariantMap();
7371  map.insert( QStringLiteral( "default_unit" ), static_cast< int >( mDefaultUnit ) );
7372  return map;
7373 }
7374 
7376 {
7378  mDefaultUnit = static_cast< QgsUnitTypes::TemporalUnit>( map.value( QStringLiteral( "default_unit" ), QgsUnitTypes::TemporalDays ).toInt() );
7379  return true;
7380 }
7381 
7382 
7383 //
7384 // QgsProcessingParameterScale
7385 //
7386 
7387 QgsProcessingParameterScale::QgsProcessingParameterScale( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
7388  : QgsProcessingParameterNumber( name, description, Double, defaultValue, optional )
7389 {
7390 
7391 }
7392 
7394 {
7395  return new QgsProcessingParameterScale( *this );
7396 }
7397 
7399 {
7400  return typeName();
7401 }
7402 
7404 {
7405  switch ( outputType )
7406  {
7408  {
7409  QString code = QStringLiteral( "QgsProcessingParameterScale('%1', %2" )
7411  if ( mFlags & FlagOptional )
7412  code += QLatin1String( ", optional=True" );
7414  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7415  return code;
7416  }
7417  }
7418  return QString();
7419 }
7420 
7421 QgsProcessingParameterScale *QgsProcessingParameterScale::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7422 {
7423  return new QgsProcessingParameterScale( name, description, definition.isEmpty() ? QVariant()
7424  : ( definition.toLower().trimmed() == QLatin1String( "none" ) ? QVariant() : definition ), isOptional );
7425 }
7426 
7427 
7428 //
7429 // QgsProcessingParameterLayout
7430 //
7431 
7432 QgsProcessingParameterLayout::QgsProcessingParameterLayout( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
7433  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
7434 {}
7435 
7437 {
7438  return new QgsProcessingParameterLayout( *this );
7439 }
7440 
7442 {
7443  if ( !value.isValid() || value.isNull() )
7444  return QStringLiteral( "None" );
7445 
7446  if ( value.canConvert<QgsProperty>() )
7447  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
7448 
7449  const QString s = value.toString();
7451 }
7452 
7454 {
7455  QString code = QStringLiteral( "##%1=" ).arg( mName );
7456  if ( mFlags & FlagOptional )
7457  code += QLatin1String( "optional " );
7458  code += QLatin1String( "layout " );
7459 
7460  code += mDefault.toString();
7461  return code.trimmed();
7462 }
7463 
7465 {
7466  switch ( outputType )
7467  {
7469  {
7470  QString code = QStringLiteral( "QgsProcessingParameterLayout('%1', %2" )
7472  if ( mFlags & FlagOptional )
7473  code += QLatin1String( ", optional=True" );
7475  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7476  return code;
7477  }
7478  }
7479  return QString();
7480 }
7481 
7482 QgsProcessingParameterLayout *QgsProcessingParameterLayout::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7483 {
7484  QString def = definition;
7485 
7486  if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
7487  def = def.mid( 1 );
7488  if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
7489  def.chop( 1 );
7490 
7491  QVariant defaultValue = def;
7492  if ( def == QLatin1String( "None" ) )
7493  defaultValue = QVariant();
7494 
7495  return new QgsProcessingParameterLayout( name, description, defaultValue, isOptional );
7496 }
7497 
7498 
7499 //
7500 // QString mParentLayerParameterName;
7501 //
7502 
7503 QgsProcessingParameterLayoutItem::QgsProcessingParameterLayoutItem( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayoutParameterName, int itemType, bool optional )
7504  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
7505  , mParentLayoutParameterName( parentLayoutParameterName )
7506  , mItemType( itemType )
7507 {
7508 
7509 }
7510 
7512 {
7513  return new QgsProcessingParameterLayoutItem( *this );
7514 }
7515 
7517 {
7518  if ( !value.isValid() || value.isNull() )
7519  return QStringLiteral( "None" );
7520 
7521  if ( value.canConvert<QgsProperty>() )
7522  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
7523 
7524  const QString s = value.toString();
7526 }
7527 
7529 {
7530  QString code = QStringLiteral( "##%1=" ).arg( mName );
7531  if ( mFlags & FlagOptional )
7532  code += QLatin1String( "optional " );
7533  code += QLatin1String( "layoutitem " );
7534  if ( mItemType >= 0 )
7535  code += QString::number( mItemType ) + ' ';
7536 
7537  code += mParentLayoutParameterName + ' ';
7538 
7539  code += mDefault.toString();
7540  return code.trimmed();
7541 }
7542 
7544 {
7545  switch ( outputType )
7546  {
7548  {
7549  QString code = QStringLiteral( "QgsProcessingParameterLayoutItem('%1', %2" )
7551  if ( mFlags & FlagOptional )
7552  code += QLatin1String( ", optional=True" );
7553 
7554  if ( mItemType >= 0 )
7555  code += QStringLiteral( ", itemType=%1" ).arg( mItemType );
7556 
7557  code += QStringLiteral( ", parentLayoutParameterName='%1'" ).arg( mParentLayoutParameterName );
7558 
7560  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7561  return code;
7562  }
7563  }
7564  return QString();
7565 }
7566 
7568 {
7570  map.insert( QStringLiteral( "parent_layout" ), mParentLayoutParameterName );
7571  map.insert( QStringLiteral( "item_type" ), mItemType );
7572  return map;
7573 }
7574 
7576 {
7578  mParentLayoutParameterName = map.value( QStringLiteral( "parent_layout" ) ).toString();
7579  mItemType = map.value( QStringLiteral( "item_type" ) ).toInt();
7580  return true;
7581 }
7582 
7584 {
7585  QStringList depends;
7586  if ( !mParentLayoutParameterName.isEmpty() )
7587  depends << mParentLayoutParameterName;
7588  return depends;
7589 }
7590 
7591 QgsProcessingParameterLayoutItem *QgsProcessingParameterLayoutItem::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7592 {
7593  QString parent;
7594  QString def = definition;
7595  int itemType = -1;
7596  const QRegularExpression re( QStringLiteral( "(\\d+)?\\s*(.*?)\\s+(.*)$" ) );
7597  const QRegularExpressionMatch m = re.match( def );
7598  if ( m.hasMatch() )
7599  {
7600  itemType = m.captured( 1 ).trimmed().isEmpty() ? -1 : m.captured( 1 ).trimmed().toInt();
7601  parent = m.captured( 2 ).trimmed().isEmpty() ? m.captured( 3 ).trimmed() : m.captured( 2 ).trimmed();
7602  def = !m.captured( 2 ).trimmed().isEmpty() ? m.captured( 3 ) : QString();
7603  }
7604  else
7605  {
7606  parent = def;
7607  def.clear();
7608  }
7609 
7610  return new QgsProcessingParameterLayoutItem( name, description, def.isEmpty() ? QVariant() : def, parent, itemType, isOptional );
7611 }
7612 
7614 {
7615  return mParentLayoutParameterName;
7616 }
7617 
7619 {
7620  mParentLayoutParameterName = name;
7621 }
7622 
7624 {
7625  return mItemType;
7626 }
7627 
7629 {
7630  mItemType = type;
7631 }
7632 
7633 //
7634 // QgsProcessingParameterColor
7635 //
7636 
7637 QgsProcessingParameterColor::QgsProcessingParameterColor( const QString &name, const QString &description, const QVariant &defaultValue, bool opacityEnabled, bool optional )
7638  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
7639  , mAllowOpacity( opacityEnabled )
7640 {
7641 
7642 }
7643 
7645 {
7646  return new QgsProcessingParameterColor( *this );
7647 }
7648 
7650 {
7651  if ( !value.isValid() || value.isNull() )
7652  return QStringLiteral( "None" );
7653 
7654  if ( value.canConvert<QgsProperty>() )
7655  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
7656 
7657  if ( value.canConvert< QColor >() && !value.value< QColor >().isValid() )
7658  return QStringLiteral( "QColor()" );
7659 
7660  if ( value.canConvert< QColor >() )
7661  {
7662  const QColor c = value.value< QColor >();
7663  if ( !mAllowOpacity || c.alpha() == 255 )
7664  return QStringLiteral( "QColor(%1, %2, %3)" ).arg( c.red() ).arg( c.green() ).arg( c.blue() );
7665  else
7666  return QStringLiteral( "QColor(%1, %2, %3, %4)" ).arg( c.red() ).arg( c.green() ).arg( c.blue() ).arg( c.alpha() );
7667  }
7668 
7669  const QString s = value.toString();
7671 }
7672 
7674 {
7675  QString code = QStringLiteral( "##%1=" ).arg( mName );
7676  if ( mFlags & FlagOptional )
7677  code += QLatin1String( "optional " );
7678  code += QLatin1String( "color " );
7679 
7680  if ( mAllowOpacity )
7681  code += QLatin1String( "withopacity " );
7682 
7683  code += mDefault.toString();
7684  return code.trimmed();
7685 }
7686 
7688 {
7689  switch ( outputType )
7690  {
7692  {
7693  QString code = QStringLiteral( "QgsProcessingParameterColor('%1', %2" )
7695  if ( mFlags & FlagOptional )
7696  code += QLatin1String( ", optional=True" );
7697 
7698  code += QStringLiteral( ", opacityEnabled=%1" ).arg( mAllowOpacity ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
7699 
7701  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7702  return code;
7703  }
7704  }
7705  return QString();
7706 }
7707 
7709 {
7710  if ( !input.isValid() && ( mDefault.isValid() && ( !mDefault.toString().isEmpty() || mDefault.value< QColor >().isValid() ) ) )
7711  return true;
7712 
7713  if ( !input.isValid() )
7714  return mFlags & FlagOptional;
7715 
7716  if ( input.type() == QVariant::Color )
7717  {
7718  return true;
7719  }
7720  else if ( input.canConvert<QgsProperty>() )
7721  {
7722  return true;
7723  }
7724 
7725  if ( input.type() != QVariant::String || input.toString().isEmpty() )
7726  return mFlags & FlagOptional;
7727 
7728  bool containsAlpha = false;
7729  return QgsSymbolLayerUtils::parseColorWithAlpha( input.toString(), containsAlpha ).isValid();
7730 }
7731 
7733 {
7735  map.insert( QStringLiteral( "opacityEnabled" ), mAllowOpacity );
7736  return map;
7737 }
7738 
7739 bool QgsProcessingParameterColor::fromVariantMap( const QVariantMap &map )
7740 {
7742  mAllowOpacity = map.value( QStringLiteral( "opacityEnabled" ) ).toBool();
7743  return true;
7744 }
7745 
7747 {
7748  return mAllowOpacity;
7749 }
7750 
7752 {
7753  mAllowOpacity = enabled;
7754 }
7755 
7756 QgsProcessingParameterColor *QgsProcessingParameterColor::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7757 {
7758  QString def = definition;
7759 
7760  bool allowOpacity = false;
7761  if ( def.startsWith( QLatin1String( "withopacity" ), Qt::CaseInsensitive ) )
7762  {
7763  allowOpacity = true;
7764  def = def.mid( 12 );
7765  }
7766 
7767  if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
7768  def = def.mid( 1 );
7769  if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
7770  def.chop( 1 );
7771 
7772  QVariant defaultValue = def;
7773  if ( def == QLatin1String( "None" ) )
7774  defaultValue = QVariant();
7775 
7776  return new QgsProcessingParameterColor( name, description, defaultValue, allowOpacity, isOptional );
7777 }
7778 
7779 //
7780 // QgsProcessingParameterCoordinateOperation
7781 //
7782 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 )
7783  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
7784  , mSourceParameterName( sourceCrsParameterName )
7785  , mDestParameterName( destinationCrsParameterName )
7786  , mSourceCrs( staticSourceCrs )
7787  , mDestCrs( staticDestinationCrs )
7788 {
7789 
7790 }
7791 
7793 {
7794  return new QgsProcessingParameterCoordinateOperation( * this );
7795 }
7796 
7798 {
7799  if ( !value.isValid() || value.isNull() )
7800  return QStringLiteral( "None" );
7801 
7802  if ( value.canConvert<QgsCoordinateReferenceSystem>() )
7803  {
7804  if ( !value.value< QgsCoordinateReferenceSystem >().isValid() )
7805  return QStringLiteral( "QgsCoordinateReferenceSystem()" );
7806  else
7807  return QStringLiteral( "QgsCoordinateReferenceSystem('%1')" ).arg( value.value< QgsCoordinateReferenceSystem >().authid() );
7808  }
7809 
7810  if ( value.canConvert<QgsProperty>() )
7811  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
7812 
7813  QVariantMap p;
7814  p.insert( name(), value );
7815  QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
7816  if ( layer )
7818 
7819  const QString s = value.toString();
7821 }
7822 
7824 {
7825  QString code = QStringLiteral( "##%1=" ).arg( mName );
7826  if ( mFlags & FlagOptional )
7827  code += QLatin1String( "optional " );
7828  code += QLatin1String( "coordinateoperation " );
7829 
7830  code += mDefault.toString();
7831  return code.trimmed();
7832 }
7833 
7835 {
7836  switch ( outputType )
7837  {
7839  {
7841  QString code = QStringLiteral( "QgsProcessingParameterCoordinateOperation('%1', %2" )
7843  if ( mFlags & FlagOptional )
7844  code += QLatin1String( ", optional=True" );
7845  if ( !mSourceParameterName.isEmpty() )
7846  code += QStringLiteral( ", sourceCrsParameterName=%1" ).arg( valueAsPythonString( mSourceParameterName, c ) );
7847  if ( !mDestParameterName.isEmpty() )
7848  code += QStringLiteral( ", destinationCrsParameterName=%1" ).arg( valueAsPythonString( mDestParameterName, c ) );
7849 
7850  if ( mSourceCrs.isValid() )
7851  code += QStringLiteral( ", staticSourceCrs=%1" ).arg( valueAsPythonString( mSourceCrs, c ) );
7852  if ( mDestCrs.isValid() )
7853  code += QStringLiteral( ", staticDestinationCrs=%1" ).arg( valueAsPythonString( mDestCrs, c ) );
7854 
7855  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7856  return code;
7857  }
7858  }
7859  return QString();
7860 }
7861 
7863 {
7864  QStringList res;
7865  if ( !mSourceParameterName.isEmpty() )
7866  res << mSourceParameterName;
7867  if ( !mDestParameterName.isEmpty() )
7868  res << mDestParameterName;
7869  return res;
7870 }
7871 
7873 {
7875  map.insert( QStringLiteral( "source_crs_parameter_name" ), mSourceParameterName );
7876  map.insert( QStringLiteral( "dest_crs_parameter_name" ), mDestParameterName );
7877  map.insert( QStringLiteral( "static_source_crs" ), mSourceCrs );
7878  map.insert( QStringLiteral( "static_dest_crs" ), mDestCrs );
7879  return map;
7880 }
7881 
7883 {
7885  mSourceParameterName = map.value( QStringLiteral( "source_crs_parameter_name" ) ).toString();
7886  mDestParameterName = map.value( QStringLiteral( "dest_crs_parameter_name" ) ).toString();
7887  mSourceCrs = map.value( QStringLiteral( "static_source_crs" ) );
7888  mDestCrs = map.value( QStringLiteral( "static_dest_crs" ) );
7889  return true;
7890 }
7891 
7892 QgsProcessingParameterCoordinateOperation *QgsProcessingParameterCoordinateOperation::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7893 {
7894  QString def = definition;
7895 
7896  if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
7897  def = def.mid( 1 );
7898  if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
7899  def.chop( 1 );
7900 
7901  QVariant defaultValue = def;
7902  if ( def == QLatin1String( "None" ) )
7903  defaultValue = QVariant();
7904 
7905  return new QgsProcessingParameterCoordinateOperation( name, description, defaultValue, QString(), QString(), QVariant(), QVariant(), isOptional );
7906 }
7907 
7908 
7909 //
7910 // QgsProcessingParameterMapTheme
7911 //
7912 
7913 QgsProcessingParameterMapTheme::QgsProcessingParameterMapTheme( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
7914  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
7915 {
7916 
7917 }
7918 
7919 
7921 {
7922  return new QgsProcessingParameterMapTheme( *this );
7923 }
7924 
7926 {
7927  if ( !input.isValid() && !mDefault.isValid() )
7928  return mFlags & FlagOptional;
7929 
7930  if ( ( input.type() == QVariant::String && input.toString().isEmpty() )
7931  || ( !input.isValid() && mDefault.type() == QVariant::String && mDefault.toString().isEmpty() ) )
7932  return mFlags & FlagOptional;
7933 
7934  return true;
7935 }
7936 
7938 {
7939  if ( !value.isValid() )
7940  return QStringLiteral( "None" );
7941 
7942  if ( value.canConvert<QgsProperty>() )
7943  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
7944 
7945  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
7946 }
7947 
7949 {
7950  QString code = QStringLiteral( "##%1=" ).arg( mName );
7951  if ( mFlags & FlagOptional )
7952  code += QLatin1String( "optional " );
7953  code += QLatin1String( "maptheme " );
7954 
7955  code += mDefault.toString();
7956  return code.trimmed();
7957 }
7958 
7960 {
7961  switch ( outputType )
7962  {
7964  {
7965  QString code = QStringLiteral( "QgsProcessingParameterMapTheme('%1', %2" )
7967  if ( mFlags & FlagOptional )
7968  code += QLatin1String( ", optional=True" );
7969 
7971  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7972 
7973  return code;
7974  }
7975  }
7976  return QString();
7977 }
7978 
7980 {
7982  return map;
7983 }
7984 
7986 {
7988  return true;
7989 }
7990 
7991 QgsProcessingParameterMapTheme *QgsProcessingParameterMapTheme::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7992 {
7993  QString def = definition;
7994  if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
7995  def = def.mid( 1 );
7996  if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
7997  def.chop( 1 );
7998 
7999  QVariant defaultValue = def;
8000 
8001  if ( defaultValue == QLatin1String( "None" ) || defaultValue.toString().isEmpty() )
8002  defaultValue = QVariant();
8003 
8004  return new QgsProcessingParameterMapTheme( name, description, defaultValue, isOptional );
8005 }
8006 
8007 
8008 //
8009 // QgsProcessingParameterDateTime
8010 //
8011 
8012 QgsProcessingParameterDateTime::QgsProcessingParameterDateTime( const QString &name, const QString &description, Type type, const QVariant &defaultValue, bool optional, const QDateTime &minValue, const QDateTime &maxValue )
8013  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
8014  , mMin( minValue )
8015  , mMax( maxValue )
8016  , mDataType( type )
8017 {
8018  if ( mMin.isValid() && mMax.isValid() && mMin >= mMax )
8019  {
8020  QgsMessageLog::logMessage( QObject::tr( "Invalid datetime parameter \"%1\": min value %2 is >= max value %3!" ).arg( name, mMin.toString(), mMax.toString() ), QObject::tr( "Processing" ) );
8021  }
8022 }
8023 
8025 {
8026  return new QgsProcessingParameterDateTime( *this );
8027 }
8028 
8030 {
8031  QVariant input = value;
8032  if ( !input.isValid() )
8033  {
8034  if ( !defaultValue().isValid() )
8035  return mFlags & FlagOptional;
8036 
8037  input = defaultValue();
8038  }
8039 
8040  if ( input.canConvert<QgsProperty>() )
8041  {
8042  return true;
8043  }
8044 
8045  if ( input.type() != QVariant::DateTime && input.type() != QVariant::Date && input.type() != QVariant::Time && input.type() != QVariant::String )
8046  return false;
8047 
8048  if ( ( input.type() == QVariant::DateTime || input.type() == QVariant::Date ) && mDataType == Time )
8049  return false;
8050 
8051  if ( input.type() == QVariant::String )
8052  {
8053  const QString s = input.toString();
8054  if ( s.isEmpty() )
8055  return mFlags & FlagOptional;
8056 
8057  input = QDateTime::fromString( s, Qt::ISODate );
8058  if ( mDataType == Time )
8059  {
8060  if ( !input.toDateTime().isValid() )
8061  input = QTime::fromString( s );
8062  else
8063  input = input.toDateTime().time();
8064  }
8065  }
8066 
8067  if ( mDataType != Time )
8068  {
8069  const QDateTime res = input.toDateTime();
8070  return res.isValid() && ( res >= mMin || !mMin.isValid() ) && ( res <= mMax || !mMax.isValid() );
8071  }
8072  else
8073  {
8074  const QTime res = input.toTime();
8075  return res.isValid() && ( res >= mMin.time() || !mMin.isValid() ) && ( res <= mMax.time() || !mMax.isValid() );
8076  }
8077 }
8078 
8080 {
8081  if ( !value.isValid() )
8082  return QStringLiteral( "None" );
8083 
8084  if ( value.canConvert<QgsProperty>() )
8085  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
8086 
8087  if ( value.type() == QVariant::DateTime )
8088  {
8089  const QDateTime dt = value.toDateTime();
8090  if ( !dt.isValid() )
8091  return QStringLiteral( "QDateTime()" );
8092  else
8093  return QStringLiteral( "QDateTime(QDate(%1, %2, %3), QTime(%4, %5, %6))" ).arg( dt.date().year() )
8094  .arg( dt.date().month() )
8095  .arg( dt.date().day() )
8096  .arg( dt.time().hour() )
8097  .arg( dt.time().minute() )
8098  .arg( dt.time().second() );
8099  }
8100  else if ( value.type() == QVariant::Date )
8101  {
8102  const QDate dt = value.toDate();
8103  if ( !dt.isValid() )
8104  return QStringLiteral( "QDate()" );
8105  else
8106  return QStringLiteral( "QDate(%1, %2, %3)" ).arg( dt.year() )
8107  .arg( dt.month() )
8108  .arg( dt.day() );
8109  }
8110  else if ( value.type() == QVariant::Time )
8111  {
8112  const QTime dt = value.toTime();
8113  if ( !dt.isValid() )
8114  return QStringLiteral( "QTime()" );
8115  else
8116  return QStringLiteral( "QTime(%4, %5, %6)" )
8117  .arg( dt.hour() )
8118  .arg( dt.minute() )
8119  .arg( dt.second() );
8120  }
8121  return value.toString();
8122 }
8123 
8125 {
8127  QStringList parts;
8128  if ( mMin.isValid() )
8129  parts << QObject::tr( "Minimum value: %1" ).arg( mMin.toString( Qt::ISODate ) );
8130  if ( mMax.isValid() )
8131  parts << QObject::tr( "Maximum value: %1" ).arg( mMax.toString( Qt::ISODate ) );
8132  if ( mDefault.isValid() )
8133  parts << QObject::tr( "Default value: %1" ).arg( mDataType == DateTime ? mDefault.toDateTime().toString( Qt::ISODate ) :
8134  ( mDataType == Date ? mDefault.toDate().toString( Qt::ISODate ) : mDefault.toTime( ).toString() ) );
8135  const QString extra = parts.join( QLatin1String( "<br />" ) );
8136  if ( !extra.isEmpty() )
8137  text += QStringLiteral( "<p>%1</p>" ).arg( extra );
8138  return text;
8139 }
8140 
8142 {
8143  switch ( outputType )
8144  {
8146  {
8147  QString code = QStringLiteral( "QgsProcessingParameterDateTime('%1', %2" )
8149  if ( mFlags & FlagOptional )
8150  code += QLatin1String( ", optional=True" );
8151 
8152  code += QStringLiteral( ", type=%1" ).arg( mDataType == DateTime ? QStringLiteral( "QgsProcessingParameterDateTime.DateTime" )
8153  : mDataType == Date ? QStringLiteral( "QgsProcessingParameterDateTime.Date" )
8154  : QStringLiteral( "QgsProcessingParameterDateTime.Time" ) );
8155 
8157  if ( mMin.isValid() )
8158  code += QStringLiteral( ", minValue=%1" ).arg( valueAsPythonString( mMin, c ) );
8159  if ( mMax.isValid() )
8160  code += QStringLiteral( ", maxValue=%1" ).arg( valueAsPythonString( mMax, c ) );
8161  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
8162  return code;
8163  }
8164  }
8165  return QString();
8166 }
8167 
8169 {
8170  return mMin;
8171 }
8172 
8174 {
8175  mMin = min;
8176 }
8177 
8179 {
8180  return mMax;
8181 }
8182 
8184 {
8185  mMax = max;
8186 }
8187 
8189 {
8190  return mDataType;
8191 }
8192 
8194 {
8195  mDataType = dataType;
8196 }
8197 
8199 {
8201  map.insert( QStringLiteral( "min" ), mMin );
8202  map.insert( QStringLiteral( "max" ), mMax );
8203  map.insert( QStringLiteral( "data_type" ), mDataType );
8204  return map;
8205 }
8206 
8208 {
8210  mMin = map.value( QStringLiteral( "min" ) ).toDateTime();
8211  mMax = map.value( QStringLiteral( "max" ) ).toDateTime();
8212  mDataType = static_cast< Type >( map.value( QStringLiteral( "data_type" ) ).toInt() );
8213  return true;
8214 }
8215 
8216 QgsProcessingParameterDateTime *QgsProcessingParameterDateTime::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
8217 {
8218  return new QgsProcessingParameterDateTime( name, description, DateTime, definition.isEmpty() ? QVariant()
8219  : ( definition.toLower().trimmed() == QLatin1String( "none" ) ? QVariant() : definition ), isOptional );
8220 }
8221 
8222 
8223 
8224 //
8225 // QgsProcessingParameterProviderConnection
8226 //
8227 
8228 QgsProcessingParameterProviderConnection::QgsProcessingParameterProviderConnection( const QString &name, const QString &description, const QString &provider, const QVariant &defaultValue, bool optional )
8229  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
8230  , mProviderId( provider )
8231 {
8232 
8233 }
8234 
8235 
8237 {
8238  return new QgsProcessingParameterProviderConnection( *this );
8239 }
8240 
8242 {
8243  if ( !input.isValid() && !mDefault.isValid() )
8244  return mFlags & FlagOptional;
8245 
8246  if ( ( input.type() == QVariant::String && input.toString().isEmpty() )
8247  || ( !input.isValid() && mDefault.type() == QVariant::String && mDefault.toString().isEmpty() ) )
8248  return mFlags & FlagOptional;
8249 
8250  return true;
8251 }
8252 
8254 {
8255  if ( !value.isValid() )
8256  return QStringLiteral( "None" );
8257 
8258  if ( value.canConvert<QgsProperty>() )
8259  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
8260 
8261  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
8262 }
8263 
8265 {
8266  QString code = QStringLiteral( "##%1=" ).arg( mName );
8267  if ( mFlags & FlagOptional )
8268  code += QLatin1String( "optional " );
8269  code += QLatin1String( "providerconnection " );
8270  code += mProviderId + ' ';
8271 
8272  code += mDefault.toString();
8273  return code.trimmed();
8274 }
8275 
8277 {
8278  switch ( outputType )
8279  {
8281  {
8282  QString code = QStringLiteral( "QgsProcessingParameterProviderConnection('%1', %2, '%3'" )
8283  .arg( name(), QgsProcessingUtils::stringToPythonLiteral( description() ), mProviderId );
8284  if ( mFlags & FlagOptional )
8285  code += QLatin1String( ", optional=True" );
8286 
8288  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
8289 
8290  return code;
8291  }
8292  }
8293  return QString();
8294 }
8295 
8297 {
8299  map.insert( QStringLiteral( "provider" ), mProviderId );
8300  return map;
8301 }
8302 
8304 {
8306  mProviderId = map.value( QStringLiteral( "provider" ) ).toString();
8307  return true;
8308 }
8309 
8310 QgsProcessingParameterProviderConnection *QgsProcessingParameterProviderConnection::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
8311 {
8312  QString def = definition;
8313  QString provider;
8314  if ( def.contains( ' ' ) )
8315  {
8316  provider = def.left( def.indexOf( ' ' ) );
8317  def = def.mid( def.indexOf( ' ' ) + 1 );
8318  }
8319  else
8320  {
8321  provider = def;
8322  def.clear();
8323  }
8324 
8325  if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
8326  def = def.mid( 1 );
8327  if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
8328  def.chop( 1 );
8329 
8330  QVariant defaultValue = def;
8331 
8332  if ( defaultValue == QLatin1String( "None" ) || defaultValue.toString().isEmpty() )
8333  defaultValue = QVariant();
8334 
8336 }
8337 
8338 
8339 //
8340 // QgsProcessingParameterDatabaseSchema
8341 //
8342 
8343 QgsProcessingParameterDatabaseSchema::QgsProcessingParameterDatabaseSchema( const QString &name, const QString &description, const QString &parentLayerParameterName, const QVariant &defaultValue, bool optional )
8344  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
8345  , mParentConnectionParameterName( parentLayerParameterName )
8346 {
8347 
8348 }
8349 
8350 
8352 {
8353  return new QgsProcessingParameterDatabaseSchema( *this );
8354 }
8355 
8357 {
8358  if ( !input.isValid() && !mDefault.isValid() )
8359  return mFlags & FlagOptional;
8360 
8361  if ( ( input.type() == QVariant::String && input.toString().isEmpty() )
8362  || ( !input.isValid() && mDefault.type() == QVariant::String && mDefault.toString().isEmpty() ) )
8363  return mFlags & FlagOptional;
8364 
8365  return true;
8366 }
8367 
8369 {
8370  if ( !value.isValid() )
8371  return QStringLiteral( "None" );
8372 
8373  if ( value.canConvert<QgsProperty>() )
8374  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
8375 
8376  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
8377 }
8378 
8380 {
8381  QString code = QStringLiteral( "##%1=" ).arg( mName );
8382  if ( mFlags & FlagOptional )
8383  code += QLatin1String( "optional " );
8384  code += QLatin1String( "databaseschema " );
8385 
8386  code += mParentConnectionParameterName + ' ';
8387 
8388  code += mDefault.toString();
8389  return code.trimmed();
8390 }
8391 
8393 {
8394  switch ( outputType )
8395  {
8397  {
8398  QString code = QStringLiteral( "QgsProcessingParameterDatabaseSchema('%1', %2" )
8400  if ( mFlags & FlagOptional )
8401  code += QLatin1String( ", optional=True" );
8402 
8403  code += QStringLiteral( ", connectionParameterName='%1'" ).arg( mParentConnectionParameterName );
8405  code += QStringLiteral( ", defaultValue=%1" ).arg( valueAsPythonString( mDefault, c ) );
8406 
8407  code += ')';
8408 
8409  return code;
8410  }
8411  }
8412  return QString();
8413 }
8414 
8416 {
8417  QStringList depends;
8418  if ( !mParentConnectionParameterName.isEmpty() )
8419  depends << mParentConnectionParameterName;
8420  return depends;
8421 }
8422 
8424 {
8425  return mParentConnectionParameterName;
8426 }
8427 
8429 {
8430  mParentConnectionParameterName = name;
8431 }
8432 
8434 {
8436  map.insert( QStringLiteral( "mParentConnectionParameterName" ), mParentConnectionParameterName );
8437  return map;
8438 }
8439 
8441 {
8443  mParentConnectionParameterName = map.value( QStringLiteral( "mParentConnectionParameterName" ) ).toString();
8444  return true;
8445 }
8446 
8447 QgsProcessingParameterDatabaseSchema *QgsProcessingParameterDatabaseSchema::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
8448 {
8449  QString parent;
8450  QString def = definition;
8451 
8452  const QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*)$" ) );
8453  const QRegularExpressionMatch m = re.match( def );
8454  if ( m.hasMatch() )
8455  {
8456  parent = m.captured( 1 ).trimmed();
8457  def = m.captured( 2 );
8458  }
8459  else
8460  {
8461  parent = def;
8462  def.clear();
8463  }
8464 
8465  return new QgsProcessingParameterDatabaseSchema( name, description, parent, def.isEmpty() ? QVariant() : def, isOptional );
8466 }
8467 
8468 //
8469 // QgsProcessingParameterDatabaseTable
8470 //
8471 
8472 QgsProcessingParameterDatabaseTable::QgsProcessingParameterDatabaseTable( const QString &name, const QString &description,
8473  const QString &connectionParameterName,
8474  const QString &schemaParameterName,
8475  const QVariant &defaultValue, bool optional, bool allowNewTableNames )
8476  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
8477  , mParentConnectionParameterName( connectionParameterName )
8478  , mParentSchemaParameterName( schemaParameterName )
8479  , mAllowNewTableNames( allowNewTableNames )
8480 {
8481 
8482 }
8483 
8484 
8486 {
8487  return new QgsProcessingParameterDatabaseTable( *this );
8488 }
8489 
8491 {
8492  if ( !input.isValid() && !mDefault.isValid() )
8493  return mFlags & FlagOptional;
8494 
8495  if ( ( input.type() == QVariant::String && input.toString().isEmpty() )
8496  || ( !input.isValid() && mDefault.type() == QVariant::String && mDefault.toString().isEmpty() ) )
8497  return mFlags & FlagOptional;
8498 
8499  return true;
8500 }
8501 
8503 {
8504  if ( !value.isValid() )
8505  return QStringLiteral( "None" );
8506 
8507  if ( value.canConvert<QgsProperty>() )
8508  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
8509 
8510  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
8511 }
8512 
8514 {
8515  QString code = QStringLiteral( "##%1=" ).arg( mName );
8516  if ( mFlags & FlagOptional )
8517  code += QLatin1String( "optional " );
8518  code += QLatin1String( "databasetable " );
8519 
8520  code += ( mParentConnectionParameterName.isEmpty() ? QStringLiteral( "none" ) : mParentConnectionParameterName ) + ' ';
8521  code += ( mParentSchemaParameterName.isEmpty() ? QStringLiteral( "none" ) : mParentSchemaParameterName ) + ' ';
8522 
8523  code += mDefault.toString();
8524  return code.trimmed();
8525 }
8526 
8528 {
8529  switch ( outputType )
8530  {
8532  {
8533  QString code = QStringLiteral( "QgsProcessingParameterDatabaseTable('%1', %2" )
8535  if ( mFlags & FlagOptional )
8536  code += QLatin1String( ", optional=True" );
8537 
8538  if ( mAllowNewTableNames )
8539  code += QLatin1String( ", allowNewTableNames=True" );
8540 
8541  code += QStringLiteral( ", connectionParameterName='%1'" ).arg( mParentConnectionParameterName );
8542  code += QStringLiteral( ", schemaParameterName='%1'" ).arg( mParentSchemaParameterName );
8544  code += QStringLiteral( ", defaultValue=%1" ).arg( valueAsPythonString( mDefault, c ) );
8545 
8546  code += ')';
8547 
8548  return code;
8549  }
8550  }
8551  return QString();
8552 }
8553 
8555 {
8556  QStringList depends;
8557  if ( !mParentConnectionParameterName.isEmpty() )
8558  depends << mParentConnectionParameterName;
8559  if ( !mParentSchemaParameterName.isEmpty() )
8560  depends << mParentSchemaParameterName;
8561  return depends;
8562 }
8563 
8565 {
8566  return mParentConnectionParameterName;
8567 }
8568 
8570 {
8571  mParentConnectionParameterName = name;
8572 }
8573 
8575 {
8576  return mParentSchemaParameterName;
8577 }
8578 
8580 {
8581  mParentSchemaParameterName = name;
8582 }
8583 
8585 {
8587  map.insert( QStringLiteral( "mParentConnectionParameterName" ), mParentConnectionParameterName );
8588  map.insert( QStringLiteral( "mParentSchemaParameterName" ), mParentSchemaParameterName );
8589  map.insert( QStringLiteral( "mAllowNewTableNames" ), mAllowNewTableNames );
8590  return map;
8591 }
8592 
8594 {
8596  mParentConnectionParameterName = map.value( QStringLiteral( "mParentConnectionParameterName" ) ).toString();
8597  mParentSchemaParameterName = map.value( QStringLiteral( "mParentSchemaParameterName" ) ).toString();
8598  mAllowNewTableNames = map.value( QStringLiteral( "mAllowNewTableNames" ), false ).toBool();
8599  return true;
8600 }
8601 
8602 QgsProcessingParameterDatabaseTable *QgsProcessingParameterDatabaseTable::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
8603 {
8604  QString connection;
8605  QString schema;
8606  QString def = definition;
8607 
8608  const QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*+)\\b\\s*(.*)$" ) );
8609  const QRegularExpressionMatch m = re.match( def );
8610  if ( m.hasMatch() )
8611  {
8612  connection = m.captured( 1 ).trimmed();
8613  if ( connection == QLatin1String( "none" ) )
8614  connection.clear();
8615  schema = m.captured( 2 ).trimmed();
8616  if ( schema == QLatin1String( "none" ) )
8617  schema.clear();
8618  def = m.captured( 3 );
8619  }
8620 
8621  return new QgsProcessingParameterDatabaseTable( name, description, connection, schema, def.isEmpty() ? QVariant() : def, isOptional );
8622 }
8623 
8625 {
8626  return mAllowNewTableNames;
8627 }
8628 
8630 {
8631  mAllowNewTableNames = allowNewTableNames;
8632 }
8633 
8634 //
8635 // QgsProcessingParameterPointCloudLayer
8636 //
8637 
8639  const QVariant &defaultValue, bool optional )
8640  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
8641 {
8642 }
8643 
8645 {
8646  return new QgsProcessingParameterPointCloudLayer( *this );
8647 }
8648 
8650 {
8651  if ( !v.isValid() )
8652  return mFlags & FlagOptional;
8653 
8654  QVariant var = v;
8655 
8656  if ( var.canConvert<QgsProperty>() )
8657  {
8658  const QgsProperty p = var.value< QgsProperty >();
8660  {
8661  var = p.staticValue();
8662  }
8663  else
8664  {
8665  return true;
8666  }
8667  }
8668 
8669  if ( qobject_cast< QgsPointCloudLayer * >( qvariant_cast<QObject *>( var ) ) )
8670  return true;
8671 
8672  if ( var.type() != QVariant::String || var.toString().isEmpty() )
8673  return mFlags & FlagOptional;
8674 
8675  if ( !context )
8676  {
8677  // that's as far as we can get without a context
8678  return true;
8679  }
8680 
8681  // try to load as layer
8683  return true;
8684 
8685  return false;
8686 }
8687 
8689 {
8690  if ( !val.isValid() )
8691  return QStringLiteral( "None" );
8692 
8693  if ( val.canConvert<QgsProperty>() )
8694  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
8695 
8696  QVariantMap p;
8697  p.insert( name(), val );
8700  : QgsProcessingUtils::stringToPythonLiteral( val.toString() );
8701 }
8702 
8704 {
8705  return QgsProviderRegistry::instance()->filePointCloudFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
8706 }
8707 
8708 QgsProcessingParameterPointCloudLayer *QgsProcessingParameterPointCloudLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
8709 {
8710  return new QgsProcessingParameterPointCloudLayer( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
8711 }
8712 
8713 //
8714 // QgsProcessingParameterAnnotationLayer
8715 //
8716 
8718  const QVariant &defaultValue, bool optional )
8719  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
8720 {
8721 }
8722 
8724 {
8725  return new QgsProcessingParameterAnnotationLayer( *this );
8726 }
8727 
8729 {
8730  if ( !v.isValid() )
8731  return mFlags & FlagOptional;
8732 
8733  QVariant var = v;
8734 
8735  if ( var.canConvert<QgsProperty>() )
8736  {
8737  const QgsProperty p = var.value< QgsProperty >();
8739  {
8740  var = p.staticValue();
8741  }
8742  else
8743  {
8744  return true;
8745  }
8746  }
8747 
8748  if ( qobject_cast< QgsAnnotationLayer * >( qvariant_cast<QObject *>( var ) ) )
8749  return true;
8750 
8751  if ( var.type() != QVariant::String || var.toString().isEmpty() )
8752  return mFlags & FlagOptional;
8753 
8754  if ( !context )
8755  {
8756  // that's as far as we can get without a context
8757  return true;
8758  }
8759 
8760  // try to load as layer
8762  return true;
8763 
8764  return false;
8765 }
8766 
8768 {
8769  if ( !val.isValid() )
8770  return QStringLiteral( "None" );
8771 
8772  if ( val.canConvert<QgsProperty>() )
8773  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
8774 
8775  QVariantMap p;
8776  p.insert( name(), val );
8778  return layer ? QgsProcessingUtils::stringToPythonLiteral( layer == context.project()->mainAnnotationLayer() ? QStringLiteral( "main" ) : layer->id() )
8779  : QgsProcessingUtils::stringToPythonLiteral( val.toString() );
8780 }
8781 
8782 QgsProcessingParameterAnnotationLayer *QgsProcessingParameterAnnotationLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
8783 {
8784  return new QgsProcessingParameterAnnotationLayer( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
8785 }
8786 
8787 QgsProcessingParameterPointCloudDestination::QgsProcessingParameterPointCloudDestination( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, bool createByDefault )
8788  : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
8789 {
8790 }
8791 
8793 {
8794  return new QgsProcessingParameterPointCloudDestination( *this );
8795 }
8796 
8798 {
8799  QVariant var = input;
8800  if ( !var.isValid() )
8801  return mFlags & FlagOptional;
8802 
8803  if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
8804  {
8805  const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
8806  var = fromVar.sink;
8807  }
8808 
8809  if ( var.canConvert<QgsProperty>() )
8810  {
8811  const QgsProperty p = var.value< QgsProperty >();
8813  {
8814  var = p.staticValue();
8815  }
8816  else
8817  {
8818  return true;
8819  }
8820  }
8821 
8822  if ( var.type() != QVariant::String )
8823  return false;
8824 
8825  if ( var.toString().isEmpty() )
8826  return mFlags & FlagOptional;
8827 
8828  return true;
8829 }
8830 
8832 {
8833  if ( !value.isValid() )
8834  return QStringLiteral( "None" );
8835 
8836  if ( value.canConvert<QgsProperty>() )
8837  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
8838 
8839  if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
8840  {
8841  const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
8842  if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
8843  {
8844  return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
8845  }
8846  else
8847  {
8848  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
8849  }
8850  }
8851 
8852  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
8853 }
8854 
8856 {
8858 }
8859 
8861 {
8862  if ( auto *lOriginalProvider = originalProvider() )
8863  {
8864  return lOriginalProvider->defaultPointCloudFileExtension();
8865  }
8866  else if ( QgsProcessingProvider *p = provider() )
8867  {
8868  return p->defaultPointCloudFileExtension();
8869  }
8870  else
8871  {
8873  }
8874 }
8875 
8877 {
8878  const QStringList exts = supportedOutputPointCloudLayerExtensions();
8879  QStringList filters;
8880  for ( const QString &ext : exts )
8881  {
8882  filters << QObject::tr( "%1 files (*.%2)" ).arg( ext.toUpper(), ext.toLower() );
8883  }
8884  return filters.join( QLatin1String( ";;" ) ) + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
8885 }
8886 
8888 {
8889  if ( auto *lOriginalProvider = originalProvider() )
8890  {
8891  return lOriginalProvider->supportedOutputPointCloudLayerExtensions();
8892  }
8893  else if ( QgsProcessingProvider *p = provider() )
8894  {
8895  return p->supportedOutputPointCloudLayerExtensions();
8896  }
8897  else
8898  {
8900  return QStringList() << QObject::tr( "%1 files (*.%2)" ).arg( ext.toUpper(), ext.toLower() );
8901  }
8902 }
8903 
8904 QgsProcessingParameterPointCloudDestination *QgsProcessingParameterPointCloudDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
8905 {
8906  return new QgsProcessingParameterPointCloudDestination( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
8907 }
Represents a map layer containing a set of georeferenced annotations, e.g.
static QgsProcessingRegistry * processingRegistry()
Returns the application's processing registry, used for managing processing providers,...
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
@ 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.
void setBallparkTransformsAreAppropriate(bool appropriate)
Sets whether approximate "ballpark" results are appropriate for this coordinate transform.
QgsRectangle transformBoundingBox(const QgsRectangle &rectangle, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool handle180Crossover=false) const SIP_THROW(QgsCsException)
Transforms a rectangle from the source CRS to the destination CRS.
QgsPointXY transform(const QgsPointXY &point, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward) const SIP_THROW(QgsCsException)
Transform the point 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 bool fileMatchesFilter(const QString &fileName, const QString &filter)
Returns true if the given fileName matches a file filter string.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:125
QgsGeometry densifyByCount(int extraNodesPerSegment) const
Returns a copy of the geometry which has been densified by adding the specified number of extra nodes...
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
Q_GADGET bool isNull
Definition: qgsgeometry.h:127
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.
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:128
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...
static QgsGeometry fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
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:73
virtual QgsRectangle extent() const
Returns the extent of the layer.
QString source() const
Returns the source for the layer.
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:79
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
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:97
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).
Represents a map layer supporting display of point clouds.
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 pointcloud layer output for processing algorithms.
A raster layer output for processing algorithms.
A vector layer output for processing algorithms.
An annotation layer parameter for processing algorithms.
QgsProcessingParameterAnnotationLayer(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterAnnotationLayer.
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...
static QgsProcessingParameterAnnotationLayer * 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.
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.
virtual QVariant valueAsJsonObject(const QVariant &value, QgsProcessingContext &context) const
Returns a version of the parameter input value, which is suitable for use in a JSON object.
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...
virtual QStringList valueAsStringList(const QVariant &value, QgsProcessingContext &context, bool &ok) const
Returns a string list version of the parameter input value (if possible).
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.
virtual QString valueAsString(const QVariant &value, QgsProcessingContext &context, bool &ok) const
Returns a string version of the parameter input value (if possible).
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.
A double numeric parameter for duration values.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QgsProcessingParameterDuration * clone() const override
Creates a clone of the parameter definition.
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...
static QString typeName()
Returns the type name for the parameter class.
QString type() const override
Unique parameter type name.
QgsProcessingParameterDuration(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, double minValue=std::numeric_limits< double >::lowest()+1, double maxValue=std::numeric_limits< double >::max())
Constructor for QgsProcessingParameterDuration.
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 cloud layer destination parameter, for specifying the destination path for a point cloud laye...
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 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 QgsProcessingParameterPointCloudDestination * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
virtual QStringList supportedOutputPointCloudLayerExtensions() const
Returns a list of the point cloud format file extensions supported for this parameter.
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.
static QString typeName()
Returns the type name for the parameter class.
QgsProcessingParameterPointCloudDestination(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, bool createByDefault=true)
Constructor for QgsProcessingParameterPointCloudDestination.
QgsProcessingOutputDefinition * toOutputDefinition() const override
Returns a new QgsProcessingOutputDefinition corresponding to the definition of the destination parame...
A point cloud 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...
static QgsProcessingParameterPointCloudLayer * 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.
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
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.
QgsProcessingParameterPointCloudLayer(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterPointCloudLayer.
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 QgsAnnotationLayer * parameterAsAnnotationLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to an annotation layer.
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 QgsPointCloudLayer * parameterAsPointCloudLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a point cloud 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.
@ Annotation
Annotation layer type, since QGIS 3.22.
@ Vector
Vector layer type.
@ Mesh
Mesh layer type, since QGIS 3.6.
@ Raster
Raster layer type.
@ UnknownType
Unknown layer type.
@ PointCloud
Point cloud layer type, since QGIS 3.22.
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 QString variantToPythonLiteral(const QVariant &value)
Converts a variant to a Python literal.
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 QString defaultPointCloudExtension()
Returns the default point cloud 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:63
@ PythonQgsProcessingAlgorithmSubclass
Full Python QgsProcessingAlgorithm subclass.
Definition: qgsprocessing.h:64
SourceType
Data source types enum.
Definition: qgsprocessing.h:46
@ TypePlugin
Plugin layers.
Definition: qgsprocessing.h:56
@ TypeVectorLine
Vector line layers.
Definition: qgsprocessing.h:50
@ TypeMapLayer
Any map layer type (raster, vector, mesh, point cloud, annotation or plugin layer)
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
@ TypeAnnotation
Annotation layers.
Definition: qgsprocessing.h:58
@ TypePointCloud
Point cloud layers.
Definition: qgsprocessing.h:57
@ 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:72
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:101
QgsAnnotationLayer * mainAnnotationLayer()
Returns the main annotation layer associated with the project.
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:231
@ ExpressionBasedProperty
Expression based property (QgsExpressionBasedProperty)
Definition: qgsproperty.h:240
@ StaticProperty
Static property (QgsStaticProperty)
Definition: qgsproperty.h:238
@ FieldBasedProperty
Field based property (QgsFieldBasedProperty)
Definition: qgsproperty.h:239
@ InvalidProperty
Invalid (not set) property.
Definition: qgsproperty.h:237
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.
QString filePointCloudFilters() const
Returns a file filter string for supported point clouds.
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
TemporalUnit
Temporal units.
Definition: qgsunittypes.h:150
@ TemporalDays
Days.
Definition: qgsunittypes.h:155
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:1530
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
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
const QString & typeName