diff --git a/src/analysis/processing/qgsmetadataalgorithms.cpp b/src/analysis/processing/qgsmetadataalgorithms.cpp index 12d6205ee7dc..3ef7d07b8f88 100644 --- a/src/analysis/processing/qgsmetadataalgorithms.cpp +++ b/src/analysis/processing/qgsmetadataalgorithms.cpp @@ -46,7 +46,7 @@ QString QgsCopyLayerMetadataAlgorithm::groupId() const QString QgsCopyLayerMetadataAlgorithm::shortHelpString() const { - return QObject::tr( "Copies metadata from an input layer to a target layer.\n\nAny existing metadata in the target layer will be replaced." ); + return QObject::tr( "Copies metadata from an source layer to a target layer.\n\nAny existing metadata in the target layer will be replaced." ); } QgsCopyLayerMetadataAlgorithm *QgsCopyLayerMetadataAlgorithm::createInstance() const @@ -56,7 +56,7 @@ QgsCopyLayerMetadataAlgorithm *QgsCopyLayerMetadataAlgorithm::createInstance() c void QgsCopyLayerMetadataAlgorithm::initAlgorithm( const QVariantMap & ) { - addParameter( new QgsProcessingParameterMapLayer( QStringLiteral( "INPUT" ), QObject::tr( "Source layer" ) ) ); + addParameter( new QgsProcessingParameterMapLayer( QStringLiteral( "SOURCE" ), QObject::tr( "Source layer" ) ) ); addParameter( new QgsProcessingParameterMapLayer( QStringLiteral( "TARGET" ), QObject::tr( "Target layer" ) ) ); addParameter( new QgsProcessingParameterBoolean( QStringLiteral( "DEFAULT" ), QObject::tr( "Save metadata as default" ), false ) ); addOutput( new QgsProcessingOutputMapLayer( QStringLiteral( "OUTPUT" ), QObject::tr( "Updated layer" ) ) ); @@ -64,19 +64,19 @@ void QgsCopyLayerMetadataAlgorithm::initAlgorithm( const QVariantMap & ) bool QgsCopyLayerMetadataAlgorithm::prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback * ) { - QgsMapLayer *inputLayer = parameterAsLayer( parameters, QStringLiteral( "INPUT" ), context ); + QgsMapLayer *sourceLayer = parameterAsLayer( parameters, QStringLiteral( "SOURCE" ), context ); QgsMapLayer *targetLayer = parameterAsLayer( parameters, QStringLiteral( "TARGET" ), context ); const bool saveAsDefault = parameterAsBool( parameters, QStringLiteral( "DEFAULT" ), context ); - if ( !inputLayer ) - throw QgsProcessingException( QObject::tr( "Invalid input layer" ) ); + if ( !sourceLayer ) + throw QgsProcessingException( QObject::tr( "Invalid source layer" ) ); if ( !targetLayer ) throw QgsProcessingException( QObject::tr( "Invalid target layer" ) ); mLayerId = targetLayer->id(); - targetLayer->setMetadata( inputLayer->metadata() ); + targetLayer->setMetadata( sourceLayer->metadata() ); if ( saveAsDefault ) { bool ok; @@ -248,4 +248,311 @@ QVariantMap QgsExportLayerMetadataAlgorithm::processAlgorithm( const QVariantMap return results; } +/// + +QString QgsAddHistoryMetadataAlgorithm::name() const +{ + return QStringLiteral( "addhistorymetadata" ); +} + +QString QgsAddHistoryMetadataAlgorithm::displayName() const +{ + return QObject::tr( "Add history metadata" ); +} + +QStringList QgsAddHistoryMetadataAlgorithm::tags() const +{ + return QObject::tr( "add,history,metadata" ).split( ',' ); +} + +QString QgsAddHistoryMetadataAlgorithm::group() const +{ + return QObject::tr( "Metadata tools" ); +} + +QString QgsAddHistoryMetadataAlgorithm::groupId() const +{ + return QStringLiteral( "metadatatools" ); +} + +QString QgsAddHistoryMetadataAlgorithm::shortHelpString() const +{ + return QObject::tr( "Adds a new history entry to the layer's metadata." ); +} + +QgsAddHistoryMetadataAlgorithm *QgsAddHistoryMetadataAlgorithm::createInstance() const +{ + return new QgsAddHistoryMetadataAlgorithm(); +} + +void QgsAddHistoryMetadataAlgorithm::initAlgorithm( const QVariantMap & ) +{ + addParameter( new QgsProcessingParameterMapLayer( QStringLiteral( "INPUT" ), QObject::tr( "Layer" ) ) ); + addParameter( new QgsProcessingParameterString( QStringLiteral( "HISTORY" ), QObject::tr( "History entry" ) ) ); + addOutput( new QgsProcessingOutputMapLayer( QStringLiteral( "OUTPUT" ), QObject::tr( "Updated" ) ) ); +} + +bool QgsAddHistoryMetadataAlgorithm::prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback * ) +{ + QgsMapLayer *layer = parameterAsLayer( parameters, QStringLiteral( "INPUT" ), context ); + const QString history = parameterAsString( parameters, QStringLiteral( "HISTORY" ), context ); + + if ( !layer ) + throw QgsProcessingException( QObject::tr( "Invalid input layer" ) ); + + mLayerId = layer->id(); + + std::unique_ptr md( layer->metadata().clone() ); + md->addHistoryItem( history ); + layer->setMetadata( *md.get() ); + + return true; +} + +QVariantMap QgsAddHistoryMetadataAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback * ) +{ + Q_UNUSED( parameters ); + Q_UNUSED( context ); + + QVariantMap results; + results.insert( QStringLiteral( "OUTPUT" ), mLayerId ); + return results; +} + +/// + +QString QgsUpdateLayerMetadataAlgorithm::name() const +{ + return QStringLiteral( "updatelayermetadata" ); +} + +QString QgsUpdateLayerMetadataAlgorithm::displayName() const +{ + return QObject::tr( "Update layer metadata" ); +} + +QStringList QgsUpdateLayerMetadataAlgorithm::tags() const +{ + return QObject::tr( "change,update,layer,metadata,qmd" ).split( ',' ); +} + +QString QgsUpdateLayerMetadataAlgorithm::group() const +{ + return QObject::tr( "Metadata tools" ); +} + +QString QgsUpdateLayerMetadataAlgorithm::groupId() const +{ + return QStringLiteral( "metadatatools" ); +} + +QString QgsUpdateLayerMetadataAlgorithm::shortHelpString() const +{ + return QObject::tr( "Copies all non-empty metadata fields from an source layer to a target layer.\n\nLeaves empty input fields unchanged in the target." ); +} + +QgsUpdateLayerMetadataAlgorithm *QgsUpdateLayerMetadataAlgorithm::createInstance() const +{ + return new QgsUpdateLayerMetadataAlgorithm(); +} + +void QgsUpdateLayerMetadataAlgorithm::initAlgorithm( const QVariantMap & ) +{ + addParameter( new QgsProcessingParameterMapLayer( QStringLiteral( "SOURCE" ), QObject::tr( "Source layer" ) ) ); + addParameter( new QgsProcessingParameterMapLayer( QStringLiteral( "TARGET" ), QObject::tr( "Target layer" ) ) ); + addOutput( new QgsProcessingOutputMapLayer( QStringLiteral( "OUTPUT" ), QObject::tr( "Updated layer" ) ) ); +} + +bool QgsUpdateLayerMetadataAlgorithm::prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback * ) +{ + QgsMapLayer *sourceLayer = parameterAsLayer( parameters, QStringLiteral( "SOURCE" ), context ); + QgsMapLayer *targetLayer = parameterAsLayer( parameters, QStringLiteral( "TARGET" ), context ); + + if ( !sourceLayer ) + throw QgsProcessingException( QObject::tr( "Invalid source layer" ) ); + + if ( !targetLayer ) + throw QgsProcessingException( QObject::tr( "Invalid target layer" ) ); + + mLayerId = targetLayer->id(); + + std::unique_ptr md( targetLayer->metadata().clone() ); + md->combine( &sourceLayer->metadata() ); + targetLayer->setMetadata( *md.get() ); + + return true; +} + +QVariantMap QgsUpdateLayerMetadataAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback * ) +{ + Q_UNUSED( parameters ); + Q_UNUSED( context ); + + QVariantMap results; + results.insert( QStringLiteral( "OUTPUT" ), mLayerId ); + return results; +} + +/// + +QString QgsSetMetadataFieldsAlgorithm::name() const +{ + return QStringLiteral( "setmetadatafields" ); +} + +QString QgsSetMetadataFieldsAlgorithm::displayName() const +{ + return QObject::tr( "Set metadata fields" ); +} + +QStringList QgsSetMetadataFieldsAlgorithm::tags() const +{ + return QObject::tr( "set,metadata,title,abstract,identifier" ).split( ',' ); +} + +QString QgsSetMetadataFieldsAlgorithm::group() const +{ + return QObject::tr( "Metadata tools" ); +} + +QString QgsSetMetadataFieldsAlgorithm::groupId() const +{ + return QStringLiteral( "metadatatools" ); +} + +QString QgsSetMetadataFieldsAlgorithm::shortHelpString() const +{ + return QObject::tr( "Sets various metadata fields for a layer." ); +} + +QgsSetMetadataFieldsAlgorithm *QgsSetMetadataFieldsAlgorithm::createInstance() const +{ + return new QgsSetMetadataFieldsAlgorithm(); +} + +void QgsSetMetadataFieldsAlgorithm::initAlgorithm( const QVariantMap & ) +{ + addParameter( new QgsProcessingParameterMapLayer( QStringLiteral( "INPUT" ), QObject::tr( "Layer" ) ) ); + addParameter( new QgsProcessingParameterString( QStringLiteral( "IDENTIFIER" ), QObject::tr( "Identifier" ), QVariant(), false, true ) ); + addParameter( new QgsProcessingParameterString( QStringLiteral( "PARENT_IDENTIFIER" ), QObject::tr( "Parent identifier" ), QVariant(), false, true ) ); + addParameter( new QgsProcessingParameterString( QStringLiteral( "TITLE" ), QObject::tr( "Title" ), QVariant(), false, true ) ); + addParameter( new QgsProcessingParameterString( QStringLiteral( "TYPE" ), QObject::tr( "Type" ), QVariant(), false, true ) ); + addParameter( new QgsProcessingParameterString( QStringLiteral( "LANGUAGE" ), QObject::tr( "Language" ), QVariant(), false, true ) ); + addParameter( new QgsProcessingParameterString( QStringLiteral( "ENCODING" ), QObject::tr( "Encoding" ), QVariant(), false, true ) ); + addParameter( new QgsProcessingParameterString( QStringLiteral( "ABSTRACT" ), QObject::tr( "Abstract" ), QVariant(), true, true ) ); + addParameter( new QgsProcessingParameterCrs( QStringLiteral( "CRS" ), QObject::tr( "Coordinatem reference system" ), QVariant(), true ) ); + addParameter( new QgsProcessingParameterString( QStringLiteral( "FEES" ), QObject::tr( "Fees" ), QVariant(), false, true ) ); + addParameter( new QgsProcessingParameterBoolean( QStringLiteral( "IGNORE_EMPTY" ), QObject::tr( "Ignore empty fields" ), false ) ); + addOutput( new QgsProcessingOutputMapLayer( QStringLiteral( "OUTPUT" ), QObject::tr( "Updated" ) ) ); +} + +bool QgsSetMetadataFieldsAlgorithm::prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback * ) +{ + QgsMapLayer *layer = parameterAsLayer( parameters, QStringLiteral( "INPUT" ), context ); + + if ( !layer ) + throw QgsProcessingException( QObject::tr( "Invalid input layer" ) ); + + mLayerId = layer->id(); + + const bool ignoreEmpty = parameterAsBool( parameters, QStringLiteral( "IGNORE_EMPTY" ), context ); + + std::unique_ptr md( layer->metadata().clone() ); + + if ( parameters.value( QStringLiteral( "IDENTIFIER" ) ).isValid() ) + { + const QString identifier = parameterAsString( parameters, QStringLiteral( "IDENTIFIER" ), context ); + if ( !identifier.isEmpty() || !ignoreEmpty ) + { + md->setIdentifier( identifier ); + } + } + + if ( parameters.value( QStringLiteral( "PARENT_IDENTIFIER" ) ).isValid() ) + { + const QString parentIdentifier = parameterAsString( parameters, QStringLiteral( "PARENT_IDENTIFIER" ), context ); + if ( !parentIdentifier.isEmpty() || !ignoreEmpty ) + { + md->setParentIdentifier( parentIdentifier ); + } + } + + if ( parameters.value( QStringLiteral( "TITLE" ) ).isValid() ) + { + const QString title = parameterAsString( parameters, QStringLiteral( "TITLE" ), context ); + if ( !title.isEmpty() || !ignoreEmpty ) + { + md->setTitle( title ); + } + } + + if ( parameters.value( QStringLiteral( "TYPE" ) ).isValid() ) + { + const QString type = parameterAsString( parameters, QStringLiteral( "TYPE" ), context ); + if ( !type.isEmpty() || !ignoreEmpty ) + { + md->setType( type ); + } + } + + if ( parameters.value( QStringLiteral( "LANGUAGE" ) ).isValid() ) + { + const QString language = parameterAsString( parameters, QStringLiteral( "LANGUAGE" ), context ); + if ( !language.isEmpty() || !ignoreEmpty ) + { + md->setLanguage( language ); + } + } + + if ( parameters.value( QStringLiteral( "ENCODING" ) ).isValid() ) + { + const QString encoding = parameterAsString( parameters, QStringLiteral( "ENCODING" ), context ); + if ( !encoding.isEmpty() || !ignoreEmpty ) + { + md->setEncoding( encoding ); + } + } + + if ( parameters.value( QStringLiteral( "ABSTRACT" ) ).isValid() ) + { + const QString abstract = parameterAsString( parameters, QStringLiteral( "ABSTRACT" ), context ); + if ( !abstract.isEmpty() || !ignoreEmpty ) + { + md->setAbstract( abstract ); + } + } + + if ( parameters.value( QStringLiteral( "CRS" ) ).isValid() ) + { + const QgsCoordinateReferenceSystem crs = parameterAsCrs( parameters, QStringLiteral( "CRS" ), context ); + if ( crs.isValid() || !ignoreEmpty ) + { + md->setCrs( crs ); + } + } + + if ( parameters.value( QStringLiteral( "FEES" ) ).isValid() ) + { + const QString fees = parameterAsString( parameters, QStringLiteral( "FEES" ), context ); + if ( !fees.isEmpty() || !ignoreEmpty ) + { + md->setFees( fees ); + } + } + + layer->setMetadata( *md.get() ); + + return true; +} + +QVariantMap QgsSetMetadataFieldsAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback * ) +{ + Q_UNUSED( parameters ); + Q_UNUSED( context ); + + QVariantMap results; + results.insert( QStringLiteral( "OUTPUT" ), mLayerId ); + return results; +} + ///@endcond diff --git a/src/analysis/processing/qgsmetadataalgorithms.h b/src/analysis/processing/qgsmetadataalgorithms.h index fe0b98b397da..04363b272406 100644 --- a/src/analysis/processing/qgsmetadataalgorithms.h +++ b/src/analysis/processing/qgsmetadataalgorithms.h @@ -73,7 +73,6 @@ class QgsApplyLayerMetadataAlgorithm : public QgsProcessingAlgorithm QString mLayerId; }; - /** * Native export layer metadata algorithm. */ @@ -97,6 +96,79 @@ class QgsExportLayerMetadataAlgorithm : public QgsProcessingAlgorithm QString mLayerId; }; +/** + * Native add history metadata algorithm. + */ +class QgsAddHistoryMetadataAlgorithm : public QgsProcessingAlgorithm +{ + public: + QgsAddHistoryMetadataAlgorithm() = default; + QString name() const override; + QString displayName() const override; + QStringList tags() const override; + QString group() const override; + QString groupId() const override; + QString shortHelpString() const override; + void initAlgorithm( const QVariantMap &configuration = QVariantMap() ) override; + QgsAddHistoryMetadataAlgorithm *createInstance() const override SIP_FACTORY; + + protected: + bool prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override; + QVariantMap processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback * ) override; + + private: + QString mLayerId; +}; + +/** + * Native update layer metadata algorithm. + */ +class QgsUpdateLayerMetadataAlgorithm : public QgsProcessingAlgorithm +{ + public: + QgsUpdateLayerMetadataAlgorithm() = default; + QString name() const override; + QString displayName() const override; + QStringList tags() const override; + QString group() const override; + QString groupId() const override; + QString shortHelpString() const override; + void initAlgorithm( const QVariantMap &configuration = QVariantMap() ) override; + QgsUpdateLayerMetadataAlgorithm *createInstance() const override SIP_FACTORY; + + protected: + bool prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override; + QVariantMap processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback * ) override; + + private: + QString mLayerId; +}; + + +/** + * Native set metadata fields algorithm. + */ +class QgsSetMetadataFieldsAlgorithm : public QgsProcessingAlgorithm +{ + public: + QgsSetMetadataFieldsAlgorithm() = default; + QString name() const override; + QString displayName() const override; + QStringList tags() const override; + QString group() const override; + QString groupId() const override; + QString shortHelpString() const override; + void initAlgorithm( const QVariantMap &configuration = QVariantMap() ) override; + QgsSetMetadataFieldsAlgorithm *createInstance() const override SIP_FACTORY; + + protected: + bool prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override; + QVariantMap processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback * ) override; + + private: + QString mLayerId; +}; + ///@endcond PRIVATE #endif // QGSMETADATAALGORITHMS_H diff --git a/src/analysis/processing/qgsnativealgorithms.cpp b/src/analysis/processing/qgsnativealgorithms.cpp index 279ea909782b..297ec61ecfaf 100644 --- a/src/analysis/processing/qgsnativealgorithms.cpp +++ b/src/analysis/processing/qgsnativealgorithms.cpp @@ -292,6 +292,7 @@ Qgis::ProcessingProviderFlags QgsNativeAlgorithms::flags() const void QgsNativeAlgorithms::loadAlgorithms() { const QgsScopedRuntimeProfile profile( QObject::tr( "QGIS native provider" ) ); + addAlgorithm( new QgsAddHistoryMetadataAlgorithm() ); addAlgorithm( new QgsAddIncrementalFieldAlgorithm() ); addAlgorithm( new QgsAddTableFieldAlgorithm() ); addAlgorithm( new QgsAddXYFieldsAlgorithm() ); @@ -519,6 +520,7 @@ void QgsNativeAlgorithms::loadAlgorithms() addAlgorithm( new QgsServiceAreaFromLayerAlgorithm() ); addAlgorithm( new QgsServiceAreaFromPointAlgorithm() ); addAlgorithm( new QgsSetLayerEncodingAlgorithm() ); + addAlgorithm( new QgsSetMetadataFieldsAlgorithm() ); addAlgorithm( new QgsSetMValueAlgorithm() ); addAlgorithm( new QgsSetProjectVariableAlgorithm() ); addAlgorithm( new QgsSetZValueAlgorithm() ); @@ -554,6 +556,7 @@ void QgsNativeAlgorithms::loadAlgorithms() addAlgorithm( new QgsTranslateAlgorithm() ); addAlgorithm( new QgsTruncateTableAlgorithm() ); addAlgorithm( new QgsUnionAlgorithm() ); + addAlgorithm( new QgsUpdateLayerMetadataAlgorithm() ); addAlgorithm( new QgsOpenUrlAlgorithm() ); addAlgorithm( new QgsHttpRequestAlgorithm() ); addAlgorithm( new QgsVariableWidthBufferByMAlgorithm() ); diff --git a/tests/src/analysis/testqgsprocessingalgspt2.cpp b/tests/src/analysis/testqgsprocessingalgspt2.cpp index 424907fd6ff9..26514b47392c 100644 --- a/tests/src/analysis/testqgsprocessingalgspt2.cpp +++ b/tests/src/analysis/testqgsprocessingalgspt2.cpp @@ -107,6 +107,9 @@ class TestQgsProcessingAlgsPt2 : public QgsTest void copyMetadata(); void applyMetadata(); void exportMetadata(); + void addHistoryMetadata(); + void updateMetadata(); + void setMetadataFields(); private: QString mPointLayerPath; @@ -1882,8 +1885,8 @@ void TestQgsProcessingAlgsPt2::generateElevationProfileImage() void TestQgsProcessingAlgsPt2::copyMetadata() { - std::unique_ptr inputLayer = std::make_unique( QStringLiteral( "Point?crs=epsg:4326&field=pk:int&field=col1:string" ), QStringLiteral( "input" ), QStringLiteral( "memory" ) ); - QVERIFY( inputLayer->isValid() ); + std::unique_ptr sourceLayer = std::make_unique( QStringLiteral( "Point?crs=epsg:4326&field=pk:int&field=col1:string" ), QStringLiteral( "input" ), QStringLiteral( "memory" ) ); + QVERIFY( sourceLayer->isValid() ); std::unique_ptr targetLayer = std::make_unique( QStringLiteral( "Point?crs=epsg:4326&field=pk:int&field=col1:string" ), QStringLiteral( "target" ), QStringLiteral( "memory" ) ); QVERIFY( targetLayer->isValid() ); @@ -1891,13 +1894,13 @@ void TestQgsProcessingAlgsPt2::copyMetadata() QgsLayerMetadata md; md.setTitle( QStringLiteral( "Title" ) ); md.setAbstract( QStringLiteral( "Abstract" ) ); - inputLayer->setMetadata( md ); + sourceLayer->setMetadata( md ); std::unique_ptr alg( QgsApplication::processingRegistry()->createAlgorithmById( QStringLiteral( "native:copylayermetadata" ) ) ); QVERIFY( alg != nullptr ); QVariantMap parameters; - parameters.insert( QStringLiteral( "INPUT" ), QVariant::fromValue( inputLayer.get() ) ); + parameters.insert( QStringLiteral( "SOURCE" ), QVariant::fromValue( sourceLayer.get() ) ); parameters.insert( QStringLiteral( "TARGET" ), QVariant::fromValue( targetLayer.get() ) ); bool ok = false; @@ -1988,6 +1991,160 @@ void TestQgsProcessingAlgsPt2::exportMetadata() QCOMPARE( md.abstract(), exportedMetadata.abstract() ); } +void TestQgsProcessingAlgsPt2::addHistoryMetadata() +{ + std::unique_ptr layer = std::make_unique( QStringLiteral( "Point?crs=epsg:4326&field=pk:int&field=col1:string" ), QStringLiteral( "input" ), QStringLiteral( "memory" ) ); + QVERIFY( layer->isValid() ); + + QgsLayerMetadata md; + md.setTitle( QStringLiteral( "Title" ) ); + md.setAbstract( QStringLiteral( "Abstract" ) ); + layer->setMetadata( md ); + + std::unique_ptr alg( QgsApplication::processingRegistry()->createAlgorithmById( QStringLiteral( "native:addhistorymetadata" ) ) ); + QVERIFY( alg != nullptr ); + + QVariantMap parameters; + parameters.insert( QStringLiteral( "INPUT" ), QVariant::fromValue( layer.get() ) ); + parameters.insert( QStringLiteral( "HISTORY" ), QStringLiteral( "do something" ) ); + + bool ok = false; + std::unique_ptr context = std::make_unique(); + QgsProcessingFeedback feedback; + QVariantMap results; + results = alg->run( parameters, *context, &feedback, &ok ); + QVERIFY( ok ); + + QCOMPARE( results.value( QStringLiteral( "OUTPUT" ) ), layer->id() ); + + QStringList history = layer->metadata().history(); + QCOMPARE( history.count(), 1 ); + QCOMPARE( history.at( 0 ), QStringLiteral( "do something" ) ); + + parameters[QStringLiteral( "HISTORY" )] = QStringLiteral( "do something else" ); + + ok = false; + results = alg->run( parameters, *context, &feedback, &ok ); + QVERIFY( ok ); + + QCOMPARE( results.value( QStringLiteral( "OUTPUT" ) ), layer->id() ); + + history = layer->metadata().history(); + QCOMPARE( history.count(), 2 ); + QCOMPARE( history.at( 0 ), QStringLiteral( "do something" ) ); + QCOMPARE( history.at( 1 ), QStringLiteral( "do something else" ) ); +} + +void TestQgsProcessingAlgsPt2::updateMetadata() +{ + std::unique_ptr sourceLayer = std::make_unique( QStringLiteral( "Point?crs=epsg:4326&field=pk:int&field=col1:string" ), QStringLiteral( "input" ), QStringLiteral( "memory" ) ); + QVERIFY( sourceLayer->isValid() ); + + std::unique_ptr targetLayer = std::make_unique( QStringLiteral( "Point?crs=epsg:4326&field=pk:int&field=col1:string" ), QStringLiteral( "target" ), QStringLiteral( "memory" ) ); + QVERIFY( targetLayer->isValid() ); + + QgsLayerMetadata mdInput; + mdInput.setTitle( QStringLiteral( "New title" ) ); + mdInput.setAbstract( QStringLiteral( "New abstract" ) ); + mdInput.setLanguage( QStringLiteral( "Language" ) ); + sourceLayer->setMetadata( mdInput ); + + QgsLayerMetadata mdTarget; + mdTarget.setTitle( QStringLiteral( "Title" ) ); + mdTarget.setAbstract( QStringLiteral( "Abstract" ) ); + mdTarget.setType( QStringLiteral( "Type" ) ); + targetLayer->setMetadata( mdTarget ); + + std::unique_ptr alg( QgsApplication::processingRegistry()->createAlgorithmById( QStringLiteral( "native:updatelayermetadata" ) ) ); + QVERIFY( alg != nullptr ); + + QVariantMap parameters; + parameters.insert( QStringLiteral( "SOURCE" ), QVariant::fromValue( sourceLayer.get() ) ); + parameters.insert( QStringLiteral( "TARGET" ), QVariant::fromValue( targetLayer.get() ) ); + + bool ok = false; + std::unique_ptr context = std::make_unique(); + QgsProcessingFeedback feedback; + QVariantMap results; + results = alg->run( parameters, *context, &feedback, &ok ); + QVERIFY( ok ); + + QCOMPARE( results.value( QStringLiteral( "OUTPUT" ) ), targetLayer->id() ); + + QgsLayerMetadata targetMetadata = targetLayer->metadata(); + QCOMPARE( targetMetadata.title(), QStringLiteral( "New title" ) ); + QCOMPARE( targetMetadata.abstract(), QStringLiteral( "New abstract" ) ); + QCOMPARE( targetMetadata.language(), QStringLiteral( "Language" ) ); + QCOMPARE( targetMetadata.type(), QStringLiteral( "Type" ) ); +} + +void TestQgsProcessingAlgsPt2::setMetadataFields() +{ + std::unique_ptr layer = std::make_unique( QStringLiteral( "Point?crs=epsg:4326&field=pk:int&field=col1:string" ), QStringLiteral( "input" ), QStringLiteral( "memory" ) ); + QVERIFY( layer->isValid() ); + + std::unique_ptr alg( QgsApplication::processingRegistry()->createAlgorithmById( QStringLiteral( "native:setmetadatafields" ) ) ); + QVERIFY( alg != nullptr ); + + QVariantMap parameters; + parameters.insert( QStringLiteral( "INPUT" ), QVariant::fromValue( layer.get() ) ); + parameters.insert( QStringLiteral( "TITLE" ), QStringLiteral( "Title" ) ); + + bool ok = false; + std::unique_ptr context = std::make_unique(); + QgsProcessingFeedback feedback; + QVariantMap results; + results = alg->run( parameters, *context, &feedback, &ok ); + QVERIFY( ok ); + + QCOMPARE( results.value( QStringLiteral( "OUTPUT" ) ), layer->id() ); + QCOMPARE( layer->metadata().title(), QStringLiteral( "Title" ) ); + + // update existing field and set new + parameters[QStringLiteral( "TITLE" )] = QStringLiteral( "New title" ); + parameters.insert( QStringLiteral( "ABSTRACT" ), QStringLiteral( "Abstract" ) ); + parameters.insert( QStringLiteral( "FEES" ), QStringLiteral( "Enormous fee" ) ); + parameters.insert( QStringLiteral( "CRS" ), QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:4326" ) ) ); + + ok = false; + results = alg->run( parameters, *context, &feedback, &ok ); + QVERIFY( ok ); + + QCOMPARE( results.value( QStringLiteral( "OUTPUT" ) ), layer->id() ); + QCOMPARE( layer->metadata().title(), QStringLiteral( "New title" ) ); + QCOMPARE( layer->metadata().abstract(), QStringLiteral( "Abstract" ) ); + QCOMPARE( layer->metadata().fees(), QStringLiteral( "Enormous fee" ) ); + QVERIFY( layer->metadata().crs().isValid() ); + QCOMPARE( layer->metadata().crs().authid(), QStringLiteral( "EPSG:4326" ) ); + + // ignore empty field + parameters[QStringLiteral( "TITLE" )] = QLatin1String( "" ); + parameters.insert( QStringLiteral( "IGNORE_EMPTY" ), true ); + + ok = false; + results = alg->run( parameters, *context, &feedback, &ok ); + QVERIFY( ok ); + + QCOMPARE( results.value( QStringLiteral( "OUTPUT" ) ), layer->id() ); + QCOMPARE( layer->metadata().title(), QStringLiteral( "New title" ) ); + QCOMPARE( layer->metadata().abstract(), QStringLiteral( "Abstract" ) ); + QCOMPARE( layer->metadata().fees(), QStringLiteral( "Enormous fee" ) ); + QVERIFY( layer->metadata().crs().isValid() ); + QCOMPARE( layer->metadata().crs().authid(), QStringLiteral( "EPSG:4326" ) ); + + parameters[QStringLiteral( "IGNORE_EMPTY" )] = false; + + ok = false; + results = alg->run( parameters, *context, &feedback, &ok ); + QVERIFY( ok ); + + QCOMPARE( results.value( QStringLiteral( "OUTPUT" ) ), layer->id() ); + QCOMPARE( layer->metadata().title(), QLatin1String( "" ) ); + QCOMPARE( layer->metadata().abstract(), QStringLiteral( "Abstract" ) ); + QCOMPARE( layer->metadata().fees(), QStringLiteral( "Enormous fee" ) ); + QVERIFY( layer->metadata().crs().isValid() ); + QCOMPARE( layer->metadata().crs().authid(), QStringLiteral( "EPSG:4326" ) ); +} QGSTEST_MAIN( TestQgsProcessingAlgsPt2 ) #include "testqgsprocessingalgspt2.moc"