QGIS API Documentation 3.30.0-'s-Hertogenbosch (f186b8efe0)
qgssymbollayerselectionwidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgssymbollayerselectionwidget.h
3 ---------------------
4 begin : July 2019
5 copyright : (C) 2019 by Hugo Mercier
6 email : hugo dot mercier at oslandia dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#include <QTreeWidget>
17#include <QVBoxLayout>
18
20#include "qgsproject.h"
21#include "qgsvectorlayer.h"
25#include "qgsguiutils.h"
26
28 : QWidget( parent )
29{
30 mTree = new QTreeWidget( this );
31 mTree->setHeaderHidden( true );
32
33 connect( mTree, &QTreeWidget::itemChanged, this, [&]( QTreeWidgetItem *, int ) { emit this->changed(); } );
34
35 // place the tree in a layout
36 QVBoxLayout *vbox = new QVBoxLayout();
37 vbox->setContentsMargins( 0, 0, 0, 0 );
38 vbox->addWidget( mTree );
39
40 setLayout( vbox );
41}
42
44{
45 mLayer = layer;
46 mItems.clear();
47 mTree->clear();
48
49 class TreeFillVisitor : public QgsStyleEntityVisitorInterface
50 {
51 public:
52 TreeFillVisitor( QTreeWidgetItem *layerItem, const QgsVectorLayer *layer, QHash<QString, QTreeWidgetItem *> &items ):
53 mLayerItem( layerItem ), mLayer( layer ), mItems( items )
54 {}
55
56 bool visitEnter( const QgsStyleEntityVisitorInterface::Node &node ) override
57 {
59 return false;
60
61 mCurrentIdentifier = node.identifier;
62 mCurrentDescription = node.description;
63
64 return true;
65 }
66
67 void visitSymbol( QTreeWidgetItem *rootItem, const QString &identifier, const QgsSymbol *symbol, QVector<int> rootPath )
68 {
69 for ( int idx = 0; idx < symbol->symbolLayerCount(); idx++ )
70 {
71 const QgsSymbolLayer *sl = symbol->symbolLayer( idx );
72 // Skip mask symbol layers. It makes no sense to take them as mask targets.
73 if ( sl->layerType() == "MaskMarker" )
74 continue;
75
76 const QgsSymbol *subSymbol = const_cast<QgsSymbolLayer *>( sl )->subSymbol();
77
78 QVector<int> indexPath = rootPath;
79 indexPath.append( idx );
80
81 QTreeWidgetItem *slItem = new QTreeWidgetItem();
82 const QIcon slIcon = QgsSymbolLayerUtils::symbolLayerPreviewIcon( sl, Qgis::RenderUnit::Millimeters, QSize( iconSize, iconSize ), QgsMapUnitScale(), symbol->type() );
83 slItem->setData( 0, Qt::UserRole, idx );
84 slItem->setIcon( 0, slIcon );
85 auto flags = slItem->flags();
86 if ( ! subSymbol || subSymbol->symbolLayerCount() == 0 )
87 {
88 flags.setFlag( Qt::ItemIsUserCheckable, true );
89 slItem->setCheckState( 0, Qt::Unchecked );
90 }
91 else
92 {
93 flags.setFlag( Qt::ItemIsUserCheckable, false );
94 }
95 slItem->setFlags( flags );
96 rootItem->addChild( slItem );
97 slItem->setExpanded( true );
98
99 mItems[sl->id()] = slItem;
100
101 if ( subSymbol )
102 {
103 visitSymbol( slItem, identifier, subSymbol, indexPath );
104 }
105 }
106 }
107
108 bool visit( const QgsStyleEntityVisitorInterface::StyleLeaf &leaf ) override
109 {
110 if ( ! leaf.entity || leaf.entity->type() != QgsStyle::SymbolEntity )
111 return true;
112
113 const auto symbolEntity = static_cast<const QgsStyleSymbolEntity *>( leaf.entity );
114 const QgsSymbol *symbol = symbolEntity->symbol();
115 if ( ! symbol )
116 return true;
117
118 // either leaf.description or mCurrentDescription is defined
119 QTreeWidgetItem *symbolItem = new QTreeWidgetItem( QStringList() << ( mCurrentDescription + leaf.description ) );
120 const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( symbol, QSize( iconSize, iconSize ) );
121 symbolItem->setData( 0, Qt::UserRole, mCurrentIdentifier );
122 symbolItem->setIcon( 0, icon );
123 mLayerItem->addChild( symbolItem );
124 symbolItem->setExpanded( true );
125
126 visitSymbol( symbolItem, leaf.identifier, symbol, {} );
127
128 return true;
129 }
130
131 const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
132 QString mCurrentDescription;
133 QString mCurrentIdentifier;
134 QTreeWidgetItem *mLayerItem;
135 const QgsVectorLayer *mLayer;
136 QHash<QString, QTreeWidgetItem *> &mItems;
137 };
138
139 // populate the tree
140 if ( ! mLayer )
141 return;
142 if ( ! mLayer->renderer() )
143 return;
144
145 TreeFillVisitor visitor( mTree->invisibleRootItem(), mLayer, mItems );
146 mLayer->renderer()->accept( &visitor );
147}
148
150{
151 QSet<QString> sel;
152 for ( auto it = mItems.begin(); it != mItems.end(); it++ )
153 {
154 if ( it.value()->checkState( 0 ) == Qt::Checked )
155 sel.insert( it.key() );
156 }
157 return sel;
158}
159
160void QgsSymbolLayerSelectionWidget::setSelection( const QSet<QString> &sel )
161{
162 // clear selection
163 for ( auto it = mItems.begin(); it != mItems.end(); it++ )
164 {
165 if ( it.value()->flags() & Qt::ItemIsUserCheckable )
166 it.value()->setCheckState( 0, Qt::Unchecked );
167 }
168
169 // apply selection passed in parameter
170 for ( const QString &lid : sel )
171 {
172 const auto it = mItems.find( lid );
173 if ( it != mItems.end() )
174 ( *it )->setCheckState( 0, Qt::Checked );
175 }
176}
virtual bool accept(QgsStyleEntityVisitorInterface *visitor) const
Accepts the specified symbology visitor, causing it to visit all symbols associated with the renderer...
Struct for storing maximum and minimum scales for measurements in map units.
virtual QgsStyle::StyleEntity type() const =0
Returns the type of style entity.
An interface for classes which can visit style entity (e.g.
@ SymbolRule
Rule based symbology or label child rule.
A symbol entity for QgsStyle databases.
Definition: qgsstyle.h:1341
@ SymbolEntity
Symbols.
Definition: qgsstyle.h:180
void setSelection(const QSet< QString > &sel)
Sets the symbol layer selection.
QgsSymbolLayerSelectionWidget(QWidget *parent=nullptr)
Default constructor.
void changed()
Signal emitted when something the configuration is changed.
QSet< QString > selection() const
Returns current symbol layer selection.
void setLayer(const QgsVectorLayer *layer)
Populate the tree with selectable symbol layers from a given layer.
static QIcon symbolPreviewIcon(const QgsSymbol *symbol, QSize size, int padding=0, QgsLegendPatchShape *shape=nullptr)
Returns an icon preview for a color ramp.
static QIcon symbolLayerPreviewIcon(const QgsSymbolLayer *layer, Qgis::RenderUnit u, QSize size, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::SymbolType parentSymbolType=Qgis::SymbolType::Hybrid, QgsMapLayer *mapLayer=nullptr)
Draws a symbol layer preview to an icon.
virtual QString layerType() const =0
Returns a string that represents this layer type.
QString id() const
Returns symbol layer identifier This id is unique in the whole project.
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:93
QgsSymbolLayer * symbolLayer(int layer)
Returns the symbol layer at the specified index.
Definition: qgssymbol.cpp:756
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
Definition: qgssymbol.h:215
Qgis::SymbolType type() const
Returns the symbol's type.
Definition: qgssymbol.h:152
Represents a vector layer which manages a vector based data sets.
QgsFeatureRenderer * renderer()
Returns the feature renderer used for rendering the features in the layer in 2D map views.
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
Contains information relating to a node (i.e.
QString identifier
A string identifying the node.
QString description
A string describing the node.
QgsStyleEntityVisitorInterface::NodeType type
Node type.
Contains information relating to the style entity currently being visited.
QString description
A string describing the style entity.
const QgsStyleEntityInterface * entity
Reference to style entity being visited.
QString identifier
A string identifying the style entity.