Skip to content

Commit

Permalink
Project layer order returns all layers in order, not just visible ones
Browse files Browse the repository at this point in the history
Otherwise map themes with different visible layers cannot be
correctly ordered
  • Loading branch information
nyalldawson committed Mar 13, 2017
1 parent 9faa628 commit 5eccaf6
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 9 deletions.
1 change: 1 addition & 0 deletions doc/api_break.dox
Expand Up @@ -1261,6 +1261,7 @@ QgsLayerTreeMapCanvasBridge {#qgis_api_break_3_0_QgsLayerTreeMapCanvasBri
-----------------

- setAutoEnableCrsTransform() and autoEnableCrsTransform() were removed. CRS transformation is now always enabled.
- setCanvasLayers() now requires a third map layer list argument for storage of all layers in the layer tree order.


QgsLayerTreeModel {#qgis_api_break_3_0_QgsLayerTreeMode}
Expand Down
4 changes: 2 additions & 2 deletions python/gui/layertree/qgslayertreemapcanvasbridge.sip
Expand Up @@ -64,8 +64,8 @@ class QgsLayerTreeMapCanvasBridge : QObject

void defaultLayerOrder( QgsLayerTreeNode* node, QStringList& order ) const;

//! Fill canvasLayers and overviewLayers lists from node and its descendants
void setCanvasLayers( QgsLayerTreeNode* node, QList<QgsMapLayer*> &canvasLayers, QList<QgsMapLayer*>& overviewLayers );
void setCanvasLayers( QgsLayerTreeNode *node, QList<QgsMapLayer *> &canvasLayers, QList<QgsMapLayer *> &overviewLayers,
QList<QgsMapLayer *> &allLayers );

void deferredSetCanvasLayers();

Expand Down
12 changes: 7 additions & 5 deletions src/gui/layertree/qgslayertreemapcanvasbridge.cpp
Expand Up @@ -117,7 +117,7 @@ void QgsLayerTreeMapCanvasBridge::setCustomLayerOrder( const QStringList &order

void QgsLayerTreeMapCanvasBridge::setCanvasLayers()
{
QList<QgsMapLayer *> canvasLayers, overviewLayers;
QList<QgsMapLayer *> canvasLayers, overviewLayers, allLayerOrder;

if ( mHasCustomLayerOrder )
{
Expand All @@ -126,6 +126,7 @@ void QgsLayerTreeMapCanvasBridge::setCanvasLayers()
QgsLayerTreeLayer *nodeLayer = mRoot->findLayer( layerId );
if ( nodeLayer )
{
allLayerOrder << nodeLayer->layer();
if ( nodeLayer->isVisible() )
canvasLayers << nodeLayer->layer();
if ( nodeLayer->customProperty( QStringLiteral( "overview" ), 0 ).toInt() )
Expand All @@ -134,13 +135,13 @@ void QgsLayerTreeMapCanvasBridge::setCanvasLayers()
}
}
else
setCanvasLayers( mRoot, canvasLayers, overviewLayers );
setCanvasLayers( mRoot, canvasLayers, overviewLayers, allLayerOrder );

QList<QgsLayerTreeLayer *> layerNodes = mRoot->findLayers();
int currentLayerCount = layerNodes.count();
bool firstLayers = mAutoSetupOnFirstLayer && mLastLayerCount == 0 && currentLayerCount != 0;

QgsProject::instance()->setLayerOrder( canvasLayers );
QgsProject::instance()->setLayerOrder( allLayerOrder );
mCanvas->setLayers( canvasLayers );
if ( mOverviewCanvas )
mOverviewCanvas->setLayers( overviewLayers );
Expand Down Expand Up @@ -229,19 +230,20 @@ void QgsLayerTreeMapCanvasBridge::writeProject( QDomDocument &doc )
doc.documentElement().appendChild( elem );
}

void QgsLayerTreeMapCanvasBridge::setCanvasLayers( QgsLayerTreeNode *node, QList<QgsMapLayer *> &canvasLayers, QList<QgsMapLayer *> &overviewLayers )
void QgsLayerTreeMapCanvasBridge::setCanvasLayers( QgsLayerTreeNode *node, QList<QgsMapLayer *> &canvasLayers, QList<QgsMapLayer *> &overviewLayers, QList<QgsMapLayer *> &allLayers )
{
if ( QgsLayerTree::isLayer( node ) )
{
QgsLayerTreeLayer *nodeLayer = QgsLayerTree::toLayer( node );
allLayers << nodeLayer->layer();
if ( nodeLayer->isVisible() )
canvasLayers << nodeLayer->layer();
if ( nodeLayer->customProperty( QStringLiteral( "overview" ), 0 ).toInt() )
overviewLayers << nodeLayer->layer();
}

Q_FOREACH ( QgsLayerTreeNode *child, node->children() )
setCanvasLayers( child, canvasLayers, overviewLayers );
setCanvasLayers( child, canvasLayers, overviewLayers, allLayers );
}

void QgsLayerTreeMapCanvasBridge::deferredSetCanvasLayers()
Expand Down
3 changes: 2 additions & 1 deletion src/gui/layertree/qgslayertreemapcanvasbridge.h
Expand Up @@ -99,7 +99,8 @@ class GUI_EXPORT QgsLayerTreeMapCanvasBridge : public QObject
void defaultLayerOrder( QgsLayerTreeNode *node, QStringList &order ) const;

//! Fill canvasLayers and overviewLayers lists from node and its descendants
void setCanvasLayers( QgsLayerTreeNode *node, QList<QgsMapLayer *> &canvasLayers, QList<QgsMapLayer *> &overviewLayers );
void setCanvasLayers( QgsLayerTreeNode *node, QList<QgsMapLayer *> &canvasLayers, QList<QgsMapLayer *> &overviewLayers,
QList<QgsMapLayer *> &allLayers );

void deferredSetCanvasLayers();

Expand Down
21 changes: 20 additions & 1 deletion tests/src/python/test_qgsmapthemecollection.py
Expand Up @@ -17,6 +17,8 @@
from qgis.core import (QgsMapThemeCollection,
QgsProject,
QgsVectorLayer)
from qgis.gui import (QgsLayerTreeMapCanvasBridge,
QgsMapCanvas)
from qgis.testing import start_app, unittest
from qgis.PyQt.QtTest import QSignalSpy

Expand Down Expand Up @@ -99,7 +101,7 @@ def testThemeChanged(self):

def testMasterLayerOrder(self):
""" test master layer order"""
prj = QgsProject()
prj = QgsProject.instance()
layer = QgsVectorLayer("Point?field=fldtxt:string",
"layer1", "memory")
layer2 = QgsVectorLayer("Point?field=fldtxt:string",
Expand Down Expand Up @@ -149,6 +151,23 @@ def testMasterLayerOrder(self):
self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme2'), [layer2.id(), layer3.id(), layer.id()])
self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme3'), [layer2.id(), layer.id()])

# check that layers include those hidden in the layer tree
canvas = QgsMapCanvas()
bridge = QgsLayerTreeMapCanvasBridge(prj.layerTreeRoot(), canvas)
root = prj.layerTreeRoot()
layer_node = root.findLayer(layer2.id())
layer_node.setItemVisibilityChecked(False)
app.processEvents()
self.assertEqual(prj.mapThemeCollection().masterLayerOrder(), [layer, layer2, layer3])

self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme1'), [layer, layer3])
self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme2'), [layer, layer2, layer3])
self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme3'), [layer, layer2])
self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme1'), [layer.id(), layer3.id()])
self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme2'),
[layer.id(), layer2.id(), layer3.id()])
self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme3'), [layer.id(), layer2.id()])


if __name__ == '__main__':
unittest.main()
6 changes: 6 additions & 0 deletions tests/src/python/test_qgsproject.py
Expand Up @@ -262,6 +262,12 @@ def testLayerOrderUpdatedThroughBridge(self):
# make sure project respects this
self.assertEqual([l.id() for l in prj.layerOrder()], [layer2.id(), layer.id(), layer3.id()])

# make sure project order includes ALL layers, not just visible ones
layer_node = root.findLayer(layer.id())
layer_node.setItemVisibilityChecked(False)
app.processEvents()
self.assertEqual([l.id() for l in prj.layerOrder()], [layer2.id(), layer.id(), layer3.id()])


if __name__ == '__main__':
unittest.main()

0 comments on commit 5eccaf6

Please sign in to comment.