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