4 changes: 4 additions & 0 deletions src/app/qgisapp.h
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,10 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
//! Opens the options dialog
void showOptionsDialog( QWidget *parent = 0, QString currentPage = QString() );

/** Refreshes the state of the layer actions toolbar action
* @note added in 2.1 */
void refreshActionFeatureAction();

protected:

//! Handle state changes (WindowTitleChange)
Expand Down
68 changes: 67 additions & 1 deletion src/app/qgsidentifyresultsdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,10 @@ void QgsIdentifyResultsDialog::addFeature( QgsVectorLayer *vlayer, const QgsFeat
}
}

if ( vlayer->pendingFields().size() > 0 || vlayer->actions()->size() )
//get valid QgsMapLayerActions for this layer
mMapLayerActions = QgsMapLayerActionRegistry::instance()->mapLayerActions( vlayer );

if ( vlayer->pendingFields().size() > 0 || vlayer->actions()->size() || mMapLayerActions.size() )
{
QTreeWidgetItem *actionItem = new QTreeWidgetItem( QStringList() << tr( "(Actions)" ) );
actionItem->setData( 0, Qt::UserRole, "actions" );
Expand All @@ -445,6 +448,17 @@ void QgsIdentifyResultsDialog::addFeature( QgsVectorLayer *vlayer, const QgsFeat
twi->setData( 0, Qt::UserRole + 1, QVariant::fromValue( i ) );
actionItem->addChild( twi );
}

//add actions from QgsMapLayerActionRegistry
for ( int i = 0; i < mMapLayerActions.size(); i++ )
{
QgsMapLayerAction* action = mMapLayerActions.at( i );
QTreeWidgetItem *twi = new QTreeWidgetItem( QStringList() << "" << action->text() );
twi->setIcon( 0, QgsApplication::getThemeIcon( "/mAction.svg" ) );
twi->setData( 0, Qt::UserRole, "map_layer_action" );
twi->setData( 0, Qt::UserRole + 1, QVariant::fromValue( i ) );
actionItem->addChild( twi );
}
}

highlightFeature( featItem );
Expand Down Expand Up @@ -674,6 +688,14 @@ void QgsIdentifyResultsDialog::itemClicked( QTreeWidgetItem *item, int column )
{
doAction( item, item->data( 0, Qt::UserRole + 1 ).toInt() );
}
else if ( item->data( 0, Qt::UserRole ).toString() == "map_layer_action" )
{
QgsMapLayerAction* action = mMapLayerActions.at( item->data( 0, Qt::UserRole + 1 ).toInt() );
if ( action )
{
doMapLayerAction( item, action );
}
}
}

// Popup (create if necessary) a context menu that contains a list of
Expand Down Expand Up @@ -779,6 +801,27 @@ void QgsIdentifyResultsDialog::contextMenuEvent( QContextMenuEvent* event )
}
}

if ( featItem && vlayer )
{
//get valid QgsMapLayerActions for this layer
QList< QgsMapLayerAction* > registeredActions = QgsMapLayerActionRegistry::instance()->mapLayerActions( vlayer );

if ( registeredActions.size() > 0 )
{
//add a seperator between user defined and standard actions
mActionPopup->addSeparator();

int featIdx = featItem->data( 0, Qt::UserRole + 1 ).toInt();

QList<QgsMapLayerAction*>::iterator actionIt;
for ( actionIt = registeredActions.begin(); actionIt != registeredActions.end(); ++actionIt )
{
QgsIdentifyResultsDialogMapLayerAction *a = new QgsIdentifyResultsDialogMapLayerAction(( *actionIt )->text(), this, ( *actionIt ), vlayer, &( mFeatures[ featIdx ] ) );
mActionPopup->addAction( QgsApplication::getThemeIcon( "/mAction.svg" ), ( *actionIt )->text(), a, SLOT( execute() ) );
}
}
}

mActionPopup->popup( event->globalPos() );
}

Expand Down Expand Up @@ -884,6 +927,20 @@ void QgsIdentifyResultsDialog::doAction( QTreeWidgetItem *item, int action )
layer->actions()->doAction( action, mFeatures[ featIdx ], idx );
}

