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