QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
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
90 = QgsSymbolLayerUtils::symbolLayerPreviewIcon( sl, Qgis::RenderUnit::Millimeters, QSize( iconSize, iconSize ), QgsMapUnitScale(), symbol->type(), nullptr, QgsScreenProperties( mScreen.data() ) );
91 slItem->setData( 0, Qt::UserRole, idx );
92 slItem->setIcon( 0, slIcon );
93 auto flags = slItem->flags();
94 if ( !subSymbol || subSymbol->symbolLayerCount() == 0 )
95 {
96 flags.setFlag( Qt::ItemIsUserCheckable, true );
97 slItem->setCheckState( 0, Qt::Unchecked );
98 }
99 else
100 {
101 flags.setFlag( Qt::ItemIsUserCheckable, false );
102 }
103 slItem->setFlags( flags );
104 rootItem->addChild( slItem );
105 slItem->setExpanded( true );
106
107 mItems[sl->id()] = slItem;
108
109 if ( subSymbol )
110 {
111 visitSymbol( slItem, identifier, subSymbol, indexPath );
112 }
113 }
114 }
115
116 bool visit( const QgsStyleEntityVisitorInterface::StyleLeaf &leaf ) override
117 {
118 if ( !leaf.entity || leaf.entity->type() != QgsStyle::SymbolEntity )
119 return true;
120
121 const auto symbolEntity = static_cast<const QgsStyleSymbolEntity *>( leaf.entity );
122 const QgsSymbol *symbol = symbolEntity->symbol();
123 if ( !symbol )
124 return true;
125
126 // either leaf.description or mCurrentDescription is defined
127 QTreeWidgetItem *symbolItem = new QTreeWidgetItem( QStringList() << ( mCurrentDescription + leaf.description ) );
128 const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( symbol, QSize( iconSize, iconSize ), 0, nullptr, QgsScreenProperties( mScreen.data() ) );
129 symbolItem->setData( 0, Qt::UserRole, mCurrentIdentifier );
130 symbolItem->setIcon( 0, icon );
131 mLayerItem->addChild( symbolItem );
132 symbolItem->setExpanded( true );
133
134 visitSymbol( symbolItem, leaf.identifier, symbol, {} );
135
136 return true;
137 }
138
139 const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
140 QString mCurrentDescription;
141 QString mCurrentIdentifier;
142 QTreeWidgetItem *mLayerItem;
143 const QgsVectorLayer *mLayer;
144 QHash<QString, QTreeWidgetItem *> &mItems;
145 QPointer<QScreen> mScreen;
146 };
147
148 // populate the tree
149 if ( !mLayer )
150 return;
151 if ( !mLayer->renderer() )
152 return;
153
154 TreeFillVisitor visitor( mTree->invisibleRootItem(), mLayer, mItems, screen() );
155 mLayer->renderer()->accept( &visitor );
156}
157
159{
160 QSet<QString> sel;
161 for ( auto it = mItems.begin(); it != mItems.end(); it++ )
162 {
163 if ( it.value()->checkState( 0 ) == Qt::Checked )
164 sel.insert( it.key() );
165 }
166 return sel;
167}
168
169void QgsSymbolLayerSelectionWidget::setSelection( const QSet<QString> &sel )
170{
171 // clear selection
172 for ( auto it = mItems.begin(); it != mItems.end(); it++ )
173 {
174 if ( it.value()->flags() & Qt::ItemIsUserCheckable )
175 it.value()->setCheckState( 0, Qt::Unchecked );
176 }
177
178 // apply selection passed in parameter
179 for ( const QString &lid : sel )
180 {
181 const auto it = mItems.find( lid );
182 if ( it != mItems.end() )
183 ( *it )->setCheckState( 0, Qt::Checked );
184 }
185}
@ Millimeters
Millimeters.
Definition qgis.h:5341
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:1393
@ 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:227
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:357
Qgis::SymbolType type() const
Returns the symbol's type.
Definition qgssymbol.h:296
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.