void QgsIdentifyResultsDialog::doMapLayerAction( QTreeWidgetItem *item, QgsMapLayerAction* action )
{
QTreeWidgetItem *featItem = featureItem( item );
if ( !featItem )
return;

QgsVectorLayer *layer = qobject_cast<QgsVectorLayer *>( featItem->parent()->data( 0, Qt::UserRole ).value<QObject *>() );
if ( !layer )
return;

int featIdx = featItem->data( 0, Qt::UserRole + 1 ).toInt();
action->triggerForFeature( layer, &mFeatures[ featIdx ] );
}

QTreeWidgetItem *QgsIdentifyResultsDialog::featureItem( QTreeWidgetItem *item )
{
if ( !item )
Expand Down Expand Up @@ -1496,3 +1553,12 @@ void QgsIdentifyResultsDialog::formatChanged( int index )
}
}
}

/*
* QgsIdentifyResultsDialogMapLayerAction
*/

void QgsIdentifyResultsDialogMapLayerAction::execute()
{
mAction->triggerForFeature( mLayer, mFeature );
}
23 changes: 23 additions & 0 deletions src/app/qgsidentifyresultsdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "qgsfield.h"
#include "qgsmaptoolidentify.h"
#include "qgscoordinatereferencesystem.h"
#include "qgsmaplayeractionregistry.h"

#include <QWidget>
#include <QList>
Expand Down Expand Up @@ -199,6 +200,8 @@ class APP_EXPORT QgsIdentifyResultsDialog: public QDialog, private Ui::QgsIdenti
QgsMapCanvas *mCanvas;
QList<QgsFeature> mFeatures;

QList< QgsMapLayerAction* > mMapLayerActions;

QgsMapLayer *layer( QTreeWidgetItem *item );
QgsVectorLayer *vectorLayer( QTreeWidgetItem *item );
QgsRasterLayer *rasterLayer( QTreeWidgetItem *item );
Expand All @@ -218,7 +221,27 @@ class APP_EXPORT QgsIdentifyResultsDialog: public QDialog, private Ui::QgsIdenti

void doAction( QTreeWidgetItem *item, int action );

void doMapLayerAction( QTreeWidgetItem *item, QgsMapLayerAction* action );

QDockWidget *mDock;
};

class QgsIdentifyResultsDialogMapLayerAction : public QAction
{
Q_OBJECT

public:
QgsIdentifyResultsDialogMapLayerAction( const QString &name, QObject *parent, QgsMapLayerAction* action, QgsMapLayer* layer, QgsFeature * f ) :
QAction( name, parent ), mAction( action ), mFeature( f ), mLayer( layer )
{}

public slots:
void execute();

private:
QgsMapLayerAction* mAction;
QgsFeature* mFeature;
QgsMapLayer* mLayer;
};

#endif
33 changes: 22 additions & 11 deletions src/app/qgsmaptoolfeatureaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "qgsvectorlayer.h"
#include "qgsproject.h"
#include "qgsmaplayerregistry.h"
#include "qgsmaplayeractionregistry.h"
#include "qgisapp.h"

#include <QSettings>
Expand Down Expand Up @@ -78,7 +79,7 @@ void QgsMapToolFeatureAction::canvasReleaseEvent( QMouseEvent *e )
}

QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
if ( vlayer->actions()->size() == 0 )
if ( vlayer->actions()->size() == 0 && QgsMapLayerActionRegistry::instance()->mapLayerActions( vlayer ).size() == 0 )
{
QMessageBox::warning( mCanvas,
tr( "No actions available" ),
Expand Down Expand Up @@ -149,16 +150,26 @@ bool QgsMapToolFeatureAction::doAction( QgsVectorLayer *layer, int x, int y )

foreach ( QgsFeature feat, featList )
{
int actionIdx = layer->actions()->defaultAction();

// define custom substitutions: layer id and clicked coords
QMap<QString, QVariant> substitutionMap;
substitutionMap.insert( "$layerid", layer->id() );
point = toLayerCoordinates( layer, point );
substitutionMap.insert( "$clickx", point.x() );
substitutionMap.insert( "$clicky", point.y() );

layer->actions()->doAction( actionIdx, feat, &substitutionMap );
if ( layer->actions()->defaultAction() >= 0 )
{
// define custom substitutions: layer id and clicked coords
QMap<QString, QVariant> substitutionMap;
substitutionMap.insert( "$layerid", layer->id() );
point = toLayerCoordinates( layer, point );
substitutionMap.insert( "$clickx", point.x() );
substitutionMap.insert( "$clicky", point.y() );

int actionIdx = layer->actions()->defaultAction();
layer->actions()->doAction( actionIdx, feat, &substitutionMap );
}
else
{
QgsMapLayerAction* mapLayerAction = QgsMapLayerActionRegistry::instance()->defaultActionForLayer( layer );
if ( mapLayerAction )
{
mapLayerAction->triggerForFeature( layer, &feat );
}
}
}

return true;
Expand Down
6 changes: 6 additions & 0 deletions src/core/composer/qgsatlascomposition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,12 @@ void QgsAtlasComposition::lastFeature()
prepareForFeature( mCurrentFeatureNo );
}

void QgsAtlasComposition::prepareForFeature( QgsFeature * feat )
{
int featureI = mFeatureIds.indexOf( feat->id() );
prepareForFeature( featureI );
}

void QgsAtlasComposition::prepareForFeature( int featureI )
{
if ( !mCoverageLayer )
Expand Down
4 changes: 4 additions & 0 deletions src/core/composer/qgsatlascomposition.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ class CORE_EXPORT QgsAtlasComposition : public QObject
/** Prepare the atlas map for the given feature. Sets the extent and context variables */
void prepareForFeature( int i );

/** Prepare the atlas map for the given feature. Sets the extent and context variables */
void prepareForFeature( QgsFeature * feat );

/** Returns the current filename. Must be called after prepareForFeature( i ) */
const QString& currentFilename() const;

Expand Down Expand Up @@ -174,6 +177,7 @@ class CORE_EXPORT QgsAtlasComposition : public QObject

public:
typedef QMap< QgsFeatureId, QVariant > SorterKeys;

private:
// value of field that is used for ordering of features
SorterKeys mFeatureKeys;
Expand Down
4 changes: 2 additions & 2 deletions src/core/qgsattributeaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class CORE_EXPORT QgsAttributeAction
{
public:
//! Constructor
QgsAttributeAction( QgsVectorLayer *layer ) : mLayer( layer ) {}
QgsAttributeAction( QgsVectorLayer *layer ) : mLayer( layer ), mDefaultAction( -1 ) {}

//! Destructor
virtual ~QgsAttributeAction() {}
Expand Down Expand Up @@ -175,7 +175,7 @@ class CORE_EXPORT QgsAttributeAction
static void setPythonExecute( void ( * )( const QString & ) );

//! Whether the action is the default action
int defaultAction() const { return mDefaultAction < 0 || mDefaultAction >= size() ? 0 : mDefaultAction; }
int defaultAction() const { return mDefaultAction < 0 || mDefaultAction >= size() ? -1 : mDefaultAction; }
void setDefaultAction( int actionNumber ) { mDefaultAction = actionNumber ; }

private:
Expand Down
2 changes: 2 additions & 0 deletions src/gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ qgsmapcanvas.cpp
qgsmapcanvasitem.cpp
qgsmapcanvasmap.cpp
qgsmapcanvassnapper.cpp
qgsmaplayeractionregistry.cpp
qgsmapoverviewcanvas.cpp
qgsmaptip.cpp
qgsmaptool.cpp
Expand Down Expand Up @@ -236,6 +237,7 @@ qgslonglongvalidator.h
qgsludialog.h
qgsmanageconnectionsdialog.h
qgsmapcanvas.h
qgsmaplayeractionregistry.h
qgsmapoverviewcanvas.h
qgsmaptoolemitpoint.h
qgsmaptoolidentify.h
Expand Down
7 changes: 7 additions & 0 deletions src/gui/attributetable/qgsattributetablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "qgsrendererv2.h"
#include "qgsmaplayerregistry.h"
#include "qgsexpression.h"
#include "qgsmaplayeractionregistry.h"

#include <QtGui>
#include <QVariant>
Expand Down Expand Up @@ -629,6 +630,12 @@ void QgsAttributeTableModel::executeAction( int action, const QModelIndex &idx )
layer()->actions()->doAction( action, f, fieldIdx( idx.column() ) );
}

void QgsAttributeTableModel::executeMapLayerAction( QgsMapLayerAction* action, const QModelIndex &idx ) const
{
QgsFeature f = feature( idx );
action->triggerForFeature( layer(), &f );
}

QgsFeature QgsAttributeTableModel::feature( const QModelIndex &idx ) const
{
QgsFeature f;
Expand Down
6 changes: 6 additions & 0 deletions src/gui/attributetable/qgsattributetablemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "qgsvectorlayercache.h"

class QgsMapCanvas;
class QgsMapLayerAction;

/**
* A model backed by a {@link QgsVectorLayerCache} which is able to provide
Expand Down Expand Up @@ -173,6 +174,11 @@ class GUI_EXPORT QgsAttributeTableModel: public QAbstractTableModel
*/
void executeAction( int action, const QModelIndex &idx ) const;

/**
* Execute a QgsMapLayerAction
*/
void executeMapLayerAction( QgsMapLayerAction* action, const QModelIndex &idx ) const;

/**
* Return the feature attributes at given model index
* @return feature attributes at given model index
Expand Down
29 changes: 28 additions & 1 deletion src/gui/attributetable/qgsdualview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "qgsmapcanvas.h"
#include "qgsvectordataprovider.h"
#include "qgsvectorlayercache.h"
#include "qgsmaplayeractionregistry.h"

#include <QDialog>
#include <QMenu>
Expand Down Expand Up @@ -418,10 +419,11 @@ void QgsDualView::viewWillShowContextMenu( QMenu* menu, QModelIndex atIndex )
{
QModelIndex sourceIndex = mFilterModel->mapToSource( atIndex );

//add user-defined actions to context menu
if ( mLayerCache->layer()->actions()->size() != 0 )
{

QAction *a = menu->addAction( tr( "Run action" ) );
QAction *a = menu->addAction( tr( "Run layer action" ) );
a->setEnabled( false );

for ( int i = 0; i < mLayerCache->layer()->actions()->size(); i++ )
Expand All @@ -436,6 +438,22 @@ void QgsDualView::viewWillShowContextMenu( QMenu* menu, QModelIndex atIndex )
}
}

//add actions from QgsMapLayerActionRegistry to context menu
QList<QgsMapLayerAction *> registeredActions = QgsMapLayerActionRegistry::instance()->mapLayerActions( mLayerCache->layer() );
if ( registeredActions.size() > 0 )
{
//add a seperator between user defined and standard actions
menu->addSeparator();

QList<QgsMapLayerAction*>::iterator actionIt;
for ( actionIt = registeredActions.begin(); actionIt != registeredActions.end(); ++actionIt )
{
QgsAttributeTableMapLayerAction *a = new QgsAttributeTableMapLayerAction(( *actionIt )->text(), this, ( *actionIt ), sourceIndex );
menu->addAction(( *actionIt )->text(), a, SLOT( execute() ) );
}
}

menu->addSeparator();
QgsAttributeTableAction *a = new QgsAttributeTableAction( tr( "Open form" ), this, -1, sourceIndex );
menu->addAction( tr( "Open form" ), a, SLOT( featureForm() ) );
}
Expand Down Expand Up @@ -612,3 +630,12 @@ void QgsAttributeTableAction::featureForm()
mDualView->setCurrentEditSelection( editedIds );
mDualView->setView( QgsDualView::AttributeEditor );
}

/*
* QgsAttributeTableMapLayerAction
*/

void QgsAttributeTableMapLayerAction::execute()
{
mDualView->masterModel()->executeMapLayerAction( mAction, mFieldIdx );
}
19 changes: 19 additions & 0 deletions src/gui/attributetable/qgsdualview.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
class QgsAttributeDialog;
class QgsFeatureRequest;
class QSignalMapper;
class QgsMapLayerAction;

/**
* This widget is used to show the attributes of a set of features of a {@link QgsVectorLayer}.
Expand Down Expand Up @@ -277,4 +278,22 @@ class GUI_EXPORT QgsAttributeTableAction : public QAction
QModelIndex mFieldIdx;
};

class GUI_EXPORT QgsAttributeTableMapLayerAction : public QAction
{
Q_OBJECT

public:
QgsAttributeTableMapLayerAction( const QString &name, QgsDualView *dualView, QgsMapLayerAction* action, const QModelIndex &fieldIdx ) :
QAction( name, dualView ), mDualView( dualView ), mAction( action ), mFieldIdx( fieldIdx )
{}

public slots:
void execute();

private:
QgsDualView* mDualView;
QgsMapLayerAction* mAction;
QModelIndex mFieldIdx;
};

#endif // QGSFEATURELIST_H
172 changes: 172 additions & 0 deletions src/gui/qgsmaplayeractionregistry.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
/***************************************************************************
qgsmaplayeractionregistry.cpp
-----------------------------
begin : January 2014
copyright : (C) 2014 by Nyall Dawson
email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* 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 "qgsmaplayeractionregistry.h"


QgsMapLayerAction::QgsMapLayerAction( QString name, QObject* parent ) : QAction( name, parent ),
mSingleLayer( false ),
mActionLayer( 0 ),
mSpecificLayerType( false )
{

}

/**Creates a map layer action which can run only on a specific layer*/
QgsMapLayerAction::QgsMapLayerAction( QString name, QObject* parent, QgsMapLayer* layer ) : QAction( name, parent ),
mSingleLayer( true ),
mActionLayer( layer ),
mSpecificLayerType( false )
{

}

/**Creates a map layer action which can run on a specific type of layer*/
QgsMapLayerAction::QgsMapLayerAction( QString name, QObject* parent, QgsMapLayer::LayerType layerType ) : QAction( name, parent ),
mSingleLayer( false ),
mActionLayer( 0 ),
mSpecificLayerType( true ),
mLayerType( layerType )
{

}

QgsMapLayerAction::~QgsMapLayerAction()
{
//remove action from registry
QgsMapLayerActionRegistry::instance()->removeMapLayerAction( this );
}

bool QgsMapLayerAction::canRunUsingLayer( QgsMapLayer* layer ) const
{
//check layer details
if ( !mSingleLayer && !mSpecificLayerType )
{
//action is not a single layer of specific layer type action,
//so return true
return true;
}
if ( mSingleLayer && layer == mActionLayer )
{
//action is a single layer type and layer matches
return true;
}
else if ( mSpecificLayerType && layer->type() == mLayerType )
{
//action is for a layer type and layer type matches
return true;
}

return false;
}

void QgsMapLayerAction::triggerForFeature( QgsMapLayer* layer, QgsFeature* feature )
{
emit triggeredForFeature( layer, feature );
//also trigger this action for the specified layer
triggerForLayer( layer );
}

void QgsMapLayerAction::triggerForLayer( QgsMapLayer* layer )
{
emit triggeredForLayer( layer );
//also emit triggered signal
emit triggered();
}

//
// Static calls to enforce singleton behaviour
//
QgsMapLayerActionRegistry *QgsMapLayerActionRegistry::mInstance = 0;
QgsMapLayerActionRegistry *QgsMapLayerActionRegistry::instance()
{
if ( mInstance == 0 )
{
mInstance = new QgsMapLayerActionRegistry();
}
return mInstance;
}

//
// Main class begins now...
//

QgsMapLayerActionRegistry::QgsMapLayerActionRegistry( QObject *parent ) : QObject( parent )
{
// constructor does nothing
}

QgsMapLayerActionRegistry::~QgsMapLayerActionRegistry()
{

}

void QgsMapLayerActionRegistry::addMapLayerAction( QgsMapLayerAction * action )
{
mMapLayerActionList.append( action );
emit changed();
}

QList< QgsMapLayerAction* > QgsMapLayerActionRegistry::mapLayerActions( QgsMapLayer* layer )
{
QList< QgsMapLayerAction* > validActions;
QList<QgsMapLayerAction*>::iterator actionIt;
for ( actionIt = mMapLayerActionList.begin(); actionIt != mMapLayerActionList.end(); ++actionIt )
{
if (( *actionIt )->canRunUsingLayer( layer ) )
{
validActions.append(( *actionIt ) );
}
}
return validActions;
}


bool QgsMapLayerActionRegistry::removeMapLayerAction( QgsMapLayerAction* action )
{
if ( mMapLayerActionList.indexOf( action ) != -1 )
{
mMapLayerActionList.removeAll( action );

//also remove this action from the default layer action map
QMap<QgsMapLayer*, QgsMapLayerAction*>::iterator defaultIt;
for ( defaultIt = mDefaultLayerActionMap.begin(); defaultIt != mDefaultLayerActionMap.end(); ++defaultIt )
{
if ( defaultIt.value() == action )
{
defaultIt.value() = 0;
}
}
emit changed();
return true;
}
//not found
return false;
}

void QgsMapLayerActionRegistry::setDefaultActionForLayer( QgsMapLayer* layer, QgsMapLayerAction* action )
{
mDefaultLayerActionMap[ layer ] = action;
}

QgsMapLayerAction * QgsMapLayerActionRegistry::defaultActionForLayer( QgsMapLayer* layer )
{
if ( !mDefaultLayerActionMap.contains( layer ) )
{
return 0;
}

return mDefaultLayerActionMap[ layer ];
}
122 changes: 122 additions & 0 deletions src/gui/qgsmaplayeractionregistry.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/***************************************************************************
qgsmaplayeractionregistry.h
---------------------------
begin : January 2014
copyright : (C) 2014 by Nyall Dawson
email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* 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 QGSMAPLAYERACTIONREGISTRY_H
#define QGSMAPLAYERACTIONREGISTRY_H

#include <QObject>
#include <QList>
#include <QMap>
#include <QAction>

#include "qgsmaplayer.h"

class QgsFeature;

/**
* An action which can run on map layers
*/
class GUI_EXPORT QgsMapLayerAction : public QAction
{
Q_OBJECT

public:
/**Creates a map layer action which can run on any layer*/
QgsMapLayerAction( QString name, QObject *parent );
/**Creates a map layer action which can run only on a specific layer*/
QgsMapLayerAction( QString name, QObject *parent, QgsMapLayer* layer );
/**Creates a map layer action which can run on a specific type of layer*/
QgsMapLayerAction( QString name, QObject *parent, QgsMapLayer::LayerType layerType );

~QgsMapLayerAction();

/** True if action can run using the specified layer */
bool canRunUsingLayer( QgsMapLayer* layer ) const;

/** Triggers the action with the specified layer and feature. This also emits the triggeredForLayer( QgsMapLayer *)
* and triggered() slots */
void triggerForFeature( QgsMapLayer* layer, QgsFeature* feature );

/** Triggers the action with the specified layer. This also emits the triggered() slot. */
void triggerForLayer( QgsMapLayer* layer );

signals:
/** Triggered when action has been run for a specific feature */
void triggeredForFeature( QgsMapLayer* layer, QgsFeature* feature );

/** Triggered when action has been run for a specific layer */
void triggeredForLayer( QgsMapLayer* layer );

private:

//true if action is only valid for a single layer
bool mSingleLayer;
//layer if action is only valid for a single layer
QgsMapLayer* mActionLayer;

//true if action is only valid for a specific layer type
bool mSpecificLayerType;
//layer type if action is only valid for a specific layer type
QgsMapLayer::LayerType mLayerType;


};

/**
* This class tracks map layer actions
*/
class GUI_EXPORT QgsMapLayerActionRegistry : public QObject
{
Q_OBJECT

public:
//! Returns the instance pointer, creating the object on the first call
static QgsMapLayerActionRegistry * instance();

~QgsMapLayerActionRegistry();

/**Adds a map layer action to the registry*/
void addMapLayerAction( QgsMapLayerAction * action );

/**Returns the map layer actions which can run on the specified layer*/
QList<QgsMapLayerAction *> mapLayerActions( QgsMapLayer* layer );

/**Removes a map layer action from the registry*/
bool removeMapLayerAction( QgsMapLayerAction *action );

/**Sets the default action for a layer*/
void setDefaultActionForLayer( QgsMapLayer* layer, QgsMapLayerAction* action );
/**Returns the default action for a layer*/
QgsMapLayerAction * defaultActionForLayer( QgsMapLayer* layer );

protected:
//! protected constructor
QgsMapLayerActionRegistry( QObject * parent = 0 );

signals:
/** Triggered when an action is added or removed from the registry */
void changed();

private:

static QgsMapLayerActionRegistry *mInstance;

QList< QgsMapLayerAction* > mMapLayerActionList;

QMap< QgsMapLayer*, QgsMapLayerAction* > mDefaultLayerActionMap;

};

#endif // QGSMAPLAYERACTIONREGISTRY_H