Skip to content

Commit

Permalink
[feature] Add layer scoped actions
Browse files Browse the repository at this point in the history
Within the attribute table, there is a new button to trigger actions
which are not based on individual features but instead on the whole layer.
Normally they will perform actions based on all features or the selection.

In addition to this, a lot of cleanup has been done.
  • Loading branch information
m-kuhn committed Nov 16, 2016
1 parent 6727ea7 commit 5b4a88f
Show file tree
Hide file tree
Showing 47 changed files with 1,308 additions and 561 deletions.
5 changes: 5 additions & 0 deletions doc/api_break.dox
Expand Up @@ -335,6 +335,11 @@ variant instead.
- expandAction() has been removed. Use QgsExpression::replaceExpressionText() instead.
- setPythonExecute() was removed. Initialize QgsPythonRunner instead.

QgsAction {#qgis_api_break_3_0_QgsAction}
---------

- `QgsAction::action()` has been renamed to `QgsAction::command()`.


QgsAdvancedDigitizingDockWidget {#qgis_api_break_3_0_QgsAdvancedDigitizingDockWidget}
-------------------------------
Expand Down
2 changes: 2 additions & 0 deletions python/core/core.sip
Expand Up @@ -18,6 +18,8 @@
%Include qgsapplication.sip
%Include qgsaction.sip
%Include qgsactionmanager.sip
%Include qgsactionscope.sip
%Include qgsactionscoperegistry.sip
%Include qgsaggregatecalculator.sip
%Include qgsattributetableconfig.sip
%Include qgsattributeeditorelement.sip
Expand Down
64 changes: 23 additions & 41 deletions python/core/qgsaction.sip
Expand Up @@ -33,41 +33,7 @@ class QgsAction
OpenUrl,
};

/**
* Create a new QgsAction
*
* @param type The type of this action
* @param description A human readable description string
* @param action The action text. Its interpretation depends on the type
* @param capture If this is set to true, the output will be captured when an action is run
*/
QgsAction( ActionType type, const QString& description, const QString& action, bool capture );


/**
* Create a new QgsAction
*
* @param type The type of this action
* @param description A human readable description string
* @param action The action text. Its interpretation depends on the type
* @param icon Path to an icon for this action
* @param capture If this is set to true, the output will be captured when an action is run
* @param shortTitle A short string used to label user interface elements like buttons
*/
QgsAction( ActionType type, const QString& description, const QString& action, const QString& icon, bool capture, const QString& shortTitle = QString() );

/**
* Create a new QgsAction
*
* @param type The type of this action
* @param description A human readable description string
* @param action The action text. Its interpretation depends on the type
* @param icon Path to an icon for this action
* @param capture If this is set to true, the output will be captured when an action is run
* @param showInAttributeTable If this is false, the action will be hidden on the attribute table action widget
* @param shortTitle A short string used to label user interface elements like buttons
*/
QgsAction( ActionType type, const QString& description, const QString& action, const QString& icon, bool capture, bool showInAttributeTable, const QString& shortTitle = QString() );
QgsAction( ActionType type, const QString& description, const QString& action, const QString& icon, bool capture, const QString& shortTitle = QString(), const QSet<QString>& actionScopes = QSet<QString>() );

//! The name of the action. This may be a longer description.
QString name() const;
Expand All @@ -81,18 +47,34 @@ class QgsAction
//! The icon
QIcon icon() const;

//! The action
QString action() const;
//! The command
QString command() const;

//! The action type
ActionType type() const;

//! Whether to capture output for display when this action is run
bool capture() const;

//! Whether this action should be shown on the attribute table
bool showInAttributeTable() const;

//! Whether the action is runable on the current platform
//! Checks if the action is runable on the current platform
bool runable() const;

/**
* The action scopes define where an action will be available.
* Action scopes may offer additional variables like the clicked
* coordinate.
*
* @see QgsActionScope
* @note Added in QGIS 3.0
*/
QSet<QString> actionScopes() const;

/**
* The action scopes define where an action will be available.
* Action scopes may offer additional variables like the clicked
* coordinate.
*
* @note Added in QGIS 3.0
*/
void setActionScopes( const QSet<QString>& actionScopes );
};
59 changes: 17 additions & 42 deletions python/core/qgsactionmanager.sip
Expand Up @@ -59,14 +59,11 @@ class QgsActionManager
*/
void addAction( const QgsAction& action );

//! Remove an action at given index
void removeAction( int index );

