QGIS API Documentation 3.99.0-Master (09f76ad7019)
Loading...
Searching...
No Matches
qgsmasksourceselectionwidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmasksourceselectionwidget.cpp
3 ---------------------
4 begin : September 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"
19#include "qgslayertree.h"
20#include "qgslayertreelayer.h"
21#include "qgsnewnamedialog.h"
22#include "qgsproject.h"
23#include "qgsrenderer.h"
29#include "qgssymbollayerutils.h"
30#include "qgsvectorlayer.h"
32
33#include <QAction>
34#include <QComboBox>
35#include <QInputDialog>
36#include <QLabel>
37#include <QMenu>
38#include <QMessageBox>
39#include <QPointer>
40#include <QScreen>
41#include <QString>
42#include <QToolButton>
43#include <QTreeWidget>
44#include <QVBoxLayout>
45
46#include "moc_qgsmasksourceselectionwidget.cpp"
47
48using namespace Qt::StringLiterals;
49
50static void expandAll( QTreeWidgetItem *item )
51{
52 for ( int i = 0; i < item->childCount(); i++ )
53 expandAll( item->child( i ) );
54 item->setExpanded( true );
55}
56
58{
59 std::cout << ref.layerId().toLocal8Bit().constData() << "/" << ref.symbolLayerIdV2().toLocal8Bit().constData();
60}
61
63 : QWidget( parent )
64{
65 QVBoxLayout *vbox = new QVBoxLayout();
66 vbox->setContentsMargins( 0, 0, 0, 0 );
67
68 QHBoxLayout *hLayout = new QHBoxLayout();
69
70 mSetComboBox = new QComboBox();
71 mManagerModel = new QgsSelectiveMaskingSourceSetManagerModel( QgsProject::instance()->selectiveMaskingSourceSetManager(), this );
72 mManagerModel->setAllowEmptyObject( true );
73 mManagerProxyModel = new QgsSelectiveMaskingSourceSetManagerProxyModel( this );
74 mManagerProxyModel->setSourceModel( mManagerModel );
75 mSetComboBox->setModel( mManagerProxyModel );
76 connect( mSetComboBox, qOverload< int >( &QComboBox::currentIndexChanged ), this, &QgsMaskSourceSelectionWidget::selectedSetChanged );
77
78 mSetsToolButton = new QToolButton();
79 mSetsToolButton->setText( u"…"_s );
80 mSetsToolButton->setPopupMode( QToolButton::InstantPopup );
81
82 QMenu *toolMenu = new QMenu( mSetsToolButton );
83 connect( toolMenu, &QMenu::aboutToShow, this, [this] {
84 const bool isCustomSelected = isCustomSet();
85 mRemoveAction->setEnabled( !isCustomSelected );
86 mRenameAction->setEnabled( !isCustomSelected );
87 } );
88 QAction *addAction = new QAction( tr( "New Selective Masking Set…" ), toolMenu );
89 connect( addAction, &QAction::triggered, this, &QgsMaskSourceSelectionWidget::newSet );
90 toolMenu->addAction( addAction );
91 mRemoveAction = new QAction( tr( "Remove Set…" ), toolMenu );
92 connect( mRemoveAction, &QAction::triggered, this, &QgsMaskSourceSelectionWidget::removeSet );
93 toolMenu->addAction( mRemoveAction );
94 mRenameAction = new QAction( tr( "Rename Set…" ), toolMenu );
95 connect( mRenameAction, &QAction::triggered, this, &QgsMaskSourceSelectionWidget::renameSet );
96 toolMenu->addAction( mRenameAction );
97 mSetsToolButton->setMenu( toolMenu );
98
99 hLayout->addWidget( new QLabel( tr( "Preset" ) ) );
100 hLayout->addWidget( mSetComboBox, 1 );
101 hLayout->addWidget( mSetsToolButton, 1 );
102 vbox->addLayout( hLayout );
103
104 mTree = new QTreeWidget( this );
105 mTree->setHeaderHidden( true );
106
107 connect( mTree, &QTreeWidget::itemChanged, this, &QgsMaskSourceSelectionWidget::onItemChanged );
108
109 vbox->addWidget( mTree, 1 );
110
111 setLayout( vbox );
112}
113
115{
116 mBlockChangedSignals++;
117 mTree->clear();
118 mItems.clear();
119
120 class SymbolLayerFillVisitor : public QgsStyleEntityVisitorInterface
121 {
122 public:
123 SymbolLayerFillVisitor( QTreeWidgetItem *layerItem, const QgsVectorLayer *layer, QHash<QgsSymbolLayerReference, QTreeWidgetItem *> &items, QScreen *screen )
124 : mLayerItem( layerItem )
125 , mLayer( layer )
126 , mItems( items )
127 , mScreen( screen )
128 {}
129
130 bool visitEnter( const QgsStyleEntityVisitorInterface::Node &node ) override
131 {
133 return false;
134
135 mCurrentDescription = node.description;
136
137 return true;
138 }
139
140 struct TreeNode
141 {
142 TreeNode( const QgsSymbol *_symbol, const QgsSymbolLayer *_sl = nullptr )
143 : sl( _sl ), symbol( _symbol ) {};
144
145 const QgsSymbolLayer *sl = nullptr;
146 const QgsSymbol *symbol = nullptr;
147 QList<TreeNode> children;
148 };
149
150
151 bool visitSymbol( TreeNode &parent, const QString &identifier, const QgsSymbol *symbol, QVector<int> rootPath )
152 {
153 bool ret = false;
154 for ( int idx = 0; idx < symbol->symbolLayerCount(); idx++ )
155 {
156 QgsSymbolLayer *sl = const_cast<QgsSymbol *>( symbol )->symbolLayer( idx );
157 QgsSymbol *subSymbol = sl->subSymbol();
158
159 QVector<int> indexPath = rootPath;
160 indexPath.append( idx );
161
162 TreeNode node( symbol, sl );
163 if ( ( sl->layerType() == "MaskMarker" ) || ( subSymbol && visitSymbol( node, identifier, subSymbol, indexPath ) ) )
164 {
165 ret = true;
166 parent.children << node;
167 }
168 }
169 return ret;
170 }
171
172 bool visit( const QgsStyleEntityVisitorInterface::StyleLeaf &leaf ) override
173 {
174 if ( !leaf.entity || leaf.entity->type() != QgsStyle::SymbolEntity )
175 return true;
176
177 const auto symbolEntity = static_cast<const QgsStyleSymbolEntity *>( leaf.entity );
178 const QgsSymbol *symbol = symbolEntity->symbol();
179 if ( !symbol )
180 return true;
181
182 TreeNode node( symbol );
183 if ( visitSymbol( node, leaf.identifier, symbol, {} ) )
184 createItems( leaf.description, mLayerItem, node );
185
186 return true;
187 }
188
189 void createItems( const QString &leafDescription, QTreeWidgetItem *rootItem, const TreeNode &node )
190 {
191 QTreeWidgetItem *item = nullptr;
192 // root symbol node
193 if ( !node.sl )
194 {
195 item = new QTreeWidgetItem( rootItem, QStringList() << ( mCurrentDescription + leafDescription ) );
196 const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( node.symbol, QSize( iconSize, iconSize ), 0, nullptr, QgsScreenProperties( mScreen.data() ) );
197 item->setIcon( 0, icon );
198 }
199 // symbol layer node
200 else
201 {
202 item = new QTreeWidgetItem( rootItem );
203 const QIcon slIcon = QgsSymbolLayerUtils::symbolLayerPreviewIcon( node.sl, Qgis::RenderUnit::Millimeters, QSize( iconSize, iconSize ), QgsMapUnitScale(), node.symbol->type(), nullptr, QgsScreenProperties( mScreen.data() ) );
204 item->setIcon( 0, slIcon );
205 if ( node.sl->layerType() == "MaskMarker" )
206 {
207 item->setText( 0, QObject::tr( "Mask symbol layer" ) );
208 item->setFlags( item->flags() | Qt::ItemIsUserCheckable );
209 item->setCheckState( 0, Qt::Unchecked );
210
211 const QgsSymbolLayerReference ref( mLayer->id(), node.sl->id() );
212 mItems[ref] = item;
213 }
214 }
215
216 rootItem->addChild( item );
217
218 for ( TreeNode child : node.children )
219 createItems( leafDescription, item, child );
220 };
221
222 const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
223 QString mCurrentDescription;
224 QTreeWidgetItem *mLayerItem;
225 const QgsVectorLayer *mLayer;
226 QHash<QgsSymbolLayerReference, QTreeWidgetItem *> &mItems;
227 QPointer<QScreen> mScreen;
228 };
229
230 class LabelMasksVisitor : public QgsStyleEntityVisitorInterface
231 {
232 public:
233 LabelMasksVisitor( QTreeWidgetItem *layerItem, const QgsVectorLayer *layer, QHash<QgsSymbolLayerReference, QTreeWidgetItem *> &items )
234 : mLayerItem( layerItem ), mLayer( layer ), mItems( items )
235 {}
236 bool visitEnter( const QgsStyleEntityVisitorInterface::Node &node ) override
237 {
239 {
240 currentRule = node.identifier;
241 currentDescription = node.description;
242 return true;
243 }
244 return false;
245 }
246 bool visit( const QgsStyleEntityVisitorInterface::StyleLeaf &leaf ) override
247 {
248 if ( leaf.entity && leaf.entity->type() == QgsStyle::LabelSettingsEntity )
249 {
250 auto labelSettingsEntity = static_cast<const QgsStyleLabelSettingsEntity *>( leaf.entity );
251 if ( labelSettingsEntity->settings().format().mask().enabled() )
252 {
253 const QString maskTitle = currentRule.isEmpty()
254 ? QObject::tr( "Label mask" )
255 : QObject::tr( "Label mask for '%1' rule" ).arg( currentDescription );
256 QTreeWidgetItem *slItem = new QTreeWidgetItem( mLayerItem, QStringList() << maskTitle );
257 slItem->setFlags( slItem->flags() | Qt::ItemIsUserCheckable );
258 slItem->setCheckState( 0, Qt::Unchecked );
259 mLayerItem->addChild( slItem );
260 mItems[QgsSymbolLayerReference( "__labels__" + mLayer->id(), currentRule )] = slItem;
261 }
262 }
263 return true;
264 }
265
266 QHash<QString, QHash<QString, QSet<QgsSymbolLayerId>>> masks;
267 // Current label rule, empty string for a simple labeling
268 QString currentRule;
269 QString currentDescription;
270 QTreeWidgetItem *mLayerItem;
271 const QgsVectorLayer *mLayer;
272 QHash<QgsSymbolLayerReference, QTreeWidgetItem *> &mItems;
273 };
274
275 // populate the tree
276 const auto layers = QgsProject::instance()->layerTreeRoot()->findLayers();
277 for ( const QgsLayerTreeLayer *layerTreeLayer : layers )
278 {
279 QgsMapLayer *layer = layerTreeLayer->layer();
280 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
281 if ( !vl )
282 continue;
283 if ( !vl->renderer() )
284 continue;
285
286 auto layerItem = std::make_unique<QTreeWidgetItem>( mTree, QStringList() << layer->name() );
287 layerItem->setData( 0, Qt::UserRole, QVariant::fromValue( vl ) );
288
289 if ( vl->labeling() )
290 {
291 LabelMasksVisitor lblVisitor( layerItem.get(), vl, mItems );
292 vl->labeling()->accept( &lblVisitor );
293 }
294
295 SymbolLayerFillVisitor slVisitor( layerItem.get(), vl, mItems, screen() );
296 vl->renderer()->accept( &slVisitor );
297
298 if ( layerItem->childCount() > 0 )
299 mTree->addTopLevelItem( layerItem.release() );
300 }
301
302 expandAll( mTree->invisibleRootItem() );
303 mBlockChangedSignals--;
304}
305
307{
309
310 const QModelIndex selectedIndex = mManagerProxyModel->mapToSource( mManagerProxyModel->index( mSetComboBox->currentIndex(), 0 ) );
311 const bool isCustomSet = mManagerModel->data( selectedIndex, static_cast< int >( QgsSelectiveMaskingSourceSetManagerModel::CustomRole::IsEmptyObject ) ).toBool();
312 if ( !isCustomSet )
313 {
314 set.setName( mManagerModel->data( selectedIndex, Qt::DisplayRole ).toString() );
315 set.setId( mManagerModel->data( selectedIndex, static_cast< int >( QgsSelectiveMaskingSourceSetManagerModel::CustomRole::SetId ) ).toString() );
316 }
317
318 for ( auto it = mItems.begin(); it != mItems.end(); it++ )
319 {
320 if ( it.value()->checkState( 0 ) == Qt::Checked )
321 {
322 const QgsSymbolLayerReference &ref = it.key();
324 const bool isLabeling = ref.layerId().startsWith( "__labels__" );
325 if ( isLabeling )
326 {
328 source.setLayerId( ref.layerId().mid( 10 ) );
329 }
330 else
331 {
333 source.setLayerId( ref.layerId() );
334 }
335 source.setSourceId( ref.symbolLayerIdV2() );
336 set.append( source );
337 }
338 }
339 return set;
340}
341
343{
344 // Clear current selection
345 mBlockChangedSignals++;
346 for ( auto it = mItems.begin(); it != mItems.end(); it++ )
347 {
348 it.value()->setCheckState( 0, Qt::Unchecked );
349 }
350
351 const QVector< QgsSelectiveMaskSource > sources = set.sources();
352 for ( const QgsSelectiveMaskSource &source : sources )
353 {
354 QString layerId;
355 switch ( source.sourceType() )
356 {
358 layerId = source.layerId();
359 break;
361 layerId = u"__labels__%1"_s.arg( source.layerId() );
362 break;
363 }
364 const auto it = mItems.find( QgsSymbolLayerReference( layerId, source.sourceId() ) );
365 if ( it != mItems.end() )
366 {
367 it.value()->setCheckState( 0, Qt::Checked );
368 }
369 }
370 if ( !set.isValid() )
371 {
372 mSetComboBox->setCurrentIndex( 0 );
373 }
374 else
375 {
376 mSetComboBox->setCurrentIndex( mSetComboBox->findText( set.name() ) );
377 }
378 mBlockChangedSignals--;
379}
380
381void QgsMaskSourceSelectionWidget::selectedSetChanged()
382{
383 mBlockChangedSignals++;
384 if ( !isCustomSet() )
385 {
386 const QModelIndex selectedIndex = mManagerProxyModel->mapToSource( mManagerProxyModel->index( mSetComboBox->currentIndex(), 0 ) );
387 const QString selectedSetId = mManagerModel->data( selectedIndex, static_cast< int >( QgsSelectiveMaskingSourceSetManagerModel::CustomRole::SetId ) ).toString();
389 setSourceSet( set );
390 }
391 mBlockChangedSignals--;
392
393 emitChanged();
394}
395
396void QgsMaskSourceSelectionWidget::emitChanged()
397{
398 if ( !mBlockChangedSignals )
399 {
400 emit changed();
401 }
402}
403
404void QgsMaskSourceSelectionWidget::onItemChanged()
405{
406 if ( mBlockChangedSignals )
407 return;
408
409 if ( !isCustomSet() )
410 {
411 const QgsSelectiveMaskingSourceSet set = sourceSet();
413 }
414 emitChanged();
415}
416
417void QgsMaskSourceSelectionWidget::newSet()
418{
420
421 QStringList existingNames;
422 const QVector<QgsSelectiveMaskingSourceSet> sets = QgsProject::instance()->selectiveMaskingSourceSetManager()->sets();
423 existingNames.reserve( sets.size() );
424 for ( const QgsSelectiveMaskingSourceSet &set : sets )
425 {
426 existingNames << set.name();
427 }
428
429 QgsNewNameDialog dlg( tr( "selective masking set" ), newTitle, QStringList(), existingNames, Qt::CaseSensitive, this );
430 dlg.setWindowTitle( tr( "Create Selective Masking Set" ) );
431 dlg.setHintString( tr( "Enter a unique selective masking set name" ) );
432 dlg.setOverwriteEnabled( false );
433 dlg.setAllowEmptyName( false );
434 dlg.setConflictingNameWarning( tr( "A masking set with this name already exists." ) );
435
436 if ( dlg.exec() != QDialog::Accepted )
437 {
438 return;
439 }
440
441 QgsSelectiveMaskingSourceSet newSet;
442 newSet.setName( dlg.name() );
444 mSetComboBox->setCurrentIndex( mSetComboBox->findText( newSet.name() ) );
445}
446
447void QgsMaskSourceSelectionWidget::removeSet()
448{
449 if ( isCustomSet() )
450 return;
451
452 const QString setName = mSetComboBox->currentText();
453 if ( QMessageBox::warning( this, tr( "Remove Selective Masking Set" ), tr( "Do you really want to remove the selective masking set “%1”?" ).arg( setName ), QMessageBox::Ok | QMessageBox::Cancel ) != QMessageBox::Ok )
454 {
455 return;
456 }
457
458 mSetComboBox->setCurrentIndex( 0 );
460}
461
462void QgsMaskSourceSelectionWidget::renameSet()
463{
464 if ( isCustomSet() )
465 return;
466
467 const QString setName = mSetComboBox->currentText();
468
469 QStringList existingNames;
470 const QVector<QgsSelectiveMaskingSourceSet> sets = QgsProject::instance()->selectiveMaskingSourceSetManager()->sets();
471 existingNames.reserve( sets.size() );
472 for ( const QgsSelectiveMaskingSourceSet &set : sets )
473 {
474 if ( set.name() != setName )
475 existingNames << set.name();
476 }
477
478 QgsNewNameDialog dlg( tr( "selective masking set" ), setName, QStringList(), existingNames, Qt::CaseSensitive, this );
479 dlg.setWindowTitle( tr( "Rename Selective Masking Set" ) );
480 dlg.setHintString( tr( "Enter a unique selective masking set name" ) );
481 dlg.setOverwriteEnabled( false );
482 dlg.setAllowEmptyName( false );
483 dlg.setConflictingNameWarning( tr( "A masking set with this name already exists." ) );
484
485 if ( dlg.exec() != QDialog::Accepted )
486 {
487 return;
488 }
489
491}
492
493bool QgsMaskSourceSelectionWidget::isCustomSet() const
494{
495 const QModelIndex selectedIndex = mManagerProxyModel->mapToSource( mManagerProxyModel->index( mSetComboBox->currentIndex(), 0 ) );
496 return mManagerModel->data( selectedIndex, static_cast< int >( QgsSelectiveMaskingSourceSetManagerModel::CustomRole::IsEmptyObject ) ).toBool();
497}
@ Label
A mask generated from a labeling provider.
Definition qgis.h:3127
@ SymbolLayer
A mask generated from a symbol layer.
Definition qgis.h:3126
@ Millimeters
Millimeters.
Definition qgis.h:5291
virtual bool accept(QgsStyleEntityVisitorInterface *visitor) const
Accepts the specified symbology visitor, causing it to visit all symbols associated with the labeling...
virtual bool accept(QgsStyleEntityVisitorInterface *visitor) const
Accepts the specified symbology visitor, causing it to visit all symbols associated with the renderer...
QList< QgsLayerTreeLayer * > findLayers() const
Find all layer nodes.
Layer tree node points to a map layer.
Base class for all map layer types.
Definition qgsmaplayer.h:83
QString name
Definition qgsmaplayer.h:87
Struct for storing maximum and minimum scales for measurements in map units.
void changed()
Emitted when an item was changed.
QgsSelectiveMaskingSourceSet sourceSet() const
Returns the current masking source set.
void update()
Updates the possible sources, from the project layers.
QgsMaskSourceSelectionWidget(QWidget *parent=nullptr)
constructor
void setSourceSet(const QgsSelectiveMaskingSourceSet &set)
Sets the current masking source set.
static QgsProject * instance()
Returns the QgsProject singleton instance.
QgsLayerTree * layerTreeRoot() const
Returns pointer to the root (invisible) node of the project's layer tree.
const QgsSelectiveMaskingSourceSetManager * selectiveMaskingSourceSetManager() const
Returns the project's selective masking set manager, which manages storage of a set of selective mask...
Stores properties relating to a screen.
Encapsulates a single source for selective masking (e.g.
void setSourceId(const QString &id)
Sets the symbol layer or label rule id.
void setLayerId(const QString &id)
Sets the source layer id.
void setSourceType(Qgis::SelectiveMaskSourceType type)
Sets the source type.
List model representing the selective masking source sets available in a selective masking source set...
QVariant data(const QModelIndex &index, int role) const override
QSortFilterProxyModel subclass for QgsSelectiveMaskingSourceSetManagerModel.
bool renameSet(const QString &oldName, const QString &newName)
Renames a set in the manager from oldName to newName.
QVector< QgsSelectiveMaskingSourceSet > sets() const
Returns a list of all sets contained in the manager.
QgsSelectiveMaskingSourceSet setById(const QString &id) const
Returns the set with a matching id, or an invalid set if no matching sets were found.
bool addSet(const QgsSelectiveMaskingSourceSet &set)
Adds a set to the manager.
QString generateUniqueTitle() const
Generates a unique title for a new set, which does not clash with any already contained by the manage...
bool removeSet(const QString &name)
Removes the set with matching name from the manager.
bool updateSet(const QgsSelectiveMaskingSourceSet &set)
Updates the definition of a set already in the manager.
Represents a named set of selective masking sources (QgsSelectiveMaskSource).
void setName(const QString &name)
Sets the set's unique name.
void setId(const QString &id)
Sets the unique identifier for the set.
QVector< QgsSelectiveMaskSource > sources() const
Returns the list of selective mask sources configured in this set.
void append(const QgsSelectiveMaskSource &source)
Appends a source to the set.
QString name() const
Returns the set's unique name.
bool isValid() const
Returns true if the source set is valid, or false if it is invalid (default constructed).
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 label settings entity for QgsStyle databases.
Definition qgsstyle.h:1491
A symbol entity for QgsStyle databases.
Definition qgsstyle.h:1398
@ LabelSettingsEntity
Label settings.
Definition qgsstyle.h:211
@ SymbolEntity
Symbols.
Definition qgsstyle.h:206
Type used to refer to a specific symbol layer in a symbol of a layer.
QString symbolLayerIdV2() const
The symbol layer's id.
QString layerId() const
The referenced vector layer / feature renderer.
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.
virtual QgsSymbol * subSymbol()
Returns the symbol's sub symbol, if present.
Abstract base class for all rendered symbols.
Definition qgssymbol.h:231
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
Definition qgssymbol.h:353
Represents a vector layer which manages a vector based dataset.
const QgsAbstractVectorLayerLabeling * labeling() const
Access to const labeling configuration.
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,...
void printSymbolLayerRef(const QgsSymbolLayerReference &ref)
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.