Skip to content

Commit 42d637d

Browse files
committedJan 28, 2013
allows for plugins to insert actions for layers in TOC, with QgsLegendInterface::addLegendLayerAction()
1 parent db7b46a commit 42d637d

File tree

7 files changed

+208
-6
lines changed

7 files changed

+208
-6
lines changed
 

‎python/gui/qgslegendinterface.sip‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,23 @@ class QgsLegendInterface : QObject
5151
//! @note added in 1.5
5252
virtual bool isLayerVisible( QgsMapLayer * ml ) = 0;
5353

54+
/** Add action for layers in the legend
55+
* @note added in 2.0
56+
*/
57+
virtual void addLegendLayerAction( QAction* action, QString menu, QString id,
58+
QgsMapLayer::LayerType type, bool allLayers ) = 0;
59+
60+
/** Add action for a specific layers in the legend.
61+
* Use this in combination with addLegendLayerAction( allLayers = False )
62+
* @note added in 2.0
63+
*/
64+
virtual void addLegendLayerActionForLayer( QAction* action, QgsMapLayer* layer ) = 0;
65+
66+
/** Remove action for layers in the legend
67+
* @note added in 2.0
68+
*/
69+
virtual bool removeLegendLayerAction( QAction* action ) = 0;
70+
5471
signals:
5572

5673
//! emitted when a group index has changed

‎src/app/legend/qgsapplegendinterface.cpp‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,20 @@ void QgsAppLegendInterface::refreshLayerSymbology( QgsMapLayer *ml )
191191
{
192192
mLegend->refreshLayerSymbology( ml->id() );
193193
}
194+
195+
void QgsAppLegendInterface::addLegendLayerAction( QAction* action,
196+
QString menu, QString id, QgsMapLayer::LayerType type, bool allLayers )
197+
{
198+
mLegend->addLegendLayerAction( action, menu, id, type, allLayers );
199+
}
200+
201+
void QgsAppLegendInterface::addLegendLayerActionForLayer( QAction* action, QgsMapLayer* layer )
202+
{
203+
mLegend->addLegendLayerActionForLayer( action, layer );
204+
}
205+
206+
bool QgsAppLegendInterface::removeLegendLayerAction( QAction* action )
207+
{
208+
return mLegend->removeLegendLayerAction( action );
209+
}
210+

‎src/app/legend/qgsapplegendinterface.h‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ class QgsAppLegendInterface : public QgsLegendInterface
6767
//! Check if a layer is visible
6868
bool isLayerVisible( QgsMapLayer * ml );
6969

70+
void addLegendLayerAction( QAction* action, QString menu, QString id,
71+
QgsMapLayer::LayerType type, bool allLayers );
72+
void addLegendLayerActionForLayer( QAction* action, QgsMapLayer* layer );
73+
bool removeLegendLayerAction( QAction* action );
74+
7075
public slots:
7176

7277
//! Add a new group

‎src/app/legend/qgslegend.cpp‎

