Skip to content

Commit

Permalink
[attribute form] Add parent feature scope when adding a child feature…
Browse files Browse the repository at this point in the history
… through the relation editor widget
  • Loading branch information
nirvn committed Jun 2, 2024
1 parent f9d3ca3 commit 54e3668
Show file tree
Hide file tree
Showing 12 changed files with 28 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) const;
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;

%Docstring
This method calls the addFeature method of the backend :py:class:`QgsVectorLayerTools`
Expand All @@ -32,6 +32,7 @@ This method calls the addFeature method of the backend :py:class:`QgsVectorLayer
: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
%End
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) 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, QgsExpressionContextScope *scope = 0 ) const = 0;
%Docstring
This method should/will be called, whenever a new feature will be added to the layer

Expand All @@ -38,6 +38,7 @@ 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
Expand Down
3 changes: 2 additions & 1 deletion python/core/auto_generated/qgstrackedvectorlayertools.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) const;
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;

%Docstring
This method calls the addFeature method of the backend :py:class:`QgsVectorLayerTools`
Expand All @@ -32,6 +32,7 @@ This method calls the addFeature method of the backend :py:class:`QgsVectorLayer
: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
%End
Expand Down
3 changes: 2 additions & 1 deletion python/core/auto_generated/vector/qgsvectorlayertools.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) 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, QgsExpressionContextScope *scope = 0 ) const = 0;
%Docstring
This method should/will be called, whenever a new feature will be added to the layer

Expand All @@ -38,6 +38,7 @@ 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
Expand Down
2 changes: 2 additions & 0 deletions src/app/qgsfeatureaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,9 @@ QgsFeatureAction::AddFeatureResult QgsFeatureAction::addFeature( const QgsAttrib
// values and field constraints
QgsExpressionContext context = mLayer->createExpressionContext();
if ( scope )
{
context.appendScope( scope.release() );
}

const QgsFeature newFeature = QgsVectorLayerUtils::createFeature( mLayer, mFeature->geometry(), initialAttributeValues,
&context );
Expand Down
4 changes: 2 additions & 2 deletions src/app/qgsguivectorlayertools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#include "qgsvectorlayer.h"
#include "qgsvectorlayerutils.h"

bool QgsGuiVectorLayerTools::addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feat, QWidget *parentWidget, bool showModal, bool hideParent ) const
bool QgsGuiVectorLayerTools::addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feat, QWidget *parentWidget, bool showModal, bool hideParent, QgsExpressionContextScope *scope ) const
{
QgsFeature *f = feat;
if ( !feat )
Expand All @@ -37,7 +37,7 @@ bool QgsGuiVectorLayerTools::addFeature( QgsVectorLayer *layer, const QgsAttribu
QgsFeatureAction *a = new QgsFeatureAction( tr( "Add feature" ), *f, layer, QUuid(), -1, parentWidget );
a->setForceSuppressFormPopup( forceSuppressFormPopup() );
connect( a, &QgsFeatureAction::addFeatureFinished, a, &QObject::deleteLater );
const QgsFeatureAction::AddFeatureResult result = a->addFeature( defaultValues, showModal, nullptr, hideParent );
const QgsFeatureAction::AddFeatureResult result = a->addFeature( defaultValues, showModal, std::unique_ptr<QgsExpressionContextScope>( scope ), hideParent );
if ( !feat )
delete f;

Expand Down
5 changes: 3 additions & 2 deletions src/app/qgsguivectorlayertools.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@ class QgsGuiVectorLayerTools : public QgsVectorLayerTools
* \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
*/
bool addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feat = nullptr, QWidget *parentWidget = nullptr, bool showModal = true, bool hideParent = false ) const override;
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;

/**
* This should be called, whenever a vector layer should be switched to edit mode. If successful
Expand Down
5 changes: 2 additions & 3 deletions src/core/qgstrackedvectorlayertools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,14 @@
#include "qgsvectorlayer.h"


bool QgsTrackedVectorLayerTools::addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feature, QWidget *parentWidget, bool showModal, bool hideParent ) const
bool QgsTrackedVectorLayerTools::addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feature, QWidget *parentWidget, bool showModal, bool hideParent, QgsExpressionContextScope *scope ) const
{
QgsFeature *f = feature;
if ( !feature )
f = new QgsFeature();

const_cast<QgsVectorLayerTools *>( mBackend )->setForceSuppressFormPopup( forceSuppressFormPopup() );

if ( mBackend->addFeature( layer, defaultValues, defaultGeometry, f, parentWidget, showModal, hideParent ) )
if ( mBackend->addFeature( layer, defaultValues, defaultGeometry, f, parentWidget, showModal, hideParent, scope ) )
{
mAddedFeatures[layer].insert( f->id() );
if ( !feature )
Expand Down
4 changes: 3 additions & 1 deletion src/core/qgstrackedvectorlayertools.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "qgis_core.h"
#include "qgsvectorlayertools.h"
#include "qgsexpressioncontext.h"

/**
* \ingroup core
Expand All @@ -43,10 +44,11 @@ class CORE_EXPORT QgsTrackedVectorLayerTools : public QgsVectorLayerTools
* \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
*/
bool addFeature( QgsVectorLayer *layer, const QgsAttributeMap &defaultValues, const QgsGeometry &defaultGeometry, QgsFeature *feature, QWidget *parentWidget = nullptr, bool showModal = true, bool hideParent = false ) const override;
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 startEditing( QgsVectorLayer *layer ) const override;
bool stopEditing( QgsVectorLayer *layer, bool allowCancel ) const override;
bool saveEdits( QgsVectorLayer *layer ) const override;
Expand Down
4 changes: 3 additions & 1 deletion src/core/vector/qgsvectorlayertools.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "qgis_sip.h"
#include <QObject>

#include "qgsexpressioncontext.h"
#include "qgsfeature.h"
#include "qgsgeometry.h"

Expand Down Expand Up @@ -56,10 +57,11 @@ 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
*
*/
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 = 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, QgsExpressionContextScope *scope = nullptr ) const = 0;

// TODO QGIS 4: remove const qualifier

Expand Down
4 changes: 3 additions & 1 deletion src/gui/qgsabstractrelationeditorwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include "qgsfeatureiterator.h"
#include "qgsexpression.h"
#include "qgsexpressioncontextutils.h"
#include "qgsfeature.h"
#include "qgsfeatureselectiondlg.h"
#include "qgsrelation.h"
Expand Down Expand Up @@ -286,8 +287,9 @@ 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() );
QgsFeature linkFeature;
if ( !vlTools->addFeature( mRelation.referencingLayer(), keyAttrs, geometry, &linkFeature, this, true, true ) )
if ( !vlTools->addFeature( mRelation.referencingLayer(), keyAttrs, geometry, &linkFeature, this, true, true, scope ) )
return QgsFeatureIds();

addedFeatureIds.insert( linkFeature.id() );
Expand Down
3 changes: 2 additions & 1 deletion tests/src/gui/testqgsrelationreferencewidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -609,11 +609,12 @@ 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 ) const override
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
{
Q_UNUSED( parentWidget );
Q_UNUSED( showModal );
Q_UNUSED( hideParent );
Q_UNUSED( scope );
feat->setAttribute( QStringLiteral( "pk" ), 13 );
feat->setAttribute( QStringLiteral( "material" ), QStringLiteral( "steel" ) );
feat->setAttribute( QStringLiteral( "diameter" ), 140 );
Expand Down

0 comments on commit 54e3668

Please sign in to comment.