Skip to content
Permalink
Browse files
allows for plugins to insert actions for layers in TOC, with QgsLegen…
…dInterface::addLegendLayerAction()
  • Loading branch information
etiennesky committed Jan 28, 2013
1 parent db7b46a commit 42d637d
Show file tree
Hide file tree
Showing 7 changed files with 208 additions and 6 deletions.
@@ -51,6 +51,23 @@ class QgsLegendInterface : QObject
//! @note added in 1.5
virtual bool isLayerVisible( QgsMapLayer * ml ) = 0;

/** Add action for layers in the legend
* @note added in 2.0
*/
virtual void addLegendLayerAction( QAction* action, QString menu, QString id,
QgsMapLayer::LayerType type, bool allLayers ) = 0;

/** Add action for a specific layers in the legend.
* Use this in combination with addLegendLayerAction( allLayers = False )
* @note added in 2.0
*/
virtual void addLegendLayerActionForLayer( QAction* action, QgsMapLayer* layer ) = 0;

/** Remove action for layers in the legend
* @note added in 2.0
*/
virtual bool removeLegendLayerAction( QAction* action ) = 0;

signals:

//! emitted when a group index has changed
@@ -191,3 +191,20 @@ void QgsAppLegendInterface::refreshLayerSymbology( QgsMapLayer *ml )
{
mLegend->refreshLayerSymbology( ml->id() );
}

void QgsAppLegendInterface::addLegendLayerAction( QAction* action,
QString menu, QString id, QgsMapLayer::LayerType type, bool allLayers )
{
mLegend->addLegendLayerAction( action, menu, id, type, allLayers );
}

void QgsAppLegendInterface::addLegendLayerActionForLayer( QAction* action, QgsMapLayer* layer )
{
mLegend->addLegendLayerActionForLayer( action, layer );
}

bool QgsAppLegendInterface::removeLegendLayerAction( QAction* action )
{
return mLegend->removeLegendLayerAction( action );
}

@@ -67,6 +67,11 @@ class QgsAppLegendInterface : public QgsLegendInterface
//! Check if a layer is visible
bool isLayerVisible( QgsMapLayer * ml );

void addLegendLayerAction( QAction* action, QString menu, QString id,
QgsMapLayer::LayerType type, bool allLayers );
void addLegendLayerActionForLayer( QAction* action, QgsMapLayer* layer );
bool removeLegendLayerAction( QAction* action );

public slots:

//! Add a new group
@@ -366,6 +366,7 @@ void QgsLegend::removeLayers( QStringList theLayers )
{
invLayerRemoved = true;
}
removeLegendLayerActionsForLayer( ll->layer() );
removeItem( ll );
delete ll;
break;
@@ -761,7 +762,73 @@ void QgsLegend::handleRightClickEvent( QTreeWidgetItem* item, const QPoint& posi
{
if ( li->type() == QgsLegendItem::LEGEND_LAYER )
{
qobject_cast<QgsLegendLayer*>( li )->addToPopupMenu( theMenu );
QgsLegendLayer* lyr = qobject_cast<QgsLegendLayer*>( li );
lyr->addToPopupMenu( theMenu );

// add custom layer actions
QList< LegendLayerAction > actions = legendLayerActions( lyr->layer()->type() );
if ( ! actions.isEmpty() )
{
theMenu.addSeparator();
QList<QMenu*> theMenus;
for ( int i = 0; i < actions.count(); i++ )
{
if ( actions[i].allLayers || actions[i].layers.contains( lyr->layer() ) )
{
if ( actions[i].menu.isEmpty() )
{
theMenu.addAction( actions[i].action );
}
else
{
// find or create menu for given menu name
// adapted from QgisApp::getPluginMenu( QString menuName )
QString menuName = actions[i].menu;
#ifdef Q_WS_MAC
// Mac doesn't have '&' keyboard shortcuts.
menuName.remove( QChar( '&' ) );
#endif
QAction* before = 0;
QMenu* newMenu = 0;
QString dst = menuName;
dst.remove( QChar( '&' ) );
foreach ( QMenu* menu, theMenus )
{
QString src = menu->title();
src.remove( QChar( '&' ) );
int comp = dst.localeAwareCompare( src );
if ( comp < 0 )
{
// Add item before this one
before = menu->menuAction();
break;
}
else if ( comp == 0 )
{
// Plugin menu item already exists
newMenu = menu;
break;
}
}
if ( ! newMenu )
{
// It doesn't exist, so create
newMenu = new QMenu( menuName, this );
theMenus.append( newMenu );
// Where to put it? - we worked that out above...
theMenu.insertMenu( before, newMenu );
}
// QMenu* menu = getMenu( actions[i].menu, &theBeforeSep, &theAfterSep, &theMenu );
newMenu->addAction( actions[i].action );
}
}
}
theMenu.addSeparator();
}

// properties goes on bottom of menu for consistency with normal ui standards
// e.g. kde stuff
theMenu.addAction( tr( "&Properties" ), QgisApp::instance(), SLOT( layerProperties() ) );

if ( li->parent() && !parentGroupEmbedded( li ) )
{
@@ -2969,3 +3036,61 @@ void QgsLegend::groupSelectedLayers()
}
}

void QgsLegend::addLegendLayerAction( QAction* action, QString menu, QString id,
QgsMapLayer::LayerType type, bool allLayers )
{
mLegendLayerActionMap[type].append( LegendLayerAction( action, menu, id, allLayers ) );
}

bool QgsLegend::removeLegendLayerAction( QAction* action )
{
QMap< QgsMapLayer::LayerType, QList< LegendLayerAction > >::iterator it;
for ( it = mLegendLayerActionMap.begin();
it != mLegendLayerActionMap.end(); ++it )
{
for ( int i = 0; i < it->count(); i++ )
{
if (( *it )[i].action == action )
{
( *it ).removeAt( i );
return true;
}
}
}
return false;
}

void QgsLegend::addLegendLayerActionForLayer( QAction* action, QgsMapLayer* layer )
{
QMap< QgsMapLayer::LayerType, QList< LegendLayerAction > >::iterator it;
for ( it = mLegendLayerActionMap.begin();
it != mLegendLayerActionMap.end(); ++it )
{
for ( int i = 0; i < it->count(); i++ )
{
if (( *it )[i].action == action )
{
( *it )[i].layers.append( layer );
return;
}
}
}
}

void QgsLegend::removeLegendLayerActionsForLayer( QgsMapLayer* layer )
{
QMap< QgsMapLayer::LayerType, QList< LegendLayerAction > >::iterator it;
for ( it = mLegendLayerActionMap.begin();
it != mLegendLayerActionMap.end(); ++it )
{
for ( int i = 0; i < it->count(); i++ )
{
( *it )[i].layers.removeAll( layer );
}
}
}

QList< LegendLayerAction > QgsLegend::legendLayerActions( QgsMapLayer::LayerType type ) const
{
return mLegendLayerActionMap.contains( type ) ? mLegendLayerActionMap.value( type ) : QList< LegendLayerAction >() ;
}
@@ -37,6 +37,8 @@ class QTreeWidgetItem;
class QgsCoordinateReferenceSystem;
class QgsMapCanvasLayer;

#include "qgsmaplayer.h"

//Information about relationship between groups and layers
//key: group name (or null strings for single layers without groups)
//value: containter with layer ids contained in the group
@@ -50,10 +52,21 @@ struct DrawingOrderInfo
bool embeddedGroup;
};

struct LegendLayerAction
{
LegendLayerAction( QAction* a, QString m, QString i, bool all )
: action( a ), menu( m ), id( i ), allLayers( all ) {}
QAction* action;
QString menu;
QString id;
bool allLayers;
QList<QgsMapLayer*> layers;
};

/**
\class QgsLegend
\brief A Legend treeview for QGIS
Map legend is a specialised QListView designed to show grooups of map layers,
Map legend is a specialised QListView designed to show groups of map layers,
map layers, and the map layer members, properties and symbols for each layer.
The legend supports simple operations such as displaying an ordered list of
@@ -362,6 +375,13 @@ class QgsLegend : public QTreeWidget
/** Create a new group for the selected items **/
void groupSelectedLayers();

void addLegendLayerAction( QAction* action, QString menu, QString id,
QgsMapLayer::LayerType type, bool allLayers );
bool removeLegendLayerAction( QAction* action );
void addLegendLayerActionForLayer( QAction* action, QgsMapLayer* layer );
void removeLegendLayerActionsForLayer( QgsMapLayer* layer );
QList< LegendLayerAction > legendLayerActions( QgsMapLayer::LayerType type ) const;

protected:

/*!Event handler for mouse movements.
@@ -549,6 +569,8 @@ class QgsLegend : public QTreeWidget
//! Widget that holds the indicator line //
QWidget *mInsertionLine;

QMap< QgsMapLayer::LayerType, QList< LegendLayerAction > > mLegendLayerActionMap;

#ifdef QGISDEBUG
void showItem( QString msg, QTreeWidgetItem *item );
#endif
@@ -520,10 +520,6 @@ void QgsLegendLayer::addToPopupMenu( QMenu& theMenu )
// disable duplication of plugin layers
duplicateLayersAction->setEnabled( false );
}

// properties goes on bottom of menu for consistency with normal ui standards
// e.g. kde stuff
theMenu.addAction( tr( "&Properties" ), QgisApp::instance(), SLOT( layerProperties() ) );
}

//////////
@@ -24,6 +24,9 @@

class QgsMapLayer;
class QTreeWidgetItem;
class QAction;

#include "qgsmaplayer.h"

//Information about relationship between groups and layers
//key: group name (or null strings for single layers without groups)
@@ -83,6 +86,23 @@ class GUI_EXPORT QgsLegendInterface : public QObject
//! @note added in 1.5
virtual bool isLayerVisible( QgsMapLayer * ml ) = 0;

/** Add action for layers in the legend
* @note added in 2.0
*/
virtual void addLegendLayerAction( QAction* action, QString menu, QString id,
QgsMapLayer::LayerType type, bool allLayers ) = 0;

/** Add action for a specific layers in the legend.
* Use this in combination with addLegendLayerAction( allLayers = False )
* @note added in 2.0
*/
virtual void addLegendLayerActionForLayer( QAction* action, QgsMapLayer* layer ) = 0;

/** Remove action for layers in the legend
* @note added in 2.0
*/
virtual bool removeLegendLayerAction( QAction* action ) = 0;

signals:

//! emitted when a group index has changed

0 comments on commit 42d637d

Please sign in to comment.