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

Generated by: LCOV version 1.14