Skip to content

Commit 2ca70dc

Browse files
committedApr 18, 2017
[composer] Correctly restore map item layers when loading a template
in a different project to that which the template was created in On behalf of Faunalia, sponsored by ENEL
1 parent dc3b2cd commit 2ca70dc

File tree

3 files changed

+77
-13
lines changed

3 files changed

+77
-13
lines changed
 

‎src/core/composer/qgscomposermap.cpp

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,14 +1190,18 @@ bool QgsComposerMap::writeXml( QDomElement &elem, QDomDocument &doc ) const
11901190

11911191
//layer set
11921192
QDomElement layerSetElem = doc.createElement( QStringLiteral( "LayerSet" ) );
1193-
Q_FOREACH ( const QgsWeakMapLayerPointer &layerPtr, mLayers )
1193+
Q_FOREACH ( const QgsMapLayerRef &layerRef, mLayers )
11941194
{
1195-
QgsMapLayer *layer = layerPtr.data();
1196-
if ( !layer )
1195+
if ( !layerRef )
11971196
continue;
11981197
QDomElement layerElem = doc.createElement( QStringLiteral( "Layer" ) );
1199-
QDomText layerIdText = doc.createTextNode( layer->id() );
1198+
QDomText layerIdText = doc.createTextNode( layerRef.layerId );
12001199
layerElem.appendChild( layerIdText );
1200+
1201+
layerElem.setAttribute( QStringLiteral( "name" ), layerRef.name );
1202+
layerElem.setAttribute( QStringLiteral( "source" ), layerRef.source );
1203+
layerElem.setAttribute( QStringLiteral( "provider" ), layerRef.provider );
1204+
12011205
layerSetElem.appendChild( layerElem );
12021206
}
12031207
composerMapElem.appendChild( layerSetElem );
@@ -1338,9 +1342,15 @@ bool QgsComposerMap::readXml( const QDomElement &itemElem, const QDomDocument &d
13381342
mLayers.reserve( layerIdNodeList.size() );
13391343
for ( int i = 0; i < layerIdNodeList.size(); ++i )
13401344
{
1341-
QString layerId = layerIdNodeList.at( i ).toElement().text();
1342-
if ( QgsMapLayer *ml = mComposition->project()->mapLayer( layerId ) )
1343-
mLayers << ml;
1345+
QDomElement layerElem = layerIdNodeList.at( i ).toElement();
1346+
QString layerId = layerElem.text();
1347+
QString layerName = layerElem.attribute( QStringLiteral( "name" ) );
1348+
QString layerSource = layerElem.attribute( QStringLiteral( "source" ) );
1349+
QString layerProvider = layerElem.attribute( QStringLiteral( "provider" ) );
1350+
1351+
QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
1352+
ref.resolveWeakly( mComposition->project() );
1353+
mLayers << ref;
13441354
}
13451355
}
13461356

