mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
[FEATURE] Add a show/hide all context menu for layer tree symbol items
Allows toggling on/off all the symbol items for categorized/graduated/ rule based layers via the right click menu on an item. Previously you'd have to manually toggle each item one-by-one. Fix #13458
This commit is contained in:
parent
dc73fb2a09
commit
91f7918e21
@ -144,6 +144,21 @@ class QgsSymbolV2LegendNode : QgsLayerTreeModelLegendNode
|
||||
//! Get the minimum icon size to prevent cropping
|
||||
//! @note added in 2.10
|
||||
QSize minimumIconSize() const;
|
||||
|
||||
public slots:
|
||||
|
||||
/** Checks all items belonging to the same layer as this node.
|
||||
* @note added in QGIS 2.14
|
||||
* @see uncheckAllItems()
|
||||
*/
|
||||
void checkAllItems();
|
||||
|
||||
/** Unchecks all items belonging to the same layer as this node.
|
||||
* @note added in QGIS 2.14
|
||||
* @see checkAllItems()
|
||||
*/
|
||||
void uncheckAllItems();
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "qgsclipboard.h"
|
||||
#include "qgslayertree.h"
|
||||
#include "qgslayertreemodel.h"
|
||||
#include "qgslayertreemodellegendnode.h"
|
||||
#include "qgslayertreeviewdefaultactions.h"
|
||||
#include "qgsmaplayerstyleguiutils.h"
|
||||
#include "qgsproject.h"
|
||||
@ -188,9 +189,19 @@ QMenu* QgsAppLayerTreeViewMenuProvider::createContextMenu()
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
else if ( QgsLayerTreeModelLegendNode* node = mView->layerTreeModel()->index2legendNode( idx ) )
|
||||
{
|
||||
// symbology item?
|
||||
if ( QgsSymbolV2LegendNode* symbolNode = dynamic_cast< QgsSymbolV2LegendNode* >( node ) )
|
||||
{
|
||||
// symbology item
|
||||
if ( symbolNode->flags() & Qt::ItemIsUserCheckable )
|
||||
{
|
||||
menu->addAction( QgsApplication::getThemeIcon( "/mActionShowAllLayers.png" ), tr( "&Show All Items" ),
|
||||
symbolNode, SLOT( checkAllItems() ) );
|
||||
menu->addAction( QgsApplication::getThemeIcon( "/mActionHideAllLayers.png" ), tr( "&Hide All Items" ),
|
||||
symbolNode, SLOT( uncheckAllItems() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return menu;
|
||||
|
@ -185,6 +185,16 @@ QSize QgsSymbolV2LegendNode::minimumIconSize() const
|
||||
return minSz;
|
||||
}
|
||||
|
||||
void QgsSymbolV2LegendNode::checkAllItems()
|
||||
{
|
||||
checkAll( true );
|
||||
}
|
||||
|
||||
void QgsSymbolV2LegendNode::uncheckAllItems()
|
||||
{
|
||||
checkAll( false );
|
||||
}
|
||||
|
||||
inline
|
||||
QgsRenderContext * QgsSymbolV2LegendNode::createTemporaryRenderContext() const
|
||||
{
|
||||
@ -203,6 +213,22 @@ QgsRenderContext * QgsSymbolV2LegendNode::createTemporaryRenderContext() const
|
||||
return validData ? context.take() : 0;
|
||||
}
|
||||
|
||||
void QgsSymbolV2LegendNode::checkAll( bool state )
|
||||
{
|
||||
QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer*>( mLayerNode->layer() );
|
||||
if ( !vlayer || !vlayer->rendererV2() )
|
||||
return;
|
||||
|
||||
QgsLegendSymbolListV2 symbolList = vlayer->rendererV2()->legendSymbolItemsV2();
|
||||
Q_FOREACH ( const QgsLegendSymbolItemV2& item, symbolList )
|
||||
{
|
||||
vlayer->rendererV2()->checkLegendSymbolItem( item.ruleKey(), state );
|
||||
}
|
||||
|
||||
emit dataChanged();
|
||||
vlayer->triggerRepaint();
|
||||
}
|
||||
|
||||
QVariant QgsSymbolV2LegendNode::data( int role ) const
|
||||
{
|
||||
if ( role == Qt::DisplayRole )
|
||||
|
@ -145,6 +145,8 @@ class CORE_EXPORT QgsLayerTreeModelLegendNode : public QObject
|
||||
*/
|
||||
class CORE_EXPORT QgsSymbolV2LegendNode : public QgsLayerTreeModelLegendNode
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsSymbolV2LegendNode( QgsLayerTreeLayer* nodeLayer, const QgsLegendSymbolItemV2& item, QObject* parent = 0 );
|
||||
~QgsSymbolV2LegendNode();
|
||||
@ -173,6 +175,20 @@ class CORE_EXPORT QgsSymbolV2LegendNode : public QgsLayerTreeModelLegendNode
|
||||
//! @note added in 2.10
|
||||
QSize minimumIconSize() const;
|
||||
|
||||
public slots:
|
||||
|
||||
/** Checks all items belonging to the same layer as this node.
|
||||
* @note added in QGIS 2.14
|
||||
* @see uncheckAllItems()
|
||||
*/
|
||||
void checkAllItems();
|
||||
|
||||
/** Unchecks all items belonging to the same layer as this node.
|
||||
* @note added in QGIS 2.14
|
||||
* @see checkAllItems()
|
||||
*/
|
||||
void uncheckAllItems();
|
||||
|
||||
private:
|
||||
void updateLabel();
|
||||
|
||||
@ -189,6 +205,10 @@ class CORE_EXPORT QgsSymbolV2LegendNode : public QgsLayerTreeModelLegendNode
|
||||
// return a temporary context or null if legendMapViewData are not valid
|
||||
QgsRenderContext * createTemporaryRenderContext() const;
|
||||
|
||||
/** Sets all items belonging to the same layer as this node to the same check state.
|
||||
* @param state check state
|
||||
*/
|
||||
void checkAll( bool state );
|
||||
};
|
||||
|
||||
|
||||
|
@ -21,6 +21,9 @@
|
||||
#include <qgsvectorlayer.h>
|
||||
#include <qgsvectorlayerdiagramprovider.h>
|
||||
#include <qgsvectorlayerlabelprovider.h>
|
||||
#include <qgscategorizedsymbolrendererv2.h>
|
||||
#include <qgslayertreemodel.h>
|
||||
#include <qgslayertreemodellegendnode.h>
|
||||
|
||||
class TestQgsLayerTree : public QObject
|
||||
{
|
||||
@ -34,6 +37,7 @@ class TestQgsLayerTree : public QObject
|
||||
void testCheckStateChildToParent();
|
||||
void testCheckStateMutuallyExclusive();
|
||||
void testCheckStateMutuallyExclusiveEdgeCases();
|
||||
void testShowHideAllSymbolNodes();
|
||||
|
||||
private:
|
||||
|
||||
@ -51,6 +55,9 @@ class TestQgsLayerTree : public QObject
|
||||
|
||||
void TestQgsLayerTree::initTestCase()
|
||||
{
|
||||
QgsApplication::init();
|
||||
QgsApplication::initQgis();
|
||||
|
||||
mRoot = new QgsLayerTreeGroup();
|
||||
mRoot->addGroup( "grp1" );
|
||||
mRoot->addGroup( "grp2" );
|
||||
@ -62,6 +69,7 @@ void TestQgsLayerTree::initTestCase()
|
||||
void TestQgsLayerTree::cleanupTestCase()
|
||||
{
|
||||
delete mRoot;
|
||||
QgsApplication::exitQgis();
|
||||
}
|
||||
|
||||
void TestQgsLayerTree::testCheckStateParentToChild()
|
||||
@ -210,6 +218,56 @@ void TestQgsLayerTree::testCheckStateMutuallyExclusiveEdgeCases()
|
||||
delete root3;
|
||||
}
|
||||
|
||||
void TestQgsLayerTree::testShowHideAllSymbolNodes()
|
||||
{
|
||||
//new memory layer
|
||||
QgsVectorLayer* vl = new QgsVectorLayer( "Point?field=col1:integer", "vl", "memory" );
|
||||
QVERIFY( vl->isValid() );
|
||||
|
||||
QgsMapLayerRegistry::instance()->addMapLayers( QList<QgsMapLayer*>() << vl );
|
||||
|
||||
//create a categorized renderer for layer
|
||||
QgsCategorizedSymbolRendererV2* renderer = new QgsCategorizedSymbolRendererV2();
|
||||
renderer->setClassAttribute( "col1" );
|
||||
renderer->setSourceSymbol( QgsSymbolV2::defaultSymbol( QGis::Point ) );
|
||||
renderer->addCategory( QgsRendererCategoryV2( "a", QgsSymbolV2::defaultSymbol( QGis::Point ), "a" ) );
|
||||
renderer->addCategory( QgsRendererCategoryV2( "b", QgsSymbolV2::defaultSymbol( QGis::Point ), "b" ) );
|
||||
renderer->addCategory( QgsRendererCategoryV2( "c", QgsSymbolV2::defaultSymbol( QGis::Point ), "c" ) );
|
||||
vl->setRendererV2( renderer );
|
||||
|
||||
//create legend with symbology nodes for categorized renderer
|
||||
QgsLayerTreeGroup* root = new QgsLayerTreeGroup();
|
||||
QgsLayerTreeLayer* n = new QgsLayerTreeLayer( vl );
|
||||
root->addChildNode( n );
|
||||
QgsLayerTreeModel* m = new QgsLayerTreeModel( root, 0 );
|
||||
m->refreshLayerLegend( n );
|
||||
|
||||
//test that all nodes are initially checked
|
||||
QList<QgsLayerTreeModelLegendNode*> nodes = m->layerLegendNodes( n );
|
||||
QCOMPARE( nodes.length(), 3 );
|
||||
Q_FOREACH ( QgsLayerTreeModelLegendNode* ln, nodes )
|
||||
{
|
||||
QVERIFY( ln->data( Qt::CheckStateRole ) == Qt::Checked );
|
||||
}
|
||||
//uncheck all and test that all nodes are unchecked
|
||||
static_cast< QgsSymbolV2LegendNode* >( nodes.at( 0 ) )->uncheckAllItems();
|
||||
Q_FOREACH ( QgsLayerTreeModelLegendNode* ln, nodes )
|
||||
{
|
||||
QVERIFY( ln->data( Qt::CheckStateRole ) == Qt::Unchecked );
|
||||
}
|
||||
//check all and test that all nodes are checked
|
||||
static_cast< QgsSymbolV2LegendNode* >( nodes.at( 0 ) )->checkAllItems();
|
||||
Q_FOREACH ( QgsLayerTreeModelLegendNode* ln, nodes )
|
||||
{
|
||||
QVERIFY( ln->data( Qt::CheckStateRole ) == Qt::Checked );
|
||||
}
|
||||
|
||||
//cleanup
|
||||
delete m;
|
||||
delete root;
|
||||
QgsMapLayerRegistry::instance()->removeMapLayers( QList<QgsMapLayer*>() << vl );
|
||||
}
|
||||
|
||||
|
||||
QTEST_MAIN( TestQgsLayerTree )
|
||||
#include "testqgslayertree.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user