Skip to content

Commit 01876d1

Browse files
committedAug 6, 2018
Make memory layer indicator respond correctly to making a layer permanent
1 parent 6ecc69f commit 01876d1

File tree

2 files changed

+94
-13
lines changed

2 files changed

+94
-13
lines changed
 

‎src/app/qgslayertreeviewmemoryindicator.cpp

Lines changed: 88 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "qgslayertree.h"
1818
#include "qgslayertreemodel.h"
1919
#include "qgslayertreeview.h"
20+
#include "qgsvectorlayer.h"
2021

2122
QgsLayerTreeViewMemoryIndicatorProvider::QgsLayerTreeViewMemoryIndicatorProvider( QgsLayerTreeView *view )
2223
: QObject( view )
@@ -28,6 +29,7 @@ QgsLayerTreeViewMemoryIndicatorProvider::QgsLayerTreeViewMemoryIndicatorProvider
2829
onAddedChildren( tree, 0, tree->children().count() - 1 );
2930

3031
connect( tree, &QgsLayerTree::addedChildren, this, &QgsLayerTreeViewMemoryIndicatorProvider::onAddedChildren );
32+
connect( tree, &QgsLayerTree::willRemoveChildren, this, &QgsLayerTreeViewMemoryIndicatorProvider::onWillRemoveChildren );
3133
}
3234

3335
void QgsLayerTreeViewMemoryIndicatorProvider::onAddedChildren( QgsLayerTreeNode *node, int indexFrom, int indexTo )
@@ -46,8 +48,11 @@ void QgsLayerTreeViewMemoryIndicatorProvider::onAddedChildren( QgsLayerTreeNode
4648
{
4749
if ( QgsLayerTreeLayer *layerNode = dynamic_cast< QgsLayerTreeLayer * >( childNode ) )
4850
{
49-
if ( layerNode->layer() && layerNode->layer()->dataProvider()->name() == QLatin1String( "memory" ) )
50-
addIndicatorForMemoryLayer( childNode );
51+
if ( QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layerNode->layer() ) )
52+
{
53+
connect( vlayer, &QgsVectorLayer::dataSourceChanged, this, &QgsLayerTreeViewMemoryIndicatorProvider::onDataSourceChanged );
54+
addOrRemoveIndicator( childNode, vlayer );
55+
}
5156
else if ( !layerNode->layer() )
5257
{
5358
// wait for layer to be loaded (e.g. when loading project, first the tree is loaded, afterwards the references to layers are resolved)
@@ -58,14 +63,63 @@ void QgsLayerTreeViewMemoryIndicatorProvider::onAddedChildren( QgsLayerTreeNode
5863
}
5964
}
6065

66+
void QgsLayerTreeViewMemoryIndicatorProvider::onWillRemoveChildren( QgsLayerTreeNode *node, int indexFrom, int indexTo )
67+
{
68+
// recursively disconnect from providers' dataChanged() signal
69+
70+
QList<QgsLayerTreeNode *> children = node->children();
71+
for ( int i = indexFrom; i <= indexTo; ++i )
72+
{
73+
QgsLayerTreeNode *childNode = children[i];
74+
75+
if ( QgsLayerTree::isGroup( childNode ) )
76+
{
77+
onWillRemoveChildren( childNode, 0, childNode->children().count() - 1 );
78+
}
79+
else if ( QgsLayerTree::isLayer( childNode ) )
80+
{
81+
QgsLayerTreeLayer *childLayerNode = QgsLayerTree::toLayer( childNode );
82+
if ( QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( childLayerNode->layer() ) )
83+
{
84+
if ( vlayer )
85+
disconnect( vlayer, &QgsVectorLayer::dataSourceChanged, this, &QgsLayerTreeViewMemoryIndicatorProvider::onDataSourceChanged );
86+
}
87+
}
88+
}
89+
}
90+
6191
void QgsLayerTreeViewMemoryIndicatorProvider::onLayerLoaded()
6292
{
6393
QgsLayerTreeLayer *layerNode = qobject_cast<QgsLayerTreeLayer *>( sender() );
6494
if ( !layerNode )
6595
return;
6696

67-
if ( layerNode->layer() && layerNode->layer()->dataProvider()->name() == QLatin1String( "memory" ) )
68-
addIndicatorForMemoryLayer( layerNode );
97+
if ( QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layerNode->layer() ) )
98+
{
99+
if ( vlayer )
100+
{
101+
connect( vlayer, &QgsVectorLayer::dataSourceChanged, this, &QgsLayerTreeViewMemoryIndicatorProvider::onDataSourceChanged );
102+
addOrRemoveIndicator( layerNode, vlayer );
103+
}
104+
}
105+
}
106+
107+
void QgsLayerTreeViewMemoryIndicatorProvider::onDataSourceChanged()
108+
{
109+
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( sender() );
110+
if ( !vlayer )
111+
return;
112+
113+
// walk the tree and find layer node that needs to be updated
114+
const QList<QgsLayerTreeLayer *> layerNodes = mLayerTreeView->layerTreeModel()->rootGroup()->findLayers();
115+
for ( QgsLayerTreeLayer *node : layerNodes )
116+
{
117+
if ( node->layer() && node->layer() == vlayer )
118+
{
119+
addOrRemoveIndicator( node, vlayer );
120+
break;
121+
}
122+
}
69123
}
70124

71125
std::unique_ptr< QgsLayerTreeViewIndicator > QgsLayerTreeViewMemoryIndicatorProvider::newIndicator()
@@ -77,19 +131,41 @@ std::unique_ptr< QgsLayerTreeViewIndicator > QgsLayerTreeViewMemoryIndicatorProv
77131
return indicator;
78132
}
79133

