QGIS API Documentation  3.12.1-București (121cc00ff0)
qgsprocessingparameters.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsprocessingparameters.cpp
3  ---------------------------
4  begin : April 2017
5  copyright : (C) 2017 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
19 #include "qgsprocessingprovider.h"
20 #include "qgsprocessingcontext.h"
21 #include "qgsprocessingutils.h"
22 #include "qgsprocessingalgorithm.h"
24 #include "qgsprocessingoutputs.h"
25 #include "qgssettings.h"
26 #include "qgsvectorfilewriter.h"
27 #include "qgsreferencedgeometry.h"
28 #include "qgsprocessingregistry.h"
30 #include "qgsrasterfilewriter.h"
31 #include "qgsvectorlayer.h"
32 #include "qgsmeshlayer.h"
33 #include "qgsapplication.h"
34 #include "qgslayoutmanager.h"
35 #include "qgsprintlayout.h"
36 #include "qgssymbollayerutils.h"
37 #include "qgsfileutils.h"
38 #include <functional>
39 
40 
42 {
43  QVariantMap map;
44  map.insert( QStringLiteral( "sink" ), sink.toVariant() );
45  map.insert( QStringLiteral( "create_options" ), createOptions );
46  return map;
47 }
48 
50 {
51  sink.loadVariant( map.value( QStringLiteral( "sink" ) ) );
52  createOptions = map.value( QStringLiteral( "create_options" ) ).toMap();
53  return true;
54 }
55 
56 bool QgsProcessingParameters::isDynamic( const QVariantMap &parameters, const QString &name )
57 {
58  QVariant val = parameters.value( name );
59  if ( val.canConvert<QgsProperty>() )
60  return val.value< QgsProperty >().propertyType() != QgsProperty::StaticProperty;
61  else
62  return false;
63 }
64 
65 QString QgsProcessingParameters::parameterAsString( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
66 {
67  if ( !definition )
68  return QString();
69 
70  return parameterAsString( definition, parameters.value( definition->name() ), context );
71 }
72 
73 QString QgsProcessingParameters::parameterAsString( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
74 {
75  if ( !definition )
76  return QString();
77 
78  QVariant val = value;
79  if ( val.canConvert<QgsProperty>() )
80  return val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
81 
82  if ( !val.isValid() )
83  {
84  // fall back to default
85  val = definition->defaultValue();
86  }
87 
89  {
90  if ( const QgsProcessingDestinationParameter *destParam = dynamic_cast< const QgsProcessingDestinationParameter * >( definition ) )
91  return destParam->generateTemporaryDestination();
92  }
93 
94  return val.toString();
95 }
96 
97 QString QgsProcessingParameters::parameterAsExpression( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
98 {
99  if ( !definition )
100  return QString();
101 
102  return parameterAsExpression( definition, parameters.value( definition->name() ), context );
103 }
104 
105 QString QgsProcessingParameters::parameterAsExpression( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
106 {
107  if ( !definition )
108  return QString();
109 
110  QVariant val = value;
111  if ( val.canConvert<QgsProperty>() )
112  return val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
113 
114  if ( val.isValid() && !val.toString().isEmpty() )
115  {
116  QgsExpression e( val.toString() );
117  if ( e.isValid() )
118  return val.toString();
119  }
120 
121  // fall back to default
122  return definition->defaultValue().toString();
123 }
124 
125 double QgsProcessingParameters::parameterAsDouble( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
126 {
127  if ( !definition )
128  return 0;
129 
130  return parameterAsDouble( definition, parameters.value( definition->name() ), context );
131 }
132 
133 double QgsProcessingParameters::parameterAsDouble( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
134 {
135  if ( !definition )
136  return 0;
137 
138  QVariant val = value;
139  if ( val.canConvert<QgsProperty>() )
140  return val.value< QgsProperty >().valueAsDouble( context.expressionContext(), definition->defaultValue().toDouble() );
141 
142  bool ok = false;
143  double res = val.toDouble( &ok );
144  if ( ok )
145  return res;
146 
147  // fall back to default
148  val = definition->defaultValue();
149  return val.toDouble();
150 }
151 
152 int QgsProcessingParameters::parameterAsInt( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
153 {
154  if ( !definition )
155  return 0;
156 
157  return parameterAsInt( definition, parameters.value( definition->name() ), context );
158 }
159 
160 int QgsProcessingParameters::parameterAsInt( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
161 {
162  if ( !definition )
163  return 0;
164 
165  QVariant val = value;
166  if ( val.canConvert<QgsProperty>() )
167  return val.value< QgsProperty >().valueAsInt( context.expressionContext(), definition->defaultValue().toInt() );
168 
169  bool ok = false;
170  double dbl = val.toDouble( &ok );
171  if ( !ok )
172  {
173  // fall back to default
174  val = definition->defaultValue();
175  dbl = val.toDouble( &ok );
176  }
177 
178  //String representations of doubles in QVariant will not convert to int
179  //work around this by first converting to double, and then checking whether the double is convertible to int
180  if ( ok )
181  {
182  double round = std::round( dbl );
183  if ( round > std::numeric_limits<int>::max() || round < -std::numeric_limits<int>::max() )
184  {
185  //double too large to fit in int
186  return 0;
187  }
188  return static_cast< int >( std::round( dbl ) );
189  }
190 
191  return val.toInt();
192 }
193 
194 QList< int > QgsProcessingParameters::parameterAsInts( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
195 {
196  if ( !definition )
197  return QList< int >();
198 
199  return parameterAsInts( definition, parameters.value( definition->name() ), context );
200 }
201 
202 QList< int > QgsProcessingParameters::parameterAsInts( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
203 {
204  if ( !definition )
205  return QList< int >();
206 
207  QList< int > resultList;
208  QVariant val = value;
209  if ( val.isValid() )
210  {
211  if ( val.canConvert<QgsProperty>() )
212  resultList << val.value< QgsProperty >().valueAsInt( context.expressionContext(), definition->defaultValue().toInt() );
213  else if ( val.type() == QVariant::List )
214  {
215  QVariantList list = val.toList();
216  for ( auto it = list.constBegin(); it != list.constEnd(); ++it )
217  resultList << it->toInt();
218  }
219  else
220  {
221  QStringList parts = val.toString().split( ';' );
222  for ( auto it = parts.constBegin(); it != parts.constEnd(); ++it )
223  resultList << it->toInt();
224  }
225  }
226 
227  if ( ( resultList.isEmpty() || resultList.at( 0 ) == 0 ) )
228  {
229  resultList.clear();
230  // check default
231  if ( definition->defaultValue().isValid() )
232  {
233  if ( definition->defaultValue().type() == QVariant::List )
234  {
235  QVariantList list = definition->defaultValue().toList();
236  for ( auto it = list.constBegin(); it != list.constEnd(); ++it )
237  resultList << it->toInt();
238  }
239  else
240  {
241  QStringList parts = definition->defaultValue().toString().split( ';' );
242  for ( auto it = parts.constBegin(); it != parts.constEnd(); ++it )
243  resultList << it->toInt();
244  }
245  }
246  }
247 
248  return resultList;
249 }
250 
251 int QgsProcessingParameters::parameterAsEnum( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
252 {
253  if ( !definition )
254  return 0;
255 
256  return parameterAsEnum( definition, parameters.value( definition->name() ), context );
257 }
258 
259 int QgsProcessingParameters::parameterAsEnum( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
260 {
261  if ( !definition )
262  return 0;
263 
264  int val = parameterAsInt( definition, value, context );
265  const QgsProcessingParameterEnum *enumDef = dynamic_cast< const QgsProcessingParameterEnum *>( definition );
266  if ( enumDef && val >= enumDef->options().size() )
267  {
268  return enumDef->defaultValue().toInt();
269  }
270  return val;
271 }
272 
273 QList<int> QgsProcessingParameters::parameterAsEnums( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
274 {
275  if ( !definition )
276  return QList<int>();
277 
278  return parameterAsEnums( definition, parameters.value( definition->name() ), context );
279 }
280 
281 QList<int> QgsProcessingParameters::parameterAsEnums( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
282 {
283  if ( !definition )
284  return QList<int>();
285 
286  QVariantList resultList;
287  QVariant val = value;
288  if ( val.canConvert<QgsProperty>() )
289  resultList << val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
290  else if ( val.type() == QVariant::List )
291  {
292  const auto constToList = val.toList();
293  for ( const QVariant &var : constToList )
294  resultList << var;
295  }
296  else if ( val.type() == QVariant::String )
297  {
298  const auto constSplit = val.toString().split( ',' );
299  for ( const QString &var : constSplit )
300  resultList << var;
301  }
302  else
303  resultList << val;
304 
305  if ( resultList.isEmpty() )
306  return QList< int >();
307 
308  if ( ( !val.isValid() || !resultList.at( 0 ).isValid() ) && definition )
309  {
310  resultList.clear();
311  // check default
312  if ( definition->defaultValue().type() == QVariant::List )
313  {
314  const auto constToList = definition->defaultValue().toList();
315  for ( const QVariant &var : constToList )
316  resultList << var;
317  }
318  else if ( definition->defaultValue().type() == QVariant::String )
319  {
320  const auto constSplit = definition->defaultValue().toString().split( ',' );
321  for ( const QString &var : constSplit )
322  resultList << var;
323  }
324  else
325  resultList << definition->defaultValue();
326  }
327 
328  QList< int > result;
329  const QgsProcessingParameterEnum *enumDef = dynamic_cast< const QgsProcessingParameterEnum *>( definition );
330  const auto constResultList = resultList;
331  for ( const QVariant &var : constResultList )
332  {
333  int resInt = var.toInt();
334  if ( !enumDef || resInt < enumDef->options().size() )
335  {
336  result << resInt;
337  }
338  }
339  return result;
340 }
341 
342 bool QgsProcessingParameters::parameterAsBool( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
343 {
344  if ( !definition )
345  return false;
346 
347  return parameterAsBool( definition, parameters.value( definition->name() ), context );
348 }
349 
350 bool QgsProcessingParameters::parameterAsBoolean( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
351 {
352  if ( !definition )
353  return false;
354 
355  return parameterAsBoolean( definition, parameters.value( definition->name() ), context );
356 }
357 
358 bool QgsProcessingParameters::parameterAsBool( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
359 {
360  if ( !definition )
361  return false;
362 
363  QVariant def = definition->defaultValue();
364 
365  QVariant val = value;
366  if ( val.canConvert<QgsProperty>() )
367  return val.value< QgsProperty >().valueAsBool( context.expressionContext(), def.toBool() );
368  else if ( val.isValid() )
369  return val.toBool();
370  else
371  return def.toBool();
372 }
373 
374 bool QgsProcessingParameters::parameterAsBoolean( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
375 {
376  if ( !definition )
377  return false;
378 
379  QVariant def = definition->defaultValue();
380 
381  QVariant val = value;
382  if ( val.canConvert<QgsProperty>() )
383  return val.value< QgsProperty >().valueAsBool( context.expressionContext(), def.toBool() );
384  else if ( val.isValid() )
385  return val.toBool();
386  else
387  return def.toBool();
388 }
389 
390 QgsFeatureSink *QgsProcessingParameters::parameterAsSink( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsFields &fields,
392  QgsProcessingContext &context, QString &destinationIdentifier, QgsFeatureSink::SinkFlags sinkFlags )
393 {
394  QVariant val;
395  if ( definition )
396  {
397  val = parameters.value( definition->name() );
398  }
399 
400  return parameterAsSink( definition, val, fields, geometryType, crs, context, destinationIdentifier, sinkFlags );
401 }
402 
403 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 )
404 {
405  QVariant val = value;
406 
407  QgsProject *destinationProject = nullptr;
408  QString destName;
409  QVariantMap createOptions;
410  if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
411  {
412  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
414  destinationProject = fromVar.destinationProject;
415  createOptions = fromVar.createOptions;
416 
417  val = fromVar.sink;
418  destName = fromVar.destinationName;
419  }
420 
421  QString dest;
422  if ( val.canConvert<QgsProperty>() )
423  {
424  dest = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
425  }
426  else if ( !val.isValid() || val.toString().isEmpty() )
427  {
428  if ( definition && definition->flags() & QgsProcessingParameterDefinition::FlagOptional && !definition->defaultValue().isValid() )
429  {
430  // unset, optional sink, no default => no sink
431  return nullptr;
432  }
433  // fall back to default
434  if ( !definition )
435  {
436  throw QgsProcessingException( QObject::tr( "No parameter definition for the sink" ) );
437  }
438  dest = definition->defaultValue().toString();
439  }
440  else
441  {
442  dest = val.toString();
443  }
444  if ( dest == QgsProcessing::TEMPORARY_OUTPUT )
445  {
446  if ( const QgsProcessingDestinationParameter *destParam = dynamic_cast< const QgsProcessingDestinationParameter * >( definition ) )
447  dest = destParam->generateTemporaryDestination();
448  }
449 
450  if ( dest.isEmpty() )
451  return nullptr;
452 
453  std::unique_ptr< QgsFeatureSink > sink( QgsProcessingUtils::createFeatureSink( dest, context, fields, geometryType, crs, createOptions, sinkFlags ) );
454  destinationIdentifier = dest;
455 
456  if ( destinationProject )
457  {
458  if ( destName.isEmpty() && definition )
459  {
460  destName = definition->description();
461  }
462  QString outputName;
463  if ( definition )
464  outputName = definition->name();
465  context.addLayerToLoadOnCompletion( destinationIdentifier, QgsProcessingContext::LayerDetails( destName, destinationProject, outputName, QgsProcessingUtils::LayerHint::Vector ) );
466  }
467 
468  return sink.release();
469 }
470 
472 {
473  if ( !definition )
474  return nullptr;
475 
476  return parameterAsSource( definition, parameters.value( definition->name() ), context );
477 }
478 
480 {
481  if ( !definition )
482  return nullptr;
483 
484  return QgsProcessingUtils::variantToSource( value, context, definition->defaultValue() );
485 }
486 
487 QString parameterAsCompatibleSourceLayerPathInternal( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingFeedback *feedback, QString *layerName )
488 {
489  if ( !definition )
490  return QString();
491 
492  QVariant val = parameters.value( definition->name() );
493 
494  bool selectedFeaturesOnly = false;
495  if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
496  {
497  // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
499  selectedFeaturesOnly = fromVar.selectedFeaturesOnly;
500  val = fromVar.source;
501  }
502  else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
503  {
504  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
506  val = fromVar.sink;
507  }
508 
509  if ( val.canConvert<QgsProperty>() )
510  {
511  val = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
512  }
513 
514  QgsVectorLayer *vl = nullptr;
515  vl = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( val ) );
516 
517  if ( !vl )
518  {
519  QString layerRef;
520  if ( val.canConvert<QgsProperty>() )
521  {
522  layerRef = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
523  }
524  else if ( !val.isValid() || val.toString().isEmpty() )
525  {
526  // fall back to default
527  val = definition->defaultValue();
528 
529  // default value may be a vector layer
530  vl = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( val ) );
531  if ( !vl )
532  layerRef = definition->defaultValue().toString();
533  }
534  else
535  {
536  layerRef = val.toString();
537  }
538 
539  if ( !vl )
540  {
541  if ( layerRef.isEmpty() )
542  return QString();
543 
544  vl = qobject_cast< QgsVectorLayer *>( QgsProcessingUtils::mapLayerFromString( layerRef, context, true, QgsProcessingUtils::LayerHint::Vector ) );
545  }
546  }
547 
548  if ( !vl )
549  return QString();
550 
551  if ( layerName )
552  return QgsProcessingUtils::convertToCompatibleFormatAndLayerName( vl, selectedFeaturesOnly, definition->name(),
553  compatibleFormats, preferredFormat, context, feedback, *layerName );
554  else
555  return QgsProcessingUtils::convertToCompatibleFormat( vl, selectedFeaturesOnly, definition->name(),
556  compatibleFormats, preferredFormat, context, feedback );
557 }
558 
559 QString QgsProcessingParameters::parameterAsCompatibleSourceLayerPath( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingFeedback *feedback )
560 {
561  return parameterAsCompatibleSourceLayerPathInternal( definition, parameters, context, compatibleFormats, preferredFormat, feedback, nullptr );
562 }
563 
564 QString QgsProcessingParameters::parameterAsCompatibleSourceLayerPathAndLayerName( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingFeedback *feedback, QString *layerName )
565 {
566  QString *destLayer = layerName;
567  QString tmp;
568  if ( destLayer )
569  destLayer->clear();
570  else
571  destLayer = &tmp;
572 
573  return parameterAsCompatibleSourceLayerPathInternal( definition, parameters, context, compatibleFormats, preferredFormat, feedback, destLayer );
574 }
575 
576 
578 {
579  if ( !definition )
580  return nullptr;
581 
582  return parameterAsLayer( definition, parameters.value( definition->name() ), context );
583 }
584 
586 {
587  if ( !definition )
588  return nullptr;
589 
590  QVariant val = value;
591  if ( val.canConvert<QgsProperty>() )
592  {
593  val = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
594  }
595 
596  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
597  {
598  return layer;
599  }
600 
601  if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
602  {
603  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
605  val = fromVar.sink;
606  }
607 
608  if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
609  {
610  val = val.value< QgsProperty >().staticValue();
611  }
612 
613  if ( !val.isValid() || val.toString().isEmpty() )
614  {
615  // fall back to default
616  val = definition->defaultValue();
617  }
618 
619  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
620  {
621  return layer;
622  }
623 
624  QString layerRef = val.toString();
625  if ( layerRef.isEmpty() )
626  layerRef = definition->defaultValue().toString();
627 
628  if ( layerRef.isEmpty() )
629  return nullptr;
630 
631  return QgsProcessingUtils::mapLayerFromString( layerRef, context );
632 }
633 
635 {
636  return qobject_cast< QgsRasterLayer *>( parameterAsLayer( definition, parameters, context ) );
637 }
638 
640 {
641  return qobject_cast< QgsRasterLayer *>( parameterAsLayer( definition, value, context ) );
642 }
643 
645 {
646  return qobject_cast< QgsMeshLayer *>( parameterAsLayer( definition, parameters, context ) );
647 }
648 
650 {
651  return qobject_cast< QgsMeshLayer *>( parameterAsLayer( definition, value, context ) );
652 }
653 
654 QString QgsProcessingParameters::parameterAsOutputLayer( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
655 {
656  QVariant val;
657  if ( definition )
658  {
659  val = parameters.value( definition->name() );
660  }
661  return parameterAsOutputLayer( definition, val, context );
662 }
663 
665 {
666  QVariant val = value;
667 
668  QgsProject *destinationProject = nullptr;
669  QVariantMap createOptions;
670  QString destName;
671  if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
672  {
673  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
675  destinationProject = fromVar.destinationProject;
676  createOptions = fromVar.createOptions;
677  val = fromVar.sink;
678  destName = fromVar.destinationName;
679  }
680 
681  QString dest;
682  if ( val.canConvert<QgsProperty>() )
683  {
684  dest = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
685  }
686  else if ( definition && ( !val.isValid() || val.toString().isEmpty() ) )
687  {
688  // fall back to default
689  dest = definition->defaultValue().toString();
690  }
691  else
692  {
693  dest = val.toString();
694  }
695  if ( dest == QgsProcessing::TEMPORARY_OUTPUT )
696  {
697  if ( const QgsProcessingDestinationParameter *destParam = dynamic_cast< const QgsProcessingDestinationParameter * >( definition ) )
698  dest = destParam->generateTemporaryDestination();
699  }
700 
701  if ( destinationProject )
702  {
703  QString outputName;
704  if ( destName.isEmpty() && definition )
705  {
706  destName = definition->description();
707  }
708  if ( definition )
709  outputName = definition->name();
710 
714  else if ( definition->type() == QgsProcessingParameterRasterDestination::typeName() )
716 
717  context.addLayerToLoadOnCompletion( dest, QgsProcessingContext::LayerDetails( destName, destinationProject, outputName, layerTypeHint ) );
718  }
719 
720  return dest;
721 }
722 
723 QString QgsProcessingParameters::parameterAsFileOutput( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
724 {
725  QVariant val;
726  if ( definition )
727  {
728  val = parameters.value( definition->name() );
729  }
730  return parameterAsFileOutput( definition, val, context );
731 }
732 
734 {
735  QVariant val = value;
736 
737  if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
738  {
739  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
741  val = fromVar.sink;
742  }
743 
744  QString dest;
745  if ( val.canConvert<QgsProperty>() )
746  {
747  dest = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
748  }
749  else if ( !val.isValid() || val.toString().isEmpty() )
750  {
751  // fall back to default
752  dest = definition->defaultValue().toString();
753  }
754  else
755  {
756  dest = val.toString();
757  }
758  if ( dest == QgsProcessing::TEMPORARY_OUTPUT )
759  {
760  if ( const QgsProcessingDestinationParameter *destParam = dynamic_cast< const QgsProcessingDestinationParameter * >( definition ) )
761  dest = destParam->generateTemporaryDestination();
762  }
763  return dest;
764 }
765 
767 {
768  return qobject_cast< QgsVectorLayer *>( parameterAsLayer( definition, parameters, context ) );
769 }
770 
772 {
773  return qobject_cast< QgsVectorLayer *>( parameterAsLayer( definition, value, context ) );
774 }
775 
777 {
778  if ( !definition )
780 
781  return parameterAsCrs( definition, parameters.value( definition->name() ), context );
782 }
783 
785 {
786  if ( !definition )
788 
789  return QgsProcessingUtils::variantToCrs( value, context, definition->defaultValue() );
790 }
791 
794 {
795  if ( !definition )
796  return QgsRectangle();
797 
798  return parameterAsExtent( definition, parameters.value( definition->name() ), context, crs );
799 }
800 
802 {
803  if ( !definition )
804  return QgsRectangle();
805 
806  QVariant val = value;
807 
808  if ( val.canConvert< QgsRectangle >() )
809  {
810  return val.value<QgsRectangle>();
811  }
812  if ( val.canConvert< QgsReferencedRectangle >() )
813  {
815  if ( crs.isValid() && rr.crs().isValid() && crs != rr.crs() )
816  {
817  QgsCoordinateTransform ct( rr.crs(), crs, context.project() );
818  try
819  {
820  return ct.transformBoundingBox( rr );
821  }
822  catch ( QgsCsException & )
823  {
824  QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
825  }
826  }
827  return rr;
828  }
829 
830  if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
831  {
832  // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
834  val = fromVar.source;
835  }
836  else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
837  {
838  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
840  val = fromVar.sink;
841  }
842 
843  if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
844  {
845  val = val.value< QgsProperty >().staticValue();
846  }
847 
848  // maybe parameter is a direct layer value?
849  QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) );
850 
851  QString rectText;
852  if ( val.canConvert<QgsProperty>() )
853  rectText = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
854  else
855  rectText = val.toString();
856 
857  if ( rectText.isEmpty() && !layer )
858  return QgsRectangle();
859 
860  QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?),\\s*(.*?),\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
861  QRegularExpressionMatch match = rx.match( rectText );
862  if ( match.hasMatch() )
863  {
864  bool xMinOk = false;
865  double xMin = match.captured( 1 ).toDouble( &xMinOk );
866  bool xMaxOk = false;
867  double xMax = match.captured( 2 ).toDouble( &xMaxOk );
868  bool yMinOk = false;
869  double yMin = match.captured( 3 ).toDouble( &yMinOk );
870  bool yMaxOk = false;
871  double yMax = match.captured( 4 ).toDouble( &yMaxOk );
872  if ( xMinOk && xMaxOk && yMinOk && yMaxOk )
873  {
874  QgsRectangle rect( xMin, yMin, xMax, yMax );
875  QgsCoordinateReferenceSystem rectCrs( match.captured( 5 ) );
876  if ( crs.isValid() && rectCrs.isValid() && crs != rectCrs )
877  {
878  QgsCoordinateTransform ct( rectCrs, crs, context.project() );
879  try
880  {
881  return ct.transformBoundingBox( rect );
882  }
883  catch ( QgsCsException & )
884  {
885  QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
886  }
887  }
888  return rect;
889  }
890  }
891 
892  // try as layer extent
893  if ( !layer )
894  layer = QgsProcessingUtils::mapLayerFromString( rectText, context );
895 
896  if ( layer )
897  {
898  QgsRectangle rect = layer->extent();
899  if ( crs.isValid() && layer->crs().isValid() && crs != layer->crs() )
900  {
901  QgsCoordinateTransform ct( layer->crs(), crs, context.project() );
902  try
903  {
904  return ct.transformBoundingBox( rect );
905  }
906  catch ( QgsCsException & )
907  {
908  QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
909  }
910  }
911  return rect;
912  }
913  return QgsRectangle();
914 }
915 
917 {
918  if ( !definition )
919  return QgsGeometry();
920 
921  QVariant val = parameters.value( definition->name() );
922 
923  if ( val.canConvert< QgsReferencedRectangle >() )
924  {
927  if ( crs.isValid() && rr.crs().isValid() && crs != rr.crs() )
928  {
929  g = g.densifyByCount( 20 );
930  QgsCoordinateTransform ct( rr.crs(), crs, context.project() );
931  try
932  {
933  g.transform( ct );
934  }
935  catch ( QgsCsException & )
936  {
937  QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
938  }
939  return g;
940  }
941  }
942 
943  if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
944  {
945  // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
947  val = fromVar.source;
948  }
949  else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
950  {
951  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
953  val = fromVar.sink;
954  }
955 
956  if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
957  {
958  val = val.value< QgsProperty >().staticValue();
959  }
960 
961  QString rectText;
962  if ( val.canConvert<QgsProperty>() )
963  rectText = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
964  else
965  rectText = val.toString();
966 
967  if ( !rectText.isEmpty() )
968  {
969  QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?),\\s*(.*?),\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
970  QRegularExpressionMatch match = rx.match( rectText );
971  if ( match.hasMatch() )
972  {
973  bool xMinOk = false;
974  double xMin = match.captured( 1 ).toDouble( &xMinOk );
975  bool xMaxOk = false;
976  double xMax = match.captured( 2 ).toDouble( &xMaxOk );
977  bool yMinOk = false;
978  double yMin = match.captured( 3 ).toDouble( &yMinOk );
979  bool yMaxOk = false;
980  double yMax = match.captured( 4 ).toDouble( &yMaxOk );
981  if ( xMinOk && xMaxOk && yMinOk && yMaxOk )
982  {
983  QgsRectangle rect( xMin, yMin, xMax, yMax );
984  QgsCoordinateReferenceSystem rectCrs( match.captured( 5 ) );
986  if ( crs.isValid() && rectCrs.isValid() && crs != rectCrs )
987  {
988  g = g.densifyByCount( 20 );
989  QgsCoordinateTransform ct( rectCrs, crs, context.project() );
990  try
991  {
992  g.transform( ct );
993  }
994  catch ( QgsCsException & )
995  {
996  QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
997  }
998  return g;
999  }
1000  }
1001  }
1002  }
1003 
1004  // try as layer extent
1005 
1006  // maybe parameter is a direct layer value?
1007  QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) );
1008  if ( !layer )
1009  layer = QgsProcessingUtils::mapLayerFromString( rectText, context );
1010 
1011  if ( layer )
1012  {
1013  QgsRectangle rect = layer->extent();
1014  QgsGeometry g = QgsGeometry::fromRect( rect );
1015  if ( crs.isValid() && layer->crs().isValid() && crs != layer->crs() )
1016  {
1017  g = g.densifyByCount( 20 );
1018  QgsCoordinateTransform ct( layer->crs(), crs, context.project() );
1019  try
1020  {
1021  g.transform( ct );
1022  }
1023  catch ( QgsCsException & )
1024  {
1025  QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
1026  }
1027  }
1028  return g;
1029  }
1030 
1031  return QgsGeometry::fromRect( parameterAsExtent( definition, parameters, context, crs ) );
1032 }
1033 
1035 {
1036  QVariant val = parameters.value( definition->name() );
1037 
1038  if ( val.canConvert< QgsReferencedRectangle >() )
1039  {
1041  if ( rr.crs().isValid() )
1042  {
1043  return rr.crs();
1044  }
1045  }
1046 
1047  if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
1048  {
1049  // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
1051  val = fromVar.source;
1052  }
1053  else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
1054  {
1055  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
1057  val = fromVar.sink;
1058  }
1059 
1060  if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
1061  {
1062  val = val.value< QgsProperty >().staticValue();
1063  }
1064 
1065  QString valueAsString;
1066  if ( val.canConvert<QgsProperty>() )
1067  valueAsString = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1068  else
1069  valueAsString = val.toString();
1070 
1071  QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?),\\s*(.*?),\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
1072 
1073  QRegularExpressionMatch match = rx.match( valueAsString );
1074  if ( match.hasMatch() )
1075  {
1076  QgsCoordinateReferenceSystem crs( match.captured( 5 ) );
1077  if ( crs.isValid() )
1078  return crs;
1079  }
1080 
1081  if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
1082  {
1083  // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
1085  val = fromVar.source;
1086  }
1087  else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
1088  {
1089  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
1091  val = fromVar.sink;
1092  }
1093 
1094  if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
1095  {
1096  val = val.value< QgsProperty >().staticValue();
1097  }
1098 
1099  // try as layer crs
1100  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
1101  return layer->crs();
1102  else if ( QgsMapLayer *layer = QgsProcessingUtils::mapLayerFromString( valueAsString, context ) )
1103  return layer->crs();
1104 
1105  if ( context.project() )
1106  return context.project()->crs();
1107  else
1109 }
1110 
1112 {
1113  if ( !definition )
1114  return QgsPointXY();
1115 
1116  return parameterAsPoint( definition, parameters.value( definition->name() ), context, crs );
1117 }
1118 
1120 {
1121  if ( !definition )
1122  return QgsPointXY();
1123 
1124  QVariant val = value;
1125  if ( val.canConvert< QgsPointXY >() )
1126  {
1127  return val.value<QgsPointXY>();
1128  }
1129  if ( val.canConvert< QgsGeometry >() )
1130  {
1131  const QgsGeometry geom = val.value<QgsGeometry>();
1132  if ( !geom.isNull() )
1133  return geom.centroid().asPoint();
1134  }
1135  if ( val.canConvert< QgsReferencedPointXY >() )
1136  {
1137  QgsReferencedPointXY rp = val.value<QgsReferencedPointXY>();
1138  if ( crs.isValid() && rp.crs().isValid() && crs != rp.crs() )
1139  {
1140  QgsCoordinateTransform ct( rp.crs(), crs, context.project() );
1141  try
1142  {
1143  return ct.transform( rp );
1144  }
1145  catch ( QgsCsException & )
1146  {
1147  QgsMessageLog::logMessage( QObject::tr( "Error transforming point geometry" ) );
1148  }
1149  }
1150  return rp;
1151  }
1152 
1153  QString pointText = parameterAsString( definition, value, context );
1154  if ( pointText.isEmpty() )
1155  pointText = definition->defaultValue().toString();
1156 
1157  if ( pointText.isEmpty() )
1158  return QgsPointXY();
1159 
1160  QRegularExpression rx( QStringLiteral( "^\\s*\\(?\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*\\)?\\s*$" ) );
1161 
1162  QString valueAsString = parameterAsString( definition, value, context );
1163  QRegularExpressionMatch match = rx.match( valueAsString );
1164  if ( match.hasMatch() )
1165  {
1166  bool xOk = false;
1167  double x = match.captured( 1 ).toDouble( &xOk );
1168  bool yOk = false;
1169  double y = match.captured( 2 ).toDouble( &yOk );
1170 
1171  if ( xOk && yOk )
1172  {
1173  QgsPointXY pt( x, y );
1174 
1175  QgsCoordinateReferenceSystem pointCrs( match.captured( 3 ) );
1176  if ( crs.isValid() && pointCrs.isValid() && crs != pointCrs )
1177  {
1178  QgsCoordinateTransform ct( pointCrs, crs, context.project() );
1179  try
1180  {
1181  return ct.transform( pt );
1182  }
1183  catch ( QgsCsException & )
1184  {
1185  QgsMessageLog::logMessage( QObject::tr( "Error transforming point geometry" ) );
1186  }
1187  }
1188  return pt;
1189  }
1190  }
1191 
1192  return QgsPointXY();
1193 }
1194 
1196 {
1197  QVariant val = parameters.value( definition->name() );
1198  return parameterAsPointCrs( definition, val, context );
1199 }
1200 
1202 {
1203  if ( value.canConvert< QgsReferencedPointXY >() )
1204  {
1205  QgsReferencedPointXY rr = value.value<QgsReferencedPointXY>();
1206  if ( rr.crs().isValid() )
1207  {
1208  return rr.crs();
1209  }
1210  }
1211 
1212  QRegularExpression rx( QStringLiteral( "^\\s*\\(?\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*\\)?\\s*$" ) );
1213 
1214  QString valueAsString = parameterAsString( definition, value, context );
1215  QRegularExpressionMatch match = rx.match( valueAsString );
1216  if ( match.hasMatch() )
1217  {
1218  QgsCoordinateReferenceSystem crs( match.captured( 3 ) );
1219  if ( crs.isValid() )
1220  return crs;
1221  }
1222 
1223  if ( context.project() )
1224  return context.project()->crs();
1225  else
1227 }
1228 
1229 QString QgsProcessingParameters::parameterAsFile( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1230 {
1231  if ( !definition )
1232  return QString();
1233 
1234  QString fileText = parameterAsString( definition, parameters, context );
1235  if ( fileText.isEmpty() )
1236  fileText = definition->defaultValue().toString();
1237  return fileText;
1238 }
1239 
1240 QString QgsProcessingParameters::parameterAsFile( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1241 {
1242  if ( !definition )
1243  return QString();
1244 
1245  QString fileText = parameterAsString( definition, value, context );
1246  if ( fileText.isEmpty() )
1247  fileText = definition->defaultValue().toString();
1248  return fileText;
1249 }
1250 
1251 QVariantList QgsProcessingParameters::parameterAsMatrix( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1252 {
1253  if ( !definition )
1254  return QVariantList();
1255 
1256  return parameterAsMatrix( definition, parameters.value( definition->name() ), context );
1257 }
1258 
1259 QVariantList QgsProcessingParameters::parameterAsMatrix( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1260 {
1261  if ( !definition )
1262  return QVariantList();
1263 
1264  QString resultString;
1265  QVariant val = value;
1266  if ( val.canConvert<QgsProperty>() )
1267  resultString = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1268  else if ( val.type() == QVariant::List )
1269  return val.toList();
1270  else
1271  resultString = val.toString();
1272 
1273  if ( resultString.isEmpty() )
1274  {
1275  // check default
1276  if ( definition->defaultValue().type() == QVariant::List )
1277  return definition->defaultValue().toList();
1278  else
1279  resultString = definition->defaultValue().toString();
1280  }
1281 
1282  QVariantList result;
1283  const auto constSplit = resultString.split( ',' );
1284  for ( const QString &s : constSplit )
1285  result << s;
1286 
1287  return result;
1288 }
1289 
1290 QList<QgsMapLayer *> QgsProcessingParameters::parameterAsLayerList( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1291 {
1292  if ( !definition )
1293  return QList<QgsMapLayer *>();
1294 
1295  return parameterAsLayerList( definition, parameters.value( definition->name() ), context );
1296 }
1297 
1298 QList<QgsMapLayer *> QgsProcessingParameters::parameterAsLayerList( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1299 {
1300  if ( !definition )
1301  return QList<QgsMapLayer *>();
1302 
1303  QVariant val = value;
1304  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
1305  {
1306  return QList<QgsMapLayer *>() << layer;
1307  }
1308 
1309  QList<QgsMapLayer *> layers;
1310 
1311  std::function< void( const QVariant &var ) > processVariant;
1312  processVariant = [ &layers, &context, &definition, &processVariant ]( const QVariant & var )
1313  {
1314  if ( var.type() == QVariant::List )
1315  {
1316  const auto constToList = var.toList();
1317  for ( const QVariant &listVar : constToList )
1318  {
1319  processVariant( listVar );
1320  }
1321  }
1322  else if ( var.type() == QVariant::StringList )
1323  {
1324  const auto constToStringList = var.toStringList();
1325  for ( const QString &s : constToStringList )
1326  {
1327  processVariant( s );
1328  }
1329  }
1330  else if ( var.canConvert<QgsProperty>() )
1331  processVariant( var.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() ) );
1332  else if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
1333  {
1334  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
1336  QVariant sink = fromVar.sink;
1337  if ( sink.canConvert<QgsProperty>() )
1338  {
1339  processVariant( sink.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() ) );
1340  }
1341  }
1342  else if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( var ) ) )
1343  {
1344  layers << layer;
1345  }
1346  else
1347  {
1348  QgsMapLayer *alayer = QgsProcessingUtils::mapLayerFromString( var.toString(), context );
1349  if ( alayer )
1350  layers << alayer;
1351  }
1352  };
1353 
1354  processVariant( val );
1355 
1356  if ( layers.isEmpty() )
1357  {
1358  // check default
1359  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( definition->defaultValue() ) ) )
1360  {
1361  layers << layer;
1362  }
1363  else if ( definition->defaultValue().type() == QVariant::List )
1364  {
1365  const auto constToList = definition->defaultValue().toList();
1366  for ( const QVariant &var : constToList )
1367  {
1368  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( var ) ) )
1369  {
1370  layers << layer;
1371  }
1372  else
1373  {
1374  processVariant( var );
1375  }
1376  }
1377  }
1378  else
1379  processVariant( definition->defaultValue() );
1380  }
1381 
1382  return layers;
1383 }
1384 
1385 QStringList QgsProcessingParameters::parameterAsFileList( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1386 {
1387  if ( !definition )
1388  return QStringList();
1389 
1390  QVariant val = value;
1391 
1392  QStringList files;
1393 
1394  std::function< void( const QVariant &var ) > processVariant;
1395  processVariant = [ &files, &context, &definition, &processVariant ]( const QVariant & var )
1396  {
1397  if ( var.type() == QVariant::List )
1398  {
1399  const auto constToList = var.toList();
1400  for ( const QVariant &listVar : constToList )
1401  {
1402  processVariant( listVar );
1403  }
1404  }
1405  else if ( var.type() == QVariant::StringList )
1406  {
1407  const auto constToStringList = var.toStringList();
1408  for ( const QString &s : constToStringList )
1409  {
1410  processVariant( s );
1411  }
1412  }
1413  else if ( var.canConvert<QgsProperty>() )
1414  processVariant( var.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() ) );
1415  else
1416  {
1417  files << var.toString();
1418  }
1419  };
1420 
1421  processVariant( val );
1422 
1423  if ( files.isEmpty() )
1424  {
1425  processVariant( definition->defaultValue() );
1426  }
1427 
1428  return files;
1429 }
1430 
1431 QStringList QgsProcessingParameters::parameterAsFileList( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1432 {
1433  if ( !definition )
1434  return QStringList();
1435 
1436  return parameterAsFileList( definition, parameters.value( definition->name() ), context );
1437 }
1438 
1439 QList<double> QgsProcessingParameters::parameterAsRange( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1440 {
1441  if ( !definition )
1442  return QList<double>();
1443 
1444  return parameterAsRange( definition, parameters.value( definition->name() ), context );
1445 }
1446 
1447 QList<double> QgsProcessingParameters::parameterAsRange( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1448 {
1449  if ( !definition )
1450  return QList<double>();
1451 
1452  QStringList resultStringList;
1453  QVariant val = value;
1454 
1455  if ( val.canConvert<QgsProperty>() )
1456  resultStringList << val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1457  else if ( val.type() == QVariant::List )
1458  {
1459  const auto constToList = val.toList();
1460  for ( const QVariant &var : constToList )
1461  resultStringList << var.toString();
1462  }
1463  else
1464  resultStringList << val.toString();
1465 
1466  if ( ( resultStringList.isEmpty() || ( resultStringList.size() == 1 && resultStringList.at( 0 ).isEmpty() ) ) )
1467  {
1468  resultStringList.clear();
1469  // check default
1470  if ( definition->defaultValue().type() == QVariant::List )
1471  {
1472  const auto constToList = definition->defaultValue().toList();
1473  for ( const QVariant &var : constToList )
1474  resultStringList << var.toString();
1475  }
1476  else
1477  resultStringList << definition->defaultValue().toString();
1478  }
1479 
1480  if ( resultStringList.size() == 1 )
1481  {
1482  resultStringList = resultStringList.at( 0 ).split( ',' );
1483  }
1484 
1485  if ( resultStringList.size() < 2 )
1486  return QList< double >() << std::numeric_limits<double>::quiet_NaN() << std::numeric_limits<double>::quiet_NaN() ;
1487 
1488  QList< double > result;
1489  bool ok = false;
1490  double n = resultStringList.at( 0 ).toDouble( &ok );
1491  if ( ok )
1492  result << n;
1493  else
1494  result << std::numeric_limits<double>::quiet_NaN() ;
1495  ok = false;
1496  n = resultStringList.at( 1 ).toDouble( &ok );
1497  if ( ok )
1498  result << n;
1499  else
1500  result << std::numeric_limits<double>::quiet_NaN() ;
1501 
1502  return result;
1503 }
1504 
1505 QStringList QgsProcessingParameters::parameterAsFields( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1506 {
1507  if ( !definition )
1508  return QStringList();
1509 
1510  QStringList resultStringList;
1511  return parameterAsFields( definition, parameters.value( definition->name() ), context );
1512 }
1513 
1514 QStringList QgsProcessingParameters::parameterAsFields( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1515 {
1516  if ( !definition )
1517  return QStringList();
1518 
1519  QStringList resultStringList;
1520  QVariant val = value;
1521  if ( val.isValid() )
1522  {
1523  if ( val.canConvert<QgsProperty>() )
1524  resultStringList << val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1525  else if ( val.type() == QVariant::List )
1526  {
1527  const auto constToList = val.toList();
1528  for ( const QVariant &var : constToList )
1529  resultStringList << var.toString();
1530  }
1531  else if ( val.type() == QVariant::StringList )
1532  {
1533  resultStringList = val.toStringList();
1534  }
1535  else
1536  resultStringList.append( val.toString().split( ';' ) );
1537  }
1538 
1539  if ( ( resultStringList.isEmpty() || resultStringList.at( 0 ).isEmpty() ) )
1540  {
1541  resultStringList.clear();
1542  // check default
1543  if ( definition->defaultValue().isValid() )
1544  {
1545  if ( definition->defaultValue().type() == QVariant::List )
1546  {
1547  const auto constToList = definition->defaultValue().toList();
1548  for ( const QVariant &var : constToList )
1549  resultStringList << var.toString();
1550  }
1551  else if ( definition->defaultValue().type() == QVariant::StringList )
1552  {
1553  resultStringList = definition->defaultValue().toStringList();
1554  }
1555  else
1556  resultStringList.append( definition->defaultValue().toString().split( ';' ) );
1557  }
1558  }
1559 
1560  return resultStringList;
1561 }
1562 
1564 {
1565  if ( !definition )
1566  return nullptr;
1567 
1568  return parameterAsLayout( definition, parameters.value( definition->name() ), context );
1569 }
1570 
1572 {
1573  const QString layoutName = parameterAsString( definition, value, context );
1574  if ( layoutName.isEmpty() )
1575  return nullptr;
1576 
1577  if ( !context.project() )
1578  return nullptr;
1579 
1580  QgsMasterLayoutInterface *l = context.project()->layoutManager()->layoutByName( layoutName );
1582  return static_cast< QgsPrintLayout * >( l );
1583  else
1584  return nullptr;
1585 }
1586 
1588 {
1589  if ( !definition )
1590  return nullptr;
1591 
1592  return parameterAsLayoutItem( definition, parameters.value( definition->name() ), context, layout );
1593 }
1594 
1596 {
1597  if ( !layout )
1598  return nullptr;
1599 
1600  const QString id = parameterAsString( definition, value, context );
1601  if ( id.isEmpty() )
1602  return nullptr;
1603 
1604  // prefer matching by uuid, since it's guaranteed to be unique.
1605  if ( QgsLayoutItem *item = layout->itemByUuid( id ) )
1606  return item;
1607  else if ( QgsLayoutItem *item = layout->itemById( id ) )
1608  return item;
1609  else
1610  return nullptr;
1611 }
1612 
1613 QColor QgsProcessingParameters::parameterAsColor( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1614 {
1615  if ( !definition )
1616  return QColor();
1617 
1618  return parameterAsColor( definition, parameters.value( definition->name() ), context );
1619 }
1620 
1622 {
1623  if ( !definition )
1624  return QColor();
1625 
1626  QVariant val = value;
1627  if ( val.canConvert<QgsProperty>() )
1628  {
1629  val = val.value< QgsProperty >().value( context.expressionContext(), definition->defaultValue() );
1630  }
1631  if ( val.type() == QVariant::Color )
1632  {
1633  QColor c = val.value< QColor >();
1634  if ( const QgsProcessingParameterColor *colorParam = dynamic_cast< const QgsProcessingParameterColor * >( definition ) )
1635  if ( !colorParam->opacityEnabled() )
1636  c.setAlpha( 255 );
1637  return c;
1638  }
1639 
1640  QString colorText = parameterAsString( definition, value, context );
1641  if ( colorText.isEmpty() && !( definition->flags() & QgsProcessingParameterDefinition::FlagOptional ) )
1642  {
1643  if ( definition->defaultValue().type() == QVariant::Color )
1644  return definition->defaultValue().value< QColor >();
1645  else
1646  colorText = definition->defaultValue().toString();
1647  }
1648 
1649  if ( colorText.isEmpty() )
1650  return QColor();
1651 
1652  bool containsAlpha = false;
1653  QColor c = QgsSymbolLayerUtils::parseColorWithAlpha( colorText, containsAlpha );
1654  if ( const QgsProcessingParameterColor *colorParam = dynamic_cast< const QgsProcessingParameterColor * >( definition ) )
1655  if ( c.isValid() && !colorParam->opacityEnabled() )
1656  c.setAlpha( 255 );
1657  return c;
1658 }
1659 
1661 {
1662  QString type = map.value( QStringLiteral( "parameter_type" ) ).toString();
1663  QString name = map.value( QStringLiteral( "name" ) ).toString();
1664  std::unique_ptr< QgsProcessingParameterDefinition > def;
1666  def.reset( new QgsProcessingParameterBoolean( name ) );
1667  else if ( type == QgsProcessingParameterCrs::typeName() )
1668  def.reset( new QgsProcessingParameterCrs( name ) );
1669  else if ( type == QgsProcessingParameterMapLayer::typeName() )
1670  def.reset( new QgsProcessingParameterMapLayer( name ) );
1671  else if ( type == QgsProcessingParameterExtent::typeName() )
1672  def.reset( new QgsProcessingParameterExtent( name ) );
1673  else if ( type == QgsProcessingParameterPoint::typeName() )
1674  def.reset( new QgsProcessingParameterPoint( name ) );
1675  else if ( type == QgsProcessingParameterFile::typeName() )
1676  def.reset( new QgsProcessingParameterFile( name ) );
1677  else if ( type == QgsProcessingParameterMatrix::typeName() )
1678  def.reset( new QgsProcessingParameterMatrix( name ) );
1680  def.reset( new QgsProcessingParameterMultipleLayers( name ) );
1681  else if ( type == QgsProcessingParameterNumber::typeName() )
1682  def.reset( new QgsProcessingParameterNumber( name ) );
1683  else if ( type == QgsProcessingParameterRange::typeName() )
1684  def.reset( new QgsProcessingParameterRange( name ) );
1685  else if ( type == QgsProcessingParameterRasterLayer::typeName() )
1686  def.reset( new QgsProcessingParameterRasterLayer( name ) );
1687  else if ( type == QgsProcessingParameterEnum::typeName() )
1688  def.reset( new QgsProcessingParameterEnum( name ) );
1689  else if ( type == QgsProcessingParameterString::typeName() )
1690  def.reset( new QgsProcessingParameterString( name ) );
1691  else if ( type == QgsProcessingParameterAuthConfig::typeName() )
1692  def.reset( new QgsProcessingParameterAuthConfig( name ) );
1693  else if ( type == QgsProcessingParameterExpression::typeName() )
1694  def.reset( new QgsProcessingParameterExpression( name ) );
1695  else if ( type == QgsProcessingParameterVectorLayer::typeName() )
1696  def.reset( new QgsProcessingParameterVectorLayer( name ) );
1697  else if ( type == QgsProcessingParameterField::typeName() )
1698  def.reset( new QgsProcessingParameterField( name ) );
1699  else if ( type == QgsProcessingParameterFeatureSource::typeName() )
1700  def.reset( new QgsProcessingParameterFeatureSource( name ) );
1701  else if ( type == QgsProcessingParameterFeatureSink::typeName() )
1702  def.reset( new QgsProcessingParameterFeatureSink( name ) );
1704  def.reset( new QgsProcessingParameterVectorDestination( name ) );
1706  def.reset( new QgsProcessingParameterRasterDestination( name ) );
1708  def.reset( new QgsProcessingParameterFileDestination( name ) );
1710  def.reset( new QgsProcessingParameterFolderDestination( name ) );
1711  else if ( type == QgsProcessingParameterBand::typeName() )
1712  def.reset( new QgsProcessingParameterBand( name ) );
1713  else if ( type == QgsProcessingParameterMeshLayer::typeName() )
1714  def.reset( new QgsProcessingParameterMeshLayer( name ) );
1715  else if ( type == QgsProcessingParameterLayout::typeName() )
1716  def.reset( new QgsProcessingParameterLayout( name ) );
1717  else if ( type == QgsProcessingParameterLayoutItem::typeName() )
1718  def.reset( new QgsProcessingParameterLayoutItem( name ) );
1719  else if ( type == QgsProcessingParameterColor::typeName() )
1720  def.reset( new QgsProcessingParameterColor( name ) );
1722  def.reset( new QgsProcessingParameterCoordinateOperation( name ) );
1723  {
1725  if ( paramType )
1726  def.reset( paramType->create( name ) );
1727  }
1728 
1729  if ( !def )
1730  return nullptr;
1731 
1732  def->fromVariantMap( map );
1733  return def.release();
1734 }
1735 
1736 QString QgsProcessingParameters::descriptionFromName( const QString &name )
1737 {
1738  QString desc = name;
1739  desc.replace( '_', ' ' );
1740  return desc;
1741 }
1742 
1744 {
1745  bool isOptional = false;
1746  QString name;
1747  QString definition;
1748  QString type;
1749  if ( !parseScriptCodeParameterOptions( code, isOptional, name, type, definition ) )
1750  return nullptr;
1751 
1752  QString description = descriptionFromName( name );
1753 
1754  if ( type == QStringLiteral( "boolean" ) )
1755  return QgsProcessingParameterBoolean::fromScriptCode( name, description, isOptional, definition );
1756  else if ( type == QStringLiteral( "crs" ) )
1757  return QgsProcessingParameterCrs::fromScriptCode( name, description, isOptional, definition );
1758  else if ( type == QStringLiteral( "layer" ) )
1759  return QgsProcessingParameterMapLayer::fromScriptCode( name, description, isOptional, definition );
1760  else if ( type == QStringLiteral( "extent" ) )
1761  return QgsProcessingParameterExtent::fromScriptCode( name, description, isOptional, definition );
1762  else if ( type == QStringLiteral( "point" ) )
1763  return QgsProcessingParameterPoint::fromScriptCode( name, description, isOptional, definition );
1764  else if ( type == QStringLiteral( "file" ) )
1765  return QgsProcessingParameterFile::fromScriptCode( name, description, isOptional, definition, QgsProcessingParameterFile::File );
1766  else if ( type == QStringLiteral( "folder" ) )
1767  return QgsProcessingParameterFile::fromScriptCode( name, description, isOptional, definition, QgsProcessingParameterFile::Folder );
1768  else if ( type == QStringLiteral( "matrix" ) )
1769  return QgsProcessingParameterMatrix::fromScriptCode( name, description, isOptional, definition );
1770  else if ( type == QStringLiteral( "multiple" ) )
1771  return QgsProcessingParameterMultipleLayers::fromScriptCode( name, description, isOptional, definition );
1772  else if ( type == QStringLiteral( "number" ) )
1773  return QgsProcessingParameterNumber::fromScriptCode( name, description, isOptional, definition );
1774  else if ( type == QStringLiteral( "distance" ) )
1775  return QgsProcessingParameterDistance::fromScriptCode( name, description, isOptional, definition );
1776  else if ( type == QStringLiteral( "scale" ) )
1777  return QgsProcessingParameterScale::fromScriptCode( name, description, isOptional, definition );
1778  else if ( type == QStringLiteral( "range" ) )
1779  return QgsProcessingParameterRange::fromScriptCode( name, description, isOptional, definition );
1780  else if ( type == QStringLiteral( "raster" ) )
1781  return QgsProcessingParameterRasterLayer::fromScriptCode( name, description, isOptional, definition );
1782  else if ( type == QStringLiteral( "enum" ) )
1783  return QgsProcessingParameterEnum::fromScriptCode( name, description, isOptional, definition );
1784  else if ( type == QStringLiteral( "string" ) )
1785  return QgsProcessingParameterString::fromScriptCode( name, description, isOptional, definition );
1786  else if ( type == QStringLiteral( "authcfg" ) )
1787  return QgsProcessingParameterAuthConfig::fromScriptCode( name, description, isOptional, definition );
1788  else if ( type == QStringLiteral( "expression" ) )
1789  return QgsProcessingParameterExpression::fromScriptCode( name, description, isOptional, definition );
1790  else if ( type == QStringLiteral( "field" ) )
1791  return QgsProcessingParameterField::fromScriptCode( name, description, isOptional, definition );
1792  else if ( type == QStringLiteral( "vector" ) )
1793  return QgsProcessingParameterVectorLayer::fromScriptCode( name, description, isOptional, definition );
1794  else if ( type == QStringLiteral( "source" ) )
1795  return QgsProcessingParameterFeatureSource::fromScriptCode( name, description, isOptional, definition );
1796  else if ( type == QStringLiteral( "sink" ) )
1797  return QgsProcessingParameterFeatureSink::fromScriptCode( name, description, isOptional, definition );
1798  else if ( type == QStringLiteral( "vectordestination" ) )
1799  return QgsProcessingParameterVectorDestination::fromScriptCode( name, description, isOptional, definition );
1800  else if ( type == QStringLiteral( "rasterdestination" ) )
1801  return QgsProcessingParameterRasterDestination::fromScriptCode( name, description, isOptional, definition );
1802  else if ( type == QStringLiteral( "filedestination" ) )
1803  return QgsProcessingParameterFileDestination::fromScriptCode( name, description, isOptional, definition );
1804  else if ( type == QStringLiteral( "folderdestination" ) )
1805  return QgsProcessingParameterFolderDestination::fromScriptCode( name, description, isOptional, definition );
1806  else if ( type == QStringLiteral( "band" ) )
1807  return QgsProcessingParameterBand::fromScriptCode( name, description, isOptional, definition );
1808  else if ( type == QStringLiteral( "mesh" ) )
1809  return QgsProcessingParameterMeshLayer::fromScriptCode( name, description, isOptional, definition );
1810  else if ( type == QStringLiteral( "layout" ) )
1811  return QgsProcessingParameterLayout::fromScriptCode( name, description, isOptional, definition );
1812  else if ( type == QStringLiteral( "layoutitem" ) )
1813  return QgsProcessingParameterLayoutItem::fromScriptCode( name, description, isOptional, definition );
1814  else if ( type == QStringLiteral( "color" ) )
1815  return QgsProcessingParameterColor::fromScriptCode( name, description, isOptional, definition );
1816  else if ( type == QStringLiteral( "coordinateoperation" ) )
1817  return QgsProcessingParameterCoordinateOperation::fromScriptCode( name, description, isOptional, definition );
1818  else if ( type == QStringLiteral( "maptheme" ) )
1819  return QgsProcessingParameterMapTheme::fromScriptCode( name, description, isOptional, definition );
1820 
1821  return nullptr;
1822 }
1823 
1824 bool QgsProcessingParameters::parseScriptCodeParameterOptions( const QString &code, bool &isOptional, QString &name, QString &type, QString &definition )
1825 {
1826  QRegularExpression re( QStringLiteral( "(?:#*)(.*?)=\\s*(.*)" ) );
1827  QRegularExpressionMatch m = re.match( code );
1828  if ( !m.hasMatch() )
1829  return false;
1830 
1831  name = m.captured( 1 );
1832  QString tokens = m.captured( 2 );
1833  if ( tokens.startsWith( QLatin1String( "optional" ), Qt::CaseInsensitive ) )
1834  {
1835  isOptional = true;
1836  tokens.remove( 0, 8 ); // length "optional" = 8
1837  }
1838  else
1839  {
1840  isOptional = false;
1841  }
1842 
1843  tokens = tokens.trimmed();
1844 
1845  QRegularExpression re2( QStringLiteral( "(.*?)\\s+(.*)" ) );
1846  m = re2.match( tokens );
1847  if ( !m.hasMatch() )
1848  {
1849  type = tokens.toLower().trimmed();
1850  definition.clear();
1851  }
1852  else
1853  {
1854  type = m.captured( 1 ).toLower().trimmed();
1855  definition = m.captured( 2 );
1856  }
1857  return true;
1858 }
1859 
1860 //
1861 // QgsProcessingParameterDefinition
1862 //
1863 
1864 QgsProcessingParameterDefinition::QgsProcessingParameterDefinition( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
1865  : mName( name )
1866  , mDescription( description )
1867  , mDefault( defaultValue )
1868  , mFlags( optional ? FlagOptional : 0 )
1869 {}
1870 
1872 {
1873  if ( !input.isValid() && !mDefault.isValid() )
1874  return mFlags & FlagOptional;
1875 
1876  if ( ( input.type() == QVariant::String && input.toString().isEmpty() )
1877  || ( !input.isValid() && mDefault.type() == QVariant::String && mDefault.toString().isEmpty() ) )
1878  return mFlags & FlagOptional;
1879 
1880  return true;
1881 }
1882 
1884 {
1885  if ( !value.isValid() )
1886  return QStringLiteral( "None" );
1887 
1888  if ( value.canConvert<QgsProperty>() )
1889  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
1890 
1891  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
1892 }
1893 
1895 {
1896  QString code = QStringLiteral( "##%1=" ).arg( mName );
1897  if ( mFlags & FlagOptional )
1898  code += QStringLiteral( "optional " );
1899  code += type() + ' ';
1900  code += mDefault.toString();
1901  return code.trimmed();
1902 }
1903 
1905 {
1906  // base class method is probably not much use
1907  if ( QgsProcessingParameterType *t = QgsApplication::processingRegistry()->parameterType( type() ) )
1908  {
1909  switch ( outputType )
1910  {
1912  {
1913  QString code = t->className() + QStringLiteral( "('%1', '%2'" ).arg( name(), description() );
1914  if ( mFlags & FlagOptional )
1915  code += QStringLiteral( ", optional=True" );
1916 
1918  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
1919  return code;
1920  }
1921  }
1922  }
1923 
1924  // oh well, we tried
1925  return QString();
1926 }
1927 
1929 {
1930  QVariantMap map;
1931  map.insert( QStringLiteral( "parameter_type" ), type() );
1932  map.insert( QStringLiteral( "name" ), mName );
1933  map.insert( QStringLiteral( "description" ), mDescription );
1934  map.insert( QStringLiteral( "default" ), mDefault );
1935  map.insert( QStringLiteral( "flags" ), static_cast< int >( mFlags ) );
1936  map.insert( QStringLiteral( "metadata" ), mMetadata );
1937  return map;
1938 }
1939 
1941 {
1942  mName = map.value( QStringLiteral( "name" ) ).toString();
1943  mDescription = map.value( QStringLiteral( "description" ) ).toString();
1944  mDefault = map.value( QStringLiteral( "default" ) );
1945  mFlags = static_cast< Flags >( map.value( QStringLiteral( "flags" ) ).toInt() );
1946  mMetadata = map.value( QStringLiteral( "metadata" ) ).toMap();
1947  return true;
1948 }
1949 
1951 {
1952  return mAlgorithm;
1953 }
1954 
1956 {
1957  return mAlgorithm ? mAlgorithm->provider() : nullptr;
1958 }
1959 
1961 {
1962  return QStringLiteral( "<p><b>%1</b></p><p>%2</p>" ).arg(
1963  description(),
1964  QObject::tr( "Python identifier: ‘%1’" ).arg( QStringLiteral( "<i>%1</i>" ).arg( name() ) ) );
1965 }
1966 
1967 QgsProcessingParameterBoolean::QgsProcessingParameterBoolean( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
1968  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
1969 {}
1970 
1972 {
1973  return new QgsProcessingParameterBoolean( *this );
1974 }
1975 
1977 {
1978  if ( !val.isValid() )
1979  return QStringLiteral( "None" );
1980 
1981  if ( val.canConvert<QgsProperty>() )
1982  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
1983  return val.toBool() ? QStringLiteral( "True" ) : QStringLiteral( "False" );
1984 }
1985 
1987 {
1988  QString code = QStringLiteral( "##%1=" ).arg( mName );
1989  if ( mFlags & FlagOptional )
1990  code += QStringLiteral( "optional " );
1991  code += type() + ' ';
1992  code += mDefault.toBool() ? QStringLiteral( "true" ) : QStringLiteral( "false" );
1993  return code.trimmed();
1994 }
1995 
1996 QgsProcessingParameterBoolean *QgsProcessingParameterBoolean::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
1997 {
1998  return new QgsProcessingParameterBoolean( name, description, definition.toLower().trimmed() != QStringLiteral( "false" ), isOptional );
1999 }
2000 
2001 QgsProcessingParameterCrs::QgsProcessingParameterCrs( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
2002  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2003 {
2004 
2005 }
2006 
2008 {
2009  return new QgsProcessingParameterCrs( *this );
2010 }
2011 
2013 {
2014  if ( !input.isValid() )
2015  return mFlags & FlagOptional;
2016 
2017  if ( input.canConvert<QgsCoordinateReferenceSystem>() )
2018  {
2019  return true;
2020  }
2021  else if ( input.canConvert<QgsProcessingFeatureSourceDefinition>() )
2022  {
2023  return true;
2024  }
2025  else if ( input.canConvert<QgsProcessingOutputLayerDefinition>() )
2026  {
2027  return true;
2028  }
2029 
2030  if ( input.canConvert<QgsProperty>() )
2031  {
2032  return true;
2033  }
2034 
2035  // direct map layer value
2036  if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
2037  return true;
2038 
2039  if ( input.type() != QVariant::String || input.toString().isEmpty() )
2040  return mFlags & FlagOptional;
2041 
2042  return true;
2043 }
2044 
2045 QString QgsProcessingParameterCrs::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
2046 {
2047  if ( !value.isValid() )
2048  return QStringLiteral( "None" );
2049 
2050  if ( value.canConvert<QgsCoordinateReferenceSystem>() )
2051  {
2052  if ( !value.value< QgsCoordinateReferenceSystem >().isValid() )
2053  return QStringLiteral( "QgsCoordinateReferenceSystem()" );
2054  else
2055  return QStringLiteral( "QgsCoordinateReferenceSystem('%1')" ).arg( value.value< QgsCoordinateReferenceSystem >().authid() );
2056  }
2057 
2058  if ( value.canConvert<QgsProperty>() )
2059  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
2060 
2061  QVariantMap p;
2062  p.insert( name(), value );
2063  QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
2064  if ( layer )
2066 
2068 }
2069 
2070 QgsProcessingParameterCrs *QgsProcessingParameterCrs::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
2071 {
2072  return new QgsProcessingParameterCrs( name, description, definition.compare( QLatin1String( "none" ), Qt::CaseInsensitive ) == 0 ? QVariant() : definition, isOptional );
2073 }
2074 
2075 QgsProcessingParameterMapLayer::QgsProcessingParameterMapLayer( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
2076  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2077 {
2078 
2079 }
2080 
2082 {
2083  return new QgsProcessingParameterMapLayer( *this );
2084 }
2085 
2087 {
2088  if ( !input.isValid() )
2089  return mFlags & FlagOptional;
2090 
2091  if ( input.canConvert<QgsProperty>() )
2092  {
2093  return true;
2094  }
2095 
2096  if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
2097  {
2098  return true;
2099  }
2100 
2101  if ( input.type() != QVariant::String || input.toString().isEmpty() )
2102  return mFlags & FlagOptional;
2103 
2104  if ( !context )
2105  {
2106  // that's as far as we can get without a context
2107  return true;
2108  }
2109 
2110  // try to load as layer
2111  if ( QgsProcessingUtils::mapLayerFromString( input.toString(), *context ) )
2112  return true;
2113 
2114  return false;
2115 }
2116 
2118 {
2119  if ( !val.isValid() )
2120  return QStringLiteral( "None" );
2121 
2122  if ( val.canConvert<QgsProperty>() )
2123  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
2124 
2125  QVariantMap p;
2126  p.insert( name(), val );
2127  QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
2129  : QgsProcessingUtils::stringToPythonLiteral( val.toString() );
2130 }
2131 
2132 QgsProcessingParameterMapLayer *QgsProcessingParameterMapLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
2133 {
2134  return new QgsProcessingParameterMapLayer( name, description, definition, isOptional );
2135 }
2136 
2137 QgsProcessingParameterExtent::QgsProcessingParameterExtent( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
2138  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2139 {
2140 
2141 }
2142 
2144 {
2145  return new QgsProcessingParameterExtent( *this );
2146 }
2147 
2149 {
2150  if ( !input.isValid() )
2151  return mFlags & FlagOptional;
2152 
2153  if ( input.canConvert<QgsProcessingFeatureSourceDefinition>() )
2154  {
2155  return true;
2156  }
2157  else if ( input.canConvert<QgsProcessingOutputLayerDefinition>() )
2158  {
2159  return true;
2160  }
2161 
2162  if ( input.canConvert<QgsProperty>() )
2163  {
2164  return true;
2165  }
2166 
2167  if ( input.canConvert< QgsRectangle >() )
2168  {
2169  QgsRectangle r = input.value<QgsRectangle>();
2170  return !r.isNull();
2171  }
2172  if ( input.canConvert< QgsReferencedRectangle >() )
2173  {
2175  return !r.isNull();
2176  }
2177 
2178  // direct map layer value
2179  if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
2180  return true;
2181 
2182  if ( input.type() != QVariant::String || input.toString().isEmpty() )
2183  return mFlags & FlagOptional;
2184 
2185  if ( !context )
2186  {
2187  // that's as far as we can get without a context
2188  return true;
2189  }
2190 
2191  QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?)\\s*,\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
2192  QRegularExpressionMatch match = rx.match( input.toString() );
2193  if ( match.hasMatch() )
2194  {
2195  bool xMinOk = false;
2196  ( void )match.captured( 1 ).toDouble( &xMinOk );
2197  bool xMaxOk = false;
2198  ( void )match.captured( 2 ).toDouble( &xMaxOk );
2199  bool yMinOk = false;
2200  ( void )match.captured( 3 ).toDouble( &yMinOk );
2201  bool yMaxOk = false;
2202  ( void )match.captured( 4 ).toDouble( &yMaxOk );
2203  if ( xMinOk && xMaxOk && yMinOk && yMaxOk )
2204  return true;
2205  }
2206 
2207  // try as layer extent
2208  return QgsProcessingUtils::mapLayerFromString( input.toString(), *context );
2209 }
2210 
2211 QString QgsProcessingParameterExtent::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
2212 {
2213  if ( !value.isValid() )
2214  return QStringLiteral( "None" );
2215 
2216  if ( value.canConvert<QgsProperty>() )
2217  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
2218 
2219  if ( value.canConvert< QgsRectangle >() )
2220  {
2221  QgsRectangle r = value.value<QgsRectangle>();
2222  return QStringLiteral( "'%1, %3, %2, %4'" ).arg( qgsDoubleToString( r.xMinimum() ),
2223  qgsDoubleToString( r.yMinimum() ),
2224  qgsDoubleToString( r.xMaximum() ),
2225  qgsDoubleToString( r.yMaximum() ) );
2226  }
2227  if ( value.canConvert< QgsReferencedRectangle >() )
2228  {
2230  return QStringLiteral( "'%1, %3, %2, %4 [%5]'" ).arg( qgsDoubleToString( r.xMinimum() ),
2231  qgsDoubleToString( r.yMinimum() ),
2232  qgsDoubleToString( r.xMaximum() ),
2233  qgsDoubleToString( r.yMaximum() ), r.crs().authid() );
2234  }
2235 
2236  QVariantMap p;
2237  p.insert( name(), value );
2238  QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
2239  if ( layer )
2241 
2243 }
2244 
2245 QgsProcessingParameterExtent *QgsProcessingParameterExtent::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
2246 {
2247  return new QgsProcessingParameterExtent( name, description, definition, isOptional );
2248 }
2249 
2250 QgsProcessingParameterPoint::QgsProcessingParameterPoint( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
2251  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2252 {
2253 
2254 }
2255 
2257 {
2258  return new QgsProcessingParameterPoint( *this );
2259 }
2260 
2262 {
2263  if ( !input.isValid() )
2264  return mFlags & FlagOptional;
2265 
2266  if ( input.canConvert<QgsProperty>() )
2267  {
2268  return true;
2269  }
2270 
2271  if ( input.canConvert< QgsPointXY >() )
2272  {
2273  return true;
2274  }
2275  if ( input.canConvert< QgsReferencedPointXY >() )
2276  {
2277  return true;
2278  }
2279  if ( input.canConvert< QgsGeometry >() )
2280  {
2281  return true;
2282  }
2283 
2284  if ( input.type() == QVariant::String )
2285  {
2286  if ( input.toString().isEmpty() )
2287  return mFlags & FlagOptional;
2288  }
2289 
2290  QRegularExpression rx( QStringLiteral( "^\\s*\\(?\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*\\)?\\s*$" ) );
2291 
2292  QRegularExpressionMatch match = rx.match( input.toString() );
2293  if ( match.hasMatch() )
2294  {
2295  bool xOk = false;
2296  ( void )match.captured( 1 ).toDouble( &xOk );
2297  bool yOk = false;
2298  ( void )match.captured( 2 ).toDouble( &yOk );
2299  return xOk && yOk;
2300  }
2301  else
2302  return false;
2303 }
2304 
2305 QString QgsProcessingParameterPoint::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
2306 {
2307  if ( !value.isValid() )
2308  return QStringLiteral( "None" );
2309 
2310  if ( value.canConvert<QgsProperty>() )
2311  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
2312 
2313  if ( value.canConvert< QgsPointXY >() )
2314  {
2315  QgsPointXY r = value.value<QgsPointXY>();
2316  return QStringLiteral( "'%1,%2'" ).arg( qgsDoubleToString( r.x() ),
2317  qgsDoubleToString( r.y() ) );
2318  }
2319  else if ( value.canConvert< QgsReferencedPointXY >() )
2320  {
2321  QgsReferencedPointXY r = value.value<QgsReferencedPointXY>();
2322  return QStringLiteral( "'%1,%2 [%3]'" ).arg( qgsDoubleToString( r.x() ),
2323  qgsDoubleToString( r.y() ),
2324  r.crs().authid() );
2325  }
2326  else if ( value.canConvert< QgsGeometry >() )
2327  {
2328  const QgsGeometry g = value.value<QgsGeometry>();
2329  if ( !g.isNull() )
2330  {
2331  const QString wkt = g.asWkt();
2332  return QStringLiteral( "QgsGeometry.fromWkt('%1')" ).arg( wkt );
2333  }
2334  }
2335 
2337 }
2338 
2339 QgsProcessingParameterPoint *QgsProcessingParameterPoint::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
2340 {
2341  return new QgsProcessingParameterPoint( name, description, definition, isOptional );
2342 }
2343 
2344 QgsProcessingParameterFile::QgsProcessingParameterFile( const QString &name, const QString &description, Behavior behavior, const QString &extension, const QVariant &defaultValue, bool optional, const QString &fileFilter )
2345  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2346  , mBehavior( behavior )
2347  , mExtension( fileFilter.isEmpty() ? extension : QString() )
2348  , mFileFilter( fileFilter.isEmpty() && extension.isEmpty() ? QObject::tr( "All files (*.*)" ) : fileFilter )
2349 {
2350 
2351 }
2352 
2354 {
2355  return new QgsProcessingParameterFile( *this );
2356 }
2357 
2359 {
2360  if ( !input.isValid() )
2361  return mFlags & FlagOptional;
2362 
2363  if ( input.canConvert<QgsProperty>() )
2364  {
2365  return true;
2366  }
2367 
2368  QString string = input.toString().trimmed();
2369 
2370  if ( input.type() != QVariant::String || string.isEmpty() )
2371  return mFlags & FlagOptional;
2372 
2373  switch ( mBehavior )
2374  {
2375  case File:
2376  {
2377  if ( !mExtension.isEmpty() )
2378  {
2379  return string.endsWith( mExtension, Qt::CaseInsensitive );
2380  }
2381  else if ( !mFileFilter.isEmpty() )
2382  {
2383  const QString test = QgsFileUtils::addExtensionFromFilter( string, mFileFilter );
2384  return test == string;
2385  }
2386  else
2387  {
2388  return true;
2389  }
2390  }
2391 
2392  case Folder:
2393  return true;
2394  }
2395  return true;
2396 }
2397 
2399 {
2400  QString code = QStringLiteral( "##%1=" ).arg( mName );
2401  if ( mFlags & FlagOptional )
2402  code += QStringLiteral( "optional " );
2403  code += ( mBehavior == File ? QStringLiteral( "file" ) : QStringLiteral( "folder" ) ) + ' ';
2404  code += mDefault.toString();
2405  return code.trimmed();
2406 }
2407 
2409 {
2410  switch ( outputType )
2411  {
2413  {
2414 
2415  QString code = QStringLiteral( "QgsProcessingParameterFile('%1', '%2'" ).arg( name(), description() );
2416  if ( mFlags & FlagOptional )
2417  code += QStringLiteral( ", optional=True" );
2418  code += QStringLiteral( ", behavior=%1" ).arg( mBehavior == File ? QStringLiteral( "QgsProcessingParameterFile.File" ) : QStringLiteral( "QgsProcessingParameterFile.Folder" ) );
2419  if ( !mExtension.isEmpty() )
2420  code += QStringLiteral( ", extension='%1'" ).arg( mExtension );
2421  if ( !mFileFilter.isEmpty() )
2422  code += QStringLiteral( ", fileFilter='%1'" ).arg( mFileFilter );
2424  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
2425  return code;
2426  }
2427  }
2428  return QString();
2429 }
2430 
2432 {
2433  mExtension = extension;
2434  mFileFilter.clear();
2435 }
2436 
2438 {
2439  return mFileFilter;
2440 }
2441 
2442 void QgsProcessingParameterFile::setFileFilter( const QString &filter )
2443 {
2444  mFileFilter = filter;
2445  mExtension.clear();
2446 }
2447 
2449 {
2451  map.insert( QStringLiteral( "behavior" ), mBehavior );
2452  map.insert( QStringLiteral( "extension" ), mExtension );
2453  map.insert( QStringLiteral( "filefilter" ), mFileFilter );
2454  return map;
2455 }
2456 
2457 bool QgsProcessingParameterFile::fromVariantMap( const QVariantMap &map )
2458 {
2460  mBehavior = static_cast< Behavior >( map.value( QStringLiteral( "behavior" ) ).toInt() );
2461  mExtension = map.value( QStringLiteral( "extension" ) ).toString();
2462  mFileFilter = map.value( QStringLiteral( "filefilter" ) ).toString();
2463  return true;
2464 }
2465 
2467 {
2468  return new QgsProcessingParameterFile( name, description, behavior, QString(), definition, isOptional );
2469 }
2470 
2471 QgsProcessingParameterMatrix::QgsProcessingParameterMatrix( const QString &name, const QString &description, int numberRows, bool fixedNumberRows, const QStringList &headers, const QVariant &defaultValue, bool optional )
2472  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2473  , mHeaders( headers )
2474  , mNumberRows( numberRows )
2475  , mFixedNumberRows( fixedNumberRows )
2476 {
2477 
2478 }
2479 
2481 {
2482  return new QgsProcessingParameterMatrix( *this );
2483 }
2484 
2486 {
2487  if ( !input.isValid() )
2488  return mFlags & FlagOptional;
2489 
2490  if ( input.type() == QVariant::String )
2491  {
2492  if ( input.toString().isEmpty() )
2493  return mFlags & FlagOptional;
2494  return true;
2495  }
2496  else if ( input.type() == QVariant::List )
2497  {
2498  if ( input.toList().isEmpty() )
2499  return mFlags & FlagOptional;
2500  return true;
2501  }
2502  else if ( input.type() == QVariant::Double || input.type() == QVariant::Int )
2503  {
2504  return true;
2505  }
2506 
2507  return false;
2508 }
2509 
2510 QString QgsProcessingParameterMatrix::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
2511 {
2512  if ( !value.isValid() )
2513  return QStringLiteral( "None" );
2514 
2515  if ( value.canConvert<QgsProperty>() )
2516  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
2517 
2518  QVariantMap p;
2519  p.insert( name(), value );
2520  QVariantList list = QgsProcessingParameters::parameterAsMatrix( this, p, context );
2521 
2522  QStringList parts;
2523  const auto constList = list;
2524  for ( const QVariant &v : constList )
2525  {
2526  if ( v.type() == QVariant::List )
2527  {
2528  QStringList parts2;
2529  const auto constToList = v.toList();
2530  for ( const QVariant &v2 : constToList )
2531  {
2532  if ( v2.isNull() || !v2.isValid() )
2533  parts2 << QStringLiteral( "None" );
2534  else if ( v2.toString().isEmpty() )
2535  parts2 << QStringLiteral( "''" );
2536  else
2537  parts2 << v2.toString();
2538  }
2539  parts << parts2.join( ',' ).prepend( '[' ).append( ']' );
2540  }
2541  else
2542  {
2543  if ( v.isNull() || !v.isValid() )
2544  parts << QStringLiteral( "None" );
2545  else if ( v.toString().isEmpty() )
2546  parts << QStringLiteral( "''" );
2547  else
2548  parts << v.toString();
2549  }
2550  }
2551 
2552  return parts.join( ',' ).prepend( '[' ).append( ']' );
2553 }
2554 
2556 {
2557  switch ( outputType )
2558  {
2560  {
2561  QString code = QStringLiteral( "QgsProcessingParameterMatrix('%1', '%2'" ).arg( name(), description() );
2562  if ( mFlags & FlagOptional )
2563  code += QStringLiteral( ", optional=True" );
2564  code += QStringLiteral( ", numberRows=" ).arg( mNumberRows );
2565  code += QStringLiteral( ", hasFixedNumberRows=" ).arg( mFixedNumberRows ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
2566 
2567  QStringList headers;
2568  headers.reserve( mHeaders.size() );
2569  for ( const QString &h : mHeaders )
2571  code += QStringLiteral( ", headers=[%1]" ).arg( headers.join( ',' ) );
2572 
2574  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
2575  return code;
2576  }
2577  }
2578  return QString();
2579 }
2580 
2582 {
2583  return mHeaders;
2584 }
2585 
2587 {
2588  mHeaders = headers;
2589 }
2590 
2592 {
2593  return mNumberRows;
2594 }
2595 
2597 {
2598  mNumberRows = numberRows;
2599 }
2600 
2602 {
2603  return mFixedNumberRows;
2604 }
2605 
2607 {
2608  mFixedNumberRows = fixedNumberRows;
2609 }
2610 
2612 {
2614  map.insert( QStringLiteral( "headers" ), mHeaders );
2615  map.insert( QStringLiteral( "rows" ), mNumberRows );
2616  map.insert( QStringLiteral( "fixed_number_rows" ), mFixedNumberRows );
2617  return map;
2618 }
2619 
2620 bool QgsProcessingParameterMatrix::fromVariantMap( const QVariantMap &map )
2621 {
2623  mHeaders = map.value( QStringLiteral( "headers" ) ).toStringList();
2624  mNumberRows = map.value( QStringLiteral( "rows" ) ).toInt();
2625  mFixedNumberRows = map.value( QStringLiteral( "fixed_number_rows" ) ).toBool();
2626  return true;
2627 }
2628 
2629 QgsProcessingParameterMatrix *QgsProcessingParameterMatrix::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
2630 {
2631  return new QgsProcessingParameterMatrix( name, description, 0, false, QStringList(), definition.isEmpty() ? QVariant() : definition, isOptional );
2632 }
2633 
2635  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2636  , mLayerType( layerType )
2637 {
2638 
2639 }
2640 
2642 {
2643  return new QgsProcessingParameterMultipleLayers( *this );
2644 }
2645 
2647 {
2648  if ( !input.isValid() )
2649  return mFlags & FlagOptional;
2650 
2651  if ( mLayerType != QgsProcessing::TypeFile )
2652  {
2653  if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
2654  {
2655  return true;
2656  }
2657  }
2658 
2659  if ( input.type() == QVariant::String )
2660  {
2661  if ( input.toString().isEmpty() )
2662  return mFlags & FlagOptional;
2663 
2664  if ( mMinimumNumberInputs > 1 )
2665  return false;
2666 
2667  if ( !context )
2668  return true;
2669 
2670  if ( mLayerType != QgsProcessing::TypeFile )
2671  return QgsProcessingUtils::mapLayerFromString( input.toString(), *context );
2672  else
2673  return true;
2674  }
2675  else if ( input.type() == QVariant::List )
2676  {
2677  if ( input.toList().count() < mMinimumNumberInputs )
2678  return mFlags & FlagOptional;
2679 
2680  if ( mMinimumNumberInputs > input.toList().count() )
2681  return false;
2682 
2683  if ( !context )
2684  return true;
2685 
2686  if ( mLayerType != QgsProcessing::TypeFile )
2687  {
2688  const auto constToList = input.toList();
2689  for ( const QVariant &v : constToList )
2690  {
2691  if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( v ) ) )
2692  continue;
2693 
2694  if ( !QgsProcessingUtils::mapLayerFromString( v.toString(), *context ) )
2695  return false;
2696  }
2697  }
2698  return true;
2699  }
2700  else if ( input.type() == QVariant::StringList )
2701  {
2702  if ( input.toStringList().count() < mMinimumNumberInputs )
2703  return mFlags & FlagOptional;
2704 
2705  if ( mMinimumNumberInputs > input.toStringList().count() )
2706  return false;
2707 
2708  if ( !context )
2709  return true;
2710 
2711  if ( mLayerType != QgsProcessing::TypeFile )
2712  {
2713  const auto constToStringList = input.toStringList();
2714  for ( const QString &v : constToStringList )
2715  {
2716  if ( !QgsProcessingUtils::mapLayerFromString( v, *context ) )
2717  return false;
2718  }
2719  }
2720  return true;
2721  }
2722  return false;
2723 }
2724 
2726 {
2727  if ( !value.isValid() )
2728  return QStringLiteral( "None" );
2729 
2730  if ( value.canConvert<QgsProperty>() )
2731  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
2732 
2733  if ( mLayerType == QgsProcessing::TypeFile )
2734  {
2735  QStringList parts;
2736  if ( value.type() == QVariant::StringList )
2737  {
2738  const QStringList list = value.toStringList();
2739  parts.reserve( list.count() );
2740  for ( const QString &v : list )
2742  }
2743  else if ( value.type() == QVariant::List )
2744  {
2745  const QVariantList list = value.toList();
2746  parts.reserve( list.count() );
2747  for ( const QVariant &v : list )
2748  parts << QgsProcessingUtils::stringToPythonLiteral( v.toString() );
2749  }
2750  if ( !parts.isEmpty() )
2751  return parts.join( ',' ).prepend( '[' ).append( ']' );
2752  }
2753  else
2754  {
2755  QVariantMap p;
2756  p.insert( name(), value );
2757  const QList<QgsMapLayer *> list = QgsProcessingParameters::parameterAsLayerList( this, p, context );
2758  if ( !list.isEmpty() )
2759  {
2760  QStringList parts;
2761  parts.reserve( list.count() );
2762  for ( const QgsMapLayer *layer : list )
2763  {
2765  }
2766  return parts.join( ',' ).prepend( '[' ).append( ']' );
2767  }
2768  }
2769 
2771 }
2772 
2774 {
2775  QString code = QStringLiteral( "##%1=" ).arg( mName );
2776  if ( mFlags & FlagOptional )
2777  code += QStringLiteral( "optional " );
2778  switch ( mLayerType )
2779  {
2781  code += QStringLiteral( "multiple raster" );
2782  break;
2783 
2785  code += QStringLiteral( "multiple file" );
2786  break;
2787 
2788  default:
2789  code += QStringLiteral( "multiple vector" );
2790  break;
2791  }
2792  code += ' ';
2793  if ( mDefault.type() == QVariant::List )
2794  {
2795  QStringList parts;
2796  const auto constToList = mDefault.toList();
2797  for ( const QVariant &var : constToList )
2798  {
2799  parts << var.toString();
2800  }
2801  code += parts.join( ',' );
2802  }
2803  else if ( mDefault.type() == QVariant::StringList )
2804  {
2805  code += mDefault.toStringList().join( ',' );
2806  }
2807  else
2808  {
2809  code += mDefault.toString();
2810  }
2811  return code.trimmed();
2812 }
2813 
2815 {
2816  switch ( outputType )
2817  {
2819  {
2820  QString code = QStringLiteral( "QgsProcessingParameterMultipleLayers('%1', '%2'" ).arg( name(), description() );
2821  if ( mFlags & FlagOptional )
2822  code += QStringLiteral( ", optional=True" );
2823 
2824  QString layerType = QStringLiteral( "QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( mLayerType ) );
2825 
2826  code += QStringLiteral( ", layerType=%1" ).arg( layerType );
2828  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
2829  return code;
2830  }
2831  }
2832  return QString();
2833 }
2834 
2836 {
2837  return mLayerType;
2838 }
2839 
2841 {
2842  mLayerType = type;
2843 }
2844 
2846 {
2847  return mMinimumNumberInputs;
2848 }
2849 
2851 {
2852  if ( mMinimumNumberInputs >= 1 || !( flags() & QgsProcessingParameterDefinition::FlagOptional ) )
2853  mMinimumNumberInputs = minimumNumberInputs;
2854 }
2855 
2857 {
2859  map.insert( QStringLiteral( "layer_type" ), mLayerType );
2860  map.insert( QStringLiteral( "min_inputs" ), mMinimumNumberInputs );
2861  return map;
2862 }
2863 
2865 {
2867  mLayerType = static_cast< QgsProcessing::SourceType >( map.value( QStringLiteral( "layer_type" ) ).toInt() );
2868  mMinimumNumberInputs = map.value( QStringLiteral( "min_inputs" ) ).toInt();
2869  return true;
2870 }
2871 
2872 QgsProcessingParameterMultipleLayers *QgsProcessingParameterMultipleLayers::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
2873 {
2874  QString type = definition;
2875  QString defaultVal;
2876  QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*)" ) );
2877  QRegularExpressionMatch m = re.match( definition );
2878  if ( m.hasMatch() )
2879  {
2880  type = m.captured( 1 ).toLower().trimmed();
2881  defaultVal = m.captured( 2 );
2882  }
2884  if ( type == QStringLiteral( "vector" ) )
2886  else if ( type == QStringLiteral( "raster" ) )
2887  layerType = QgsProcessing::TypeRaster;
2888  else if ( type == QStringLiteral( "file" ) )
2889  layerType = QgsProcessing::TypeFile;
2890  return new QgsProcessingParameterMultipleLayers( name, description, layerType, defaultVal.isEmpty() ? QVariant() : defaultVal, isOptional );
2891 }
2892 
2893 QgsProcessingParameterNumber::QgsProcessingParameterNumber( const QString &name, const QString &description, Type type, const QVariant &defaultValue, bool optional, double minValue, double maxValue )
2894  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2895  , mMin( minValue )
2896  , mMax( maxValue )
2897  , mDataType( type )
2898 {
2899  if ( mMin >= mMax )
2900  {
2901  QgsMessageLog::logMessage( QObject::tr( "Invalid number parameter \"%1\": min value %2 is >= max value %3!" ).arg( name ).arg( mMin ).arg( mMax ), QObject::tr( "Processing" ) );
2902  }
2903 }
2904 
2906 {
2907  return new QgsProcessingParameterNumber( *this );
2908 }
2909 
2911 {
2912  QVariant input = value;
2913  if ( !input.isValid() )
2914  {
2915  if ( !defaultValue().isValid() )
2916  return mFlags & FlagOptional;
2917 
2918  input = defaultValue();
2919  }
2920 
2921  if ( input.canConvert<QgsProperty>() )
2922  {
2923  return true;
2924  }
2925 
2926  bool ok = false;
2927  double res = input.toDouble( &ok );
2928  if ( !ok )
2929  return mFlags & FlagOptional;
2930 
2931  return !( res < mMin || res > mMax );
2932 }
2933 
2935 {
2936  if ( !value.isValid() )
2937  return QStringLiteral( "None" );
2938 
2939  if ( value.canConvert<QgsProperty>() )
2940  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
2941 
2942  return value.toString();
2943 }
2944 
2946 {
2948  QStringList parts;
2949  if ( mMin > std::numeric_limits<double>::lowest() + 1 )
2950  parts << QObject::tr( "Minimum value: %1" ).arg( mMin );
2951  if ( mMax < std::numeric_limits<double>::max() )
2952  parts << QObject::tr( "Maximum value: %1" ).arg( mMax );
2953  if ( mDefault.isValid() )
2954  parts << QObject::tr( "Default value: %1" ).arg( mDataType == Integer ? mDefault.toInt() : mDefault.toDouble() );
2955  QString extra = parts.join( QStringLiteral( "<br />" ) );
2956  if ( !extra.isEmpty() )
2957  text += QStringLiteral( "<p>%1</p>" ).arg( extra );
2958  return text;
2959 }
2960 
2962 {
2963  switch ( outputType )
2964  {
2966  {
2967  QString code = QStringLiteral( "QgsProcessingParameterNumber('%1', '%2'" ).arg( name(), description() );
2968  if ( mFlags & FlagOptional )
2969  code += QStringLiteral( ", optional=True" );
2970 
2971  code += QStringLiteral( ", type=%1" ).arg( mDataType == Integer ? QStringLiteral( "QgsProcessingParameterNumber.Integer" ) : QStringLiteral( "QgsProcessingParameterNumber.Double" ) );
2972 
2973  if ( mMin != std::numeric_limits<double>::lowest() + 1 )
2974  code += QStringLiteral( ", minValue=%1" ).arg( mMin );
2975  if ( mMax != std::numeric_limits<double>::max() )
2976  code += QStringLiteral( ", maxValue=%1" ).arg( mMax );
2978  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
2979  return code;
2980  }
2981  }
2982  return QString();
2983 }
2984 
2986 {
2987  return mMin;
2988 }
2989 
2991 {
2992  mMin = min;
2993 }
2994 
2996 {
2997  return mMax;
2998 }
2999 
3001 {
3002  mMax = max;
3003 }
3004 
3006 {
3007  return mDataType;
3008 }
3009 
3011 {
3012  mDataType = dataType;
3013 }
3014 
3016 {
3018  map.insert( QStringLiteral( "min" ), mMin );
3019  map.insert( QStringLiteral( "max" ), mMax );
3020  map.insert( QStringLiteral( "data_type" ), mDataType );
3021  return map;
3022 }
3023 
3024 bool QgsProcessingParameterNumber::fromVariantMap( const QVariantMap &map )
3025 {
3027  mMin = map.value( QStringLiteral( "min" ) ).toDouble();
3028  mMax = map.value( QStringLiteral( "max" ) ).toDouble();
3029  mDataType = static_cast< Type >( map.value( QStringLiteral( "data_type" ) ).toInt() );
3030  return true;
3031 }
3032 
3033 QgsProcessingParameterNumber *QgsProcessingParameterNumber::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3034 {
3035  return new QgsProcessingParameterNumber( name, description, Double, definition.isEmpty() ? QVariant()
3036  : ( definition.toLower().trimmed() == QStringLiteral( "none" ) ? QVariant() : definition ), isOptional );
3037 }
3038 
3040  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3041  , mDataType( type )
3042 {
3043 
3044 }
3045 
3047 {
3048  return new QgsProcessingParameterRange( *this );
3049 }
3050 
3052 {
3053  if ( !input.isValid() )
3054  return mFlags & FlagOptional;
3055 
3056  if ( input.canConvert<QgsProperty>() )
3057  {
3058  return true;
3059  }
3060 
3061  if ( input.type() == QVariant::String )
3062  {
3063  QStringList list = input.toString().split( ',' );
3064  if ( list.count() != 2 )
3065  return mFlags & FlagOptional;
3066  bool ok = false;
3067  list.at( 0 ).toDouble( &ok );
3068  bool ok2 = false;
3069  list.at( 1 ).toDouble( &ok2 );
3070  if ( !ok || !ok2 )
3071  return mFlags & FlagOptional;
3072  return true;
3073  }
3074  else if ( input.type() == QVariant::List )
3075  {
3076  if ( input.toList().count() != 2 )
3077  return mFlags & FlagOptional;
3078 
3079  bool ok = false;
3080  input.toList().at( 0 ).toDouble( &ok );
3081  bool ok2 = false;
3082  input.toList().at( 1 ).toDouble( &ok2 );
3083  if ( !ok || !ok2 )
3084  return mFlags & FlagOptional;
3085  return true;
3086  }
3087 
3088  return false;
3089 }
3090 
3091 QString QgsProcessingParameterRange::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
3092 {
3093  if ( !value.isValid() )
3094  return QStringLiteral( "None" );
3095 
3096  if ( value.canConvert<QgsProperty>() )
3097  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
3098 
3099  QVariantMap p;
3100  p.insert( name(), value );
3101  QList< double > parts = QgsProcessingParameters::parameterAsRange( this, p, context );
3102 
3103  QStringList stringParts;
3104  const auto constParts = parts;
3105  for ( double v : constParts )
3106  {
3107  stringParts << QString::number( v );
3108  }
3109  return stringParts.join( ',' ).prepend( '[' ).append( ']' );
3110 }
3111 
3113 {
3114  switch ( outputType )
3115  {
3117  {
3118  QString code = QStringLiteral( "QgsProcessingParameterRange('%1', '%2'" ).arg( name(), description() );
3119  if ( mFlags & FlagOptional )
3120  code += QStringLiteral( ", optional=True" );
3121 
3122  code += QStringLiteral( ", type=%1" ).arg( mDataType == QgsProcessingParameterNumber::Integer ? QStringLiteral( "QgsProcessingParameterNumber.Integer" ) : QStringLiteral( "QgsProcessingParameterNumber.Double" ) );
3123 
3125  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
3126  return code;
3127  }
3128  }
3129  return QString();
3130 }
3131 
3133 {
3134  return mDataType;
3135 }
3136 
3138 {
3139  mDataType = dataType;
3140 }
3141 
3143 {
3145  map.insert( QStringLiteral( "data_type" ), mDataType );
3146  return map;
3147 }
3148 
3149 bool QgsProcessingParameterRange::fromVariantMap( const QVariantMap &map )
3150 {
3152  mDataType = static_cast< QgsProcessingParameterNumber::Type >( map.value( QStringLiteral( "data_type" ) ).toInt() );
3153  return true;
3154 }
3155 
3156 QgsProcessingParameterRange *QgsProcessingParameterRange::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3157 {
3158  return new QgsProcessingParameterRange( name, description, QgsProcessingParameterNumber::Double, definition.isEmpty() ? QVariant()
3159  : ( definition.toLower().trimmed() == QStringLiteral( "none" ) ? QVariant() : definition ), isOptional );
3160 }
3161 
3162 QgsProcessingParameterRasterLayer::QgsProcessingParameterRasterLayer( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
3163  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3164 {
3165 
3166 }
3167 
3169 {
3170  return new QgsProcessingParameterRasterLayer( *this );
3171 }
3172 
3174 {
3175  if ( !input.isValid() )
3176  return mFlags & FlagOptional;
3177 
3178  if ( input.canConvert<QgsProperty>() )
3179  {
3180  return true;
3181  }
3182 
3183  if ( qobject_cast< QgsRasterLayer * >( qvariant_cast<QObject *>( input ) ) )
3184  return true;
3185 
3186  if ( input.type() != QVariant::String || input.toString().isEmpty() )
3187  return mFlags & FlagOptional;
3188 
3189  if ( !context )
3190  {
3191  // that's as far as we can get without a context
3192  return true;
3193  }
3194 
3195  // try to load as layer
3196  if ( QgsProcessingUtils::mapLayerFromString( input.toString(), *context, true, QgsProcessingUtils::LayerHint::Raster ) )
3197  return true;
3198 
3199  return false;
3200 }
3201 
3203 {
3204  if ( !val.isValid() )
3205  return QStringLiteral( "None" );
3206 
3207  if ( val.canConvert<QgsProperty>() )
3208  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
3209 
3210  QVariantMap p;
3211  p.insert( name(), val );
3214  : QgsProcessingUtils::stringToPythonLiteral( val.toString() );
3215 }
3216 
3217 QgsProcessingParameterRasterLayer *QgsProcessingParameterRasterLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3218 {
3219  return new QgsProcessingParameterRasterLayer( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
3220 }
3221 
3222 QgsProcessingParameterEnum::QgsProcessingParameterEnum( const QString &name, const QString &description, const QStringList &options, bool allowMultiple, const QVariant &defaultValue, bool optional )
3223  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3224  , mOptions( options )
3225  , mAllowMultiple( allowMultiple )
3226 {
3227 
3228 }
3229 
3231 {
3232  return new QgsProcessingParameterEnum( *this );
3233 }
3234 
3236 {
3237  QVariant input = value;
3238  if ( !input.isValid() )
3239  {
3240  if ( !defaultValue().isValid() )
3241  return mFlags & FlagOptional;
3242 
3243  input = defaultValue();
3244  }
3245 
3246  if ( input.canConvert<QgsProperty>() )
3247  {
3248  return true;
3249  }
3250 
3251  if ( input.type() == QVariant::List )
3252  {
3253  if ( !mAllowMultiple )
3254  return false;
3255 
3256  const QVariantList values = input.toList();
3257  if ( values.empty() && !( mFlags & FlagOptional ) )
3258  return false;
3259 
3260  for ( const QVariant &val : values )
3261  {
3262  bool ok = false;
3263  int res = val.toInt( &ok );
3264  if ( !ok )
3265  return false;
3266  else if ( res < 0 || res >= mOptions.count() )
3267  return false;
3268  }
3269 
3270  return true;
3271  }
3272  else if ( input.type() == QVariant::String )
3273  {
3274  QStringList parts = input.toString().split( ',' );
3275  if ( parts.count() > 1 && !mAllowMultiple )
3276  return false;
3277 
3278  const auto constParts = parts;
3279  for ( const QString &part : constParts )
3280  {
3281  bool ok = false;
3282  int res = part.toInt( &ok );
3283  if ( !ok )
3284  return false;
3285  else if ( res < 0 || res >= mOptions.count() )
3286  return false;
3287  }
3288  return true;
3289  }
3290  else if ( input.type() == QVariant::Int || input.type() == QVariant::Double )
3291  {
3292  bool ok = false;
3293  int res = input.toInt( &ok );
3294  if ( !ok )
3295  return false;
3296  else if ( res >= 0 && res < mOptions.count() )
3297  return true;
3298  }
3299  return false;
3300 }
3301 
3303 {
3304  if ( !value.isValid() )
3305  return QStringLiteral( "None" );
3306 
3307  if ( value.canConvert<QgsProperty>() )
3308  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
3309 
3310  if ( value.type() == QVariant::List )
3311  {
3312  QStringList parts;
3313  const auto constToList = value.toList();
3314  for ( const QVariant &val : constToList )
3315  {
3316  parts << QString::number( static_cast< int >( val.toDouble() ) );
3317  }
3318  return parts.join( ',' ).prepend( '[' ).append( ']' );
3319  }
3320  else if ( value.type() == QVariant::String )
3321  {
3322  QStringList parts = value.toString().split( ',' );
3323  if ( parts.count() > 1 )
3324  {
3325  return parts.join( ',' ).prepend( '[' ).append( ']' );
3326  }
3327  }
3328 
3329  return QString::number( static_cast< int >( value.toDouble() ) );
3330 }
3331 
3333 {
3334  QString code = QStringLiteral( "##%1=" ).arg( mName );
3335  if ( mFlags & FlagOptional )
3336  code += QStringLiteral( "optional " );
3337  code += QStringLiteral( "enum " );
3338 
3339  if ( mAllowMultiple )
3340  code += QStringLiteral( "multiple " );
3341 
3342  code += mOptions.join( ';' ) + ' ';
3343 
3344  code += mDefault.toString();
3345  return code.trimmed();
3346 }
3347 
3349 {
3350  switch ( outputType )
3351  {
3353  {
3354  QString code = QStringLiteral( "QgsProcessingParameterEnum('%1', '%2'" ).arg( name(), description() );
3355  if ( mFlags & FlagOptional )
3356  code += QStringLiteral( ", optional=True" );
3357 
3358  QStringList options;
3359  options.reserve( mOptions.size() );
3360  for ( const QString &o : mOptions )
3362  code += QStringLiteral( ", options=[%1]" ).arg( options.join( ',' ) );
3363 
3364  code += QStringLiteral( ", allowMultiple=%1" ).arg( mAllowMultiple ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
3365 
3367  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
3368  return code;
3369  }
3370  }
3371  return QString();
3372 }
3373 
3375 {
3376  return mOptions;
3377 }
3378 
3380 {
3381  mOptions = options;
3382 }
3383 
3385 {
3386  return mAllowMultiple;
3387 }
3388 
3390 {
3391  mAllowMultiple = allowMultiple;
3392 }
3393 
3395 {
3397  map.insert( QStringLiteral( "options" ), mOptions );
3398  map.insert( QStringLiteral( "allow_multiple" ), mAllowMultiple );
3399  return map;
3400 }
3401 
3402 bool QgsProcessingParameterEnum::fromVariantMap( const QVariantMap &map )
3403 {
3405  mOptions = map.value( QStringLiteral( "options" ) ).toStringList();
3406  mAllowMultiple = map.value( QStringLiteral( "allow_multiple" ) ).toBool();
3407  return true;
3408 }
3409 
3410 QgsProcessingParameterEnum *QgsProcessingParameterEnum::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3411 {
3412  QString defaultVal;
3413  bool multiple = false;
3414  QString def = definition;
3415  if ( def.startsWith( QLatin1String( "multiple" ), Qt::CaseInsensitive ) )
3416  {
3417  multiple = true;
3418  def = def.mid( 9 );
3419  }
3420 
3421  QRegularExpression re( QStringLiteral( "(.*)\\s+(.*?)$" ) );
3422  QRegularExpressionMatch m = re.match( def );
3423  QString values = def;
3424  if ( m.hasMatch() )
3425  {
3426  values = m.captured( 1 ).trimmed();
3427  defaultVal = m.captured( 2 );
3428  }
3429 
3430  return new QgsProcessingParameterEnum( name, description, values.split( ';' ), multiple, defaultVal.isEmpty() ? QVariant() : defaultVal, isOptional );
3431 }
3432 
3433 QgsProcessingParameterString::QgsProcessingParameterString( const QString &name, const QString &description, const QVariant &defaultValue, bool multiLine, bool optional )
3434  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3435  , mMultiLine( multiLine )
3436 {
3437 
3438 }
3439 
3441 {
3442  return new QgsProcessingParameterString( *this );
3443 }
3444 
3446 {
3447  if ( !value.isValid() || value.isNull() )
3448  return QStringLiteral( "None" );
3449 
3450  if ( value.canConvert<QgsProperty>() )
3451  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
3452 
3453  QString s = value.toString();
3455 }
3456 
3458 {
3459  QString code = QStringLiteral( "##%1=" ).arg( mName );
3460  if ( mFlags & FlagOptional )
3461  code += QStringLiteral( "optional " );
3462  code += QStringLiteral( "string " );
3463 
3464  if ( mMultiLine )
3465  code += QStringLiteral( "long " );
3466 
3467  code += mDefault.toString();
3468  return code.trimmed();
3469 }
3470 
3472 {
3473  switch ( outputType )
3474  {
3476  {
3477  QString code = QStringLiteral( "QgsProcessingParameterString('%1', '%2'" ).arg( name(), description() );
3478  if ( mFlags & FlagOptional )
3479  code += QStringLiteral( ", optional=True" );
3480  code += QStringLiteral( ", multiLine=%1" ).arg( mMultiLine ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
3481 
3483  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
3484  return code;
3485  }
3486  }
3487  return QString();
3488 }
3489 
3491 {
3492  return mMultiLine;
3493 }
3494 
3496 {
3497  mMultiLine = multiLine;
3498 }
3499 
3501 {
3503  map.insert( QStringLiteral( "multiline" ), mMultiLine );
3504  return map;
3505 }
3506 
3507 bool QgsProcessingParameterString::fromVariantMap( const QVariantMap &map )
3508 {
3510  mMultiLine = map.value( QStringLiteral( "multiline" ) ).toBool();
3511  return true;
3512 }
3513 
3514 QgsProcessingParameterString *QgsProcessingParameterString::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3515 {
3516  QString def = definition;
3517  bool multiLine = false;
3518  if ( def.startsWith( QLatin1String( "long" ), Qt::CaseInsensitive ) )
3519  {
3520  multiLine = true;
3521  def = def.mid( 5 );
3522  }
3523 
3524  if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
3525  def = def.mid( 1 );
3526  if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
3527  def.chop( 1 );
3528 
3529  QVariant defaultValue = def;
3530  if ( def == QStringLiteral( "None" ) )
3531  defaultValue = QVariant();
3532 
3533  return new QgsProcessingParameterString( name, description, defaultValue, multiLine, isOptional );
3534 }
3535 
3536 //
3537 // QgsProcessingParameterAuthConfig
3538 //
3539 
3540 QgsProcessingParameterAuthConfig::QgsProcessingParameterAuthConfig( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
3541  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3542 {
3543 
3544 }
3545 
3547 {
3548  return new QgsProcessingParameterAuthConfig( *this );
3549 }
3550 
3552 {
3553  if ( !value.isValid() )
3554  return QStringLiteral( "None" );
3555 
3556  QString s = value.toString();
3558 }
3559 
3561 {
3562  QString code = QStringLiteral( "##%1=" ).arg( mName );
3563  if ( mFlags & FlagOptional )
3564  code += QStringLiteral( "optional " );
3565  code += QStringLiteral( "authcfg " );
3566 
3567  code += mDefault.toString();
3568  return code.trimmed();
3569 }
3570 
3571 QgsProcessingParameterAuthConfig *QgsProcessingParameterAuthConfig::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3572 {
3573  QString def = definition;
3574 
3575  if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
3576  def = def.mid( 1 );
3577  if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
3578  def.chop( 1 );
3579 
3580  QVariant defaultValue = def;
3581  if ( def == QStringLiteral( "None" ) )
3582  defaultValue = QVariant();
3583 
3584  return new QgsProcessingParameterAuthConfig( name, description, defaultValue, isOptional );
3585 }
3586 
3587 
3588 //
3589 // QgsProcessingParameterExpression
3590 //
3591 
3592 QgsProcessingParameterExpression::QgsProcessingParameterExpression( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayerParameterName, bool optional )
3593  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3594  , mParentLayerParameterName( parentLayerParameterName )
3595 {
3596 
3597 }
3598 
3600 {
3601  return new QgsProcessingParameterExpression( *this );
3602 }
3603 
3605 {
3606  if ( !value.isValid() )
3607  return QStringLiteral( "None" );
3608 
3609  if ( value.canConvert<QgsProperty>() )
3610  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
3611 
3612  QString s = value.toString();
3614 }
3615 
3617 {
3618  QStringList depends;
3619  if ( !mParentLayerParameterName.isEmpty() )
3620  depends << mParentLayerParameterName;
3621  return depends;
3622 }
3623 
3625 {
3626  switch ( outputType )
3627  {
3629  {
3630  QString code = QStringLiteral( "QgsProcessingParameterExpression('%1', '%2'" ).arg( name(), description() );
3631  if ( mFlags & FlagOptional )
3632  code += QStringLiteral( ", optional=True" );
3633 
3634  code += QStringLiteral( ", parentLayerParameterName='%1'" ).arg( mParentLayerParameterName );
3635 
3637  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
3638  return code;
3639  }
3640  }
3641  return QString();
3642 }
3643 
3645 {
3646  return mParentLayerParameterName;
3647 }
3648 
3650 {
3651  mParentLayerParameterName = parentLayerParameterName;
3652 }
3653 
3655 {
3657  map.insert( QStringLiteral( "parent_layer" ), mParentLayerParameterName );
3658  return map;
3659 }
3660 
3662 {
3664  mParentLayerParameterName = map.value( QStringLiteral( "parent_layer" ) ).toString();
3665  return true;
3666 }
3667 
3668 QgsProcessingParameterExpression *QgsProcessingParameterExpression::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3669 {
3670  return new QgsProcessingParameterExpression( name, description, definition, QString(), isOptional );
3671 }
3672 
3673 QgsProcessingParameterVectorLayer::QgsProcessingParameterVectorLayer( const QString &name, const QString &description, const QList<int> &types, const QVariant &defaultValue, bool optional )
3674  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3676 {
3677 
3678 }
3679 
3681 {
3682  return new QgsProcessingParameterVectorLayer( *this );
3683 }
3684 
3686 {
3687  if ( !v.isValid() )
3688  return mFlags & FlagOptional;
3689 
3690  QVariant var = v;
3691 
3692  if ( var.canConvert<QgsProperty>() )
3693  {
3694  QgsProperty p = var.value< QgsProperty >();
3696  {
3697  var = p.staticValue();
3698  }
3699  else
3700  {
3701  return true;
3702  }
3703  }
3704 
3705  if ( qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( var ) ) )
3706  return true;
3707 
3708  if ( var.type() != QVariant::String || var.toString().isEmpty() )
3709  return mFlags & FlagOptional;
3710 
3711  if ( !context )
3712  {
3713  // that's as far as we can get without a context
3714  return true;
3715  }
3716 
3717  // try to load as layer
3718  if ( QgsProcessingUtils::mapLayerFromString( var.toString(), *context, true, QgsProcessingUtils::LayerHint::Vector ) )
3719  return true;
3720 
3721  return false;
3722 }
3723 
3725 {
3726  if ( !val.isValid() )
3727  return QStringLiteral( "None" );
3728 
3729  if ( val.canConvert<QgsProperty>() )
3730  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
3731 
3732  QVariantMap p;
3733  p.insert( name(), val );
3736  : QgsProcessingUtils::stringToPythonLiteral( val.toString() );
3737 }
3738 
3740 {
3741  switch ( outputType )
3742  {
3744  {
3745  QString code = QStringLiteral( "QgsProcessingParameterVectorLayer('%1', '%2'" ).arg( name(), description() );
3746  if ( mFlags & FlagOptional )
3747  code += QStringLiteral( ", optional=True" );
3748 
3749  if ( !mDataTypes.empty() )
3750  {
3751  QStringList options;
3752  for ( int t : mDataTypes )
3753  options << QStringLiteral( "QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( static_cast< QgsProcessing::SourceType >( t ) ) );
3754  code += QStringLiteral( ", types=[%1]" ).arg( options.join( ',' ) );
3755  }
3756 
3758  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
3759  return code;
3760  }
3761  }
3762  return QString();
3763 }
3764 
3766 {
3767  return mDataTypes;
3768 }
3769 
3771 {
3772  mDataTypes = types;
3773 }
3774 
3776 {
3778  QVariantList types;
3779  const auto constMDataTypes = mDataTypes;
3780  for ( int type : constMDataTypes )
3781  {
3782  types << type;
3783  }
3784  map.insert( QStringLiteral( "data_types" ), types );
3785  return map;
3786 }
3787 
3789 {
3791  mDataTypes.clear();
3792  QVariantList values = map.value( QStringLiteral( "data_types" ) ).toList();
3793  const auto constValues = values;
3794  for ( const QVariant &val : constValues )
3795  {
3796  mDataTypes << val.toInt();
3797  }
3798  return true;
3799 }
3800 
3801 QgsProcessingParameterVectorLayer *QgsProcessingParameterVectorLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3802 {
3803  return new QgsProcessingParameterVectorLayer( name, description, QList< int>(), definition.isEmpty() ? QVariant() : definition, isOptional );
3804 }
3805 
3807  const QString &description,
3808  const QVariant &defaultValue,
3809  bool optional )
3810  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3811 {
3812 
3813 }
3814 
3816 {
3817  return new QgsProcessingParameterMeshLayer( *this );
3818 }
3819 
3821 {
3822  if ( !v.isValid() )
3823  return mFlags & FlagOptional;
3824 
3825  QVariant var = v;
3826 
3827  if ( var.canConvert<QgsProperty>() )
3828  {
3829  QgsProperty p = var.value< QgsProperty >();
3831  {
3832  var = p.staticValue();
3833  }
3834  else
3835  {
3836  return true;
3837  }
3838  }
3839 
3840  if ( qobject_cast< QgsMeshLayer * >( qvariant_cast<QObject *>( var ) ) )
3841  return true;
3842 
3843  if ( var.type() != QVariant::String || var.toString().isEmpty() )
3844  return mFlags & FlagOptional;
3845 
3846  if ( !context )
3847  {
3848  // that's as far as we can get without a context
3849  return true;
3850  }
3851 
3852  // try to load as layer
3853  if ( QgsProcessingUtils::mapLayerFromString( var.toString(), *context, true, QgsProcessingUtils::LayerHint::Mesh ) )
3854  return true;
3855 
3856  return false;
3857 }
3858 
3860 {
3861  if ( !val.isValid() )
3862  return QStringLiteral( "None" );
3863 
3864  if ( val.canConvert<QgsProperty>() )
3865  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
3866 
3867  QVariantMap p;
3868  p.insert( name(), val );
3869  QgsMeshLayer *layer = QgsProcessingParameters::parameterAsMeshLayer( this, p, context );
3871  : QgsProcessingUtils::stringToPythonLiteral( val.toString() );
3872 }
3873 
3874 QgsProcessingParameterMeshLayer *QgsProcessingParameterMeshLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3875 {
3876  return new QgsProcessingParameterMeshLayer( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
3877 }
3878 
3879 QgsProcessingParameterField::QgsProcessingParameterField( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayerParameterName, DataType type, bool allowMultiple, bool optional, bool defaultToAllFields )
3880  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3881  , mParentLayerParameterName( parentLayerParameterName )
3882  , mDataType( type )
3883  , mAllowMultiple( allowMultiple )
3884  , mDefaultToAllFields( defaultToAllFields )
3885 {
3886 
3887 }
3888 
3889 
3891 {
3892  return new QgsProcessingParameterField( *this );
3893 }
3894 
3896 {
3897  if ( !input.isValid() )
3898  return mFlags & FlagOptional;
3899 
3900  if ( input.canConvert<QgsProperty>() )
3901  {
3902  return true;
3903  }
3904 
3905  if ( input.type() == QVariant::List || input.type() == QVariant::StringList )
3906  {
3907  if ( !mAllowMultiple )
3908  return false;
3909 
3910  if ( input.toList().isEmpty() && !( mFlags & FlagOptional ) )
3911  return false;
3912  }
3913  else if ( input.type() == QVariant::String )
3914  {
3915  if ( input.toString().isEmpty() )
3916  return mFlags & FlagOptional;
3917 
3918  QStringList parts = input.toString().split( ';' );
3919  if ( parts.count() > 1 && !mAllowMultiple )
3920  return false;
3921  }
3922  else
3923  {
3924  if ( input.toString().isEmpty() )
3925  return mFlags & FlagOptional;
3926  }
3927  return true;
3928 }
3929 
3931 {
3932  if ( !value.isValid() )
3933  return QStringLiteral( "None" );
3934 
3935  if ( value.canConvert<QgsProperty>() )
3936  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
3937 
3938  if ( value.type() == QVariant::List )
3939  {
3940  QStringList parts;
3941  const auto constToList = value.toList();
3942  for ( const QVariant &val : constToList )
3943  {
3944  parts << QgsProcessingUtils::stringToPythonLiteral( val.toString() );
3945  }
3946  return parts.join( ',' ).prepend( '[' ).append( ']' );
3947  }
3948  else if ( value.type() == QVariant::StringList )
3949  {
3950  QStringList parts;
3951  const auto constToStringList = value.toStringList();
3952  for ( QString s : constToStringList )
3953  {
3955  }
3956  return parts.join( ',' ).prepend( '[' ).append( ']' );
3957  }
3958 
3959  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
3960 }
3961 
3963 {
3964  QString code = QStringLiteral( "##%1=" ).arg( mName );
3965  if ( mFlags & FlagOptional )
3966  code += QStringLiteral( "optional " );
3967  code += QStringLiteral( "field " );
3968 
3969  switch ( mDataType )
3970  {
3971  case Numeric:
3972  code += QStringLiteral( "numeric " );
3973  break;
3974 
3975  case String:
3976  code += QStringLiteral( "string " );
3977  break;
3978 
3979  case DateTime:
3980  code += QStringLiteral( "datetime " );
3981  break;
3982 
3983  case Any:
3984  break;
3985  }
3986 
3987  if ( mAllowMultiple )
3988  code += QStringLiteral( "multiple " );
3989 
3990  if ( mDefaultToAllFields )
3991  code += QStringLiteral( "default_to_all_fields " );
3992 
3993  code += mParentLayerParameterName + ' ';
3994 
3995  code += mDefault.toString();
3996  return code.trimmed();
3997 }
3998 
4000 {
4001  switch ( outputType )
4002  {
4004  {
4005  QString code = QStringLiteral( "QgsProcessingParameterField('%1', '%2'" ).arg( name(), description() );
4006  if ( mFlags & FlagOptional )
4007  code += QStringLiteral( ", optional=True" );
4008 
4009  QString dataType;
4010  switch ( mDataType )
4011  {
4012  case Any:
4013  dataType = QStringLiteral( "QgsProcessingParameterField.Any" );
4014  break;
4015 
4016  case Numeric:
4017  dataType = QStringLiteral( "QgsProcessingParameterField.Numeric" );
4018  break;
4019 
4020  case String:
4021  dataType = QStringLiteral( "QgsProcessingParameterField.String" );
4022  break;
4023 
4024  case DateTime:
4025  dataType = QStringLiteral( "QgsProcessingParameterField.DateTime" );
4026  break;
4027  }
4028  code += QStringLiteral( ", type=%1" ).arg( dataType );
4029 
4030  code += QStringLiteral( ", parentLayerParameterName='%1'" ).arg( mParentLayerParameterName );
4031  code += QStringLiteral( ", allowMultiple=%1" ).arg( mAllowMultiple ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
4033  code += QStringLiteral( ", defaultValue=%1" ).arg( valueAsPythonString( mDefault, c ) );
4034 
4035  if ( mDefaultToAllFields )
4036  code += QStringLiteral( ", defaultToAllFields=True" );
4037 
4038  code += ')';
4039 
4040  return code;
4041  }
4042  }
4043  return QString();
4044 }
4045 
4047 {
4048  QStringList depends;
4049  if ( !mParentLayerParameterName.isEmpty() )
4050  depends << mParentLayerParameterName;
4051  return depends;
4052 }
4053 
4055 {
4056  return mParentLayerParameterName;
4057 }
4058 
4060 {
4061  mParentLayerParameterName = parentLayerParameterName;
4062 }
4063 
4065 {
4066  return mDataType;
4067 }
4068 
4070 {
4071  mDataType = dataType;
4072 }
4073 
4075 {
4076  return mAllowMultiple;
4077 }
4078 
4080 {
4081  mAllowMultiple = allowMultiple;
4082 }
4083 
4085 {
4086  return mDefaultToAllFields;
4087 }
4088 
4090 {
4091  mDefaultToAllFields = enabled;
4092 }
4093 
4095 {
4097  map.insert( QStringLiteral( "parent_layer" ), mParentLayerParameterName );
4098  map.insert( QStringLiteral( "data_type" ), mDataType );
4099  map.insert( QStringLiteral( "allow_multiple" ), mAllowMultiple );
4100  map.insert( QStringLiteral( "default_to_all_fields" ), mDefaultToAllFields );
4101  return map;
4102 }
4103 
4104 bool QgsProcessingParameterField::fromVariantMap( const QVariantMap &map )
4105 {
4107  mParentLayerParameterName = map.value( QStringLiteral( "parent_layer" ) ).toString();
4108  mDataType = static_cast< DataType >( map.value( QStringLiteral( "data_type" ) ).toInt() );
4109  mAllowMultiple = map.value( QStringLiteral( "allow_multiple" ) ).toBool();
4110  mDefaultToAllFields = map.value( QStringLiteral( "default_to_all_fields" ) ).toBool();
4111  return true;
4112 }
4113 
4114 QgsProcessingParameterField *QgsProcessingParameterField::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4115 {
4116  QString parent;
4117  DataType type = Any;
4118  bool allowMultiple = false;
4119  bool defaultToAllFields = false;
4120  QString def = definition;
4121 
4122  if ( def.startsWith( QLatin1String( "numeric " ), Qt::CaseInsensitive ) )
4123  {
4124  type = Numeric;
4125  def = def.mid( 8 );
4126  }
4127  else if ( def.startsWith( QLatin1String( "string " ), Qt::CaseInsensitive ) )
4128  {
4129  type = String;
4130  def = def.mid( 7 );
4131  }
4132  else if ( def.startsWith( QLatin1String( "datetime " ), Qt::CaseInsensitive ) )
4133  {
4134  type = DateTime;
4135  def = def.mid( 9 );
4136  }
4137 
4138  if ( def.startsWith( QLatin1String( "multiple" ), Qt::CaseInsensitive ) )
4139  {
4140  allowMultiple = true;
4141  def = def.mid( 8 ).trimmed();
4142  }
4143 
4144  if ( def.startsWith( QLatin1String( "default_to_all_fields" ), Qt::CaseInsensitive ) )
4145  {
4146  defaultToAllFields = true;
4147  def = def.mid( 21 ).trimmed();
4148  }
4149 
4150  QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*)$" ) );
4151  QRegularExpressionMatch m = re.match( def );
4152  if ( m.hasMatch() )
4153  {
4154  parent = m.captured( 1 ).trimmed();
4155  def = m.captured( 2 );
4156  }
4157  else
4158  {
4159  parent = def;
4160  def.clear();
4161  }
4162 
4163  return new QgsProcessingParameterField( name, description, def.isEmpty() ? QVariant() : def, parent, type, allowMultiple, isOptional, defaultToAllFields );
4164 }
4165 
4166 QgsProcessingParameterFeatureSource::QgsProcessingParameterFeatureSource( const QString &name, const QString &description, const QList<int> &types, const QVariant &defaultValue, bool optional )
4167  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4169 {
4170 
4171 }
4172 
4174 {
4175  return new QgsProcessingParameterFeatureSource( *this );
4176 }
4177 
4179 {
4180  QVariant var = input;
4181  if ( !var.isValid() )
4182  return mFlags & FlagOptional;
4183 
4184  if ( var.canConvert<QgsProcessingFeatureSourceDefinition>() )
4185  {
4187  var = fromVar.source;
4188  }
4189  else if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
4190  {
4191  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
4193  var = fromVar.sink;
4194  }
4195 
4196  if ( var.canConvert<QgsProperty>() )
4197  {
4198  QgsProperty p = var.value< QgsProperty >();
4200  {
4201  var = p.staticValue();
4202  }
4203  else
4204  {
4205  return true;
4206  }
4207  }
4208  if ( qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( input ) ) )
4209  {
4210  return true;
4211  }
4212 
4213  if ( var.type() != QVariant::String || var.toString().isEmpty() )
4214  return mFlags & FlagOptional;
4215 
4216  if ( !context )
4217  {
4218  // that's as far as we can get without a context
4219  return true;
4220  }
4221 
4222  // try to load as layer
4223  if ( QgsProcessingUtils::mapLayerFromString( var.toString(), *context, true, QgsProcessingUtils::LayerHint::Vector ) )
4224  return true;
4225 
4226  return false;
4227 }
4228 
4230 {
4231  if ( !value.isValid() )
4232  return QStringLiteral( "None" );
4233 
4234  if ( value.canConvert<QgsProperty>() )
4235  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4236 
4237  if ( value.canConvert<QgsProcessingFeatureSourceDefinition>() )
4238  {
4240  if ( fromVar.source.propertyType() == QgsProperty::StaticProperty )
4241  {
4242  if ( fromVar.selectedFeaturesOnly )
4243  {
4244  return QStringLiteral( "QgsProcessingFeatureSourceDefinition('%1', True)" ).arg( fromVar.source.staticValue().toString() );
4245  }
4246  else
4247  {
4248  QString layerString = fromVar.source.staticValue().toString();
4249  // prefer to use layer source instead of id if possible (since it's persistent)
4250  if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( QgsProcessingUtils::mapLayerFromString( layerString, context, true, QgsProcessingUtils::LayerHint::Vector ) ) )
4251  layerString = layer->source();
4252  return QgsProcessingUtils::stringToPythonLiteral( layerString );
4253  }
4254  }
4255  else
4256  {
4257  if ( fromVar.selectedFeaturesOnly )
4258  {
4259  return QStringLiteral( "QgsProcessingFeatureSourceDefinition(QgsProperty.fromExpression('%1'), True)" ).arg( fromVar.source.asExpression() );
4260  }
4261  else
4262  {
4263  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.source.asExpression() );
4264  }
4265  }
4266  }
4267  else if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( value ) ) )
4268  {
4269  return QgsProcessingUtils::stringToPythonLiteral( layer->source() );
4270  }
4271 
4272  QString layerString = value.toString();
4273 
4274  // prefer to use layer source if possible (since it's persistent)
4275  if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( QgsProcessingUtils::mapLayerFromString( layerString, context, true, QgsProcessingUtils::LayerHint::Vector ) ) )
4276  layerString = layer->source();
4277 
4278  return QgsProcessingUtils::stringToPythonLiteral( layerString );
4279 }
4280 
4282 {
4283  QString code = QStringLiteral( "##%1=" ).arg( mName );
4284  if ( mFlags & FlagOptional )
4285  code += QStringLiteral( "optional " );
4286  code += QStringLiteral( "source " );
4287 
4288  const auto constMDataTypes = mDataTypes;
4289  for ( int type : constMDataTypes )
4290  {
4291  switch ( type )
4292  {
4294  code += QStringLiteral( "point " );
4295  break;
4296 
4298  code += QStringLiteral( "line " );
4299  break;
4300 
4302  code += QStringLiteral( "polygon " );
4303  break;
4304 
4305  }
4306  }
4307 
4308  code += mDefault.toString();
4309  return code.trimmed();
4310 }
4311 
4313 {
4314  switch ( outputType )
4315  {
4317  {
4318  QString code = QStringLiteral( "QgsProcessingParameterFeatureSource('%1', '%2'" ).arg( name(), description() );
4319  if ( mFlags & FlagOptional )
4320  code += QStringLiteral( ", optional=True" );
4321 
4322  if ( !mDataTypes.empty() )
4323  {
4324  QStringList options;
4325  options.reserve( mDataTypes.size() );
4326  for ( int t : mDataTypes )
4327  options << QStringLiteral( "QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( static_cast< QgsProcessing::SourceType >( t ) ) );
4328  code += QStringLiteral( ", types=[%1]" ).arg( options.join( ',' ) );
4329  }
4330 
4332  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4333  return code;
4334  }
4335  }
4336  return QString();
4337 }
4338 
4340  : mDataTypes( types )
4341 {
4342 
4343 }
4344 
4346 {
4348  QVariantList types;
4349  const auto constMDataTypes = mDataTypes;
4350  for ( int type : constMDataTypes )
4351  {
4352  types << type;
4353  }
4354  map.insert( QStringLiteral( "data_types" ), types );
4355  return map;
4356 }
4357 
4359 {
4361  mDataTypes.clear();
4362  QVariantList values = map.value( QStringLiteral( "data_types" ) ).toList();
4363  const auto constValues = values;
4364  for ( const QVariant &val : constValues )
4365  {
4366  mDataTypes << val.toInt();
4367  }
4368  return true;
4369 }
4370 
4371 QgsProcessingParameterFeatureSource *QgsProcessingParameterFeatureSource::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4372 {
4373  QList< int > types;
4374  QString def = definition;
4375  while ( true )
4376  {
4377  if ( def.startsWith( QLatin1String( "point" ), Qt::CaseInsensitive ) )
4378  {
4380  def = def.mid( 6 );
4381  continue;
4382  }
4383  else if ( def.startsWith( QLatin1String( "line" ), Qt::CaseInsensitive ) )
4384  {
4386  def = def.mid( 5 );
4387  continue;
4388  }
4389  else if ( def.startsWith( QLatin1String( "polygon" ), Qt::CaseInsensitive ) )
4390  {
4392  def = def.mid( 8 );
4393  continue;
4394  }
4395  break;
4396  }
4397 
4398  return new QgsProcessingParameterFeatureSource( name, description, types, def, isOptional );
4399 }
4400 
4401 QgsProcessingParameterFeatureSink::QgsProcessingParameterFeatureSink( const QString &name, const QString &description, QgsProcessing::SourceType type, const QVariant &defaultValue, bool optional, bool createByDefault )
4402  : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
4403  , mDataType( type )
4404 {
4405 }
4406 
4408 {
4409  return new QgsProcessingParameterFeatureSink( *this );
4410 }
4411 
4413 {
4414  QVariant var = input;
4415  if ( !var.isValid() )
4416  return mFlags & FlagOptional;
4417 
4418  if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
4419  {
4421  var = fromVar.sink;
4422  }
4423 
4424  if ( var.canConvert<QgsProperty>() )
4425  {
4426  QgsProperty p = var.value< QgsProperty >();
4428  {
4429  var = p.staticValue();
4430  }
4431  else
4432  {
4433  return true;
4434  }
4435  }
4436 
4437  if ( var.type() != QVariant::String )
4438  return false;
4439 
4440  if ( var.toString().isEmpty() )
4441  return mFlags & FlagOptional;
4442 
4443  return true;
4444 }
4445 
4447 {
4448  if ( !value.isValid() )
4449  return QStringLiteral( "None" );
4450 
4451  if ( value.canConvert<QgsProperty>() )
4452  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4453 
4454  if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
4455  {
4457  if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
4458  {
4459  return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
4460  }
4461  else
4462  {
4463  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
4464  }
4465  }
4466 
4467  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
4468 }
4469 
4471 {
4472  QString code = QStringLiteral( "##%1=" ).arg( mName );
4473  if ( mFlags & FlagOptional )
4474  code += QStringLiteral( "optional " );
4475  code += QStringLiteral( "sink " );
4476 
4477  switch ( mDataType )
4478  {
4480  code += QStringLiteral( "point " );
4481  break;
4482 
4484  code += QStringLiteral( "line " );
4485  break;
4486 
4488  code += QStringLiteral( "polygon " );
4489  break;
4490 
4492  code += QStringLiteral( "table " );
4493  break;
4494 
4495  default:
4496  break;
4497  }
4498 
4499  code += mDefault.toString();
4500  return code.trimmed();
4501 }
4502 
4504 {
4505  return new QgsProcessingOutputVectorLayer( name(), description(), mDataType );
4506 }
4507 
4509 {
4510  if ( originalProvider() )
4511  {
4513  }
4514  else if ( QgsProcessingProvider *p = provider() )
4515  {
4516  return p->defaultVectorFileExtension( hasGeometry() );
4517  }
4518  else
4519  {
4520  if ( hasGeometry() )
4521  {
4523  }
4524  else
4525  {
4526  return QStringLiteral( "dbf" );
4527  }
4528  }
4529 }
4530 
4532 {
4533  switch ( outputType )
4534  {
4536  {
4537  QString code = QStringLiteral( "QgsProcessingParameterFeatureSink('%1', '%2'" ).arg( name(), description() );
4538  if ( mFlags & FlagOptional )
4539  code += QStringLiteral( ", optional=True" );
4540 
4541  code += QStringLiteral( ", type=QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( mDataType ) );
4542 
4543  code += QStringLiteral( ", createByDefault=%1" ).arg( createByDefault() ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
4544 
4546  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4547  return code;
4548  }
4549  }
4550  return QString();
4551 }
4552 
4554 {
4555  if ( originalProvider() )
4556  {
4557  if ( hasGeometry() )
4559  else
4561  }
4562  else if ( QgsProcessingProvider *p = provider() )
4563  {
4564  if ( hasGeometry() )
4565  return p->supportedOutputVectorLayerExtensions();
4566  else
4567  return p->supportedOutputTableExtensions();
4568  }
4569  else
4570  {
4572  }
4573 }
4574 
4576 {
4577  return mDataType;
4578 }
4579 
4581 {
4582  switch ( mDataType )
4583  {
4589  return true;
4590 
4595  return false;
4596  }
4597  return true;
4598 }
4599 
4601 {
4602  mDataType = type;
4603 }
4604 
4606 {
4608  map.insert( QStringLiteral( "data_type" ), mDataType );
4609  return map;
4610 }
4611 
4613 {
4615  mDataType = static_cast< QgsProcessing::SourceType >( map.value( QStringLiteral( "data_type" ) ).toInt() );
4616  return true;
4617 }
4618 
4620 {
4622  return QStringLiteral( "memory:%1" ).arg( description() );
4623  else
4625 }
4626 
4627 QgsProcessingParameterFeatureSink *QgsProcessingParameterFeatureSink::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4628 {
4630  QString def = definition;
4631  if ( def.startsWith( QLatin1String( "point" ), Qt::CaseInsensitive ) )
4632  {
4634  def = def.mid( 6 );
4635  }
4636  else if ( def.startsWith( QLatin1String( "line" ), Qt::CaseInsensitive ) )
4637  {
4639  def = def.mid( 5 );
4640  }
4641  else if ( def.startsWith( QLatin1String( "polygon" ), Qt::CaseInsensitive ) )
4642  {
4644  def = def.mid( 8 );
4645  }
4646  else if ( def.startsWith( QLatin1String( "table" ), Qt::CaseInsensitive ) )
4647  {
4649  def = def.mid( 6 );
4650  }
4651 
4652  return new QgsProcessingParameterFeatureSink( name, description, type, definition, isOptional );
4653 }
4654 
4656  : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
4657 {
4658 }
4659 
4661 {
4662  return new QgsProcessingParameterRasterDestination( *this );
4663 }
4664 
4666 {
4667  QVariant var = input;
4668  if ( !var.isValid() )
4669  return mFlags & FlagOptional;
4670 
4671  if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
4672  {
4674  var = fromVar.sink;
4675  }
4676 
4677  if ( var.canConvert<QgsProperty>() )
4678  {
4679  QgsProperty p = var.value< QgsProperty >();
4681  {
4682  var = p.staticValue();
4683  }
4684  else
4685  {
4686  return true;
4687  }
4688  }
4689 
4690  if ( var.type() != QVariant::String )
4691  return false;
4692 
4693  if ( var.toString().isEmpty() )
4694  return mFlags & FlagOptional;
4695 
4696  return true;
4697 }
4698 
4700 {
4701  if ( !value.isValid() )
4702  return QStringLiteral( "None" );
4703 
4704  if ( value.canConvert<QgsProperty>() )
4705  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4706 
4707  if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
4708  {
4710  if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
4711  {
4712  return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
4713  }
4714  else
4715  {
4716  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
4717  }
4718  }
4719 
4720  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
4721 }
4722 
4724 {
4725  return new QgsProcessingOutputRasterLayer( name(), description() );
4726 }
4727 
4729 {
4730  if ( originalProvider() )
4731  {
4733  }
4734  else if ( QgsProcessingProvider *p = provider() )
4735  {
4736  return p->defaultRasterFileExtension();
4737  }
4738  else
4739  {
4741  }
4742 }
4743 
4745 {
4746  if ( originalProvider() )
4747  {
4749  }
4750  else if ( QgsProcessingProvider *p = provider() )
4751  {
4752  return p->supportedOutputRasterLayerExtensions();
4753  }
4754  else
4755  {
4757  }
4758 }
4759 
4760 QgsProcessingParameterRasterDestination *QgsProcessingParameterRasterDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4761 {
4762  return new QgsProcessingParameterRasterDestination( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
4763 }
4764 
4765 
4766 QgsProcessingParameterFileDestination::QgsProcessingParameterFileDestination( const QString &name, const QString &description, const QString &fileFilter, const QVariant &defaultValue, bool optional, bool createByDefault )
4767  : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
4768  , mFileFilter( fileFilter.isEmpty() ? QObject::tr( "All files (*.*)" ) : fileFilter )
4769 {
4770 
4771 }
4772 
4774 {
4775  return new QgsProcessingParameterFileDestination( *this );
4776 }
4777 
4779 {
4780  QVariant var = input;
4781  if ( !var.isValid() )
4782  return mFlags & FlagOptional;
4783 
4784  if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
4785  {
4787  var = fromVar.sink;
4788  }
4789 
4790  if ( var.canConvert<QgsProperty>() )
4791  {
4792  QgsProperty p = var.value< QgsProperty >();
4794  {
4795  var = p.staticValue();
4796  }
4797  else
4798  {
4799  return true;
4800  }
4801  }
4802 
4803  if ( var.type() != QVariant::String )
4804  return false;
4805 
4806  if ( var.toString().isEmpty() )
4807  return mFlags & FlagOptional;
4808 
4809  // possible enhancement - check that value is compatible with file filter?
4810 
4811  return true;
4812 }
4813 
4815 {
4816  if ( !value.isValid() )
4817  return QStringLiteral( "None" );
4818 
4819  if ( value.canConvert<QgsProperty>() )
4820  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4821 
4822  if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
4823  {
4825  if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
4826  {
4827  return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
4828  }
4829  else
4830  {
4831  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
4832  }
4833  }
4834 
4835  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
4836 }
4837 
4839 {
4840  if ( !mFileFilter.isEmpty() && mFileFilter.contains( QStringLiteral( "htm" ), Qt::CaseInsensitive ) )
4841  {
4842  return new QgsProcessingOutputHtml( name(), description() );
4843  }
4844  else
4845  {
4846  return new QgsProcessingOutputFile( name(), description() );
4847  }
4848 }
4849 
4851 {
4852  if ( mFileFilter.isEmpty() || mFileFilter == QObject::tr( "All files (*.*)" ) )
4853  return QStringLiteral( "file" );
4854 
4855  // get first extension from filter
4856  QRegularExpression rx( QStringLiteral( ".*?\\(\\*\\.([a-zA-Z0-9._]+).*" ) );
4857  QRegularExpressionMatch match = rx.match( mFileFilter );
4858  if ( !match.hasMatch() )
4859  return QStringLiteral( "file" );
4860 
4861  return match.captured( 1 );
4862 }
4863 
4865 {
4866  switch ( outputType )
4867  {
4869  {
4870  QString code = QStringLiteral( "QgsProcessingParameterFileDestination('%1', '%2'" ).arg( name(), description() );
4871  if ( mFlags & FlagOptional )
4872  code += QStringLiteral( ", optional=True" );
4873 
4874  code += QStringLiteral( ", fileFilter=%1" ).arg( QgsProcessingUtils::stringToPythonLiteral( mFileFilter ) );
4875 
4876  code += QStringLiteral( ", createByDefault=%1" ).arg( createByDefault() ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
4877 
4879  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4880  return code;
4881  }
4882  }
4883  return QString();
4884 }
4885 
4887 {
4888  return mFileFilter;
4889 }
4890 
4892 {
4893  mFileFilter = fileFilter;
4894 }
4895 
4897 {
4899  map.insert( QStringLiteral( "file_filter" ), mFileFilter );
4900  return map;
4901 }
4902 
4904 {
4906  mFileFilter = map.value( QStringLiteral( "file_filter" ) ).toString();
4907  return true;
4908 
4909 }
4910 
4911 QgsProcessingParameterFileDestination *QgsProcessingParameterFileDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4912 {
4913  return new QgsProcessingParameterFileDestination( name, description, QString(), definition.isEmpty() ? QVariant() : definition, isOptional );
4914 }
4915 
4917  : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
4918 {}
4919 
4921 {
4922  return new QgsProcessingParameterFolderDestination( *this );
4923 }
4924 
4926 {
4927  QVariant var = input;
4928  if ( !var.isValid() )
4929  return mFlags & FlagOptional;
4930 
4931  if ( var.canConvert<QgsProperty>() )
4932  {
4933  QgsProperty p = var.value< QgsProperty >();
4935  {
4936  var = p.staticValue();
4937  }
4938  else
4939  {
4940  return true;
4941  }
4942  }
4943 
4944  if ( var.type() != QVariant::String )
4945  return false;
4946 
4947  if ( var.toString().isEmpty() )
4948  return mFlags & FlagOptional;
4949 
4950  return true;
4951 }
4952 
4954 {
4955  return new QgsProcessingOutputFolder( name(), description() );
4956 }
4957 
4959 {
4960  return QString();
4961 }
4962 
4963 QgsProcessingParameterFolderDestination *QgsProcessingParameterFolderDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4964 {
4965  return new QgsProcessingParameterFolderDestination( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
4966 }
4967 
4968 QgsProcessingDestinationParameter::QgsProcessingDestinationParameter( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, bool createByDefault )
4969  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4970  , mCreateByDefault( createByDefault )
4971 {
4972 
4973 }
4974 
4976 {
4978  map.insert( QStringLiteral( "supports_non_file_outputs" ), mSupportsNonFileBasedOutputs );
4979  map.insert( QStringLiteral( "create_by_default" ), mCreateByDefault );
4980  return map;
4981 }
4982 
4984 {
4986  mSupportsNonFileBasedOutputs = map.value( QStringLiteral( "supports_non_file_outputs" ) ).toBool();
4987  mCreateByDefault = map.value( QStringLiteral( "create_by_default" ), QStringLiteral( "1" ) ).toBool();
4988  return true;
4989 }
4990 
4992 {
4993  switch ( outputType )
4994  {
4996  {
4997  // base class method is probably not much use
4998  if ( QgsProcessingParameterType *t = QgsApplication::processingRegistry()->parameterType( type() ) )
4999  {
5000  QString code = t->className() + QStringLiteral( "('%1', '%2'" ).arg( name(), description() );
5001  if ( mFlags & FlagOptional )
5002  code += QStringLiteral( ", optional=True" );
5003 
5004  code += QStringLiteral( ", createByDefault=%1" ).arg( mCreateByDefault ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
5005 
5007  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
5008  return code;
5009  }
5010  break;
5011  }
5012  }
5013  // oh well, we tried
5014  return QString();
5015 }
5016 
5018 {
5019  if ( defaultFileExtension().isEmpty() )
5020  {
5022  }
5023  else
5024  {
5026  }
5027 }
5028 
5030 {
5031  return mCreateByDefault;
5032 }
5033 
5035 {
5036  mCreateByDefault = createByDefault;
5037 }
5038 
5040  : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
5041  , mDataType( type )
5042 {
5043 
5044 }
5045 
5047 {
5048  return new QgsProcessingParameterVectorDestination( *this );
5049 }
5050 
5052 {
5053  QVariant var = input;
5054  if ( !var.isValid() )
5055  return mFlags & FlagOptional;
5056 
5057  if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
5058  {
5060  var = fromVar.sink;
5061  }
5062 
5063  if ( var.canConvert<QgsProperty>() )
5064  {
5065  QgsProperty p = var.value< QgsProperty >();
5067  {
5068  var = p.staticValue();
5069  }
5070  else
5071  {
5072  return true;
5073  }
5074  }
5075 
5076  if ( var.type() != QVariant::String )
5077  return false;
5078 
5079  if ( var.toString().isEmpty() )
5080  return mFlags & FlagOptional;
5081 
5082  return true;
5083 }
5084 
5086 {
5087  if ( !value.isValid() )
5088  return QStringLiteral( "None" );
5089 
5090  if ( value.canConvert<QgsProperty>() )
5091  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
5092 
5093  if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
5094  {
5096  if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
5097  {
5098  return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
5099  }
5100  else
5101  {
5102  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
5103  }
5104  }
5105 
5106  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
5107 }
5108 
5110 {
5111  QString code = QStringLiteral( "##%1=" ).arg( mName );
5112  if ( mFlags & FlagOptional )
5113  code += QStringLiteral( "optional " );
5114  code += QStringLiteral( "vectorDestination " );
5115 
5116  switch ( mDataType )
5117  {
5119  code += QStringLiteral( "point " );
5120  break;
5121 
5123  code += QStringLiteral( "line " );
5124  break;
5125 
5127  code += QStringLiteral( "polygon " );
5128  break;
5129 
5130  default:
5131  break;
5132  }
5133 
5134  code += mDefault.toString();
5135  return code.trimmed();
5136 }
5137 
5139 {
5140  return new QgsProcessingOutputVectorLayer( name(), description(), mDataType );
5141 }
5142 
5144 {
5145  if ( originalProvider() )
5146  {
5148  }
5149  else if ( QgsProcessingProvider *p = provider() )
5150  {
5151  return p->defaultVectorFileExtension( hasGeometry() );
5152  }
5153  else
5154  {
5155  if ( hasGeometry() )
5156  {
5158  }
5159  else
5160  {
5161  return QStringLiteral( "dbf" );
5162  }
5163  }
5164 }
5165 
5167 {
5168  switch ( outputType )
5169  {
5171  {
5172  QString code = QStringLiteral( "QgsProcessingParameterVectorDestination('%1', '%2'" ).arg( name(), description() );
5173  if ( mFlags & FlagOptional )
5174  code += QStringLiteral( ", optional=True" );
5175 
5176  code += QStringLiteral( ", type=QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( mDataType ) );
5177 
5178  code += QStringLiteral( ", createByDefault=%1" ).arg( createByDefault() ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
5179 
5181  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
5182  return code;
5183  }
5184  }
5185  return QString();
5186 }
5187 
5189 {
5190  if ( originalProvider() )
5191  {
5192  if ( hasGeometry() )
5194  else
5196  }
5197  else if ( QgsProcessingProvider *p = provider() )
5198  {
5199  if ( hasGeometry() )
5200  return p->supportedOutputVectorLayerExtensions();
5201  else
5202  return p->supportedOutputTableExtensions();
5203  }
5204  else
5205  {
5207  }
5208 }
5209 
5211 {
5212  return mDataType;
5213 }
5214 
5216 {
5217  switch ( mDataType )
5218  {
5224  return true;
5225 
5230  return false;
5231  }
5232  return true;
5233 }
5234 
5236 {
5237  mDataType = type;
5238 }
5239 
5241 {
5243  map.insert( QStringLiteral( "data_type" ), mDataType );
5244  return map;
5245 }
5246 
5248 {
5250  mDataType = static_cast< QgsProcessing::SourceType >( map.value( QStringLiteral( "data_type" ) ).toInt() );
5251  return true;
5252 }
5253 
5254 QgsProcessingParameterVectorDestination *QgsProcessingParameterVectorDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5255 {
5257  QString def = definition;
5258  if ( def.startsWith( QLatin1String( "point" ), Qt::CaseInsensitive ) )
5259  {
5261  def = def.mid( 6 );
5262  }
5263  else if ( def.startsWith( QLatin1String( "line" ), Qt::CaseInsensitive ) )
5264  {
5266  def = def.mid( 5 );
5267  }
5268  else if ( def.startsWith( QLatin1String( "polygon" ), Qt::CaseInsensitive ) )
5269  {
5271  def = def.mid( 8 );
5272  }
5273 
5274  return new QgsProcessingParameterVectorDestination( name, description, type, definition, isOptional );
5275 }
5276 
5277 QgsProcessingParameterBand::QgsProcessingParameterBand( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayerParameterName, bool optional, bool allowMultiple )
5278  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5279  , mParentLayerParameterName( parentLayerParameterName )
5280  , mAllowMultiple( allowMultiple )
5281 {
5282 
5283 }
5284 
5286 {
5287  return new QgsProcessingParameterBand( *this );
5288 }
5289 
5291 {
5292  if ( !input.isValid() )
5293  return mFlags & FlagOptional;
5294 
5295  if ( input.canConvert<QgsProperty>() )
5296  {
5297  return true;
5298  }
5299 
5300  if ( input.type() == QVariant::List || input.type() == QVariant::StringList )
5301  {
5302  if ( !mAllowMultiple )
5303  return false;
5304 
5305  if ( input.toList().isEmpty() && !( mFlags & FlagOptional ) )
5306  return false;
5307  }
5308  else
5309  {
5310  bool ok = false;
5311  double res = input.toInt( &ok );
5312  Q_UNUSED( res )
5313  if ( !ok )
5314  return mFlags & FlagOptional;
5315  }
5316  return true;
5317 }
5318 
5320 {
5321  return mAllowMultiple;
5322 }
5323 
5325 {
5326  mAllowMultiple = allowMultiple;
5327 }
5328 
5330 {
5331  if ( !value.isValid() )
5332  return QStringLiteral( "None" );
5333 
5334  if ( value.canConvert<QgsProperty>() )
5335  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
5336 
5337  if ( value.type() == QVariant::List )
5338  {
5339  QStringList parts;
5340  QVariantList values = value.toList();
5341  for ( auto it = values.constBegin(); it != values.constEnd(); ++it )
5342  {
5343  parts << QString::number( static_cast< int >( it->toDouble() ) );
5344  }
5345  return parts.join( ',' ).prepend( '[' ).append( ']' );
5346  }
5347  else if ( value.type() == QVariant::StringList )
5348  {
5349  QStringList parts;
5350  QStringList values = value.toStringList();
5351  for ( auto it = values.constBegin(); it != values.constEnd(); ++it )
5352  {
5353  parts << QString::number( static_cast< int >( it->toDouble() ) );
5354  }
5355  return parts.join( ',' ).prepend( '[' ).append( ']' );
5356  }
5357 
5358  return value.toString();
5359 }
5360 
5362 {
5363  QString code = QStringLiteral( "##%1=" ).arg( mName );
5364  if ( mFlags & FlagOptional )
5365  code += QStringLiteral( "optional " );
5366  code += QStringLiteral( "band " );
5367 
5368  if ( mAllowMultiple )
5369  code += QStringLiteral( "multiple " );
5370 
5371  code += mParentLayerParameterName + ' ';
5372 
5373  code += mDefault.toString();
5374  return code.trimmed();
5375 }
5376 
5378 {
5379  QStringList depends;
5380  if ( !mParentLayerParameterName.isEmpty() )
5381  depends << mParentLayerParameterName;
5382  return depends;
5383 }
5384 
5386 {
5387  switch ( outputType )
5388  {
5390  {
5391  QString code = QStringLiteral( "QgsProcessingParameterBand('%1', '%2'" ).arg( name(), description() );
5392  if ( mFlags & FlagOptional )
5393  code += QStringLiteral( ", optional=True" );
5394 
5395  code += QStringLiteral( ", parentLayerParameterName='%1'" ).arg( mParentLayerParameterName );
5396  code += QStringLiteral( ", allowMultiple=%1" ).arg( mAllowMultiple ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
5397 
5399  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
5400  return code;
5401  }
5402  }
5403  return QString();
5404 }
5405 
5407 {
5408  return mParentLayerParameterName;
5409 }
5410 
5412 {
5413  mParentLayerParameterName = parentLayerParameterName;
5414 }
5415 
5417 {
5419  map.insert( QStringLiteral( "parent_layer" ), mParentLayerParameterName );
5420  map.insert( QStringLiteral( "allow_multiple" ), mAllowMultiple );
5421  return map;
5422 }
5423 
5424 bool QgsProcessingParameterBand::fromVariantMap( const QVariantMap &map )
5425 {
5427  mParentLayerParameterName = map.value( QStringLiteral( "parent_layer" ) ).toString();
5428  mAllowMultiple = map.value( QStringLiteral( "allow_multiple" ) ).toBool();
5429  return true;
5430 }
5431 
5432 QgsProcessingParameterBand *QgsProcessingParameterBand::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5433 {
5434  QString parent;
5435  QString def = definition;
5436  bool allowMultiple = false;
5437 
5438  if ( def.startsWith( QLatin1String( "multiple" ), Qt::CaseInsensitive ) )
5439  {
5440  allowMultiple = true;
5441  def = def.mid( 8 ).trimmed();
5442  }
5443 
5444  QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*)$" ) );
5445  QRegularExpressionMatch m = re.match( def );
5446  if ( m.hasMatch() )
5447  {
5448  parent = m.captured( 1 ).trimmed();
5449  def = m.captured( 2 );
5450  }
5451  else
5452  {
5453  parent = def;
5454  def.clear();
5455  }
5456 
5457  return new QgsProcessingParameterBand( name, description, def.isEmpty() ? QVariant() : def, parent, isOptional, allowMultiple );
5458 }
5459 
5460 //
5461 // QgsProcessingParameterDistance
5462 //
5463 
5464 QgsProcessingParameterDistance::QgsProcessingParameterDistance( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentParameterName, bool optional, double minValue, double maxValue )
5465  : QgsProcessingParameterNumber( name, description, Double, defaultValue, optional, minValue, maxValue )
5466  , mParentParameterName( parentParameterName )
5467 {
5468 
5469 }
5470 
5472 {
5473  return new QgsProcessingParameterDistance( *this );
5474 }
5475 
5477 {
5478  return typeName();
5479 }
5480 
5482 {
5483  QStringList depends;
5484  if ( !mParentParameterName.isEmpty() )
5485  depends << mParentParameterName;
5486  return depends;
5487 }
5488 
5490 {
5491  switch ( outputType )
5492  {
5494  {
5495  QString code = QStringLiteral( "QgsProcessingParameterDistance('%1', '%2'" ).arg( name(), description() );
5496  if ( mFlags & FlagOptional )
5497  code += QStringLiteral( ", optional=True" );
5498 
5499  code += QStringLiteral( ", parentParameterName='%1'" ).arg( mParentParameterName );
5500 
5501  if ( minimum() != std::numeric_limits<double>::lowest() + 1 )
5502  code += QStringLiteral( ", minValue=%1" ).arg( minimum() );
5503  if ( maximum() != std::numeric_limits<double>::max() )
5504  code += QStringLiteral( ", maxValue=%1" ).arg( maximum() );
5506  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
5507  return code;
5508  }
5509  }
5510  return QString();
5511 }
5512 
5514 {
5515  return mParentParameterName;
5516 }
5517 
5519 {
5520  mParentParameterName = parentParameterName;
5521 }
5522 
5524 {
5525  QVariantMap map = QgsProcessingParameterNumber::toVariantMap();
5526  map.insert( QStringLiteral( "parent" ), mParentParameterName );
5527  map.insert( QStringLiteral( "default_unit" ), static_cast< int >( mDefaultUnit ) );
5528  return map;
5529 }
5530 
5532 {
5534  mParentParameterName = map.value( QStringLiteral( "parent" ) ).toString();
5535  mDefaultUnit = static_cast< QgsUnitTypes::DistanceUnit>( map.value( QStringLiteral( "default_unit" ), QgsUnitTypes::DistanceUnknownUnit ).toInt() );
5536  return true;
5537 }
5538 
5539 
5540 //
5541 // QgsProcessingParameterScale
5542 //
5543 
5544 QgsProcessingParameterScale::QgsProcessingParameterScale( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
5545  : QgsProcessingParameterNumber( name, description, Double, defaultValue, optional )
5546 {
5547 
5548 }
5549 
5551 {
5552  return new QgsProcessingParameterScale( *this );
5553 }
5554 
5556 {
5557  return typeName();
5558 }
5559 
5561 {
5562  switch ( outputType )
5563  {
5565  {
5566  QString code = QStringLiteral( "QgsProcessingParameterScale('%1', '%2'" ).arg( name(), description() );
5567  if ( mFlags & FlagOptional )
5568  code += QStringLiteral( ", optional=True" );
5570  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
5571  return code;
5572  }
5573  }
5574  return QString();
5575 }
5576 
5577 QgsProcessingParameterScale *QgsProcessingParameterScale::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5578 {
5579  return new QgsProcessingParameterScale( name, description, definition.isEmpty() ? QVariant()
5580  : ( definition.toLower().trimmed() == QStringLiteral( "none" ) ? QVariant() : definition ), isOptional );
5581 }
5582 
5583 
5584 //
5585 // QgsProcessingParameterLayout
5586 //
5587 
5588 QgsProcessingParameterLayout::QgsProcessingParameterLayout( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
5589  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5590 {}
5591 
5593 {
5594  return new QgsProcessingParameterLayout( *this );
5595 }
5596 
5598 {
5599  if ( !value.isValid() || value.isNull() )
5600  return QStringLiteral( "None" );
5601 
5602  if ( value.canConvert<QgsProperty>() )
5603  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
5604 
5605  QString s = value.toString();
5607 }
5608 
5610 {
5611  QString code = QStringLiteral( "##%1=" ).arg( mName );
5612  if ( mFlags & FlagOptional )
5613  code += QStringLiteral( "optional " );
5614  code += QStringLiteral( "layout " );
5615 
5616  code += mDefault.toString();
5617  return code.trimmed();
5618 }
5619 
5621 {
5622  switch ( outputType )
5623  {
5625  {
5626  QString code = QStringLiteral( "QgsProcessingParameterLayout('%1', '%2'" ).arg( name(), description() );
5627  if ( mFlags & FlagOptional )
5628  code += QStringLiteral( ", optional=True" );
5630  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
5631  return code;
5632  }
5633  }
5634  return QString();
5635 }
5636 
5637 QgsProcessingParameterLayout *QgsProcessingParameterLayout::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5638 {
5639  QString def = definition;
5640 
5641  if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
5642  def = def.mid( 1 );
5643  if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
5644  def.chop( 1 );
5645 
5646  QVariant defaultValue = def;
5647  if ( def == QStringLiteral( "None" ) )
5648  defaultValue = QVariant();
5649 
5650  return new QgsProcessingParameterLayout( name, description, defaultValue, isOptional );
5651 }
5652 
5653 
5654 //
5655 // QString mParentLayerParameterName;
5656 //
5657 
5658 QgsProcessingParameterLayoutItem::QgsProcessingParameterLayoutItem( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayoutParameterName, int itemType, bool optional )
5659  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5660  , mParentLayoutParameterName( parentLayoutParameterName )
5661  , mItemType( itemType )
5662 {
5663 
5664 }
5665 
5667 {
5668  return new QgsProcessingParameterLayoutItem( *this );
5669 }
5670 
5672 {
5673  if ( !value.isValid() || value.isNull() )
5674  return QStringLiteral( "None" );
5675 
5676  if ( value.canConvert<QgsProperty>() )
5677  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
5678 
5679  QString s = value.toString();
5681 }
5682 
5684 {
5685  QString code = QStringLiteral( "##%1=" ).arg( mName );
5686  if ( mFlags & FlagOptional )
5687  code += QStringLiteral( "optional " );
5688  code += QStringLiteral( "layoutitem " );
5689  if ( mItemType >= 0 )
5690  code += QString::number( mItemType ) + ' ';
5691 
5692  code += mParentLayoutParameterName + ' ';
5693 
5694  code += mDefault.toString();
5695  return code.trimmed();
5696 }
5697 
5699 {
5700  switch ( outputType )
5701  {
5703  {
5704  QString code = QStringLiteral( "QgsProcessingParameterLayoutItem('%1', '%2'" ).arg( name(), description() );
5705  if ( mFlags & FlagOptional )
5706  code += QStringLiteral( ", optional=True" );
5707 
5708  if ( mItemType >= 0 )
5709  code += QStringLiteral( ", itemType=%1" ).arg( mItemType );
5710 
5711  code += QStringLiteral( ", parentLayoutParameterName='%1'" ).arg( mParentLayoutParameterName );
5712 
5714  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
5715  return code;
5716  }
5717  }
5718  return QString();
5719 }
5720 
5722 {
5724  map.insert( QStringLiteral( "parent_layout" ), mParentLayoutParameterName );
5725  map.insert( QStringLiteral( "item_type" ), mItemType );
5726  return map;
5727 }
5728 
5730 {
5732  mParentLayoutParameterName = map.value( QStringLiteral( "parent_layout" ) ).toString();
5733  mItemType = map.value( QStringLiteral( "item_type" ) ).toInt();
5734  return true;
5735 }
5736 
5738 {
5739  QStringList depends;
5740  if ( !mParentLayoutParameterName.isEmpty() )
5741  depends << mParentLayoutParameterName;
5742  return depends;
5743 }
5744 
5745 QgsProcessingParameterLayoutItem *QgsProcessingParameterLayoutItem::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5746 {
5747  QString parent;
5748  QString def = definition;
5749  int itemType = -1;
5750  QRegularExpression re( QStringLiteral( "(\\d+)?\\s*(.*?)\\s+(.*)$" ) );
5751  QRegularExpressionMatch m = re.match( def );
5752  if ( m.hasMatch() )
5753  {
5754  itemType = m.captured( 1 ).trimmed().isEmpty() ? -1 : m.captured( 1 ).trimmed().toInt();
5755  parent = m.captured( 2 ).trimmed().isEmpty() ? m.captured( 3 ).trimmed() : m.captured( 2 ).trimmed();
5756  def = !m.captured( 2 ).trimmed().isEmpty() ? m.captured( 3 ) : QString();
5757  }
5758  else
5759  {
5760  parent = def;
5761  def.clear();
5762  }
5763 
5764  return new QgsProcessingParameterLayoutItem( name, description, def.isEmpty() ? QVariant() : def, parent, itemType, isOptional );
5765 }
5766 
5768 {
5769  return mParentLayoutParameterName;
5770 }
5771 
5773 {
5774  mParentLayoutParameterName = name;
5775 }
5776 
5778 {
5779  return mItemType;
5780 }
5781 
5783 {
5784  mItemType = type;
5785 }
5786 
5787 //
5788 // QgsProcessingParameterColor
5789 //
5790 
5791 QgsProcessingParameterColor::QgsProcessingParameterColor( const QString &name, const QString &description, const QVariant &defaultValue, bool opacityEnabled, bool optional )
5792  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5793  , mAllowOpacity( opacityEnabled )
5794 {
5795 
5796 }
5797 
5799 {
5800  return new QgsProcessingParameterColor( *this );
5801 }
5802 
5804 {
5805  if ( !value.isValid() || value.isNull() )
5806  return QStringLiteral( "None" );
5807 
5808  if ( value.canConvert<QgsProperty>() )
5809  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
5810 
5811  if ( value.canConvert< QColor >() && !value.value< QColor >().isValid() )
5812  return QStringLiteral( "QColor()" );
5813 
5814  if ( value.canConvert< QColor >() )
5815  {
5816  QColor c = value.value< QColor >();
5817  if ( !mAllowOpacity || c.alpha() == 255 )
5818  return QStringLiteral( "QColor(%1, %2, %3)" ).arg( c.red() ).arg( c.green() ).arg( c.blue() );
5819  else
5820  return QStringLiteral( "QColor(%1, %2, %3, %4)" ).arg( c.red() ).arg( c.green() ).arg( c.blue() ).arg( c.alpha() );
5821  }
5822 
5823  QString s = value.toString();
5825 }
5826 
5828 {
5829  QString code = QStringLiteral( "##%1=" ).arg( mName );
5830  if ( mFlags & FlagOptional )
5831  code += QStringLiteral( "optional " );
5832  code += QStringLiteral( "color " );
5833 
5834  if ( mAllowOpacity )
5835  code += QStringLiteral( "withopacity " );
5836 
5837  code += mDefault.toString();
5838  return code.trimmed();
5839 }
5840 
5842 {
5843  switch ( outputType )
5844  {
5846  {
5847  QString code = QStringLiteral( "QgsProcessingParameterColor('%1', '%2'" ).arg( name(), description() );
5848  if ( mFlags & FlagOptional )
5849  code += QStringLiteral( ", optional=True" );
5850 
5851  code += QStringLiteral( ", opacityEnabled=%1" ).arg( mAllowOpacity ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
5852 
5854  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
5855  return code;
5856  }
5857  }
5858  return QString();
5859 }
5860 
5862 {
5863  if ( !input.isValid() && ( mDefault.isValid() && ( !mDefault.toString().isEmpty() || mDefault.value< QColor >().isValid() ) ) )
5864  return true;
5865 
5866  if ( !input.isValid() )
5867  return mFlags & FlagOptional;
5868 
5869  if ( input.type() == QVariant::Color )
5870  {
5871  return true;
5872  }
5873  else if ( input.canConvert<QgsProperty>() )
5874  {
5875  return true;
5876  }
5877 
5878  if ( input.type() != QVariant::String || input.toString().isEmpty() )
5879  return mFlags & FlagOptional;
5880 
5881  bool containsAlpha = false;
5882  return QgsSymbolLayerUtils::parseColorWithAlpha( input.toString(), containsAlpha ).isValid();
5883 }
5884 
5886 {
5888  map.insert( QStringLiteral( "opacityEnabled" ), mAllowOpacity );
5889  return map;
5890 }
5891 
5892 bool QgsProcessingParameterColor::fromVariantMap( const QVariantMap &map )
5893 {
5895  mAllowOpacity = map.value( QStringLiteral( "opacityEnabled" ) ).toBool();
5896  return true;
5897 }
5898 
5900 {
5901  return mAllowOpacity;
5902 }
5903 
5905 {
5906  mAllowOpacity = enabled;
5907 }
5908 
5909 QgsProcessingParameterColor *QgsProcessingParameterColor::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5910 {
5911  QString def = definition;
5912 
5913  bool allowOpacity = false;
5914  if ( def.startsWith( QLatin1String( "withopacity" ), Qt::CaseInsensitive ) )
5915  {
5916  allowOpacity = true;
5917  def = def.mid( 12 );
5918  }
5919 
5920  if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
5921  def = def.mid( 1 );
5922  if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
5923  def.chop( 1 );
5924 
5925  QVariant defaultValue = def;
5926  if ( def == QStringLiteral( "None" ) )
5927  defaultValue = QVariant();
5928 
5929  return new QgsProcessingParameterColor( name, description, defaultValue, allowOpacity, isOptional );
5930 }
5931 
5932 //
5933 // QgsProcessingParameterCoordinateOperation
5934 //
5935 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 )
5936  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5937  , mSourceParameterName( sourceCrsParameterName )
5938  , mDestParameterName( destinationCrsParameterName )
5939  , mSourceCrs( staticSourceCrs )
5940  , mDestCrs( staticDestinationCrs )
5941 {
5942 
5943 }
5944 
5946 {
5947  return new QgsProcessingParameterCoordinateOperation( * this );
5948 }
5949 
5951 {
5952  if ( !value.isValid() || value.isNull() )
5953  return QStringLiteral( "None" );
5954 
5955  if ( value.canConvert<QgsCoordinateReferenceSystem>() )
5956  {
5957  if ( !value.value< QgsCoordinateReferenceSystem >().isValid() )
5958  return QStringLiteral( "QgsCoordinateReferenceSystem()" );
5959  else
5960  return QStringLiteral( "QgsCoordinateReferenceSystem('%1')" ).arg( value.value< QgsCoordinateReferenceSystem >().authid() );
5961  }
5962 
5963  if ( value.canConvert<QgsProperty>() )
5964  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
5965 
5966  QVariantMap p;
5967  p.insert( name(), value );
5968  QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
5969  if ( layer )
5971 
5972  QString s = value.toString();
5974 }
5975 
5977 {
5978  QString code = QStringLiteral( "##%1=" ).arg( mName );
5979  if ( mFlags & FlagOptional )
5980  code += QStringLiteral( "optional " );
5981  code += QStringLiteral( "coordinateoperation " );
5982 
5983  code += mDefault.toString();
5984  return code.trimmed();
5985 }
5986 
5988 {
5989  switch ( outputType )
5990  {
5992  {
5994  QString code = QStringLiteral( "QgsProcessingParameterCoordinateOperation('%1', '%2'" ).arg( name(), description() );
5995  if ( mFlags & FlagOptional )
5996  code += QStringLiteral( ", optional=True" );
5997  if ( !mSourceParameterName.isEmpty() )
5998  code += QStringLiteral( ", sourceCrsParameterName=%1" ).arg( valueAsPythonString( mSourceParameterName, c ) );
5999  if ( !mDestParameterName.isEmpty() )
6000  code += QStringLiteral( ", destinationCrsParameterName=%1" ).arg( valueAsPythonString( mDestParameterName, c ) );
6001 
6002  if ( mSourceCrs.isValid() )
6003  code += QStringLiteral( ", staticSourceCrs=%1" ).arg( valueAsPythonString( mSourceCrs, c ) );
6004  if ( mDestCrs.isValid() )
6005  code += QStringLiteral( ", staticDestinationCrs=%1" ).arg( valueAsPythonString( mDestCrs, c ) );
6006 
6007  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
6008  return code;
6009  }
6010  }
6011  return QString();
6012 }
6013 
6015 {
6017  map.insert( QStringLiteral( "source_crs_parameter_name" ), mSourceParameterName );
6018  map.insert( QStringLiteral( "dest_crs_parameter_name" ), mDestParameterName );
6019  map.insert( QStringLiteral( "static_source_crs" ), mSourceCrs );
6020  map.insert( QStringLiteral( "static_dest_crs" ), mDestCrs );
6021  return map;
6022 }
6023 
6025 {
6027  mSourceParameterName = map.value( QStringLiteral( "source_crs_parameter_name" ) ).toString();
6028  mDestParameterName = map.value( QStringLiteral( "dest_crs_parameter_name" ) ).toString();
6029  mSourceCrs = map.value( QStringLiteral( "static_source_crs" ) );
6030  mDestCrs = map.value( QStringLiteral( "static_dest_crs" ) );
6031  return true;
6032 }
6033 
6034 QgsProcessingParameterCoordinateOperation *QgsProcessingParameterCoordinateOperation::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6035 {
6036  QString def = definition;
6037 
6038  if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
6039  def = def.mid( 1 );
6040  if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
6041  def.chop( 1 );
6042 
6043  QVariant defaultValue = def;
6044  if ( def == QStringLiteral( "None" ) )
6045  defaultValue = QVariant();
6046 
6047  return new QgsProcessingParameterCoordinateOperation( name, description, defaultValue, QString(), QString(), QVariant(), QVariant(), isOptional );
6048 }
6049 
6050 
6051 //
6052 // QgsProcessingParameterMapTheme
6053 //
6054 
6055 QgsProcessingParameterMapTheme::QgsProcessingParameterMapTheme( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
6056  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
6057 {
6058 
6059 }
6060 
6061 
6063 {
6064  return new QgsProcessingParameterMapTheme( *this );
6065 }
6066 
6068 {
6069  if ( !input.isValid() && !mDefault.isValid() )
6070  return mFlags & FlagOptional;
6071 
6072  if ( ( input.type() == QVariant::String && input.toString().isEmpty() )
6073  || ( !input.isValid() && mDefault.type() == QVariant::String && mDefault.toString().isEmpty() ) )
6074  return mFlags & FlagOptional;
6075 
6076  return true;
6077 }
6078 
6080 {
6081  if ( !value.isValid() )
6082  return QStringLiteral( "None" );
6083 
6084  if ( value.canConvert<QgsProperty>() )
6085  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
6086 
6087  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
6088 }
6089 
6091 {
6092  QString code = QStringLiteral( "##%1=" ).arg( mName );
6093  if ( mFlags & FlagOptional )
6094  code += QStringLiteral( "optional " );
6095  code += QStringLiteral( "maptheme " );
6096 
6097  code += mDefault.toString();
6098  return code.trimmed();
6099 }
6100 
6102 {
6103  switch ( outputType )
6104  {
6106  {
6107  QString code = QStringLiteral( "QgsProcessingParameterMapTheme('%1', '%2'" ).arg( name(), description() );
6108  if ( mFlags & FlagOptional )
6109  code += QStringLiteral( ", optional=True" );
6110 
6112  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
6113 
6114  return code;
6115  }
6116  }
6117  return QString();
6118 }
6119 
6121 {
6123  return map;
6124 }
6125 
6127 {
6129  return true;
6130 }
6131 
6132 QgsProcessingParameterMapTheme *QgsProcessingParameterMapTheme::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6133 {
6134  QString parent;
6135 
6136  QString def = definition;
6137  if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
6138  def = def.mid( 1 );
6139  if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
6140  def.chop( 1 );
6141 
6142  QVariant defaultValue = def;
6143 
6144  if ( defaultValue == QStringLiteral( "None" ) || defaultValue.toString().isEmpty() )
6145  defaultValue = QVariant();
6146 
6147  return new QgsProcessingParameterMapTheme( name, description, defaultValue, isOptional );
6148 }
QgsProcessingParameterDefinition(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterDefinition.
QgsProperty sink
Sink/layer definition.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
static QgsCoordinateReferenceSystem parameterAsCrs(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a coordinate reference system.
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...
A boolean parameter for processing algorithms.
int itemType() const
Returns the acceptable item type, or -1 if any item type is allowed.
Class for parsing and evaluation of expressions (formerly called "search strings").
void setDataTypes(const QList< int > &types)
Sets the geometry types for sources acceptable by the parameter.
static QString typeName()
Returns the type name for the parameter class.
An input file or folder parameter for processing algorithms.
A parameter for processing algorithms which accepts multiple map layers.
QgsProcessingOutputDefinition * toOutputDefinition() const override
Returns a new QgsProcessingOutputDefinition corresponding to the definition of the destination parame...
virtual QString asScriptCode() const
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 QgsProcessingParameterLayoutItem * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
A rectangle specified with double values.
Definition: qgsrectangle.h:41
QString asExpression() const
Returns an expression string representing the state of the property, or an empty string if the proper...
Base class for all map layer types.
Definition: qgsmaplayer.h:79
static QString descriptionFromName(const QString &name)
Creates an autogenerated parameter description from a parameter name.
static QString parameterAsString(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static string value.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
bool defaultToAllFields() const
Returns whether a parameter which allows multiple selections (see allowMultiple()) should automatical...
QgsLayoutItem * itemById(const QString &id) const
Returns a layout item given its id.
Definition: qgslayout.cpp:265
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.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
static int parameterAsEnum(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a enum value.
static QString typeName()
Returns the type name for the parameter class.
Base class for providing feedback from a processing algorithm.
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...
virtual bool fromVariantMap(const QVariantMap &map)
Restores 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...
QgsMasterLayoutInterface * layoutByName(const QString &name) const
Returns the layout with a matching name, or nullptr if no matching layouts were found.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
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.
static QVariantList parameterAsMatrix(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a matrix/table of values.
Base class for graphical items within a QgsLayout.
virtual QStringList supportedOutputTableExtensions() const
Returns a list of the table (geometry-less vector layers) file extensions supported by this provider...
Encapsulates settings relating to a feature sink or output raster layer for a processing algorithm...
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QgsProcessingParameterFolderDestination(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, bool createByDefault=true)
Constructor for QgsProcessingParameterFolderDestination.
QString type() const override
Unique parameter type name.
static QgsApplication * instance()
Returns the singleton instance of the QgsApplication.
bool hasFixedNumberRows() const
Returns whether the table has a fixed number of rows.
virtual QStringList supportedOutputVectorLayerExtensions() const
Returns a list of the vector format file extensions supported by this parameter.
QString type() const override
Unique parameter type name.
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 vector layer or feature source field parameter for processing algorithms.
OperationResult transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection direction=QgsCoordinateTransform::ForwardTransform, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
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.
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.
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.
QgsProcessingParameterColor(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool opacityEnabled=true, bool optional=false)
Constructor for QgsProcessingParameterColor.
DataType dataType() const
Returns the acceptable data type for the field.
bool fromVariantMap(const QVariantMap &map) override
Restores 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 type() const override
Unique parameter type name.
static QString defaultVectorExtension()
Returns the default vector extension to use, in the absence of all other constraints (e...
virtual QStringList supportedOutputRasterLayerExtensions() const
Returns a list of the raster format file extensions supported for this parameter. ...
void setHasFixedNumberRows(bool hasFixedNumberRows)
Sets whether the table has a fixed number of rows.
QgsProcessingParameterMultipleLayers(const QString &name, const QString &description=QString(), QgsProcessing::SourceType layerType=QgsProcessing::TypeVectorAnyGeometry, const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterMultipleLayers.
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...
QgsProcessingParameterExpression(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), const QString &parentLayerParameterName=QString(), bool optional=false)
Constructor for QgsProcessingParameterExpression.
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...
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
LayerHint
Layer type hints.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
static QString typeName()
Returns the type name for the parameter class.
QgsProcessingParameterRange(const QString &name, const QString &description=QString(), QgsProcessingParameterNumber::Type type=QgsProcessingParameterNumber::Integer, const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterRange.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QgsProcessingParameterFeatureSource(const QString &name, const QString &description=QString(), const QList< int > &types=QList< int >(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterFeatureSource.
void setDataType(QgsProcessingParameterNumber::Type dataType)
Sets the acceptable data type for the range.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
void setDefaultToAllFields(bool enabled)
Sets whether a parameter which allows multiple selections (see allowMultiple()) should automatically ...
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.
Represents 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.
QgsPointXY transform(const QgsPointXY &point, TransformDirection direction=ForwardTransform) const SIP_THROW(QgsCsException)
Transform the point from the source CRS to the destination CRS.
static QString typeName()
Returns the type name for the parameter class.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
A print layout parameter, allowing users to select a print layout.
QString type() const override
Unique parameter type name.
double y
Definition: qgspointxy.h:48
A map layer 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...
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...
QStringList headers() const
Returns a list of column headers (if set).
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
void setParentLayerParameterName(const QString &parentLayerParameterName)
Sets the name of the parent layer parameter.
QgsProcessingProvider * provider() const
Returns the provider to which this algorithm belongs.
A class to represent a 2D point.
Definition: qgspointxy.h:43
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...
A HTML file output for processing algorithms.
QgsProcessingParameterLayout(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterLayout.
QgsProcessingProvider * provider() const
Returns a pointer to the provider for the algorithm which owns this parameter.
An expression parameter for processing algorithms.
A QgsPointXY with associated coordinate reference system.
static QString typeName()
Returns the type name for the parameter class.
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.
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:237
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
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 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...
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...
bool createByDefault() const
Returns true if the destination should be created by default.
An interface for objects which accept features via addFeature(s) methods.
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 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...
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script...
PythonOutputType
Available Python output types.
Definition: qgsprocessing.h:58
QgsProcessingProvider * originalProvider() const
Original (source) provider which this parameter has been derived from.
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...
void setFileFilter(const QString &filter)
Sets the file filter string for file destinations compatible with this parameter. ...
QgsProcessingAlgorithm * mAlgorithm
Pointer to algorithm which owns this parameter.
virtual QStringList supportedOutputRasterLayerExtensions() const
Returns a list of the raster format file extensions supported by this provider.
static QString typeName()
Returns the type name for the parameter class.
static QString stringToPythonLiteral(const QString &string)
Converts a string to a Python string literal.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
static QString typeName()
Returns the type name for the parameter class.
QVariantMap mMetadata
Freeform metadata for parameter. Mostly used by widget wrappers to customize their appearance and beh...
QString type() const override
Unique parameter type name.
double minimum() const
Returns the minimum value acceptable by the parameter.
QgsFeatureSource subclass which proxies methods to an underlying QgsFeatureSource, modifying results according to the settings in a QgsProcessingContext.
Container of fields for a vector layer.
Definition: qgsfields.h:42
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.
static QgsRasterLayer * parameterAsRasterLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a raster layer.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:122
static QgsMapLayer * parameterAsLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a map layer.
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...
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.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
Abstract base class for processing providers.
virtual QVariantMap toVariantMap() const
Saves this parameter to a QVariantMap.
QgsGeometry centroid() const
Returns the center of mass of a geometry.
bool allowMultiple() const
Returns true if the parameter allows multiple selected values.
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...
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script...
QgsProcessingParameterMapLayer(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterMapLayer.
A raster band parameter for Processing algorithms.
QString type() const override
Unique parameter type name.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
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...
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.
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...
bool fromVariantMap(const QVariantMap &map) override
Restores 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 QgsProcessingParameterDefinition * parameterFromVariantMap(const QVariantMap &map)
Creates a new QgsProcessingParameterDefinition using the configuration from a supplied variant map...
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...
QgsProcessingParameterEnum(const QString &name, const QString &description=QString(), const QStringList &options=QStringList(), bool allowMultiple=false, const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterEnum.
QgsProcessingParameterBoolean(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterBoolean.
QString type() const override
Unique parameter type name.
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.
QgsProcessingParameterType * parameterType(const QString &id) const
Returns the parameter type registered for id.
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.
static QString typeName()
Returns the type name for the parameter class.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
const QgsCoordinateReferenceSystem & crs
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 convertToCompatibleFormat(const QgsVectorLayer *layer, bool selectedFeaturesOnly, const QString &baseName, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingContext &context, QgsProcessingFeedback *feedback)
Converts a source vector layer to a file path of a vector layer of compatible format.
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...
static QString typeName()
Returns the type name for the parameter class.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
void setMaximum(double maximum)
Sets the maximum value acceptable by the parameter.
void setParentLayerParameterName(const QString &parentLayerParameterName)
Sets the name of the parent layer parameter.
static QString normalizeLayerSource(const QString &source)
Normalizes a layer source string for safe comparison across different operating system environments...
static QgsVectorLayer * parameterAsVectorLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a vector layer.
Base class for all parameter definitions which represent file or layer destinations, e.g.
Abstract base class for processing algorithms.
A coordinate operation parameter for processing algorithms, for selection between available coordinat...
static QgsPointXY parameterAsPoint(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QgsCoordinateReferenceSystem &crs=QgsCoordinateReferenceSystem())
Evaluates the parameter with matching definition to a point.
A vector layer output for processing algorithms.
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.
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.
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 parameterAsFile(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a file/folder name.
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
A feature sink output for processing algorithms.
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.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QString fileFilter() const
Returns the file filter string for file destinations compatible with this 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.
QgsProject * project() const
Returns the project in which the algorithm is being executed.
Files (i.e. non map layer sources, such as text files)
Definition: qgsprocessing.h:52
bool selectedFeaturesOnly
true if only selected features in the source should be used by algorithms.
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...
virtual QgsRectangle extent() const
Returns the extent of the layer.
static QgsCoordinateReferenceSystem variantToCrs(const QVariant &value, QgsProcessingContext &context, const QVariant &fallbackValue=QVariant())
Converts a variant value to a coordinate reference system.
QgsProcessingParameterScale(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterScale.
A raster layer destination parameter, for specifying the destination path for a raster layer created ...
int minimumNumberInputs() const
Returns the minimum number of layers required for the parameter.
void setAllowMultiple(bool allowMultiple)
Sets whether multiple field selections are permitted.
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
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 QgsProcessingParameterBoolean * 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.
QgsProcessing::SourceType layerType() const
Returns the layer type for layers acceptable by the parameter.
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 QgsCoordinateReferenceSystem parameterAsExtentCrs(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Returns the coordinate reference system associated with an extent parameter value.
static QString typeName()
Returns the type name for the parameter class.
A numeric range parameter for processing algorithms.
A double numeric parameter for map scale values.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
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.
QString parentLayoutParameterName() const
Returns the name of the parent layout parameter, or an empty string if this is not set...
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.
QgsProcessingOutputDefinition * toOutputDefinition() const override
Returns a new QgsProcessingOutputDefinition corresponding to the definition of the destination parame...
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.
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
QgsProcessingParameterCrs(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterCrs.
QVariant toVariant() const
Saves this property to a QVariantMap, wrapped in a QVariant.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QList< int > dataTypes() const
Returns the geometry types for sources acceptable by the parameter.
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.
QgsCoordinateReferenceSystem crs() const
Returns the associated coordinate reference system, or an invalid CRS if no reference system is set...
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QgsFeatureSink * createFeatureSink(QString &destination, QgsProcessingContext &context, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, const QVariantMap &createOptions=QVariantMap(), QgsFeatureSink::SinkFlags sinkFlags=nullptr)
Creates a feature sink ready for adding features.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QString parentLayerParameterName() const
Returns the name of the parent layer parameter, or an empty string if this is not set...
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
Can be inherited by parameters which require limits to their acceptable data types.
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...
A raster layer parameter for processing algorithms.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QgsProcessingParameterFeatureSink(const QString &name, const QString &description=QString(), QgsProcessing::SourceType type=QgsProcessing::TypeVectorAnyGeometry, const QVariant &defaultValue=QVariant(), bool optional=false, bool createByDefault=true)
Constructor for QgsProcessingParameterFeatureSink.
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:68
static QStringList supportedFormatExtensions(RasterFormatOptions options=SortRecommended)
Returns a list of file extensions for supported formats.
void setOpacityEnabled(bool enabled)
Sets whether the parameter allows opacity control.
virtual QString toolTip() const
Returns a formatted tooltip for use with the parameter, which gives helpful information like paramete...
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.
Mesh layer type, since QGIS 3.6.
QString fileFilter() const
Returns the file filter string for file destinations compatible with this parameter.
static QgsCoordinateReferenceSystem parameterAsPointCrs(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Returns the coordinate reference system associated with an point parameter value. ...
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.
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
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=nullptr)
Evaluates the parameter with matching definition to a feature sink.
QgsProperty source
Source definition.
virtual QgsProcessingParameterDefinition * create(const QString &name) const =0
Creates a new parameter of this type.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
Type propertyType() const
Returns the property type.
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...
QVariantMap toVariantMap() const override
Saves 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.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable 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 type() const override
Unique parameter type name.
An enum based parameter for processing algorithms, allowing for selection from predefined values...
bool loadVariant(const QVariant &property)
Loads this property from a QVariantMap, wrapped in a QVariant.
void setMinimum(double minimum)
Sets the minimum value acceptable by the parameter.
Flags flags() const
Returns any flags associated with the parameter.
QgsProcessing::SourceType dataType() const
Returns the layer type for this created vector layer.
static QString typeName()
Returns the type name for the parameter class.
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.
bool opacityEnabled() const
Returns true if the parameter allows opacity control.
QVariant defaultValue() const
Returns the default value 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...
bool hasGeometry() const
Returns true if the created layer is likely to include geometries.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QgsProcessingParameterDistance * clone() const override
Creates a clone of the parameter definition.
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...
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script...
static QString convertToCompatibleFormatAndLayerName(const QgsVectorLayer *layer, bool selectedFeaturesOnly, const QString &baseName, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingContext &context, QgsProcessingFeedback *feedback, QString &layerName)
Converts a source vector layer to a file path and layer name of a vector layer of compatible format...
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...
bool allowMultiple() const
Returns whether multiple band selections are permitted.
static QString typeName()
Returns the type name for the parameter class.
QgsGeometry densifyByCount(int extraNodesPerSegment) const
Returns a copy of the geometry which has been densified by adding the specified number of extra nodes...
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:275
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
virtual QString defaultRasterFileExtension() const
Returns the default file extension to use for raster outputs created by the provider.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
A double numeric parameter for distance values.
A file output for processing algorithms.
QgsCoordinateReferenceSystem crs
Definition: qgsproject.h:97
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
QgsProcessingDestinationParameter(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, bool createByDefault=true)
Constructor for QgsProcessingDestinationParameter.
QString parentParameterName() const
Returns the name of the parent 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 defaultRasterExtension()
Returns the default raster extension to use, in the absence of all other constraints (e...
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.
QgsProcessingAlgorithm * algorithm() const
Returns a pointer to the algorithm which owns this parameter.
static const QString TEMPORARY_OUTPUT
Constant used to indicate that a Processing algorithm output should be a temporary layer/file...
Definition: qgsprocessing.h:99
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script...
static QList< double > parameterAsRange(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a range of values.
QString type() const override
Unique parameter type name.
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.
Custom exception class for processing related exceptions.
Definition: qgsexception.h:82
static QStringList supportedFormatExtensions(VectorFormatOptions options=SortRecommended)
Returns a list of file extensions for supported formats, e.g "shp", "gpkg".
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
virtual QgsMasterLayoutInterface::Type layoutType() const =0
Returns the master layout type.
virtual QString type() const =0
Unique parameter type name.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script...
QgsProcessingOutputDefinition * toOutputDefinition() const override
Returns a new QgsProcessingOutputDefinition corresponding to the definition of the destination parame...
Encapsulates a QGIS project, including sets of map layers and their styles, layouts, annotations, canvases, etc.
Definition: qgsproject.h:91
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.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
Vector polygon layers.
Definition: qgsprocessing.h:50
static bool parameterAsBoolean(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static boolean value.
A vector layer (with or without geometry) parameter for processing algorithms.
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.
bool multiLine() const
Returns true if the parameter allows multiline strings.
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...
virtual QString defaultFileExtension() const =0
Returns the default file extension for destination file paths associated with this parameter...
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QgsProcessingParameterScale * clone() const override
Creates a clone of the parameter definition.
void setParentLayerParameterName(const QString &parentLayerParameterName)
Sets the name of the parent layer parameter.
static QStringList parameterAsFileList(const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a list of files (for QgsProcessingParameterMultip...
void setParentParameterName(const QString &parentParameterName)
Sets the name of the parent layer parameter.
QStringList options() const
Returns the list of acceptable options for the parameter.
A QgsRectangle with associated coordinate reference system.
void setItemType(int type)
Sets the acceptable item type, or -1 if any item type is allowed.
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
A print layout item parameter, allowing users to select a particular item from a print layout...
A mesh layer parameter for processing algorithms.
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.
A coordinate reference system parameter for processing algorithms.
static QgsProcessingFeatureSource * variantToSource(const QVariant &value, QgsProcessingContext &context, const QVariant &fallbackValue=QVariant())
Converts a variant value to a new feature source.
A store for object properties.
Definition: qgsproperty.h:229
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...
A rectangular map extent parameter for processing algorithms.
void setMinimumNumberInputs(int minimum)
Sets the minimum number of layers required for 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...
void setLayerType(QgsProcessing::SourceType type)
Sets the layer type for layers acceptable by the parameter.
void setAllowMultiple(bool allowMultiple)
Sets whether multiple band selections are permitted.
Details for layers to load into projects.
void setAllowMultiple(bool allowMultiple)
Sets whether the parameter allows multiple selected values.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
A numeric parameter for processing algorithms.
bool loadVariant(const QVariantMap &map)
Loads this output layer definition from a QVariantMap, wrapped in a QVariant.
A generic file based destination parameter, for specifying the destination path for a file (non-map l...
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.
void setExtension(const QString &extension)
Sets a file extension for the parameter.
QgsExpressionContext & expressionContext()
Returns the expression context.
double x
Definition: qgspointxy.h:47
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 QgsPrintLayout * parameterAsLayout(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a print layout.
const QgsLayoutManager * layoutManager() const
Returns the project&#39;s layout manager, which manages print layouts, atlases and reports within the pro...
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.
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 fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString parameterAsCompatibleSourceLayerPathInternal(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingFeedback *feedback, QString *layerName)
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script...
QString name() const
Returns the name of 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...
QList< int > mDataTypes
List of acceptable data types for the parameter.
Encapsulates settings relating to a feature source input to a processing algorithm.
void setMultiLine(bool multiLine)
Sets whether the parameter allows multiline strings.
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
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...
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:177
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
bool supportsNonFileBasedOutput() const
Returns true if the destination parameter supports non filed-based outputs, such as memory layers or ...
Behavior behavior() const
Returns the parameter behavior (e.g.
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.
QString asWkt(int precision=17) const
Exports the geometry to WKT.
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.
static QString generateTempFilename(const QString &basename)
Returns a temporary filename for a given file, putting it into a temporary folder (creating that fold...
QString type() const override
Unique parameter type name.
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:66
QVariant toVariant() const
Saves this output layer definition to a QVariantMap, wrapped in a QVariant.
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...
double xMaximum() const
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:162
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 extension() const
Returns any specified file extension for the 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...
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
virtual QString defaultVectorFileExtension(bool hasGeometry=true) const
Returns the default file extension to use for vector outputs created by the provider.
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.
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.
Base class for the definition of processing outputs.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script...
void setCreateByDefault(bool createByDefault)
Sets whether the destination should be created by default.
static QString typeName()
Returns the type name for the parameter class.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
Unknown distance unit.
Definition: qgsunittypes.h:77
QgsProcessing::SourceType dataType() const
Returns the layer type for sinks associated with the parameter.
QString defaultFileExtension() const override
Returns the default file extension for destination file paths associated with this parameter...
QgsProcessingParameterLimitedDataTypes(const QList< int > &types=QList< int >())
Constructor for QgsProcessingParameterLimitedDataTypes, with a list of acceptable data types...
void setNumberRows(int rows)
Sets the fixed number of rows in the table.
A vector layer destination parameter, for specifying the destination path for a vector layer created ...
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
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...
A point parameter for processing algorithms.
static QgsMeshLayer * parameterAsMeshLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition and value to a mesh layer.
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.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
void setDataType(DataType type)
Sets the acceptable data type for the field.
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.
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
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...
Vector point layers.
Definition: qgsprocessing.h:48
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script...
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.
QString source() const
Returns the source for the layer.
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 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...
QString defaultFileExtension() const override
Returns the default file extension for destination file paths associated with this parameter...
An input feature source (such as vector layers) parameter for processing algorithms.
A folder destination parameter, for specifying the destination path for a folder created by the algor...
int valueAsInt(const QgsExpressionContext &context, int defaultValue=0, bool *ok=nullptr) const
Calculates the current value of the property and interprets it as an integer.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString destinationName
Name to use for sink if it&#39;s to be loaded into a destination project.
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.
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.
Any map layer type (raster or vector or mesh)
Definition: qgsprocessing.h:46
Makes metadata of processing parameters available.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QString toolTip() const override
Returns a formatted tooltip for use with the parameter, which gives helpful information like paramete...
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.
QgsProject * destinationProject
Destination project.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
This class represents a coordinate reference system (CRS).
int numberRows() const
Returns the fixed number of rows in the table.
Base class for the definition of processing parameters.
Vector line layers.
Definition: qgsprocessing.h:49
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
Definition: qgsrectangle.h:436
virtual bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const
Checks whether the specified input value is acceptable for the parameter.
static QgsProcessingParameterDefinition * parameterFromScriptCode(const QString &code)
Creates a new QgsProcessingParameterDefinition using the configuration from a supplied script code st...
QVariant staticValue() const
Returns the current static value for the property.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
Definition: qgsprocessing.h:53
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...
Class for doing transforms between two map coordinate systems.
static double parameterAsDouble(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static double value.
QVariant mDefault
Default value for parameter.
SourceType
Data source types enum.
Definition: qgsprocessing.h:44
static QString parameterAsOutputLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a output layer destination.
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.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:167
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 typeName()
Returns the type name for the parameter class.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
static QgsProcessingFeatureSource * parameterAsSource(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a feature source.
bool fromVariantMap(const QVariantMap &map) override
Restores 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...
QgsProcessingParameterMeshLayer(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterMeshLayer.
static QString addExtensionFromFilter(const QString &fileName, const QString &filter)
Ensures that a fileName ends with an extension from the specified filter string.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:172
Represents a mesh layer supporting display of data on structured or unstructured meshes.
Definition: qgsmeshlayer.h:91
static QString typeName()
Returns the type name for the parameter class.
static bool parameterAsBool(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static boolean value.
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...
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.
virtual QString generateTemporaryDestination() const
Generates a temporary destination value for this parameter.
A folder output for processing algorithms.
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...
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
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.
A table (matrix) parameter for processing algorithms.
Full Python QgsProcessingAlgorithm subclass.
Definition: qgsprocessing.h:60
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65
Type dataType() const
Returns the acceptable data type for the parameter.
QString type() const override
Unique parameter type name.
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.
Print layout, a QgsLayout subclass for static or atlas-based layouts.
A string parameter for authentication configuration ID values.
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.
virtual QStringList supportedOutputVectorLayerExtensions() const
Returns a list of the vector format file extensions supported by this provider.
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 mDescription
Parameter description.
void setFileFilter(const QString &filter)
Sets 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.
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 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...
bool hasGeometry() const
Returns true if sink is likely to include geometries.
QgsProcessingParameterAuthConfig(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterAuthConfig.
Interface for master layout type objects, such as print layouts and reports.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QgsProcessingParameterExtent(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterExtent.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
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.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script...
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.
Represents a vector layer which manages a vector based data sets.
static QString parameterAsExpression(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to an expression.
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...
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
A map theme parameter for processing algorithms, allowing users to select an existing map theme from ...
Static property (QgsStaticProperty)
Definition: qgsproperty.h:237
Contains information about the context in which a processing algorithm is executed.
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 QgsProcessingParameterLayout * 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 sourceTypeToString(SourceType type)
Converts a source type to a string representation.
Definition: qgsprocessing.h:68
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 defaultFileExtension() const override
Returns the default file extension for destination file paths associated with this parameter...
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...
void setDataType(QgsProcessing::SourceType type)
Sets the layer type for the created vector layer.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
A string 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 description() const
Returns the description for the parameter.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
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 QgsProcessingParameterMapTheme * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QgsProcessingParameterVectorLayer(const QString &name, const QString &description=QString(), const QList< int > &types=QList< int >(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterVectorLayer.
void setDataType(QgsProcessing::SourceType type)
Sets the layer type for the sinks associated with the parameter.
Any vector layer with geometry.
Definition: qgsprocessing.h:47
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QgsProcessingParameterNumber::Type dataType() const
Returns the acceptable data type for the range.
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.
QString type() const override
Unique parameter type name.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
bool allowMultiple() const
Returns whether multiple field selections are permitted.
QString authid() const
Returns the authority identifier for the CRS.
QString defaultFileExtension() const override
Returns the default file extension for destination file paths associated with this parameter...
virtual QStringList supportedOutputVectorLayerExtensions() const
Returns a list of the vector format file extensions supported by this parameter.
QString generateTemporaryDestination() const override
Generates a temporary destination value for this parameter.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QgsRectangle transformBoundingBox(const QgsRectangle &rectangle, TransformDirection direction=ForwardTransform, bool handle180Crossover=false) const SIP_THROW(QgsCsException)
Transforms a rectangle from the source CRS to the destination CRS.
static QString typeName()
Returns the type name for the parameter class.
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:86
void setParentLayoutParameterName(const QString &name)
Sets the name of the parent layout parameter.
QgsProcessingParameterRasterLayer(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterRasterLayer.
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.
double maximum() const
Returns the maximum value acceptable by the parameter.
QVariantMap createOptions
Map of optional sink/layer creation options, which are passed to the underlying provider when creatin...
Individual print layout (QgsPrintLayout)
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
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.
QgsProcessingParameterRasterDestination(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, bool createByDefault=true)
Constructor for QgsProcessingParameterRasterDestination.
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.
QgsProcessingOutputDefinition * toOutputDefinition() const override
Returns a new QgsProcessingOutputDefinition corresponding to the definition of the destination parame...
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.
A raster layer output for processing algorithms.
static QgsProcessingRegistry * processingRegistry()
Returns the application&#39;s processing registry, used for managing processing providers, algorithms, and various parameters and outputs.
static QString parameterAsFileOutput(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a file based output destination.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
static QStringList parameterAsFields(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a list of fields.
void setHeaders(const QStringList &headers)
Sets the list of column headers.