Skip to content

Commit 8a539e0

Browse files
committed
Split subclasses of QgsLayerTreeNode into their own cpp/h files
1 parent 56ee3f4 commit 8a539e0

9 files changed

+574
-548
lines changed

src/core/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ SET(QGIS_CORE_SRCS
5151
diagram/qgstextdiagram.cpp
5252
diagram/qgshistogramdiagram.cpp
5353

54+
layertree/qgslayertreegroup.cpp
55+
layertree/qgslayertreelayer.cpp
5456
layertree/qgslayertreenode.cpp
5557
layertree/qgslayertreeregistrybridge.cpp
5658
layertree/qgslayertreeutils.cpp
@@ -380,6 +382,8 @@ SET(QGIS_CORE_MOC_HDRS
380382
symbology-ng/qgssvgcache.h
381383
symbology-ng/qgsstylev2.h
382384

385+
layertree/qgslayertreegroup.h
386+
layertree/qgslayertreelayer.h
383387
layertree/qgslayertreenode.h
384388
layertree/qgslayertreeregistrybridge.h
385389
)
@@ -590,6 +594,9 @@ SET(QGIS_CORE_HDRS
590594
symbology-ng/qgscptcityarchive.h
591595
symbology-ng/qgsvectorfieldsymbollayer.h
592596

597+
layertree/qgslayertree.h
598+
layertree/qgslayertreegroup.h
599+
layertree/qgslayertreelayer.h
593600
layertree/qgslayertreenode.h
594601
layertree/qgslayertreeregistrybridge.h
595602
layertree/qgslayertreeutils.h

src/core/layertree/qgslayertree.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#define QGSLAYERTREE_H
33

44
#include "qgslayertreenode.h"
5+
#include "qgslayertreegroup.h"
6+
#include "qgslayertreelayer.h"
57

68
namespace QgsLayerTree
79
{
Lines changed: 314 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,314 @@
1+
#include "qgslayertreegroup.h"
2+
3+
#include "qgslayertree.h"
4+
#include "qgslayertreeutils.h"
5+
6+
QgsLayerTreeGroup::QgsLayerTreeGroup(const QString& name, Qt::CheckState checked)
7+
: QgsLayerTreeNode(NodeGroup)
8+
, mName(name)
9+
, mChecked(checked)
10+
, mChangingChildVisibility(false)
11+
{
12+
}
13+
14+
QgsLayerTreeGroup::QgsLayerTreeGroup(const QgsLayerTreeGroup& other)
15+
: QgsLayerTreeNode(other)
16+
, mName(other.mName)
17+
, mChecked(other.mChecked)
18+
, mChangingChildVisibility(false)
19+
{
20+
}
21+
22+
23+
QgsLayerTreeGroup* QgsLayerTreeGroup::addGroup(const QString &name)
24+
{
25+
QgsLayerTreeGroup* grp = new QgsLayerTreeGroup(name);
26+
addChildNode( grp );
27+
return grp;
28+
}
29+
30+
QgsLayerTreeLayer*QgsLayerTreeGroup::insertLayer(int index, QgsMapLayer* layer)
31+
{
32+
QgsLayerTreeLayer* ll = new QgsLayerTreeLayer(layer);
33+
insertChildNode( index, ll );
34+
return ll;
35+
}
36+
37+
QgsLayerTreeLayer* QgsLayerTreeGroup::addLayer(QgsMapLayer* layer)
38+
{
39+
QgsLayerTreeLayer* ll = new QgsLayerTreeLayer(layer);
40+
addChildNode( ll );
41+
return ll;
42+
}
43+
44+
void QgsLayerTreeGroup::connectToChildNode(QgsLayerTreeNode* node)
45+
{
46+
if (QgsLayerTree::isLayer(node))
47+
{
48+
// TODO: this could be handled directly by LayerTreeLayer by listening to QgsMapLayerRegistry...
49+
//QgsLayerTreeLayer* nodeLayer = QgsLayerTree::toLayer(node);
50+
//connect(nodeLayer->layer(), SIGNAL(destroyed()), this, SLOT(layerDestroyed()));
51+
}
52+
53+
connect(node, SIGNAL(visibilityChanged(Qt::CheckState)), this, SLOT(updateVisibilityFromChildren()));
54+
// forward the signal towards the root
55+
connect(node, SIGNAL(customPropertyChanged(QgsLayerTreeNode*,QString)), this, SIGNAL(customPropertyChanged(QgsLayerTreeNode*,QString)));
56+
}
57+
58+
void QgsLayerTreeGroup::insertChildNode(int index, QgsLayerTreeNode* node)
59+
{
60+
QList<QgsLayerTreeNode*> nodes;
61+
nodes << node;
62+
insertChildNodes(index, nodes);
63+
}
64+
65+
void QgsLayerTreeGroup::insertChildNodes(int index, QList<QgsLayerTreeNode*> nodes)
66+
{
67+
// low-level insert
68+
insertChildren(index, nodes);
69+
70+
foreach (QgsLayerTreeNode* node, nodes)
71+
connectToChildNode(node);
72+
73+
updateVisibilityFromChildren();
74+
}
75+
76+
void QgsLayerTreeGroup::addChildNode(QgsLayerTreeNode* node)
77+
{
78+
insertChildNode(-1, node);
79+
}
80+
81+
void QgsLayerTreeGroup::removeChildNode(QgsLayerTreeNode *node)
82+
{
83+
int i = mChildren.indexOf(node);
84+
if (i >= 0)
85+
removeChildAt(i);
86+
}
87+
88+
void QgsLayerTreeGroup::removeLayer(QgsMapLayer* layer)
89+
{
90+
foreach (QgsLayerTreeNode* child, mChildren)
91+
{
92+
if (QgsLayerTree::isLayer(child))
93+
{
94+
QgsLayerTreeLayer* childLayer = QgsLayerTree::toLayer(child);
95+
if (childLayer->layer() == layer)
96+
{
97+
removeChildAt(mChildren.indexOf(child));
98+
break;
99+
}
100+
}
101+
}
102+
}
103+
104+
void QgsLayerTreeGroup::removeChildren(int from, int count)
105+
{
106+
removeChildrenRange(from, count);
107+
108+
updateVisibilityFromChildren();
109+
}
110+
111+
void QgsLayerTreeGroup::removeAllChildren()
112+
{
113+
removeChildren(0, mChildren.count());
114+
}
115+
116+
QgsLayerTreeLayer *QgsLayerTreeGroup::findLayer(const QString& layerId)
117+
{
118+
foreach (QgsLayerTreeNode* child, mChildren)
119+
{
120+
if (QgsLayerTree::isLayer(child))
121+
{
122+
QgsLayerTreeLayer* childLayer = QgsLayerTree::toLayer(child);
123+
if (childLayer->layerId() == layerId)
124+
return childLayer;
125+
}
126+
else if (QgsLayerTree::isGroup(child))
127+
{
128+
QgsLayerTreeLayer* res = QgsLayerTree::toGroup(child)->findLayer(layerId);
129+
if (res)
130+
return res;
131+
}
132+
}
133+
return 0;
134+
}
135+
136+
QList<QgsLayerTreeLayer*> QgsLayerTreeGroup::findLayers() const
137+
{
138+
QList<QgsLayerTreeLayer*> list;
139+
foreach (QgsLayerTreeNode* child, mChildren)
140+
{
141+
if (QgsLayerTree::isLayer(child))
142+
list << QgsLayerTree::toLayer(child);
143+
else if (QgsLayerTree::isGroup(child))
144+
list << QgsLayerTree::toGroup(child)->findLayers();
145+
}
146+
return list;
147+
}
148+
149+
QgsLayerTreeGroup* QgsLayerTreeGroup::findGroup(const QString& name)
150+
{
151+
foreach (QgsLayerTreeNode* child, mChildren)
152+
{
153+
if (QgsLayerTree::isGroup(child))
154+
{
155+
QgsLayerTreeGroup* childGroup = QgsLayerTree::toGroup(child);
156+
if (childGroup->name() == name)
157+
return childGroup;
158+
else
159+
{
160+
QgsLayerTreeGroup* grp = childGroup->findGroup(name);
161+
if (grp)
162+
return grp;
163+
}
164+
}
165+
}
166+
return 0;
167+
}
168+
169+
QgsLayerTreeGroup* QgsLayerTreeGroup::readXML(QDomElement& element)
170+
{
171+
if (element.tagName() != "layer-tree-group")
172+
return 0;
173+
174+
QString name = element.attribute("name");
175+
bool isExpanded = (element.attribute("expanded", "1") == "1");
176+
Qt::CheckState checked = QgsLayerTreeUtils::checkStateFromXml(element.attribute("checked"));
177+
178+
QgsLayerTreeGroup* groupNode = new QgsLayerTreeGroup(name, checked);
179+
groupNode->setExpanded(isExpanded);
180+
181+
groupNode->readCommonXML(element);
182+
183+
groupNode->readChildrenFromXML(element);
184+
185+
return groupNode;
186+
}
187+
188+
void QgsLayerTreeGroup::writeXML(QDomElement& parentElement)
189+
{
190+
QDomDocument doc = parentElement.ownerDocument();
191+
QDomElement elem = doc.createElement("layer-tree-group");
192+
elem.setAttribute("name", mName);
193+
elem.setAttribute("expanded", mExpanded ? "1" : "0");
194+
elem.setAttribute("checked", QgsLayerTreeUtils::checkStateToXml(mChecked));
195+
196+
writeCommonXML(elem);
197+
198+
foreach (QgsLayerTreeNode* node, mChildren)
199+
node->writeXML(elem);
200+
201+
parentElement.appendChild(elem);
202+
}
203+
204+
void QgsLayerTreeGroup::readChildrenFromXML(QDomElement& element)
205+
{
206+
QDomElement childElem = element.firstChildElement();
207+
while (!childElem.isNull())
208+
{
209+
QgsLayerTreeNode* newNode = QgsLayerTreeNode::readXML(childElem);
210+
if (newNode)
211+
addChildNode(newNode);
212+
213+
childElem = childElem.nextSiblingElement();
214+
}
215+
}
216+
217+
QString QgsLayerTreeGroup::dump() const
218+
{
219+
QString header = QString( "GROUP: %1 visible=%2 expanded=%3\n" ).arg( name() ).arg( mChecked ).arg( mExpanded );
220+
QStringList childrenDump;
221+
foreach (QgsLayerTreeNode* node, mChildren)
222+
childrenDump << node->dump().split( "\n" );
223+
for (int i = 0; i < childrenDump.count(); ++i)
224+
childrenDump[i].prepend( " " );
225+
return header + childrenDump.join( "\n" );
226+
}
227+
228+
QgsLayerTreeNode* QgsLayerTreeGroup::clone() const
229+
{
230+
return new QgsLayerTreeGroup(*this);
231+
}
232+
233+
void QgsLayerTreeGroup::setVisible(Qt::CheckState state)
234+
{
235+
if (mChecked == state)
236+
return;
237+
238+
mChecked = state;
239+
emit visibilityChanged(state);
240+
241+
if (mChecked == Qt::Unchecked || mChecked == Qt::Checked)
242+
{
243+
mChangingChildVisibility = true; // guard against running again setVisible() triggered from children
244+
245+
// update children to have the correct visibility
246+
foreach (QgsLayerTreeNode* child, mChildren)
247+
{
248+
if (QgsLayerTree::isGroup(child))
249+
QgsLayerTree::toGroup(child)->setVisible(mChecked);
250+
else if (QgsLayerTree::isLayer(child))
251+
QgsLayerTree::toLayer(child)->setVisible(mChecked == Qt::Checked);
252+
}
253+
254+
mChangingChildVisibility = false;
255+
}
256+
}
257+
258+
QStringList QgsLayerTreeGroup::childLayerIds() const
259+
{
260+
QStringList lst;
261+
foreach (QgsLayerTreeNode* child, mChildren)
262+
{
263+
if (QgsLayerTree::isGroup(child))
264+
lst << QgsLayerTree::toGroup(child)->childLayerIds();
265+
else if (QgsLayerTree::isLayer(child))
266+
lst << QgsLayerTree::toLayer(child)->layerId();
267+
}
268+
return lst;
269+
}
270+
271+
272+
void QgsLayerTreeGroup::layerDestroyed()
273+
{
274+
QgsMapLayer* layer = static_cast<QgsMapLayer*>(sender());
275+
removeLayer(layer);
276+
}
277+
278+
void QgsLayerTreeGroup::updateVisibilityFromChildren()
279+
{
280+
if (mChangingChildVisibility)
281+
return;
282+
283+
if (mChildren.count() == 0)
284+
return;
285+
286+
bool hasVisible = false, hasHidden = false;
287+
288+
foreach (QgsLayerTreeNode* child, mChildren)
289+
{
290+
if (QgsLayerTree::isLayer(child))
291+
{
292+
bool layerVisible = QgsLayerTree::toLayer(child)->isVisible();
293+
if (layerVisible) hasVisible = true;
294+
if (!layerVisible) hasHidden = true;
295+
}
296+
else if (QgsLayerTree::isGroup(child))
297+
{
298+
Qt::CheckState state = QgsLayerTree::toGroup(child)->isVisible();
299+
if (state == Qt::Checked || state == Qt::PartiallyChecked) hasVisible = true;
300+
if (state == Qt::Unchecked || state == Qt::PartiallyChecked) hasHidden = true;
301+
}
302+
}
303+
304+
Qt::CheckState newState;
305+
if (hasVisible && !hasHidden)
306+
newState = Qt::Checked;
307+
else if (hasHidden && !hasVisible)
308+
newState = Qt::Unchecked;
309+
else
310+
newState = Qt::PartiallyChecked;
311+
312+
setVisible(newState);
313+
}
314+

0 commit comments

Comments
 (0)