80-
void QgsLayerTreeViewMemoryIndicatorProvider::addIndicatorForMemoryLayer( QgsLayerTreeNode *node )
134+
void QgsLayerTreeViewMemoryIndicatorProvider::addOrRemoveIndicator( QgsLayerTreeNode *node, QgsVectorLayer *vlayer )
81135
{
82-
const QList<QgsLayerTreeViewIndicator *> nodeIndicators = mLayerTreeView->indicators( node );
136+
const bool isMemory = vlayer->dataProvider()->name() == QLatin1String( "memory" );
83137

84-
// maybe the indicator exists already
85-
for ( QgsLayerTreeViewIndicator *indicator : nodeIndicators )
138+
if ( isMemory )
86139
{
87-
if ( mIndicators.contains( indicator ) )
140+
const QList<QgsLayerTreeViewIndicator *> nodeIndicators = mLayerTreeView->indicators( node );
141+
142+
// maybe the indicator exists already
143+
for ( QgsLayerTreeViewIndicator *indicator : nodeIndicators )
88144
{
89-
return;
145+
if ( mIndicators.contains( indicator ) )
146+
{
147+
return;
148+
}
90149
}
150+
151+
// it does not exist: need to create a new one
152+
mLayerTreeView->addIndicator( node, newIndicator().release() );
91153
}
154+
else
155+
{
156+
const QList<QgsLayerTreeViewIndicator *> nodeIndicators = mLayerTreeView->indicators( node );
92157

93-
// it does not exist: need to create a new one
94-
mLayerTreeView->addIndicator( node, newIndicator().release() );
158+
// there may be existing indicator we need to get rid of
159+
for ( QgsLayerTreeViewIndicator *indicator : nodeIndicators )
160+
{
161+
if ( mIndicators.contains( indicator ) )
162+
{
163+
mLayerTreeView->removeIndicator( node, indicator );
164+
indicator->deleteLater();
165+
return;
166+
}
167+
}
168+
169+
// no indicator was there before, nothing to do
170+
}
95171
}

‎src/app/qgslayertreeviewmemoryindicator.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
class QgsLayerTreeNode;
2525
class QgsLayerTreeView;
26+
class QgsVectorLayer;
2627

2728
//! Adds indicators showing whether layers are memory layers.
2829
class QgsLayerTreeViewMemoryIndicatorProvider : public QObject
@@ -34,11 +35,15 @@ class QgsLayerTreeViewMemoryIndicatorProvider : public QObject
3435
private slots:
3536
//! Connects to signals of layers newly added to the tree
3637
void onAddedChildren( QgsLayerTreeNode *node, int indexFrom, int indexTo );
38+
//! Disconnects from layers about to be removed from the tree
39+
void onWillRemoveChildren( QgsLayerTreeNode *node, int indexFrom, int indexTo );
3740
void onLayerLoaded();
41+
//! Adds/removes indicator of a layer
42+
void onDataSourceChanged();
3843

3944
private:
4045
std::unique_ptr< QgsLayerTreeViewIndicator > newIndicator();
41-
void addIndicatorForMemoryLayer( QgsLayerTreeNode *node );
46+
void addOrRemoveIndicator( QgsLayerTreeNode *node, QgsVectorLayer *vlayer );
4247

4348
private:
4449
QgsLayerTreeView *mLayerTreeView = nullptr;

0 commit comments

Comments
 (0)
Please sign in to comment.