@@ -1498,12 +1508,12 @@ bool QgsComposerMap::readXml( const QDomElement &itemElem, const QDomDocument &d
14981508

14991509
QList<QgsMapLayer *> QgsComposerMap::layers() const
15001510
{
1501-
return _qgis_listQPointerToRaw( mLayers );
1511+
return _qgis_listRefToRaw( mLayers );
15021512
}
15031513

15041514
void QgsComposerMap::setLayers( const QList<QgsMapLayer *> &layers )
15051515
{
1506-
mLayers = _qgis_listRawToQPointer( layers );
1516+
mLayers = _qgis_listRawToRef( layers );
15071517
}
15081518

15091519

@@ -1520,9 +1530,9 @@ void QgsComposerMap::setLayerStyleOverrides( const QMap<QString, QString> &overr
15201530
void QgsComposerMap::storeCurrentLayerStyles()
15211531
{
15221532
mLayerStyleOverrides.clear();
1523-
Q_FOREACH ( const QgsWeakMapLayerPointer &layerPtr, mLayers )
1533+
Q_FOREACH ( const QgsMapLayerRef &layerRef, mLayers )
15241534
{
1525-
if ( QgsMapLayer *layer = layerPtr.data() )
1535+
if ( QgsMapLayer *layer = &layerRef )
15261536
{
15271537
QgsMapLayerStyle style;
15281538
style.readFromLayer( layer );
@@ -1538,8 +1548,8 @@ void QgsComposerMap::layersAboutToBeRemoved( QList< QgsMapLayer * > layers )
15381548
Q_FOREACH ( QgsMapLayer *layer, layers )
15391549
{
15401550
mLayerStyleOverrides.remove( layer->id() );
1541-
mLayers.removeAll( layer );
15421551
}
1552+
_qgis_removeLayers( mLayers, layers );
15431553
}
15441554
}
15451555

‎src/core/composer/qgscomposermap.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "qgscoordinatereferencesystem.h"
2525
#include "qgsrendercontext.h"
2626
#include "qgsmaplayer.h"
27+
#include "qgsmaplayerref.h"
2728
#include <QFont>
2829
#include <QGraphicsRectItem>
2930

@@ -541,7 +542,7 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
541542
bool mKeepLayerSet = false;
542543

543544
//! Stored layer list (used if layer live-link mKeepLayerSet is disabled)
544-
QgsWeakMapLayerPointerList mLayers;
545+
QList< QgsMapLayerRef > mLayers;
545546

546547
bool mKeepLayerStyles = false;
547548
//! Stored style names (value) to be used with particular layer IDs (key) instead of default style

‎tests/src/core/testqgscomposition.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class TestQgsComposition : public QObject
6767
void legendRestoredFromTemplate();
6868
void legendRestoredFromTemplateAutoUpdate();
6969
void attributeTableRestoredFromTemplate();
70+
void mapLayersRestoredFromTemplate();
7071

7172
private:
7273
QgsComposition *mComposition = nullptr;
@@ -859,5 +860,57 @@ void TestQgsComposition::attributeTableRestoredFromTemplate()
859860
QCOMPARE( table2->vectorLayer(), layer3 );
860861
}
861862

863+
void TestQgsComposition::mapLayersRestoredFromTemplate()
864+
{
865+
// load some layers
866+
QFileInfo vectorFileInfo( QString( TEST_DATA_DIR ) + "/points.shp" );
867+
QgsVectorLayer *layer = new QgsVectorLayer( vectorFileInfo.filePath(),
868+
vectorFileInfo.completeBaseName(),
869+
"ogr" );
870+
QFileInfo vectorFileInfo2( QString( TEST_DATA_DIR ) + "/polys.shp" );
871+
QgsVectorLayer *layer2 = new QgsVectorLayer( vectorFileInfo2.filePath(),
872+
vectorFileInfo2.completeBaseName(),
873+
"ogr" );
874+
QgsProject p;
875+
p.addMapLayer( layer2 );
876+
p.addMapLayer( layer );
877+
878+
// create composition
879+
QgsComposition c( &p );
880+
// add a map
881+
QgsComposerMap *map = new QgsComposerMap( &c, 1, 1, 10, 10 );
882+
c.addComposerMap( map );
883+
map->setLayers( QList<QgsMapLayer *>() << layer << layer2 );
884+
885+
// save composition to template
886+
QDomDocument doc;
887+
QDomElement composerElem = doc.createElement( "Composer" );
888+
doc.appendChild( composerElem );
889+
c.writeXml( composerElem, doc );
890+
c.atlasComposition().writeXml( composerElem, doc );
891+
892+
// new project
893+
QgsProject p2;
894+
QgsVectorLayer *layer3 = new QgsVectorLayer( vectorFileInfo.filePath(),
895+
vectorFileInfo.completeBaseName(),
896+
"ogr" );
897+
QgsVectorLayer *layer4 = new QgsVectorLayer( vectorFileInfo2.filePath(),
898+
vectorFileInfo2.completeBaseName(),
899+
"ogr" );
900+
p2.addMapLayer( layer4 );
901+
p2.addMapLayer( layer3 );
902+
903+
// make a new composition from template
904+
QgsComposition c2( &p2 );
905+
QVERIFY( c2.loadFromTemplate( doc ) );
906+
// get map from new composition
907+
QList< QgsComposerMap * > maps;
908+
c2.composerItems( maps );
909+
QgsComposerMap *map2 = static_cast< QgsComposerMap *>( maps.at( 0 ) );
910+
QVERIFY( map2 );
911+
912+
QCOMPARE( map2->layers(), QList<QgsMapLayer *>() << layer3 << layer4 );
913+
}
914+
862915
QGSTEST_MAIN( TestQgsComposition )
863916
#include "testqgscomposition.moc"

0 commit comments

Comments
 (0)
Please sign in to comment.