Skip to content

Commit

Permalink
Add framework so that a QgsMapLayerAction can get a reference
Browse files Browse the repository at this point in the history
to the QgsAttributeDialog it is executed from
  • Loading branch information
nyalldawson committed Nov 23, 2022
1 parent b6badb6 commit 0c4aff9
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 4 deletions.
9 changes: 9 additions & 0 deletions python/gui/auto_generated/qgsactionmenu.sip.in
Expand Up @@ -63,6 +63,15 @@ Constructs a new QgsActionMenu
:param fid: The feature id of the feature for which this action will be run.
:param parent: The usual QWidget parent.
:param actionScope: The action scope this menu will run in
%End

void setActionContextGenerator( QgsMapLayerActionContextGenerator *generator );
%Docstring
Sets a :py:class:`QgsMapLayerActionContextGenerator` to create action contexts for the menu.

The ``generator`` object must exist for the lifetime of the menu.

.. versionadded:: 3.30
%End

void setFeature( const QgsFeature &feature );
Expand Down
5 changes: 4 additions & 1 deletion python/gui/auto_generated/qgsattributedialog.sip.in
Expand Up @@ -10,7 +10,7 @@



class QgsAttributeDialog : QDialog
class QgsAttributeDialog : QDialog, QgsMapLayerActionContextGenerator
{

%TypeHeaderCode
Expand Down Expand Up @@ -83,6 +83,9 @@ for calculations in this form.
.. versionadded:: 3.16
%End

virtual QgsMapLayerActionContext createActionContext();


public slots:
virtual void accept();

Expand Down
38 changes: 38 additions & 0 deletions python/gui/auto_generated/qgsmaplayeractionregistry.sip.in
Expand Up @@ -23,10 +23,48 @@ Encapsulates the context in which a :py:class:`QgsMapLayerAction` action is exec
%End
public:

QgsMapLayerActionContext();

QgsAttributeDialog *attributeDialog() const;
%Docstring
Returns the attribute dialog associated with the action's execution.

May be ``None`` if the action is not being executed from an attribute dialog.

.. seealso:: :py:func:`setAttributeDialog`
%End

void setAttributeDialog( QgsAttributeDialog *dialog );
%Docstring
Sets the attribute ``dialog`` associated with the action's execution.

.. seealso:: :py:func:`attributeDialog`
%End

};


class QgsMapLayerActionContextGenerator
{
%Docstring(signature="appended")
An interface for objects which can create a QgsMapLayerActionContext.

.. versionadded:: 3.30
%End

%TypeHeaderCode
#include "qgsmaplayeractionregistry.h"
%End
public:

virtual ~QgsMapLayerActionContextGenerator();

virtual QgsMapLayerActionContext createActionContext() = 0;
%Docstring
Creates a :py:class:`QgsMapLayerActionContext`.
%End
};

