QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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#include <QPointer>
19#include <QScreen>
20
22#include "qgsvectorlayer.h"
26#include "qgsguiutils.h"
27
29 : QWidget( parent )
30{
31 mTree = new QTreeWidget( this );
32 mTree->setHeaderHidden( true );
33
34 connect( mTree, &QTreeWidget::itemChanged, this, [&]( QTreeWidgetItem *, int ) { emit this->changed(); } );
35
36 // place the tree in a layout
37 QVBoxLayout *vbox = new QVBoxLayout();
38 vbox->setContentsMargins( 0, 0, 0, 0 );
39 vbox->addWidget( mTree );
40
41 setLayout( vbox );
42}
43
45{
46 mLayer = layer;
47 mItems.clear();
48 mTree->clear();
49
50 class TreeFillVisitor : public QgsStyleEntityVisitorInterface
51 {
52 public:
53 TreeFillVisitor( QTreeWidgetItem *layerItem, const QgsVectorLayer *layer, QHash<QString, QTreeWidgetItem *> &items, QScreen *screen )
54 : mLayerItem( layerItem )
55 , mLayer( layer )
56 , mItems( items )
57 , mScreen( screen )
58 {}
59
60 bool visitEnter( const QgsStyleEntityVisitorInterface::Node &node ) override
61 {
63 return false;
64
65 mCurrentIdentifier = node.identifier;
66 mCurrentDescription = node.description;
67
68 return true;
69 }
70
71 void visitSymbol( QTreeWidgetItem *rootItem, const QString &identifier, const QgsSymbol *symbol, QVector<int> rootPath )
72 {
73 for ( int idx = 0; idx < symbol->symbolLayerCount(); idx++ )
74 {
75 const QgsSymbolLayer *sl = symbol->symbolLayer( idx );
76 // Skip mask symbol layers. It makes no sense to take them as mask targets.
77 if ( sl->layerType() == "MaskMarker" )
78 continue;
79
80 const QgsSymbol *subSymbol = const_cast<QgsSymbolLayer *>( sl )->subSymbol();
81
82 QVector<int> indexPath = rootPath;
83 indexPath.append( idx );
84
85 QTreeWidgetItem *slItem = new QTreeWidgetItem();
86 const QIcon slIcon = QgsSymbolLayerUtils::symbolLayerPreviewIcon( sl, Qgis::RenderUnit::Millimeters, QSize( iconSize, iconSize ), QgsMapUnitScale(), symbol->type(), nullptr, QgsScreenProperties( mScreen.data() ) );
87 slItem->setData( 0, Qt::UserRole, idx );
88 slItem->setIcon( 0, slIcon );
89 auto flags = slItem->flags();
90 if ( ! subSymbol || subSymbol->symbolLayerCount() == 0 )
91 {
92 flags.setFlag( Qt::ItemIsUserCheckable, true );
93 slItem->setCheckState( 0, Qt::Unchecked );
94 }
95 else
96 {
97 flags.setFlag( Qt::ItemIsUserCheckable, false );
98 }
99 slItem->setFlags( flags );
100 rootItem->addChild( slItem );
101 slItem->setExpanded( true );
102
103 mItems[sl->id()] = slItem;
104
105 if ( subSymbol )
106 {
107 visitSymbol( slItem, identifier, subSymbol, indexPath );
108 }
109 }
110 }
111
112 bool visit( const QgsStyleEntityVisitorInterface::StyleLeaf &leaf ) override
113 {
114 if ( ! leaf.entity || leaf.entity->type() != QgsStyle::SymbolEntity )
115 return true;
116
117 const auto symbolEntity = static_cast<const QgsStyleSymbolEntity *>( leaf.entity );
118 const QgsSymbol *symbol = symbolEntity->symbol();
119 if ( ! symbol )
120 return true;
121
122 // either leaf.description or mCurrentDescription is defined
123 QTreeWidgetItem *symbolItem = new QTreeWidgetItem( QStringList() << ( mCurrentDescription + leaf.description ) );
124 const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( symbol, QSize( iconSize, iconSize ), 0, nullptr, QgsScreenProperties( mScreen.data() ) );
125 symbolItem->setData( 0, Qt::UserRole, mCurrentIdentifier );
126 symbolItem->setIcon( 0, icon );
127 mLayerItem->addChild( symbolItem );
128 symbolItem->setExpanded( true );
129
130 visitSymbol( symbolItem, leaf.identifier, symbol, {} );
131
132 return true;
133 }
134
135 const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
136 QString mCurrentDescription;
137 QString mCurrentIdentifier;
138 QTreeWidgetItem *mLayerItem;
139 const QgsVectorLayer *mLayer;
140 QHash<QString, QTreeWidgetItem *> &mItems;
141 QPointer< QScreen > mScreen;
142 };
143
144 // populate the tree
145 if ( ! mLayer )
146 return;
147 if ( ! mLayer->renderer() )
148 return;
149
150 TreeFillVisitor visitor( mTree->invisibleRootItem(), mLayer, mItems, screen() );
151 mLayer->renderer()->accept( &visitor );
152}
153
155{
156 QSet<QString> sel;
157 for ( auto it = mItems.begin(); it != mItems.end(); it++ )
158 {
159 if ( it.value()->checkState( 0 ) == Qt::Checked )
160 sel.insert( it.key() );
161 }
162 return sel;
163}
164
165void QgsSymbolLayerSelectionWidget::setSelection( const QSet<QString> &sel )
166{
167 // clear selection
168 for ( auto it = mItems.begin(); it != mItems.end(); it++ )
169 {
170 if ( it.value()->flags() & Qt::ItemIsUserCheckable )
171 it.value()->setCheckState( 0, Qt::Unchecked );
172 }
173
174 // apply selection passed in parameter
175 for ( const QString &lid : sel )
176 {
177 const auto it = mItems.find( lid );
178 if ( it != mItems.end() )
179 ( *it )->setCheckState( 0, Qt::Checked );
180 }
181}
@ Millimeters
Millimeters.
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.
Stores properties relating to a screen.
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:1372
@ 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 symbolLayerPreviewIcon(const QgsSymbolLayer *layer, Qgis::RenderUnit u, QSize size, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::SymbolType parentSymbolType=Qgis::SymbolType::Hybrid, QgsMapLayer *mapLayer=nullptr, const QgsScreenProperties &screen=QgsScreenProperties())
Draws a symbol layer preview to an icon.
static QIcon symbolPreviewIcon(const QgsSymbol *symbol, QSize size, int padding=0, QgsLegendPatchShape *shape=nullptr, const QgsScreenProperties &screen=QgsScreenProperties())
Returns an icon preview for a color ramp.
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:94
QgsSymbolLayer * symbolLayer(int layer)
Returns the symbol layer at the specified index.
Definition: qgssymbol.cpp:760
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:156
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.