Lines changed: 126 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ void QgsLegend::removeLayers( QStringList theLayers )
366366
{
367367
invLayerRemoved = true;
368368
}
369+
removeLegendLayerActionsForLayer( ll->layer() );
369370
removeItem( ll );
370371
delete ll;
371372
break;
@@ -761,7 +762,73 @@ void QgsLegend::handleRightClickEvent( QTreeWidgetItem* item, const QPoint& posi
761762
{
762763
if ( li->type() == QgsLegendItem::LEGEND_LAYER )
763764
{
764-
qobject_cast<QgsLegendLayer*>( li )->addToPopupMenu( theMenu );
765+
QgsLegendLayer* lyr = qobject_cast<QgsLegendLayer*>( li );
766+
lyr->addToPopupMenu( theMenu );
767+
768+
// add custom layer actions
769+
QList< LegendLayerAction > actions = legendLayerActions( lyr->layer()->type() );
770+
if ( ! actions.isEmpty() )
771+
{
772+
theMenu.addSeparator();
773+
QList<QMenu*> theMenus;
774+
for ( int i = 0; i < actions.count(); i++ )
775+
{
776+
if ( actions[i].allLayers || actions[i].layers.contains( lyr->layer() ) )
777+
{
778+
if ( actions[i].menu.isEmpty() )
779+
{
780+
theMenu.addAction( actions[i].action );
781+
}
782+
else
783+
{
784+
// find or create menu for given menu name
785+
// adapted from QgisApp::getPluginMenu( QString menuName )
786+
QString menuName = actions[i].menu;
787+
#ifdef Q_WS_MAC
788+
// Mac doesn't have '&' keyboard shortcuts.
789+
menuName.remove( QChar( '&' ) );
790+
#endif
791+
QAction* before = 0;
792+
QMenu* newMenu = 0;
793+
QString dst = menuName;
794+
dst.remove( QChar( '&' ) );
795+
foreach ( QMenu* menu, theMenus )
796+
{
797+
QString src = menu->title();
798+
src.remove( QChar( '&' ) );
799+
int comp = dst.localeAwareCompare( src );
800+
if ( comp < 0 )
801+
{
802+
// Add item before this one
803+
before = menu->menuAction();
804+
break;
805+
}
806+
else if ( comp == 0 )
807+
{
808+
// Plugin menu item already exists
809+
newMenu = menu;
810+
break;
811+
}
812+
}
813+
if ( ! newMenu )
814+
{
815+
// It doesn't exist, so create
816+
newMenu = new QMenu( menuName, this );
817+
theMenus.append( newMenu );
818+
// Where to put it? - we worked that out above...
819+
theMenu.insertMenu( before, newMenu );
820+
}
821+
// QMenu* menu = getMenu( actions[i].menu, &theBeforeSep, &theAfterSep, &theMenu );
822+
newMenu->addAction( actions[i].action );
823+
}
824+
}
825+
}
826+
theMenu.addSeparator();
827+
}
828+
829+
// properties goes on bottom of menu for consistency with normal ui standards
830+
// e.g. kde stuff
831+
theMenu.addAction( tr( "&Properties" ), QgisApp::instance(), SLOT( layerProperties() ) );
765832

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

3039+
void QgsLegend::addLegendLayerAction( QAction* action, QString menu, QString id,
3040+
QgsMapLayer::LayerType type, bool allLayers )
3041+
{
3042+
mLegendLayerActionMap[type].append( LegendLayerAction( action, menu, id, allLayers ) );
3043+
}
3044+
3045+
bool QgsLegend::removeLegendLayerAction( QAction* action )
3046+
{
3047+
QMap< QgsMapLayer::LayerType, QList< LegendLayerAction > >::iterator it;
3048+
for ( it = mLegendLayerActionMap.begin();
3049+
it != mLegendLayerActionMap.end(); ++it )
3050+
{
3051+
for ( int i = 0; i < it->count(); i++ )
3052+
{
3053+
if (( *it )[i].action == action )
3054+
{
3055+
( *it ).removeAt( i );
3056+
return true;
3057+
}
3058+
}
3059+
}
3060+
return false;
3061+
}
3062+
3063+
void QgsLegend::addLegendLayerActionForLayer( QAction* action, QgsMapLayer* layer )
3064+
{
3065+
QMap< QgsMapLayer::LayerType, QList< LegendLayerAction > >::iterator it;
3066+
for ( it = mLegendLayerActionMap.begin();
3067+
it != mLegendLayerActionMap.end(); ++it )
3068+
{
3069+
for ( int i = 0; i < it->count(); i++ )
3070+
{
3071+
if (( *it )[i].action == action )
3072+
{
3073+
( *it )[i].layers.append( layer );
3074+
return;
3075+
}
3076+
}
3077+
}
3078+
}
3079+
3080+
void QgsLegend::removeLegendLayerActionsForLayer( QgsMapLayer* layer )
3081+
{
3082+
QMap< QgsMapLayer::LayerType, QList< LegendLayerAction > >::iterator it;
3083+
for ( it = mLegendLayerActionMap.begin();
3084+
it != mLegendLayerActionMap.end(); ++it )
3085+
{
3086+
for ( int i = 0; i < it->count(); i++ )
3087+
{
3088+
( *it )[i].layers.removeAll( layer );
3089+
}
3090+
}
3091+
}
3092+
3093+
QList< LegendLayerAction > QgsLegend::legendLayerActions( QgsMapLayer::LayerType type ) const
3094+
{
3095+
return mLegendLayerActionMap.contains( type ) ? mLegendLayerActionMap.value( type ) : QList< LegendLayerAction >() ;
3096+
}

‎src/app/legend/qgslegend.h‎

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ class QTreeWidgetItem;
3737
class QgsCoordinateReferenceSystem;
3838
class QgsMapCanvasLayer;
3939

40+
#include "qgsmaplayer.h"
41+
4042
//Information about relationship between groups and layers
4143
//key: group name (or null strings for single layers without groups)
4244
//value: containter with layer ids contained in the group
@@ -50,10 +52,21 @@ struct DrawingOrderInfo
5052
bool embeddedGroup;
5153
};
5254

55+
struct LegendLayerAction
56+
{
57+
LegendLayerAction( QAction* a, QString m, QString i, bool all )
58+
: action( a ), menu( m ), id( i ), allLayers( all ) {}
59+
QAction* action;
60+
QString menu;
61+
QString id;
62+
bool allLayers;
63+
QList<QgsMapLayer*> layers;
64+
};
65+
5366
/**
5467
\class QgsLegend
5568
\brief A Legend treeview for QGIS
56-
Map legend is a specialised QListView designed to show grooups of map layers,
69+
Map legend is a specialised QListView designed to show groups of map layers,
5770
map layers, and the map layer members, properties and symbols for each layer.
5871
5972
The legend supports simple operations such as displaying an ordered list of
@@ -362,6 +375,13 @@ class QgsLegend : public QTreeWidget
362375
/** Create a new group for the selected items **/
363376
void groupSelectedLayers();
364377

378+
void addLegendLayerAction( QAction* action, QString menu, QString id,
379+
QgsMapLayer::LayerType type, bool allLayers );
380+
bool removeLegendLayerAction( QAction* action );
381+
void addLegendLayerActionForLayer( QAction* action, QgsMapLayer* layer );
382+
void removeLegendLayerActionsForLayer( QgsMapLayer* layer );
383+
QList< LegendLayerAction > legendLayerActions( QgsMapLayer::LayerType type ) const;
384+
365385
protected:
366386

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

572+
QMap< QgsMapLayer::LayerType, QList< LegendLayerAction > > mLegendLayerActionMap;
573+
552574
#ifdef QGISDEBUG
553575
void showItem( QString msg, QTreeWidgetItem *item );
554576
#endif

‎src/app/legend/qgslegendlayer.cpp‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -520,10 +520,6 @@ void QgsLegendLayer::addToPopupMenu( QMenu& theMenu )
520520
// disable duplication of plugin layers
521521
duplicateLayersAction->setEnabled( false );
522522
}
523-
524-
// properties goes on bottom of menu for consistency with normal ui standards
525-
// e.g. kde stuff
526-
theMenu.addAction( tr( "&Properties" ), QgisApp::instance(), SLOT( layerProperties() ) );
527523
}
528524

529525
//////////

‎src/gui/qgslegendinterface.h‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424

2525
class QgsMapLayer;
2626
class QTreeWidgetItem;
27+
class QAction;
28+
29+
#include "qgsmaplayer.h"
2730

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

89+
/** Add action for layers in the legend
90+
* @note added in 2.0
91+
*/
92+
virtual void addLegendLayerAction( QAction* action, QString menu, QString id,
93+
QgsMapLayer::LayerType type, bool allLayers ) = 0;
94+
95+
/** Add action for a specific layers in the legend.
96+
* Use this in combination with addLegendLayerAction( allLayers = False )
97+
* @note added in 2.0
98+
*/
99+
virtual void addLegendLayerActionForLayer( QAction* action, QgsMapLayer* layer ) = 0;
100+
101+
/** Remove action for layers in the legend
102+
* @note added in 2.0
103+
*/
104+
virtual bool removeLegendLayerAction( QAction* action ) = 0;
105+
86106
signals:
87107

88108
//! emitted when a group index has changed

0 commit comments

Comments
 (0)
Please sign in to comment.