diff --git a/python/PyQt6/core/auto_generated/qgstrackedvectorlayertools.sip.in b/python/PyQt6/core/auto_generated/qgstrackedvectorlayertools.sip.in index 5b720368f1cc..bd1278cc6230 100644 --- a/python/PyQt6/core/auto_generated/qgstrackedvectorlayertools.sip.in +++ b/python/PyQt6/core/auto_generated/qgstrackedvectorlayertools.sip.in @@ -20,7 +20,7 @@ class QgsTrackedVectorLayerTools : QgsVectorLayerTools Constructor for QgsTrackedVectorLayerTools. %End - virtual bool addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feature, QWidget *parentWidget = 0, bool showModal = true, bool hideParent = false, QgsExpressionContextScope *scope = 0 ) const; + virtual bool addFeatureV2( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feature, const QgsVectorLayerToolsContext &context ) const; %Docstring This method calls the addFeature method of the backend :py:class:`QgsVectorLayerTools` @@ -29,10 +29,7 @@ This method calls the addFeature method of the backend :py:class:`QgsVectorLayer :param defaultValues: Default values for the feature to add :param defaultGeometry: A default geometry to add to the feature :param feature: A pointer to the feature -:param parentWidget: The widget calling this function to be passed to the used dialog -:param showModal: If the used dialog should be modal or not -:param hideParent: If the parent widget should be hidden, when the used dialog is opened -:param scope: A context scope to be used to calculate feature expression-based values +:param context: A context object to be used for e.g. to calculate feature expression-based values (since QGIS 3.38) :return: ``True`` in case of success, ``False`` if the operation failed/was aborted %End diff --git a/python/PyQt6/core/auto_generated/vector/qgsvectorlayer.sip.in b/python/PyQt6/core/auto_generated/vector/qgsvectorlayer.sip.in index 6cb83580ecea..1e9c11afd9e9 100644 --- a/python/PyQt6/core/auto_generated/vector/qgsvectorlayer.sip.in +++ b/python/PyQt6/core/auto_generated/vector/qgsvectorlayer.sip.in @@ -1777,7 +1777,7 @@ be updated. This can be used to override default field value expressions. .. seealso:: :py:func:`updateFeature` %End - bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant(), bool skipDefaultValues = false, QgsExpressionContext *context = 0 ); + bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant(), bool skipDefaultValues = false, QgsVectorLayerToolsContext *context = 0 ); %Docstring Changes an attribute value for a feature (but does not immediately commit the changes). The ``fid`` argument specifies the ID of the feature to be changed. @@ -1796,7 +1796,7 @@ so it is more efficient to explicitly pass an ``oldValue`` if it is already avai If ``skipDefaultValues`` is set to ``True``, default field values will not be updated. This can be used to override default field value expressions. -If ``context`` is provided, it will be used when updating default values. +If ``context`` is provided, it will be used when updating default values (since QGIS 3.38). :return: ``True`` if the feature's attribute was successfully changed. @@ -1817,7 +1817,7 @@ If ``context`` is provided, it will be used when updating default values. .. seealso:: :py:func:`updateFeature` %End - bool changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues = QgsAttributeMap(), bool skipDefaultValues = false, QgsExpressionContext *context = 0 ); + bool changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues = QgsAttributeMap(), bool skipDefaultValues = false, QgsVectorLayerToolsContext *context = 0 ); %Docstring Changes attributes' values for a feature (but does not immediately commit the changes). @@ -1837,7 +1837,7 @@ If ``skipDefaultValues`` is set to ``True``, default field values will not be updated. This can be used to override default field value expressions. -If ``context`` is provided, it will be used when updating default values. +If ``context`` is provided, it will be used when updating default values (since QGIS 3.38). :return: ``True`` if feature's attributes was successfully changed. diff --git a/python/PyQt6/core/auto_generated/vector/qgsvectorlayertools.sip.in b/python/PyQt6/core/auto_generated/vector/qgsvectorlayertools.sip.in index c37a098bb3da..e6eeebdb50d5 100644 --- a/python/PyQt6/core/auto_generated/vector/qgsvectorlayertools.sip.in +++ b/python/PyQt6/core/auto_generated/vector/qgsvectorlayertools.sip.in @@ -28,7 +28,7 @@ in your application. QgsVectorLayerTools(); - virtual bool addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues = QgsAttributeMap(), const QgsGeometry &defaultGeometry = QgsGeometry(), QgsFeature *feature /Out/ = 0, QWidget *parentWidget = 0, bool showModal = true, bool hideParent = false, QgsExpressionContextScope *scope = 0 ) const = 0; + virtual bool addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues = QgsAttributeMap(), const QgsGeometry &defaultGeometry = QgsGeometry(), QgsFeature *feature /Out/ = 0, QWidget *parentWidget = 0, bool showModal = true, bool hideParent = false ) const; %Docstring This method should/will be called, whenever a new feature will be added to the layer @@ -38,10 +38,32 @@ This method should/will be called, whenever a new feature will be added to the l :param parentWidget: The widget calling this function to be passed to the used dialog :param showModal: If the used dialog should be modal or not :param hideParent: If the parent widget should be hidden, when the used dialog is opened -:param scope: A context scope to be used to calculate feature expression-based values :return: - ``True`` in case of success, ``False`` if the operation failed/was aborted - feature: Updated feature after adding will be written back to this + +.. note:: + + addFeature or addFeatureV2 must be overwritten when implementing a class inheriting from QgsVectorLayerTools +%End + + virtual bool addFeatureV2( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues = QgsAttributeMap(), const QgsGeometry &defaultGeometry = QgsGeometry(), QgsFeature *feature /Out/ = 0, const QgsVectorLayerToolsContext &context = QgsVectorLayerToolsContext() ) const; +%Docstring +This method should/will be called, whenever a new feature will be added to the layer + +:param layer: The layer to which the feature should be added +:param defaultValues: Default values for the feature to add +:param defaultGeometry: A default geometry to add to the feature +:param context: A context object to be used for e.g. to calculate feature expression-based values (since QGIS 3.38) + +:return: - ``True`` in case of success, ``False`` if the operation failed/was aborted + - feature: Updated feature after adding will be written back to this + +.. note:: + + addFeature or addFeatureV2 must be overwritten when implementing a class inheriting from QgsVectorLayerTools + +.. versionadded:: 3.38 %End diff --git a/python/PyQt6/core/auto_generated/vector/qgsvectorlayertoolscontext.sip.in b/python/PyQt6/core/auto_generated/vector/qgsvectorlayertoolscontext.sip.in new file mode 100644 index 000000000000..13d2e0158a08 --- /dev/null +++ b/python/PyQt6/core/auto_generated/vector/qgsvectorlayertoolscontext.sip.in @@ -0,0 +1,115 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/vector/qgsvectorlayertoolscontext.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + + +class QgsVectorLayerToolsContext +{ +%Docstring(signature="appended") +Contains settings which reflect the context in which vector layer tool operations should +consider. + +.. versionadded:: 3.38 +%End + +%TypeHeaderCode +#include "qgsvectorlayertoolscontext.h" +%End + public: + + QgsVectorLayerToolsContext(); +%Docstring +Constructor for QgsVectorLayerToolsContext. +%End + + QgsVectorLayerToolsContext( const QgsVectorLayerToolsContext &other ); +%Docstring +Copy constructor. + +:param other: source QgsVectorLayerToolsContext +%End + + + void setExpressionContext( QgsExpressionContext *context ); +%Docstring +Sets the optional expression context used by the vector layer tools. + +:param context: expression context pointer. Ownership is not transferred. + +.. seealso:: :py:func:`expressionContext` + +.. seealso:: :py:func:`setAdditionalExpressionContextScope` +%End + + QgsExpressionContext *expressionContext() const; +%Docstring +Returns the optional expression context used by the vector layer tools. + +.. seealso:: :py:func:`setExpressionContext` + +.. seealso:: :py:func:`additionalExpressionContextScope` +%End + + void setAdditionalExpressionContextScope( QgsExpressionContextScope *scope ); +%Docstring +Sets an additional expression context scope to be made available when calculating expressions. + +:param scope: additional scope. Ownership is not transferred and a copy will be made. + +.. seealso:: :py:func:`additionalExpressionContextScope` +%End + + const QgsExpressionContextScope *additionalExpressionContextScope() const; +%Docstring +Returns an additional expression context scope to be made available when calculating expressions. + +.. seealso:: :py:func:`setAdditionalExpressionContextScope` +%End + + QWidget *parentWidget() const; +%Docstring +Returns the widget which should be parented to tools dialogues. +%End + + void setParentWidget( QWidget *parent ); +%Docstring +Sets the widget which should be parented to tools' dialogues. + +:param parent: the widget actign as parent +%End + + bool showModal() const; +%Docstring +Returns whether tools' dialogues should be modal. +%End + + void setShowModal( bool modal ); +%Docstring +Sets whether tools' dialogues should be modal. +%End + + bool hideParent() const; +%Docstring +Returns whether the parent widget should be hidden when showing tools' dialogues. +%End + + void setHideParent( bool hide ); +%Docstring +Sets whether the parent widget should be hidden when showing tools' dialogues. +%End + +}; + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/vector/qgsvectorlayertoolscontext.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ diff --git a/python/PyQt6/core/core_auto.sip b/python/PyQt6/core/core_auto.sip index e0e0d9a1076f..c5361cba7cb8 100644 --- a/python/PyQt6/core/core_auto.sip +++ b/python/PyQt6/core/core_auto.sip @@ -771,6 +771,7 @@ %Include auto_generated/vector/qgsvectorlayerselectionproperties.sip %Include auto_generated/vector/qgsvectorlayertemporalproperties.sip %Include auto_generated/vector/qgsvectorlayertools.sip +%Include auto_generated/vector/qgsvectorlayertoolscontext.sip %Include auto_generated/vector/qgsvectorlayerundocommand.sip %Include auto_generated/vector/qgsvectorlayerundopassthroughcommand.sip %Include auto_generated/vector/qgsvectorlayerutils.sip diff --git a/python/core/auto_generated/qgstrackedvectorlayertools.sip.in b/python/core/auto_generated/qgstrackedvectorlayertools.sip.in index 5b720368f1cc..bd1278cc6230 100644 --- a/python/core/auto_generated/qgstrackedvectorlayertools.sip.in +++ b/python/core/auto_generated/qgstrackedvectorlayertools.sip.in @@ -20,7 +20,7 @@ class QgsTrackedVectorLayerTools : QgsVectorLayerTools Constructor for QgsTrackedVectorLayerTools. %End - virtual bool addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feature, QWidget *parentWidget = 0, bool showModal = true, bool hideParent = false, QgsExpressionContextScope *scope = 0 ) const; + virtual bool addFeatureV2( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feature, const QgsVectorLayerToolsContext &context ) const; %Docstring This method calls the addFeature method of the backend :py:class:`QgsVectorLayerTools` @@ -29,10 +29,7 @@ This method calls the addFeature method of the backend :py:class:`QgsVectorLayer :param defaultValues: Default values for the feature to add :param defaultGeometry: A default geometry to add to the feature :param feature: A pointer to the feature -:param parentWidget: The widget calling this function to be passed to the used dialog -:param showModal: If the used dialog should be modal or not -:param hideParent: If the parent widget should be hidden, when the used dialog is opened -:param scope: A context scope to be used to calculate feature expression-based values +:param context: A context object to be used for e.g. to calculate feature expression-based values (since QGIS 3.38) :return: ``True`` in case of success, ``False`` if the operation failed/was aborted %End diff --git a/python/core/auto_generated/vector/qgsvectorlayer.sip.in b/python/core/auto_generated/vector/qgsvectorlayer.sip.in index 6cb83580ecea..1e9c11afd9e9 100644 --- a/python/core/auto_generated/vector/qgsvectorlayer.sip.in +++ b/python/core/auto_generated/vector/qgsvectorlayer.sip.in @@ -1777,7 +1777,7 @@ be updated. This can be used to override default field value expressions. .. seealso:: :py:func:`updateFeature` %End - bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant(), bool skipDefaultValues = false, QgsExpressionContext *context = 0 ); + bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant(), bool skipDefaultValues = false, QgsVectorLayerToolsContext *context = 0 ); %Docstring Changes an attribute value for a feature (but does not immediately commit the changes). The ``fid`` argument specifies the ID of the feature to be changed. @@ -1796,7 +1796,7 @@ so it is more efficient to explicitly pass an ``oldValue`` if it is already avai If ``skipDefaultValues`` is set to ``True``, default field values will not be updated. This can be used to override default field value expressions. -If ``context`` is provided, it will be used when updating default values. +If ``context`` is provided, it will be used when updating default values (since QGIS 3.38). :return: ``True`` if the feature's attribute was successfully changed. @@ -1817,7 +1817,7 @@ If ``context`` is provided, it will be used when updating default values. .. seealso:: :py:func:`updateFeature` %End - bool changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues = QgsAttributeMap(), bool skipDefaultValues = false, QgsExpressionContext *context = 0 ); + bool changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues = QgsAttributeMap(), bool skipDefaultValues = false, QgsVectorLayerToolsContext *context = 0 ); %Docstring Changes attributes' values for a feature (but does not immediately commit the changes). @@ -1837,7 +1837,7 @@ If ``skipDefaultValues`` is set to ``True``, default field values will not be updated. This can be used to override default field value expressions. -If ``context`` is provided, it will be used when updating default values. +If ``context`` is provided, it will be used when updating default values (since QGIS 3.38). :return: ``True`` if feature's attributes was successfully changed. diff --git a/python/core/auto_generated/vector/qgsvectorlayertools.sip.in b/python/core/auto_generated/vector/qgsvectorlayertools.sip.in index c37a098bb3da..e6eeebdb50d5 100644 --- a/python/core/auto_generated/vector/qgsvectorlayertools.sip.in +++ b/python/core/auto_generated/vector/qgsvectorlayertools.sip.in @@ -28,7 +28,7 @@ in your application. QgsVectorLayerTools(); - virtual bool addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues = QgsAttributeMap(), const QgsGeometry &defaultGeometry = QgsGeometry(), QgsFeature *feature /Out/ = 0, QWidget *parentWidget = 0, bool showModal = true, bool hideParent = false, QgsExpressionContextScope *scope = 0 ) const = 0; + virtual bool addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues = QgsAttributeMap(), const QgsGeometry &defaultGeometry = QgsGeometry(), QgsFeature *feature /Out/ = 0, QWidget *parentWidget = 0, bool showModal = true, bool hideParent = false ) const; %Docstring This method should/will be called, whenever a new feature will be added to the layer @@ -38,10 +38,32 @@ This method should/will be called, whenever a new feature will be added to the l :param parentWidget: The widget calling this function to be passed to the used dialog :param showModal: If the used dialog should be modal or not :param hideParent: If the parent widget should be hidden, when the used dialog is opened -:param scope: A context scope to be used to calculate feature expression-based values :return: - ``True`` in case of success, ``False`` if the operation failed/was aborted - feature: Updated feature after adding will be written back to this + +.. note:: + + addFeature or addFeatureV2 must be overwritten when implementing a class inheriting from QgsVectorLayerTools +%End + + virtual bool addFeatureV2( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues = QgsAttributeMap(), const QgsGeometry &defaultGeometry = QgsGeometry(), QgsFeature *feature /Out/ = 0, const QgsVectorLayerToolsContext &context = QgsVectorLayerToolsContext() ) const; +%Docstring +This method should/will be called, whenever a new feature will be added to the layer + +:param layer: The layer to which the feature should be added +:param defaultValues: Default values for the feature to add +:param defaultGeometry: A default geometry to add to the feature +:param context: A context object to be used for e.g. to calculate feature expression-based values (since QGIS 3.38) + +:return: - ``True`` in case of success, ``False`` if the operation failed/was aborted + - feature: Updated feature after adding will be written back to this + +.. note:: + + addFeature or addFeatureV2 must be overwritten when implementing a class inheriting from QgsVectorLayerTools + +.. versionadded:: 3.38 %End diff --git a/python/core/auto_generated/vector/qgsvectorlayertoolscontext.sip.in b/python/core/auto_generated/vector/qgsvectorlayertoolscontext.sip.in new file mode 100644 index 000000000000..13d2e0158a08 --- /dev/null +++ b/python/core/auto_generated/vector/qgsvectorlayertoolscontext.sip.in @@ -0,0 +1,115 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/vector/qgsvectorlayertoolscontext.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + + +class QgsVectorLayerToolsContext +{ +%Docstring(signature="appended") +Contains settings which reflect the context in which vector layer tool operations should +consider. + +.. versionadded:: 3.38 +%End + +%TypeHeaderCode +#include "qgsvectorlayertoolscontext.h" +%End + public: + + QgsVectorLayerToolsContext(); +%Docstring +Constructor for QgsVectorLayerToolsContext. +%End + + QgsVectorLayerToolsContext( const QgsVectorLayerToolsContext &other ); +%Docstring +Copy constructor. + +:param other: source QgsVectorLayerToolsContext +%End + + + void setExpressionContext( QgsExpressionContext *context ); +%Docstring +Sets the optional expression context used by the vector layer tools. + +:param context: expression context pointer. Ownership is not transferred. + +.. seealso:: :py:func:`expressionContext` + +.. seealso:: :py:func:`setAdditionalExpressionContextScope` +%End + + QgsExpressionContext *expressionContext() const; +%Docstring +Returns the optional expression context used by the vector layer tools. + +.. seealso:: :py:func:`setExpressionContext` + +.. seealso:: :py:func:`additionalExpressionContextScope` +%End + + void setAdditionalExpressionContextScope( QgsExpressionContextScope *scope ); +%Docstring +Sets an additional expression context scope to be made available when calculating expressions. + +:param scope: additional scope. Ownership is not transferred and a copy will be made. + +.. seealso:: :py:func:`additionalExpressionContextScope` +%End + + const QgsExpressionContextScope *additionalExpressionContextScope() const; +%Docstring +Returns an additional expression context scope to be made available when calculating expressions. + +.. seealso:: :py:func:`setAdditionalExpressionContextScope` +%End + + QWidget *parentWidget() const; +%Docstring +Returns the widget which should be parented to tools dialogues. +%End + + void setParentWidget( QWidget *parent ); +%Docstring +Sets the widget which should be parented to tools' dialogues. + +:param parent: the widget actign as parent +%End + + bool showModal() const; +%Docstring +Returns whether tools' dialogues should be modal. +%End + + void setShowModal( bool modal ); +%Docstring +Sets whether tools' dialogues should be modal. +%End + + bool hideParent() const; +%Docstring +Returns whether the parent widget should be hidden when showing tools' dialogues. +%End + + void setHideParent( bool hide ); +%Docstring +Sets whether the parent widget should be hidden when showing tools' dialogues. +%End + +}; + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/vector/qgsvectorlayertoolscontext.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ diff --git a/python/core/core_auto.sip b/python/core/core_auto.sip index e0e0d9a1076f..c5361cba7cb8 100644 --- a/python/core/core_auto.sip +++ b/python/core/core_auto.sip @@ -771,6 +771,7 @@ %Include auto_generated/vector/qgsvectorlayerselectionproperties.sip %Include auto_generated/vector/qgsvectorlayertemporalproperties.sip %Include auto_generated/vector/qgsvectorlayertools.sip +%Include auto_generated/vector/qgsvectorlayertoolscontext.sip %Include auto_generated/vector/qgsvectorlayerundocommand.sip %Include auto_generated/vector/qgsvectorlayerundopassthroughcommand.sip %Include auto_generated/vector/qgsvectorlayerutils.sip diff --git a/src/app/qgsguivectorlayertools.cpp b/src/app/qgsguivectorlayertools.cpp index acd58434155e..7469c5e903ae 100644 --- a/src/app/qgsguivectorlayertools.cpp +++ b/src/app/qgsguivectorlayertools.cpp @@ -26,19 +26,20 @@ #include "qgsmessageviewer.h" #include "qgsvectorlayer.h" #include "qgsvectorlayerutils.h" +#include "qgsvectorlayertoolscontext.h" -bool QgsGuiVectorLayerTools::addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feat, QWidget *parentWidget, bool showModal, bool hideParent, QgsExpressionContextScope *scope ) const +bool QgsGuiVectorLayerTools::addFeatureV2( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feature, const QgsVectorLayerToolsContext &context ) const { - QgsFeature *f = feat; - if ( !feat ) + QgsFeature *f = feature; + if ( !feature ) f = new QgsFeature(); f->setGeometry( defaultGeometry ); - QgsFeatureAction *a = new QgsFeatureAction( tr( "Add feature" ), *f, layer, QUuid(), -1, parentWidget ); + QgsFeatureAction *a = new QgsFeatureAction( tr( "Add feature" ), *f, layer, QUuid(), -1, context.parentWidget() ); a->setForceSuppressFormPopup( forceSuppressFormPopup() ); connect( a, &QgsFeatureAction::addFeatureFinished, a, &QObject::deleteLater ); - const QgsFeatureAction::AddFeatureResult result = a->addFeature( defaultValues, showModal, std::unique_ptr( scope ), hideParent ); - if ( !feat ) + const QgsFeatureAction::AddFeatureResult result = a->addFeature( defaultValues, context.showModal(), std::unique_ptr( context.additionalExpressionContextScope() ? new QgsExpressionContextScope( *context.additionalExpressionContextScope() ) : nullptr ), context.hideParent() ); + if ( !feature ) delete f; switch ( result ) diff --git a/src/app/qgsguivectorlayertools.h b/src/app/qgsguivectorlayertools.h index 57be6215afeb..57c956c3b39c 100644 --- a/src/app/qgsguivectorlayertools.h +++ b/src/app/qgsguivectorlayertools.h @@ -40,15 +40,12 @@ class QgsGuiVectorLayerTools : public QgsVectorLayerTools * \param layer The layer to which the feature should be added * \param defaultValues Default values for the feature to add * \param defaultGeometry A default geometry to add to the feature - * \param feat A pointer to the feature - * \param parentWidget The widget calling this function to be passed to the used dialog - * \param showModal If the used dialog should be modal or not - * \param hideParent If the parent widget should be hidden, when the used dialog is opened - * \param scope A context scope to be used to calculate feature expression-based values + * \param feature A pointer to the feature + * \param context A context object to be used for e.g. to calculate feature expression-based values (since QGIS 3.38) * * \returns TRUE in case of success, FALSE if the operation failed/was aborted */ - bool addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feat = nullptr, QWidget *parentWidget = nullptr, bool showModal = true, bool hideParent = false, QgsExpressionContextScope *scope = nullptr ) const override; + bool addFeatureV2( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feature, const QgsVectorLayerToolsContext &context ) const override; /** * This should be called, whenever a vector layer should be switched to edit mode. If successful diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index ac53902c20ad..7e550d220824 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -955,6 +955,7 @@ set(QGIS_CORE_SRCS vector/qgsvectorlayerselectionproperties.cpp vector/qgsvectorlayertemporalproperties.cpp vector/qgsvectorlayertools.cpp + vector/qgsvectorlayertoolscontext.cpp vector/qgsvectorlayerundocommand.cpp vector/qgsvectorlayerundopassthroughcommand.cpp vector/qgsvectorlayerutils.cpp @@ -2029,6 +2030,7 @@ set(QGIS_CORE_HDRS vector/qgsvectorlayerselectionproperties.h vector/qgsvectorlayertemporalproperties.h vector/qgsvectorlayertools.h + vector/qgsvectorlayertoolscontext.h vector/qgsvectorlayerundocommand.h vector/qgsvectorlayerundopassthroughcommand.h vector/qgsvectorlayerutils.h diff --git a/src/core/qgstrackedvectorlayertools.cpp b/src/core/qgstrackedvectorlayertools.cpp index b6b753b785b4..9a07efe6f766 100644 --- a/src/core/qgstrackedvectorlayertools.cpp +++ b/src/core/qgstrackedvectorlayertools.cpp @@ -13,18 +13,20 @@ * (at your option) any later version. * * * ***************************************************************************/ + #include "qgstrackedvectorlayertools.h" #include "qgsvectorlayer.h" +#include "qgsvectorlayertoolscontext.h" -bool QgsTrackedVectorLayerTools::addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feature, QWidget *parentWidget, bool showModal, bool hideParent, QgsExpressionContextScope *scope ) const +bool QgsTrackedVectorLayerTools::addFeatureV2( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feature, const QgsVectorLayerToolsContext &context ) const { QgsFeature *f = feature; if ( !feature ) f = new QgsFeature(); const_cast( mBackend )->setForceSuppressFormPopup( forceSuppressFormPopup() ); - if ( mBackend->addFeature( layer, defaultValues, defaultGeometry, f, parentWidget, showModal, hideParent, scope ) ) + if ( mBackend->addFeatureV2( layer, defaultValues, defaultGeometry, f, context ) ) { mAddedFeatures[layer].insert( f->id() ); if ( !feature ) diff --git a/src/core/qgstrackedvectorlayertools.h b/src/core/qgstrackedvectorlayertools.h index 64bb534394a4..89299c4f58bb 100644 --- a/src/core/qgstrackedvectorlayertools.h +++ b/src/core/qgstrackedvectorlayertools.h @@ -41,14 +41,11 @@ class CORE_EXPORT QgsTrackedVectorLayerTools : public QgsVectorLayerTools * \param defaultValues Default values for the feature to add * \param defaultGeometry A default geometry to add to the feature * \param feature A pointer to the feature - * \param parentWidget The widget calling this function to be passed to the used dialog - * \param showModal If the used dialog should be modal or not - * \param hideParent If the parent widget should be hidden, when the used dialog is opened - * \param scope A context scope to be used to calculate feature expression-based values + * \param context A context object to be used for e.g. to calculate feature expression-based values (since QGIS 3.38) * * \returns TRUE in case of success, FALSE if the operation failed/was aborted */ - bool addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feature, QWidget *parentWidget = nullptr, bool showModal = true, bool hideParent = false, QgsExpressionContextScope *scope = nullptr ) const override; + bool addFeatureV2( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feature, const QgsVectorLayerToolsContext &context ) const override; bool startEditing( QgsVectorLayer *layer ) const override; bool stopEditing( QgsVectorLayer *layer, bool allowCancel ) const override; bool saveEdits( QgsVectorLayer *layer ) const override; diff --git a/src/core/vector/qgsvectorlayer.cpp b/src/core/vector/qgsvectorlayer.cpp index 0717519fe834..12af50d7fdfb 100644 --- a/src/core/vector/qgsvectorlayer.cpp +++ b/src/core/vector/qgsvectorlayer.cpp @@ -3398,7 +3398,7 @@ bool QgsVectorLayer::changeGeometry( QgsFeatureId fid, QgsGeometry &geom, bool s } -bool QgsVectorLayer::changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue, bool skipDefaultValues, QgsExpressionContext *context ) +bool QgsVectorLayer::changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue, bool skipDefaultValues, QgsVectorLayerToolsContext *context ) { QGIS_PROTECT_QOBJECT_THREAD_ACCESS @@ -3426,12 +3426,12 @@ bool QgsVectorLayer::changeAttributeValue( QgsFeatureId fid, int field, const QV } if ( result && !skipDefaultValues && !mDefaultValueOnUpdateFields.isEmpty() ) - updateDefaultValues( fid, QgsFeature(), context ); + updateDefaultValues( fid, QgsFeature(), context ? context->expressionContext() : nullptr ); return result; } -bool QgsVectorLayer::changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues, bool skipDefaultValues, QgsExpressionContext *context ) +bool QgsVectorLayer::changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues, bool skipDefaultValues, QgsVectorLayerToolsContext *context ) { QGIS_PROTECT_QOBJECT_THREAD_ACCESS @@ -3488,7 +3488,7 @@ bool QgsVectorLayer::changeAttributeValues( QgsFeatureId fid, const QgsAttribute if ( result && !skipDefaultValues && !mDefaultValueOnUpdateFields.isEmpty() ) { - updateDefaultValues( fid, QgsFeature(), context ); + updateDefaultValues( fid, QgsFeature(), context ? context->expressionContext() : nullptr ); } return result; diff --git a/src/core/vector/qgsvectorlayer.h b/src/core/vector/qgsvectorlayer.h index 12566cd4cac7..496e05370ea8 100644 --- a/src/core/vector/qgsvectorlayer.h +++ b/src/core/vector/qgsvectorlayer.h @@ -33,6 +33,7 @@ #include "qgsfeaturesource.h" #include "qgsfields.h" #include "qgsvectordataprovider.h" +#include "qgsvectorlayertoolscontext.h" #include "qgsvectorsimplifymethod.h" #include "qgseditformconfig.h" #include "qgsattributetableconfig.h" @@ -1735,7 +1736,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte * If \a skipDefaultValues is set to TRUE, default field values will not * be updated. This can be used to override default field value expressions. * - * If \a context is provided, it will be used when updating default values. + * If \a context is provided, it will be used when updating default values (since QGIS 3.38). * * \returns TRUE if the feature's attribute was successfully changed. * @@ -1749,7 +1750,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte * \see changeGeometry() * \see updateFeature() */ - Q_INVOKABLE bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant(), bool skipDefaultValues = false, QgsExpressionContext *context = nullptr ); + Q_INVOKABLE bool changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue = QVariant(), bool skipDefaultValues = false, QgsVectorLayerToolsContext *context = nullptr ); /** * Changes attributes' values for a feature (but does not immediately @@ -1770,7 +1771,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte * be updated. This can be used to override default field value * expressions. * - * If \a context is provided, it will be used when updating default values. + * If \a context is provided, it will be used when updating default values (since QGIS 3.38). * * \returns TRUE if feature's attributes was successfully changed. * @@ -1787,7 +1788,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte * \see changeAttributeValue() * */ - Q_INVOKABLE bool changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues = QgsAttributeMap(), bool skipDefaultValues = false, QgsExpressionContext *context = nullptr ); + Q_INVOKABLE bool changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues = QgsAttributeMap(), bool skipDefaultValues = false, QgsVectorLayerToolsContext *context = nullptr ); /** * Add an attribute field (but does not commit it) diff --git a/src/core/vector/qgsvectorlayertools.h b/src/core/vector/qgsvectorlayertools.h index d8cc9e1386eb..780bd2a4e46e 100644 --- a/src/core/vector/qgsvectorlayertools.h +++ b/src/core/vector/qgsvectorlayertools.h @@ -23,6 +23,7 @@ #include "qgsexpressioncontext.h" #include "qgsfeature.h" #include "qgsgeometry.h" +#include "qgsvectorlayertoolscontext.h" class QgsFeatureRequest; class QgsVectorLayer; @@ -57,11 +58,37 @@ class CORE_EXPORT QgsVectorLayerTools : public QObject * \param parentWidget The widget calling this function to be passed to the used dialog * \param showModal If the used dialog should be modal or not * \param hideParent If the parent widget should be hidden, when the used dialog is opened - * \param scope A context scope to be used to calculate feature expression-based values - * \returns TRUE in case of success, FALSE if the operation failed/was aborted + * \returns TRUE in case of success, FALSE if the operation failed/was aborted * + * \note addFeature or addFeatureV2 must be overwritten when implementing a class inheriting from QgsVectorLayerTools */ - virtual bool addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues = QgsAttributeMap(), const QgsGeometry &defaultGeometry = QgsGeometry(), QgsFeature *feature SIP_OUT = nullptr, QWidget *parentWidget = nullptr, bool showModal = true, bool hideParent = false, QgsExpressionContextScope *scope = nullptr ) const = 0; + virtual bool addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues = QgsAttributeMap(), const QgsGeometry &defaultGeometry = QgsGeometry(), QgsFeature *feature SIP_OUT = nullptr, QWidget *parentWidget = nullptr, bool showModal = true, bool hideParent = false ) const + { + QgsVectorLayerToolsContext context; + context.setParentWidget( parentWidget ); + context.setShowModal( showModal ); + context.setHideParent( hideParent ); + return addFeatureV2( layer, defaultValues, defaultGeometry, feature, context ); + } + + /** + * This method should/will be called, whenever a new feature will be added to the layer + * + * \param layer The layer to which the feature should be added + * \param defaultValues Default values for the feature to add + * \param defaultGeometry A default geometry to add to the feature + * \param feature Updated feature after adding will be written back to this + * \param context A context object to be used for e.g. to calculate feature expression-based values (since QGIS 3.38) + * \returns TRUE in case of success, FALSE if the operation failed/was aborted + * + * \note addFeature or addFeatureV2 must be overwritten when implementing a class inheriting from QgsVectorLayerTools + * \since QGIS 3.38 + */ + virtual bool addFeatureV2( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues = QgsAttributeMap(), const QgsGeometry &defaultGeometry = QgsGeometry(), QgsFeature *feature SIP_OUT = nullptr, const QgsVectorLayerToolsContext &context = QgsVectorLayerToolsContext() ) const + { + Q_UNUSED( context ) + return addFeature( layer, defaultValues, defaultGeometry, feature, context.parentWidget(), context.showModal(), context.hideParent() ); + } // TODO QGIS 4: remove const qualifier diff --git a/src/core/vector/qgsvectorlayertoolscontext.cpp b/src/core/vector/qgsvectorlayertoolscontext.cpp new file mode 100644 index 000000000000..d25802a99835 --- /dev/null +++ b/src/core/vector/qgsvectorlayertoolscontext.cpp @@ -0,0 +1,78 @@ +/*************************************************************************** + qgsvectorlayertoolscontext.cpp + ------------------------ + begin : May 2024 + copyright : (C) 2024 by Mathieu Pellerin + email : mathieu at opengis dot ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgsvectorlayertoolscontext.h" +#include "qgsexpressioncontextutils.h" + +QgsVectorLayerToolsContext::QgsVectorLayerToolsContext( const QgsVectorLayerToolsContext &other ) + : mParentWidget( other.mParentWidget ) + , mShowModal( other.mShowModal ) + , mHideParent( other.mHideParent ) +{ + if ( other.mAdditionalExpressionContextScope ) + { + mAdditionalExpressionContextScope.reset( new QgsExpressionContextScope( *other.mAdditionalExpressionContextScope ) ); + } + if ( other.mExpressionContext ) + { + mExpressionContext.reset( new QgsExpressionContext( *other.mExpressionContext ) ); + } +} + +QgsVectorLayerToolsContext &QgsVectorLayerToolsContext::operator=( const QgsVectorLayerToolsContext &other ) +{ + mParentWidget = other.mParentWidget; + mShowModal = other.mShowModal; + mHideParent = other.mHideParent; + if ( other.mAdditionalExpressionContextScope ) + { + mAdditionalExpressionContextScope.reset( new QgsExpressionContextScope( *other.mAdditionalExpressionContextScope ) ); + } + if ( other.mExpressionContext ) + { + mExpressionContext.reset( new QgsExpressionContext( *other.mExpressionContext ) ); + } + else + { + mExpressionContext.reset(); + } + return *this; +} + +void QgsVectorLayerToolsContext::setExpressionContext( QgsExpressionContext *context ) +{ + if ( context ) + mExpressionContext.reset( new QgsExpressionContext( *context ) ); + else + mExpressionContext.reset(); +} + +QgsExpressionContext *QgsVectorLayerToolsContext::expressionContext() const +{ + return mExpressionContext.get(); +} + +void QgsVectorLayerToolsContext::setAdditionalExpressionContextScope( QgsExpressionContextScope *scope ) +{ + if ( scope ) + mAdditionalExpressionContextScope.reset( new QgsExpressionContextScope( *scope ) ); + else + mAdditionalExpressionContextScope.reset(); +} + +const QgsExpressionContextScope *QgsVectorLayerToolsContext::additionalExpressionContextScope() const +{ + return mAdditionalExpressionContextScope.get(); +} diff --git a/src/core/vector/qgsvectorlayertoolscontext.h b/src/core/vector/qgsvectorlayertoolscontext.h new file mode 100644 index 000000000000..90019e124504 --- /dev/null +++ b/src/core/vector/qgsvectorlayertoolscontext.h @@ -0,0 +1,117 @@ +/*************************************************************************** + qgsvectorlayertoolscontext.h + ------------------------ + begin : May 2024 + copyright : (C) 2024 by Mathieu Pellerin + email : mathieu at opengis dot ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSVECTORLAYERTOOLSCONTEXT_H +#define QGSVECTORLAYERTOOLSCONTEXT_H + +#include "qgsexpressioncontext.h" +#include "qgis_core.h" + +#include + +/** + * \ingroup core + * \class QgsVectorLayerToolsContext + * \brief Contains settings which reflect the context in which vector layer tool operations should + * consider. + * \since QGIS 3.38 + */ +class CORE_EXPORT QgsVectorLayerToolsContext +{ + public: + + /** + * Constructor for QgsVectorLayerToolsContext. + */ + QgsVectorLayerToolsContext() = default; + + /** + * Copy constructor. + * \param other source QgsVectorLayerToolsContext + */ + QgsVectorLayerToolsContext( const QgsVectorLayerToolsContext &other ); + + QgsVectorLayerToolsContext &operator=( const QgsVectorLayerToolsContext &other ); + + /** + * Sets the optional expression context used by the vector layer tools. + * \param context expression context pointer. Ownership is not transferred. + * \see expressionContext() + * \see setAdditionalExpressionContextScope() + */ + void setExpressionContext( QgsExpressionContext *context ); + + /** + * Returns the optional expression context used by the vector layer tools. + * \see setExpressionContext() + * \see additionalExpressionContextScope() + */ + QgsExpressionContext *expressionContext() const; + + /** + * Sets an additional expression context scope to be made available when calculating expressions. + * \param scope additional scope. Ownership is not transferred and a copy will be made. + * \see additionalExpressionContextScope() + */ + void setAdditionalExpressionContextScope( QgsExpressionContextScope *scope ); + + /** + * Returns an additional expression context scope to be made available when calculating expressions. + * \see setAdditionalExpressionContextScope() + */ + const QgsExpressionContextScope *additionalExpressionContextScope() const; + + /** + * Returns the widget which should be parented to tools dialogues. + */ + QWidget *parentWidget() const { return mParentWidget; } + + /** + * Sets the widget which should be parented to tools' dialogues. + * \param parent the widget actign as parent + */ + void setParentWidget( QWidget *parent ) { mParentWidget = parent; } + + /** + * Returns whether tools' dialogues should be modal. + */ + bool showModal() const { return mShowModal; } + + /** + * Sets whether tools' dialogues should be modal. + */ + void setShowModal( bool modal ) { mShowModal = modal; } + + /** + * Returns whether the parent widget should be hidden when showing tools' dialogues. + */ + bool hideParent() const { return mHideParent; } + + /** + * Sets whether the parent widget should be hidden when showing tools' dialogues. + */ + void setHideParent( bool hide ) { mHideParent = hide; } + + private: + + std::unique_ptr< QgsExpressionContext > mExpressionContext; + std::unique_ptr< QgsExpressionContextScope > mAdditionalExpressionContextScope; + + QWidget *mParentWidget = nullptr; + bool mShowModal = true; + bool mHideParent = false; +}; + +#endif // QGSVECTORLAYERTOOLSCONTEXT_H diff --git a/src/gui/qgsabstractrelationeditorwidget.cpp b/src/gui/qgsabstractrelationeditorwidget.cpp index 808a73010be7..b82081be896f 100644 --- a/src/gui/qgsabstractrelationeditorwidget.cpp +++ b/src/gui/qgsabstractrelationeditorwidget.cpp @@ -287,9 +287,14 @@ QgsFeatureIds QgsAbstractRelationEditorWidget::addFeature( const QgsGeometry &ge for ( const QgsRelation::FieldPair &fieldPair : constFieldPairs ) keyAttrs.insert( fields.indexFromName( fieldPair.referencingField() ), mFeatureList.first().attribute( fieldPair.referencedField() ) ); - QgsExpressionContextScope *scope = QgsExpressionContextUtils::parentFormScope( mFeatureList.first(), mEditorContext.attributeFormModeString() ); + QgsVectorLayerToolsContext context; + context.setParentWidget( this ); + context.setShowModal( true ); + context.setHideParent( true ); + std::unique_ptr scope( QgsExpressionContextUtils::parentFormScope( mFeatureList.first(), mEditorContext.attributeFormModeString() ) ); + context.setAdditionalExpressionContextScope( scope.get() ); QgsFeature linkFeature; - if ( !vlTools->addFeature( mRelation.referencingLayer(), keyAttrs, geometry, &linkFeature, this, true, true, scope ) ) + if ( !vlTools->addFeatureV2( mRelation.referencingLayer(), keyAttrs, geometry, &linkFeature, context ) ) return QgsFeatureIds(); addedFeatureIds.insert( linkFeature.id() ); diff --git a/src/gui/qgsattributeform.cpp b/src/gui/qgsattributeform.cpp index a4e64074961e..1f206899fb3f 100644 --- a/src/gui/qgsattributeform.cpp +++ b/src/gui/qgsattributeform.cpp @@ -44,6 +44,7 @@ #include "qgstabwidget.h" #include "qgsscrollarea.h" #include "qgsvectorlayerjoinbuffer.h" +#include "qgsvectorlayertoolscontext.h" #include "qgsvectorlayerutils.h" #include "qgsactionwidgetwrapper.h" #include "qgsqmlwidgetwrapper.h" @@ -463,8 +464,10 @@ bool QgsAttributeForm::saveEdits( QString *error ) n++; } - QgsExpressionContext context = createExpressionContext( updatedFeature ); - success = mLayer->changeAttributeValues( mFeature.id(), newValues, oldValues, false, &context ); + std::unique_ptr context = std::make_unique(); + QgsExpressionContext expressionContext = createExpressionContext( updatedFeature ); + context->setExpressionContext( &expressionContext ); + success = mLayer->changeAttributeValues( mFeature.id(), newValues, oldValues, false, context.get() ); if ( success && n > 0 ) { diff --git a/tests/src/gui/testqgsrelationreferencewidget.cpp b/tests/src/gui/testqgsrelationreferencewidget.cpp index 9530dfcfabf0..80f7da84e602 100644 --- a/tests/src/gui/testqgsrelationreferencewidget.cpp +++ b/tests/src/gui/testqgsrelationreferencewidget.cpp @@ -31,6 +31,7 @@ #include "qgsgui.h" #include "qgsmapcanvas.h" #include "qgsvectorlayertools.h" +#include "qgsvectorlayertoolscontext.h" #include "qgsadvanceddigitizingdockwidget.h" #include "qgsmaptooldigitizefeature.h" @@ -609,12 +610,9 @@ void TestQgsRelationReferenceWidget::testIdentifyOnMap() // referenced layer class DummyVectorLayerTools : public QgsVectorLayerTools // clazy:exclude=missing-qobject-macro { - bool addFeature( QgsVectorLayer *layer, const QgsAttributeMap &, const QgsGeometry &, QgsFeature *feat = nullptr, QWidget *parentWidget = nullptr, bool showModal = true, bool hideParent = false, QgsExpressionContextScope *scope = nullptr ) const override + bool addFeatureV2( QgsVectorLayer *layer, const QgsAttributeMap &, const QgsGeometry &, QgsFeature *feat, const QgsVectorLayerToolsContext &context ) const override { - Q_UNUSED( parentWidget ); - Q_UNUSED( showModal ); - Q_UNUSED( hideParent ); - Q_UNUSED( scope ); + Q_UNUSED( context ); feat->setAttribute( QStringLiteral( "pk" ), 13 ); feat->setAttribute( QStringLiteral( "material" ), QStringLiteral( "steel" ) ); feat->setAttribute( QStringLiteral( "diameter" ), 140 ); diff --git a/tests/src/python/test_qgsrelationeditwidget.py b/tests/src/python/test_qgsrelationeditwidget.py index cf69ff3d44be..ece758559334 100644 --- a/tests/src/python/test_qgsrelationeditwidget.py +++ b/tests/src/python/test_qgsrelationeditwidget.py @@ -341,7 +341,7 @@ def test_add_feature_geometry(self): # Mock vector layer tool to just set default value on created feature class DummyVlTools(QgsVectorLayerTools): - def addFeature(self, layer, defaultValues, defaultGeometry, parentWidget=None, showModal=True, hideParent=False, scope=None): + def addFeature(self, layer, defaultValues, defaultGeometry, parentWidget=None, showModal=True, hideParent=False): f = QgsFeature(layer.fields()) for idx, value in defaultValues.items(): f.setAttribute(idx, value) @@ -440,7 +440,7 @@ def setValues(self, values): """ self.values = values - def addFeature(self, layer, defaultValues, defaultGeometry, parentWidget=None, showModal=True, hideParent=False, scope=None): + def addFeature(self, layer, defaultValues, defaultGeometry, parentWidget=None, showModal=True, hideParent=False): """ Overrides the addFeature method :param layer: vector layer diff --git a/tests/src/python/test_qgsvectorlayer.py b/tests/src/python/test_qgsvectorlayer.py index 3832d8a27a18..881578a0bb0f 100644 --- a/tests/src/python/test_qgsvectorlayer.py +++ b/tests/src/python/test_qgsvectorlayer.py @@ -78,6 +78,7 @@ QgsVectorLayerJoinInfo, QgsVectorLayerSelectedFeatureSource, QgsVectorLayerSimpleLabeling, + QgsVectorLayerToolsContext, QgsWkbTypes, ) from qgis.gui import QgsAttributeTableModel, QgsGui @@ -1162,8 +1163,10 @@ def test_ChangeAttributeValuesWithContext(self): layer.startEditing() - context = layer.createExpressionContext() - context.appendScope(QgsExpressionContextUtils.parentFormScope(pf)) + expressionContext = layer.createExpressionContext() + expressionContext.appendScope(QgsExpressionContextUtils.parentFormScope(pf)) + context = QgsVectorLayerToolsContext() + context.setExpressionContext(expressionContext) self.assertTrue(layer.changeAttributeValues(fid, {1: 100}, {}, False, context)) f = layer.getFeature(1)