LCOV - code coverage report
Current view: top level - core/processing - qgsprocessingparameters.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 16 5062 0.3 %
Date: 2021-04-10 08:29:14 Functions: 0 0 -
Branches: 0 0 -

           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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 &parameters, 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 : }

Generated by: LCOV version 1.14