QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
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
20#include "qgsproject.h"
21#include "qgslogger.h"
22
24 : QObject( parent )
25 , mRoot( root )
26 , mProject( project )
27 , mRegistryRemovingLayers( false )
28 , mEnabled( true )
29 , mNewLayersVisible( true )
30 , mInsertionPoint( root, 0 )
31{
33 connect( mProject, qOverload<const QStringList &>( &QgsProject::layersWillBeRemoved ), this, &QgsLayerTreeRegistryBridge::layersWillBeRemoved );
34
37}
38
40{
41 mInsertionPoint.group = parentGroup;
43}
44
46{
47 mInsertionPoint = insertionPoint;
48}
49
50void QgsLayerTreeRegistryBridge::layersAdded( const QList<QgsMapLayer *> &layers )
51{
52 if ( !mEnabled )
53 return;
54
55 QList<QgsLayerTreeNode *> nodes;
56 for ( QgsMapLayer *layer : layers )
57 {
58 QgsLayerTreeLayer *nodeLayer = new QgsLayerTreeLayer( layer );
60
61 nodes << nodeLayer;
62
63 // check whether the layer is marked as embedded
64 const QString projectFile = mProject->layerIsEmbedded( nodeLayer->layerId() );
65 if ( !projectFile.isEmpty() )
66 {
67 nodeLayer->setCustomProperty( QStringLiteral( "embedded" ), 1 );
68 nodeLayer->setCustomProperty( QStringLiteral( "embedded_project" ), projectFile );
69 }
70 }
71
72 // add new layers to the right place
74
75 // tell other components that layers have been added - this signal is used in QGIS to auto-select the first layer
76 emit addedLayersToLayerTree( layers );
77}
78
79void QgsLayerTreeRegistryBridge::layersWillBeRemoved( const QStringList &layerIds )
80{
81 QgsDebugMsgLevel( QStringLiteral( "%1 layers will be removed, enabled:%2" ).arg( layerIds.count() ).arg( mEnabled ), 4 );
82
83 if ( !mEnabled )
84 return;
85
86 // when we start removing child nodes, the bridge would try to remove those layers from
87 // the registry _again_ in groupRemovedChildren() - this prevents it
89
90 const auto constLayerIds = layerIds;
91 for ( const QString &layerId : constLayerIds )
92 {
93 QgsLayerTreeLayer *nodeLayer = mRoot->findLayer( layerId );
94 if ( nodeLayer )
95 qobject_cast<QgsLayerTreeGroup *>( nodeLayer->parent() )->removeChildNode( nodeLayer );
96 }
97
99}
100
101
102static void _collectLayerIdsInGroup( QgsLayerTreeGroup *group, int indexFrom, int indexTo, QStringList &lst )
103{
104 for ( int i = indexFrom; i <= indexTo; ++i )
105 {
106 QgsLayerTreeNode *child = group->children().at( i );
107 if ( QgsLayerTree::isLayer( child ) )
108 {
109 lst << QgsLayerTree::toLayer( child )->layerId();
110 }
111 else if ( QgsLayerTree::isGroup( child ) )
112 {
113 _collectLayerIdsInGroup( QgsLayerTree::toGroup( child ), 0, child->children().count() - 1, lst );
114 }
115 }
116}
117
119{
121 return; // do not try to remove those layers again
122
123 Q_ASSERT( mLayerIdsForRemoval.isEmpty() );
124
125 Q_ASSERT( QgsLayerTree::isGroup( node ) );
127
128 _collectLayerIdsInGroup( group, indexFrom, indexTo, mLayerIdsForRemoval );
129}
130
132{
134 return; // do not try to remove those layers again
135
136 // remove only those that really do not exist in the tree
137 // (ignores layers that were dragged'n'dropped: 1. drop new 2. remove old)
138 QStringList toRemove;
139 const auto constMLayerIdsForRemoval = mLayerIdsForRemoval;
140 for ( const QString &layerId : constMLayerIdsForRemoval )
141 if ( !mRoot->findLayer( layerId ) )
142 toRemove << layerId;
143 mLayerIdsForRemoval.clear();
144
145 QgsDebugMsgLevel( QStringLiteral( "%1 layers will be removed" ).arg( toRemove.count() ), 4 );
146
147 // delay the removal of layers from the registry. There may be other slots connected to map layer registry's signals
148 // that might disrupt the execution flow - e.g. a processEvents() call may force update of layer tree view with
149 // semi-broken tree model
150 QMetaObject::invokeMethod( this, "removeLayersFromRegistry", Qt::QueuedConnection, Q_ARG( QStringList, toRemove ) );
151}
152
154{
155 mProject->removeMapLayers( layerIds );
156}
Layer tree group node serves as a container for layers and further groups.
void insertChildNodes(int index, const QList< QgsLayerTreeNode * > &nodes)
Insert existing nodes at specified position.
QgsLayerTreeLayer * findLayer(QgsMapLayer *layer) const
Find layer node representing the map layer.
Layer tree node points to a map layer.
QString layerId() const
Returns the ID for the map layer associated with this node.
This class is a 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)
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.
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
Definition: qgslayertree.h:75
static bool isLayer(const QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
Definition: qgslayertree.h:53
static bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
Definition: qgslayertree.h:43
static QgsLayerTreeGroup * toGroup(QgsLayerTreeNode *node)
Cast node to a group.
Definition: qgslayertree.h:64
Base class for all map layer types.
Definition: qgsmaplayer.h:73
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:104
void layersWillBeRemoved(const QStringList &layerIds)
Emitted when one or more layers are about to be removed from the registry.
void removeMapLayers(const QStringList &layerIds)
Remove a set of layers from the registry by layer ID.
void legendLayersAdded(const QList< QgsMapLayer * > &layers)
Emitted, when a layer was added to the registry and the legend.
QString layerIsEmbedded(const QString &id) const
Returns the source project file path if the layer with matching id is embedded from other project fil...
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
A structure to define the insertion point to the layer tree.