mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-17 00:04:02 -04:00
Layer order in map themes must always respect project layer order
This commit is contained in:
parent
6cfc6a1b98
commit
9faa628f8b
@ -102,62 +102,22 @@ class QgsMapThemeCollection : QObject
|
|||||||
//! Returns a list of existing map theme names.
|
//! Returns a list of existing map theme names.
|
||||||
QStringList mapThemes() const;
|
QStringList mapThemes() const;
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the recorded state of a map theme.
|
|
||||||
*/
|
|
||||||
MapThemeRecord mapThemeState( const QString& name ) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the list of layer IDs that are visible for the specified map theme.
|
|
||||||
*
|
|
||||||
* @note The order of the returned list is not guaranteed to reflect the order of layers
|
|
||||||
* in the canvas.
|
|
||||||
* @note Added in QGIS 3.0
|
|
||||||
*/
|
|
||||||
QStringList mapThemeVisibleLayerIds( const QString& name ) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the list of layers that are visible for the specified map theme.
|
|
||||||
*
|
|
||||||
* @note The order of the returned list is not guaranteed to reflect the order of layers
|
|
||||||
* in the canvas.
|
|
||||||
* @note Added in QGIS 3.0
|
|
||||||
*/
|
|
||||||
QList<QgsMapLayer*> mapThemeVisibleLayers( const QString& name ) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get layer style overrides (for QgsMapSettings) of the visible layers for given map theme.
|
|
||||||
*/
|
|
||||||
QMap<QString, QString> mapThemeStyleOverrides( const QString& name );
|
|
||||||
|
|
||||||
/**
|
MapThemeRecord mapThemeState( const QString &name ) const;
|
||||||
* Reads the map theme collection state from XML
|
QStringList mapThemeVisibleLayerIds( const QString &name ) const;
|
||||||
* @param doc DOM document
|
QList<QgsMapLayer *> mapThemeVisibleLayers( const QString &name ) const;
|
||||||
* @see writeXml
|
QMap<QString, QString> mapThemeStyleOverrides( const QString &name );
|
||||||
*/
|
void readXml( const QDomDocument &doc );
|
||||||
void readXml( const QDomDocument& doc );
|
void writeXml( QDomDocument &doc );
|
||||||
|
static MapThemeRecord createThemeFromCurrentState( QgsLayerTreeGroup *root, QgsLayerTreeModel *model );
|
||||||
|
void applyTheme( const QString &name, QgsLayerTreeGroup *root, QgsLayerTreeModel *model );
|
||||||
|
QgsProject *project();
|
||||||
|
void setProject( QgsProject *project );
|
||||||
|
QList< QgsMapLayer * > masterLayerOrder() const;
|
||||||
|
|
||||||
/** Writes the map theme collection state to XML.
|
|
||||||
* @param doc DOM document
|
|
||||||
* @see readXml
|
|
||||||
*/
|
|
||||||
void writeXml( QDomDocument& doc );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Static method to create theme from the current state of layer visibilities in layer tree,
|
|
||||||
* current style of layers and check state of legend items (from a layer tree model).
|
|
||||||
* @note added in QGIS 3.0
|
|
||||||
*/
|
|
||||||
static MapThemeRecord createThemeFromCurrentState( QgsLayerTreeGroup* root, QgsLayerTreeModel* model );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply theme given by its name and modify layer tree, current style of layers and checked
|
|
||||||
* legend items of passed layer tree model.
|
|
||||||
* @note added in QGIS 3.0
|
|
||||||
*/
|
|
||||||
void applyTheme( const QString& name, QgsLayerTreeGroup* root, QgsLayerTreeModel* model );
|
|
||||||
QgsProject* project();
|
|
||||||
void setProject( QgsProject* project );
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void mapThemesChanged();
|
void mapThemesChanged();
|
||||||
|
@ -175,6 +175,14 @@ void QgsMapThemeCollection::setProject( QgsProject *project )
|
|||||||
emit projectChanged();
|
emit projectChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<QgsMapLayer *> QgsMapThemeCollection::masterLayerOrder() const
|
||||||
|
{
|
||||||
|
if ( !mProject )
|
||||||
|
return QList< QgsMapLayer * >();
|
||||||
|
|
||||||
|
return mProject->layerOrder();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool QgsMapThemeCollection::hasMapTheme( const QString &name ) const
|
bool QgsMapThemeCollection::hasMapTheme( const QString &name ) const
|
||||||
{
|
{
|
||||||
@ -229,23 +237,26 @@ QStringList QgsMapThemeCollection::mapThemes() const
|
|||||||
QStringList QgsMapThemeCollection::mapThemeVisibleLayerIds( const QString &name ) const
|
QStringList QgsMapThemeCollection::mapThemeVisibleLayerIds( const QString &name ) const
|
||||||
{
|
{
|
||||||
QStringList layerIds;
|
QStringList layerIds;
|
||||||
Q_FOREACH ( const MapThemeLayerRecord &layerRec, mMapThemes.value( name ).mLayerRecords )
|
Q_FOREACH ( QgsMapLayer *layer, mapThemeVisibleLayers( name ) )
|
||||||
{
|
{
|
||||||
if ( layerRec.layer() )
|
layerIds << layer->id();
|
||||||
layerIds << layerRec.layer()->id();
|
|
||||||
}
|
}
|
||||||
return layerIds;
|
return layerIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QList<QgsMapLayer *> QgsMapThemeCollection::mapThemeVisibleLayers( const QString &name ) const
|
QList<QgsMapLayer *> QgsMapThemeCollection::mapThemeVisibleLayers( const QString &name ) const
|
||||||
{
|
{
|
||||||
QList<QgsMapLayer *> layers;
|
QList<QgsMapLayer *> layers;
|
||||||
Q_FOREACH ( const MapThemeLayerRecord &layerRec, mMapThemes.value( name ).mLayerRecords )
|
const QList<MapThemeLayerRecord> &recs = mMapThemes.value( name ).mLayerRecords;
|
||||||
|
Q_FOREACH ( QgsMapLayer *layer, masterLayerOrder() )
|
||||||
{
|
{
|
||||||
if ( layerRec.layer() )
|
Q_FOREACH ( const MapThemeLayerRecord &layerRec, recs )
|
||||||
layers << layerRec.layer();
|
{
|
||||||
|
if ( layerRec.layer() == layer )
|
||||||
|
layers << layerRec.layer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return layers;
|
return layers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,6 +242,13 @@ class CORE_EXPORT QgsMapThemeCollection : public QObject
|
|||||||
*/
|
*/
|
||||||
void setProject( QgsProject *project );
|
void setProject( QgsProject *project );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the master layer order (this will always match the project's QgsProject::layerOrder() ).
|
||||||
|
* All map themes will maintain the same layer order as the master layer order.
|
||||||
|
* @note added in QGIS 3.0
|
||||||
|
*/
|
||||||
|
QList< QgsMapLayer * > masterLayerOrder() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,6 +97,58 @@ class TestQgsMapThemeCollection(unittest.TestCase):
|
|||||||
app.processEvents()
|
app.processEvents()
|
||||||
self.assertEqual(len(theme_changed_spy), 6) # signal should be emitted - layer is in record
|
self.assertEqual(len(theme_changed_spy), 6) # signal should be emitted - layer is in record
|
||||||
|
|
||||||
|
def testMasterLayerOrder(self):
|
||||||
|
""" test master layer order"""
|
||||||
|
prj = QgsProject()
|
||||||
|
layer = QgsVectorLayer("Point?field=fldtxt:string",
|
||||||
|
"layer1", "memory")
|
||||||
|
layer2 = QgsVectorLayer("Point?field=fldtxt:string",
|
||||||
|
"layer2", "memory")
|
||||||
|
layer3 = QgsVectorLayer("Point?field=fldtxt:string",
|
||||||
|
"layer3", "memory")
|
||||||
|
prj.addMapLayers([layer, layer2, layer3])
|
||||||
|
|
||||||
|
prj.setLayerOrder([layer2, layer])
|
||||||
|
self.assertEqual(prj.mapThemeCollection().masterLayerOrder(), [layer2, layer])
|
||||||
|
|
||||||
|
prj.setLayerOrder([layer, layer2, layer3])
|
||||||
|
# make some themes...
|
||||||
|
theme1 = QgsMapThemeCollection.MapThemeRecord()
|
||||||
|
theme1.setLayerRecords([QgsMapThemeCollection.MapThemeLayerRecord(layer3),
|
||||||
|
QgsMapThemeCollection.MapThemeLayerRecord(layer)])
|
||||||
|
|
||||||
|
theme2 = QgsMapThemeCollection.MapThemeRecord()
|
||||||
|
theme2.setLayerRecords([QgsMapThemeCollection.MapThemeLayerRecord(layer3),
|
||||||
|
QgsMapThemeCollection.MapThemeLayerRecord(layer2),
|
||||||
|
QgsMapThemeCollection.MapThemeLayerRecord(layer)])
|
||||||
|
|
||||||
|
theme3 = QgsMapThemeCollection.MapThemeRecord()
|
||||||
|
theme3.setLayerRecords([QgsMapThemeCollection.MapThemeLayerRecord(layer2),
|
||||||
|
QgsMapThemeCollection.MapThemeLayerRecord(layer)])
|
||||||
|
|
||||||
|
prj.mapThemeCollection().insert('theme1', theme1)
|
||||||
|
prj.mapThemeCollection().insert('theme2', theme2)
|
||||||
|
prj.mapThemeCollection().insert('theme3', theme3)
|
||||||
|
|
||||||
|
#order of layers in theme should respect master order
|
||||||
|
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])
|
||||||
|
|
||||||
|
# also check ids!
|
||||||
|
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()])
|
||||||
|
|
||||||
|
# reset master order
|
||||||
|
prj.setLayerOrder([layer2, layer3, layer])
|
||||||
|
self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme1'), [layer3, layer])
|
||||||
|
self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme2'), [layer2, layer3, layer])
|
||||||
|
self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme3'), [layer2, layer])
|
||||||
|
self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme1'), [layer3.id(), layer.id()])
|
||||||
|
self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme2'), [layer2.id(), layer3.id(), layer.id()])
|
||||||
|
self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme3'), [layer2.id(), layer.id()])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user