Skip to content
Permalink
Browse files

Merge pull request #4239 from nyalldawson/layer_freakin_order

Allow retrieval of project layer order through QgsProject
  • Loading branch information
nyalldawson committed Mar 13, 2017
2 parents 1ca73f4 + a8d627d commit a652f73f57abd49478f13fcea4bfc3c5e8d60361
@@ -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}
@@ -12,11 +12,8 @@
*/
namespace QgsLayerTree
{
//! Check whether the node is a valid group node
bool isGroup( QgsLayerTreeNode* node );

//! Check whether the node is a valid layer node
bool isLayer( QgsLayerTreeNode* node );
bool isGroup( QgsLayerTreeNode *node );
bool isLayer( const QgsLayerTreeNode *node );

//! Cast node to a group. No type checking is done - use isGroup() to find out whether this operation is legal.
// PYTHON: automatic cast
@@ -70,7 +70,7 @@ class QgsLayerTreeNode : QObject
~QgsLayerTreeNode();

//! Find out about type of the node. It is usually shorter to use convenience functions from QgsLayerTree namespace for that
NodeType nodeType();
NodeType nodeType() const;
//! Get pointer to the parent. If parent is a null pointer, the node is a root node
QgsLayerTreeNode *parent();
//! Get list of children of the node. Children are owned by the parent
@@ -132,8 +132,7 @@ class QgsLayerTreeNode : QObject
//! Return whether this node is unchecked and all its children.
//! @note added in 3.0
bool isItemVisibilityUncheckedRecursive() const;

//! Return whether the node should be shown as expanded or collapsed in GUI
QList< QgsMapLayer * > checkedLayers() const;
bool isExpanded() const;
//! Set whether the node should be shown as expanded or collapsed in GUI
void setExpanded( bool expanded );
@@ -102,62 +102,23 @@ class QgsMapThemeCollection : QObject
//! Returns a list of existing map theme names.
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 );

/**
* Reads the map theme collection state from XML
* @param doc DOM document
* @see writeXml
*/
void readXml( const QDomDocument& doc );
MapThemeRecord mapThemeState( const QString &name ) const;
QStringList mapThemeVisibleLayerIds( const QString &name ) const;
QList<QgsMapLayer *> mapThemeVisibleLayers( const QString &name ) const;
QMap<QString, QString> mapThemeStyleOverrides( const QString &name );
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;
QList< QgsMapLayer * > masterVisibleLayers() 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:

void mapThemesChanged();
@@ -487,6 +487,9 @@ class QgsProject : QObject, QgsExpressionContextGenerator
*/
void reloadAllLayers();

QList< QgsMapLayer * > layerOrder() const;
void setLayerOrder( const QList< QgsMapLayer * > &order );

signals:
//! emitted when project is being read
void readProject( const QDomDocument& );
@@ -623,12 +626,12 @@ class QgsProject : QObject, QgsExpressionContextGenerator
*/
//TODO QGIS 3.0 - rename to past tense
void removeAll();
void layersAdded( const QList<QgsMapLayer *> &layers );

void layersAdded( const QList<QgsMapLayer *>& layers );

void layerWasAdded( QgsMapLayer* layer );
void layerWasAdded( QgsMapLayer *layer );
void legendLayersAdded( const QList<QgsMapLayer *> &layers );

void legendLayersAdded( const QList<QgsMapLayer*>& layers );
void layerOrderChanged();

public slots:
/**
@@ -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();

@@ -37,7 +37,7 @@ namespace QgsLayerTree
}

//! Check whether the node is a valid layer node
inline bool isLayer( QgsLayerTreeNode *node )
inline bool isLayer( const QgsLayerTreeNode *node )
{
return node && node->nodeType() == QgsLayerTreeNode::NodeLayer;
}
@@ -54,6 +54,12 @@ namespace QgsLayerTree
return static_cast<QgsLayerTreeLayer *>( node );
}

//! Cast node to a layer. No type checking is done - use isLayer() to find out whether this operation is legal.
inline const QgsLayerTreeLayer *toLayer( const QgsLayerTreeNode *node )
{
return static_cast< const QgsLayerTreeLayer *>( node );
}

}

#endif // QGSLAYERTREE_H
@@ -126,6 +126,26 @@ bool QgsLayerTreeNode::isItemVisibilityUncheckedRecursive() const
return true;
}

void fetchCheckedLayers( const QgsLayerTreeNode *node, QList<QgsMapLayer *> &layers )
{
if ( QgsLayerTree::isLayer( node ) )
{
const QgsLayerTreeLayer *nodeLayer = QgsLayerTree::toLayer( node );
if ( nodeLayer->isVisible() )
layers << nodeLayer->layer();
}

Q_FOREACH ( QgsLayerTreeNode *child, node->children() )
fetchCheckedLayers( child, layers );
}

QList<QgsMapLayer *> QgsLayerTreeNode::checkedLayers() const
{
QList<QgsMapLayer *> layers;
fetchCheckedLayers( this, layers );
return layers;
}

void QgsLayerTreeNode::setExpanded( bool expanded )
{
if ( mExpanded == expanded )
@@ -24,6 +24,7 @@
class QDomElement;

class QgsProject;
class QgsMapLayer;

/** \ingroup core
* This class is a base class for nodes in a layer tree.
@@ -80,7 +81,7 @@ class CORE_EXPORT QgsLayerTreeNode : public QObject
~QgsLayerTreeNode();

//! Find out about type of the node. It is usually shorter to use convenience functions from QgsLayerTree namespace for that
NodeType nodeType() { return mNodeType; }
NodeType nodeType() const { return mNodeType; }
//! Get pointer to the parent. If parent is a null pointer, the node is a root node
QgsLayerTreeNode *parent() { return mParent; }
//! Get list of children of the node. Children are owned by the parent
@@ -145,6 +146,13 @@ class CORE_EXPORT QgsLayerTreeNode : public QObject
//! @note added in 3.0
bool isItemVisibilityUncheckedRecursive() const;

/**
* Returns a list of any checked layers which belong to this node or its
* children.
* @note added in QGIS 3.0
*/
QList< QgsMapLayer * > checkedLayers() const;

