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 : :
803 : : // default value may be a vector layer
804 : 0 : vl = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( val ) );
805 : 0 : if ( !vl )
806 : 0 : layerRef = definition->defaultValue().toString();
807 : 0 : }
808 : : else
809 : 5 : {
810 : 0 : layerRef = val.toString();
811 : : }
812 : 5 :
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 : :
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 : 0 : }
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::valueAsPythonComment( const QVariant &, QgsProcessingContext & ) const
2411 : : {
2412 : 0 : return QString();
2413 : : }
2414 : :
2415 : 0 : QString QgsProcessingParameterDefinition::asScriptCode() const
2416 : : {
2417 : 0 : QString code = QStringLiteral( "##%1=" ).arg( mName );
2418 : 0 : if ( mFlags & FlagOptional )
2419 : 0 : code += QLatin1String( "optional " );
2420 : 0 : code += type() + ' ';
2421 : 0 : code += mDefault.toString();
2422 : 0 : return code.trimmed();
2423 : 0 : }
2424 : :
2425 : 0 : QString QgsProcessingParameterDefinition::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
2426 : : {
2427 : : // base class method is probably not much use
2428 : 0 : if ( QgsProcessingParameterType *t = QgsApplication::processingRegistry()->parameterType( type() ) )
2429 : : {
2430 : 0 : switch ( outputType )
2431 : : {
2432 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
2433 : : {
2434 : 0 : QString code = t->className() + QStringLiteral( "('%1', '%2'" ).arg( name(), description() );
2435 : 0 : if ( mFlags & FlagOptional )
2436 : 0 : code += QLatin1String( ", optional=True" );
2437 : :
2438 : 0 : QgsProcessingContext c;
2439 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
2440 : 0 : return code;
2441 : 0 : }
2442 : : }
2443 : 0 : }
2444 : :
2445 : : // oh well, we tried
2446 : 0 : return QString();
2447 : 0 : }
2448 : :
2449 : 0 : QVariantMap QgsProcessingParameterDefinition::toVariantMap() const
2450 : : {
2451 : 0 : QVariantMap map;
2452 : 0 : map.insert( QStringLiteral( "parameter_type" ), type() );
2453 : 0 : map.insert( QStringLiteral( "name" ), mName );
2454 : 0 : map.insert( QStringLiteral( "description" ), mDescription );
2455 : 0 : map.insert( QStringLiteral( "help" ), mHelp );
2456 : 0 : map.insert( QStringLiteral( "default" ), mDefault );
2457 : 0 : map.insert( QStringLiteral( "defaultGui" ), mGuiDefault );
2458 : 0 : map.insert( QStringLiteral( "flags" ), static_cast< int >( mFlags ) );
2459 : 0 : map.insert( QStringLiteral( "metadata" ), mMetadata );
2460 : 0 : return map;
2461 : 0 : }
2462 : :
2463 : 0 : bool QgsProcessingParameterDefinition::fromVariantMap( const QVariantMap &map )
2464 : : {
2465 : 0 : mName = map.value( QStringLiteral( "name" ) ).toString();
2466 : 0 : mDescription = map.value( QStringLiteral( "description" ) ).toString();
2467 : 0 : mHelp = map.value( QStringLiteral( "help" ) ).toString();
2468 : 0 : mDefault = map.value( QStringLiteral( "default" ) );
2469 : 0 : mGuiDefault = map.value( QStringLiteral( "defaultGui" ) );
2470 : 0 : mFlags = static_cast< Flags >( map.value( QStringLiteral( "flags" ) ).toInt() );
2471 : 0 : mMetadata = map.value( QStringLiteral( "metadata" ) ).toMap();
2472 : 0 : return true;
2473 : 0 : }
2474 : :
2475 : 0 : QgsProcessingAlgorithm *QgsProcessingParameterDefinition::algorithm() const
2476 : : {
2477 : 0 : return mAlgorithm;
2478 : : }
2479 : :
2480 : 0 : QgsProcessingProvider *QgsProcessingParameterDefinition::provider() const
2481 : : {
2482 : 0 : return mAlgorithm ? mAlgorithm->provider() : nullptr;
2483 : : }
2484 : :
2485 : 0 : QString QgsProcessingParameterDefinition::toolTip() const
2486 : : {
2487 : 0 : QString text = QStringLiteral( "<p><b>%1</b></p>" ).arg( description() );
2488 : 0 : if ( !help().isEmpty() )
2489 : : {
2490 : 0 : text += QStringLiteral( "<p>%1</p>" ).arg( help() );
2491 : 0 : }
2492 : 0 : text += QStringLiteral( "<p>%1</p>" ).arg( QObject::tr( "Python identifier: ‘%1’" ).arg( QStringLiteral( "<i>%1</i>" ).arg( name() ) ) );
2493 : 0 : return text;
2494 : 0 : }
2495 : :
2496 : 0 : QgsProcessingParameterBoolean::QgsProcessingParameterBoolean( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
2497 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2498 : 0 : {}
2499 : :
2500 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterBoolean::clone() const
2501 : : {
2502 : 0 : return new QgsProcessingParameterBoolean( *this );
2503 : 0 : }
2504 : :
2505 : 0 : QString QgsProcessingParameterBoolean::valueAsPythonString( const QVariant &val, QgsProcessingContext & ) const
2506 : : {
2507 : 0 : if ( !val.isValid() )
2508 : 0 : return QStringLiteral( "None" );
2509 : :
2510 : 0 : if ( val.canConvert<QgsProperty>() )
2511 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
2512 : 0 : return val.toBool() ? QStringLiteral( "True" ) : QStringLiteral( "False" );
2513 : 0 : }
2514 : :
2515 : 0 : QString QgsProcessingParameterBoolean::asScriptCode() const
2516 : : {
2517 : 0 : QString code = QStringLiteral( "##%1=" ).arg( mName );
2518 : 0 : if ( mFlags & FlagOptional )
2519 : 0 : code += QLatin1String( "optional " );
2520 : 0 : code += type() + ' ';
2521 : 0 : code += mDefault.toBool() ? QStringLiteral( "true" ) : QStringLiteral( "false" );
2522 : 0 : return code.trimmed();
2523 : 0 : }
2524 : :
2525 : 0 : QgsProcessingParameterBoolean *QgsProcessingParameterBoolean::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
2526 : : {
2527 : 0 : return new QgsProcessingParameterBoolean( name, description, definition.toLower().trimmed() != QStringLiteral( "false" ), isOptional );
2528 : 0 : }
2529 : :
2530 : 0 : QgsProcessingParameterCrs::QgsProcessingParameterCrs( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
2531 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2532 : 0 : {
2533 : :
2534 : 0 : }
2535 : :
2536 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterCrs::clone() const
2537 : : {
2538 : 0 : return new QgsProcessingParameterCrs( *this );
2539 : 0 : }
2540 : :
2541 : 0 : bool QgsProcessingParameterCrs::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
2542 : : {
2543 : 0 : if ( !input.isValid() )
2544 : 0 : return mFlags & FlagOptional;
2545 : :
2546 : 0 : if ( input.canConvert<QgsCoordinateReferenceSystem>() )
2547 : : {
2548 : 0 : return true;
2549 : : }
2550 : 0 : else if ( input.canConvert<QgsProcessingFeatureSourceDefinition>() )
2551 : : {
2552 : 0 : return true;
2553 : : }
2554 : 0 : else if ( input.canConvert<QgsProcessingOutputLayerDefinition>() )
2555 : : {
2556 : 0 : return true;
2557 : : }
2558 : :
2559 : 0 : if ( input.canConvert<QgsProperty>() )
2560 : : {
2561 : 0 : return true;
2562 : : }
2563 : :
2564 : : // direct map layer value
2565 : 0 : if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
2566 : 0 : return true;
2567 : :
2568 : 0 : if ( input.type() != QVariant::String || input.toString().isEmpty() )
2569 : 0 : return mFlags & FlagOptional;
2570 : :
2571 : 0 : return true;
2572 : 0 : }
2573 : :
2574 : 0 : QString QgsProcessingParameterCrs::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
2575 : : {
2576 : 0 : if ( !value.isValid() )
2577 : 0 : return QStringLiteral( "None" );
2578 : :
2579 : 0 : if ( value.canConvert<QgsCoordinateReferenceSystem>() )
2580 : : {
2581 : 0 : if ( !value.value< QgsCoordinateReferenceSystem >().isValid() )
2582 : 0 : return QStringLiteral( "QgsCoordinateReferenceSystem()" );
2583 : : else
2584 : 0 : return QStringLiteral( "QgsCoordinateReferenceSystem('%1')" ).arg( value.value< QgsCoordinateReferenceSystem >().authid() );
2585 : : }
2586 : :
2587 : 0 : if ( value.canConvert<QgsProperty>() )
2588 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
2589 : :
2590 : 0 : QVariantMap p;
2591 : 0 : p.insert( name(), value );
2592 : 0 : QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
2593 : 0 : if ( layer )
2594 : 0 : return QgsProcessingUtils::stringToPythonLiteral( QgsProcessingUtils::normalizeLayerSource( layer->source() ) );
2595 : :
2596 : 0 : return QgsProcessingParameterDefinition::valueAsPythonString( value, context );
2597 : 0 : }
2598 : :
2599 : 0 : QgsProcessingParameterCrs *QgsProcessingParameterCrs::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
2600 : : {
2601 : 0 : return new QgsProcessingParameterCrs( name, description, definition.compare( QLatin1String( "none" ), Qt::CaseInsensitive ) == 0 ? QVariant() : definition, isOptional );
2602 : 0 : }
2603 : :
2604 : 0 : QgsProcessingParameterMapLayer::QgsProcessingParameterMapLayer( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, const QList<int> &types )
2605 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2606 : 0 : , QgsProcessingParameterLimitedDataTypes( types )
2607 : 0 : {
2608 : :
2609 : 0 : }
2610 : :
2611 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterMapLayer::clone() const
2612 : : {
2613 : 0 : return new QgsProcessingParameterMapLayer( *this );
2614 : 0 : }
2615 : :
2616 : 0 : bool QgsProcessingParameterMapLayer::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context ) const
2617 : : {
2618 : 0 : if ( !input.isValid() )
2619 : 0 : return mFlags & FlagOptional;
2620 : :
2621 : 0 : if ( input.canConvert<QgsProperty>() )
2622 : : {
2623 : 0 : return true;
2624 : : }
2625 : :
2626 : 0 : if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
2627 : : {
2628 : 0 : return true;
2629 : : }
2630 : :
2631 : 0 : if ( input.type() != QVariant::String || input.toString().isEmpty() )
2632 : 0 : return mFlags & FlagOptional;
2633 : :
2634 : 0 : if ( !context )
2635 : : {
2636 : : // that's as far as we can get without a context
2637 : 0 : return true;
2638 : : }
2639 : :
2640 : : // try to load as layer
2641 : 0 : if ( QgsProcessingUtils::mapLayerFromString( input.toString(), *context ) )
2642 : 0 : return true;
2643 : :
2644 : 0 : return false;
2645 : 0 : }
2646 : :
2647 : 0 : QString QgsProcessingParameterMapLayer::valueAsPythonString( const QVariant &val, QgsProcessingContext &context ) const
2648 : : {
2649 : 0 : if ( !val.isValid() )
2650 : 0 : return QStringLiteral( "None" );
2651 : :
2652 : 0 : if ( val.canConvert<QgsProperty>() )
2653 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
2654 : :
2655 : 0 : QVariantMap p;
2656 : 0 : p.insert( name(), val );
2657 : 0 : QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
2658 : 0 : return layer ? QgsProcessingUtils::stringToPythonLiteral( QgsProcessingUtils::normalizeLayerSource( layer->source() ) )
2659 : 0 : : QgsProcessingUtils::stringToPythonLiteral( val.toString() );
2660 : 0 : }
2661 : :
2662 : 0 : QString createAllMapLayerFileFilter()
2663 : : {
2664 : 0 : QStringList vectors = QgsProviderRegistry::instance()->fileVectorFilters().split( QStringLiteral( ";;" ) );
2665 : 0 : QStringList rasters = QgsProviderRegistry::instance()->fileRasterFilters().split( QStringLiteral( ";;" ) );
2666 : 0 : for ( const QString &raster : rasters )
2667 : : {
2668 : 0 : if ( !vectors.contains( raster ) )
2669 : 0 : vectors << raster;
2670 : : }
2671 : 0 : QStringList meshFilters = QgsProviderRegistry::instance()->fileMeshFilters().split( QStringLiteral( ";;" ) );
2672 : 0 : for ( const QString &mesh : meshFilters )
2673 : : {
2674 : 0 : if ( !vectors.contains( mesh ) )
2675 : 0 : vectors << mesh;
2676 : : }
2677 : 0 : vectors.removeAll( QObject::tr( "All files (*.*)" ) );
2678 : 0 : std::sort( vectors.begin(), vectors.end() );
2679 : :
2680 : 0 : return QObject::tr( "All files (*.*)" ) + QStringLiteral( ";;" ) + vectors.join( QLatin1String( ";;" ) );
2681 : 0 : }
2682 : :
2683 : 0 : QString QgsProcessingParameterMapLayer::createFileFilter() const
2684 : : {
2685 : 0 : return createAllMapLayerFileFilter();
2686 : : }
2687 : :
2688 : 0 : QString QgsProcessingParameterMapLayer::asScriptCode() const
2689 : : {
2690 : 0 : QString code = QStringLiteral( "##%1=" ).arg( mName );
2691 : 0 : if ( mFlags & FlagOptional )
2692 : 0 : code += QLatin1String( "optional " );
2693 : 0 : code += QLatin1String( "layer " );
2694 : :
2695 : 0 : for ( int type : mDataTypes )
2696 : : {
2697 : 0 : switch ( type )
2698 : : {
2699 : : case QgsProcessing::TypeVectorAnyGeometry:
2700 : 0 : code += QLatin1String( "hasgeometry " );
2701 : 0 : break;
2702 : :
2703 : : case QgsProcessing::TypeVectorPoint:
2704 : 0 : code += QLatin1String( "point " );
2705 : 0 : break;
2706 : :
2707 : : case QgsProcessing::TypeVectorLine:
2708 : 0 : code += QLatin1String( "line " );
2709 : 0 : break;
2710 : :
2711 : : case QgsProcessing::TypeVectorPolygon:
2712 : 0 : code += QLatin1String( "polygon " );
2713 : 0 : break;
2714 : :
2715 : : case QgsProcessing::TypeRaster:
2716 : 0 : code += QLatin1String( "raster " );
2717 : 0 : break;
2718 : :
2719 : : case QgsProcessing::TypeMesh:
2720 : 0 : code += QLatin1String( "mesh " );
2721 : 0 : break;
2722 : : }
2723 : : }
2724 : :
2725 : 0 : code += mDefault.toString();
2726 : 0 : return code.trimmed();
2727 : 0 : }
2728 : :
2729 : 0 : QgsProcessingParameterMapLayer *QgsProcessingParameterMapLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
2730 : : {
2731 : 0 : QList< int > types;
2732 : 0 : QString def = definition;
2733 : 0 : while ( true )
2734 : : {
2735 : 0 : if ( def.startsWith( QLatin1String( "hasgeometry" ), Qt::CaseInsensitive ) )
2736 : : {
2737 : 0 : types << QgsProcessing::TypeVectorAnyGeometry;
2738 : 0 : def = def.mid( 12 );
2739 : 0 : continue;
2740 : : }
2741 : 0 : else if ( def.startsWith( QLatin1String( "point" ), Qt::CaseInsensitive ) )
2742 : : {
2743 : 0 : types << QgsProcessing::TypeVectorPoint;
2744 : 0 : def = def.mid( 6 );
2745 : 0 : continue;
2746 : : }
2747 : 0 : else if ( def.startsWith( QLatin1String( "line" ), Qt::CaseInsensitive ) )
2748 : : {
2749 : 0 : types << QgsProcessing::TypeVectorLine;
2750 : 0 : def = def.mid( 5 );
2751 : 0 : continue;
2752 : : }
2753 : 0 : else if ( def.startsWith( QLatin1String( "polygon" ), Qt::CaseInsensitive ) )
2754 : : {
2755 : 0 : types << QgsProcessing::TypeVectorPolygon;
2756 : 0 : def = def.mid( 8 );
2757 : 0 : continue;
2758 : : }
2759 : 0 : else if ( def.startsWith( QLatin1String( "raster" ), Qt::CaseInsensitive ) )
2760 : : {
2761 : 0 : types << QgsProcessing::TypeRaster;
2762 : 0 : def = def.mid( 7 );
2763 : 0 : continue;
2764 : : }
2765 : 0 : else if ( def.startsWith( QLatin1String( "mesh" ), Qt::CaseInsensitive ) )
2766 : : {
2767 : 0 : types << QgsProcessing::TypeMesh;
2768 : 0 : def = def.mid( 5 );
2769 : 0 : continue;
2770 : : }
2771 : 0 : break;
2772 : : }
2773 : :
2774 : 0 : return new QgsProcessingParameterMapLayer( name, description, def, isOptional, types );
2775 : 0 : }
2776 : :
2777 : 0 : QString QgsProcessingParameterMapLayer::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
2778 : : {
2779 : 0 : switch ( outputType )
2780 : : {
2781 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
2782 : : {
2783 : 0 : QString code = QStringLiteral( "QgsProcessingParameterMapLayer('%1', '%2'" ).arg( name(), description() );
2784 : 0 : if ( mFlags & FlagOptional )
2785 : 0 : code += QLatin1String( ", optional=True" );
2786 : :
2787 : 0 : QgsProcessingContext c;
2788 : 0 : code += QStringLiteral( ", defaultValue=%1" ).arg( valueAsPythonString( mDefault, c ) );
2789 : :
2790 : 0 : if ( !mDataTypes.empty() )
2791 : : {
2792 : 0 : QStringList options;
2793 : 0 : options.reserve( mDataTypes.size() );
2794 : 0 : for ( int t : mDataTypes )
2795 : 0 : options << QStringLiteral( "QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( static_cast< QgsProcessing::SourceType >( t ) ) );
2796 : 0 : code += QStringLiteral( ", types=[%1])" ).arg( options.join( ',' ) );
2797 : 0 : }
2798 : : else
2799 : : {
2800 : 0 : code += QLatin1Char( ')' );
2801 : : }
2802 : :
2803 : 0 : return code;
2804 : 0 : }
2805 : : }
2806 : 0 : return QString();
2807 : 0 : }
2808 : :
2809 : 0 : QVariantMap QgsProcessingParameterMapLayer::toVariantMap() const
2810 : : {
2811 : 0 : QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
2812 : 0 : QVariantList types;
2813 : 0 : for ( int type : mDataTypes )
2814 : : {
2815 : 0 : types << type;
2816 : : }
2817 : 0 : map.insert( QStringLiteral( "data_types" ), types );
2818 : 0 : return map;
2819 : 0 : }
2820 : :
2821 : 0 : bool QgsProcessingParameterMapLayer::fromVariantMap( const QVariantMap &map )
2822 : : {
2823 : 0 : QgsProcessingParameterDefinition::fromVariantMap( map );
2824 : 0 : mDataTypes.clear();
2825 : 0 : const QVariantList values = map.value( QStringLiteral( "data_types" ) ).toList();
2826 : 0 : for ( const QVariant &val : values )
2827 : : {
2828 : 0 : mDataTypes << val.toInt();
2829 : : }
2830 : : return true;
2831 : 0 : }
2832 : :
2833 : 0 : QgsProcessingParameterExtent::QgsProcessingParameterExtent( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
2834 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2835 : 0 : {
2836 : :
2837 : 0 : }
2838 : :
2839 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterExtent::clone() const
2840 : : {
2841 : 0 : return new QgsProcessingParameterExtent( *this );
2842 : 0 : }
2843 : :
2844 : 0 : bool QgsProcessingParameterExtent::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context ) const
2845 : : {
2846 : 0 : if ( !input.isValid() )
2847 : 0 : return mFlags & FlagOptional;
2848 : :
2849 : 0 : if ( input.canConvert<QgsProcessingFeatureSourceDefinition>() )
2850 : : {
2851 : 0 : return true;
2852 : : }
2853 : 0 : else if ( input.canConvert<QgsProcessingOutputLayerDefinition>() )
2854 : : {
2855 : 0 : return true;
2856 : : }
2857 : :
2858 : 0 : if ( input.canConvert<QgsProperty>() )
2859 : : {
2860 : 0 : return true;
2861 : : }
2862 : :
2863 : 0 : if ( input.canConvert< QgsRectangle >() )
2864 : : {
2865 : 0 : QgsRectangle r = input.value<QgsRectangle>();
2866 : 0 : return !r.isNull();
2867 : : }
2868 : 0 : if ( input.canConvert< QgsGeometry >() )
2869 : : {
2870 : 0 : return true;
2871 : : }
2872 : 0 : if ( input.canConvert< QgsReferencedRectangle >() )
2873 : : {
2874 : 0 : QgsReferencedRectangle r = input.value<QgsReferencedRectangle>();
2875 : 0 : return !r.isNull();
2876 : 0 : }
2877 : :
2878 : : // direct map layer value
2879 : 0 : if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
2880 : 0 : return true;
2881 : :
2882 : 0 : if ( input.type() != QVariant::String || input.toString().isEmpty() )
2883 : 0 : return mFlags & FlagOptional;
2884 : :
2885 : 0 : if ( !context )
2886 : : {
2887 : : // that's as far as we can get without a context
2888 : 0 : return true;
2889 : : }
2890 : :
2891 : 0 : QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?)\\s*,\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
2892 : 0 : QRegularExpressionMatch match = rx.match( input.toString() );
2893 : 0 : if ( match.hasMatch() )
2894 : : {
2895 : 0 : bool xMinOk = false;
2896 : 0 : ( void )match.captured( 1 ).toDouble( &xMinOk );
2897 : 0 : bool xMaxOk = false;
2898 : 0 : ( void )match.captured( 2 ).toDouble( &xMaxOk );
2899 : 0 : bool yMinOk = false;
2900 : 0 : ( void )match.captured( 3 ).toDouble( &yMinOk );
2901 : 0 : bool yMaxOk = false;
2902 : 0 : ( void )match.captured( 4 ).toDouble( &yMaxOk );
2903 : 0 : if ( xMinOk && xMaxOk && yMinOk && yMaxOk )
2904 : 0 : return true;
2905 : 0 : }
2906 : :
2907 : : // try as layer extent
2908 : 0 : return QgsProcessingUtils::mapLayerFromString( input.toString(), *context );
2909 : 0 : }
2910 : :
2911 : 0 : QString QgsProcessingParameterExtent::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
2912 : : {
2913 : 0 : if ( !value.isValid() )
2914 : 0 : return QStringLiteral( "None" );
2915 : :
2916 : 0 : if ( value.canConvert<QgsProperty>() )
2917 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
2918 : :
2919 : 0 : if ( value.canConvert< QgsRectangle >() )
2920 : : {
2921 : 0 : QgsRectangle r = value.value<QgsRectangle>();
2922 : 0 : return QStringLiteral( "'%1, %3, %2, %4'" ).arg( qgsDoubleToString( r.xMinimum() ),
2923 : 0 : qgsDoubleToString( r.yMinimum() ),
2924 : 0 : qgsDoubleToString( r.xMaximum() ),
2925 : 0 : qgsDoubleToString( r.yMaximum() ) );
2926 : : }
2927 : 0 : else if ( value.canConvert< QgsReferencedRectangle >() )
2928 : : {
2929 : 0 : QgsReferencedRectangle r = value.value<QgsReferencedRectangle>();
2930 : 0 : return QStringLiteral( "'%1, %3, %2, %4 [%5]'" ).arg( qgsDoubleToString( r.xMinimum() ),
2931 : 0 : qgsDoubleToString( r.yMinimum() ),
2932 : 0 : qgsDoubleToString( r.xMaximum() ),
2933 : 0 : qgsDoubleToString( r.yMaximum() ), r.crs().authid() );
2934 : 0 : }
2935 : 0 : else if ( value.canConvert< QgsGeometry >() )
2936 : : {
2937 : 0 : const QgsGeometry g = value.value<QgsGeometry>();
2938 : 0 : if ( !g.isNull() )
2939 : : {
2940 : 0 : const QString wkt = g.asWkt();
2941 : 0 : return QStringLiteral( "QgsGeometry.fromWkt('%1')" ).arg( wkt );
2942 : 0 : }
2943 : 0 : }
2944 : :
2945 : 0 : QVariantMap p;
2946 : 0 : p.insert( name(), value );
2947 : 0 : QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
2948 : 0 : if ( layer )
2949 : 0 : return QgsProcessingUtils::stringToPythonLiteral( QgsProcessingUtils::normalizeLayerSource( layer->source() ) );
2950 : :
2951 : 0 : return QgsProcessingParameterDefinition::valueAsPythonString( value, context );
2952 : 0 : }
2953 : :
2954 : 0 : QgsProcessingParameterExtent *QgsProcessingParameterExtent::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
2955 : : {
2956 : 0 : return new QgsProcessingParameterExtent( name, description, definition, isOptional );
2957 : 0 : }
2958 : :
2959 : 0 : QgsProcessingParameterPoint::QgsProcessingParameterPoint( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
2960 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2961 : 0 : {
2962 : :
2963 : 0 : }
2964 : :
2965 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterPoint::clone() const
2966 : : {
2967 : 0 : return new QgsProcessingParameterPoint( *this );
2968 : 0 : }
2969 : :
2970 : 0 : bool QgsProcessingParameterPoint::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
2971 : : {
2972 : 0 : if ( !input.isValid() )
2973 : 0 : return mFlags & FlagOptional;
2974 : :
2975 : 0 : if ( input.canConvert<QgsProperty>() )
2976 : : {
2977 : 0 : return true;
2978 : : }
2979 : :
2980 : 0 : if ( input.canConvert< QgsPointXY >() )
2981 : : {
2982 : 0 : return true;
2983 : : }
2984 : 0 : if ( input.canConvert< QgsReferencedPointXY >() )
2985 : : {
2986 : 0 : return true;
2987 : : }
2988 : 0 : if ( input.canConvert< QgsGeometry >() )
2989 : : {
2990 : 0 : return true;
2991 : : }
2992 : :
2993 : 0 : if ( input.type() == QVariant::String )
2994 : : {
2995 : 0 : if ( input.toString().isEmpty() )
2996 : 0 : return mFlags & FlagOptional;
2997 : 0 : }
2998 : :
2999 : 0 : QRegularExpression rx( QStringLiteral( "^\\s*\\(?\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*\\)?\\s*$" ) );
3000 : :
3001 : 0 : QRegularExpressionMatch match = rx.match( input.toString() );
3002 : 0 : if ( match.hasMatch() )
3003 : : {
3004 : 0 : bool xOk = false;
3005 : 0 : ( void )match.captured( 1 ).toDouble( &xOk );
3006 : 0 : bool yOk = false;
3007 : 0 : ( void )match.captured( 2 ).toDouble( &yOk );
3008 : 0 : return xOk && yOk;
3009 : : }
3010 : : else
3011 : 0 : return false;
3012 : 0 : }
3013 : :
3014 : 0 : QString QgsProcessingParameterPoint::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
3015 : : {
3016 : 0 : if ( !value.isValid() )
3017 : 0 : return QStringLiteral( "None" );
3018 : :
3019 : 0 : if ( value.canConvert<QgsProperty>() )
3020 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
3021 : :
3022 : 0 : if ( value.canConvert< QgsPointXY >() )
3023 : : {
3024 : 0 : QgsPointXY r = value.value<QgsPointXY>();
3025 : 0 : return QStringLiteral( "'%1,%2'" ).arg( qgsDoubleToString( r.x() ),
3026 : 0 : qgsDoubleToString( r.y() ) );
3027 : : }
3028 : 0 : else if ( value.canConvert< QgsReferencedPointXY >() )
3029 : : {
3030 : 0 : QgsReferencedPointXY r = value.value<QgsReferencedPointXY>();
3031 : 0 : return QStringLiteral( "'%1,%2 [%3]'" ).arg( qgsDoubleToString( r.x() ),
3032 : 0 : qgsDoubleToString( r.y() ),
3033 : 0 : r.crs().authid() );
3034 : 0 : }
3035 : 0 : else if ( value.canConvert< QgsGeometry >() )
3036 : : {
3037 : 0 : const QgsGeometry g = value.value<QgsGeometry>();
3038 : 0 : if ( !g.isNull() )
3039 : : {
3040 : 0 : const QString wkt = g.asWkt();
3041 : 0 : return QStringLiteral( "QgsGeometry.fromWkt('%1')" ).arg( wkt );
3042 : 0 : }
3043 : 0 : }
3044 : :
3045 : 0 : return QgsProcessingParameterDefinition::valueAsPythonString( value, context );
3046 : 0 : }
3047 : :
3048 : 0 : QgsProcessingParameterPoint *QgsProcessingParameterPoint::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3049 : : {
3050 : 0 : return new QgsProcessingParameterPoint( name, description, definition, isOptional );
3051 : 0 : }
3052 : :
3053 : 0 : QgsProcessingParameterGeometry::QgsProcessingParameterGeometry( const QString &name, const QString &description,
3054 : : const QVariant &defaultValue, bool optional, const QList<int> &geometryTypes, bool allowMultipart )
3055 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional ),
3056 : 0 : mGeomTypes( geometryTypes ),
3057 : 0 : mAllowMultipart( allowMultipart )
3058 : 0 : {
3059 : :
3060 : 0 : }
3061 : :
3062 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterGeometry::clone() const
3063 : : {
3064 : 0 : return new QgsProcessingParameterGeometry( *this );
3065 : 0 : }
3066 : :
3067 : 0 : bool QgsProcessingParameterGeometry::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
3068 : : {
3069 : 0 : if ( !input.isValid() )
3070 : 0 : return mFlags & FlagOptional;
3071 : :
3072 : 0 : if ( input.canConvert<QgsProperty>() )
3073 : : {
3074 : 0 : return true;
3075 : : }
3076 : :
3077 : 0 : bool anyTypeAllowed = mGeomTypes.isEmpty() || mGeomTypes.contains( QgsWkbTypes::UnknownGeometry );
3078 : :
3079 : 0 : if ( input.canConvert< QgsGeometry >() )
3080 : : {
3081 : 0 : return ( anyTypeAllowed || mGeomTypes.contains( input.value<QgsGeometry>().type() ) ) &&
3082 : 0 : ( mAllowMultipart || !input.value<QgsGeometry>().isMultipart() );
3083 : : }
3084 : :
3085 : 0 : if ( input.canConvert< QgsReferencedGeometry >() )
3086 : : {
3087 : 0 : return ( anyTypeAllowed || mGeomTypes.contains( input.value<QgsReferencedGeometry>().type() ) ) &&
3088 : 0 : ( mAllowMultipart || !input.value<QgsReferencedGeometry>().isMultipart() );
3089 : : }
3090 : :
3091 : 0 : if ( input.canConvert< QgsPointXY >() )
3092 : : {
3093 : 0 : return anyTypeAllowed || mGeomTypes.contains( QgsWkbTypes::PointGeometry );
3094 : : }
3095 : :
3096 : 0 : if ( input.canConvert< QgsRectangle >() )
3097 : : {
3098 : 0 : return anyTypeAllowed || mGeomTypes.contains( QgsWkbTypes::PolygonGeometry );
3099 : : }
3100 : :
3101 : 0 : if ( input.canConvert< QgsReferencedPointXY >() )
3102 : : {
3103 : 0 : return anyTypeAllowed || mGeomTypes.contains( QgsWkbTypes::PointGeometry );
3104 : : }
3105 : :
3106 : 0 : if ( input.canConvert< QgsReferencedRectangle >() )
3107 : : {
3108 : 0 : return anyTypeAllowed || mGeomTypes.contains( QgsWkbTypes::PolygonGeometry );
3109 : : }
3110 : :
3111 : 0 : if ( input.type() == QVariant::String )
3112 : : {
3113 : 0 : if ( input.toString().isEmpty() )
3114 : 0 : return mFlags & FlagOptional;
3115 : 0 : }
3116 : :
3117 : : // Match against EWKT
3118 : 0 : QRegularExpression rx( QStringLiteral( "^\\s*(?:CRS=(.*);)?(.*?)$" ) );
3119 : :
3120 : 0 : QRegularExpressionMatch match = rx.match( input.toString() );
3121 : 0 : if ( match.hasMatch() )
3122 : : {
3123 : 0 : QgsGeometry g = QgsGeometry::fromWkt( match.captured( 2 ) );
3124 : 0 : if ( ! g.isNull() )
3125 : : {
3126 : 0 : return ( anyTypeAllowed || mGeomTypes.contains( g.type() ) ) && ( mAllowMultipart || !g.isMultipart() );
3127 : : }
3128 : : else
3129 : : {
3130 : 0 : QgsMessageLog::logMessage( QObject::tr( "Error creating geometry: \"%1\"" ).arg( g.lastError() ), QObject::tr( "Processing" ) );
3131 : : }
3132 : 0 : }
3133 : 0 : return false;
3134 : 0 : }
3135 : :
3136 : 0 : QString QgsProcessingParameterGeometry::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
3137 : : {
3138 : 0 : auto asPythonString = []( const QgsGeometry & g, const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() )
3139 : : {
3140 : 0 : if ( !crs.isValid() )
3141 : 0 : return QgsProcessingUtils::stringToPythonLiteral( g.asWkt() );
3142 : : else
3143 : 0 : return QgsProcessingUtils::stringToPythonLiteral( QStringLiteral( "CRS=%1;%2" ).arg( crs.authid().isEmpty() ? crs.toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ) : crs.authid(), g.asWkt() ) );
3144 : 0 : };
3145 : :
3146 : 0 : if ( !value.isValid() )
3147 : 0 : return QStringLiteral( "None" );
3148 : :
3149 : 0 : if ( value.canConvert<QgsProperty>() )
3150 : 0 : return QStringLiteral( "QgsProperty.fromExpression(%1)" ).arg( QgsProcessingUtils::stringToPythonLiteral( value.value< QgsProperty >().asExpression() ) );
3151 : :
3152 : 0 : if ( value.canConvert< QgsGeometry >() )
3153 : : {
3154 : 0 : const QgsGeometry g = value.value<QgsGeometry>();
3155 : 0 : if ( !g.isNull() )
3156 : 0 : return asPythonString( g );
3157 : 0 : }
3158 : :
3159 : 0 : if ( value.canConvert< QgsReferencedGeometry >() )
3160 : : {
3161 : 0 : const QgsReferencedGeometry g = value.value<QgsReferencedGeometry>();
3162 : 0 : if ( !g.isNull() )
3163 : 0 : return asPythonString( g, g.crs() );
3164 : 0 : }
3165 : :
3166 : 0 : if ( value.canConvert< QgsPointXY >() )
3167 : : {
3168 : 0 : const QgsGeometry g = QgsGeometry::fromPointXY( value.value<QgsPointXY>() );
3169 : 0 : if ( !g.isNull() )
3170 : 0 : return asPythonString( g );
3171 : 0 : }
3172 : :
3173 : 0 : if ( value.canConvert< QgsReferencedPointXY >() )
3174 : : {
3175 : 0 : const QgsReferencedGeometry g = QgsReferencedGeometry::fromReferencedPointXY( value.value<QgsReferencedPointXY>() );
3176 : 0 : if ( !g.isNull() )
3177 : 0 : return asPythonString( g, g.crs() );
3178 : 0 : }
3179 : :
3180 : 0 : if ( value.canConvert< QgsRectangle >() )
3181 : : {
3182 : 0 : const QgsGeometry g = QgsGeometry::fromRect( value.value<QgsRectangle>() );
3183 : 0 : if ( !g.isNull() )
3184 : 0 : return asPythonString( g );
3185 : 0 : }
3186 : :
3187 : 0 : if ( value.canConvert< QgsReferencedRectangle >() )
3188 : : {
3189 : 0 : const QgsReferencedGeometry g = QgsReferencedGeometry::fromReferencedRect( value.value<QgsReferencedRectangle>() );
3190 : 0 : if ( !g.isNull() )
3191 : 0 : return asPythonString( g, g.crs() );
3192 : 0 : }
3193 : :
3194 : 0 : return QgsProcessingParameterDefinition::valueAsPythonString( value, context );
3195 : 0 : }
3196 : :
3197 : 0 : QString QgsProcessingParameterGeometry::asScriptCode() const
3198 : : {
3199 : 0 : QString code = QStringLiteral( "##%1=" ).arg( mName );
3200 : 0 : if ( mFlags & FlagOptional )
3201 : 0 : code += QLatin1String( "optional " );
3202 : 0 : code += type() + ' ';
3203 : :
3204 : 0 : for ( int type : mGeomTypes )
3205 : : {
3206 : 0 : switch ( static_cast<QgsWkbTypes::GeometryType>( type ) )
3207 : : {
3208 : : case QgsWkbTypes::PointGeometry:
3209 : 0 : code += QLatin1String( "point " );
3210 : 0 : break;
3211 : :
3212 : : case QgsWkbTypes::LineGeometry:
3213 : 0 : code += QLatin1String( "line " );
3214 : 0 : break;
3215 : :
3216 : : case QgsWkbTypes::PolygonGeometry:
3217 : 0 : code += QLatin1String( "polygon " );
3218 : 0 : break;
3219 : :
3220 : : default:
3221 : 0 : code += QLatin1String( "unknown " );
3222 : 0 : break;
3223 : : }
3224 : : }
3225 : :
3226 : 0 : code += mDefault.toString();
3227 : 0 : return code.trimmed();
3228 : 0 : }
3229 : :
3230 : 0 : QString QgsProcessingParameterGeometry::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
3231 : : {
3232 : 0 : switch ( outputType )
3233 : : {
3234 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
3235 : : {
3236 : 0 : QString code = QStringLiteral( "QgsProcessingParameterGeometry('%1', '%2'" ).arg( name(), description() );
3237 : 0 : if ( mFlags & FlagOptional )
3238 : 0 : code += QLatin1String( ", optional=True" );
3239 : :
3240 : 0 : if ( !mGeomTypes.empty() )
3241 : : {
3242 : 0 : auto geomTypeToString = []( QgsWkbTypes::GeometryType t ) -> QString
3243 : : {
3244 : 0 : switch ( t )
3245 : : {
3246 : : case QgsWkbTypes::PointGeometry:
3247 : 0 : return QStringLiteral( "PointGeometry" );
3248 : :
3249 : : case QgsWkbTypes::LineGeometry:
3250 : 0 : return QStringLiteral( "LineGeometry" );
3251 : :
3252 : : case QgsWkbTypes::PolygonGeometry:
3253 : 0 : return QStringLiteral( "PolygonGeometry" );
3254 : :
3255 : : case QgsWkbTypes::UnknownGeometry:
3256 : 0 : return QStringLiteral( "UnknownGeometry" );
3257 : :
3258 : : case QgsWkbTypes::NullGeometry:
3259 : 0 : return QStringLiteral( "NullGeometry" );
3260 : : }
3261 : 0 : return QString();
3262 : 0 : };
3263 : :
3264 : 0 : QStringList options;
3265 : 0 : options.reserve( mGeomTypes.size() );
3266 : 0 : for ( int type : mGeomTypes )
3267 : : {
3268 : 0 : options << QStringLiteral( " QgsWkbTypes.%1" ).arg( geomTypeToString( static_cast<QgsWkbTypes::GeometryType>( type ) ) );
3269 : : }
3270 : 0 : code += QStringLiteral( ", geometryTypes=[%1 ]" ).arg( options.join( ',' ) );
3271 : 0 : }
3272 : :
3273 : 0 : if ( ! mAllowMultipart )
3274 : : {
3275 : 0 : code += QStringLiteral( ", allowMultipart=False" );
3276 : 0 : }
3277 : :
3278 : 0 : QgsProcessingContext c;
3279 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
3280 : 0 : return code;
3281 : 0 : }
3282 : : }
3283 : 0 : return QString();
3284 : 0 : }
3285 : :
3286 : 0 : QVariantMap QgsProcessingParameterGeometry::toVariantMap() const
3287 : : {
3288 : 0 : QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
3289 : 0 : QVariantList types;
3290 : 0 : for ( int type : mGeomTypes )
3291 : : {
3292 : 0 : types << type;
3293 : : }
3294 : 0 : map.insert( QStringLiteral( "geometrytypes" ), types );
3295 : 0 : map.insert( QStringLiteral( "multipart" ), mAllowMultipart );
3296 : 0 : return map;
3297 : 0 : }
3298 : :
3299 : 0 : bool QgsProcessingParameterGeometry::fromVariantMap( const QVariantMap &map )
3300 : : {
3301 : 0 : QgsProcessingParameterDefinition::fromVariantMap( map );
3302 : 0 : mGeomTypes.clear();
3303 : 0 : const QVariantList values = map.value( QStringLiteral( "geometrytypes" ) ).toList();
3304 : 0 : for ( const QVariant &val : values )
3305 : : {
3306 : 0 : mGeomTypes << val.toInt();
3307 : : }
3308 : 0 : mAllowMultipart = map.value( QStringLiteral( "multipart" ) ).toBool();
3309 : : return true;
3310 : 0 : }
3311 : :
3312 : 0 : QgsProcessingParameterGeometry *QgsProcessingParameterGeometry::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3313 : : {
3314 : 0 : return new QgsProcessingParameterGeometry( name, description, definition, isOptional );
3315 : 0 : }
3316 : :
3317 : 0 : QgsProcessingParameterFile::QgsProcessingParameterFile( const QString &name, const QString &description, Behavior behavior, const QString &extension, const QVariant &defaultValue, bool optional, const QString &fileFilter )
3318 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3319 : 0 : , mBehavior( behavior )
3320 : 0 : , mExtension( fileFilter.isEmpty() ? extension : QString() )
3321 : 0 : , mFileFilter( fileFilter.isEmpty() && extension.isEmpty() ? QObject::tr( "All files (*.*)" ) : fileFilter )
3322 : 0 : {
3323 : :
3324 : 0 : }
3325 : :
3326 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterFile::clone() const
3327 : : {
3328 : 0 : return new QgsProcessingParameterFile( *this );
3329 : 0 : }
3330 : :
3331 : 0 : bool QgsProcessingParameterFile::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
3332 : : {
3333 : 0 : if ( !input.isValid() )
3334 : 0 : return mFlags & FlagOptional;
3335 : :
3336 : 0 : if ( input.canConvert<QgsProperty>() )
3337 : : {
3338 : 0 : return true;
3339 : : }
3340 : :
3341 : 0 : QString string = input.toString().trimmed();
3342 : :
3343 : 0 : if ( input.type() != QVariant::String || string.isEmpty() )
3344 : 0 : return mFlags & FlagOptional;
3345 : :
3346 : 0 : switch ( mBehavior )
3347 : : {
3348 : : case File:
3349 : : {
3350 : 0 : if ( !mExtension.isEmpty() )
3351 : : {
3352 : 0 : return string.endsWith( mExtension, Qt::CaseInsensitive );
3353 : : }
3354 : 0 : else if ( !mFileFilter.isEmpty() )
3355 : : {
3356 : 0 : const QString test = QgsFileUtils::addExtensionFromFilter( string, mFileFilter );
3357 : 0 : return test == string;
3358 : 0 : }
3359 : : else
3360 : : {
3361 : 0 : return true;
3362 : : }
3363 : : }
3364 : :
3365 : : case Folder:
3366 : 0 : return true;
3367 : : }
3368 : 0 : return true;
3369 : 0 : }
3370 : :
3371 : 0 : QString QgsProcessingParameterFile::asScriptCode() const
3372 : : {
3373 : 0 : QString code = QStringLiteral( "##%1=" ).arg( mName );
3374 : 0 : if ( mFlags & FlagOptional )
3375 : 0 : code += QLatin1String( "optional " );
3376 : 0 : code += ( mBehavior == File ? QStringLiteral( "file" ) : QStringLiteral( "folder" ) ) + ' ';
3377 : 0 : code += mDefault.toString();
3378 : 0 : return code.trimmed();
3379 : 0 : }
3380 : :
3381 : 0 : QString QgsProcessingParameterFile::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
3382 : : {
3383 : 0 : switch ( outputType )
3384 : : {
3385 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
3386 : : {
3387 : :
3388 : 0 : QString code = QStringLiteral( "QgsProcessingParameterFile('%1', '%2'" ).arg( name(), description() );
3389 : 0 : if ( mFlags & FlagOptional )
3390 : 0 : code += QLatin1String( ", optional=True" );
3391 : 0 : code += QStringLiteral( ", behavior=%1" ).arg( mBehavior == File ? QStringLiteral( "QgsProcessingParameterFile.File" ) : QStringLiteral( "QgsProcessingParameterFile.Folder" ) );
3392 : 0 : if ( !mExtension.isEmpty() )
3393 : 0 : code += QStringLiteral( ", extension='%1'" ).arg( mExtension );
3394 : 0 : if ( !mFileFilter.isEmpty() )
3395 : 0 : code += QStringLiteral( ", fileFilter='%1'" ).arg( mFileFilter );
3396 : 0 : QgsProcessingContext c;
3397 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
3398 : 0 : return code;
3399 : 0 : }
3400 : : }
3401 : 0 : return QString();
3402 : 0 : }
3403 : :
3404 : 0 : QString QgsProcessingParameterFile::createFileFilter() const
3405 : : {
3406 : 0 : switch ( mBehavior )
3407 : : {
3408 : : case File:
3409 : : {
3410 : 0 : if ( !mFileFilter.isEmpty() )
3411 : 0 : return mFileFilter != QObject::tr( "All files (*.*)" ) ? mFileFilter + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" ) : mFileFilter;
3412 : 0 : else if ( !mExtension.isEmpty() )
3413 : 0 : return QObject::tr( "%1 files" ).arg( mExtension.toUpper() ) + QStringLiteral( " (*." ) + mExtension.toLower() + QStringLiteral( ");;" ) + QObject::tr( "All files (*.*)" );
3414 : : else
3415 : 0 : return QObject::tr( "All files (*.*)" );
3416 : : }
3417 : :
3418 : : case Folder:
3419 : 0 : return QString();
3420 : : }
3421 : 0 : return QString();
3422 : 0 : }
3423 : :
3424 : 0 : void QgsProcessingParameterFile::setExtension( const QString &extension )
3425 : : {
3426 : 0 : mExtension = extension;
3427 : 0 : mFileFilter.clear();
3428 : 0 : }
3429 : :
3430 : 0 : QString QgsProcessingParameterFile::fileFilter() const
3431 : : {
3432 : 0 : return mFileFilter;
3433 : : }
3434 : :
3435 : 0 : void QgsProcessingParameterFile::setFileFilter( const QString &filter )
3436 : : {
3437 : 0 : mFileFilter = filter;
3438 : 0 : mExtension.clear();
3439 : 0 : }
3440 : :
3441 : 0 : QVariantMap QgsProcessingParameterFile::toVariantMap() const
3442 : : {
3443 : 0 : QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
3444 : 0 : map.insert( QStringLiteral( "behavior" ), mBehavior );
3445 : 0 : map.insert( QStringLiteral( "extension" ), mExtension );
3446 : 0 : map.insert( QStringLiteral( "filefilter" ), mFileFilter );
3447 : 0 : return map;
3448 : 0 : }
3449 : :
3450 : 0 : bool QgsProcessingParameterFile::fromVariantMap( const QVariantMap &map )
3451 : : {
3452 : 0 : QgsProcessingParameterDefinition::fromVariantMap( map );
3453 : 0 : mBehavior = static_cast< Behavior >( map.value( QStringLiteral( "behavior" ) ).toInt() );
3454 : 0 : mExtension = map.value( QStringLiteral( "extension" ) ).toString();
3455 : 0 : mFileFilter = map.value( QStringLiteral( "filefilter" ) ).toString();
3456 : 0 : return true;
3457 : 0 : }
3458 : :
3459 : 0 : QgsProcessingParameterFile *QgsProcessingParameterFile::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition, QgsProcessingParameterFile::Behavior behavior )
3460 : : {
3461 : 0 : return new QgsProcessingParameterFile( name, description, behavior, QString(), definition, isOptional );
3462 : 0 : }
3463 : :
3464 : 0 : QgsProcessingParameterMatrix::QgsProcessingParameterMatrix( const QString &name, const QString &description, int numberRows, bool fixedNumberRows, const QStringList &headers, const QVariant &defaultValue, bool optional )
3465 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3466 : 0 : , mHeaders( headers )
3467 : 0 : , mNumberRows( numberRows )
3468 : 0 : , mFixedNumberRows( fixedNumberRows )
3469 : 0 : {
3470 : :
3471 : 0 : }
3472 : :
3473 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterMatrix::clone() const
3474 : : {
3475 : 0 : return new QgsProcessingParameterMatrix( *this );
3476 : 0 : }
3477 : :
3478 : 0 : bool QgsProcessingParameterMatrix::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
3479 : : {
3480 : 0 : if ( !input.isValid() )
3481 : 0 : return mFlags & FlagOptional;
3482 : :
3483 : 0 : if ( input.type() == QVariant::String )
3484 : : {
3485 : 0 : if ( input.toString().isEmpty() )
3486 : 0 : return mFlags & FlagOptional;
3487 : 0 : return true;
3488 : : }
3489 : 0 : else if ( input.type() == QVariant::List )
3490 : : {
3491 : 0 : if ( input.toList().isEmpty() )
3492 : 0 : return mFlags & FlagOptional;
3493 : 0 : return true;
3494 : : }
3495 : 0 : else if ( input.type() == QVariant::Double || input.type() == QVariant::Int )
3496 : : {
3497 : 0 : return true;
3498 : : }
3499 : :
3500 : 0 : return false;
3501 : 0 : }
3502 : :
3503 : 0 : QString QgsProcessingParameterMatrix::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
3504 : : {
3505 : 0 : if ( !value.isValid() )
3506 : 0 : return QStringLiteral( "None" );
3507 : :
3508 : 0 : if ( value.canConvert<QgsProperty>() )
3509 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
3510 : :
3511 : 0 : QVariantMap p;
3512 : 0 : p.insert( name(), value );
3513 : 0 : QVariantList list = QgsProcessingParameters::parameterAsMatrix( this, p, context );
3514 : :
3515 : 0 : QStringList parts;
3516 : 0 : const auto constList = list;
3517 : 0 : for ( const QVariant &v : constList )
3518 : : {
3519 : 0 : if ( v.type() == QVariant::List )
3520 : : {
3521 : 0 : QStringList parts2;
3522 : 0 : const auto constToList = v.toList();
3523 : 0 : for ( const QVariant &v2 : constToList )
3524 : : {
3525 : 0 : if ( v2.isNull() || !v2.isValid() )
3526 : 0 : parts2 << QStringLiteral( "None" );
3527 : 0 : else if ( v2.toString().isEmpty() )
3528 : 0 : parts2 << QStringLiteral( "''" );
3529 : : else
3530 : 0 : parts2 << v2.toString();
3531 : : }
3532 : 0 : parts << parts2.join( ',' ).prepend( '[' ).append( ']' );
3533 : 0 : }
3534 : : else
3535 : : {
3536 : 0 : if ( v.isNull() || !v.isValid() )
3537 : 0 : parts << QStringLiteral( "None" );
3538 : 0 : else if ( v.toString().isEmpty() )
3539 : 0 : parts << QStringLiteral( "''" );
3540 : : else
3541 : 0 : parts << v.toString();
3542 : : }
3543 : : }
3544 : :
3545 : 0 : return parts.join( ',' ).prepend( '[' ).append( ']' );
3546 : 0 : }
3547 : :
3548 : 0 : QString QgsProcessingParameterMatrix::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
3549 : : {
3550 : 0 : switch ( outputType )
3551 : : {
3552 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
3553 : : {
3554 : 0 : QString code = QStringLiteral( "QgsProcessingParameterMatrix('%1', '%2'" ).arg( name(), description() );
3555 : 0 : if ( mFlags & FlagOptional )
3556 : 0 : code += QLatin1String( ", optional=True" );
3557 : 0 : code += QStringLiteral( ", numberRows=" ).arg( mNumberRows );
3558 : 0 : code += QStringLiteral( ", hasFixedNumberRows=" ).arg( mFixedNumberRows ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
3559 : :
3560 : 0 : QStringList headers;
3561 : 0 : headers.reserve( mHeaders.size() );
3562 : 0 : for ( const QString &h : mHeaders )
3563 : 0 : headers << QgsProcessingUtils::stringToPythonLiteral( h );
3564 : 0 : code += QStringLiteral( ", headers=[%1]" ).arg( headers.join( ',' ) );
3565 : :
3566 : 0 : QgsProcessingContext c;
3567 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
3568 : 0 : return code;
3569 : 0 : }
3570 : : }
3571 : 0 : return QString();
3572 : 0 : }
3573 : :
3574 : 0 : QStringList QgsProcessingParameterMatrix::headers() const
3575 : : {
3576 : 0 : return mHeaders;
3577 : : }
3578 : :
3579 : 0 : void QgsProcessingParameterMatrix::setHeaders( const QStringList &headers )
3580 : : {
3581 : 0 : mHeaders = headers;
3582 : 0 : }
3583 : :
3584 : 0 : int QgsProcessingParameterMatrix::numberRows() const
3585 : : {
3586 : 0 : return mNumberRows;
3587 : : }
3588 : :
3589 : 0 : void QgsProcessingParameterMatrix::setNumberRows( int numberRows )
3590 : : {
3591 : 0 : mNumberRows = numberRows;
3592 : 0 : }
3593 : :
3594 : 0 : bool QgsProcessingParameterMatrix::hasFixedNumberRows() const
3595 : : {
3596 : 0 : return mFixedNumberRows;
3597 : : }
3598 : :
3599 : 0 : void QgsProcessingParameterMatrix::setHasFixedNumberRows( bool fixedNumberRows )
3600 : : {
3601 : 0 : mFixedNumberRows = fixedNumberRows;
3602 : 0 : }
3603 : :
3604 : 0 : QVariantMap QgsProcessingParameterMatrix::toVariantMap() const
3605 : : {
3606 : 0 : QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
3607 : 0 : map.insert( QStringLiteral( "headers" ), mHeaders );
3608 : 0 : map.insert( QStringLiteral( "rows" ), mNumberRows );
3609 : 0 : map.insert( QStringLiteral( "fixed_number_rows" ), mFixedNumberRows );
3610 : 0 : return map;
3611 : 0 : }
3612 : :
3613 : 0 : bool QgsProcessingParameterMatrix::fromVariantMap( const QVariantMap &map )
3614 : : {
3615 : 0 : QgsProcessingParameterDefinition::fromVariantMap( map );
3616 : 0 : mHeaders = map.value( QStringLiteral( "headers" ) ).toStringList();
3617 : 0 : mNumberRows = map.value( QStringLiteral( "rows" ) ).toInt();
3618 : 0 : mFixedNumberRows = map.value( QStringLiteral( "fixed_number_rows" ) ).toBool();
3619 : 0 : return true;
3620 : 0 : }
3621 : :
3622 : 0 : QgsProcessingParameterMatrix *QgsProcessingParameterMatrix::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3623 : : {
3624 : 0 : return new QgsProcessingParameterMatrix( name, description, 0, false, QStringList(), definition.isEmpty() ? QVariant() : definition, isOptional );
3625 : 0 : }
3626 : :
3627 : 0 : QgsProcessingParameterMultipleLayers::QgsProcessingParameterMultipleLayers( const QString &name, const QString &description, QgsProcessing::SourceType layerType, const QVariant &defaultValue, bool optional )
3628 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3629 : 0 : , mLayerType( layerType )
3630 : 0 : {
3631 : :
3632 : 0 : }
3633 : :
3634 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterMultipleLayers::clone() const
3635 : : {
3636 : 0 : return new QgsProcessingParameterMultipleLayers( *this );
3637 : 0 : }
3638 : :
3639 : 0 : bool QgsProcessingParameterMultipleLayers::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context ) const
3640 : : {
3641 : 0 : if ( !input.isValid() )
3642 : 0 : return mFlags & FlagOptional;
3643 : :
3644 : 0 : if ( mLayerType != QgsProcessing::TypeFile )
3645 : : {
3646 : 0 : if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
3647 : : {
3648 : 0 : return true;
3649 : : }
3650 : 0 : }
3651 : :
3652 : 0 : if ( input.type() == QVariant::String )
3653 : : {
3654 : 0 : if ( input.toString().isEmpty() )
3655 : 0 : return mFlags & FlagOptional;
3656 : :
3657 : 0 : if ( mMinimumNumberInputs > 1 )
3658 : 0 : return false;
3659 : :
3660 : 0 : if ( !context )
3661 : 0 : return true;
3662 : :
3663 : 0 : if ( mLayerType != QgsProcessing::TypeFile )
3664 : 0 : return QgsProcessingUtils::mapLayerFromString( input.toString(), *context );
3665 : : else
3666 : 0 : return true;
3667 : : }
3668 : 0 : else if ( input.type() == QVariant::List )
3669 : : {
3670 : 0 : if ( input.toList().count() < mMinimumNumberInputs )
3671 : 0 : return mFlags & FlagOptional;
3672 : :
3673 : 0 : if ( mMinimumNumberInputs > input.toList().count() )
3674 : 0 : return false;
3675 : :
3676 : 0 : if ( !context )
3677 : 0 : return true;
3678 : :
3679 : 0 : if ( mLayerType != QgsProcessing::TypeFile )
3680 : : {
3681 : 0 : const auto constToList = input.toList();
3682 : 0 : for ( const QVariant &v : constToList )
3683 : : {
3684 : 0 : if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( v ) ) )
3685 : 0 : continue;
3686 : :
3687 : 0 : if ( !QgsProcessingUtils::mapLayerFromString( v.toString(), *context ) )
3688 : 0 : return false;
3689 : : }
3690 : 0 : }
3691 : 0 : return true;
3692 : : }
3693 : 0 : else if ( input.type() == QVariant::StringList )
3694 : : {
3695 : 0 : if ( input.toStringList().count() < mMinimumNumberInputs )
3696 : 0 : return mFlags & FlagOptional;
3697 : :
3698 : 0 : if ( mMinimumNumberInputs > input.toStringList().count() )
3699 : 0 : return false;
3700 : :
3701 : 0 : if ( !context )
3702 : 0 : return true;
3703 : :
3704 : 0 : if ( mLayerType != QgsProcessing::TypeFile )
3705 : : {
3706 : 0 : const auto constToStringList = input.toStringList();
3707 : 0 : for ( const QString &v : constToStringList )
3708 : : {
3709 : 0 : if ( !QgsProcessingUtils::mapLayerFromString( v, *context ) )
3710 : 0 : return false;
3711 : : }
3712 : 0 : }
3713 : 0 : return true;
3714 : : }
3715 : 0 : return false;
3716 : 0 : }
3717 : :
3718 : 0 : QString QgsProcessingParameterMultipleLayers::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
3719 : : {
3720 : 0 : if ( !value.isValid() )
3721 : 0 : return QStringLiteral( "None" );
3722 : :
3723 : 0 : if ( value.canConvert<QgsProperty>() )
3724 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
3725 : :
3726 : 0 : if ( mLayerType == QgsProcessing::TypeFile )
3727 : : {
3728 : 0 : QStringList parts;
3729 : 0 : if ( value.type() == QVariant::StringList )
3730 : : {
3731 : 0 : const QStringList list = value.toStringList();
3732 : 0 : parts.reserve( list.count() );
3733 : 0 : for ( const QString &v : list )
3734 : 0 : parts << QgsProcessingUtils::stringToPythonLiteral( v );
3735 : 0 : }
3736 : 0 : else if ( value.type() == QVariant::List )
3737 : : {
3738 : 0 : const QVariantList list = value.toList();
3739 : 0 : parts.reserve( list.count() );
3740 : 0 : for ( const QVariant &v : list )
3741 : 0 : parts << QgsProcessingUtils::stringToPythonLiteral( v.toString() );
3742 : 0 : }
3743 : 0 : if ( !parts.isEmpty() )
3744 : 0 : return parts.join( ',' ).prepend( '[' ).append( ']' );
3745 : 0 : }
3746 : : else
3747 : : {
3748 : 0 : QVariantMap p;
3749 : 0 : p.insert( name(), value );
3750 : 0 : const QList<QgsMapLayer *> list = QgsProcessingParameters::parameterAsLayerList( this, p, context );
3751 : 0 : if ( !list.isEmpty() )
3752 : : {
3753 : 0 : QStringList parts;
3754 : 0 : parts.reserve( list.count() );
3755 : 0 : for ( const QgsMapLayer *layer : list )
3756 : : {
3757 : 0 : parts << QgsProcessingUtils::stringToPythonLiteral( QgsProcessingUtils::normalizeLayerSource( layer->source() ) );
3758 : : }
3759 : 0 : return parts.join( ',' ).prepend( '[' ).append( ']' );
3760 : 0 : }
3761 : 0 : }
3762 : :
3763 : 0 : return QgsProcessingParameterDefinition::valueAsPythonString( value, context );
3764 : 0 : }
3765 : :
3766 : 0 : QString QgsProcessingParameterMultipleLayers::asScriptCode() const
3767 : : {
3768 : 0 : QString code = QStringLiteral( "##%1=" ).arg( mName );
3769 : 0 : if ( mFlags & FlagOptional )
3770 : 0 : code += QLatin1String( "optional " );
3771 : 0 : switch ( mLayerType )
3772 : : {
3773 : : case QgsProcessing::TypeRaster:
3774 : 0 : code += QLatin1String( "multiple raster" );
3775 : 0 : break;
3776 : :
3777 : : case QgsProcessing::TypeFile:
3778 : 0 : code += QLatin1String( "multiple file" );
3779 : 0 : break;
3780 : :
3781 : : default:
3782 : 0 : code += QLatin1String( "multiple vector" );
3783 : 0 : break;
3784 : : }
3785 : 0 : code += ' ';
3786 : 0 : if ( mDefault.type() == QVariant::List )
3787 : : {
3788 : 0 : QStringList parts;
3789 : 0 : const auto constToList = mDefault.toList();
3790 : 0 : for ( const QVariant &var : constToList )
3791 : : {
3792 : 0 : parts << var.toString();
3793 : : }
3794 : 0 : code += parts.join( ',' );
3795 : 0 : }
3796 : 0 : else if ( mDefault.type() == QVariant::StringList )
3797 : : {
3798 : 0 : code += mDefault.toStringList().join( ',' );
3799 : 0 : }
3800 : : else
3801 : : {
3802 : 0 : code += mDefault.toString();
3803 : : }
3804 : 0 : return code.trimmed();
3805 : 0 : }
3806 : :
3807 : 0 : QString QgsProcessingParameterMultipleLayers::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
3808 : : {
3809 : 0 : switch ( outputType )
3810 : : {
3811 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
3812 : : {
3813 : 0 : QString code = QStringLiteral( "QgsProcessingParameterMultipleLayers('%1', '%2'" ).arg( name(), description() );
3814 : 0 : if ( mFlags & FlagOptional )
3815 : 0 : code += QLatin1String( ", optional=True" );
3816 : :
3817 : 0 : QString layerType = QStringLiteral( "QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( mLayerType ) );
3818 : :
3819 : 0 : code += QStringLiteral( ", layerType=%1" ).arg( layerType );
3820 : 0 : QgsProcessingContext c;
3821 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
3822 : 0 : return code;
3823 : 0 : }
3824 : : }
3825 : 0 : return QString();
3826 : 0 : }
3827 : :
3828 : 0 : QString QgsProcessingParameterMultipleLayers::createFileFilter() const
3829 : : {
3830 : 0 : QStringList exts;
3831 : 0 : switch ( mLayerType )
3832 : : {
3833 : : case QgsProcessing::TypeFile:
3834 : 0 : return QObject::tr( "All files (*.*)" );
3835 : :
3836 : : case QgsProcessing::TypeRaster:
3837 : 0 : return QgsProviderRegistry::instance()->fileRasterFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
3838 : :
3839 : : case QgsProcessing::TypeVector:
3840 : : case QgsProcessing::TypeVectorAnyGeometry:
3841 : : case QgsProcessing::TypeVectorPoint:
3842 : : case QgsProcessing::TypeVectorLine:
3843 : : case QgsProcessing::TypeVectorPolygon:
3844 : 0 : return QgsProviderRegistry::instance()->fileVectorFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
3845 : :
3846 : : case QgsProcessing::TypeMesh:
3847 : 0 : return QgsProviderRegistry::instance()->fileMeshFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
3848 : :
3849 : : case QgsProcessing::TypeMapLayer:
3850 : 0 : return createAllMapLayerFileFilter();
3851 : : }
3852 : 0 : return QString();
3853 : 0 : }
3854 : :
3855 : 0 : QgsProcessing::SourceType QgsProcessingParameterMultipleLayers::layerType() const
3856 : : {
3857 : 0 : return mLayerType;
3858 : : }
3859 : :
3860 : 0 : void QgsProcessingParameterMultipleLayers::setLayerType( QgsProcessing::SourceType type )
3861 : : {
3862 : 0 : mLayerType = type;
3863 : 0 : }
3864 : :
3865 : 0 : int QgsProcessingParameterMultipleLayers::minimumNumberInputs() const
3866 : : {
3867 : 0 : return mMinimumNumberInputs;
3868 : : }
3869 : :
3870 : 0 : void QgsProcessingParameterMultipleLayers::setMinimumNumberInputs( int minimumNumberInputs )
3871 : : {
3872 : 0 : if ( mMinimumNumberInputs >= 1 || !( flags() & QgsProcessingParameterDefinition::FlagOptional ) )
3873 : 0 : mMinimumNumberInputs = minimumNumberInputs;
3874 : 0 : }
3875 : :
3876 : 0 : QVariantMap QgsProcessingParameterMultipleLayers::toVariantMap() const
3877 : : {
3878 : 0 : QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
3879 : 0 : map.insert( QStringLiteral( "layer_type" ), mLayerType );
3880 : 0 : map.insert( QStringLiteral( "min_inputs" ), mMinimumNumberInputs );
3881 : 0 : return map;
3882 : 0 : }
3883 : :
3884 : 0 : bool QgsProcessingParameterMultipleLayers::fromVariantMap( const QVariantMap &map )
3885 : : {
3886 : 0 : QgsProcessingParameterDefinition::fromVariantMap( map );
3887 : 0 : mLayerType = static_cast< QgsProcessing::SourceType >( map.value( QStringLiteral( "layer_type" ) ).toInt() );
3888 : 0 : mMinimumNumberInputs = map.value( QStringLiteral( "min_inputs" ) ).toInt();
3889 : 0 : return true;
3890 : 0 : }
3891 : :
3892 : 0 : QgsProcessingParameterMultipleLayers *QgsProcessingParameterMultipleLayers::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3893 : : {
3894 : 0 : QString type = definition;
3895 : 0 : QString defaultVal;
3896 : 0 : QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*)" ) );
3897 : 0 : QRegularExpressionMatch m = re.match( definition );
3898 : 0 : if ( m.hasMatch() )
3899 : : {
3900 : 0 : type = m.captured( 1 ).toLower().trimmed();
3901 : 0 : defaultVal = m.captured( 2 );
3902 : 0 : }
3903 : 0 : QgsProcessing::SourceType layerType = QgsProcessing::TypeVectorAnyGeometry;
3904 : 0 : if ( type == QLatin1String( "vector" ) )
3905 : 0 : layerType = QgsProcessing::TypeVectorAnyGeometry;
3906 : 0 : else if ( type == QLatin1String( "raster" ) )
3907 : 0 : layerType = QgsProcessing::TypeRaster;
3908 : 0 : else if ( type == QLatin1String( "file" ) )
3909 : 0 : layerType = QgsProcessing::TypeFile;
3910 : 0 : return new QgsProcessingParameterMultipleLayers( name, description, layerType, defaultVal.isEmpty() ? QVariant() : defaultVal, isOptional );
3911 : 0 : }
3912 : :
3913 : 0 : QgsProcessingParameterNumber::QgsProcessingParameterNumber( const QString &name, const QString &description, Type type, const QVariant &defaultValue, bool optional, double minValue, double maxValue )
3914 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3915 : 0 : , mMin( minValue )
3916 : 0 : , mMax( maxValue )
3917 : 0 : , mDataType( type )
3918 : 0 : {
3919 : 0 : if ( mMin >= mMax )
3920 : : {
3921 : 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" ) );
3922 : 0 : }
3923 : 0 : }
3924 : :
3925 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterNumber::clone() const
3926 : : {
3927 : 0 : return new QgsProcessingParameterNumber( *this );
3928 : 0 : }
3929 : :
3930 : 0 : bool QgsProcessingParameterNumber::checkValueIsAcceptable( const QVariant &value, QgsProcessingContext * ) const
3931 : : {
3932 : 0 : QVariant input = value;
3933 : 0 : if ( !input.isValid() )
3934 : : {
3935 : 0 : if ( !defaultValue().isValid() )
3936 : 0 : return mFlags & FlagOptional;
3937 : :
3938 : 0 : input = defaultValue();
3939 : 0 : }
3940 : :
3941 : 0 : if ( input.canConvert<QgsProperty>() )
3942 : : {
3943 : 0 : return true;
3944 : : }
3945 : :
3946 : 0 : bool ok = false;
3947 : 0 : double res = input.toDouble( &ok );
3948 : 0 : if ( !ok )
3949 : 0 : return mFlags & FlagOptional;
3950 : :
3951 : 0 : return !( res < mMin || res > mMax );
3952 : 0 : }
3953 : :
3954 : 0 : QString QgsProcessingParameterNumber::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
3955 : : {
3956 : 0 : if ( !value.isValid() )
3957 : 0 : return QStringLiteral( "None" );
3958 : :
3959 : 0 : if ( value.canConvert<QgsProperty>() )
3960 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
3961 : :
3962 : 0 : return value.toString();
3963 : 0 : }
3964 : :
3965 : 0 : QString QgsProcessingParameterNumber::toolTip() const
3966 : : {
3967 : 0 : QString text = QgsProcessingParameterDefinition::toolTip();
3968 : 0 : QStringList parts;
3969 : 0 : if ( mMin > std::numeric_limits<double>::lowest() + 1 )
3970 : 0 : parts << QObject::tr( "Minimum value: %1" ).arg( mMin );
3971 : 0 : if ( mMax < std::numeric_limits<double>::max() )
3972 : 0 : parts << QObject::tr( "Maximum value: %1" ).arg( mMax );
3973 : 0 : if ( mDefault.isValid() )
3974 : 0 : parts << QObject::tr( "Default value: %1" ).arg( mDataType == Integer ? mDefault.toInt() : mDefault.toDouble() );
3975 : 0 : QString extra = parts.join( QLatin1String( "<br />" ) );
3976 : 0 : if ( !extra.isEmpty() )
3977 : 0 : text += QStringLiteral( "<p>%1</p>" ).arg( extra );
3978 : 0 : return text;
3979 : 0 : }
3980 : :
3981 : 0 : QString QgsProcessingParameterNumber::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
3982 : : {
3983 : 0 : switch ( outputType )
3984 : : {
3985 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
3986 : : {
3987 : 0 : QString code = QStringLiteral( "QgsProcessingParameterNumber('%1', '%2'" ).arg( name(), description() );
3988 : 0 : if ( mFlags & FlagOptional )
3989 : 0 : code += QLatin1String( ", optional=True" );
3990 : :
3991 : 0 : code += QStringLiteral( ", type=%1" ).arg( mDataType == Integer ? QStringLiteral( "QgsProcessingParameterNumber.Integer" ) : QStringLiteral( "QgsProcessingParameterNumber.Double" ) );
3992 : :
3993 : 0 : if ( mMin != std::numeric_limits<double>::lowest() + 1 )
3994 : 0 : code += QStringLiteral( ", minValue=%1" ).arg( mMin );
3995 : 0 : if ( mMax != std::numeric_limits<double>::max() )
3996 : 0 : code += QStringLiteral( ", maxValue=%1" ).arg( mMax );
3997 : 0 : QgsProcessingContext c;
3998 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
3999 : 0 : return code;
4000 : 0 : }
4001 : : }
4002 : 0 : return QString();
4003 : 0 : }
4004 : :
4005 : 0 : double QgsProcessingParameterNumber::minimum() const
4006 : : {
4007 : 0 : return mMin;
4008 : : }
4009 : :
4010 : 0 : void QgsProcessingParameterNumber::setMinimum( double min )
4011 : : {
4012 : 0 : mMin = min;
4013 : 0 : }
4014 : :
4015 : 0 : double QgsProcessingParameterNumber::maximum() const
4016 : : {
4017 : 0 : return mMax;
4018 : : }
4019 : :
4020 : 0 : void QgsProcessingParameterNumber::setMaximum( double max )
4021 : : {
4022 : 0 : mMax = max;
4023 : 0 : }
4024 : :
4025 : 0 : QgsProcessingParameterNumber::Type QgsProcessingParameterNumber::dataType() const
4026 : : {
4027 : 0 : return mDataType;
4028 : : }
4029 : :
4030 : 0 : void QgsProcessingParameterNumber::setDataType( Type dataType )
4031 : : {
4032 : 0 : mDataType = dataType;
4033 : 0 : }
4034 : :
4035 : 0 : QVariantMap QgsProcessingParameterNumber::toVariantMap() const
4036 : : {
4037 : 0 : QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
4038 : 0 : map.insert( QStringLiteral( "min" ), mMin );
4039 : 0 : map.insert( QStringLiteral( "max" ), mMax );
4040 : 0 : map.insert( QStringLiteral( "data_type" ), mDataType );
4041 : 0 : return map;
4042 : 0 : }
4043 : :
4044 : 0 : bool QgsProcessingParameterNumber::fromVariantMap( const QVariantMap &map )
4045 : : {
4046 : 0 : QgsProcessingParameterDefinition::fromVariantMap( map );
4047 : 0 : mMin = map.value( QStringLiteral( "min" ) ).toDouble();
4048 : 0 : mMax = map.value( QStringLiteral( "max" ) ).toDouble();
4049 : 0 : mDataType = static_cast< Type >( map.value( QStringLiteral( "data_type" ) ).toInt() );
4050 : 0 : return true;
4051 : 0 : }
4052 : :
4053 : 0 : QgsProcessingParameterNumber *QgsProcessingParameterNumber::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4054 : : {
4055 : 0 : return new QgsProcessingParameterNumber( name, description, Double, definition.isEmpty() ? QVariant()
4056 : 0 : : ( definition.toLower().trimmed() == QLatin1String( "none" ) ? QVariant() : definition ), isOptional );
4057 : 0 : }
4058 : :
4059 : 0 : QgsProcessingParameterRange::QgsProcessingParameterRange( const QString &name, const QString &description, QgsProcessingParameterNumber::Type type, const QVariant &defaultValue, bool optional )
4060 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4061 : 0 : , mDataType( type )
4062 : 0 : {
4063 : :
4064 : 0 : }
4065 : :
4066 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterRange::clone() const
4067 : : {
4068 : 0 : return new QgsProcessingParameterRange( *this );
4069 : 0 : }
4070 : :
4071 : 0 : bool QgsProcessingParameterRange::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
4072 : : {
4073 : 0 : if ( !input.isValid() )
4074 : 0 : return mFlags & FlagOptional;
4075 : :
4076 : 0 : if ( input.canConvert<QgsProperty>() )
4077 : : {
4078 : 0 : return true;
4079 : : }
4080 : :
4081 : 0 : if ( input.type() == QVariant::String )
4082 : : {
4083 : 0 : QStringList list = input.toString().split( ',' );
4084 : 0 : if ( list.count() != 2 )
4085 : 0 : return mFlags & FlagOptional;
4086 : 0 : bool ok = false;
4087 : 0 : list.at( 0 ).toDouble( &ok );
4088 : 0 : bool ok2 = false;
4089 : 0 : list.at( 1 ).toDouble( &ok2 );
4090 : 0 : if ( !ok || !ok2 )
4091 : 0 : return mFlags & FlagOptional;
4092 : 0 : return true;
4093 : 0 : }
4094 : 0 : else if ( input.type() == QVariant::List )
4095 : : {
4096 : 0 : if ( input.toList().count() != 2 )
4097 : 0 : return mFlags & FlagOptional;
4098 : :
4099 : 0 : bool ok = false;
4100 : 0 : input.toList().at( 0 ).toDouble( &ok );
4101 : 0 : bool ok2 = false;
4102 : 0 : input.toList().at( 1 ).toDouble( &ok2 );
4103 : 0 : if ( !ok || !ok2 )
4104 : 0 : return mFlags & FlagOptional;
4105 : 0 : return true;
4106 : : }
4107 : :
4108 : 0 : return false;
4109 : 0 : }
4110 : :
4111 : 0 : QString QgsProcessingParameterRange::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
4112 : : {
4113 : 0 : if ( !value.isValid() )
4114 : 0 : return QStringLiteral( "None" );
4115 : :
4116 : 0 : if ( value.canConvert<QgsProperty>() )
4117 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4118 : :
4119 : 0 : QVariantMap p;
4120 : 0 : p.insert( name(), value );
4121 : 0 : QList< double > parts = QgsProcessingParameters::parameterAsRange( this, p, context );
4122 : :
4123 : 0 : QStringList stringParts;
4124 : 0 : const auto constParts = parts;
4125 : 0 : for ( double v : constParts )
4126 : : {
4127 : 0 : stringParts << QString::number( v );
4128 : : }
4129 : 0 : return stringParts.join( ',' ).prepend( '[' ).append( ']' );
4130 : 0 : }
4131 : :
4132 : 0 : QString QgsProcessingParameterRange::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
4133 : : {
4134 : 0 : switch ( outputType )
4135 : : {
4136 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
4137 : : {
4138 : 0 : QString code = QStringLiteral( "QgsProcessingParameterRange('%1', '%2'" ).arg( name(), description() );
4139 : 0 : if ( mFlags & FlagOptional )
4140 : 0 : code += QLatin1String( ", optional=True" );
4141 : :
4142 : 0 : code += QStringLiteral( ", type=%1" ).arg( mDataType == QgsProcessingParameterNumber::Integer ? QStringLiteral( "QgsProcessingParameterNumber.Integer" ) : QStringLiteral( "QgsProcessingParameterNumber.Double" ) );
4143 : :
4144 : 0 : QgsProcessingContext c;
4145 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4146 : 0 : return code;
4147 : 0 : }
4148 : : }
4149 : 0 : return QString();
4150 : 0 : }
4151 : :
4152 : 0 : QgsProcessingParameterNumber::Type QgsProcessingParameterRange::dataType() const
4153 : : {
4154 : 0 : return mDataType;
4155 : : }
4156 : :
4157 : 0 : void QgsProcessingParameterRange::setDataType( QgsProcessingParameterNumber::Type dataType )
4158 : : {
4159 : 0 : mDataType = dataType;
4160 : 0 : }
4161 : :
4162 : 0 : QVariantMap QgsProcessingParameterRange::toVariantMap() const
4163 : : {
4164 : 0 : QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
4165 : 0 : map.insert( QStringLiteral( "data_type" ), mDataType );
4166 : 0 : return map;
4167 : 0 : }
4168 : :
4169 : 0 : bool QgsProcessingParameterRange::fromVariantMap( const QVariantMap &map )
4170 : : {
4171 : 0 : QgsProcessingParameterDefinition::fromVariantMap( map );
4172 : 0 : mDataType = static_cast< QgsProcessingParameterNumber::Type >( map.value( QStringLiteral( "data_type" ) ).toInt() );
4173 : 0 : return true;
4174 : 0 : }
4175 : :
4176 : 0 : QgsProcessingParameterRange *QgsProcessingParameterRange::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4177 : : {
4178 : 0 : return new QgsProcessingParameterRange( name, description, QgsProcessingParameterNumber::Double, definition.isEmpty() ? QVariant()
4179 : 0 : : ( definition.toLower().trimmed() == QLatin1String( "none" ) ? QVariant() : definition ), isOptional );
4180 : 0 : }
4181 : :
4182 : 0 : QgsProcessingParameterRasterLayer::QgsProcessingParameterRasterLayer( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
4183 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4184 : 0 : {
4185 : :
4186 : 0 : }
4187 : :
4188 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterRasterLayer::clone() const
4189 : : {
4190 : 0 : return new QgsProcessingParameterRasterLayer( *this );
4191 : 0 : }
4192 : :
4193 : 0 : bool QgsProcessingParameterRasterLayer::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context ) const
4194 : : {
4195 : 0 : if ( !input.isValid() )
4196 : 0 : return mFlags & FlagOptional;
4197 : :
4198 : 0 : if ( input.canConvert<QgsProperty>() )
4199 : : {
4200 : 0 : return true;
4201 : : }
4202 : :
4203 : 0 : if ( qobject_cast< QgsRasterLayer * >( qvariant_cast<QObject *>( input ) ) )
4204 : 0 : return true;
4205 : :
4206 : 0 : if ( input.type() != QVariant::String || input.toString().isEmpty() )
4207 : 0 : return mFlags & FlagOptional;
4208 : :
4209 : 0 : if ( !context )
4210 : : {
4211 : : // that's as far as we can get without a context
4212 : 0 : return true;
4213 : : }
4214 : :
4215 : : // try to load as layer
4216 : 0 : if ( QgsProcessingUtils::mapLayerFromString( input.toString(), *context, true, QgsProcessingUtils::LayerHint::Raster ) )
4217 : 0 : return true;
4218 : :
4219 : 0 : return false;
4220 : 0 : }
4221 : :
4222 : 0 : QString QgsProcessingParameterRasterLayer::valueAsPythonString( const QVariant &val, QgsProcessingContext &context ) const
4223 : : {
4224 : 0 : if ( !val.isValid() )
4225 : 0 : return QStringLiteral( "None" );
4226 : :
4227 : 0 : if ( val.canConvert<QgsProperty>() )
4228 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
4229 : :
4230 : 0 : QVariantMap p;
4231 : 0 : p.insert( name(), val );
4232 : 0 : QgsRasterLayer *layer = QgsProcessingParameters::parameterAsRasterLayer( this, p, context );
4233 : 0 : return layer ? QgsProcessingUtils::stringToPythonLiteral( QgsProcessingUtils::normalizeLayerSource( layer->source() ) )
4234 : 0 : : QgsProcessingUtils::stringToPythonLiteral( val.toString() );
4235 : 0 : }
4236 : :
4237 : 0 : QString QgsProcessingParameterRasterLayer::createFileFilter() const
4238 : : {
4239 : 0 : return QgsProviderRegistry::instance()->fileRasterFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
4240 : 0 : }
4241 : :
4242 : 0 : QgsProcessingParameterRasterLayer *QgsProcessingParameterRasterLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4243 : : {
4244 : 0 : return new QgsProcessingParameterRasterLayer( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
4245 : 0 : }
4246 : :
4247 : 5 : QgsProcessingParameterEnum::QgsProcessingParameterEnum( const QString &name, const QString &description, const QStringList &options, bool allowMultiple, const QVariant &defaultValue, bool optional, bool usesStaticStrings )
4248 : 5 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4249 : 5 : , mOptions( options )
4250 : 5 : , mAllowMultiple( allowMultiple )
4251 : 5 : , mUsesStaticStrings( usesStaticStrings )
4252 : 5 : {
4253 : :
4254 : 5 : }
4255 : :
4256 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterEnum::clone() const
4257 : : {
4258 : 0 : return new QgsProcessingParameterEnum( *this );
4259 : 0 : }
4260 : :
4261 : 0 : bool QgsProcessingParameterEnum::checkValueIsAcceptable( const QVariant &value, QgsProcessingContext * ) const
4262 : : {
4263 : 0 : QVariant input = value;
4264 : 0 : if ( !input.isValid() )
4265 : : {
4266 : 0 : if ( !defaultValue().isValid() )
4267 : 0 : return mFlags & FlagOptional;
4268 : :
4269 : 0 : input = defaultValue();
4270 : 0 : }
4271 : :
4272 : 0 : if ( input.canConvert<QgsProperty>() )
4273 : : {
4274 : 0 : return true;
4275 : : }
4276 : :
4277 : 0 : if ( mUsesStaticStrings )
4278 : : {
4279 : 0 : if ( input.type() == QVariant::List )
4280 : : {
4281 : 0 : if ( !mAllowMultiple )
4282 : 0 : return false;
4283 : :
4284 : 0 : const QVariantList values = input.toList();
4285 : 0 : if ( values.empty() && !( mFlags & FlagOptional ) )
4286 : 0 : return false;
4287 : :
4288 : 0 : for ( const QVariant &val : values )
4289 : : {
4290 : 0 : if ( !mOptions.contains( val.toString() ) )
4291 : 0 : return false;
4292 : : }
4293 : :
4294 : 0 : return true;
4295 : 0 : }
4296 : 0 : else if ( input.type() == QVariant::StringList )
4297 : : {
4298 : 0 : if ( !mAllowMultiple )
4299 : 0 : return false;
4300 : :
4301 : 0 : const QStringList values = input.toStringList();
4302 : :
4303 : 0 : if ( values.empty() && !( mFlags & FlagOptional ) )
4304 : 0 : return false;
4305 : :
4306 : 0 : if ( values.count() > 1 && !mAllowMultiple )
4307 : 0 : return false;
4308 : :
4309 : 0 : for ( const QString &val : values )
4310 : : {
4311 : 0 : if ( !mOptions.contains( val ) )
4312 : 0 : return false;
4313 : : }
4314 : 0 : return true;
4315 : 0 : }
4316 : 0 : else if ( input.type() == QVariant::String )
4317 : : {
4318 : 0 : QStringList parts = input.toString().split( ',' );
4319 : 0 : if ( parts.count() > 1 && !mAllowMultiple )
4320 : 0 : return false;
4321 : :
4322 : 0 : const auto constParts = parts;
4323 : 0 : for ( const QString &part : constParts )
4324 : : {
4325 : 0 : if ( !mOptions.contains( part ) )
4326 : 0 : return false;
4327 : : }
4328 : 0 : return true;
4329 : 0 : }
4330 : 0 : }
4331 : : else
4332 : : {
4333 : 0 : if ( input.type() == QVariant::List )
4334 : : {
4335 : 0 : if ( !mAllowMultiple )
4336 : 0 : return false;
4337 : :
4338 : 0 : const QVariantList values = input.toList();
4339 : 0 : if ( values.empty() && !( mFlags & FlagOptional ) )
4340 : 0 : return false;
4341 : :
4342 : 0 : for ( const QVariant &val : values )
4343 : : {
4344 : 0 : bool ok = false;
4345 : 0 : int res = val.toInt( &ok );
4346 : 0 : if ( !ok )
4347 : 0 : return false;
4348 : 0 : else if ( res < 0 || res >= mOptions.count() )
4349 : 0 : return false;
4350 : : }
4351 : :
4352 : 0 : return true;
4353 : 0 : }
4354 : 0 : else if ( input.type() == QVariant::String )
4355 : : {
4356 : 0 : QStringList parts = input.toString().split( ',' );
4357 : 0 : if ( parts.count() > 1 && !mAllowMultiple )
4358 : 0 : return false;
4359 : :
4360 : 0 : const auto constParts = parts;
4361 : 0 : for ( const QString &part : constParts )
4362 : : {
4363 : 0 : bool ok = false;
4364 : 0 : int res = part.toInt( &ok );
4365 : 0 : if ( !ok )
4366 : 0 : return false;
4367 : 0 : else if ( res < 0 || res >= mOptions.count() )
4368 : 0 : return false;
4369 : : }
4370 : 0 : return true;
4371 : 0 : }
4372 : 0 : else if ( input.type() == QVariant::Int || input.type() == QVariant::Double )
4373 : : {
4374 : 0 : bool ok = false;
4375 : 0 : int res = input.toInt( &ok );
4376 : 0 : if ( !ok )
4377 : 0 : return false;
4378 : 0 : else if ( res >= 0 && res < mOptions.count() )
4379 : 0 : return true;
4380 : 0 : }
4381 : : }
4382 : :
4383 : 0 : return false;
4384 : 0 : }
4385 : :
4386 : 0 : QString QgsProcessingParameterEnum::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
4387 : : {
4388 : 0 : if ( !value.isValid() )
4389 : 0 : return QStringLiteral( "None" );
4390 : :
4391 : 0 : if ( value.canConvert<QgsProperty>() )
4392 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4393 : :
4394 : 0 : if ( mUsesStaticStrings )
4395 : : {
4396 : 0 : if ( value.type() == QVariant::StringList )
4397 : : {
4398 : 0 : QStringList parts;
4399 : 0 : const QStringList constList = value.toStringList();
4400 : 0 : for ( const QString &val : constList )
4401 : : {
4402 : 0 : parts << QgsProcessingUtils::stringToPythonLiteral( val );
4403 : : }
4404 : 0 : return parts.join( ',' ).prepend( '[' ).append( ']' );
4405 : 0 : }
4406 : 0 : else if ( value.type() == QVariant::String )
4407 : : {
4408 : 0 : QStringList parts;
4409 : 0 : const QStringList constList = value.toString().split( ',' );
4410 : 0 : if ( constList.count() > 1 )
4411 : : {
4412 : 0 : for ( const QString &val : constList )
4413 : : {
4414 : 0 : parts << QgsProcessingUtils::stringToPythonLiteral( val );
4415 : : }
4416 : 0 : return parts.join( ',' ).prepend( '[' ).append( ']' );
4417 : : }
4418 : 0 : }
4419 : :
4420 : 0 : return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
4421 : : }
4422 : : else
4423 : : {
4424 : 0 : if ( value.type() == QVariant::List )
4425 : : {
4426 : 0 : QStringList parts;
4427 : 0 : const auto constToList = value.toList();
4428 : 0 : for ( const QVariant &val : constToList )
4429 : : {
4430 : 0 : parts << QString::number( static_cast< int >( val.toDouble() ) );
4431 : : }
4432 : 0 : return parts.join( ',' ).prepend( '[' ).append( ']' );
4433 : 0 : }
4434 : 0 : else if ( value.type() == QVariant::String )
4435 : : {
4436 : 0 : QStringList parts = value.toString().split( ',' );
4437 : 0 : if ( parts.count() > 1 )
4438 : : {
4439 : 0 : return parts.join( ',' ).prepend( '[' ).append( ']' );
4440 : : }
4441 : 0 : }
4442 : :
4443 : 0 : return QString::number( static_cast< int >( value.toDouble() ) );
4444 : : }
4445 : 0 : }
4446 : :
4447 : 0 : QString QgsProcessingParameterEnum::valueAsPythonComment( const QVariant &value, QgsProcessingContext & ) const
4448 : : {
4449 : 0 : if ( !value.isValid() )
4450 : 0 : return QString();
4451 : :
4452 : 0 : if ( value.canConvert<QgsProperty>() )
4453 : 0 : return QString();
4454 : :
4455 : 0 : if ( mUsesStaticStrings )
4456 : : {
4457 : 0 : return QString();
4458 : : }
4459 : : else
4460 : : {
4461 : 0 : if ( value.type() == QVariant::List )
4462 : : {
4463 : 0 : QStringList parts;
4464 : 0 : const QVariantList toList = value.toList();
4465 : 0 : parts.reserve( toList.size() );
4466 : 0 : for ( const QVariant &val : toList )
4467 : : {
4468 : 0 : parts << mOptions.value( static_cast< int >( val.toDouble() ) );
4469 : : }
4470 : 0 : return parts.join( ',' );
4471 : 0 : }
4472 : 0 : else if ( value.type() == QVariant::String )
4473 : : {
4474 : 0 : const QStringList parts = value.toString().split( ',' );
4475 : 0 : QStringList comments;
4476 : 0 : if ( parts.count() > 1 )
4477 : : {
4478 : 0 : for ( const QString &part : parts )
4479 : : {
4480 : 0 : bool ok = false;
4481 : 0 : int val = part.toInt( &ok );
4482 : 0 : if ( ok )
4483 : 0 : comments << mOptions.value( val );
4484 : : }
4485 : 0 : return comments.join( ',' );
4486 : : }
4487 : 0 : }
4488 : :
4489 : 0 : return mOptions.value( static_cast< int >( value.toDouble() ) );
4490 : : }
4491 : 0 : }
4492 : :
4493 : 0 : QString QgsProcessingParameterEnum::asScriptCode() const
4494 : : {
4495 : 0 : QString code = QStringLiteral( "##%1=" ).arg( mName );
4496 : 0 : if ( mFlags & FlagOptional )
4497 : 0 : code += QLatin1String( "optional " );
4498 : 0 : code += QLatin1String( "enum " );
4499 : :
4500 : 0 : if ( mAllowMultiple )
4501 : 0 : code += QLatin1String( "multiple " );
4502 : :
4503 : 0 : if ( mUsesStaticStrings )
4504 : 0 : code += QLatin1String( "static " );
4505 : :
4506 : 0 : code += mOptions.join( ';' ) + ' ';
4507 : :
4508 : 0 : code += mDefault.toString();
4509 : 0 : return code.trimmed();
4510 : 0 : }
4511 : :
4512 : 0 : QString QgsProcessingParameterEnum::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
4513 : : {
4514 : 0 : switch ( outputType )
4515 : : {
4516 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
4517 : : {
4518 : 0 : QString code = QStringLiteral( "QgsProcessingParameterEnum('%1', '%2'" ).arg( name(), description() );
4519 : 0 : if ( mFlags & FlagOptional )
4520 : 0 : code += QLatin1String( ", optional=True" );
4521 : :
4522 : 0 : QStringList options;
4523 : 0 : options.reserve( mOptions.size() );
4524 : 0 : for ( const QString &o : mOptions )
4525 : 0 : options << QgsProcessingUtils::stringToPythonLiteral( o );
4526 : 0 : code += QStringLiteral( ", options=[%1]" ).arg( options.join( ',' ) );
4527 : :
4528 : 0 : code += QStringLiteral( ", allowMultiple=%1" ).arg( mAllowMultiple ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
4529 : :
4530 : 0 : code += QStringLiteral( ", usesStaticStrings=%1" ).arg( mUsesStaticStrings ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
4531 : :
4532 : 0 : QgsProcessingContext c;
4533 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4534 : :
4535 : 0 : return code;
4536 : 0 : }
4537 : : }
4538 : 0 : return QString();
4539 : 0 : }
4540 : :
4541 : 0 : QStringList QgsProcessingParameterEnum::options() const
4542 : : {
4543 : 0 : return mOptions;
4544 : : }
4545 : :
4546 : 0 : void QgsProcessingParameterEnum::setOptions( const QStringList &options )
4547 : : {
4548 : 0 : mOptions = options;
4549 : 0 : }
4550 : :
4551 : 0 : bool QgsProcessingParameterEnum::allowMultiple() const
4552 : : {
4553 : 0 : return mAllowMultiple;
4554 : : }
4555 : :
4556 : 0 : void QgsProcessingParameterEnum::setAllowMultiple( bool allowMultiple )
4557 : : {
4558 : 0 : mAllowMultiple = allowMultiple;
4559 : 0 : }
4560 : :
4561 : 0 : bool QgsProcessingParameterEnum::usesStaticStrings() const
4562 : : {
4563 : 0 : return mUsesStaticStrings;
4564 : : }
4565 : :
4566 : 0 : void QgsProcessingParameterEnum::setUsesStaticStrings( bool usesStaticStrings )
4567 : : {
4568 : 0 : mUsesStaticStrings = usesStaticStrings;
4569 : 0 : }
4570 : :
4571 : 0 : QVariantMap QgsProcessingParameterEnum::toVariantMap() const
4572 : : {
4573 : 0 : QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
4574 : 0 : map.insert( QStringLiteral( "options" ), mOptions );
4575 : 0 : map.insert( QStringLiteral( "allow_multiple" ), mAllowMultiple );
4576 : 0 : map.insert( QStringLiteral( "uses_static_strings" ), mUsesStaticStrings );
4577 : 0 : return map;
4578 : 0 : }
4579 : :
4580 : 0 : bool QgsProcessingParameterEnum::fromVariantMap( const QVariantMap &map )
4581 : : {
4582 : 0 : QgsProcessingParameterDefinition::fromVariantMap( map );
4583 : 0 : mOptions = map.value( QStringLiteral( "options" ) ).toStringList();
4584 : 0 : mAllowMultiple = map.value( QStringLiteral( "allow_multiple" ) ).toBool();
4585 : 0 : mUsesStaticStrings = map.value( QStringLiteral( "uses_static_strings" ) ).toBool();
4586 : 0 : return true;
4587 : 0 : }
4588 : :
4589 : 0 : QgsProcessingParameterEnum *QgsProcessingParameterEnum::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4590 : : {
4591 : 0 : QString defaultVal;
4592 : 0 : QString def = definition;
4593 : :
4594 : 0 : bool multiple = false;
4595 : 0 : if ( def.startsWith( QLatin1String( "multiple" ), Qt::CaseInsensitive ) )
4596 : : {
4597 : 0 : multiple = true;
4598 : 0 : def = def.mid( 9 );
4599 : 0 : }
4600 : :
4601 : 0 : bool staticStrings = false;
4602 : 0 : if ( def.startsWith( QLatin1String( "static" ), Qt::CaseInsensitive ) )
4603 : : {
4604 : 0 : staticStrings = true;
4605 : 0 : def = def.mid( 7 );
4606 : 0 : }
4607 : :
4608 : 0 : QRegularExpression re( QStringLiteral( "(.*)\\s+(.*?)$" ) );
4609 : 0 : QRegularExpressionMatch m = re.match( def );
4610 : 0 : QString values = def;
4611 : 0 : if ( m.hasMatch() )
4612 : : {
4613 : 0 : values = m.captured( 1 ).trimmed();
4614 : 0 : defaultVal = m.captured( 2 );
4615 : 0 : }
4616 : :
4617 : 0 : return new QgsProcessingParameterEnum( name, description, values.split( ';' ), multiple, defaultVal.isEmpty() ? QVariant() : defaultVal, isOptional, staticStrings );
4618 : 0 : }
4619 : :
4620 : 0 : QgsProcessingParameterString::QgsProcessingParameterString( const QString &name, const QString &description, const QVariant &defaultValue, bool multiLine, bool optional )
4621 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4622 : 0 : , mMultiLine( multiLine )
4623 : 0 : {
4624 : :
4625 : 0 : }
4626 : :
4627 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterString::clone() const
4628 : : {
4629 : 0 : return new QgsProcessingParameterString( *this );
4630 : 0 : }
4631 : :
4632 : 0 : QString QgsProcessingParameterString::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
4633 : : {
4634 : 0 : if ( !value.isValid() || value.isNull() )
4635 : 0 : return QStringLiteral( "None" );
4636 : :
4637 : 0 : if ( value.canConvert<QgsProperty>() )
4638 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4639 : :
4640 : 0 : QString s = value.toString();
4641 : 0 : return QgsProcessingUtils::stringToPythonLiteral( s );
4642 : 0 : }
4643 : :
4644 : 0 : QString QgsProcessingParameterString::asScriptCode() const
4645 : : {
4646 : 0 : QString code = QStringLiteral( "##%1=" ).arg( mName );
4647 : 0 : if ( mFlags & FlagOptional )
4648 : 0 : code += QLatin1String( "optional " );
4649 : 0 : code += QLatin1String( "string " );
4650 : :
4651 : 0 : if ( mMultiLine )
4652 : 0 : code += QLatin1String( "long " );
4653 : :
4654 : 0 : code += mDefault.toString();
4655 : 0 : return code.trimmed();
4656 : 0 : }
4657 : :
4658 : 0 : QString QgsProcessingParameterString::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
4659 : : {
4660 : 0 : switch ( outputType )
4661 : : {
4662 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
4663 : : {
4664 : 0 : QString code = QStringLiteral( "QgsProcessingParameterString('%1', '%2'" ).arg( name(), description() );
4665 : 0 : if ( mFlags & FlagOptional )
4666 : 0 : code += QLatin1String( ", optional=True" );
4667 : 0 : code += QStringLiteral( ", multiLine=%1" ).arg( mMultiLine ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
4668 : :
4669 : 0 : QgsProcessingContext c;
4670 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4671 : 0 : return code;
4672 : 0 : }
4673 : : }
4674 : 0 : return QString();
4675 : 0 : }
4676 : :
4677 : 0 : bool QgsProcessingParameterString::multiLine() const
4678 : : {
4679 : 0 : return mMultiLine;
4680 : : }
4681 : :
4682 : 0 : void QgsProcessingParameterString::setMultiLine( bool multiLine )
4683 : : {
4684 : 0 : mMultiLine = multiLine;
4685 : 0 : }
4686 : :
4687 : 0 : QVariantMap QgsProcessingParameterString::toVariantMap() const
4688 : : {
4689 : 0 : QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
4690 : 0 : map.insert( QStringLiteral( "multiline" ), mMultiLine );
4691 : 0 : return map;
4692 : 0 : }
4693 : :
4694 : 0 : bool QgsProcessingParameterString::fromVariantMap( const QVariantMap &map )
4695 : : {
4696 : 0 : QgsProcessingParameterDefinition::fromVariantMap( map );
4697 : 0 : mMultiLine = map.value( QStringLiteral( "multiline" ) ).toBool();
4698 : 0 : return true;
4699 : 0 : }
4700 : :
4701 : 0 : QgsProcessingParameterString *QgsProcessingParameterString::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4702 : : {
4703 : 0 : QString def = definition;
4704 : 0 : bool multiLine = false;
4705 : 0 : if ( def.startsWith( QLatin1String( "long" ), Qt::CaseInsensitive ) )
4706 : : {
4707 : 0 : multiLine = true;
4708 : 0 : def = def.mid( 5 );
4709 : 0 : }
4710 : :
4711 : 0 : if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
4712 : 0 : def = def.mid( 1 );
4713 : 0 : if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
4714 : 0 : def.chop( 1 );
4715 : :
4716 : 0 : QVariant defaultValue = def;
4717 : 0 : if ( def == QLatin1String( "None" ) )
4718 : 0 : defaultValue = QVariant();
4719 : :
4720 : 0 : return new QgsProcessingParameterString( name, description, defaultValue, multiLine, isOptional );
4721 : 0 : }
4722 : :
4723 : : //
4724 : : // QgsProcessingParameterAuthConfig
4725 : : //
4726 : :
4727 : 0 : QgsProcessingParameterAuthConfig::QgsProcessingParameterAuthConfig( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
4728 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4729 : 0 : {
4730 : :
4731 : 0 : }
4732 : :
4733 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterAuthConfig::clone() const
4734 : : {
4735 : 0 : return new QgsProcessingParameterAuthConfig( *this );
4736 : 0 : }
4737 : :
4738 : 0 : QString QgsProcessingParameterAuthConfig::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
4739 : : {
4740 : 0 : if ( !value.isValid() )
4741 : 0 : return QStringLiteral( "None" );
4742 : :
4743 : 0 : QString s = value.toString();
4744 : 0 : return QgsProcessingUtils::stringToPythonLiteral( s );
4745 : 0 : }
4746 : :
4747 : 0 : QString QgsProcessingParameterAuthConfig::asScriptCode() const
4748 : : {
4749 : 0 : QString code = QStringLiteral( "##%1=" ).arg( mName );
4750 : 0 : if ( mFlags & FlagOptional )
4751 : 0 : code += QLatin1String( "optional " );
4752 : 0 : code += QLatin1String( "authcfg " );
4753 : :
4754 : 0 : code += mDefault.toString();
4755 : 0 : return code.trimmed();
4756 : 0 : }
4757 : :
4758 : 0 : QgsProcessingParameterAuthConfig *QgsProcessingParameterAuthConfig::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4759 : : {
4760 : 0 : QString def = definition;
4761 : :
4762 : 0 : if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
4763 : 0 : def = def.mid( 1 );
4764 : 0 : if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
4765 : 0 : def.chop( 1 );
4766 : :
4767 : 0 : QVariant defaultValue = def;
4768 : 0 : if ( def == QLatin1String( "None" ) )
4769 : 0 : defaultValue = QVariant();
4770 : :
4771 : 0 : return new QgsProcessingParameterAuthConfig( name, description, defaultValue, isOptional );
4772 : 0 : }
4773 : :
4774 : :
4775 : : //
4776 : : // QgsProcessingParameterExpression
4777 : : //
4778 : :
4779 : 0 : QgsProcessingParameterExpression::QgsProcessingParameterExpression( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayerParameterName, bool optional )
4780 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4781 : 0 : , mParentLayerParameterName( parentLayerParameterName )
4782 : 0 : {
4783 : :
4784 : 0 : }
4785 : :
4786 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterExpression::clone() const
4787 : : {
4788 : 0 : return new QgsProcessingParameterExpression( *this );
4789 : 0 : }
4790 : :
4791 : 0 : QString QgsProcessingParameterExpression::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
4792 : : {
4793 : 0 : if ( !value.isValid() )
4794 : 0 : return QStringLiteral( "None" );
4795 : :
4796 : 0 : if ( value.canConvert<QgsProperty>() )
4797 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4798 : :
4799 : 0 : QString s = value.toString();
4800 : 0 : return QgsProcessingUtils::stringToPythonLiteral( s );
4801 : 0 : }
4802 : :
4803 : 0 : QStringList QgsProcessingParameterExpression::dependsOnOtherParameters() const
4804 : : {
4805 : 0 : QStringList depends;
4806 : 0 : if ( !mParentLayerParameterName.isEmpty() )
4807 : 0 : depends << mParentLayerParameterName;
4808 : 0 : return depends;
4809 : 0 : }
4810 : :
4811 : 0 : QString QgsProcessingParameterExpression::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
4812 : : {
4813 : 0 : switch ( outputType )
4814 : : {
4815 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
4816 : : {
4817 : 0 : QString code = QStringLiteral( "QgsProcessingParameterExpression('%1', '%2'" ).arg( name(), description() );
4818 : 0 : if ( mFlags & FlagOptional )
4819 : 0 : code += QLatin1String( ", optional=True" );
4820 : :
4821 : 0 : code += QStringLiteral( ", parentLayerParameterName='%1'" ).arg( mParentLayerParameterName );
4822 : :
4823 : 0 : QgsProcessingContext c;
4824 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4825 : 0 : return code;
4826 : 0 : }
4827 : : }
4828 : 0 : return QString();
4829 : 0 : }
4830 : :
4831 : 0 : QString QgsProcessingParameterExpression::parentLayerParameterName() const
4832 : : {
4833 : 0 : return mParentLayerParameterName;
4834 : : }
4835 : :
4836 : 0 : void QgsProcessingParameterExpression::setParentLayerParameterName( const QString &parentLayerParameterName )
4837 : : {
4838 : 0 : mParentLayerParameterName = parentLayerParameterName;
4839 : 0 : }
4840 : :
4841 : 0 : QVariantMap QgsProcessingParameterExpression::toVariantMap() const
4842 : : {
4843 : 0 : QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
4844 : 0 : map.insert( QStringLiteral( "parent_layer" ), mParentLayerParameterName );
4845 : 0 : return map;
4846 : 0 : }
4847 : :
4848 : 0 : bool QgsProcessingParameterExpression::fromVariantMap( const QVariantMap &map )
4849 : : {
4850 : 0 : QgsProcessingParameterDefinition::fromVariantMap( map );
4851 : 0 : mParentLayerParameterName = map.value( QStringLiteral( "parent_layer" ) ).toString();
4852 : 0 : return true;
4853 : 0 : }
4854 : :
4855 : 0 : QgsProcessingParameterExpression *QgsProcessingParameterExpression::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4856 : : {
4857 : 0 : return new QgsProcessingParameterExpression( name, description, definition, QString(), isOptional );
4858 : 0 : }
4859 : :
4860 : 0 : QgsProcessingParameterVectorLayer::QgsProcessingParameterVectorLayer( const QString &name, const QString &description, const QList<int> &types, const QVariant &defaultValue, bool optional )
4861 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4862 : 0 : , QgsProcessingParameterLimitedDataTypes( types )
4863 : 0 : {
4864 : :
4865 : 0 : }
4866 : :
4867 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterVectorLayer::clone() const
4868 : : {
4869 : 0 : return new QgsProcessingParameterVectorLayer( *this );
4870 : 0 : }
4871 : :
4872 : 0 : bool QgsProcessingParameterVectorLayer::checkValueIsAcceptable( const QVariant &v, QgsProcessingContext *context ) const
4873 : : {
4874 : 0 : if ( !v.isValid() )
4875 : 0 : return mFlags & FlagOptional;
4876 : :
4877 : 0 : QVariant var = v;
4878 : :
4879 : 0 : if ( var.canConvert<QgsProperty>() )
4880 : : {
4881 : 0 : QgsProperty p = var.value< QgsProperty >();
4882 : 0 : if ( p.propertyType() == QgsProperty::StaticProperty )
4883 : : {
4884 : 0 : var = p.staticValue();
4885 : 0 : }
4886 : : else
4887 : : {
4888 : 0 : return true;
4889 : : }
4890 : 0 : }
4891 : :
4892 : 0 : if ( qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( var ) ) )
4893 : 0 : return true;
4894 : :
4895 : 0 : if ( var.type() != QVariant::String || var.toString().isEmpty() )
4896 : 0 : return mFlags & FlagOptional;
4897 : :
4898 : 0 : if ( !context )
4899 : : {
4900 : : // that's as far as we can get without a context
4901 : 0 : return true;
4902 : : }
4903 : :
4904 : : // try to load as layer
4905 : 0 : if ( QgsProcessingUtils::mapLayerFromString( var.toString(), *context, true, QgsProcessingUtils::LayerHint::Vector ) )
4906 : 0 : return true;
4907 : :
4908 : 0 : return false;
4909 : 0 : }
4910 : :
4911 : 0 : QString QgsProcessingParameterVectorLayer::valueAsPythonString( const QVariant &val, QgsProcessingContext &context ) const
4912 : : {
4913 : 0 : if ( !val.isValid() )
4914 : 0 : return QStringLiteral( "None" );
4915 : :
4916 : 0 : if ( val.canConvert<QgsProperty>() )
4917 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
4918 : :
4919 : 0 : QVariantMap p;
4920 : 0 : p.insert( name(), val );
4921 : 0 : QgsVectorLayer *layer = QgsProcessingParameters::parameterAsVectorLayer( this, p, context );
4922 : 0 : return layer ? QgsProcessingUtils::stringToPythonLiteral( QgsProcessingUtils::normalizeLayerSource( layer->source() ) )
4923 : 0 : : QgsProcessingUtils::stringToPythonLiteral( val.toString() );
4924 : 0 : }
4925 : :
4926 : 0 : QString QgsProcessingParameterVectorLayer::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
4927 : : {
4928 : 0 : switch ( outputType )
4929 : : {
4930 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
4931 : : {
4932 : 0 : QString code = QStringLiteral( "QgsProcessingParameterVectorLayer('%1', '%2'" ).arg( name(), description() );
4933 : 0 : if ( mFlags & FlagOptional )
4934 : 0 : code += QLatin1String( ", optional=True" );
4935 : :
4936 : 0 : if ( !mDataTypes.empty() )
4937 : : {
4938 : 0 : QStringList options;
4939 : 0 : for ( int t : mDataTypes )
4940 : 0 : options << QStringLiteral( "QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( static_cast< QgsProcessing::SourceType >( t ) ) );
4941 : 0 : code += QStringLiteral( ", types=[%1]" ).arg( options.join( ',' ) );
4942 : 0 : }
4943 : :
4944 : 0 : QgsProcessingContext c;
4945 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4946 : 0 : return code;
4947 : 0 : }
4948 : : }
4949 : 0 : return QString();
4950 : 0 : }
4951 : :
4952 : 0 : QString QgsProcessingParameterVectorLayer::createFileFilter() const
4953 : : {
4954 : 0 : return QgsProviderRegistry::instance()->fileVectorFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
4955 : 0 : }
4956 : :
4957 : 0 : QList<int> QgsProcessingParameterLimitedDataTypes::dataTypes() const
4958 : : {
4959 : 0 : return mDataTypes;
4960 : : }
4961 : :
4962 : 0 : void QgsProcessingParameterLimitedDataTypes::setDataTypes( const QList<int> &types )
4963 : : {
4964 : 0 : mDataTypes = types;
4965 : 0 : }
4966 : :
4967 : 0 : QVariantMap QgsProcessingParameterVectorLayer::toVariantMap() const
4968 : : {
4969 : 0 : QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
4970 : 0 : QVariantList types;
4971 : 0 : for ( int type : mDataTypes )
4972 : : {
4973 : 0 : types << type;
4974 : : }
4975 : 0 : map.insert( QStringLiteral( "data_types" ), types );
4976 : 0 : return map;
4977 : 0 : }
4978 : :
4979 : 0 : bool QgsProcessingParameterVectorLayer::fromVariantMap( const QVariantMap &map )
4980 : : {
4981 : 0 : QgsProcessingParameterDefinition::fromVariantMap( map );
4982 : 0 : mDataTypes.clear();
4983 : 0 : const QVariantList values = map.value( QStringLiteral( "data_types" ) ).toList();
4984 : 0 : for ( const QVariant &val : values )
4985 : : {
4986 : 0 : mDataTypes << val.toInt();
4987 : : }
4988 : : return true;
4989 : 0 : }
4990 : :
4991 : 0 : QgsProcessingParameterVectorLayer *QgsProcessingParameterVectorLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4992 : : {
4993 : 0 : return new QgsProcessingParameterVectorLayer( name, description, QList< int>(), definition.isEmpty() ? QVariant() : definition, isOptional );
4994 : 0 : }
4995 : :
4996 : 0 : QgsProcessingParameterMeshLayer::QgsProcessingParameterMeshLayer( const QString &name,
4997 : : const QString &description,
4998 : : const QVariant &defaultValue,
4999 : : bool optional )
5000 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5001 : 0 : {
5002 : :
5003 : 0 : }
5004 : :
5005 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterMeshLayer::clone() const
5006 : : {
5007 : 0 : return new QgsProcessingParameterMeshLayer( *this );
5008 : 0 : }
5009 : :
5010 : 0 : bool QgsProcessingParameterMeshLayer::checkValueIsAcceptable( const QVariant &v, QgsProcessingContext *context ) const
5011 : : {
5012 : 0 : if ( !v.isValid() )
5013 : 0 : return mFlags & FlagOptional;
5014 : :
5015 : 0 : QVariant var = v;
5016 : :
5017 : 0 : if ( var.canConvert<QgsProperty>() )
5018 : : {
5019 : 0 : QgsProperty p = var.value< QgsProperty >();
5020 : 0 : if ( p.propertyType() == QgsProperty::StaticProperty )
5021 : : {
5022 : 0 : var = p.staticValue();
5023 : 0 : }
5024 : : else
5025 : : {
5026 : 0 : return true;
5027 : : }
5028 : 0 : }
5029 : :
5030 : 0 : if ( qobject_cast< QgsMeshLayer * >( qvariant_cast<QObject *>( var ) ) )
5031 : 0 : return true;
5032 : :
5033 : 0 : if ( var.type() != QVariant::String || var.toString().isEmpty() )
5034 : 0 : return mFlags & FlagOptional;
5035 : :
5036 : 0 : if ( !context )
5037 : : {
5038 : : // that's as far as we can get without a context
5039 : 0 : return true;
5040 : : }
5041 : :
5042 : : // try to load as layer
5043 : 0 : if ( QgsProcessingUtils::mapLayerFromString( var.toString(), *context, true, QgsProcessingUtils::LayerHint::Mesh ) )
5044 : 0 : return true;
5045 : :
5046 : 0 : return false;
5047 : 0 : }
5048 : :
5049 : 0 : QString QgsProcessingParameterMeshLayer::valueAsPythonString( const QVariant &val, QgsProcessingContext &context ) const
5050 : : {
5051 : 0 : if ( !val.isValid() )
5052 : 0 : return QStringLiteral( "None" );
5053 : :
5054 : 0 : if ( val.canConvert<QgsProperty>() )
5055 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
5056 : :
5057 : 0 : QVariantMap p;
5058 : 0 : p.insert( name(), val );
5059 : 0 : QgsMeshLayer *layer = QgsProcessingParameters::parameterAsMeshLayer( this, p, context );
5060 : 0 : return layer ? QgsProcessingUtils::stringToPythonLiteral( QgsProcessingUtils::normalizeLayerSource( layer->source() ) )
5061 : 0 : : QgsProcessingUtils::stringToPythonLiteral( val.toString() );
5062 : 0 : }
5063 : :
5064 : 0 : QString QgsProcessingParameterMeshLayer::createFileFilter() const
5065 : : {
5066 : 0 : return QgsProviderRegistry::instance()->fileMeshFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
5067 : 0 : }
5068 : :
5069 : 0 : QgsProcessingParameterMeshLayer *QgsProcessingParameterMeshLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5070 : : {
5071 : 0 : return new QgsProcessingParameterMeshLayer( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
5072 : 0 : }
5073 : :
5074 : 0 : QgsProcessingParameterField::QgsProcessingParameterField( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayerParameterName, DataType type, bool allowMultiple, bool optional, bool defaultToAllFields )
5075 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5076 : 0 : , mParentLayerParameterName( parentLayerParameterName )
5077 : 0 : , mDataType( type )
5078 : 0 : , mAllowMultiple( allowMultiple )
5079 : 0 : , mDefaultToAllFields( defaultToAllFields )
5080 : 0 : {
5081 : :
5082 : 0 : }
5083 : :
5084 : :
5085 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterField::clone() const
5086 : : {
5087 : 0 : return new QgsProcessingParameterField( *this );
5088 : 0 : }
5089 : :
5090 : 0 : bool QgsProcessingParameterField::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
5091 : : {
5092 : 0 : if ( !input.isValid() )
5093 : 0 : return mFlags & FlagOptional;
5094 : :
5095 : 0 : if ( input.canConvert<QgsProperty>() )
5096 : : {
5097 : 0 : return true;
5098 : : }
5099 : :
5100 : 0 : if ( input.type() == QVariant::List || input.type() == QVariant::StringList )
5101 : : {
5102 : 0 : if ( !mAllowMultiple )
5103 : 0 : return false;
5104 : :
5105 : 0 : if ( input.toList().isEmpty() && !( mFlags & FlagOptional ) )
5106 : 0 : return false;
5107 : 0 : }
5108 : 0 : else if ( input.type() == QVariant::String )
5109 : : {
5110 : 0 : if ( input.toString().isEmpty() )
5111 : 0 : return mFlags & FlagOptional;
5112 : :
5113 : 0 : QStringList parts = input.toString().split( ';' );
5114 : 0 : if ( parts.count() > 1 && !mAllowMultiple )
5115 : 0 : return false;
5116 : 0 : }
5117 : : else
5118 : : {
5119 : 0 : if ( input.toString().isEmpty() )
5120 : 0 : return mFlags & FlagOptional;
5121 : : }
5122 : 0 : return true;
5123 : 0 : }
5124 : :
5125 : 0 : QString QgsProcessingParameterField::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
5126 : : {
5127 : 0 : if ( !value.isValid() )
5128 : 0 : return QStringLiteral( "None" );
5129 : :
5130 : 0 : if ( value.canConvert<QgsProperty>() )
5131 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
5132 : :
5133 : 0 : if ( value.type() == QVariant::List )
5134 : : {
5135 : 0 : QStringList parts;
5136 : 0 : const auto constToList = value.toList();
5137 : 0 : for ( const QVariant &val : constToList )
5138 : : {
5139 : 0 : parts << QgsProcessingUtils::stringToPythonLiteral( val.toString() );
5140 : : }
5141 : 0 : return parts.join( ',' ).prepend( '[' ).append( ']' );
5142 : 0 : }
5143 : 0 : else if ( value.type() == QVariant::StringList )
5144 : : {
5145 : 0 : QStringList parts;
5146 : 0 : const auto constToStringList = value.toStringList();
5147 : 0 : for ( QString s : constToStringList )
5148 : : {
5149 : 0 : parts << QgsProcessingUtils::stringToPythonLiteral( s );
5150 : 0 : }
5151 : 0 : return parts.join( ',' ).prepend( '[' ).append( ']' );
5152 : 0 : }
5153 : :
5154 : 0 : return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
5155 : 0 : }
5156 : :
5157 : 0 : QString QgsProcessingParameterField::asScriptCode() const
5158 : : {
5159 : 0 : QString code = QStringLiteral( "##%1=" ).arg( mName );
5160 : 0 : if ( mFlags & FlagOptional )
5161 : 0 : code += QLatin1String( "optional " );
5162 : 0 : code += QLatin1String( "field " );
5163 : :
5164 : 0 : switch ( mDataType )
5165 : : {
5166 : : case Numeric:
5167 : 0 : code += QLatin1String( "numeric " );
5168 : 0 : break;
5169 : :
5170 : : case String:
5171 : 0 : code += QLatin1String( "string " );
5172 : 0 : break;
5173 : :
5174 : : case DateTime:
5175 : 0 : code += QLatin1String( "datetime " );
5176 : 0 : break;
5177 : :
5178 : : case Any:
5179 : 0 : break;
5180 : : }
5181 : :
5182 : 0 : if ( mAllowMultiple )
5183 : 0 : code += QLatin1String( "multiple " );
5184 : :
5185 : 0 : if ( mDefaultToAllFields )
5186 : 0 : code += QLatin1String( "default_to_all_fields " );
5187 : :
5188 : 0 : code += mParentLayerParameterName + ' ';
5189 : :
5190 : 0 : code += mDefault.toString();
5191 : 0 : return code.trimmed();
5192 : 0 : }
5193 : :
5194 : 0 : QString QgsProcessingParameterField::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
5195 : : {
5196 : 0 : switch ( outputType )
5197 : : {
5198 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
5199 : : {
5200 : 0 : QString code = QStringLiteral( "QgsProcessingParameterField('%1', '%2'" ).arg( name(), description() );
5201 : 0 : if ( mFlags & FlagOptional )
5202 : 0 : code += QLatin1String( ", optional=True" );
5203 : :
5204 : 0 : QString dataType;
5205 : 0 : switch ( mDataType )
5206 : : {
5207 : : case Any:
5208 : 0 : dataType = QStringLiteral( "QgsProcessingParameterField.Any" );
5209 : 0 : break;
5210 : :
5211 : : case Numeric:
5212 : 0 : dataType = QStringLiteral( "QgsProcessingParameterField.Numeric" );
5213 : 0 : break;
5214 : :
5215 : : case String:
5216 : 0 : dataType = QStringLiteral( "QgsProcessingParameterField.String" );
5217 : 0 : break;
5218 : :
5219 : : case DateTime:
5220 : 0 : dataType = QStringLiteral( "QgsProcessingParameterField.DateTime" );
5221 : 0 : break;
5222 : : }
5223 : 0 : code += QStringLiteral( ", type=%1" ).arg( dataType );
5224 : :
5225 : 0 : code += QStringLiteral( ", parentLayerParameterName='%1'" ).arg( mParentLayerParameterName );
5226 : 0 : code += QStringLiteral( ", allowMultiple=%1" ).arg( mAllowMultiple ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
5227 : 0 : QgsProcessingContext c;
5228 : 0 : code += QStringLiteral( ", defaultValue=%1" ).arg( valueAsPythonString( mDefault, c ) );
5229 : :
5230 : 0 : if ( mDefaultToAllFields )
5231 : 0 : code += QLatin1String( ", defaultToAllFields=True" );
5232 : :
5233 : 0 : code += ')';
5234 : :
5235 : 0 : return code;
5236 : 0 : }
5237 : : }
5238 : 0 : return QString();
5239 : 0 : }
5240 : :
5241 : 0 : QStringList QgsProcessingParameterField::dependsOnOtherParameters() const
5242 : : {
5243 : 0 : QStringList depends;
5244 : 0 : if ( !mParentLayerParameterName.isEmpty() )
5245 : 0 : depends << mParentLayerParameterName;
5246 : 0 : return depends;
5247 : 0 : }
5248 : :
5249 : 0 : QString QgsProcessingParameterField::parentLayerParameterName() const
5250 : : {
5251 : 0 : return mParentLayerParameterName;
5252 : : }
5253 : :
5254 : 0 : void QgsProcessingParameterField::setParentLayerParameterName( const QString &parentLayerParameterName )
5255 : : {
5256 : 0 : mParentLayerParameterName = parentLayerParameterName;
5257 : 0 : }
5258 : :
5259 : 0 : QgsProcessingParameterField::DataType QgsProcessingParameterField::dataType() const
5260 : : {
5261 : 0 : return mDataType;
5262 : : }
5263 : :
5264 : 0 : void QgsProcessingParameterField::setDataType( DataType dataType )
5265 : : {
5266 : 0 : mDataType = dataType;
5267 : 0 : }
5268 : :
5269 : 0 : bool QgsProcessingParameterField::allowMultiple() const
5270 : : {
5271 : 0 : return mAllowMultiple;
5272 : : }
5273 : :
5274 : 0 : void QgsProcessingParameterField::setAllowMultiple( bool allowMultiple )
5275 : : {
5276 : 0 : mAllowMultiple = allowMultiple;
5277 : 0 : }
5278 : :
5279 : 0 : bool QgsProcessingParameterField::defaultToAllFields() const
5280 : : {
5281 : 0 : return mDefaultToAllFields;
5282 : : }
5283 : :
5284 : 0 : void QgsProcessingParameterField::setDefaultToAllFields( bool enabled )
5285 : : {
5286 : 0 : mDefaultToAllFields = enabled;
5287 : 0 : }
5288 : :
5289 : 0 : QVariantMap QgsProcessingParameterField::toVariantMap() const
5290 : : {
5291 : 0 : QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
5292 : 0 : map.insert( QStringLiteral( "parent_layer" ), mParentLayerParameterName );
5293 : 0 : map.insert( QStringLiteral( "data_type" ), mDataType );
5294 : 0 : map.insert( QStringLiteral( "allow_multiple" ), mAllowMultiple );
5295 : 0 : map.insert( QStringLiteral( "default_to_all_fields" ), mDefaultToAllFields );
5296 : 0 : return map;
5297 : 0 : }
5298 : :
5299 : 0 : bool QgsProcessingParameterField::fromVariantMap( const QVariantMap &map )
5300 : : {
5301 : 0 : QgsProcessingParameterDefinition::fromVariantMap( map );
5302 : 0 : mParentLayerParameterName = map.value( QStringLiteral( "parent_layer" ) ).toString();
5303 : 0 : mDataType = static_cast< DataType >( map.value( QStringLiteral( "data_type" ) ).toInt() );
5304 : 0 : mAllowMultiple = map.value( QStringLiteral( "allow_multiple" ) ).toBool();
5305 : 0 : mDefaultToAllFields = map.value( QStringLiteral( "default_to_all_fields" ) ).toBool();
5306 : 0 : return true;
5307 : 0 : }
5308 : :
5309 : 0 : QgsProcessingParameterField *QgsProcessingParameterField::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5310 : : {
5311 : 0 : QString parent;
5312 : 0 : DataType type = Any;
5313 : 0 : bool allowMultiple = false;
5314 : 0 : bool defaultToAllFields = false;
5315 : 0 : QString def = definition;
5316 : :
5317 : 0 : if ( def.startsWith( QLatin1String( "numeric " ), Qt::CaseInsensitive ) )
5318 : : {
5319 : 0 : type = Numeric;
5320 : 0 : def = def.mid( 8 );
5321 : 0 : }
5322 : 0 : else if ( def.startsWith( QLatin1String( "string " ), Qt::CaseInsensitive ) )
5323 : : {
5324 : 0 : type = String;
5325 : 0 : def = def.mid( 7 );
5326 : 0 : }
5327 : 0 : else if ( def.startsWith( QLatin1String( "datetime " ), Qt::CaseInsensitive ) )
5328 : : {
5329 : 0 : type = DateTime;
5330 : 0 : def = def.mid( 9 );
5331 : 0 : }
5332 : :
5333 : 0 : if ( def.startsWith( QLatin1String( "multiple" ), Qt::CaseInsensitive ) )
5334 : : {
5335 : 0 : allowMultiple = true;
5336 : 0 : def = def.mid( 8 ).trimmed();
5337 : 0 : }
5338 : :
5339 : 0 : if ( def.startsWith( QLatin1String( "default_to_all_fields" ), Qt::CaseInsensitive ) )
5340 : : {
5341 : 0 : defaultToAllFields = true;
5342 : 0 : def = def.mid( 21 ).trimmed();
5343 : 0 : }
5344 : :
5345 : 0 : QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*)$" ) );
5346 : 0 : QRegularExpressionMatch m = re.match( def );
5347 : 0 : if ( m.hasMatch() )
5348 : : {
5349 : 0 : parent = m.captured( 1 ).trimmed();
5350 : 0 : def = m.captured( 2 );
5351 : 0 : }
5352 : : else
5353 : : {
5354 : 0 : parent = def;
5355 : 0 : def.clear();
5356 : : }
5357 : :
5358 : 0 : return new QgsProcessingParameterField( name, description, def.isEmpty() ? QVariant() : def, parent, type, allowMultiple, isOptional, defaultToAllFields );
5359 : 0 : }
5360 : :
5361 : 0 : QgsProcessingParameterFeatureSource::QgsProcessingParameterFeatureSource( const QString &name, const QString &description, const QList<int> &types, const QVariant &defaultValue, bool optional )
5362 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5363 : 0 : , QgsProcessingParameterLimitedDataTypes( types )
5364 : 0 : {
5365 : :
5366 : 0 : }
5367 : :
5368 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterFeatureSource::clone() const
5369 : : {
5370 : 0 : return new QgsProcessingParameterFeatureSource( *this );
5371 : 0 : }
5372 : :
5373 : 0 : bool QgsProcessingParameterFeatureSource::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context ) const
5374 : : {
5375 : 0 : QVariant var = input;
5376 : 0 : if ( !var.isValid() )
5377 : 0 : return mFlags & FlagOptional;
5378 : :
5379 : 0 : if ( var.canConvert<QgsProcessingFeatureSourceDefinition>() )
5380 : : {
5381 : 0 : QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( var );
5382 : 0 : var = fromVar.source;
5383 : 0 : }
5384 : 0 : else if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
5385 : : {
5386 : : // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
5387 : 0 : QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
5388 : 0 : var = fromVar.sink;
5389 : 0 : }
5390 : :
5391 : 0 : if ( var.canConvert<QgsProperty>() )
5392 : : {
5393 : 0 : QgsProperty p = var.value< QgsProperty >();
5394 : 0 : if ( p.propertyType() == QgsProperty::StaticProperty )
5395 : : {
5396 : 0 : var = p.staticValue();
5397 : 0 : }
5398 : : else
5399 : : {
5400 : 0 : return true;
5401 : : }
5402 : 0 : }
5403 : 0 : if ( qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( input ) ) )
5404 : : {
5405 : 0 : return true;
5406 : : }
5407 : :
5408 : 0 : if ( var.type() != QVariant::String || var.toString().isEmpty() )
5409 : 0 : return mFlags & FlagOptional;
5410 : :
5411 : 0 : if ( !context )
5412 : : {
5413 : : // that's as far as we can get without a context
5414 : 0 : return true;
5415 : : }
5416 : :
5417 : : // try to load as layer
5418 : 0 : if ( QgsProcessingUtils::mapLayerFromString( var.toString(), *context, true, QgsProcessingUtils::LayerHint::Vector ) )
5419 : 0 : return true;
5420 : :
5421 : 0 : return false;
5422 : 0 : }
5423 : :
5424 : 0 : QString QgsProcessingParameterFeatureSource::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
5425 : : {
5426 : 0 : if ( !value.isValid() )
5427 : 0 : return QStringLiteral( "None" );
5428 : :
5429 : 0 : if ( value.canConvert<QgsProperty>() )
5430 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
5431 : :
5432 : 0 : if ( value.canConvert<QgsProcessingFeatureSourceDefinition>() )
5433 : : {
5434 : 0 : QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( value );
5435 : 0 : QString geometryCheckString;
5436 : 0 : switch ( fromVar.geometryCheck )
5437 : : {
5438 : : case QgsFeatureRequest::GeometryNoCheck:
5439 : 0 : geometryCheckString = QStringLiteral( "QgsFeatureRequest.GeometryNoCheck" );
5440 : 0 : break;
5441 : :
5442 : : case QgsFeatureRequest::GeometrySkipInvalid:
5443 : 0 : geometryCheckString = QStringLiteral( "QgsFeatureRequest.GeometrySkipInvalid" );
5444 : 0 : break;
5445 : :
5446 : : case QgsFeatureRequest::GeometryAbortOnInvalid:
5447 : 0 : geometryCheckString = QStringLiteral( "QgsFeatureRequest.GeometryAbortOnInvalid" );
5448 : 0 : break;
5449 : : }
5450 : :
5451 : 0 : QStringList flags;
5452 : 0 : QString flagString;
5453 : 0 : if ( fromVar.flags & QgsProcessingFeatureSourceDefinition::Flag::FlagOverrideDefaultGeometryCheck )
5454 : 0 : flags << QStringLiteral( "QgsProcessingFeatureSourceDefinition.FlagOverrideDefaultGeometryCheck" );
5455 : 0 : if ( fromVar.flags & QgsProcessingFeatureSourceDefinition::Flag::FlagCreateIndividualOutputPerInputFeature )
5456 : 0 : flags << QStringLiteral( "QgsProcessingFeatureSourceDefinition.FlagCreateIndividualOutputPerInputFeature" );
5457 : 0 : if ( !flags.empty() )
5458 : 0 : flagString = flags.join( QLatin1String( " | " ) );
5459 : :
5460 : 0 : if ( fromVar.source.propertyType() == QgsProperty::StaticProperty )
5461 : : {
5462 : 0 : QString layerString = fromVar.source.staticValue().toString();
5463 : : // prefer to use layer source instead of id if possible (since it's persistent)
5464 : 0 : if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( QgsProcessingUtils::mapLayerFromString( layerString, context, true, QgsProcessingUtils::LayerHint::Vector ) ) )
5465 : 0 : layerString = layer->source();
5466 : :
5467 : 0 : if ( fromVar.selectedFeaturesOnly || fromVar.featureLimit != -1 || fromVar.flags )
5468 : : {
5469 : 0 : return QStringLiteral( "QgsProcessingFeatureSourceDefinition('%1', selectedFeaturesOnly=%2, featureLimit=%3%4, geometryCheck=%5)" ).arg( layerString,
5470 : 0 : fromVar.selectedFeaturesOnly ? QStringLiteral( "True" ) : QStringLiteral( "False" ),
5471 : 0 : QString::number( fromVar.featureLimit ),
5472 : 0 : flagString.isEmpty() ? QString() : ( QStringLiteral( ", flags=%1" ).arg( flagString ) ),
5473 : : geometryCheckString );
5474 : : }
5475 : : else
5476 : : {
5477 : 0 : return QgsProcessingUtils::stringToPythonLiteral( layerString );
5478 : : }
5479 : 0 : }
5480 : : else
5481 : : {
5482 : 0 : if ( fromVar.selectedFeaturesOnly || fromVar.featureLimit != -1 || fromVar.flags )
5483 : : {
5484 : 0 : return QStringLiteral( "QgsProcessingFeatureSourceDefinition(QgsProperty.fromExpression('%1'), selectedFeaturesOnly=%2, featureLimit=%3%4, geometryCheck=%5)" )
5485 : 0 : .arg( fromVar.source.asExpression(),
5486 : 0 : fromVar.selectedFeaturesOnly ? QStringLiteral( "True" ) : QStringLiteral( "False" ),
5487 : 0 : QString::number( fromVar.featureLimit ),
5488 : 0 : flagString.isEmpty() ? QString() : ( QStringLiteral( ", flags=%1" ).arg( flagString ) ),
5489 : : geometryCheckString );
5490 : : }
5491 : : else
5492 : : {
5493 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.source.asExpression() );
5494 : : }
5495 : : }
5496 : 0 : }
5497 : 0 : else if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( value ) ) )
5498 : : {
5499 : 0 : return QgsProcessingUtils::stringToPythonLiteral( layer->source() );
5500 : : }
5501 : :
5502 : 0 : QString layerString = value.toString();
5503 : :
5504 : : // prefer to use layer source if possible (since it's persistent)
5505 : 0 : if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( QgsProcessingUtils::mapLayerFromString( layerString, context, true, QgsProcessingUtils::LayerHint::Vector ) ) )
5506 : 0 : layerString = layer->providerType() != QLatin1String( "ogr" ) && layer->providerType() != QLatin1String( "gdal" ) && layer->providerType() != QLatin1String( "mdal" ) ? QgsProcessingUtils::encodeProviderKeyAndUri( layer->providerType(), layer->source() ) : layer->source();
5507 : :
5508 : 0 : return QgsProcessingUtils::stringToPythonLiteral( layerString );
5509 : 0 : }
5510 : :
5511 : 0 : QString QgsProcessingParameterFeatureSource::asScriptCode() const
5512 : : {
5513 : 0 : QString code = QStringLiteral( "##%1=" ).arg( mName );
5514 : 0 : if ( mFlags & FlagOptional )
5515 : 0 : code += QLatin1String( "optional " );
5516 : 0 : code += QLatin1String( "source " );
5517 : :
5518 : 0 : for ( int type : mDataTypes )
5519 : : {
5520 : 0 : switch ( type )
5521 : : {
5522 : : case QgsProcessing::TypeVectorPoint:
5523 : 0 : code += QLatin1String( "point " );
5524 : 0 : break;
5525 : :
5526 : : case QgsProcessing::TypeVectorLine:
5527 : 0 : code += QLatin1String( "line " );
5528 : 0 : break;
5529 : :
5530 : : case QgsProcessing::TypeVectorPolygon:
5531 : 0 : code += QLatin1String( "polygon " );
5532 : 0 : break;
5533 : :
5534 : : }
5535 : : }
5536 : :
5537 : 0 : code += mDefault.toString();
5538 : 0 : return code.trimmed();
5539 : 0 : }
5540 : :
5541 : 0 : QString QgsProcessingParameterFeatureSource::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
5542 : : {
5543 : 0 : switch ( outputType )
5544 : : {
5545 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
5546 : : {
5547 : 0 : QString code = QStringLiteral( "QgsProcessingParameterFeatureSource('%1', '%2'" ).arg( name(), description() );
5548 : 0 : if ( mFlags & FlagOptional )
5549 : 0 : code += QLatin1String( ", optional=True" );
5550 : :
5551 : 0 : if ( !mDataTypes.empty() )
5552 : : {
5553 : 0 : QStringList options;
5554 : 0 : options.reserve( mDataTypes.size() );
5555 : 0 : for ( int t : mDataTypes )
5556 : 0 : options << QStringLiteral( "QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( static_cast< QgsProcessing::SourceType >( t ) ) );
5557 : 0 : code += QStringLiteral( ", types=[%1]" ).arg( options.join( ',' ) );
5558 : 0 : }
5559 : :
5560 : 0 : QgsProcessingContext c;
5561 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
5562 : 0 : return code;
5563 : 0 : }
5564 : : }
5565 : 0 : return QString();
5566 : 0 : }
5567 : :
5568 : 0 : QString QgsProcessingParameterFeatureSource::createFileFilter() const
5569 : : {
5570 : 0 : return QgsProviderRegistry::instance()->fileVectorFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
5571 : 0 : }
5572 : :
5573 : 0 : QgsProcessingParameterLimitedDataTypes::QgsProcessingParameterLimitedDataTypes( const QList<int> &types )
5574 : 0 : : mDataTypes( types )
5575 : : {
5576 : :
5577 : 0 : }
5578 : :
5579 : 0 : QVariantMap QgsProcessingParameterFeatureSource::toVariantMap() const
5580 : : {
5581 : 0 : QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
5582 : 0 : QVariantList types;
5583 : 0 : for ( int type : mDataTypes )
5584 : : {
5585 : 0 : types << type;
5586 : : }
5587 : 0 : map.insert( QStringLiteral( "data_types" ), types );
5588 : 0 : return map;
5589 : 0 : }
5590 : :
5591 : 0 : bool QgsProcessingParameterFeatureSource::fromVariantMap( const QVariantMap &map )
5592 : : {
5593 : 0 : QgsProcessingParameterDefinition::fromVariantMap( map );
5594 : 0 : mDataTypes.clear();
5595 : 0 : const QVariantList values = map.value( QStringLiteral( "data_types" ) ).toList();
5596 : 0 : for ( const QVariant &val : values )
5597 : : {
5598 : 0 : mDataTypes << val.toInt();
5599 : : }
5600 : : return true;
5601 : 0 : }
5602 : :
5603 : 0 : QgsProcessingParameterFeatureSource *QgsProcessingParameterFeatureSource::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5604 : : {
5605 : 0 : QList< int > types;
5606 : 0 : QString def = definition;
5607 : 0 : while ( true )
5608 : : {
5609 : 0 : if ( def.startsWith( QLatin1String( "point" ), Qt::CaseInsensitive ) )
5610 : : {
5611 : 0 : types << QgsProcessing::TypeVectorPoint;
5612 : 0 : def = def.mid( 6 );
5613 : 0 : continue;
5614 : : }
5615 : 0 : else if ( def.startsWith( QLatin1String( "line" ), Qt::CaseInsensitive ) )
5616 : : {
5617 : 0 : types << QgsProcessing::TypeVectorLine;
5618 : 0 : def = def.mid( 5 );
5619 : 0 : continue;
5620 : : }
5621 : 0 : else if ( def.startsWith( QLatin1String( "polygon" ), Qt::CaseInsensitive ) )
5622 : : {
5623 : 0 : types << QgsProcessing::TypeVectorPolygon;
5624 : 0 : def = def.mid( 8 );
5625 : 0 : continue;
5626 : : }
5627 : 0 : break;
5628 : : }
5629 : :
5630 : 0 : return new QgsProcessingParameterFeatureSource( name, description, types, def, isOptional );
5631 : 0 : }
5632 : :
5633 : 0 : QgsProcessingParameterFeatureSink::QgsProcessingParameterFeatureSink( const QString &name, const QString &description, QgsProcessing::SourceType type, const QVariant &defaultValue, bool optional, bool createByDefault, bool supportsAppend )
5634 : 0 : : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
5635 : 0 : , mDataType( type )
5636 : 0 : , mSupportsAppend( supportsAppend )
5637 : 0 : {
5638 : 0 : }
5639 : :
5640 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterFeatureSink::clone() const
5641 : : {
5642 : 0 : return new QgsProcessingParameterFeatureSink( *this );
5643 : 0 : }
5644 : :
5645 : 0 : bool QgsProcessingParameterFeatureSink::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
5646 : : {
5647 : 0 : QVariant var = input;
5648 : 0 : if ( !var.isValid() )
5649 : 0 : return mFlags & FlagOptional;
5650 : :
5651 : 0 : if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
5652 : : {
5653 : 0 : QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
5654 : 0 : var = fromVar.sink;
5655 : 0 : }
5656 : :
5657 : 0 : if ( var.canConvert<QgsProperty>() )
5658 : : {
5659 : 0 : QgsProperty p = var.value< QgsProperty >();
5660 : 0 : if ( p.propertyType() == QgsProperty::StaticProperty )
5661 : : {
5662 : 0 : var = p.staticValue();
5663 : 0 : }
5664 : : else
5665 : : {
5666 : 0 : return true;
5667 : : }
5668 : 0 : }
5669 : :
5670 : 0 : if ( var.type() != QVariant::String )
5671 : 0 : return false;
5672 : :
5673 : 0 : if ( var.toString().isEmpty() )
5674 : 0 : return mFlags & FlagOptional;
5675 : :
5676 : 0 : return true;
5677 : 0 : }
5678 : :
5679 : 0 : QString QgsProcessingParameterFeatureSink::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
5680 : : {
5681 : 0 : if ( !value.isValid() )
5682 : 0 : return QStringLiteral( "None" );
5683 : :
5684 : 0 : if ( value.canConvert<QgsProperty>() )
5685 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
5686 : :
5687 : 0 : if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
5688 : : {
5689 : 0 : QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
5690 : 0 : if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
5691 : : {
5692 : 0 : return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
5693 : : }
5694 : : else
5695 : : {
5696 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
5697 : : }
5698 : 0 : }
5699 : :
5700 : 0 : return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
5701 : 0 : }
5702 : :
5703 : 0 : QString QgsProcessingParameterFeatureSink::asScriptCode() const
5704 : : {
5705 : 0 : QString code = QStringLiteral( "##%1=" ).arg( mName );
5706 : 0 : if ( mFlags & FlagOptional )
5707 : 0 : code += QLatin1String( "optional " );
5708 : 0 : code += QLatin1String( "sink " );
5709 : :
5710 : 0 : switch ( mDataType )
5711 : : {
5712 : : case QgsProcessing::TypeVectorPoint:
5713 : 0 : code += QLatin1String( "point " );
5714 : 0 : break;
5715 : :
5716 : : case QgsProcessing::TypeVectorLine:
5717 : 0 : code += QLatin1String( "line " );
5718 : 0 : break;
5719 : :
5720 : : case QgsProcessing::TypeVectorPolygon:
5721 : 0 : code += QLatin1String( "polygon " );
5722 : 0 : break;
5723 : :
5724 : : case QgsProcessing::TypeVector:
5725 : 0 : code += QLatin1String( "table " );
5726 : 0 : break;
5727 : :
5728 : : default:
5729 : 0 : break;
5730 : : }
5731 : :
5732 : 0 : code += mDefault.toString();
5733 : 0 : return code.trimmed();
5734 : 0 : }
5735 : :
5736 : 0 : QgsProcessingOutputDefinition *QgsProcessingParameterFeatureSink::toOutputDefinition() const
5737 : : {
5738 : 0 : return new QgsProcessingOutputVectorLayer( name(), description(), mDataType );
5739 : 0 : }
5740 : :
5741 : 0 : QString QgsProcessingParameterFeatureSink::defaultFileExtension() const
5742 : : {
5743 : 0 : if ( auto *lOriginalProvider = originalProvider() )
5744 : : {
5745 : 0 : return lOriginalProvider->defaultVectorFileExtension( hasGeometry() );
5746 : : }
5747 : 0 : else if ( QgsProcessingProvider *p = provider() )
5748 : : {
5749 : 0 : return p->defaultVectorFileExtension( hasGeometry() );
5750 : : }
5751 : : else
5752 : : {
5753 : 0 : if ( hasGeometry() )
5754 : : {
5755 : 0 : return QgsProcessingUtils::defaultVectorExtension();
5756 : : }
5757 : : else
5758 : : {
5759 : 0 : return QStringLiteral( "dbf" );
5760 : : }
5761 : : }
5762 : 0 : }
5763 : :
5764 : 0 : QString QgsProcessingParameterFeatureSink::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
5765 : : {
5766 : 0 : switch ( outputType )
5767 : : {
5768 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
5769 : : {
5770 : 0 : QString code = QStringLiteral( "QgsProcessingParameterFeatureSink('%1', '%2'" ).arg( name(), description() );
5771 : 0 : if ( mFlags & FlagOptional )
5772 : 0 : code += QLatin1String( ", optional=True" );
5773 : :
5774 : 0 : code += QStringLiteral( ", type=QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( mDataType ) );
5775 : :
5776 : 0 : code += QStringLiteral( ", createByDefault=%1" ).arg( createByDefault() ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
5777 : 0 : if ( mSupportsAppend )
5778 : 0 : code += QLatin1String( ", supportsAppend=True" );
5779 : :
5780 : 0 : QgsProcessingContext c;
5781 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
5782 : 0 : return code;
5783 : 0 : }
5784 : : }
5785 : 0 : return QString();
5786 : 0 : }
5787 : :
5788 : 0 : QString QgsProcessingParameterFeatureSink::createFileFilter() const
5789 : : {
5790 : 0 : const QStringList exts = supportedOutputVectorLayerExtensions();
5791 : 0 : QStringList filters;
5792 : 0 : for ( const QString &ext : exts )
5793 : : {
5794 : 0 : filters << QObject::tr( "%1 files (*.%2)" ).arg( ext.toUpper(), ext.toLower() );
5795 : : }
5796 : 0 : return filters.join( QLatin1String( ";;" ) ) + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
5797 : :
5798 : 0 : }
5799 : :
5800 : 0 : QStringList QgsProcessingParameterFeatureSink::supportedOutputVectorLayerExtensions() const
5801 : : {
5802 : 0 : if ( auto *lOriginalProvider = originalProvider() )
5803 : : {
5804 : 0 : if ( hasGeometry() )
5805 : 0 : return lOriginalProvider->supportedOutputVectorLayerExtensions();
5806 : : else
5807 : 0 : return lOriginalProvider->supportedOutputTableExtensions();
5808 : : }
5809 : 0 : else if ( QgsProcessingProvider *p = provider() )
5810 : : {
5811 : 0 : if ( hasGeometry() )
5812 : 0 : return p->supportedOutputVectorLayerExtensions();
5813 : : else
5814 : 0 : return p->supportedOutputTableExtensions();
5815 : : }
5816 : : else
5817 : : {
5818 : 0 : return QgsVectorFileWriter::supportedFormatExtensions();
5819 : : }
5820 : 0 : }
5821 : :
5822 : 0 : QgsProcessing::SourceType QgsProcessingParameterFeatureSink::dataType() const
5823 : : {
5824 : 0 : return mDataType;
5825 : : }
5826 : :
5827 : 0 : bool QgsProcessingParameterFeatureSink::hasGeometry() const
5828 : : {
5829 : 0 : switch ( mDataType )
5830 : : {
5831 : : case QgsProcessing::TypeMapLayer:
5832 : : case QgsProcessing::TypeVectorAnyGeometry:
5833 : : case QgsProcessing::TypeVectorPoint:
5834 : : case QgsProcessing::TypeVectorLine:
5835 : : case QgsProcessing::TypeVectorPolygon:
5836 : 0 : return true;
5837 : :
5838 : : case QgsProcessing::TypeRaster:
5839 : : case QgsProcessing::TypeFile:
5840 : : case QgsProcessing::TypeVector:
5841 : : case QgsProcessing::TypeMesh:
5842 : 0 : return false;
5843 : : }
5844 : 0 : return true;
5845 : 0 : }
5846 : :
5847 : 0 : void QgsProcessingParameterFeatureSink::setDataType( QgsProcessing::SourceType type )
5848 : : {
5849 : 0 : mDataType = type;
5850 : 0 : }
5851 : :
5852 : 0 : QVariantMap QgsProcessingParameterFeatureSink::toVariantMap() const
5853 : : {
5854 : 0 : QVariantMap map = QgsProcessingDestinationParameter::toVariantMap();
5855 : 0 : map.insert( QStringLiteral( "data_type" ), mDataType );
5856 : 0 : map.insert( QStringLiteral( "supports_append" ), mSupportsAppend );
5857 : 0 : return map;
5858 : 0 : }
5859 : :
5860 : 0 : bool QgsProcessingParameterFeatureSink::fromVariantMap( const QVariantMap &map )
5861 : : {
5862 : 0 : QgsProcessingDestinationParameter::fromVariantMap( map );
5863 : 0 : mDataType = static_cast< QgsProcessing::SourceType >( map.value( QStringLiteral( "data_type" ) ).toInt() );
5864 : 0 : mSupportsAppend = map.value( QStringLiteral( "supports_append" ), false ).toBool();
5865 : 0 : return true;
5866 : 0 : }
5867 : :
5868 : 0 : QString QgsProcessingParameterFeatureSink::generateTemporaryDestination() const
5869 : : {
5870 : 0 : if ( supportsNonFileBasedOutput() )
5871 : 0 : return QStringLiteral( "memory:%1" ).arg( description() );
5872 : : else
5873 : 0 : return QgsProcessingDestinationParameter::generateTemporaryDestination();
5874 : 0 : }
5875 : :
5876 : 0 : QgsProcessingParameterFeatureSink *QgsProcessingParameterFeatureSink::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5877 : : {
5878 : 0 : QgsProcessing::SourceType type = QgsProcessing::TypeVectorAnyGeometry;
5879 : 0 : QString def = definition;
5880 : 0 : if ( def.startsWith( QLatin1String( "point" ), Qt::CaseInsensitive ) )
5881 : : {
5882 : 0 : type = QgsProcessing::TypeVectorPoint;
5883 : 0 : def = def.mid( 6 );
5884 : 0 : }
5885 : 0 : else if ( def.startsWith( QLatin1String( "line" ), Qt::CaseInsensitive ) )
5886 : : {
5887 : 0 : type = QgsProcessing::TypeVectorLine;
5888 : 0 : def = def.mid( 5 );
5889 : 0 : }
5890 : 0 : else if ( def.startsWith( QLatin1String( "polygon" ), Qt::CaseInsensitive ) )
5891 : : {
5892 : 0 : type = QgsProcessing::TypeVectorPolygon;
5893 : 0 : def = def.mid( 8 );
5894 : 0 : }
5895 : 0 : else if ( def.startsWith( QLatin1String( "table" ), Qt::CaseInsensitive ) )
5896 : : {
5897 : 0 : type = QgsProcessing::TypeVector;
5898 : 0 : def = def.mid( 6 );
5899 : 0 : }
5900 : :
5901 : 0 : return new QgsProcessingParameterFeatureSink( name, description, type, definition, isOptional );
5902 : 0 : }
5903 : :
5904 : 0 : bool QgsProcessingParameterFeatureSink::supportsAppend() const
5905 : : {
5906 : 0 : return mSupportsAppend;
5907 : : }
5908 : :
5909 : 0 : void QgsProcessingParameterFeatureSink::setSupportsAppend( bool supportsAppend )
5910 : : {
5911 : 0 : mSupportsAppend = supportsAppend;
5912 : 0 : }
5913 : :
5914 : 0 : QgsProcessingParameterRasterDestination::QgsProcessingParameterRasterDestination( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, bool createByDefault )
5915 : 0 : : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
5916 : 0 : {
5917 : 0 : }
5918 : :
5919 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterRasterDestination::clone() const
5920 : : {
5921 : 0 : return new QgsProcessingParameterRasterDestination( *this );
5922 : 0 : }
5923 : :
5924 : 0 : bool QgsProcessingParameterRasterDestination::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
5925 : : {
5926 : 0 : QVariant var = input;
5927 : 0 : if ( !var.isValid() )
5928 : 0 : return mFlags & FlagOptional;
5929 : :
5930 : 0 : if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
5931 : : {
5932 : 0 : QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
5933 : 0 : var = fromVar.sink;
5934 : 0 : }
5935 : :
5936 : 0 : if ( var.canConvert<QgsProperty>() )
5937 : : {
5938 : 0 : QgsProperty p = var.value< QgsProperty >();
5939 : 0 : if ( p.propertyType() == QgsProperty::StaticProperty )
5940 : : {
5941 : 0 : var = p.staticValue();
5942 : 0 : }
5943 : : else
5944 : : {
5945 : 0 : return true;
5946 : : }
5947 : 0 : }
5948 : :
5949 : 0 : if ( var.type() != QVariant::String )
5950 : 0 : return false;
5951 : :
5952 : 0 : if ( var.toString().isEmpty() )
5953 : 0 : return mFlags & FlagOptional;
5954 : :
5955 : 0 : return true;
5956 : 0 : }
5957 : :
5958 : 0 : QString QgsProcessingParameterRasterDestination::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
5959 : : {
5960 : 0 : if ( !value.isValid() )
5961 : 0 : return QStringLiteral( "None" );
5962 : :
5963 : 0 : if ( value.canConvert<QgsProperty>() )
5964 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
5965 : :
5966 : 0 : if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
5967 : : {
5968 : 0 : QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
5969 : 0 : if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
5970 : : {
5971 : 0 : return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
5972 : : }
5973 : : else
5974 : : {
5975 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
5976 : : }
5977 : 0 : }
5978 : :
5979 : 0 : return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
5980 : 0 : }
5981 : :
5982 : 0 : QgsProcessingOutputDefinition *QgsProcessingParameterRasterDestination::toOutputDefinition() const
5983 : : {
5984 : 0 : return new QgsProcessingOutputRasterLayer( name(), description() );
5985 : 0 : }
5986 : :
5987 : 0 : QString QgsProcessingParameterRasterDestination::defaultFileExtension() const
5988 : : {
5989 : 0 : if ( auto *lOriginalProvider = originalProvider() )
5990 : : {
5991 : 0 : return lOriginalProvider->defaultRasterFileExtension();
5992 : : }
5993 : 0 : else if ( QgsProcessingProvider *p = provider() )
5994 : : {
5995 : 0 : return p->defaultRasterFileExtension();
5996 : : }
5997 : : else
5998 : : {
5999 : 0 : return QgsProcessingUtils::defaultRasterExtension();
6000 : : }
6001 : 0 : }
6002 : :
6003 : 0 : QString QgsProcessingParameterRasterDestination::createFileFilter() const
6004 : : {
6005 : 0 : const QStringList exts = supportedOutputRasterLayerExtensions();
6006 : 0 : QStringList filters;
6007 : 0 : for ( const QString &ext : exts )
6008 : : {
6009 : 0 : filters << QObject::tr( "%1 files (*.%2)" ).arg( ext.toUpper(), ext.toLower() );
6010 : : }
6011 : 0 : return filters.join( QLatin1String( ";;" ) ) + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
6012 : 0 : }
6013 : :
6014 : 0 : QStringList QgsProcessingParameterRasterDestination::supportedOutputRasterLayerExtensions() const
6015 : : {
6016 : 0 : if ( auto *lOriginalProvider = originalProvider() )
6017 : : {
6018 : 0 : return lOriginalProvider->supportedOutputRasterLayerExtensions();
6019 : : }
6020 : 0 : else if ( QgsProcessingProvider *p = provider() )
6021 : : {
6022 : 0 : return p->supportedOutputRasterLayerExtensions();
6023 : : }
6024 : : else
6025 : : {
6026 : 0 : return QgsRasterFileWriter::supportedFormatExtensions();
6027 : : }
6028 : 0 : }
6029 : :
6030 : 0 : QgsProcessingParameterRasterDestination *QgsProcessingParameterRasterDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6031 : : {
6032 : 0 : return new QgsProcessingParameterRasterDestination( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
6033 : 0 : }
6034 : :
6035 : :
6036 : 0 : QgsProcessingParameterFileDestination::QgsProcessingParameterFileDestination( const QString &name, const QString &description, const QString &fileFilter, const QVariant &defaultValue, bool optional, bool createByDefault )
6037 : 0 : : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
6038 : 0 : , mFileFilter( fileFilter.isEmpty() ? QObject::tr( "All files (*.*)" ) : fileFilter )
6039 : 0 : {
6040 : :
6041 : 0 : }
6042 : :
6043 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterFileDestination::clone() const
6044 : : {
6045 : 0 : return new QgsProcessingParameterFileDestination( *this );
6046 : 0 : }
6047 : :
6048 : 0 : bool QgsProcessingParameterFileDestination::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
6049 : : {
6050 : 0 : QVariant var = input;
6051 : 0 : if ( !var.isValid() )
6052 : 0 : return mFlags & FlagOptional;
6053 : :
6054 : 0 : if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
6055 : : {
6056 : 0 : QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
6057 : 0 : var = fromVar.sink;
6058 : 0 : }
6059 : :
6060 : 0 : if ( var.canConvert<QgsProperty>() )
6061 : : {
6062 : 0 : QgsProperty p = var.value< QgsProperty >();
6063 : 0 : if ( p.propertyType() == QgsProperty::StaticProperty )
6064 : : {
6065 : 0 : var = p.staticValue();
6066 : 0 : }
6067 : : else
6068 : : {
6069 : 0 : return true;
6070 : : }
6071 : 0 : }
6072 : :
6073 : 0 : if ( var.type() != QVariant::String )
6074 : 0 : return false;
6075 : :
6076 : 0 : if ( var.toString().isEmpty() )
6077 : 0 : return mFlags & FlagOptional;
6078 : :
6079 : : // possible enhancement - check that value is compatible with file filter?
6080 : :
6081 : 0 : return true;
6082 : 0 : }
6083 : :
6084 : 0 : QString QgsProcessingParameterFileDestination::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
6085 : : {
6086 : 0 : if ( !value.isValid() )
6087 : 0 : return QStringLiteral( "None" );
6088 : :
6089 : 0 : if ( value.canConvert<QgsProperty>() )
6090 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
6091 : :
6092 : 0 : if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
6093 : : {
6094 : 0 : QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
6095 : 0 : if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
6096 : : {
6097 : 0 : return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
6098 : : }
6099 : : else
6100 : : {
6101 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
6102 : : }
6103 : 0 : }
6104 : :
6105 : 0 : return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
6106 : 0 : }
6107 : :
6108 : 0 : QgsProcessingOutputDefinition *QgsProcessingParameterFileDestination::toOutputDefinition() const
6109 : : {
6110 : 0 : if ( !mFileFilter.isEmpty() && mFileFilter.contains( QStringLiteral( "htm" ), Qt::CaseInsensitive ) )
6111 : : {
6112 : 0 : return new QgsProcessingOutputHtml( name(), description() );
6113 : : }
6114 : : else
6115 : : {
6116 : 0 : return new QgsProcessingOutputFile( name(), description() );
6117 : : }
6118 : 0 : }
6119 : :
6120 : 0 : QString QgsProcessingParameterFileDestination::defaultFileExtension() const
6121 : : {
6122 : 0 : if ( mFileFilter.isEmpty() || mFileFilter == QObject::tr( "All files (*.*)" ) )
6123 : 0 : return QStringLiteral( "file" );
6124 : :
6125 : : // get first extension from filter
6126 : 0 : QRegularExpression rx( QStringLiteral( ".*?\\(\\*\\.([a-zA-Z0-9._]+).*" ) );
6127 : 0 : QRegularExpressionMatch match = rx.match( mFileFilter );
6128 : 0 : if ( !match.hasMatch() )
6129 : 0 : return QStringLiteral( "file" );
6130 : :
6131 : 0 : return match.captured( 1 );
6132 : 0 : }
6133 : :
6134 : 0 : QString QgsProcessingParameterFileDestination::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
6135 : : {
6136 : 0 : switch ( outputType )
6137 : : {
6138 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
6139 : : {
6140 : 0 : QString code = QStringLiteral( "QgsProcessingParameterFileDestination('%1', '%2'" ).arg( name(), description() );
6141 : 0 : if ( mFlags & FlagOptional )
6142 : 0 : code += QLatin1String( ", optional=True" );
6143 : :
6144 : 0 : code += QStringLiteral( ", fileFilter=%1" ).arg( QgsProcessingUtils::stringToPythonLiteral( mFileFilter ) );
6145 : :
6146 : 0 : code += QStringLiteral( ", createByDefault=%1" ).arg( createByDefault() ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
6147 : :
6148 : 0 : QgsProcessingContext c;
6149 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
6150 : 0 : return code;
6151 : 0 : }
6152 : : }
6153 : 0 : return QString();
6154 : 0 : }
6155 : :
6156 : 0 : QString QgsProcessingParameterFileDestination::createFileFilter() const
6157 : : {
6158 : 0 : return ( fileFilter().isEmpty() ? QString() : fileFilter() + QStringLiteral( ";;" ) ) + QObject::tr( "All files (*.*)" );
6159 : 0 : }
6160 : :
6161 : 0 : QString QgsProcessingParameterFileDestination::fileFilter() const
6162 : : {
6163 : 0 : return mFileFilter;
6164 : : }
6165 : :
6166 : 0 : void QgsProcessingParameterFileDestination::setFileFilter( const QString &fileFilter )
6167 : : {
6168 : 0 : mFileFilter = fileFilter;
6169 : 0 : }
6170 : :
6171 : 0 : QVariantMap QgsProcessingParameterFileDestination::toVariantMap() const
6172 : : {
6173 : 0 : QVariantMap map = QgsProcessingDestinationParameter::toVariantMap();
6174 : 0 : map.insert( QStringLiteral( "file_filter" ), mFileFilter );
6175 : 0 : return map;
6176 : 0 : }
6177 : :
6178 : 0 : bool QgsProcessingParameterFileDestination::fromVariantMap( const QVariantMap &map )
6179 : : {
6180 : 0 : QgsProcessingDestinationParameter::fromVariantMap( map );
6181 : 0 : mFileFilter = map.value( QStringLiteral( "file_filter" ) ).toString();
6182 : 0 : return true;
6183 : :
6184 : 0 : }
6185 : :
6186 : 0 : QgsProcessingParameterFileDestination *QgsProcessingParameterFileDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6187 : : {
6188 : 0 : return new QgsProcessingParameterFileDestination( name, description, QString(), definition.isEmpty() ? QVariant() : definition, isOptional );
6189 : 0 : }
6190 : :
6191 : 0 : QgsProcessingParameterFolderDestination::QgsProcessingParameterFolderDestination( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, bool createByDefault )
6192 : 0 : : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
6193 : 0 : {}
6194 : :
6195 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterFolderDestination::clone() const
6196 : : {
6197 : 0 : return new QgsProcessingParameterFolderDestination( *this );
6198 : 0 : }
6199 : :
6200 : 0 : bool QgsProcessingParameterFolderDestination::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
6201 : : {
6202 : 0 : QVariant var = input;
6203 : 0 : if ( !var.isValid() )
6204 : 0 : return mFlags & FlagOptional;
6205 : :
6206 : 0 : if ( var.canConvert<QgsProperty>() )
6207 : : {
6208 : 0 : QgsProperty p = var.value< QgsProperty >();
6209 : 0 : if ( p.propertyType() == QgsProperty::StaticProperty )
6210 : : {
6211 : 0 : var = p.staticValue();
6212 : 0 : }
6213 : : else
6214 : : {
6215 : 0 : return true;
6216 : : }
6217 : 0 : }
6218 : :
6219 : 0 : if ( var.type() != QVariant::String )
6220 : 0 : return false;
6221 : :
6222 : 0 : if ( var.toString().isEmpty() )
6223 : 0 : return mFlags & FlagOptional;
6224 : :
6225 : 0 : return true;
6226 : 0 : }
6227 : :
6228 : 0 : QgsProcessingOutputDefinition *QgsProcessingParameterFolderDestination::toOutputDefinition() const
6229 : : {
6230 : 0 : return new QgsProcessingOutputFolder( name(), description() );
6231 : 0 : }
6232 : :
6233 : 0 : QString QgsProcessingParameterFolderDestination::defaultFileExtension() const
6234 : : {
6235 : 0 : return QString();
6236 : : }
6237 : :
6238 : 0 : QgsProcessingParameterFolderDestination *QgsProcessingParameterFolderDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6239 : : {
6240 : 0 : return new QgsProcessingParameterFolderDestination( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
6241 : 0 : }
6242 : :
6243 : 0 : QgsProcessingDestinationParameter::QgsProcessingDestinationParameter( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, bool createByDefault )
6244 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
6245 : 0 : , mCreateByDefault( createByDefault )
6246 : 0 : {
6247 : :
6248 : 0 : }
6249 : :
6250 : 0 : QVariantMap QgsProcessingDestinationParameter::toVariantMap() const
6251 : : {
6252 : 0 : QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
6253 : 0 : map.insert( QStringLiteral( "supports_non_file_outputs" ), mSupportsNonFileBasedOutputs );
6254 : 0 : map.insert( QStringLiteral( "create_by_default" ), mCreateByDefault );
6255 : 0 : return map;
6256 : 0 : }
6257 : :
6258 : 0 : bool QgsProcessingDestinationParameter::fromVariantMap( const QVariantMap &map )
6259 : : {
6260 : 0 : QgsProcessingParameterDefinition::fromVariantMap( map );
6261 : 0 : mSupportsNonFileBasedOutputs = map.value( QStringLiteral( "supports_non_file_outputs" ) ).toBool();
6262 : 0 : mCreateByDefault = map.value( QStringLiteral( "create_by_default" ), QStringLiteral( "1" ) ).toBool();
6263 : 0 : return true;
6264 : 0 : }
6265 : :
6266 : 0 : QString QgsProcessingDestinationParameter::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
6267 : : {
6268 : 0 : switch ( outputType )
6269 : : {
6270 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
6271 : : {
6272 : : // base class method is probably not much use
6273 : 0 : if ( QgsProcessingParameterType *t = QgsApplication::processingRegistry()->parameterType( type() ) )
6274 : : {
6275 : 0 : QString code = t->className() + QStringLiteral( "('%1', '%2'" ).arg( name(), description() );
6276 : 0 : if ( mFlags & FlagOptional )
6277 : 0 : code += QLatin1String( ", optional=True" );
6278 : :
6279 : 0 : code += QStringLiteral( ", createByDefault=%1" ).arg( mCreateByDefault ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
6280 : :
6281 : 0 : QgsProcessingContext c;
6282 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
6283 : 0 : return code;
6284 : 0 : }
6285 : 0 : break;
6286 : : }
6287 : : }
6288 : : // oh well, we tried
6289 : 0 : return QString();
6290 : 0 : }
6291 : :
6292 : 0 : QString QgsProcessingDestinationParameter::createFileFilter() const
6293 : : {
6294 : 0 : return QObject::tr( "Default extension" ) + QStringLiteral( " (*." ) + defaultFileExtension() + ')';
6295 : 0 : }
6296 : :
6297 : 0 : QString QgsProcessingDestinationParameter::generateTemporaryDestination() const
6298 : : {
6299 : : // sanitize name to avoid multiple . in the filename. E.g. when name() contain
6300 : : // backend command name having a "." inside as in case of grass commands
6301 : 0 : QRegularExpression rx( QStringLiteral( "[.]" ) );
6302 : 0 : QString sanitizedName = name();
6303 : 0 : sanitizedName.replace( rx, QStringLiteral( "_" ) );
6304 : :
6305 : 0 : if ( defaultFileExtension().isEmpty() )
6306 : : {
6307 : 0 : return QgsProcessingUtils::generateTempFilename( sanitizedName );
6308 : : }
6309 : : else
6310 : : {
6311 : 0 : return QgsProcessingUtils::generateTempFilename( sanitizedName + '.' + defaultFileExtension() );
6312 : : }
6313 : 0 : }
6314 : :
6315 : 0 : bool QgsProcessingDestinationParameter::isSupportedOutputValue( const QVariant &value, QgsProcessingContext &context, QString &error ) const
6316 : : {
6317 : 0 : if ( auto *lOriginalProvider = originalProvider() )
6318 : 0 : return lOriginalProvider->isSupportedOutputValue( value, this, context, error );
6319 : 0 : else if ( provider() )
6320 : 0 : return provider()->isSupportedOutputValue( value, this, context, error );
6321 : :
6322 : 0 : return true;
6323 : 0 : }
6324 : :
6325 : 0 : bool QgsProcessingDestinationParameter::createByDefault() const
6326 : : {
6327 : 0 : return mCreateByDefault;
6328 : : }
6329 : :
6330 : 0 : void QgsProcessingDestinationParameter::setCreateByDefault( bool createByDefault )
6331 : : {
6332 : 0 : mCreateByDefault = createByDefault;
6333 : 0 : }
6334 : :
6335 : 0 : QgsProcessingParameterVectorDestination::QgsProcessingParameterVectorDestination( const QString &name, const QString &description, QgsProcessing::SourceType type, const QVariant &defaultValue, bool optional, bool createByDefault )
6336 : 0 : : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
6337 : 0 : , mDataType( type )
6338 : 0 : {
6339 : :
6340 : 0 : }
6341 : :
6342 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterVectorDestination::clone() const
6343 : : {
6344 : 0 : return new QgsProcessingParameterVectorDestination( *this );
6345 : 0 : }
6346 : :
6347 : 0 : bool QgsProcessingParameterVectorDestination::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
6348 : : {
6349 : 0 : QVariant var = input;
6350 : 0 : if ( !var.isValid() )
6351 : 0 : return mFlags & FlagOptional;
6352 : :
6353 : 0 : if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
6354 : : {
6355 : 0 : QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
6356 : 0 : var = fromVar.sink;
6357 : 0 : }
6358 : :
6359 : 0 : if ( var.canConvert<QgsProperty>() )
6360 : : {
6361 : 0 : QgsProperty p = var.value< QgsProperty >();
6362 : 0 : if ( p.propertyType() == QgsProperty::StaticProperty )
6363 : : {
6364 : 0 : var = p.staticValue();
6365 : 0 : }
6366 : : else
6367 : : {
6368 : 0 : return true;
6369 : : }
6370 : 0 : }
6371 : :
6372 : 0 : if ( var.type() != QVariant::String )
6373 : 0 : return false;
6374 : :
6375 : 0 : if ( var.toString().isEmpty() )
6376 : 0 : return mFlags & FlagOptional;
6377 : :
6378 : 0 : return true;
6379 : 0 : }
6380 : :
6381 : 0 : QString QgsProcessingParameterVectorDestination::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
6382 : : {
6383 : 0 : if ( !value.isValid() )
6384 : 0 : return QStringLiteral( "None" );
6385 : :
6386 : 0 : if ( value.canConvert<QgsProperty>() )
6387 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
6388 : :
6389 : 0 : if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
6390 : : {
6391 : 0 : QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
6392 : 0 : if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
6393 : : {
6394 : 0 : return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
6395 : : }
6396 : : else
6397 : : {
6398 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
6399 : : }
6400 : 0 : }
6401 : :
6402 : 0 : return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
6403 : 0 : }
6404 : :
6405 : 0 : QString QgsProcessingParameterVectorDestination::asScriptCode() const
6406 : : {
6407 : 0 : QString code = QStringLiteral( "##%1=" ).arg( mName );
6408 : 0 : if ( mFlags & FlagOptional )
6409 : 0 : code += QLatin1String( "optional " );
6410 : 0 : code += QLatin1String( "vectorDestination " );
6411 : :
6412 : 0 : switch ( mDataType )
6413 : : {
6414 : : case QgsProcessing::TypeVectorPoint:
6415 : 0 : code += QLatin1String( "point " );
6416 : 0 : break;
6417 : :
6418 : : case QgsProcessing::TypeVectorLine:
6419 : 0 : code += QLatin1String( "line " );
6420 : 0 : break;
6421 : :
6422 : : case QgsProcessing::TypeVectorPolygon:
6423 : 0 : code += QLatin1String( "polygon " );
6424 : 0 : break;
6425 : :
6426 : : default:
6427 : 0 : break;
6428 : : }
6429 : :
6430 : 0 : code += mDefault.toString();
6431 : 0 : return code.trimmed();
6432 : 0 : }
6433 : :
6434 : 0 : QgsProcessingOutputDefinition *QgsProcessingParameterVectorDestination::toOutputDefinition() const
6435 : : {
6436 : 0 : return new QgsProcessingOutputVectorLayer( name(), description(), mDataType );
6437 : 0 : }
6438 : :
6439 : 0 : QString QgsProcessingParameterVectorDestination::defaultFileExtension() const
6440 : : {
6441 : 0 : if ( auto *lOriginalProvider = originalProvider() )
6442 : : {
6443 : 0 : return lOriginalProvider->defaultVectorFileExtension( hasGeometry() );
6444 : : }
6445 : 0 : else if ( QgsProcessingProvider *p = provider() )
6446 : : {
6447 : 0 : return p->defaultVectorFileExtension( hasGeometry() );
6448 : : }
6449 : : else
6450 : : {
6451 : 0 : if ( hasGeometry() )
6452 : : {
6453 : 0 : return QgsProcessingUtils::defaultVectorExtension();
6454 : : }
6455 : : else
6456 : : {
6457 : 0 : return QStringLiteral( "dbf" );
6458 : : }
6459 : : }
6460 : 0 : }
6461 : :
6462 : 0 : QString QgsProcessingParameterVectorDestination::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
6463 : : {
6464 : 0 : switch ( outputType )
6465 : : {
6466 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
6467 : : {
6468 : 0 : QString code = QStringLiteral( "QgsProcessingParameterVectorDestination('%1', '%2'" ).arg( name(), description() );
6469 : 0 : if ( mFlags & FlagOptional )
6470 : 0 : code += QLatin1String( ", optional=True" );
6471 : :
6472 : 0 : code += QStringLiteral( ", type=QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( mDataType ) );
6473 : :
6474 : 0 : code += QStringLiteral( ", createByDefault=%1" ).arg( createByDefault() ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
6475 : :
6476 : 0 : QgsProcessingContext c;
6477 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
6478 : 0 : return code;
6479 : 0 : }
6480 : : }
6481 : 0 : return QString();
6482 : 0 : }
6483 : :
6484 : 0 : QString QgsProcessingParameterVectorDestination::createFileFilter() const
6485 : : {
6486 : 0 : const QStringList exts = supportedOutputVectorLayerExtensions();
6487 : 0 : QStringList filters;
6488 : 0 : for ( const QString &ext : exts )
6489 : : {
6490 : 0 : filters << QObject::tr( "%1 files (*.%2)" ).arg( ext.toUpper(), ext.toLower() );
6491 : : }
6492 : 0 : return filters.join( QLatin1String( ";;" ) ) + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
6493 : 0 : }
6494 : :
6495 : 0 : QStringList QgsProcessingParameterVectorDestination::supportedOutputVectorLayerExtensions() const
6496 : : {
6497 : 0 : if ( auto *lOriginalProvider = originalProvider() )
6498 : : {
6499 : 0 : if ( hasGeometry() )
6500 : 0 : return lOriginalProvider->supportedOutputVectorLayerExtensions();
6501 : : else
6502 : 0 : return lOriginalProvider->supportedOutputTableExtensions();
6503 : : }
6504 : 0 : else if ( QgsProcessingProvider *p = provider() )
6505 : : {
6506 : 0 : if ( hasGeometry() )
6507 : 0 : return p->supportedOutputVectorLayerExtensions();
6508 : : else
6509 : 0 : return p->supportedOutputTableExtensions();
6510 : : }
6511 : : else
6512 : : {
6513 : 0 : return QgsVectorFileWriter::supportedFormatExtensions();
6514 : : }
6515 : 0 : }
6516 : :
6517 : 0 : QgsProcessing::SourceType QgsProcessingParameterVectorDestination::dataType() const
6518 : : {
6519 : 0 : return mDataType;
6520 : : }
6521 : :
6522 : 0 : bool QgsProcessingParameterVectorDestination::hasGeometry() const
6523 : : {
6524 : 0 : switch ( mDataType )
6525 : : {
6526 : : case QgsProcessing::TypeMapLayer:
6527 : : case QgsProcessing::TypeVectorAnyGeometry:
6528 : : case QgsProcessing::TypeVectorPoint:
6529 : : case QgsProcessing::TypeVectorLine:
6530 : : case QgsProcessing::TypeVectorPolygon:
6531 : 0 : return true;
6532 : :
6533 : : case QgsProcessing::TypeRaster:
6534 : : case QgsProcessing::TypeFile:
6535 : : case QgsProcessing::TypeVector:
6536 : : case QgsProcessing::TypeMesh:
6537 : 0 : return false;
6538 : : }
6539 : 0 : return true;
6540 : 0 : }
6541 : :
6542 : 0 : void QgsProcessingParameterVectorDestination::setDataType( QgsProcessing::SourceType type )
6543 : : {
6544 : 0 : mDataType = type;
6545 : 0 : }
6546 : :
6547 : 0 : QVariantMap QgsProcessingParameterVectorDestination::toVariantMap() const
6548 : : {
6549 : 0 : QVariantMap map = QgsProcessingDestinationParameter::toVariantMap();
6550 : 0 : map.insert( QStringLiteral( "data_type" ), mDataType );
6551 : 0 : return map;
6552 : 0 : }
6553 : :
6554 : 0 : bool QgsProcessingParameterVectorDestination::fromVariantMap( const QVariantMap &map )
6555 : : {
6556 : 0 : QgsProcessingDestinationParameter::fromVariantMap( map );
6557 : 0 : mDataType = static_cast< QgsProcessing::SourceType >( map.value( QStringLiteral( "data_type" ) ).toInt() );
6558 : 0 : return true;
6559 : 0 : }
6560 : :
6561 : 0 : QgsProcessingParameterVectorDestination *QgsProcessingParameterVectorDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6562 : : {
6563 : 0 : QgsProcessing::SourceType type = QgsProcessing::TypeVectorAnyGeometry;
6564 : 0 : QString def = definition;
6565 : 0 : if ( def.startsWith( QLatin1String( "point" ), Qt::CaseInsensitive ) )
6566 : : {
6567 : 0 : type = QgsProcessing::TypeVectorPoint;
6568 : 0 : def = def.mid( 6 );
6569 : 0 : }
6570 : 0 : else if ( def.startsWith( QLatin1String( "line" ), Qt::CaseInsensitive ) )
6571 : : {
6572 : 0 : type = QgsProcessing::TypeVectorLine;
6573 : 0 : def = def.mid( 5 );
6574 : 0 : }
6575 : 0 : else if ( def.startsWith( QLatin1String( "polygon" ), Qt::CaseInsensitive ) )
6576 : : {
6577 : 0 : type = QgsProcessing::TypeVectorPolygon;
6578 : 0 : def = def.mid( 8 );
6579 : 0 : }
6580 : :
6581 : 0 : return new QgsProcessingParameterVectorDestination( name, description, type, definition, isOptional );
6582 : 0 : }
6583 : :
6584 : 0 : QgsProcessingParameterBand::QgsProcessingParameterBand( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayerParameterName, bool optional, bool allowMultiple )
6585 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
6586 : 0 : , mParentLayerParameterName( parentLayerParameterName )
6587 : 0 : , mAllowMultiple( allowMultiple )
6588 : 0 : {
6589 : :
6590 : 0 : }
6591 : :
6592 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterBand::clone() const
6593 : : {
6594 : 0 : return new QgsProcessingParameterBand( *this );
6595 : 0 : }
6596 : :
6597 : 0 : bool QgsProcessingParameterBand::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
6598 : : {
6599 : 0 : if ( !input.isValid() )
6600 : 0 : return mFlags & FlagOptional;
6601 : :
6602 : 0 : if ( input.canConvert<QgsProperty>() )
6603 : : {
6604 : 0 : return true;
6605 : : }
6606 : :
6607 : 0 : if ( input.type() == QVariant::List || input.type() == QVariant::StringList )
6608 : : {
6609 : 0 : if ( !mAllowMultiple )
6610 : 0 : return false;
6611 : :
6612 : 0 : if ( input.toList().isEmpty() && !( mFlags & FlagOptional ) )
6613 : 0 : return false;
6614 : 0 : }
6615 : : else
6616 : : {
6617 : 0 : bool ok = false;
6618 : 0 : double res = input.toInt( &ok );
6619 : : Q_UNUSED( res )
6620 : 0 : if ( !ok )
6621 : 0 : return mFlags & FlagOptional;
6622 : : }
6623 : 0 : return true;
6624 : 0 : }
6625 : :
6626 : 0 : bool QgsProcessingParameterBand::allowMultiple() const
6627 : : {
6628 : 0 : return mAllowMultiple;
6629 : : }
6630 : :
6631 : 0 : void QgsProcessingParameterBand::setAllowMultiple( bool allowMultiple )
6632 : : {
6633 : 0 : mAllowMultiple = allowMultiple;
6634 : 0 : }
6635 : :
6636 : 0 : QString QgsProcessingParameterBand::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
6637 : : {
6638 : 0 : if ( !value.isValid() )
6639 : 0 : return QStringLiteral( "None" );
6640 : :
6641 : 0 : if ( value.canConvert<QgsProperty>() )
6642 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
6643 : :
6644 : 0 : if ( value.type() == QVariant::List )
6645 : : {
6646 : 0 : QStringList parts;
6647 : 0 : QVariantList values = value.toList();
6648 : 0 : for ( auto it = values.constBegin(); it != values.constEnd(); ++it )
6649 : : {
6650 : 0 : parts << QString::number( static_cast< int >( it->toDouble() ) );
6651 : 0 : }
6652 : 0 : return parts.join( ',' ).prepend( '[' ).append( ']' );
6653 : 0 : }
6654 : 0 : else if ( value.type() == QVariant::StringList )
6655 : : {
6656 : 0 : QStringList parts;
6657 : 0 : QStringList values = value.toStringList();
6658 : 0 : for ( auto it = values.constBegin(); it != values.constEnd(); ++it )
6659 : : {
6660 : 0 : parts << QString::number( static_cast< int >( it->toDouble() ) );
6661 : 0 : }
6662 : 0 : return parts.join( ',' ).prepend( '[' ).append( ']' );
6663 : 0 : }
6664 : :
6665 : 0 : return value.toString();
6666 : 0 : }
6667 : :
6668 : 0 : QString QgsProcessingParameterBand::asScriptCode() const
6669 : : {
6670 : 0 : QString code = QStringLiteral( "##%1=" ).arg( mName );
6671 : 0 : if ( mFlags & FlagOptional )
6672 : 0 : code += QLatin1String( "optional " );
6673 : 0 : code += QLatin1String( "band " );
6674 : :
6675 : 0 : if ( mAllowMultiple )
6676 : 0 : code += QLatin1String( "multiple " );
6677 : :
6678 : 0 : code += mParentLayerParameterName + ' ';
6679 : :
6680 : 0 : code += mDefault.toString();
6681 : 0 : return code.trimmed();
6682 : 0 : }
6683 : :
6684 : 0 : QStringList QgsProcessingParameterBand::dependsOnOtherParameters() const
6685 : : {
6686 : 0 : QStringList depends;
6687 : 0 : if ( !mParentLayerParameterName.isEmpty() )
6688 : 0 : depends << mParentLayerParameterName;
6689 : 0 : return depends;
6690 : 0 : }
6691 : :
6692 : 0 : QString QgsProcessingParameterBand::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
6693 : : {
6694 : 0 : switch ( outputType )
6695 : : {
6696 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
6697 : : {
6698 : 0 : QString code = QStringLiteral( "QgsProcessingParameterBand('%1', '%2'" ).arg( name(), description() );
6699 : 0 : if ( mFlags & FlagOptional )
6700 : 0 : code += QLatin1String( ", optional=True" );
6701 : :
6702 : 0 : code += QStringLiteral( ", parentLayerParameterName='%1'" ).arg( mParentLayerParameterName );
6703 : 0 : code += QStringLiteral( ", allowMultiple=%1" ).arg( mAllowMultiple ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
6704 : :
6705 : 0 : QgsProcessingContext c;
6706 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
6707 : 0 : return code;
6708 : 0 : }
6709 : : }
6710 : 0 : return QString();
6711 : 0 : }
6712 : :
6713 : 0 : QString QgsProcessingParameterBand::parentLayerParameterName() const
6714 : : {
6715 : 0 : return mParentLayerParameterName;
6716 : : }
6717 : :
6718 : 0 : void QgsProcessingParameterBand::setParentLayerParameterName( const QString &parentLayerParameterName )
6719 : : {
6720 : 0 : mParentLayerParameterName = parentLayerParameterName;
6721 : 0 : }
6722 : :
6723 : 0 : QVariantMap QgsProcessingParameterBand::toVariantMap() const
6724 : : {
6725 : 0 : QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
6726 : 0 : map.insert( QStringLiteral( "parent_layer" ), mParentLayerParameterName );
6727 : 0 : map.insert( QStringLiteral( "allow_multiple" ), mAllowMultiple );
6728 : 0 : return map;
6729 : 0 : }
6730 : :
6731 : 0 : bool QgsProcessingParameterBand::fromVariantMap( const QVariantMap &map )
6732 : : {
6733 : 0 : QgsProcessingParameterDefinition::fromVariantMap( map );
6734 : 0 : mParentLayerParameterName = map.value( QStringLiteral( "parent_layer" ) ).toString();
6735 : 0 : mAllowMultiple = map.value( QStringLiteral( "allow_multiple" ) ).toBool();
6736 : 0 : return true;
6737 : 0 : }
6738 : :
6739 : 0 : QgsProcessingParameterBand *QgsProcessingParameterBand::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6740 : : {
6741 : 0 : QString parent;
6742 : 0 : QString def = definition;
6743 : 0 : bool allowMultiple = false;
6744 : :
6745 : 0 : if ( def.startsWith( QLatin1String( "multiple" ), Qt::CaseInsensitive ) )
6746 : : {
6747 : 0 : allowMultiple = true;
6748 : 0 : def = def.mid( 8 ).trimmed();
6749 : 0 : }
6750 : :
6751 : 0 : QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*)$" ) );
6752 : 0 : QRegularExpressionMatch m = re.match( def );
6753 : 0 : if ( m.hasMatch() )
6754 : : {
6755 : 0 : parent = m.captured( 1 ).trimmed();
6756 : 0 : def = m.captured( 2 );
6757 : 0 : }
6758 : : else
6759 : : {
6760 : 0 : parent = def;
6761 : 0 : def.clear();
6762 : : }
6763 : :
6764 : 0 : return new QgsProcessingParameterBand( name, description, def.isEmpty() ? QVariant() : def, parent, isOptional, allowMultiple );
6765 : 0 : }
6766 : :
6767 : : //
6768 : : // QgsProcessingParameterDistance
6769 : : //
6770 : :
6771 : 0 : QgsProcessingParameterDistance::QgsProcessingParameterDistance( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentParameterName, bool optional, double minValue, double maxValue )
6772 : 0 : : QgsProcessingParameterNumber( name, description, Double, defaultValue, optional, minValue, maxValue )
6773 : 0 : , mParentParameterName( parentParameterName )
6774 : 0 : {
6775 : :
6776 : 0 : }
6777 : :
6778 : 0 : QgsProcessingParameterDistance *QgsProcessingParameterDistance::clone() const
6779 : : {
6780 : 0 : return new QgsProcessingParameterDistance( *this );
6781 : 0 : }
6782 : :
6783 : 0 : QString QgsProcessingParameterDistance::type() const
6784 : : {
6785 : 0 : return typeName();
6786 : : }
6787 : :
6788 : 0 : QStringList QgsProcessingParameterDistance::dependsOnOtherParameters() const
6789 : : {
6790 : 0 : QStringList depends;
6791 : 0 : if ( !mParentParameterName.isEmpty() )
6792 : 0 : depends << mParentParameterName;
6793 : 0 : return depends;
6794 : 0 : }
6795 : :
6796 : 0 : QString QgsProcessingParameterDistance::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
6797 : : {
6798 : 0 : switch ( outputType )
6799 : : {
6800 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
6801 : : {
6802 : 0 : QString code = QStringLiteral( "QgsProcessingParameterDistance('%1', '%2'" ).arg( name(), description() );
6803 : 0 : if ( mFlags & FlagOptional )
6804 : 0 : code += QLatin1String( ", optional=True" );
6805 : :
6806 : 0 : code += QStringLiteral( ", parentParameterName='%1'" ).arg( mParentParameterName );
6807 : :
6808 : 0 : if ( minimum() != std::numeric_limits<double>::lowest() + 1 )
6809 : 0 : code += QStringLiteral( ", minValue=%1" ).arg( minimum() );
6810 : 0 : if ( maximum() != std::numeric_limits<double>::max() )
6811 : 0 : code += QStringLiteral( ", maxValue=%1" ).arg( maximum() );
6812 : 0 : QgsProcessingContext c;
6813 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
6814 : 0 : return code;
6815 : 0 : }
6816 : : }
6817 : 0 : return QString();
6818 : 0 : }
6819 : :
6820 : 0 : QString QgsProcessingParameterDistance::parentParameterName() const
6821 : : {
6822 : 0 : return mParentParameterName;
6823 : : }
6824 : :
6825 : 0 : void QgsProcessingParameterDistance::setParentParameterName( const QString &parentParameterName )
6826 : : {
6827 : 0 : mParentParameterName = parentParameterName;
6828 : 0 : }
6829 : :
6830 : 0 : QVariantMap QgsProcessingParameterDistance::toVariantMap() const
6831 : : {
6832 : 0 : QVariantMap map = QgsProcessingParameterNumber::toVariantMap();
6833 : 0 : map.insert( QStringLiteral( "parent" ), mParentParameterName );
6834 : 0 : map.insert( QStringLiteral( "default_unit" ), static_cast< int >( mDefaultUnit ) );
6835 : 0 : return map;
6836 : 0 : }
6837 : :
6838 : 0 : bool QgsProcessingParameterDistance::fromVariantMap( const QVariantMap &map )
6839 : : {
6840 : 0 : QgsProcessingParameterNumber::fromVariantMap( map );
6841 : 0 : mParentParameterName = map.value( QStringLiteral( "parent" ) ).toString();
6842 : 0 : mDefaultUnit = static_cast< QgsUnitTypes::DistanceUnit>( map.value( QStringLiteral( "default_unit" ), QgsUnitTypes::DistanceUnknownUnit ).toInt() );
6843 : 0 : return true;
6844 : 0 : }
6845 : :
6846 : :
6847 : : //
6848 : : // QgsProcessingParameterScale
6849 : : //
6850 : :
6851 : 0 : QgsProcessingParameterScale::QgsProcessingParameterScale( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
6852 : 0 : : QgsProcessingParameterNumber( name, description, Double, defaultValue, optional )
6853 : 0 : {
6854 : :
6855 : 0 : }
6856 : :
6857 : 0 : QgsProcessingParameterScale *QgsProcessingParameterScale::clone() const
6858 : : {
6859 : 0 : return new QgsProcessingParameterScale( *this );
6860 : 0 : }
6861 : :
6862 : 0 : QString QgsProcessingParameterScale::type() const
6863 : : {
6864 : 0 : return typeName();
6865 : : }
6866 : :
6867 : 0 : QString QgsProcessingParameterScale::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
6868 : : {
6869 : 0 : switch ( outputType )
6870 : : {
6871 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
6872 : : {
6873 : 0 : QString code = QStringLiteral( "QgsProcessingParameterScale('%1', '%2'" ).arg( name(), description() );
6874 : 0 : if ( mFlags & FlagOptional )
6875 : 0 : code += QLatin1String( ", optional=True" );
6876 : 0 : QgsProcessingContext c;
6877 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
6878 : 0 : return code;
6879 : 0 : }
6880 : : }
6881 : 0 : return QString();
6882 : 0 : }
6883 : :
6884 : 0 : QgsProcessingParameterScale *QgsProcessingParameterScale::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6885 : : {
6886 : 0 : return new QgsProcessingParameterScale( name, description, definition.isEmpty() ? QVariant()
6887 : 0 : : ( definition.toLower().trimmed() == QLatin1String( "none" ) ? QVariant() : definition ), isOptional );
6888 : 0 : }
6889 : :
6890 : :
6891 : : //
6892 : : // QgsProcessingParameterLayout
6893 : : //
6894 : :
6895 : 0 : QgsProcessingParameterLayout::QgsProcessingParameterLayout( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
6896 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
6897 : 0 : {}
6898 : :
6899 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterLayout::clone() const
6900 : : {
6901 : 0 : return new QgsProcessingParameterLayout( *this );
6902 : 0 : }
6903 : :
6904 : 0 : QString QgsProcessingParameterLayout::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
6905 : : {
6906 : 0 : if ( !value.isValid() || value.isNull() )
6907 : 0 : return QStringLiteral( "None" );
6908 : :
6909 : 0 : if ( value.canConvert<QgsProperty>() )
6910 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
6911 : :
6912 : 0 : QString s = value.toString();
6913 : 0 : return QgsProcessingUtils::stringToPythonLiteral( s );
6914 : 0 : }
6915 : :
6916 : 0 : QString QgsProcessingParameterLayout::asScriptCode() const
6917 : : {
6918 : 0 : QString code = QStringLiteral( "##%1=" ).arg( mName );
6919 : 0 : if ( mFlags & FlagOptional )
6920 : 0 : code += QLatin1String( "optional " );
6921 : 0 : code += QLatin1String( "layout " );
6922 : :
6923 : 0 : code += mDefault.toString();
6924 : 0 : return code.trimmed();
6925 : 0 : }
6926 : :
6927 : 0 : QString QgsProcessingParameterLayout::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
6928 : : {
6929 : 0 : switch ( outputType )
6930 : : {
6931 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
6932 : : {
6933 : 0 : QString code = QStringLiteral( "QgsProcessingParameterLayout('%1', '%2'" ).arg( name(), description() );
6934 : 0 : if ( mFlags & FlagOptional )
6935 : 0 : code += QLatin1String( ", optional=True" );
6936 : 0 : QgsProcessingContext c;
6937 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
6938 : 0 : return code;
6939 : 0 : }
6940 : : }
6941 : 0 : return QString();
6942 : 0 : }
6943 : :
6944 : 0 : QgsProcessingParameterLayout *QgsProcessingParameterLayout::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6945 : : {
6946 : 0 : QString def = definition;
6947 : :
6948 : 0 : if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
6949 : 0 : def = def.mid( 1 );
6950 : 0 : if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
6951 : 0 : def.chop( 1 );
6952 : :
6953 : 0 : QVariant defaultValue = def;
6954 : 0 : if ( def == QLatin1String( "None" ) )
6955 : 0 : defaultValue = QVariant();
6956 : :
6957 : 0 : return new QgsProcessingParameterLayout( name, description, defaultValue, isOptional );
6958 : 0 : }
6959 : :
6960 : :
6961 : : //
6962 : : // QString mParentLayerParameterName;
6963 : : //
6964 : :
6965 : 0 : QgsProcessingParameterLayoutItem::QgsProcessingParameterLayoutItem( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayoutParameterName, int itemType, bool optional )
6966 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
6967 : 0 : , mParentLayoutParameterName( parentLayoutParameterName )
6968 : 0 : , mItemType( itemType )
6969 : 0 : {
6970 : :
6971 : 0 : }
6972 : :
6973 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterLayoutItem::clone() const
6974 : : {
6975 : 0 : return new QgsProcessingParameterLayoutItem( *this );
6976 : 0 : }
6977 : :
6978 : 0 : QString QgsProcessingParameterLayoutItem::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
6979 : : {
6980 : 0 : if ( !value.isValid() || value.isNull() )
6981 : 0 : return QStringLiteral( "None" );
6982 : :
6983 : 0 : if ( value.canConvert<QgsProperty>() )
6984 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
6985 : :
6986 : 0 : QString s = value.toString();
6987 : 0 : return QgsProcessingUtils::stringToPythonLiteral( s );
6988 : 0 : }
6989 : :
6990 : 0 : QString QgsProcessingParameterLayoutItem::asScriptCode() const
6991 : : {
6992 : 0 : QString code = QStringLiteral( "##%1=" ).arg( mName );
6993 : 0 : if ( mFlags & FlagOptional )
6994 : 0 : code += QLatin1String( "optional " );
6995 : 0 : code += QLatin1String( "layoutitem " );
6996 : 0 : if ( mItemType >= 0 )
6997 : 0 : code += QString::number( mItemType ) + ' ';
6998 : :
6999 : 0 : code += mParentLayoutParameterName + ' ';
7000 : :
7001 : 0 : code += mDefault.toString();
7002 : 0 : return code.trimmed();
7003 : 0 : }
7004 : :
7005 : 0 : QString QgsProcessingParameterLayoutItem::asPythonString( QgsProcessing::PythonOutputType outputType ) const
7006 : : {
7007 : 0 : switch ( outputType )
7008 : : {
7009 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
7010 : : {
7011 : 0 : QString code = QStringLiteral( "QgsProcessingParameterLayoutItem('%1', '%2'" ).arg( name(), description() );
7012 : 0 : if ( mFlags & FlagOptional )
7013 : 0 : code += QLatin1String( ", optional=True" );
7014 : :
7015 : 0 : if ( mItemType >= 0 )
7016 : 0 : code += QStringLiteral( ", itemType=%1" ).arg( mItemType );
7017 : :
7018 : 0 : code += QStringLiteral( ", parentLayoutParameterName='%1'" ).arg( mParentLayoutParameterName );
7019 : :
7020 : 0 : QgsProcessingContext c;
7021 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7022 : 0 : return code;
7023 : 0 : }
7024 : : }
7025 : 0 : return QString();
7026 : 0 : }
7027 : :
7028 : 0 : QVariantMap QgsProcessingParameterLayoutItem::toVariantMap() const
7029 : : {
7030 : 0 : QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
7031 : 0 : map.insert( QStringLiteral( "parent_layout" ), mParentLayoutParameterName );
7032 : 0 : map.insert( QStringLiteral( "item_type" ), mItemType );
7033 : 0 : return map;
7034 : 0 : }
7035 : :
7036 : 0 : bool QgsProcessingParameterLayoutItem::fromVariantMap( const QVariantMap &map )
7037 : : {
7038 : 0 : QgsProcessingParameterDefinition::fromVariantMap( map );
7039 : 0 : mParentLayoutParameterName = map.value( QStringLiteral( "parent_layout" ) ).toString();
7040 : 0 : mItemType = map.value( QStringLiteral( "item_type" ) ).toInt();
7041 : 0 : return true;
7042 : 0 : }
7043 : :
7044 : 0 : QStringList QgsProcessingParameterLayoutItem::dependsOnOtherParameters() const
7045 : : {
7046 : 0 : QStringList depends;
7047 : 0 : if ( !mParentLayoutParameterName.isEmpty() )
7048 : 0 : depends << mParentLayoutParameterName;
7049 : 0 : return depends;
7050 : 0 : }
7051 : :
7052 : 0 : QgsProcessingParameterLayoutItem *QgsProcessingParameterLayoutItem::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7053 : : {
7054 : 0 : QString parent;
7055 : 0 : QString def = definition;
7056 : 0 : int itemType = -1;
7057 : 0 : QRegularExpression re( QStringLiteral( "(\\d+)?\\s*(.*?)\\s+(.*)$" ) );
7058 : 0 : QRegularExpressionMatch m = re.match( def );
7059 : 0 : if ( m.hasMatch() )
7060 : : {
7061 : 0 : itemType = m.captured( 1 ).trimmed().isEmpty() ? -1 : m.captured( 1 ).trimmed().toInt();
7062 : 0 : parent = m.captured( 2 ).trimmed().isEmpty() ? m.captured( 3 ).trimmed() : m.captured( 2 ).trimmed();
7063 : 0 : def = !m.captured( 2 ).trimmed().isEmpty() ? m.captured( 3 ) : QString();
7064 : 0 : }
7065 : : else
7066 : : {
7067 : 0 : parent = def;
7068 : 0 : def.clear();
7069 : : }
7070 : :
7071 : 0 : return new QgsProcessingParameterLayoutItem( name, description, def.isEmpty() ? QVariant() : def, parent, itemType, isOptional );
7072 : 0 : }
7073 : :
7074 : 0 : QString QgsProcessingParameterLayoutItem::parentLayoutParameterName() const
7075 : : {
7076 : 0 : return mParentLayoutParameterName;
7077 : : }
7078 : :
7079 : 0 : void QgsProcessingParameterLayoutItem::setParentLayoutParameterName( const QString &name )
7080 : : {
7081 : 0 : mParentLayoutParameterName = name;
7082 : 0 : }
7083 : :
7084 : 0 : int QgsProcessingParameterLayoutItem::itemType() const
7085 : : {
7086 : 0 : return mItemType;
7087 : : }
7088 : :
7089 : 0 : void QgsProcessingParameterLayoutItem::setItemType( int type )
7090 : : {
7091 : 0 : mItemType = type;
7092 : 0 : }
7093 : :
7094 : : //
7095 : : // QgsProcessingParameterColor
7096 : : //
7097 : :
7098 : 0 : QgsProcessingParameterColor::QgsProcessingParameterColor( const QString &name, const QString &description, const QVariant &defaultValue, bool opacityEnabled, bool optional )
7099 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
7100 : 0 : , mAllowOpacity( opacityEnabled )
7101 : 0 : {
7102 : :
7103 : 0 : }
7104 : :
7105 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterColor::clone() const
7106 : : {
7107 : 0 : return new QgsProcessingParameterColor( *this );
7108 : 0 : }
7109 : :
7110 : 0 : QString QgsProcessingParameterColor::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
7111 : : {
7112 : 0 : if ( !value.isValid() || value.isNull() )
7113 : 0 : return QStringLiteral( "None" );
7114 : :
7115 : 0 : if ( value.canConvert<QgsProperty>() )
7116 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
7117 : :
7118 : 0 : if ( value.canConvert< QColor >() && !value.value< QColor >().isValid() )
7119 : 0 : return QStringLiteral( "QColor()" );
7120 : :
7121 : 0 : if ( value.canConvert< QColor >() )
7122 : : {
7123 : 0 : QColor c = value.value< QColor >();
7124 : 0 : if ( !mAllowOpacity || c.alpha() == 255 )
7125 : 0 : return QStringLiteral( "QColor(%1, %2, %3)" ).arg( c.red() ).arg( c.green() ).arg( c.blue() );
7126 : : else
7127 : 0 : return QStringLiteral( "QColor(%1, %2, %3, %4)" ).arg( c.red() ).arg( c.green() ).arg( c.blue() ).arg( c.alpha() );
7128 : : }
7129 : :
7130 : 0 : QString s = value.toString();
7131 : 0 : return QgsProcessingUtils::stringToPythonLiteral( s );
7132 : 0 : }
7133 : :
7134 : 0 : QString QgsProcessingParameterColor::asScriptCode() const
7135 : : {
7136 : 0 : QString code = QStringLiteral( "##%1=" ).arg( mName );
7137 : 0 : if ( mFlags & FlagOptional )
7138 : 0 : code += QLatin1String( "optional " );
7139 : 0 : code += QLatin1String( "color " );
7140 : :
7141 : 0 : if ( mAllowOpacity )
7142 : 0 : code += QLatin1String( "withopacity " );
7143 : :
7144 : 0 : code += mDefault.toString();
7145 : 0 : return code.trimmed();
7146 : 0 : }
7147 : :
7148 : 0 : QString QgsProcessingParameterColor::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
7149 : : {
7150 : 0 : switch ( outputType )
7151 : : {
7152 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
7153 : : {
7154 : 0 : QString code = QStringLiteral( "QgsProcessingParameterColor('%1', '%2'" ).arg( name(), description() );
7155 : 0 : if ( mFlags & FlagOptional )
7156 : 0 : code += QLatin1String( ", optional=True" );
7157 : :
7158 : 0 : code += QStringLiteral( ", opacityEnabled=%1" ).arg( mAllowOpacity ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
7159 : :
7160 : 0 : QgsProcessingContext c;
7161 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7162 : 0 : return code;
7163 : 0 : }
7164 : : }
7165 : 0 : return QString();
7166 : 0 : }
7167 : :
7168 : 0 : bool QgsProcessingParameterColor::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
7169 : : {
7170 : 0 : if ( !input.isValid() && ( mDefault.isValid() && ( !mDefault.toString().isEmpty() || mDefault.value< QColor >().isValid() ) ) )
7171 : 0 : return true;
7172 : :
7173 : 0 : if ( !input.isValid() )
7174 : 0 : return mFlags & FlagOptional;
7175 : :
7176 : 0 : if ( input.type() == QVariant::Color )
7177 : : {
7178 : 0 : return true;
7179 : : }
7180 : 0 : else if ( input.canConvert<QgsProperty>() )
7181 : : {
7182 : 0 : return true;
7183 : : }
7184 : :
7185 : 0 : if ( input.type() != QVariant::String || input.toString().isEmpty() )
7186 : 0 : return mFlags & FlagOptional;
7187 : :
7188 : 0 : bool containsAlpha = false;
7189 : 0 : return QgsSymbolLayerUtils::parseColorWithAlpha( input.toString(), containsAlpha ).isValid();
7190 : 0 : }
7191 : :
7192 : 0 : QVariantMap QgsProcessingParameterColor::toVariantMap() const
7193 : : {
7194 : 0 : QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
7195 : 0 : map.insert( QStringLiteral( "opacityEnabled" ), mAllowOpacity );
7196 : 0 : return map;
7197 : 0 : }
7198 : :
7199 : 0 : bool QgsProcessingParameterColor::fromVariantMap( const QVariantMap &map )
7200 : : {
7201 : 0 : QgsProcessingParameterDefinition::fromVariantMap( map );
7202 : 0 : mAllowOpacity = map.value( QStringLiteral( "opacityEnabled" ) ).toBool();
7203 : 0 : return true;
7204 : 0 : }
7205 : :
7206 : 0 : bool QgsProcessingParameterColor::opacityEnabled() const
7207 : : {
7208 : 0 : return mAllowOpacity;
7209 : : }
7210 : :
7211 : 0 : void QgsProcessingParameterColor::setOpacityEnabled( bool enabled )
7212 : : {
7213 : 0 : mAllowOpacity = enabled;
7214 : 0 : }
7215 : :
7216 : 0 : QgsProcessingParameterColor *QgsProcessingParameterColor::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7217 : : {
7218 : 0 : QString def = definition;
7219 : :
7220 : 0 : bool allowOpacity = false;
7221 : 0 : if ( def.startsWith( QLatin1String( "withopacity" ), Qt::CaseInsensitive ) )
7222 : : {
7223 : 0 : allowOpacity = true;
7224 : 0 : def = def.mid( 12 );
7225 : 0 : }
7226 : :
7227 : 0 : if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
7228 : 0 : def = def.mid( 1 );
7229 : 0 : if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
7230 : 0 : def.chop( 1 );
7231 : :
7232 : 0 : QVariant defaultValue = def;
7233 : 0 : if ( def == QLatin1String( "None" ) )
7234 : 0 : defaultValue = QVariant();
7235 : :
7236 : 0 : return new QgsProcessingParameterColor( name, description, defaultValue, allowOpacity, isOptional );
7237 : 0 : }
7238 : :
7239 : : //
7240 : : // QgsProcessingParameterCoordinateOperation
7241 : : //
7242 : 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 )
7243 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
7244 : 0 : , mSourceParameterName( sourceCrsParameterName )
7245 : 0 : , mDestParameterName( destinationCrsParameterName )
7246 : 0 : , mSourceCrs( staticSourceCrs )
7247 : 0 : , mDestCrs( staticDestinationCrs )
7248 : 0 : {
7249 : :
7250 : 0 : }
7251 : :
7252 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterCoordinateOperation::clone() const
7253 : : {
7254 : 0 : return new QgsProcessingParameterCoordinateOperation( * this );
7255 : 0 : }
7256 : :
7257 : 0 : QString QgsProcessingParameterCoordinateOperation::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
7258 : : {
7259 : 0 : if ( !value.isValid() || value.isNull() )
7260 : 0 : return QStringLiteral( "None" );
7261 : :
7262 : 0 : if ( value.canConvert<QgsCoordinateReferenceSystem>() )
7263 : : {
7264 : 0 : if ( !value.value< QgsCoordinateReferenceSystem >().isValid() )
7265 : 0 : return QStringLiteral( "QgsCoordinateReferenceSystem()" );
7266 : : else
7267 : 0 : return QStringLiteral( "QgsCoordinateReferenceSystem('%1')" ).arg( value.value< QgsCoordinateReferenceSystem >().authid() );
7268 : : }
7269 : :
7270 : 0 : if ( value.canConvert<QgsProperty>() )
7271 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
7272 : :
7273 : 0 : QVariantMap p;
7274 : 0 : p.insert( name(), value );
7275 : 0 : QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
7276 : 0 : if ( layer )
7277 : 0 : return QgsProcessingUtils::stringToPythonLiteral( QgsProcessingUtils::normalizeLayerSource( layer->source() ) );
7278 : :
7279 : 0 : QString s = value.toString();
7280 : 0 : return QgsProcessingUtils::stringToPythonLiteral( s );
7281 : 0 : }
7282 : :
7283 : 0 : QString QgsProcessingParameterCoordinateOperation::asScriptCode() const
7284 : : {
7285 : 0 : QString code = QStringLiteral( "##%1=" ).arg( mName );
7286 : 0 : if ( mFlags & FlagOptional )
7287 : 0 : code += QLatin1String( "optional " );
7288 : 0 : code += QLatin1String( "coordinateoperation " );
7289 : :
7290 : 0 : code += mDefault.toString();
7291 : 0 : return code.trimmed();
7292 : 0 : }
7293 : :
7294 : 0 : QString QgsProcessingParameterCoordinateOperation::asPythonString( QgsProcessing::PythonOutputType outputType ) const
7295 : : {
7296 : 0 : switch ( outputType )
7297 : : {
7298 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
7299 : : {
7300 : 0 : QgsProcessingContext c;
7301 : 0 : QString code = QStringLiteral( "QgsProcessingParameterCoordinateOperation('%1', '%2'" ).arg( name(), description() );
7302 : 0 : if ( mFlags & FlagOptional )
7303 : 0 : code += QLatin1String( ", optional=True" );
7304 : 0 : if ( !mSourceParameterName.isEmpty() )
7305 : 0 : code += QStringLiteral( ", sourceCrsParameterName=%1" ).arg( valueAsPythonString( mSourceParameterName, c ) );
7306 : 0 : if ( !mDestParameterName.isEmpty() )
7307 : 0 : code += QStringLiteral( ", destinationCrsParameterName=%1" ).arg( valueAsPythonString( mDestParameterName, c ) );
7308 : :
7309 : 0 : if ( mSourceCrs.isValid() )
7310 : 0 : code += QStringLiteral( ", staticSourceCrs=%1" ).arg( valueAsPythonString( mSourceCrs, c ) );
7311 : 0 : if ( mDestCrs.isValid() )
7312 : 0 : code += QStringLiteral( ", staticDestinationCrs=%1" ).arg( valueAsPythonString( mDestCrs, c ) );
7313 : :
7314 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7315 : 0 : return code;
7316 : 0 : }
7317 : : }
7318 : 0 : return QString();
7319 : 0 : }
7320 : :
7321 : 0 : QStringList QgsProcessingParameterCoordinateOperation::dependsOnOtherParameters() const
7322 : : {
7323 : 0 : QStringList res;
7324 : 0 : if ( !mSourceParameterName.isEmpty() )
7325 : 0 : res << mSourceParameterName;
7326 : 0 : if ( !mDestParameterName.isEmpty() )
7327 : 0 : res << mDestParameterName;
7328 : 0 : return res;
7329 : 0 : }
7330 : :
7331 : 0 : QVariantMap QgsProcessingParameterCoordinateOperation::toVariantMap() const
7332 : : {
7333 : 0 : QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
7334 : 0 : map.insert( QStringLiteral( "source_crs_parameter_name" ), mSourceParameterName );
7335 : 0 : map.insert( QStringLiteral( "dest_crs_parameter_name" ), mDestParameterName );
7336 : 0 : map.insert( QStringLiteral( "static_source_crs" ), mSourceCrs );
7337 : 0 : map.insert( QStringLiteral( "static_dest_crs" ), mDestCrs );
7338 : 0 : return map;
7339 : 0 : }
7340 : :
7341 : 0 : bool QgsProcessingParameterCoordinateOperation::fromVariantMap( const QVariantMap &map )
7342 : : {
7343 : 0 : QgsProcessingParameterDefinition::fromVariantMap( map );
7344 : 0 : mSourceParameterName = map.value( QStringLiteral( "source_crs_parameter_name" ) ).toString();
7345 : 0 : mDestParameterName = map.value( QStringLiteral( "dest_crs_parameter_name" ) ).toString();
7346 : 0 : mSourceCrs = map.value( QStringLiteral( "static_source_crs" ) );
7347 : 0 : mDestCrs = map.value( QStringLiteral( "static_dest_crs" ) );
7348 : 0 : return true;
7349 : 0 : }
7350 : :
7351 : 0 : QgsProcessingParameterCoordinateOperation *QgsProcessingParameterCoordinateOperation::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7352 : : {
7353 : 0 : QString def = definition;
7354 : :
7355 : 0 : if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
7356 : 0 : def = def.mid( 1 );
7357 : 0 : if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
7358 : 0 : def.chop( 1 );
7359 : :
7360 : 0 : QVariant defaultValue = def;
7361 : 0 : if ( def == QLatin1String( "None" ) )
7362 : 0 : defaultValue = QVariant();
7363 : :
7364 : 0 : return new QgsProcessingParameterCoordinateOperation( name, description, defaultValue, QString(), QString(), QVariant(), QVariant(), isOptional );
7365 : 0 : }
7366 : :
7367 : :
7368 : : //
7369 : : // QgsProcessingParameterMapTheme
7370 : : //
7371 : :
7372 : 0 : QgsProcessingParameterMapTheme::QgsProcessingParameterMapTheme( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
7373 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
7374 : 0 : {
7375 : :
7376 : 0 : }
7377 : :
7378 : :
7379 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterMapTheme::clone() const
7380 : : {
7381 : 0 : return new QgsProcessingParameterMapTheme( *this );
7382 : 0 : }
7383 : :
7384 : 0 : bool QgsProcessingParameterMapTheme::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
7385 : : {
7386 : 0 : if ( !input.isValid() && !mDefault.isValid() )
7387 : 0 : return mFlags & FlagOptional;
7388 : :
7389 : 0 : if ( ( input.type() == QVariant::String && input.toString().isEmpty() )
7390 : 0 : || ( !input.isValid() && mDefault.type() == QVariant::String && mDefault.toString().isEmpty() ) )
7391 : 0 : return mFlags & FlagOptional;
7392 : :
7393 : 0 : return true;
7394 : 0 : }
7395 : :
7396 : 0 : QString QgsProcessingParameterMapTheme::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
7397 : : {
7398 : 0 : if ( !value.isValid() )
7399 : 0 : return QStringLiteral( "None" );
7400 : :
7401 : 0 : if ( value.canConvert<QgsProperty>() )
7402 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
7403 : :
7404 : 0 : return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
7405 : 0 : }
7406 : :
7407 : 0 : QString QgsProcessingParameterMapTheme::asScriptCode() const
7408 : : {
7409 : 0 : QString code = QStringLiteral( "##%1=" ).arg( mName );
7410 : 0 : if ( mFlags & FlagOptional )
7411 : 0 : code += QLatin1String( "optional " );
7412 : 0 : code += QLatin1String( "maptheme " );
7413 : :
7414 : 0 : code += mDefault.toString();
7415 : 0 : return code.trimmed();
7416 : 0 : }
7417 : :
7418 : 0 : QString QgsProcessingParameterMapTheme::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
7419 : : {
7420 : 0 : switch ( outputType )
7421 : : {
7422 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
7423 : : {
7424 : 0 : QString code = QStringLiteral( "QgsProcessingParameterMapTheme('%1', '%2'" ).arg( name(), description() );
7425 : 0 : if ( mFlags & FlagOptional )
7426 : 0 : code += QLatin1String( ", optional=True" );
7427 : :
7428 : 0 : QgsProcessingContext c;
7429 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7430 : :
7431 : 0 : return code;
7432 : 0 : }
7433 : : }
7434 : 0 : return QString();
7435 : 0 : }
7436 : :
7437 : 0 : QVariantMap QgsProcessingParameterMapTheme::toVariantMap() const
7438 : : {
7439 : 0 : QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
7440 : 0 : return map;
7441 : 0 : }
7442 : :
7443 : 0 : bool QgsProcessingParameterMapTheme::fromVariantMap( const QVariantMap &map )
7444 : : {
7445 : 0 : QgsProcessingParameterDefinition::fromVariantMap( map );
7446 : 0 : return true;
7447 : : }
7448 : :
7449 : 0 : QgsProcessingParameterMapTheme *QgsProcessingParameterMapTheme::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7450 : : {
7451 : 0 : QString parent;
7452 : :
7453 : 0 : QString def = definition;
7454 : 0 : if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
7455 : 0 : def = def.mid( 1 );
7456 : 0 : if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
7457 : 0 : def.chop( 1 );
7458 : :
7459 : 0 : QVariant defaultValue = def;
7460 : :
7461 : 0 : if ( defaultValue == QLatin1String( "None" ) || defaultValue.toString().isEmpty() )
7462 : 0 : defaultValue = QVariant();
7463 : :
7464 : 0 : return new QgsProcessingParameterMapTheme( name, description, defaultValue, isOptional );
7465 : 0 : }
7466 : :
7467 : :
7468 : : //
7469 : : // QgsProcessingParameterDateTime
7470 : : //
7471 : :
7472 : 0 : QgsProcessingParameterDateTime::QgsProcessingParameterDateTime( const QString &name, const QString &description, Type type, const QVariant &defaultValue, bool optional, const QDateTime &minValue, const QDateTime &maxValue )
7473 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
7474 : 0 : , mMin( minValue )
7475 : 0 : , mMax( maxValue )
7476 : 0 : , mDataType( type )
7477 : 0 : {
7478 : 0 : if ( mMin.isValid() && mMax.isValid() && mMin >= mMax )
7479 : : {
7480 : 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" ) );
7481 : 0 : }
7482 : 0 : }
7483 : :
7484 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterDateTime::clone() const
7485 : : {
7486 : 0 : return new QgsProcessingParameterDateTime( *this );
7487 : 0 : }
7488 : :
7489 : 0 : bool QgsProcessingParameterDateTime::checkValueIsAcceptable( const QVariant &value, QgsProcessingContext * ) const
7490 : : {
7491 : 0 : QVariant input = value;
7492 : 0 : if ( !input.isValid() )
7493 : : {
7494 : 0 : if ( !defaultValue().isValid() )
7495 : 0 : return mFlags & FlagOptional;
7496 : :
7497 : 0 : input = defaultValue();
7498 : 0 : }
7499 : :
7500 : 0 : if ( input.canConvert<QgsProperty>() )
7501 : : {
7502 : 0 : return true;
7503 : : }
7504 : :
7505 : 0 : if ( input.type() != QVariant::DateTime && input.type() != QVariant::Date && input.type() != QVariant::Time && input.type() != QVariant::String )
7506 : 0 : return false;
7507 : :
7508 : 0 : if ( ( input.type() == QVariant::DateTime || input.type() == QVariant::Date ) && mDataType == Time )
7509 : 0 : return false;
7510 : :
7511 : 0 : if ( input.type() == QVariant::String )
7512 : : {
7513 : 0 : QString s = input.toString();
7514 : 0 : if ( s.isEmpty() )
7515 : 0 : return mFlags & FlagOptional;
7516 : :
7517 : 0 : input = QDateTime::fromString( s, Qt::ISODate );
7518 : 0 : if ( mDataType == Time )
7519 : : {
7520 : 0 : if ( !input.toDateTime().isValid() )
7521 : 0 : input = QTime::fromString( s );
7522 : : else
7523 : 0 : input = input.toDateTime().time();
7524 : 0 : }
7525 : 0 : }
7526 : :
7527 : 0 : if ( mDataType != Time )
7528 : : {
7529 : 0 : QDateTime res = input.toDateTime();
7530 : 0 : return res.isValid() && ( res >= mMin || !mMin.isValid() ) && ( res <= mMax || !mMax.isValid() );
7531 : 0 : }
7532 : : else
7533 : : {
7534 : 0 : QTime res = input.toTime();
7535 : 0 : return res.isValid() && ( res >= mMin.time() || !mMin.isValid() ) && ( res <= mMax.time() || !mMax.isValid() );
7536 : : }
7537 : 0 : }
7538 : :
7539 : 0 : QString QgsProcessingParameterDateTime::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
7540 : : {
7541 : 0 : if ( !value.isValid() )
7542 : 0 : return QStringLiteral( "None" );
7543 : :
7544 : 0 : if ( value.canConvert<QgsProperty>() )
7545 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
7546 : :
7547 : 0 : if ( value.type() == QVariant::DateTime )
7548 : : {
7549 : 0 : const QDateTime dt = value.toDateTime();
7550 : 0 : if ( !dt.isValid() )
7551 : 0 : return QStringLiteral( "QDateTime()" );
7552 : : else
7553 : 0 : return QStringLiteral( "QDateTime(QDate(%1, %2, %3), QTime(%4, %5, %6))" ).arg( dt.date().year() )
7554 : 0 : .arg( dt.date().month() )
7555 : 0 : .arg( dt.date().day() )
7556 : 0 : .arg( dt.time().hour() )
7557 : 0 : .arg( dt.time().minute() )
7558 : 0 : .arg( dt.time().second() );
7559 : 0 : }
7560 : 0 : else if ( value.type() == QVariant::Date )
7561 : : {
7562 : 0 : const QDate dt = value.toDate();
7563 : 0 : if ( !dt.isValid() )
7564 : 0 : return QStringLiteral( "QDate()" );
7565 : : else
7566 : 0 : return QStringLiteral( "QDate(%1, %2, %3)" ).arg( dt.year() )
7567 : 0 : .arg( dt.month() )
7568 : 0 : .arg( dt.day() );
7569 : : }
7570 : 0 : else if ( value.type() == QVariant::Time )
7571 : : {
7572 : 0 : const QTime dt = value.toTime();
7573 : 0 : if ( !dt.isValid() )
7574 : 0 : return QStringLiteral( "QTime()" );
7575 : : else
7576 : 0 : return QStringLiteral( "QTime(%4, %5, %6)" )
7577 : 0 : .arg( dt.hour() )
7578 : 0 : .arg( dt.minute() )
7579 : 0 : .arg( dt.second() );
7580 : : }
7581 : 0 : return value.toString();
7582 : 0 : }
7583 : :
7584 : 0 : QString QgsProcessingParameterDateTime::toolTip() const
7585 : : {
7586 : 0 : QString text = QgsProcessingParameterDefinition::toolTip();
7587 : 0 : QStringList parts;
7588 : 0 : if ( mMin.isValid() )
7589 : 0 : parts << QObject::tr( "Minimum value: %1" ).arg( mMin.toString( Qt::ISODate ) );
7590 : 0 : if ( mMax.isValid() )
7591 : 0 : parts << QObject::tr( "Maximum value: %1" ).arg( mMax.toString( Qt::ISODate ) );
7592 : 0 : if ( mDefault.isValid() )
7593 : 0 : parts << QObject::tr( "Default value: %1" ).arg( mDataType == DateTime ? mDefault.toDateTime().toString( Qt::ISODate ) :
7594 : 0 : ( mDataType == Date ? mDefault.toDate().toString( Qt::ISODate ) : mDefault.toTime( ).toString() ) );
7595 : 0 : QString extra = parts.join( QLatin1String( "<br />" ) );
7596 : 0 : if ( !extra.isEmpty() )
7597 : 0 : text += QStringLiteral( "<p>%1</p>" ).arg( extra );
7598 : 0 : return text;
7599 : 0 : }
7600 : :
7601 : 0 : QString QgsProcessingParameterDateTime::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
7602 : : {
7603 : 0 : switch ( outputType )
7604 : : {
7605 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
7606 : : {
7607 : 0 : QString code = QStringLiteral( "QgsProcessingParameterDateTime('%1', '%2'" ).arg( name(), description() );
7608 : 0 : if ( mFlags & FlagOptional )
7609 : 0 : code += QLatin1String( ", optional=True" );
7610 : :
7611 : 0 : code += QStringLiteral( ", type=%1" ).arg( mDataType == DateTime ? QStringLiteral( "QgsProcessingParameterDateTime.DateTime" )
7612 : 0 : : mDataType == Date ? QStringLiteral( "QgsProcessingParameterDateTime.Date" )
7613 : 0 : : QStringLiteral( "QgsProcessingParameterDateTime.Time" ) );
7614 : :
7615 : 0 : QgsProcessingContext c;
7616 : 0 : if ( mMin.isValid() )
7617 : 0 : code += QStringLiteral( ", minValue=%1" ).arg( valueAsPythonString( mMin, c ) );
7618 : 0 : if ( mMax.isValid() )
7619 : 0 : code += QStringLiteral( ", maxValue=%1" ).arg( valueAsPythonString( mMax, c ) );
7620 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7621 : 0 : return code;
7622 : 0 : }
7623 : : }
7624 : 0 : return QString();
7625 : 0 : }
7626 : :
7627 : 0 : QDateTime QgsProcessingParameterDateTime::minimum() const
7628 : : {
7629 : 0 : return mMin;
7630 : : }
7631 : :
7632 : 0 : void QgsProcessingParameterDateTime::setMinimum( const QDateTime &min )
7633 : : {
7634 : 0 : mMin = min;
7635 : 0 : }
7636 : :
7637 : 0 : QDateTime QgsProcessingParameterDateTime::maximum() const
7638 : : {
7639 : 0 : return mMax;
7640 : : }
7641 : :
7642 : 0 : void QgsProcessingParameterDateTime::setMaximum( const QDateTime &max )
7643 : : {
7644 : 0 : mMax = max;
7645 : 0 : }
7646 : :
7647 : 0 : QgsProcessingParameterDateTime::Type QgsProcessingParameterDateTime::dataType() const
7648 : : {
7649 : 0 : return mDataType;
7650 : : }
7651 : :
7652 : 0 : void QgsProcessingParameterDateTime::setDataType( Type dataType )
7653 : : {
7654 : 0 : mDataType = dataType;
7655 : 0 : }
7656 : :
7657 : 0 : QVariantMap QgsProcessingParameterDateTime::toVariantMap() const
7658 : : {
7659 : 0 : QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
7660 : 0 : map.insert( QStringLiteral( "min" ), mMin );
7661 : 0 : map.insert( QStringLiteral( "max" ), mMax );
7662 : 0 : map.insert( QStringLiteral( "data_type" ), mDataType );
7663 : 0 : return map;
7664 : 0 : }
7665 : :
7666 : 0 : bool QgsProcessingParameterDateTime::fromVariantMap( const QVariantMap &map )
7667 : : {
7668 : 0 : QgsProcessingParameterDefinition::fromVariantMap( map );
7669 : 0 : mMin = map.value( QStringLiteral( "min" ) ).toDateTime();
7670 : 0 : mMax = map.value( QStringLiteral( "max" ) ).toDateTime();
7671 : 0 : mDataType = static_cast< Type >( map.value( QStringLiteral( "data_type" ) ).toInt() );
7672 : 0 : return true;
7673 : 0 : }
7674 : :
7675 : 0 : QgsProcessingParameterDateTime *QgsProcessingParameterDateTime::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7676 : : {
7677 : 0 : return new QgsProcessingParameterDateTime( name, description, DateTime, definition.isEmpty() ? QVariant()
7678 : 0 : : ( definition.toLower().trimmed() == QLatin1String( "none" ) ? QVariant() : definition ), isOptional );
7679 : 0 : }
7680 : :
7681 : :
7682 : :
7683 : : //
7684 : : // QgsProcessingParameterProviderConnection
7685 : : //
7686 : :
7687 : 0 : QgsProcessingParameterProviderConnection::QgsProcessingParameterProviderConnection( const QString &name, const QString &description, const QString &provider, const QVariant &defaultValue, bool optional )
7688 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
7689 : 0 : , mProviderId( provider )
7690 : 0 : {
7691 : :
7692 : 0 : }
7693 : :
7694 : :
7695 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterProviderConnection::clone() const
7696 : : {
7697 : 0 : return new QgsProcessingParameterProviderConnection( *this );
7698 : 0 : }
7699 : :
7700 : 0 : bool QgsProcessingParameterProviderConnection::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
7701 : : {
7702 : 0 : if ( !input.isValid() && !mDefault.isValid() )
7703 : 0 : return mFlags & FlagOptional;
7704 : :
7705 : 0 : if ( ( input.type() == QVariant::String && input.toString().isEmpty() )
7706 : 0 : || ( !input.isValid() && mDefault.type() == QVariant::String && mDefault.toString().isEmpty() ) )
7707 : 0 : return mFlags & FlagOptional;
7708 : :
7709 : 0 : return true;
7710 : 0 : }
7711 : :
7712 : 0 : QString QgsProcessingParameterProviderConnection::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
7713 : : {
7714 : 0 : if ( !value.isValid() )
7715 : 0 : return QStringLiteral( "None" );
7716 : :
7717 : 0 : if ( value.canConvert<QgsProperty>() )
7718 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
7719 : :
7720 : 0 : return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
7721 : 0 : }
7722 : :
7723 : 0 : QString QgsProcessingParameterProviderConnection::asScriptCode() const
7724 : : {
7725 : 0 : QString code = QStringLiteral( "##%1=" ).arg( mName );
7726 : 0 : if ( mFlags & FlagOptional )
7727 : 0 : code += QLatin1String( "optional " );
7728 : 0 : code += QLatin1String( "providerconnection " );
7729 : 0 : code += mProviderId + ' ';
7730 : :
7731 : 0 : code += mDefault.toString();
7732 : 0 : return code.trimmed();
7733 : 0 : }
7734 : :
7735 : 0 : QString QgsProcessingParameterProviderConnection::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
7736 : : {
7737 : 0 : switch ( outputType )
7738 : : {
7739 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
7740 : : {
7741 : 0 : QString code = QStringLiteral( "QgsProcessingParameterProviderConnection('%1', '%2', '%3'" ).arg( name(), description(), mProviderId );
7742 : 0 : if ( mFlags & FlagOptional )
7743 : 0 : code += QLatin1String( ", optional=True" );
7744 : :
7745 : 0 : QgsProcessingContext c;
7746 : 0 : code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7747 : :
7748 : 0 : return code;
7749 : 0 : }
7750 : : }
7751 : 0 : return QString();
7752 : 0 : }
7753 : :
7754 : 0 : QVariantMap QgsProcessingParameterProviderConnection::toVariantMap() const
7755 : : {
7756 : 0 : QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
7757 : 0 : map.insert( QStringLiteral( "provider" ), mProviderId );
7758 : 0 : return map;
7759 : 0 : }
7760 : :
7761 : 0 : bool QgsProcessingParameterProviderConnection::fromVariantMap( const QVariantMap &map )
7762 : : {
7763 : 0 : QgsProcessingParameterDefinition::fromVariantMap( map );
7764 : 0 : mProviderId = map.value( QStringLiteral( "provider" ) ).toString();
7765 : 0 : return true;
7766 : 0 : }
7767 : :
7768 : 0 : QgsProcessingParameterProviderConnection *QgsProcessingParameterProviderConnection::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7769 : : {
7770 : 0 : QString parent;
7771 : :
7772 : 0 : QString def = definition;
7773 : 0 : QString provider;
7774 : 0 : if ( def.contains( ' ' ) )
7775 : : {
7776 : 0 : provider = def.left( def.indexOf( ' ' ) );
7777 : 0 : def = def.mid( def.indexOf( ' ' ) + 1 );
7778 : 0 : }
7779 : : else
7780 : : {
7781 : 0 : provider = def;
7782 : 0 : def.clear();
7783 : : }
7784 : :
7785 : 0 : if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
7786 : 0 : def = def.mid( 1 );
7787 : 0 : if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
7788 : 0 : def.chop( 1 );
7789 : :
7790 : 0 : QVariant defaultValue = def;
7791 : :
7792 : 0 : if ( defaultValue == QLatin1String( "None" ) || defaultValue.toString().isEmpty() )
7793 : 0 : defaultValue = QVariant();
7794 : :
7795 : 0 : return new QgsProcessingParameterProviderConnection( name, description, provider, defaultValue, isOptional );
7796 : 0 : }
7797 : :
7798 : :
7799 : : //
7800 : : // QgsProcessingParameterDatabaseSchema
7801 : : //
7802 : :
7803 : 0 : QgsProcessingParameterDatabaseSchema::QgsProcessingParameterDatabaseSchema( const QString &name, const QString &description, const QString &parentLayerParameterName, const QVariant &defaultValue, bool optional )
7804 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
7805 : 0 : , mParentConnectionParameterName( parentLayerParameterName )
7806 : 0 : {
7807 : :
7808 : 0 : }
7809 : :
7810 : :
7811 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterDatabaseSchema::clone() const
7812 : : {
7813 : 0 : return new QgsProcessingParameterDatabaseSchema( *this );
7814 : 0 : }
7815 : :
7816 : 0 : bool QgsProcessingParameterDatabaseSchema::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
7817 : : {
7818 : 0 : if ( !input.isValid() && !mDefault.isValid() )
7819 : 0 : return mFlags & FlagOptional;
7820 : :
7821 : 0 : if ( ( input.type() == QVariant::String && input.toString().isEmpty() )
7822 : 0 : || ( !input.isValid() && mDefault.type() == QVariant::String && mDefault.toString().isEmpty() ) )
7823 : 0 : return mFlags & FlagOptional;
7824 : :
7825 : 0 : return true;
7826 : 0 : }
7827 : :
7828 : 0 : QString QgsProcessingParameterDatabaseSchema::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
7829 : : {
7830 : 0 : if ( !value.isValid() )
7831 : 0 : return QStringLiteral( "None" );
7832 : :
7833 : 0 : if ( value.canConvert<QgsProperty>() )
7834 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
7835 : :
7836 : 0 : return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
7837 : 0 : }
7838 : :
7839 : 0 : QString QgsProcessingParameterDatabaseSchema::asScriptCode() const
7840 : : {
7841 : 0 : QString code = QStringLiteral( "##%1=" ).arg( mName );
7842 : 0 : if ( mFlags & FlagOptional )
7843 : 0 : code += QLatin1String( "optional " );
7844 : 0 : code += QLatin1String( "databaseschema " );
7845 : :
7846 : 0 : code += mParentConnectionParameterName + ' ';
7847 : :
7848 : 0 : code += mDefault.toString();
7849 : 0 : return code.trimmed();
7850 : 0 : }
7851 : :
7852 : 0 : QString QgsProcessingParameterDatabaseSchema::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
7853 : : {
7854 : 0 : switch ( outputType )
7855 : : {
7856 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
7857 : : {
7858 : 0 : QString code = QStringLiteral( "QgsProcessingParameterDatabaseSchema('%1', '%2'" ).arg( name(), description() );
7859 : 0 : if ( mFlags & FlagOptional )
7860 : 0 : code += QLatin1String( ", optional=True" );
7861 : :
7862 : 0 : code += QStringLiteral( ", connectionParameterName='%1'" ).arg( mParentConnectionParameterName );
7863 : 0 : QgsProcessingContext c;
7864 : 0 : code += QStringLiteral( ", defaultValue=%1" ).arg( valueAsPythonString( mDefault, c ) );
7865 : :
7866 : 0 : code += ')';
7867 : :
7868 : 0 : return code;
7869 : 0 : }
7870 : : }
7871 : 0 : return QString();
7872 : 0 : }
7873 : :
7874 : 0 : QStringList QgsProcessingParameterDatabaseSchema::dependsOnOtherParameters() const
7875 : : {
7876 : 0 : QStringList depends;
7877 : 0 : if ( !mParentConnectionParameterName.isEmpty() )
7878 : 0 : depends << mParentConnectionParameterName;
7879 : 0 : return depends;
7880 : 0 : }
7881 : :
7882 : 0 : QString QgsProcessingParameterDatabaseSchema::parentConnectionParameterName() const
7883 : : {
7884 : 0 : return mParentConnectionParameterName;
7885 : : }
7886 : :
7887 : 0 : void QgsProcessingParameterDatabaseSchema::setParentConnectionParameterName( const QString &name )
7888 : : {
7889 : 0 : mParentConnectionParameterName = name;
7890 : 0 : }
7891 : :
7892 : 0 : QVariantMap QgsProcessingParameterDatabaseSchema::toVariantMap() const
7893 : : {
7894 : 0 : QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
7895 : 0 : map.insert( QStringLiteral( "mParentConnectionParameterName" ), mParentConnectionParameterName );
7896 : 0 : return map;
7897 : 0 : }
7898 : :
7899 : 0 : bool QgsProcessingParameterDatabaseSchema::fromVariantMap( const QVariantMap &map )
7900 : : {
7901 : 0 : QgsProcessingParameterDefinition::fromVariantMap( map );
7902 : 0 : mParentConnectionParameterName = map.value( QStringLiteral( "mParentConnectionParameterName" ) ).toString();
7903 : 0 : return true;
7904 : 0 : }
7905 : :
7906 : 0 : QgsProcessingParameterDatabaseSchema *QgsProcessingParameterDatabaseSchema::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7907 : : {
7908 : 0 : QString parent;
7909 : 0 : QString def = definition;
7910 : :
7911 : 0 : QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*)$" ) );
7912 : 0 : QRegularExpressionMatch m = re.match( def );
7913 : 0 : if ( m.hasMatch() )
7914 : : {
7915 : 0 : parent = m.captured( 1 ).trimmed();
7916 : 0 : def = m.captured( 2 );
7917 : 0 : }
7918 : : else
7919 : : {
7920 : 0 : parent = def;
7921 : 0 : def.clear();
7922 : : }
7923 : :
7924 : 0 : return new QgsProcessingParameterDatabaseSchema( name, description, parent, def.isEmpty() ? QVariant() : def, isOptional );
7925 : 0 : }
7926 : :
7927 : : //
7928 : : // QgsProcessingParameterDatabaseTable
7929 : : //
7930 : :
7931 : 0 : QgsProcessingParameterDatabaseTable::QgsProcessingParameterDatabaseTable( const QString &name, const QString &description,
7932 : : const QString &connectionParameterName,
7933 : : const QString &schemaParameterName,
7934 : : const QVariant &defaultValue, bool optional, bool allowNewTableNames )
7935 : 0 : : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
7936 : 0 : , mParentConnectionParameterName( connectionParameterName )
7937 : 0 : , mParentSchemaParameterName( schemaParameterName )
7938 : 0 : , mAllowNewTableNames( allowNewTableNames )
7939 : 0 : {
7940 : :
7941 : 0 : }
7942 : :
7943 : :
7944 : 0 : QgsProcessingParameterDefinition *QgsProcessingParameterDatabaseTable::clone() const
7945 : : {
7946 : 0 : return new QgsProcessingParameterDatabaseTable( *this );
7947 : 0 : }
7948 : :
7949 : 0 : bool QgsProcessingParameterDatabaseTable::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
7950 : : {
7951 : 0 : if ( !input.isValid() && !mDefault.isValid() )
7952 : 0 : return mFlags & FlagOptional;
7953 : :
7954 : 0 : if ( ( input.type() == QVariant::String && input.toString().isEmpty() )
7955 : 0 : || ( !input.isValid() && mDefault.type() == QVariant::String && mDefault.toString().isEmpty() ) )
7956 : 0 : return mFlags & FlagOptional;
7957 : :
7958 : 0 : return true;
7959 : 0 : }
7960 : :
7961 : 0 : QString QgsProcessingParameterDatabaseTable::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
7962 : : {
7963 : 0 : if ( !value.isValid() )
7964 : 0 : return QStringLiteral( "None" );
7965 : :
7966 : 0 : if ( value.canConvert<QgsProperty>() )
7967 : 0 : return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
7968 : :
7969 : 0 : return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
7970 : 0 : }
7971 : :
7972 : 0 : QString QgsProcessingParameterDatabaseTable::asScriptCode() const
7973 : : {
7974 : 0 : QString code = QStringLiteral( "##%1=" ).arg( mName );
7975 : 0 : if ( mFlags & FlagOptional )
7976 : 0 : code += QLatin1String( "optional " );
7977 : 0 : code += QLatin1String( "databasetable " );
7978 : :
7979 : 0 : code += ( mParentConnectionParameterName.isEmpty() ? QStringLiteral( "none" ) : mParentConnectionParameterName ) + ' ';
7980 : 0 : code += ( mParentSchemaParameterName.isEmpty() ? QStringLiteral( "none" ) : mParentSchemaParameterName ) + ' ';
7981 : :
7982 : 0 : code += mDefault.toString();
7983 : 0 : return code.trimmed();
7984 : 0 : }
7985 : :
7986 : 0 : QString QgsProcessingParameterDatabaseTable::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
7987 : : {
7988 : 0 : switch ( outputType )
7989 : : {
7990 : : case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
7991 : : {
7992 : 0 : QString code = QStringLiteral( "QgsProcessingParameterDatabaseTable('%1', '%2'" ).arg( name(), description() );
7993 : 0 : if ( mFlags & FlagOptional )
7994 : 0 : code += QLatin1String( ", optional=True" );
7995 : :
7996 : 0 : if ( mAllowNewTableNames )
7997 : 0 : code += QLatin1String( ", allowNewTableNames=True" );
7998 : :
7999 : 0 : code += QStringLiteral( ", connectionParameterName='%1'" ).arg( mParentConnectionParameterName );
8000 : 0 : code += QStringLiteral( ", schemaParameterName='%1'" ).arg( mParentSchemaParameterName );
8001 : 0 : QgsProcessingContext c;
8002 : 0 : code += QStringLiteral( ", defaultValue=%1" ).arg( valueAsPythonString( mDefault, c ) );
8003 : :
8004 : 0 : code += ')';
8005 : :
8006 : 0 : return code;
8007 : 0 : }
8008 : : }
8009 : 0 : return QString();
8010 : 0 : }
8011 : :
8012 : 0 : QStringList QgsProcessingParameterDatabaseTable::dependsOnOtherParameters() const
8013 : : {
8014 : 0 : QStringList depends;
8015 : 0 : if ( !mParentConnectionParameterName.isEmpty() )
8016 : 0 : depends << mParentConnectionParameterName;
8017 : 0 : if ( !mParentSchemaParameterName.isEmpty() )
8018 : 0 : depends << mParentSchemaParameterName;
8019 : 0 : return depends;
8020 : 0 : }
8021 : :
8022 : 0 : QString QgsProcessingParameterDatabaseTable::parentConnectionParameterName() const
8023 : : {
8024 : 0 : return mParentConnectionParameterName;
8025 : : }
8026 : :
8027 : 0 : void QgsProcessingParameterDatabaseTable::setParentConnectionParameterName( const QString &name )
8028 : : {
8029 : 0 : mParentConnectionParameterName = name;
8030 : 0 : }
8031 : :
8032 : 0 : QString QgsProcessingParameterDatabaseTable::parentSchemaParameterName() const
8033 : : {
8034 : 0 : return mParentSchemaParameterName;
8035 : : }
8036 : :
8037 : 0 : void QgsProcessingParameterDatabaseTable::setParentSchemaParameterName( const QString &name )
8038 : : {
8039 : 0 : mParentSchemaParameterName = name;
8040 : 0 : }
8041 : :
8042 : 0 : QVariantMap QgsProcessingParameterDatabaseTable::toVariantMap() const
8043 : : {
8044 : 0 : QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
8045 : 0 : map.insert( QStringLiteral( "mParentConnectionParameterName" ), mParentConnectionParameterName );
8046 : 0 : map.insert( QStringLiteral( "mParentSchemaParameterName" ), mParentSchemaParameterName );
8047 : 0 : map.insert( QStringLiteral( "mAllowNewTableNames" ), mAllowNewTableNames );
8048 : 0 : return map;
8049 : 0 : }
8050 : :
8051 : 0 : bool QgsProcessingParameterDatabaseTable::fromVariantMap( const QVariantMap &map )
8052 : : {
8053 : 0 : QgsProcessingParameterDefinition::fromVariantMap( map );
8054 : 0 : mParentConnectionParameterName = map.value( QStringLiteral( "mParentConnectionParameterName" ) ).toString();
8055 : 0 : mParentSchemaParameterName = map.value( QStringLiteral( "mParentSchemaParameterName" ) ).toString();
8056 : 0 : mAllowNewTableNames = map.value( QStringLiteral( "mAllowNewTableNames" ), false ).toBool();
8057 : 0 : return true;
8058 : 0 : }
8059 : :
8060 : 0 : QgsProcessingParameterDatabaseTable *QgsProcessingParameterDatabaseTable::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
8061 : : {
8062 : 0 : QString connection;
8063 : 0 : QString schema;
8064 : 0 : QString def = definition;
8065 : :
8066 : 0 : QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*+)\\b\\s*(.*)$" ) );
8067 : 0 : QRegularExpressionMatch m = re.match( def );
8068 : 0 : if ( m.hasMatch() )
8069 : : {
8070 : 0 : connection = m.captured( 1 ).trimmed();
8071 : 0 : if ( connection == QLatin1String( "none" ) )
8072 : 0 : connection.clear();
8073 : 0 : schema = m.captured( 2 ).trimmed();
8074 : 0 : if ( schema == QLatin1String( "none" ) )
8075 : 0 : schema.clear();
8076 : 0 : def = m.captured( 3 );
8077 : 0 : }
8078 : :
8079 : 0 : return new QgsProcessingParameterDatabaseTable( name, description, connection, schema, def.isEmpty() ? QVariant() : def, isOptional );
8080 : 0 : }
8081 : :
8082 : 0 : bool QgsProcessingParameterDatabaseTable::allowNewTableNames() const
8083 : : {
8084 : 0 : return mAllowNewTableNames;
8085 : : }
8086 : :
8087 : 0 : void QgsProcessingParameterDatabaseTable::setAllowNewTableNames( bool allowNewTableNames )
8088 : : {
8089 : 0 : mAllowNewTableNames = allowNewTableNames;
8090 : 0 : }
|