Skip to content
Permalink
Browse files

[feature] Add layer scoped actions

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 5b4a88f8e07e8ee1f9bfc0570f76f68717688cf2
Showing with 1,308 additions and 561 deletions.
  1. +5 −0 doc/api_break.dox
  2. +2 −0 python/core/core.sip
  3. +23 −41 python/core/qgsaction.sip
  4. +17 −42 python/core/qgsactionmanager.sip
  5. +113 −0 python/core/qgsactionscope.sip
  6. +74 −0 python/core/qgsactionscoperegistry.sip
  7. +1 −1 python/gui/attributetable/qgsattributetablemodel.sip
  8. +5 −7 python/gui/qgsactionmenu.sip
  9. +2 −2 src/app/gps/qgsgpsinformationwidget.cpp
  10. +26 −30 src/app/qgisapp.cpp
  11. +1 −1 src/app/qgisappinterface.cpp
  12. +27 −18 src/app/qgsattributeactiondialog.cpp
  13. +2 −2 src/app/qgsattributeactiondialog.h
  14. +83 −46 src/app/qgsattributeactionpropertiesdialog.cpp
  15. +8 −3 src/app/qgsattributeactionpropertiesdialog.h
  16. +35 −1 src/app/qgsattributetabledialog.cpp
  17. +1 −0 src/app/qgsattributetabledialog.h
  18. +7 −8 src/app/qgsfeatureaction.cpp
  19. +2 −2 src/app/qgsfeatureaction.h
  20. +24 −26 src/app/qgsidentifyresultsdialog.cpp
  21. +1 −1 src/app/qgsidentifyresultsdialog.h
  22. +1 −1 src/app/qgsmaptooladdfeature.cpp
  23. +17 −22 src/app/qgsmaptoolfeatureaction.cpp
  24. +4 −0 src/core/CMakeLists.txt
  25. +61 −0 src/core/qgsaction.cpp
  26. +61 −31 src/core/qgsaction.h
  27. +89 −47 src/core/qgsactionmanager.cpp
  28. +24 −29 src/core/qgsactionmanager.h
  29. +90 −0 src/core/qgsactionscope.cpp
  30. +126 −0 src/core/qgsactionscope.h
  31. +73 −0 src/core/qgsactionscoperegistry.cpp
  32. +81 −0 src/core/qgsactionscoperegistry.h
  33. +15 −1 src/core/qgsapplication.cpp
  34. +17 −0 src/core/qgsapplication.h
  35. +1 −1 src/gui/attributetable/qgsattributetablemodel.cpp
  36. +1 −1 src/gui/attributetable/qgsattributetablemodel.h
  37. +8 −10 src/gui/attributetable/qgsattributetableview.cpp
  38. +6 −8 src/gui/attributetable/qgsdualview.cpp
  39. +2 −2 src/gui/attributetable/qgsdualview.h
  40. +1 −1 src/gui/attributetable/qgsfeaturelistview.cpp
  41. +56 −50 src/gui/qgsactionmenu.cpp
  42. +13 −36 src/gui/qgsactionmenu.h
  43. +1 −1 src/gui/qgsattributedialog.cpp
  44. +2 −2 src/gui/qgsidentifymenu.cpp
  45. +1 −1 src/ui/qgsattributeactiondialogbase.ui
  46. +87 −86 src/ui/qgsattributeactionpropertiesdialogbase.ui
  47. +11 −0 src/ui/qgsattributetabledialog.ui
@@ -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}
-------------------------------
@@ -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
@@ -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;
@@ -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,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/;

@@ -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;
@@ -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 );
};
@@ -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;
};
@@ -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.
You can’t perform that action at this time.