Skip to content

Commit

Permalink
[layouts] Fix layers are incorrectly shown when groups are unchecked
Browse files Browse the repository at this point in the history
for a map theme

Followup #33099

Fixes #34257

(cherry picked from commit 38a3a2d)
(cherry picked from commit 5a8e131)
  • Loading branch information
nyalldawson committed Mar 17, 2020
1 parent ee5e99b commit b7bc1c3
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 8 deletions.
2 changes: 2 additions & 0 deletions python/core/auto_generated/qgsmapthemecollection.sip.in
Expand Up @@ -55,6 +55,8 @@ Returns map layer or ``None`` if the layer does not exist anymore
Sets the map layer for this record
%End

bool isVisible;

bool usingCurrentStyle;
QString currentStyle;
bool usingLegendItems;
Expand Down
22 changes: 15 additions & 7 deletions src/core/qgsmapthemecollection.cpp
Expand Up @@ -35,6 +35,7 @@ QgsMapThemeCollection::QgsMapThemeCollection( QgsProject *project )
QgsMapThemeCollection::MapThemeLayerRecord QgsMapThemeCollection::createThemeLayerRecord( QgsLayerTreeLayer *nodeLayer, QgsLayerTreeModel *model )
{
MapThemeLayerRecord layerRec( nodeLayer->layer() );
layerRec.isVisible = nodeLayer->isVisible();
layerRec.usingCurrentStyle = true;
layerRec.currentStyle = nodeLayer->layer()->styleManager()->currentStyle();
layerRec.expandedLayerNode = nodeLayer->isExpanded();
Expand Down Expand Up @@ -124,15 +125,20 @@ bool QgsMapThemeCollection::findRecordForLayer( QgsMapLayer *layer, const QgsMap
void QgsMapThemeCollection::applyThemeToLayer( QgsLayerTreeLayer *nodeLayer, QgsLayerTreeModel *model, const QgsMapThemeCollection::MapThemeRecord &rec )
{
MapThemeLayerRecord layerRec;
bool isVisible = findRecordForLayer( nodeLayer->layer(), rec, layerRec );
const bool recordExists = findRecordForLayer( nodeLayer->layer(), rec, layerRec );

// Make sure the whole tree is visible
if ( isVisible )
nodeLayer->setItemVisibilityCheckedParentRecursive( isVisible );
if ( recordExists )
{
if ( rec.hasCheckedStateInfo() )
nodeLayer->setItemVisibilityChecked( true );
else
nodeLayer->setItemVisibilityCheckedParentRecursive( true );
}
else
nodeLayer->setItemVisibilityChecked( isVisible );
nodeLayer->setItemVisibilityChecked( false );

if ( !isVisible )
if ( !recordExists )
return;

if ( layerRec.usingCurrentStyle )
Expand Down Expand Up @@ -322,7 +328,7 @@ QList<QgsMapLayer *> QgsMapThemeCollection::mapThemeVisibleLayers( const QString
const auto records {mMapThemes.value( name ).mLayerRecords};
for ( const MapThemeLayerRecord &layerRec : records )
{
if ( layerRec.layer() )
if ( layerRec.isVisible && layerRec.layer() )
layers << layerRec.layer();
}
}
Expand All @@ -334,7 +340,7 @@ QList<QgsMapLayer *> QgsMapThemeCollection::mapThemeVisibleLayers( const QString
const auto constRecs = recs;
for ( const MapThemeLayerRecord &layerRec : constRecs )
{
if ( layerRec.layer() == layer )
if ( layerRec.isVisible && layerRec.layer() == layer )
layers << layerRec.layer();
}
}
Expand Down Expand Up @@ -448,6 +454,7 @@ void QgsMapThemeCollection::readXml( const QDomDocument &doc )
if ( QgsMapLayer *layer = mProject->mapLayer( layerID ) )
{
layerRecords[layerID] = MapThemeLayerRecord( layer );
layerRecords[layerID].isVisible = visPresetLayerElem.attribute( QStringLiteral( "visible" ), QStringLiteral( "1" ) ).toInt();

if ( visPresetLayerElem.hasAttribute( QStringLiteral( "style" ) ) )
{
Expand Down Expand Up @@ -575,6 +582,7 @@ void QgsMapThemeCollection::writeXml( QDomDocument &doc )
QString layerID = layerRec.layer()->id();
QDomElement layerElem = doc.createElement( QStringLiteral( "layer" ) );
layerElem.setAttribute( QStringLiteral( "id" ), layerID );
layerElem.setAttribute( QStringLiteral( "visible" ), layerRec.isVisible ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
if ( layerRec.usingCurrentStyle )
layerElem.setAttribute( QStringLiteral( "style" ), layerRec.currentStyle );
visPresetElem.appendChild( layerElem );
Expand Down
8 changes: 7 additions & 1 deletion src/core/qgsmapthemecollection.h
Expand Up @@ -63,7 +63,7 @@ class CORE_EXPORT QgsMapThemeCollection : public QObject

bool operator==( const QgsMapThemeCollection::MapThemeLayerRecord &other ) const
{
return mLayer == other.mLayer &&
return mLayer == other.mLayer && isVisible == other.isVisible &&
usingCurrentStyle == other.usingCurrentStyle && currentStyle == other.currentStyle &&
usingLegendItems == other.usingLegendItems && checkedLegendItems == other.checkedLegendItems &&
expandedLegendItems == other.expandedLegendItems && expandedLayerNode == other.expandedLayerNode;
Expand All @@ -79,6 +79,12 @@ class CORE_EXPORT QgsMapThemeCollection : public QObject
//! Sets the map layer for this record
void setLayer( QgsMapLayer *layer );

/**
* TRUE if the layer is visible in the associated theme.
* \since QGIS 3.14
*/
bool isVisible = true;

//! Whether current style is valid and should be applied
bool usingCurrentStyle = false;
//! Name of the current style of the layer
Expand Down
17 changes: 17 additions & 0 deletions tests/src/core/testqgsmapthemecollection.cpp
Expand Up @@ -244,12 +244,21 @@ void TestQgsMapThemeCollection::checkedState()
QgsMapThemeCollection::MapThemeRecord recUnchecked = themes.mapThemeState( "all-unchecked" );
QVERIFY( recUnchecked.hasCheckedStateInfo() );
QCOMPARE( recUnchecked.checkedGroupNodes().count(), 0 );
QVERIFY( themes.mapThemeVisibleLayers( QStringLiteral( "all-unchecked" ) ).isEmpty() );
QVERIFY( themes.mapThemeVisibleLayerIds( QStringLiteral( "all-unchecked" ) ).isEmpty() );
QCOMPARE( mNodeLayerLines->itemVisibilityChecked(), false );
QCOMPARE( mNodeLayerPolys->itemVisibilityChecked(), true );

QgsMapThemeCollection::MapThemeRecord recChecked = themes.mapThemeState( "all-checked" );
QVERIFY( recChecked.hasCheckedStateInfo() );
QCOMPARE( recChecked.checkedGroupNodes().count(), 3 );
QCOMPARE( themes.mapThemeVisibleLayers( QStringLiteral( "all-checked" ) ).size(), 2 );
QVERIFY( themes.mapThemeVisibleLayers( QStringLiteral( "all-checked" ) ).contains( mPolysLayer ) );
QVERIFY( themes.mapThemeVisibleLayers( QStringLiteral( "all-checked" ) ).contains( mPointsLayer ) );
QCOMPARE( themes.mapThemeVisibleLayerIds( QStringLiteral( "all-checked" ) ).size(), 2 );
QVERIFY( themes.mapThemeVisibleLayerIds( QStringLiteral( "all-checked" ) ).contains( mPolysLayer->id() ) );
QVERIFY( themes.mapThemeVisibleLayerIds( QStringLiteral( "all-checked" ) ).contains( mPointsLayer->id() ) );

QCOMPARE( mNodeLayerLines->itemVisibilityChecked(), false );
QCOMPARE( mNodeLayerPolys->itemVisibilityChecked(), true );

Expand Down Expand Up @@ -280,10 +289,18 @@ void TestQgsMapThemeCollection::checkedState()
QgsMapThemeCollection::MapThemeRecord recUnchecked2 = themes2.mapThemeState( "all-unchecked" );
QVERIFY( recUnchecked2.hasCheckedStateInfo() );
QCOMPARE( recUnchecked2.checkedGroupNodes().count(), 0 );
QVERIFY( themes2.mapThemeVisibleLayers( QStringLiteral( "all-unchecked" ) ).isEmpty() );
QVERIFY( themes2.mapThemeVisibleLayerIds( QStringLiteral( "all-unchecked" ) ).isEmpty() );

QgsMapThemeCollection::MapThemeRecord recChecked2 = themes2.mapThemeState( "all-checked" );
QVERIFY( recChecked2.hasCheckedStateInfo() );
QCOMPARE( recChecked2.checkedGroupNodes().count(), 3 );
QCOMPARE( themes2.mapThemeVisibleLayers( QStringLiteral( "all-checked" ) ).size(), 2 );
QVERIFY( themes2.mapThemeVisibleLayers( QStringLiteral( "all-checked" ) ).contains( mPolysLayer ) );
QVERIFY( themes2.mapThemeVisibleLayers( QStringLiteral( "all-checked" ) ).contains( mPointsLayer ) );
QCOMPARE( themes2.mapThemeVisibleLayerIds( QStringLiteral( "all-checked" ) ).size(), 2 );
QVERIFY( themes2.mapThemeVisibleLayerIds( QStringLiteral( "all-checked" ) ).contains( mPolysLayer->id() ) );
QVERIFY( themes2.mapThemeVisibleLayerIds( QStringLiteral( "all-checked" ) ).contains( mPointsLayer->id() ) );
}

QGSTEST_MAIN( TestQgsMapThemeCollection )
Expand Down

0 comments on commit b7bc1c3

Please sign in to comment.