class QgsMapLayerAction : QAction
{
%Docstring(signature="appended")
Expand Down
7 changes: 6 additions & 1 deletion src/gui/qgsactionmenu.cpp
Expand Up @@ -39,6 +39,11 @@ QgsActionMenu::QgsActionMenu( QgsVectorLayer *layer, const QgsFeatureId fid, con
init();
}

void QgsActionMenu::setActionContextGenerator( QgsMapLayerActionContextGenerator *generator )
{
mContextGenerator = generator;
}

void QgsActionMenu::init()
{
setTitle( tr( "&Actions" ) );
Expand Down Expand Up @@ -94,7 +99,7 @@ void QgsActionMenu::triggerAction()
{
QgsMapLayerAction *mapLayerAction = data.actionData.value<QgsMapLayerAction *>();

QgsMapLayerActionContext context;
const QgsMapLayerActionContext context = mContextGenerator ? mContextGenerator->createActionContext() : QgsMapLayerActionContext();
Q_NOWARN_DEPRECATED_PUSH
mapLayerAction->triggerForFeature( data.mapLayer, mFeature );
Q_NOWARN_DEPRECATED_POP
Expand Down
14 changes: 13 additions & 1 deletion src/gui/qgsactionmenu.h
Expand Up @@ -21,13 +21,14 @@

#include "qgsfeature.h"
#include "qgsaction.h"
#include "qgsattributeeditorcontext.h"
#include "qgis_gui.h"
#include "qgsattributeform.h"

class QgsMapLayer;
class QgsMapLayerAction;
class QgsVectorLayer;
class QgsActionManager;
class QgsMapLayerActionContextGenerator;

/**
* \ingroup gui
Expand Down Expand Up @@ -83,6 +84,15 @@ class GUI_EXPORT QgsActionMenu : public QMenu
*/
explicit QgsActionMenu( QgsVectorLayer *layer, QgsFeatureId fid, const QString &actionScope, QWidget *parent SIP_TRANSFERTHIS = nullptr );

/**
* Sets a QgsMapLayerActionContextGenerator to create action contexts for the menu.
*
* The \a generator object must exist for the lifetime of the menu.
*
* \since QGIS 3.30
*/
void setActionContextGenerator( QgsMapLayerActionContextGenerator *generator );

/**
* Change the feature on which actions are performed
*
Expand Down Expand Up @@ -146,6 +156,8 @@ class GUI_EXPORT QgsActionMenu : public QMenu
QString mActionScope;
QgsExpressionContextScope mExpressionContextScope;
QgsAttributeEditorContext::Mode mMode = QgsAttributeEditorContext::SingleEditMode;

QgsMapLayerActionContextGenerator *mContextGenerator = nullptr;
};


Expand Down
8 changes: 8 additions & 0 deletions src/gui/qgsattributedialog.cpp
Expand Up @@ -125,6 +125,7 @@ void QgsAttributeDialog::init( QgsVectorLayer *layer, QgsFeature *feature, const
connect( layer, &QObject::destroyed, this, &QWidget::close );

mMenu = new QgsActionMenu( layer, mAttributeForm->feature(), QStringLiteral( "Feature" ), this );
mMenu->setActionContextGenerator( this );
if ( !mMenu->isEmpty() )
{
mMenuBar = new QMenuBar( this );
Expand Down Expand Up @@ -169,3 +170,10 @@ void QgsAttributeDialog::setExtraContextScope( QgsExpressionContextScope *extraS
{
mAttributeForm->setExtraContextScope( extraScope );
}

QgsMapLayerActionContext QgsAttributeDialog::createActionContext()
{
QgsMapLayerActionContext context;
context.setAttributeDialog( this );
return context;
}
5 changes: 4 additions & 1 deletion src/gui/qgsattributedialog.h
Expand Up @@ -22,6 +22,7 @@
#include "qgsattributeform.h"
#include "qgstrackedvectorlayertools.h"
#include "qgsactionmenu.h"
#include "qgsmaplayeractionregistry.h"

#include <QDialog>
#include <QMenuBar>
Expand All @@ -34,7 +35,7 @@ class QgsHighlight;
* \ingroup gui
* \class QgsAttributeDialog
*/
class GUI_EXPORT QgsAttributeDialog : public QDialog
class GUI_EXPORT QgsAttributeDialog : public QDialog, public QgsMapLayerActionContextGenerator
{
Q_OBJECT

Expand Down Expand Up @@ -103,6 +104,8 @@ class GUI_EXPORT QgsAttributeDialog : public QDialog
*/
void setExtraContextScope( QgsExpressionContextScope *extraScope SIP_TRANSFER );

QgsMapLayerActionContext createActionContext() override;

public slots:
void accept() override;
void reject() override;
Expand Down
19 changes: 19 additions & 0 deletions src/gui/qgsmaplayeractionregistry.cpp
Expand Up @@ -16,6 +16,7 @@
#include "qgsmaplayeractionregistry.h"
#include "qgsgui.h"
#include "qgsvectorlayer.h"
#include "qgsattributedialog.h"

QgsMapLayerAction::QgsMapLayerAction( const QString &name, QObject *parent, Targets targets, const QIcon &icon, QgsMapLayerAction::Flags flags )
: QAction( icon, name, parent )
Expand Down Expand Up @@ -195,3 +196,21 @@ QgsMapLayerAction *QgsMapLayerActionRegistry::defaultActionForLayer( QgsMapLayer

return mDefaultLayerActionMap[ layer ];
}

//
// QgsMapLayerActionContext
//

QgsMapLayerActionContext::QgsMapLayerActionContext() = default;

QgsAttributeDialog *QgsMapLayerActionContext::attributeDialog() const
{
return mAttributeDialog;
}

void QgsMapLayerActionContext::setAttributeDialog( QgsAttributeDialog *dialog )
{
mAttributeDialog = dialog;
}

QgsMapLayerActionContextGenerator::~QgsMapLayerActionContextGenerator() = default;
41 changes: 41 additions & 0 deletions src/gui/qgsmaplayeractionregistry.h
Expand Up @@ -21,12 +21,14 @@
#include <QList>
#include <QMap>
#include <QAction>
#include <QPointer>

#include "qgis.h"
#include "qgis_gui.h"

class QgsFeature;
class QgsMapLayer;
class QgsAttributeDialog;

/**
* \ingroup gui
Expand All @@ -37,11 +39,50 @@ class GUI_EXPORT QgsMapLayerActionContext
{
public:

QgsMapLayerActionContext();

/**
* Returns the attribute dialog associated with the action's execution.
*
* May be NULLPTR if the action is not being executed from an attribute dialog.
*
* \see setAttributeDialog()
*/
QgsAttributeDialog *attributeDialog() const;

/**
* Sets the attribute \a dialog associated with the action's execution.
*
* \see attributeDialog()
*/
void setAttributeDialog( QgsAttributeDialog *dialog );

private:

QPointer< QgsAttributeDialog > mAttributeDialog;


};

Q_DECLARE_METATYPE( QgsMapLayerActionContext )

/**
* \ingroup gui
* \brief An interface for objects which can create a QgsMapLayerActionContext.
* \since QGIS 3.30
*/
class GUI_EXPORT QgsMapLayerActionContextGenerator
{
public:

virtual ~QgsMapLayerActionContextGenerator();

/**
* Creates a QgsMapLayerActionContext.
*/
virtual QgsMapLayerActionContext createActionContext() = 0;
};

/**
* \ingroup gui
* \brief An action which can run on map layers
Expand Down

0 comments on commit 0c4aff9

Please sign in to comment.