//! Return whether the node should be shown as expanded or collapsed in GUI
bool isExpanded() const;
//! Set whether the node should be shown as expanded or collapsed in GUI
@@ -175,6 +175,37 @@ void QgsMapThemeCollection::setProject( QgsProject *project )
emit projectChanged();
}

QList<QgsMapLayer *> QgsMapThemeCollection::masterLayerOrder() const
{
if ( !mProject )
return QList< QgsMapLayer * >();

return mProject->layerOrder();
}

QList<QgsMapLayer *> QgsMapThemeCollection::masterVisibleLayers() const
{
QList< QgsMapLayer *> allLayers = masterLayerOrder();
QList< QgsMapLayer * > visibleLayers = mProject->layerTreeRoot()->checkedLayers();

if ( allLayers.isEmpty() )
{
// no project layer order set
return visibleLayers;
}

else
{
QList< QgsMapLayer * > orderedVisibleLayers;
Q_FOREACH ( QgsMapLayer *layer, allLayers )
{
if ( visibleLayers.contains( layer ) )
orderedVisibleLayers << layer;
}
return orderedVisibleLayers;
}
}


bool QgsMapThemeCollection::hasMapTheme( const QString &name ) const
{
@@ -229,23 +260,39 @@ QStringList QgsMapThemeCollection::mapThemes() const
QStringList QgsMapThemeCollection::mapThemeVisibleLayerIds( const QString &name ) const
{
QStringList layerIds;
Q_FOREACH ( const MapThemeLayerRecord &layerRec, mMapThemes.value( name ).mLayerRecords )
Q_FOREACH ( QgsMapLayer *layer, mapThemeVisibleLayers( name ) )
{
if ( layerRec.layer() )
layerIds << layerRec.layer()->id();
layerIds << layer->id();
}
return layerIds;
}


QList<QgsMapLayer *> QgsMapThemeCollection::mapThemeVisibleLayers( const QString &name ) const
{
QList<QgsMapLayer *> layers;
Q_FOREACH ( const MapThemeLayerRecord &layerRec, mMapThemes.value( name ).mLayerRecords )
const QList<MapThemeLayerRecord> &recs = mMapThemes.value( name ).mLayerRecords;
QList<QgsMapLayer *> layerOrder = masterLayerOrder();
if ( layerOrder.isEmpty() )
{
if ( layerRec.layer() )
layers << layerRec.layer();
// no master layer order - so we have to just use the stored theme layer order as a fallback
Q_FOREACH ( const MapThemeLayerRecord &layerRec, mMapThemes.value( name ).mLayerRecords )
{
if ( layerRec.layer() )
layers << layerRec.layer();
}
}
else
{
Q_FOREACH ( QgsMapLayer *layer, layerOrder )
{
Q_FOREACH ( const MapThemeLayerRecord &layerRec, recs )
{
if ( layerRec.layer() == layer )
layers << layerRec.layer();
}
}
}

return layers;
}

@@ -242,6 +242,23 @@ class CORE_EXPORT QgsMapThemeCollection : public QObject
*/
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
* @see masterVisibleLayers()
*/
QList< QgsMapLayer * > masterLayerOrder() const;

/**
* Returns the master list of visible layers. The order of returned layers will always match those
* of masterLayerOrder(), but the returned layers are filtered to only include those visible
* in the project's layer tree.
* @note added in QGIS 3.0
* @see masterLayerOrder()
*/
QList< QgsMapLayer * > masterVisibleLayers() const;

signals:

/**

0 comments on commit a652f73

Please sign in to comment.
You can’t perform that action at this time.