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