/** Does the given values. defaultValueIndex is the index of the
* field to be used if the action has a $currfield placeholder.
* @note available in python bindings as doActionFeature
*/
void doAction( int index,
void doAction( const QString& actionId,
const QgsFeature &feat,
int defaultValueIndex = 0 ) /PyName=doActionFeature/;

Expand All @@ -76,15 +73,15 @@ class QgsActionManager
* @param feature feature to run action for
* @param context expression context to evalute expressions under
*/
void doAction( int index,
void doAction( const QString& actionId,
const QgsFeature& feature,
const QgsExpressionContext& context );

//! Removes all actions
void clearActions();

//! List all actions
QList<QgsAction> listActions() const;
QList<QgsAction> listActions( const QString& actionScope = QString() ) const;

//! Return the layer
QgsVectorLayer* layer() const;
Expand All @@ -95,49 +92,27 @@ class QgsActionManager
//! Reads the actions in in XML format
bool readXml( const QDomNode& layer_node );

int size() const;
/**
* Get the action at the specified index.
* Get an action by its id.
*
* @note Added in QGIS 3.0
*/
QgsAction at( int idx ) const /Factory/;
%MethodCode
if ( a0 < 0 || a0 >= sipCpp->size() )
{
PyErr_SetString(PyExc_KeyError, QByteArray::number(a0));
sipIsErr = 1;
}
else
{
sipRes = new QgsAction( sipCpp->at( a0 ) );
}
%End
QgsAction action( const QString& id );

/**
* Get the action at the specified index.
* Each scope can have a default action. This will be saved in the project
* file.
*
* @note Added in QGIS 3.0
*/
QgsAction operator[]( int idx ) const;
%MethodCode
if ( a0 < 0 || a0 >= sipCpp->size() )
{
PyErr_SetString(PyExc_KeyError, QByteArray::number(a0));
sipIsErr = 1;
}
else
{
sipRes = new QgsAction( sipCpp->at( a0 ) );
}
%End
void setDefaultAction( const QString& actionScope, const QString& actionId );

/**
* Returns the index of the default action, or -1 if no default action is available.
* @see setDefaultAction()
* Each scope can have a default action. This will be saved in the project
* file.
*
* @note Added in QGIS 3.0
*/
int defaultAction() const;
QgsAction defaultAction( const QString& actionScope );

/**
* Set the index of the default action.
* @param actionNumber index of action which should be made the default for the layer
* @see defaultAction()
*/
void setDefaultAction( int actionNumber );
};
113 changes: 113 additions & 0 deletions python/core/qgsactionscope.sip
@@ -0,0 +1,113 @@
/***************************************************************************
qgsactionscope.sip - QgsActionScope

---------------------
begin : 1.11.2016
copyright : (C) 2016 by Matthias Kuhn
email : matthias@opengis.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. *
* *
***************************************************************************/

/** \ingroup core
* An action scope defines a "place" for an action to be shown and may add
* additional expression variables.
* Each QgsAction can be available in one or several action scopes.
*
* Examples:
* ---------
*
* <dl>
* <dt>Canvas</dt>
* <dd>Show for canvas tools. Adds `@clicked_x` and `@clicked_y` in map coordinates.</dd>
* <dt>AttributeTable</dt>
* <dd>Show in attribute table for each row.</dd>
* <dt>FieldSpecific</dt>
* <dd>Show on right click in attribute table. Adds `@field_index` and `@field_name`.</dd>
* <dt>Selection</dt>
* <dd>Show in attribute table and work on the layer or selection.</dd>
* </dl>
*
* @note Added in QGIS 3.0
*/

class QgsActionScope
{
%TypeHeaderCode
#include "qgsactionscope.h"
%End
public:
/**
* Creates a new action scope.
*/
explicit QgsActionScope();

/**
* Creates a new action scope.
* For details concerning the parameters check the documentation
* of the corresponding properties.
*/
explicit QgsActionScope( const QString& id, const QString& title, const QString& description, const QgsExpressionContextScope& expressionContextScope = QgsExpressionContextScope() );

/**
* Compares two action scopes
*/
bool operator==( const QgsActionScope& other ) const;

/**
* An expression scope may offer additional variables for an action scope.
* This can be an `field_name` for the attribute which was clicked or
* `clicked_x` and `clicked_y` for actions which are available as map canvas clicks.
*
* @note Added in QGIS 3.0
*/
QgsExpressionContextScope expressionContextScope() const;

/**
* \copydoc expressionContextScope()
*/
void setExpressionContextScope( const QgsExpressionContextScope& expressionContextScope );

/**
* A unique identifier for this action scope.
*
* @note Added in QGIS 3.0
*/
QString id() const;

//! \copydoc id()
void setId( const QString& id );

/**
* The title is a human readable and translated string that will be
* presented to the user in the properties dialog.
*
* @note Added in QGIS 3.0
*/
QString title() const;
//! \copydoc title()
void setTitle( const QString& title );

/**
* The description should be a longer description of where actions in this scope
* are available. It is not necessary to list the available expression variables
* in here, they are extracted automatically from the expressionContextScope().
*
* @note Added in QGIS 3.0
*/
QString description() const;
//! \copydoc description()
void setDescription( const QString& description );

/**
* Returns if this scope is valid.
*
* @note Added in QGIS 3.0
*/
bool isValid() const;
};
74 changes: 74 additions & 0 deletions python/core/qgsactionscoperegistry.sip
@@ -0,0 +1,74 @@
/***************************************************************************
qgsactionscoperegistry.h - QgsActionScopeRegistry

---------------------
begin : 1.11.2016
copyright : (C) 2016 by Matthias Kuhn
email : matthias@opengis.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. *
* *
***************************************************************************/

/** \ingroup core
* The action scope registry is an application wide registry that
* contains a list of available action scopes.
* Some scopes are available by default, additional ones can be registered
* at runtime by plugins or custom applications.
*
* To get access use the QgsApplication:
*
* ```
* QgsApplication::actionScopeRegistry()
* ```
*
* @note Added in QGIS 3.0
*/
class QgsActionScopeRegistry : QObject
{
%TypeHeaderCode
#include "qgsactionscoperegistry.h"
%End

public:
explicit QgsActionScopeRegistry( QObject* parent = nullptr );

/**
* Get all registered action scopes.
*/
QSet<QgsActionScope> actionScopes() const;

/**
* Register an additional action scope.
*
* @note Added in QGIS 3.0
*/
void registerActionScope( const QgsActionScope& actionScope );

/**
* Unregister an additional action scope.
*
* @note Added in QGIS 3.0
*/
void unregisterActionScope( const QgsActionScope& actionScope );

/**
* Get an action scope by its id.
*
* @note Added in QGIS 3.0
*/
QgsActionScope actionScope( const QString& id );

signals:
/**
* Emitted whenever a new action scope is registered or an action scope
* is unregistered.
*
* @note Added in QGIS 3.0
*/
void actionScopesChanged();
};

0 comments on commit 5b4a88f

Please sign in to comment.