QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
qgslayertreeregistrybridge.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgslayertreeregistrybridge.cpp
3 --------------------------------------
4 Date : May 2014
5 Copyright : (C) 2014 by Martin Dobias
6 Email : wonder dot sk at gmail 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 "qgslayertree.h"
19#include "qgslayertreeutils.h"
20#include "qgslogger.h"
21#include "qgsproject.h"
22
23#include <QString>
24
25#include "moc_qgslayertreeregistrybridge.cpp"
26
27using namespace Qt::StringLiterals;
28
41
47
49{
50 mInsertionPointGroup = insertionPoint.group;
51 mInsertionPointPosition = insertionPoint.position;
52}
53
59
60void QgsLayerTreeRegistryBridge::layersAdded( const QList<QgsMapLayer *> &layers )
61{
62 if ( !mEnabled )
63 return;
64
65 QList<QgsLayerTreeNode *> newNodes;
66 for ( QgsMapLayer *layer : layers )
67 {
68 QgsLayerTreeLayer *nodeLayer = nullptr;
69 switch ( mInsertionMethod )
70 {
72 {
74 if ( !targetGroup )
75 targetGroup = mRoot;
76
77 // returned layer is already owned by the group!
78 nodeLayer = QgsLayerTreeUtils::insertLayerAtOptimalPlacement( targetGroup, layer );
79 break;
80 }
81
84 {
85 nodeLayer = new QgsLayerTreeLayer( layer );
86 newNodes << nodeLayer;
87 break;
88 }
89 }
90
91 if ( !nodeLayer )
92 continue;
93
95
96 // check whether the layer is marked as embedded
97 const QString projectFile = mProject->layerIsEmbedded( nodeLayer->layerId() );
98 if ( !projectFile.isEmpty() )
99 {
100 nodeLayer->setCustomProperty( u"embedded"_s, 1 );
101 nodeLayer->setCustomProperty( u"embedded_project"_s, projectFile );
102 }
103 }
104
105 switch ( mInsertionMethod )
106 {
109 {
110 group->insertChildNodes( mInsertionPointPosition, newNodes );
111 break;
112 }
113 // if no group for the insertion point, then insert into root instead
114 [[fallthrough]];
116 mRoot->insertChildNodes( 0, newNodes );
117 break;
119 break;
120 }
121
122 // tell other components that layers have been added - this signal is used in QGIS to auto-select the first layer
123 emit addedLayersToLayerTree( layers );
124}
125
126void QgsLayerTreeRegistryBridge::layersWillBeRemoved( const QStringList &layerIds )
127{
128 QgsDebugMsgLevel( u"%1 layers will be removed, enabled:%2"_s.arg( layerIds.count() ).arg( mEnabled ), 4 );
129
130 if ( !mEnabled )
131 return;
132
133 // when we start removing child nodes, the bridge would try to remove those layers from
134 // the registry _again_ in groupRemovedChildren() - this prevents it
136
137 const auto constLayerIds = layerIds;
138 for ( const QString &layerId : constLayerIds )
139 {
140 QgsLayerTreeLayer *nodeLayer = mRoot->findLayer( layerId );
141 if ( nodeLayer )
142 qobject_cast<QgsLayerTreeGroup *>( nodeLayer->parent() )->removeChildNode( nodeLayer );
143 }
144
146}
147
148
149static void _collectLayerIdsInGroup( QgsLayerTreeGroup *group, int indexFrom, int indexTo, QStringList &lst )
150{
151 for ( int i = indexFrom; i <= indexTo; ++i )
152 {
153 QgsLayerTreeNode *child = group->children().at( i );
154 if ( QgsLayerTree::isLayer( child ) )
155 {
156 lst << QgsLayerTree::toLayer( child )->layerId();
157 }
158 else if ( QgsLayerTree::isGroup( child ) )
159 {
160 _collectLayerIdsInGroup( QgsLayerTree::toGroup( child ), 0, child->children().count() - 1, lst );
161 }
162 }
163}
164
166{
168 return; // do not try to remove those layers again
169
170 Q_ASSERT( mLayerIdsForRemoval.isEmpty() );
171
172 Q_ASSERT( QgsLayerTree::isGroup( node ) );
174
175 _collectLayerIdsInGroup( group, indexFrom, indexTo, mLayerIdsForRemoval );
176}
177
179{
181 return; // do not try to remove those layers again
182
183 // remove only those that really do not exist in the tree
184 // (ignores layers that were dragged'n'dropped: 1. drop new 2. remove old)
185 QStringList toRemove;
186 const auto constMLayerIdsForRemoval = mLayerIdsForRemoval;
187 for ( const QString &layerId : constMLayerIdsForRemoval )
188 if ( !mRoot->findLayer( layerId ) )
189 toRemove << layerId;
190 mLayerIdsForRemoval.clear();
191
192 QgsDebugMsgLevel( u"%1 layers will be removed"_s.arg( toRemove.count() ), 4 );
193
194 // delay the removal of layers from the registry. There may be other slots connected to map layer registry's signals
195 // that might disrupt the execution flow - e.g. a processEvents() call may force update of layer tree view with
196 // semi-broken tree model
197 QMetaObject::invokeMethod( this, "removeLayersFromRegistry", Qt::QueuedConnection, Q_ARG( QStringList, toRemove ) );
198}
199
201{
202 mProject->removeMapLayers( layerIds );
203}
@ TopOfTree
Layers are added at the top of the layer tree.
Definition qgis.h:4583
@ AboveInsertionPoint
Layers are added in the tree above the insertion point.
Definition qgis.h:4582
@ OptimalInInsertionGroup
Layers are added at optimal locations across the insertion point's group.
Definition qgis.h:4584
Layer tree group node serves as a container for layers and further groups.
Layer tree node points to a map layer.
QString layerId() const
Returns the ID for the map layer associated with this node.
Base class for nodes in a layer tree.
void removedChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
Emitted when one or more nodes has been removed from a node within the tree.
void setCustomProperty(const QString &key, const QVariant &value)
Sets a custom property for the node. Properties are stored in a map and saved in project file.
QList< QgsLayerTreeNode * > children()
Gets list of children of the node. Children are owned by the parent.
void willRemoveChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
Emitted when one or more nodes will be removed from a node within the tree.
QgsLayerTreeNode * parent()
Gets pointer to the parent. If parent is nullptr, the node is a root node.
void setItemVisibilityChecked(bool checked)
Check or uncheck a node (independently of its ancestors or children).
void removeLayersFromRegistry(const QStringList &layerIds)
void layersWillBeRemoved(const QStringList &layerIds)
void layersAdded(const QList< QgsMapLayer * > &layers)
void addedLayersToLayerTree(const QList< QgsMapLayer * > &layers)
Tell others we have just added layers to the tree (used in QGIS to auto-select first newly added laye...
void groupWillRemoveChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
QPointer< QgsLayerTreeGroup > mInsertionPointGroup
QgsLayerTreeRegistryBridge(QgsLayerTreeGroup *root, QgsProject *project, QObject *parent=nullptr)
Create the instance that synchronizes given project with a layer tree root.
Q_DECL_DEPRECATED void setLayerInsertionPoint(QgsLayerTreeGroup *parentGroup, int index)
Set where the new layers should be inserted - can be used to follow current selection.
InsertionPoint layerInsertionPoint() const
Returns the insertion point used to add layers to the tree.
Qgis::LayerTreeInsertionMethod mInsertionMethod
static QgsLayerTreeLayer * insertLayerAtOptimalPlacement(QgsLayerTreeGroup *group, QgsMapLayer *layer)
Inserts a layer within a given group at an optimal index position by insuring a given layer type will...
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
static bool isLayer(const QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
static bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
static QgsLayerTreeGroup * toGroup(QgsLayerTreeNode *node)
Cast node to a group.
Base class for all map layer types.
Definition qgsmaplayer.h:83
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition qgsproject.h:112
void layersWillBeRemoved(const QStringList &layerIds)
Emitted when one or more layers are about to be removed from the registry.
void legendLayersAdded(const QList< QgsMapLayer * > &layers)
Emitted when layers were added to the registry and the legend.
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:63
A structure to define the insertion point to the layer tree.