Skip to content

Commit

Permalink
allows for plugins to insert actions for layers in TOC, with QgsLegen…
Browse files Browse the repository at this point in the history
…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.
17 changes: 17 additions & 0 deletions python/gui/qgslegendinterface.sip
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
17 changes: 17 additions & 0 deletions src/app/legend/qgsapplegendinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
}

5 changes: 5 additions & 0 deletions src/app/legend/qgsapplegendinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
127 changes: 126 additions & 1 deletion src/app/legend/qgslegend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ void QgsLegend::removeLayers( QStringList theLayers )
{
invLayerRemoved = true;
}
removeLegendLayerActionsForLayer( ll->layer() );
removeItem( ll );
delete ll;
break;
Expand Down Expand Up @@ -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 ) )
{
Expand Down Expand Up @@ -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 >() ;
}
24 changes: 23 additions & 1 deletion src/app/legend/qgslegend.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
4 changes: 0 additions & 4 deletions src/app/legend/qgslegendlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() ) );
}

//////////
Expand Down
20 changes: 20 additions & 0 deletions src/gui/qgslegendinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 42d637d

Please sign in to comment.