Completely move layer order to core

This commit is contained in:
Matthias Kuhn 2017-03-22 19:15:44 +01:00
parent 798b1ed69e
commit f33aabd90a
44 changed files with 636 additions and 506 deletions

View File

@ -13,7 +13,7 @@ class QgsLegendModel : QgsLayerTreeModel
public:
//! Construct the model based on the given layer tree
QgsLegendModel( QgsLayerTreeGroup* rootNode, QObject *parent /TransferThis/ = 0 );
QgsLegendModel( QgsLayerTree* rootNode, QObject *parent /TransferThis/ = 0 );
QVariant data( const QModelIndex& index, int role ) const;

View File

@ -1,19 +1,10 @@
%ModuleHeaderCode
class QgsLayerTree : QgsLayerTreeGroup
{
%TypeHeaderCode
#include <qgslayertree.h>
%End
/**
* Namespace with helper functions for layer tree operations.
*
* Only generally useful routines should be here. Miscellaneous utility functions for work
* with the layer tree are in QgsLayerTreeUtils class.
*
* @note added in 2.4
*/
namespace QgsLayerTree
{
bool isGroup( QgsLayerTreeNode *node );
bool isLayer( const QgsLayerTreeNode *node );
static bool isGroup( QgsLayerTreeNode *node );
static 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
@ -23,4 +14,46 @@ namespace QgsLayerTree
// PYTHON: automatic cast
//inline QgsLayerTreeLayer* toLayer( QgsLayerTreeNode* node );
QList<QgsMapLayer *> customLayerOrder() const;
void setCustomLayerOrder( const QList<QgsMapLayer *> &customLayerOrder );
void setCustomLayerOrder( const QStringList &customLayerOrder );
QList<QgsMapLayer *> layerOrder() const;
bool hasCustomLayerOrder() const;
void setHasCustomLayerOrder( bool hasCustomLayerOrder );
static QgsLayerTree *readXml( QDomElement &element );
void readLayerOrderFromXml( const QDomElement &doc );
virtual void writeXml( QDomElement &parentElement );
virtual QgsLayerTree *clone() const;
void clear();
signals:
void customLayerOrderChanged();
void layerOrderChanged();
void hasCustomLayerOrderChanged( bool hasCustomLayerOrder );
};

View File

@ -28,7 +28,7 @@ class QgsLayerTreeModel : QAbstractItemModel
public:
//! Construct a new tree model with given layer tree (root node must not be null pointer).
//! The root node is not transferred by the model.
explicit QgsLayerTreeModel( QgsLayerTreeGroup* rootNode, QObject *parent /TransferThis/ = 0 );
explicit QgsLayerTreeModel( QgsLayerTree* rootNode, QObject *parent /TransferThis/ = 0 );
~QgsLayerTreeModel();
// Implementation of virtual functions from QAbstractItemModel
@ -118,10 +118,10 @@ class QgsLayerTreeModel : QAbstractItemModel
QgsLayerTreeModelLegendNode* findLegendNode( const QString& layerId, const QString& ruleKey ) const;
//! Return pointer to the root node of the layer tree. Always a non-null pointer.
QgsLayerTreeGroup* rootGroup() const;
QgsLayerTree* rootGroup() const;
//! Reset the model and use a new root group node
//! @note added in 2.6
void setRootGroup( QgsLayerTreeGroup* newRootGroup );
void setRootGroup( QgsLayerTree* newRootGroup );
//! Force a refresh of legend nodes of a layer node.
//! Not necessary to call when layer's renderer is changed as the model listens to these events.

View File

@ -16,7 +16,7 @@ class QgsLayerTreeUtils
//! Try to load custom layer order from \verbatim <legend> \endverbatim tag from project files from QGIS 2.2 and below
static bool readOldLegendLayerOrder( const QDomElement& legendElem, bool& hasCustomOrder, QStringList& order );
//! Return \verbatim <legend> \endverbatim tag used in QGIS 2.2 and below
static QDomElement writeOldLegend( QDomDocument& doc, QgsLayerTreeGroup* root, bool hasCustomOrder, const QStringList& order );
static QDomElement writeOldLegend( QDomDocument& doc, QgsLayerTreeGroup* root, bool hasCustomOrder, const QList<QgsMapLayer *> &order );
//! Convert Qt::CheckState to QString
static QString checkStateToXml( Qt::CheckState state );

View File

@ -486,9 +486,6 @@ 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& );
@ -630,7 +627,6 @@ class QgsProject : QObject, QgsExpressionContextGenerator
void layerWasAdded( QgsMapLayer *layer );
void legendLayersAdded( const QList<QgsMapLayer *> &layers );
void layerOrderChanged();
public slots:
/**

View File

@ -16,12 +16,4 @@ class QgsCustomLayerOrderWidget : QWidget
public:
explicit QgsCustomLayerOrderWidget( QgsLayerTreeMapCanvasBridge* bridge, QWidget *parent /TransferThis/ = 0 );
protected slots:
void bridgeHasCustomLayerOrderChanged( bool state );
void bridgeCustomLayerOrderChanged( const QStringList& order );
//! Slot triggered when the ivsibility of a node changes
void nodeVisibilityChanged( QgsLayerTreeNode* node );
void modelUpdated();
};

View File

@ -21,57 +21,26 @@ class QgsLayerTreeMapCanvasBridge : QObject
public:
//! Constructor: does not take ownership of the layer tree nor canvas
QgsLayerTreeMapCanvasBridge( QgsLayerTreeGroup* root, QgsMapCanvas* canvas, QObject* parent /TransferThis/ = 0 );
QgsLayerTreeMapCanvasBridge( QgsLayerTree* root, QgsMapCanvas* canvas, QObject* parent /TransferThis/ = 0 );
void clear();
QgsLayerTreeGroup* rootGroup() const;
QgsMapCanvas* mapCanvas() const;
QgsLayerTree *rootGroup() const;
QgsMapCanvas *mapCanvas() const;
//! Associates overview canvas with the bridge, so the overview will be updated whenever main canvas is updated
//! @note added in 3.0
void setOvervewCanvas( QgsMapOverviewCanvas* overviewCanvas );
//! Returns associated overview canvas (may be null)
//! @note added in 3.0
QgsMapOverviewCanvas* overviewCanvas() const;
bool hasCustomLayerOrder() const;
QStringList customLayerOrder() const;
QStringList defaultLayerOrder() const;
QgsMapOverviewCanvas *overviewCanvas() const;
//! if enabled, will automatically set full canvas extent and destination CRS + map units
//! when first layer(s) are added
void setAutoSetupOnFirstLayer( bool enabled );
bool autoSetupOnFirstLayer() const;
public slots:
void setHasCustomLayerOrder( bool state );
void setCustomLayerOrder( const QStringList& order );
//! force update of canvas layers from the layer tree. Normally this should not be needed to be called.
void setCanvasLayers();
void readProject( const QDomDocument& doc );
void writeProject( QDomDocument& doc );
signals:
void hasCustomLayerOrderChanged( bool );
void customLayerOrderChanged( const QStringList& order );
void canvasLayersChanged( const QList< QgsMapLayer* >& layers );
protected:
void defaultLayerOrder( QgsLayerTreeNode* node, QStringList& order ) const;
void setCanvasLayers( QgsLayerTreeNode *node, QList<QgsMapLayer *> &canvasLayers, QList<QgsMapLayer *> &overviewLayers,
QList<QgsMapLayer *> &allLayers );
void deferredSetCanvasLayers();
protected slots:
void nodeAddedChildren( QgsLayerTreeNode* node, int indexFrom, int indexTo );
void nodeRemovedChildren();
void nodeVisibilityChanged();
void nodeCustomPropertyChanged( QgsLayerTreeNode* node, const QString& key );
};

View File

@ -42,6 +42,7 @@
#include "qgsmessagelog.h"
#include "qgslogger.h"
#include "qgsproperty.h"
#include "qgslayertree.h"
struct CursorOverride

View File

@ -3378,8 +3378,6 @@ void QgisApp::initLayerTreeView()
addDockWidget( Qt::LeftDockWidgetArea, mLayerTreeDock );
mLayerTreeCanvasBridge = new QgsLayerTreeMapCanvasBridge( QgsProject::instance()->layerTreeRoot(), mMapCanvas, this );
connect( QgsProject::instance(), &QgsProject::writeProject, mLayerTreeCanvasBridge, &QgsLayerTreeMapCanvasBridge::writeProject );
connect( QgsProject::instance(), &QgsProject::readProject, mLayerTreeCanvasBridge, &QgsLayerTreeMapCanvasBridge::readProject );
mMapLayerOrder = new QgsCustomLayerOrderWidget( mLayerTreeCanvasBridge, this );
mMapLayerOrder->setObjectName( QStringLiteral( "theMapLayerOrder" ) );
@ -4769,8 +4767,6 @@ void QgisApp::fileNew( bool promptToSaveFlag, bool forceBlank )
prj->layerTreeRegistryBridge()->setNewLayersVisible( settings.value( QStringLiteral( "qgis/new_layers_visible" ), true ).toBool() );
mLayerTreeCanvasBridge->clear();
//set the color for selections
//the default can be set in qgisoptions
//use project properties to override the color on a per project basis
@ -11833,11 +11829,11 @@ void QgisApp::writeProject( QDomDocument &doc )
// The <legend> tag is ignored by QGIS application in >= 2.4 and this way also the new project files
// can be opened in older versions of QGIS without losing information about layer groups.
QgsLayerTreeNode *clonedRoot = QgsProject::instance()->layerTreeRoot()->clone();
QgsLayerTree *clonedRoot = QgsProject::instance()->layerTreeRoot()->clone();
QgsLayerTreeUtils::replaceChildrenOfEmbeddedGroups( QgsLayerTree::toGroup( clonedRoot ) );
QgsLayerTreeUtils::updateEmbeddedGroupsProjectPath( QgsLayerTree::toGroup( clonedRoot ), QgsProject::instance() ); // convert absolute paths to relative paths if required
QDomElement oldLegendElem = QgsLayerTreeUtils::writeOldLegend( doc, QgsLayerTree::toGroup( clonedRoot ),
mLayerTreeCanvasBridge->hasCustomLayerOrder(), mLayerTreeCanvasBridge->customLayerOrder() );
clonedRoot->hasCustomLayerOrder(), clonedRoot->customLayerOrder() );
delete clonedRoot;
QDomElement qgisNode = doc.firstChildElement( QStringLiteral( "qgis" ) );
qgisNode.appendChild( oldLegendElem );

View File

@ -94,7 +94,7 @@ void FieldSelectorDelegate::setModelData( QWidget *editor, QAbstractItemModel *m
model->setData( index, vl->fields().lookupField( fcb->currentField() ) );
}
QgsVectorLayerAndAttributeModel::QgsVectorLayerAndAttributeModel( QgsLayerTreeGroup *rootNode, QObject *parent )
QgsVectorLayerAndAttributeModel::QgsVectorLayerAndAttributeModel( QgsLayerTree *rootNode, QObject *parent )
: QgsLayerTreeModel( rootNode, parent )
{
}
@ -312,13 +312,18 @@ QList< QPair<QgsVectorLayer *, int> > QgsVectorLayerAndAttributeModel::layers()
}
}
QgsLayerTreeMapCanvasBridge *bridge = QgisApp::instance()->layerTreeCanvasBridge();
QStringList inDrawingOrder = bridge->hasCustomLayerOrder() ? bridge->customLayerOrder() : bridge->defaultLayerOrder();
QList< QPair<QgsVectorLayer *, int> > layersInROrder;
for ( int i = inDrawingOrder.size() - 1; i >= 0; i-- )
QList<QgsMapLayer *> layerOrder = mRootNode->layerOrder();
QList<QgsMapLayer *>::ConstIterator layerIterator = layerOrder.constEnd();
while ( layerIterator != layerOrder.constBegin() )
{
int idx = layerIdx.value( inDrawingOrder[i], -1 );
--layerIterator;
QgsMapLayer *l = *layerIterator;
int idx = layerIdx.value( l->id(), -1 );
if ( idx < 0 )
continue;
@ -422,7 +427,7 @@ QgsDxfExportDialog::QgsDxfExportDialog( QWidget *parent, Qt::WindowFlags f )
{
setupUi( this );
mLayerTreeGroup = QgsLayerTree::toGroup( QgsProject::instance()->layerTreeRoot()->clone() );
mLayerTreeGroup = QgsProject::instance()->layerTreeRoot()->clone();
cleanGroup( mLayerTreeGroup );
mFieldSelectorDelegate = new FieldSelectorDelegate( this );

View File

@ -45,7 +45,7 @@ class QgsVectorLayerAndAttributeModel : public QgsLayerTreeModel
{
Q_OBJECT
public:
QgsVectorLayerAndAttributeModel( QgsLayerTreeGroup *rootNode, QObject *parent = nullptr );
QgsVectorLayerAndAttributeModel( QgsLayerTree *rootNode, QObject *parent = nullptr );
~QgsVectorLayerAndAttributeModel();
int columnCount( const QModelIndex &parent = QModelIndex() ) const override;
@ -105,7 +105,7 @@ class QgsDxfExportDialog : public QDialog, private Ui::QgsDxfExportDialogBase
private:
void cleanGroup( QgsLayerTreeNode *node );
QgsLayerTreeGroup *mLayerTreeGroup = nullptr;
QgsLayerTree *mLayerTreeGroup = nullptr;
FieldSelectorDelegate *mFieldSelectorDelegate = nullptr;
QgsCoordinateReferenceSystem mCRS;

View File

@ -86,15 +86,12 @@ QList<QgsMapLayer *> QgsMapThemes::orderedPresetVisibleLayers( const QString &na
QStringList visibleIds = QgsProject::instance()->mapThemeCollection()->mapThemeVisibleLayerIds( name );
// also make sure to order the layers according to map canvas order
QgsLayerTreeMapCanvasBridge *bridge = QgisApp::instance()->layerTreeCanvasBridge();
QStringList order = bridge->hasCustomLayerOrder() ? bridge->customLayerOrder() : bridge->defaultLayerOrder();
QList<QgsMapLayer *> lst;
Q_FOREACH ( const QString &layerID, order )
Q_FOREACH ( QgsMapLayer *layer, QgsProject::instance()->layerTreeRoot()->layerOrder() )
{
if ( visibleIds.contains( layerID ) )
if ( visibleIds.contains( layer->id() ) )
{
if ( QgsMapLayer *layer = QgsProject::instance()->mapLayer( layerID ) )
lst << layer;
lst << layer;
}
}
return lst;

View File

@ -29,7 +29,7 @@
QgsProjectLayerGroupDialog::QgsProjectLayerGroupDialog( QWidget *parent, const QString &projectFile, Qt::WindowFlags f )
: QDialog( parent, f )
, mShowEmbeddedContent( false )
, mRootGroup( new QgsLayerTreeGroup )
, mRootGroup( new QgsLayerTree )
{
setupUi( this );

View File

@ -21,7 +21,7 @@
class QDomElement;
class QgsLayerTreeGroup;
class QgsLayerTree;
//! A dialog to select layers and groups from a qgs project
class APP_EXPORT QgsProjectLayerGroupDialog: public QDialog, private Ui::QgsProjectLayerGroupDialogBase
@ -52,7 +52,7 @@ class APP_EXPORT QgsProjectLayerGroupDialog: public QDialog, private Ui::QgsProj
QString mProjectPath;
bool mShowEmbeddedContent;
QgsLayerTreeGroup *mRootGroup = nullptr;
QgsLayerTree *mRootGroup = nullptr;
};
#endif //QGSPROJECTLAYERGROUPDIALOG_H

View File

@ -54,6 +54,7 @@
#include "qgslayertreemodel.h"
#include "qgsunittypes.h"
#include "qgstablewidgetitem.h"
#include "qgslayertree.h"
#include "qgsmessagelog.h"

View File

@ -57,6 +57,7 @@
#include "qgsstyle.h"
#include "layertree/qgslayertreelayer.h"
#include "qgslayertree.h"
#include <QMessageBox>
#include <QDir>

View File

@ -196,7 +196,7 @@ class APP_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private
QgsExpressionContext createExpressionContext() const override;
std::unique_ptr<QgsLayerTreeGroup> mLayersDependenciesTreeGroup;
std::unique_ptr<QgsLayerTree> mLayersDependenciesTreeGroup;
std::unique_ptr<QgsLayerTreeModel> mLayersDependenciesTreeModel;
private slots:

View File

@ -69,6 +69,7 @@ SET(QGIS_CORE_SRCS
layertree/qgslayertreenode.cpp
layertree/qgslayertreeregistrybridge.cpp
layertree/qgslayertreeutils.cpp
layertree/qgslayertree.cpp
auth/qgsauthcertutils.cpp
auth/qgsauthconfig.cpp
@ -605,6 +606,7 @@ SET(QGIS_CORE_MOC_HDRS
symbology-ng/qgssvgcache.h
symbology-ng/qgsstyle.h
layertree/qgslayertree.h
layertree/qgslayertreegroup.h
layertree/qgslayertreelayer.h
layertree/qgslayertreemodel.h
@ -899,7 +901,6 @@ SET(QGIS_CORE_HDRS
symbology-ng/qgsvectorfieldsymbollayer.h
symbology-ng/qgsgeometrygeneratorsymbollayer.h
layertree/qgslayertree.h
layertree/qgslayertreeutils.h
geometry/qgsabstractgeometry.h

View File

@ -223,7 +223,7 @@ bool QgsComposerLegend::resizeToContents() const
return mSizeToContents;
}
void QgsComposerLegend::setCustomLayerTree( QgsLayerTreeGroup *rootGroup )
void QgsComposerLegend::setCustomLayerTree( QgsLayerTree *rootGroup )
{
mLegendModel->setRootGroup( rootGroup ? rootGroup : mComposition->project()->layerTreeRoot() );
@ -237,7 +237,7 @@ void QgsComposerLegend::setAutoUpdateModel( bool autoUpdate )
if ( autoUpdate == autoUpdateModel() )
return;
setCustomLayerTree( autoUpdate ? nullptr : QgsLayerTree::toGroup( mComposition->project()->layerTreeRoot()->clone() ) );
setCustomLayerTree( autoUpdate ? nullptr : mComposition->project()->layerTreeRoot()->clone() );
adjustBoxSize();
updateItem();
}
@ -528,20 +528,12 @@ bool QgsComposerLegend::readXml( const QDomElement &itemElem, const QDomDocument
setComposerMap( mComposition->getComposerMapById( itemElem.attribute( QStringLiteral( "map" ) ).toInt() ) );
}
QDomElement oldLegendModelElem = itemElem.firstChildElement( QStringLiteral( "Model" ) );
if ( !oldLegendModelElem.isNull() )
{
// QGIS <= 2.4
QgsLayerTreeGroup *nodeRoot = new QgsLayerTreeGroup();
_readOldLegendGroup( oldLegendModelElem, nodeRoot, mComposition->project() );
setCustomLayerTree( nodeRoot );
}
else
{
// QGIS >= 2.6
QDomElement layerTreeElem = itemElem.firstChildElement( QStringLiteral( "layer-tree-group" ) );
setCustomLayerTree( QgsLayerTreeGroup::readXml( layerTreeElem, mComposition->project() ) );
}
// QGIS >= 2.6
QDomElement layerTreeElem = itemElem.firstChildElement( QStringLiteral( "layer-tree" ) );
if ( layerTreeElem.isNull() )
layerTreeElem = itemElem.firstChildElement( QStringLiteral( "layer-tree-group" ) );
setCustomLayerTree( QgsLayerTree::readXml( layerTreeElem ) );
//restore general composer item properties
QDomNodeList composerItemList = itemElem.elementsByTagName( QStringLiteral( "ComposerItem" ) );
@ -789,7 +781,7 @@ void QgsComposerLegend::onAtlasEnded()
#include "qgslayertreemodellegendnode.h"
#include "qgsvectorlayer.h"
QgsLegendModel::QgsLegendModel( QgsLayerTreeGroup *rootNode, QObject *parent )
QgsLegendModel::QgsLegendModel( QgsLayerTree *rootNode, QObject *parent )
: QgsLayerTreeModel( rootNode, parent )
{
setFlag( QgsLayerTreeModel::AllowLegendChangeState, false );

View File

@ -41,7 +41,7 @@ class CORE_EXPORT QgsLegendModel : public QgsLayerTreeModel
public:
//! Construct the model based on the given layer tree
QgsLegendModel( QgsLayerTreeGroup *rootNode, QObject *parent = nullptr );
QgsLegendModel( QgsLayerTree *rootNode, QObject *parent = nullptr );
QVariant data( const QModelIndex &index, int role ) const override;
@ -306,7 +306,7 @@ class CORE_EXPORT QgsComposerLegend : public QgsComposerItem
QgsComposerLegend(); //forbidden
//! use new custom layer tree and update model. if new root is null pointer, will use project's tree
void setCustomLayerTree( QgsLayerTreeGroup *rootGroup );
void setCustomLayerTree( QgsLayerTree *rootGroup );
QgsLegendModel *mLegendModel = nullptr;
QgsLayerTreeGroup *mCustomLayerTree = nullptr;

View File

@ -0,0 +1,243 @@
/***************************************************************************
qgslayertree
---------------------
begin : 22.3.2017
copyright : (C) 2017 by Matthias Kuhn
email : matthias@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgslayertree.h"
#include "qgsmaplayerlistutils.h"
QgsLayerTree::QgsLayerTree()
: QgsLayerTreeGroup()
{
connect( this, &QgsLayerTree::addedChildren, this, &QgsLayerTree::nodeAddedChildren );
connect( this, &QgsLayerTree::removedChildren, this, &QgsLayerTree::nodeRemovedChildren );
}
QgsLayerTree::QgsLayerTree( const QgsLayerTree &other )
: QgsLayerTreeGroup( other )
, mCustomLayerOrder( other.mCustomLayerOrder )
, mHasCustomLayerOrder( other.mHasCustomLayerOrder )
{
connect( this, &QgsLayerTree::addedChildren, this, &QgsLayerTree::nodeAddedChildren );
connect( this, &QgsLayerTree::removedChildren, this, &QgsLayerTree::nodeRemovedChildren );
}
QList<QgsMapLayer *> QgsLayerTree::customLayerOrder() const
{
return _qgis_listQPointerToRaw( mCustomLayerOrder );
}
void QgsLayerTree::setCustomLayerOrder( const QList<QgsMapLayer *> &customLayerOrder )
{
QgsWeakMapLayerPointerList newOrder = _qgis_listRawToQPointer( customLayerOrder );
if ( newOrder == mCustomLayerOrder )
return;
mCustomLayerOrder = newOrder;
emit customLayerOrderChanged();
if ( mHasCustomLayerOrder )
emit layerOrderChanged();
}
void QgsLayerTree::setCustomLayerOrder( const QStringList &customLayerOrder )
{
QList<QgsMapLayer *> layers;
Q_FOREACH ( const QString &layerId, customLayerOrder )
{
QgsLayerTreeLayer *nodeLayer = findLayer( layerId );
if ( nodeLayer )
{
layers.append( nodeLayer->layer() );
}
}
setCustomLayerOrder( layers );
}
QList<QgsMapLayer *> QgsLayerTree::layerOrder() const
{
if ( mHasCustomLayerOrder )
return customLayerOrder();
else
{
QList<QgsMapLayer *> layers;
Q_FOREACH ( QgsLayerTreeLayer *treeLayer, findLayers() )
{
layers.append( treeLayer->layer() );
}
return layers;
}
}
bool QgsLayerTree::hasCustomLayerOrder() const
{
return mHasCustomLayerOrder;
}
void QgsLayerTree::setHasCustomLayerOrder( bool hasCustomLayerOrder )
{
if ( hasCustomLayerOrder == mHasCustomLayerOrder )
return;
mHasCustomLayerOrder = hasCustomLayerOrder;
emit hasCustomLayerOrderChanged( hasCustomLayerOrder );
emit layerOrderChanged();
}
QgsLayerTree *QgsLayerTree::readXml( QDomElement &element )
{
QgsLayerTree *tree = new QgsLayerTree();
tree->readCommonXml( element );
tree->readChildrenFromXml( element );
return tree;
}
void QgsLayerTree::writeXml( QDomElement &parentElement )
{
QDomDocument doc = parentElement.ownerDocument();
QDomElement elem = doc.createElement( QStringLiteral( "layer-tree" ) );
writeCommonXml( elem );
Q_FOREACH ( QgsLayerTreeNode *node, mChildren )
node->writeXml( elem );
QDomElement customOrderElem = doc.createElement( QStringLiteral( "custom-order" ) );
customOrderElem.setAttribute( QStringLiteral( "enabled" ), mHasCustomLayerOrder ? 1 : 0 );
elem.appendChild( customOrderElem );
Q_FOREACH ( QgsMapLayer *layer, mCustomLayerOrder )
{
QDomElement layerElem = doc.createElement( QStringLiteral( "item" ) );
layerElem.appendChild( doc.createTextNode( layer->id() ) );
customOrderElem.appendChild( layerElem );
}
elem.appendChild( customOrderElem );
parentElement.appendChild( elem );
}
QgsLayerTree *QgsLayerTree::clone() const
{
return new QgsLayerTree( *this );
}
void QgsLayerTree::clear()
{
removeAllChildren();
setHasCustomLayerOrder( false );
setCustomLayerOrder( QStringList() );
}
void QgsLayerTree::nodeAddedChildren( QgsLayerTreeNode *node, int indexFrom, int indexTo )
{
Q_ASSERT( node );
// collect layer IDs that have been added in order to put them into custom layer order
QList<QgsMapLayer *> layers;
QList<QgsLayerTreeNode *> children = node->children();
for ( int i = indexFrom; i <= indexTo; ++i )
{
QgsLayerTreeNode *child = children.at( i );
if ( QgsLayerTree::isLayer( child ) )
{
layers << QgsLayerTree::toLayer( child )->layer();
}
else if ( QgsLayerTree::isGroup( child ) )
{
Q_FOREACH ( QgsLayerTreeLayer *nodeL, QgsLayerTree::toGroup( child )->findLayers() )
layers << nodeL->layer();
}
}
Q_FOREACH ( QgsMapLayer *layer, layers )
{
if ( !mCustomLayerOrder.contains( layer ) && layer )
mCustomLayerOrder.append( layer );
}
emit customLayerOrderChanged();
emit layerOrderChanged();
}
void QgsLayerTree::nodeRemovedChildren()
{
QList<QgsMapLayer *> layers = customLayerOrder();
auto layer = layers.begin();
while ( layer != layers.end() )
{
if ( !findLayer( *layer ) )
layer = layers.erase( layer );
else
++layer;
}
setCustomLayerOrder( layers );
emit layerOrderChanged();
}
void QgsLayerTree::addMissingLayers()
{
bool changed = false;
QList<QgsLayerTreeLayer *> allLayers = findLayers();
Q_FOREACH ( QgsLayerTreeLayer *layer, allLayers )
{
if ( !mCustomLayerOrder.contains( layer->layer() ) && layer->layer() )
{
mCustomLayerOrder.append( layer->layer() );
changed = true;
}
}
if ( changed )
{
emit customLayerOrderChanged();
if ( mHasCustomLayerOrder )
emit layerOrderChanged();
}
}
void QgsLayerTree::readLayerOrderFromXml( const QDomElement &elem )
{
QStringList order;
QDomElement customOrderElem = elem.firstChildElement( QStringLiteral( "custom-order" ) );
if ( !customOrderElem.isNull() )
{
setHasCustomLayerOrder( customOrderElem.attribute( QStringLiteral( "enabled" ) ).toInt() );
QDomElement itemElem = customOrderElem.firstChildElement( QStringLiteral( "item" ) );
while ( !itemElem.isNull() )
{
order.append( itemElem.text() );
itemElem = itemElem.nextSiblingElement( QStringLiteral( "item" ) );
}
}
setCustomLayerOrder( order );
addMissingLayers();
}

View File

@ -26,40 +26,201 @@
* Only generally useful routines should be here. Miscellaneous utility functions for work
* with the layer tree are in QgsLayerTreeUtils class.
*
* @note added in 2.4
* @note added in QGIS 3.0
*/
namespace QgsLayerTree
class CORE_EXPORT QgsLayerTree : public QgsLayerTreeGroup
{
//! Check whether the node is a valid group node
inline bool isGroup( QgsLayerTreeNode *node )
{
return node && node->nodeType() == QgsLayerTreeNode::NodeGroup;
}
Q_OBJECT
//! Check whether the node is a valid layer node
inline bool isLayer( const QgsLayerTreeNode *node )
{
return node && node->nodeType() == QgsLayerTreeNode::NodeLayer;
}
public:
//! Cast node to a group. No type checking is done - use isGroup() to find out whether this operation is legal.
inline QgsLayerTreeGroup *toGroup( QgsLayerTreeNode *node )
{
return static_cast<QgsLayerTreeGroup *>( node );
}
/**
* Check whether the node is a valid group node
*
* @note Added in QGIS 2.4
*/
static inline bool isGroup( QgsLayerTreeNode *node )
{
return node && node->nodeType() == QgsLayerTreeNode::NodeGroup;
}
//! Cast node to a layer. No type checking is done - use isLayer() to find out whether this operation is legal.
inline QgsLayerTreeLayer *toLayer( QgsLayerTreeNode *node )
{
return static_cast<QgsLayerTreeLayer *>( node );
}
/**
* Check whether the node is a valid layer node
*
* @note Added in QGIS 2.4
*/
static inline bool isLayer( const QgsLayerTreeNode *node )
{
return node && node->nodeType() == QgsLayerTreeNode::NodeLayer;
}
//! 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 );
}
/**
* Cast node to a group. No type checking is done - use isGroup() to find out whether this operation is legal.
*
* @note Added in QGIS 2.4
*/
static inline QgsLayerTreeGroup *toGroup( QgsLayerTreeNode *node )
{
return static_cast<QgsLayerTreeGroup *>( node );
}
}
/**
* Cast node to a layer. No type checking is done - use isLayer() to find out whether this operation is legal.
*
* @note Added in QGIS 2.4
*/
static inline QgsLayerTreeLayer *toLayer( QgsLayerTreeNode *node )
{
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.
*
* @note Added in QGIS 2.4
*/
static inline const QgsLayerTreeLayer *toLayer( const QgsLayerTreeNode *node )
{
return static_cast< const QgsLayerTreeLayer *>( node );
}
//! Constructor
QgsLayerTree();
QgsLayerTree( const QgsLayerTree &other );
/**
* The order in which layers will be rendered on the canvas.
* Will only be used if the property hasCustomLayerOrder is true.
* If you need the current layer order that is active, prefer using layerOrder().
*
* @see setCustomLayerOrder
* @see layerOrder
* @see hasCustomLayerOrder
*
* @note Added in QGIS 3.0
*/
QList<QgsMapLayer *> customLayerOrder() const;
/**
* The order in which layers will be rendered on the canvas.
* Will only be used if the property hasCustomLayerOrder is true.
* If you need the current layer order that is active, prefer using layerOrder().
*
* @see customLayerOrder
* @see layerOrder
* @see hasCustomLayerOrder
*
* @note Added in QGIS 3.0
*/
void setCustomLayerOrder( const QList<QgsMapLayer *> &customLayerOrder );
/**
* The order in which layers will be rendered on the canvas.
* Will only be used if the property hasCustomLayerOrder is true.
* If you need the current layer order that is active, prefer using layerOrder().
*
* @see customLayerOrder
* @see layerOrder
* @see hasCustomLayerOrder
*
* @note Added in QGIS 3.0
*/
void setCustomLayerOrder( const QStringList &customLayerOrder );
/**
* The order in which layers will be rendered on the canvas.
* Depending on hasCustomLayerOrder, this will return either the override
* customLayerOrder or the layer order derived from the tree.
* This property is read only.
*
* @see customLayerOrder
*
* @note Added in QGIS 3.0
*/
QList<QgsMapLayer *> layerOrder() const;
/**
* Determines if the layer order should be derived from the layer tree
* or if a custom override order shall be used instead.
*
* @see customLayerOrder
*
* @note Added in QGIS 3.0
*/
bool hasCustomLayerOrder() const;
/**
* Determines if the layer order should be derived from the layer tree
* or if a custom override order shall be used instead.
*
* @see setCustomLayerOrder
*
* @note Added in QGIS 3.0
*/
void setHasCustomLayerOrder( bool hasCustomLayerOrder );
/**
* Load the layer tree from an XML element.
* It is not required that layers are loaded at this point.
* resolveReferences() needs to be called after loading the layers and
* before using the tree.
*
* @note Added in QGIS 3.0
*/
static QgsLayerTree *readXml( QDomElement &element );
/**
* Load the layer order from an XML element.
* Make sure that this is only called after the layers are loaded.
*
* @note Added in QGIS 3.0
*/
void readLayerOrderFromXml( const QDomElement &doc );
virtual void writeXml( QDomElement &parentElement ) override;
virtual QgsLayerTree *clone() const override;
/**
* Clear any information from this layer tree.
*
* @note Added in QGIS 3.0
*/
void clear();
signals:
/**
* Emitted when the custom layer order has changed.
*
* @note Added in QGIS 3.0
*/
void customLayerOrderChanged();
/**
* Emitted when the layer order has changed.
*
* @note Added in QGIS 3.0
*/
void layerOrderChanged();
/**
* Emitted when the hasCustomLayerOrder flag changes.
*
* @see hasCustomLayerOrder
*
* @note Added in QGIS 3.0
*/
void hasCustomLayerOrderChanged( bool hasCustomLayerOrder );
private slots:
void nodeAddedChildren( QgsLayerTreeNode *node, int indexFrom, int indexTo );
void nodeRemovedChildren();
private:
void addMissingLayers();
QgsWeakMapLayerPointerList mCustomLayerOrder;
bool mHasCustomLayerOrder = false;
};
#endif // QGSLAYERTREE_H

View File

@ -63,7 +63,7 @@ class EmbeddedWidgetLegendNode : public QgsLayerTreeModelLegendNode
///@endcond
QgsLayerTreeModel::QgsLayerTreeModel( QgsLayerTreeGroup *rootNode, QObject *parent )
QgsLayerTreeModel::QgsLayerTreeModel( QgsLayerTree *rootNode, QObject *parent )
: QAbstractItemModel( parent )
, mRootNode( rootNode )
, mFlags( ShowLegend | AllowLegendChangeState | DeferredLegendInvalidation )
@ -498,12 +498,12 @@ QList<QgsLayerTreeNode *> QgsLayerTreeModel::indexes2nodes( const QModelIndexLis
return nodesFinal;
}
QgsLayerTreeGroup *QgsLayerTreeModel::rootGroup() const
QgsLayerTree *QgsLayerTreeModel::rootGroup() const
{
return mRootNode;
}
void QgsLayerTreeModel::setRootGroup( QgsLayerTreeGroup *newRootGroup )
void QgsLayerTreeModel::setRootGroup( QgsLayerTree *newRootGroup )
{
beginResetModel();

View File

@ -24,6 +24,7 @@
#include <memory>
#include "qgsgeometry.h"
#include "qgsmaplayer.h"
class QgsLayerTreeNode;
class QgsLayerTreeGroup;
@ -34,6 +35,7 @@ class QgsMapLayer;
class QgsMapSettings;
class QgsExpression;
class QgsRenderContext;
class QgsLayerTree;
/** \ingroup core
* The QgsLayerTreeModel class is model implementation for Qt item views framework.
@ -55,7 +57,8 @@ class CORE_EXPORT QgsLayerTreeModel : public QAbstractItemModel
public:
//! Construct a new tree model with given layer tree (root node must not be null pointer).
//! The root node is not transferred by the model.
explicit QgsLayerTreeModel( QgsLayerTreeGroup *rootNode, QObject *parent = nullptr );
explicit QgsLayerTreeModel( QgsLayerTree *rootNode, QObject *parent = nullptr );
~QgsLayerTreeModel();
// Implementation of virtual functions from QAbstractItemModel
@ -146,10 +149,10 @@ class CORE_EXPORT QgsLayerTreeModel : public QAbstractItemModel
QgsLayerTreeModelLegendNode *findLegendNode( const QString &layerId, const QString &ruleKey ) const;
//! Return pointer to the root node of the layer tree. Always a non-null pointer.
QgsLayerTreeGroup *rootGroup() const;
QgsLayerTree *rootGroup() const;
//! Reset the model and use a new root group node
//! @note added in 2.6
void setRootGroup( QgsLayerTreeGroup *newRootGroup );
void setRootGroup( QgsLayerTree *newRootGroup );
//! Force a refresh of legend nodes of a layer node.
//! Not necessary to call when layer's renderer is changed as the model listens to these events.
@ -210,8 +213,6 @@ class CORE_EXPORT QgsLayerTreeModel : public QAbstractItemModel
//! @note added in 2.10
void setLayerStyleOverrides( const QMap<QString, QString> &overrides );
signals:
protected slots:
void nodeWillAddChildren( QgsLayerTreeNode *node, int indexFrom, int indexTo );
void nodeAddedChildren( QgsLayerTreeNode *node, int indexFrom, int indexTo );
@ -277,7 +278,7 @@ class CORE_EXPORT QgsLayerTreeModel : public QAbstractItemModel
protected:
//! Pointer to the root node of the layer tree. Not owned by the model
QgsLayerTreeGroup *mRootNode = nullptr;
QgsLayerTree *mRootNode = nullptr;
//! Set of flags for the model
Flags mFlags;
//! Current index - will be underlined

View File

@ -103,11 +103,11 @@ bool QgsLayerTreeUtils::readOldLegendLayerOrder( const QDomElement &legendElem,
}
static QDomElement _writeOldLegendLayer( QDomDocument &doc, QgsLayerTreeLayer *nodeLayer, bool hasCustomOrder, const QStringList &order )
static QDomElement _writeOldLegendLayer( QDomDocument &doc, QgsLayerTreeLayer *nodeLayer, bool hasCustomOrder, const QList<QgsMapLayer *> &order )
{
int drawingOrder = -1;
if ( hasCustomOrder )
drawingOrder = order.indexOf( nodeLayer->layerId() );
drawingOrder = order.indexOf( nodeLayer->layer() );
QDomElement layerElem = doc.createElement( QStringLiteral( "legendlayer" ) );
layerElem.setAttribute( QStringLiteral( "drawingOrder" ), drawingOrder );
@ -131,9 +131,9 @@ static QDomElement _writeOldLegendLayer( QDomDocument &doc, QgsLayerTreeLayer *n
}
// need forward declaration as write[..]Group and write[..]GroupChildren call each other
static void _writeOldLegendGroupChildren( QDomDocument &doc, QDomElement &groupElem, QgsLayerTreeGroup *nodeGroup, bool hasCustomOrder, const QStringList &order );
static void _writeOldLegendGroupChildren( QDomDocument &doc, QDomElement &groupElem, QgsLayerTreeGroup *nodeGroup, bool hasCustomOrder, const QList<QgsMapLayer *> &order );
static QDomElement _writeOldLegendGroup( QDomDocument &doc, QgsLayerTreeGroup *nodeGroup, bool hasCustomOrder, const QStringList &order )
static QDomElement _writeOldLegendGroup( QDomDocument &doc, QgsLayerTreeGroup *nodeGroup, bool hasCustomOrder, const QList<QgsMapLayer *> &order )
{
QDomElement groupElem = doc.createElement( QStringLiteral( "legendgroup" ) );
groupElem.setAttribute( QStringLiteral( "open" ), nodeGroup->isExpanded() ? "true" : "false" );
@ -151,7 +151,7 @@ static QDomElement _writeOldLegendGroup( QDomDocument &doc, QgsLayerTreeGroup *n
}
static void _writeOldLegendGroupChildren( QDomDocument &doc, QDomElement &groupElem, QgsLayerTreeGroup *nodeGroup, bool hasCustomOrder, const QStringList &order )
static void _writeOldLegendGroupChildren( QDomDocument &doc, QDomElement &groupElem, QgsLayerTreeGroup *nodeGroup, bool hasCustomOrder, const QList<QgsMapLayer *> &order )
{
Q_FOREACH ( QgsLayerTreeNode *node, nodeGroup->children() )
{
@ -167,7 +167,7 @@ static void _writeOldLegendGroupChildren( QDomDocument &doc, QDomElement &groupE
}
QDomElement QgsLayerTreeUtils::writeOldLegend( QDomDocument &doc, QgsLayerTreeGroup *root, bool hasCustomOrder, const QStringList &order )
QDomElement QgsLayerTreeUtils::writeOldLegend( QDomDocument &doc, QgsLayerTreeGroup *root, bool hasCustomOrder, const QList<QgsMapLayer *> &order )
{
QDomElement legendElem = doc.createElement( QStringLiteral( "legend" ) );
legendElem.setAttribute( QStringLiteral( "updateDrawingOrder" ), hasCustomOrder ? "false" : "true" );

View File

@ -45,7 +45,7 @@ class CORE_EXPORT QgsLayerTreeUtils
//! Try to load custom layer order from \verbatim <legend> \endverbatim tag from project files from QGIS 2.2 and below
static bool readOldLegendLayerOrder( const QDomElement &legendElem, bool &hasCustomOrder, QStringList &order );
//! Return \verbatim <legend> \endverbatim tag used in QGIS 2.2 and below
static QDomElement writeOldLegend( QDomDocument &doc, QgsLayerTreeGroup *root, bool hasCustomOrder, const QStringList &order );
static QDomElement writeOldLegend( QDomDocument &doc, QgsLayerTreeGroup *root, bool hasCustomOrder, const QList<QgsMapLayer *> &order );
//! Convert Qt::CheckState to QString
static QString checkStateToXml( Qt::CheckState state );

View File

@ -180,7 +180,7 @@ QList<QgsMapLayer *> QgsMapThemeCollection::masterLayerOrder() const
if ( !mProject )
return QList< QgsMapLayer * >();
return mProject->layerOrder();
return mProject->layerTreeRoot()->layerOrder();
}
QList<QgsMapLayer *> QgsMapThemeCollection::masterVisibleLayers() const

View File

@ -327,7 +327,7 @@ QgsProject::QgsProject( QObject *parent )
, mRelationManager( new QgsRelationManager( this ) )
, mAnnotationManager( new QgsAnnotationManager( this ) )
, mLayoutManager( new QgsLayoutManager( this ) )
, mRootGroup( new QgsLayerTreeGroup )
, mRootGroup( new QgsLayerTree )
, mAutoTransaction( false )
, mEvaluateDefaultValues( false )
, mDirty( false )
@ -458,7 +458,6 @@ void QgsProject::clear()
mEvaluateDefaultValues = false;
mDirty = false;
mCustomVariables.clear();
mLayerOrder.clear();
mEmbeddedLayers.clear();
mRelationManager->clear();
@ -470,7 +469,7 @@ void QgsProject::clear()
mMapThemeCollection.reset( new QgsMapThemeCollection( this ) );
emit mapThemeCollectionChanged();
mRootGroup->removeAllChildren();
mRootGroup->clear();
// reset some default project properties
// XXX THESE SHOULD BE MOVED TO STATUSBAR RELATED SOURCE
@ -847,7 +846,7 @@ bool QgsProject::read()
mRootGroup->setCustomProperty( QStringLiteral( "loading" ), 1 );
QDomElement layerTreeElem = doc->documentElement().firstChildElement( QStringLiteral( "layer-tree-group" ) );
QDomElement layerTreeElem = doc->documentElement().firstChildElement( QStringLiteral( "layer-tree" ) );
if ( !layerTreeElem.isNull() )
{
// read the tree but do not resolve the references (we have not loaded the layers yet)
@ -855,11 +854,17 @@ bool QgsProject::read()
}
else
{
QgsLayerTreeUtils::readOldLegend( mRootGroup, doc->documentElement().firstChildElement( QStringLiteral( "legend" ) ) );
QDomElement layerTreeGroupElem = doc->documentElement().firstChildElement( QStringLiteral( "layer-tree-group" ) );
if ( !layerTreeGroupElem.isNull() )
{
mRootGroup->readChildrenFromXml( layerTreeGroupElem );
}
else
{
QgsLayerTreeUtils::readOldLegend( mRootGroup, doc->documentElement().firstChildElement( QStringLiteral( "legend" ) ) );
}
}
QgsDebugMsg( "Loaded layer tree:\n " + mRootGroup->dump() );
mLayerTreeRegistryBridge->setEnabled( false );
// get the map layers
@ -894,51 +899,20 @@ bool QgsProject::read()
// load embedded groups and layers
loadEmbeddedNodes( mRootGroup );
// load layer order
QList< QgsMapLayer * > layerOrder;
QDomNodeList layerOrderNodes = doc->elementsByTagName( QStringLiteral( "layerorder" ) );
if ( layerOrderNodes.count() )
// now that layers are loaded, we can resolve layer tree's references to the layers
mRootGroup->resolveReferences( this );
if ( !layerTreeElem.isNull() )
{
QDomElement layerOrderElem = layerOrderNodes.at( 0 ).toElement();
for ( int i = 0; i < layerOrderElem.childNodes().count(); ++i )
{
QDomElement layerElem = layerOrderElem.childNodes().at( i ).toElement();
layerOrder << mMapLayers.value( layerElem.attribute( QStringLiteral( "id" ) ) );
}
mRootGroup->readLayerOrderFromXml( layerTreeElem );
}
else
{
//old layer order nodes
QStringList order;
// Load pre 3.0 configuration
QDomElement elem = doc->documentElement().firstChildElement( QStringLiteral( "layer-tree-canvas" ) );
if ( elem.isNull() )
{
bool oldEnabled;
QgsLayerTreeUtils::readOldLegendLayerOrder( doc->documentElement().firstChildElement( QStringLiteral( "legend" ) ), oldEnabled, order );
}
else
{
QDomElement customOrderElem = elem.firstChildElement( QStringLiteral( "custom-order" ) );
if ( !customOrderElem.isNull() )
{
QDomElement itemElem = customOrderElem.firstChildElement( QStringLiteral( "item" ) );
while ( !itemElem.isNull() )
{
order.append( itemElem.text() );
itemElem = itemElem.nextSiblingElement( QStringLiteral( "item" ) );
}
}
}
Q_FOREACH ( const QString &id, order )
{
layerOrder << mMapLayers.value( id );
}
mRootGroup->readLayerOrderFromXml( elem );
}
setLayerOrder( layerOrder );
// now that layers are loaded, we can resolve layer tree's references to the layers
mRootGroup->resolveReferences( this );
// make sure the are just valid layers
QgsLayerTreeUtils::removeInvalidLayers( mRootGroup );
@ -1302,7 +1276,7 @@ bool QgsProject::write()
qgisNode.appendChild( projectLayersNode );
QDomElement layerOrderNode = doc->createElement( QStringLiteral( "layerorder" ) );
Q_FOREACH ( QgsMapLayer *layer, layerOrder() )
Q_FOREACH ( QgsMapLayer *layer, mRootGroup->customLayerOrder() )
{
QDomElement mapLayerElem = doc->createElement( QStringLiteral( "layer" ) );
mapLayerElem.setAttribute( QStringLiteral( "id" ), layer->id() );
@ -2004,7 +1978,7 @@ QgsLayoutManager *QgsProject::layoutManager()
return mLayoutManager.get();
}
QgsLayerTreeGroup *QgsProject::layerTreeRoot() const
QgsLayerTree *QgsProject::layerTreeRoot() const
{
return mRootGroup;
}
@ -2171,7 +2145,6 @@ void QgsProject::removeMapLayers( const QList<QgsMapLayer *> &layers )
QStringList layerIds;
QList<QgsMapLayer *> layerList;
QList< QgsMapLayer * > currentOrder = layerOrder();
Q_FOREACH ( QgsMapLayer *layer, layers )
{
// check layer and the registry contains it
@ -2232,20 +2205,6 @@ void QgsProject::reloadAllLayers()
}
}
QList<QgsMapLayer *> QgsProject::layerOrder() const
{
return _qgis_listQPointerToRaw( mLayerOrder );
}
void QgsProject::setLayerOrder( const QList<QgsMapLayer *> &order )
{
if ( order == layerOrder() )
return;
mLayerOrder = _qgis_listRawToQPointer( order );
emit layerOrderChanged();
}
void QgsProject::onMapLayerDeleted( QObject *obj )
{
QString id = mMapLayers.key( static_cast<QgsMapLayer *>( obj ) );

View File

@ -57,6 +57,7 @@ class QgsTransactionGroup;
class QgsVectorLayer;
class QgsAnnotationManager;
class QgsLayoutManager;
class QgsLayerTree;
/** \ingroup core
* Reads and writes project states.
@ -395,7 +396,7 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
/** Return pointer to the root (invisible) node of the project's layer tree
* @note added in 2.4
*/
QgsLayerTreeGroup *layerTreeRoot() const;
QgsLayerTree *layerTreeRoot() const;
/** Return pointer to the helper class that synchronizes map layer registry with layer tree
* @note added in 2.4
@ -705,22 +706,6 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
*/
void reloadAllLayers();
/**
* Returns an ordered list of layers. This list reflects the order of layers as
* drawn in the main map canvas for the project.
* @note added in QGIS 3.0
* @see setLayerOrder()
*/
QList< QgsMapLayer * > layerOrder() const;
/**
* Sets the \a order for layers in the project. This list reflects the order of layers shown in
* the layer tree for the project.
* @note added in QGIS 3.0
* @see layerOrder()
*/
void setLayerOrder( const QList< QgsMapLayer * > &order );
signals:
//! emitted when project is being read
void readProject( const QDomDocument & );
@ -923,13 +908,6 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
*/
void legendLayersAdded( const QList<QgsMapLayer *> &layers );
/**
* Emitted when the order of layers in the project is changed.
* @note added in QGIS 3.0
* @see setLayerOrder()
*/
void layerOrderChanged();
public slots:
/**
@ -989,8 +967,6 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
QMap<QString, QgsMapLayer *> mMapLayers;
QgsWeakMapLayerPointerList mLayerOrder;
QString mErrorMessage;
QgsProjectBadLayerHandler *mBadLayerHandler = nullptr;
@ -1008,7 +984,7 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
std::unique_ptr<QgsAnnotationManager> mAnnotationManager;
std::unique_ptr<QgsLayoutManager> mLayoutManager;
QgsLayerTreeGroup *mRootGroup = nullptr;
QgsLayerTree *mRootGroup = nullptr;
QgsLayerTreeRegistryBridge *mLayerTreeRegistryBridge = nullptr;

View File

@ -45,11 +45,11 @@ QgsCustomLayerOrderWidget::QgsCustomLayerOrderWidget( QgsLayerTreeMapCanvasBridg
mView->setModel( mModel );
mChkOverride = new QCheckBox( tr( "Control rendering order" ) );
bridgeHasCustomLayerOrderChanged( bridge->hasCustomLayerOrder() );
connect( mChkOverride, &QAbstractButton::toggled, bridge, &QgsLayerTreeMapCanvasBridge::setHasCustomLayerOrder );
bridgeHasCustomLayerOrderChanged( bridge->rootGroup()->hasCustomLayerOrder() );
connect( mChkOverride, &QAbstractButton::toggled, bridge->rootGroup(), &QgsLayerTree::setHasCustomLayerOrder );
connect( bridge, &QgsLayerTreeMapCanvasBridge::hasCustomLayerOrderChanged, this, &QgsCustomLayerOrderWidget::bridgeHasCustomLayerOrderChanged );
connect( bridge, &QgsLayerTreeMapCanvasBridge::customLayerOrderChanged, this, &QgsCustomLayerOrderWidget::bridgeCustomLayerOrderChanged );
connect( bridge->rootGroup(), &QgsLayerTree::hasCustomLayerOrderChanged, this, &QgsCustomLayerOrderWidget::bridgeHasCustomLayerOrderChanged );
connect( bridge->rootGroup(), &QgsLayerTree::customLayerOrderChanged, this, &QgsCustomLayerOrderWidget::bridgeCustomLayerOrderChanged );
connect( mModel, &QAbstractItemModel::rowsInserted, this, &QgsCustomLayerOrderWidget::modelUpdated );
connect( mModel, &QAbstractItemModel::rowsRemoved, this, &QgsCustomLayerOrderWidget::modelUpdated );
@ -66,14 +66,12 @@ QgsCustomLayerOrderWidget::QgsCustomLayerOrderWidget( QgsLayerTreeMapCanvasBridg
void QgsCustomLayerOrderWidget::bridgeHasCustomLayerOrderChanged( bool state )
{
mChkOverride->setChecked( state );
mModel->refreshModel( mBridge->hasCustomLayerOrder() ? mBridge->customLayerOrder() : mBridge->defaultLayerOrder() );
mView->setEnabled( state );
}
void QgsCustomLayerOrderWidget::bridgeCustomLayerOrderChanged( const QStringList &order )
void QgsCustomLayerOrderWidget::bridgeCustomLayerOrderChanged()
{
Q_UNUSED( order );
mModel->refreshModel( mBridge->hasCustomLayerOrder() ? mBridge->customLayerOrder() : mBridge->defaultLayerOrder() );
mModel->refreshModel( mBridge->rootGroup()->layerOrder() );
}
void QgsCustomLayerOrderWidget::nodeVisibilityChanged( QgsLayerTreeNode *node )
@ -86,7 +84,7 @@ void QgsCustomLayerOrderWidget::nodeVisibilityChanged( QgsLayerTreeNode *node )
void QgsCustomLayerOrderWidget::modelUpdated()
{
mBridge->setCustomLayerOrder( mModel->order() );
mBridge->rootGroup()->setCustomLayerOrder( mModel->order() );
}
@ -215,11 +213,21 @@ bool CustomLayerOrderModel::removeRows( int row, int count, const QModelIndex &p
return true;
}
void CustomLayerOrderModel::refreshModel( const QStringList &order )
void CustomLayerOrderModel::refreshModel( const QList<QgsMapLayer *> &order )
{
beginResetModel();
mOrder = order;
endResetModel();
QStringList orderedIds;
Q_FOREACH ( QgsMapLayer *layer, order )
{
if ( layer )
orderedIds.append( layer->id() );
}
if ( orderedIds != mOrder )
{
beginResetModel();
mOrder = orderedIds;
endResetModel();
}
}
void CustomLayerOrderModel::updateLayerVisibility( const QString &layerId )

View File

@ -23,6 +23,7 @@
class CustomLayerOrderModel;
class QgsLayerTreeMapCanvasBridge;
class QgsLayerTreeNode;
class QgsMapLayer;
class QCheckBox;
class QListView;
@ -46,15 +47,15 @@ class GUI_EXPORT QgsCustomLayerOrderWidget : public QWidget
signals:
protected slots:
private slots:
void bridgeHasCustomLayerOrderChanged( bool state );
void bridgeCustomLayerOrderChanged( const QStringList &order );
void bridgeCustomLayerOrderChanged();
//! Slot triggered when the ivsibility of a node changes
void nodeVisibilityChanged( QgsLayerTreeNode *node );
void modelUpdated();
protected:
private:
QgsLayerTreeMapCanvasBridge *mBridge = nullptr;
QCheckBox *mChkOverride = nullptr;
@ -89,7 +90,7 @@ class CustomLayerOrderModel : public QAbstractListModel
bool removeRows( int row, int count, const QModelIndex &parent ) override;
void refreshModel( const QStringList &order );
void refreshModel( const QList<QgsMapLayer *> &order );
QStringList order() const { return mOrder; }

View File

@ -23,108 +23,31 @@
#include "qgsmapoverviewcanvas.h"
#include "qgsproject.h"
QgsLayerTreeMapCanvasBridge::QgsLayerTreeMapCanvasBridge( QgsLayerTreeGroup *root, QgsMapCanvas *canvas, QObject *parent )
QgsLayerTreeMapCanvasBridge::QgsLayerTreeMapCanvasBridge( QgsLayerTree *root, QgsMapCanvas *canvas, QObject *parent )
: QObject( parent )
, mRoot( root )
, mCanvas( canvas )
, mOverviewCanvas( nullptr )
, mPendingCanvasUpdate( false )
, mHasCustomLayerOrder( false )
, mAutoSetupOnFirstLayer( true )
, mLastLayerCount( !root->findLayers().isEmpty() )
{
connect( root, &QgsLayerTreeGroup::addedChildren, this, &QgsLayerTreeMapCanvasBridge::nodeAddedChildren );
connect( root, &QgsLayerTreeGroup::customPropertyChanged, this, &QgsLayerTreeMapCanvasBridge::nodeCustomPropertyChanged );
connect( root, &QgsLayerTreeGroup::removedChildren, this, &QgsLayerTreeMapCanvasBridge::nodeRemovedChildren );
connect( root, &QgsLayerTreeNode::visibilityChanged, this, &QgsLayerTreeMapCanvasBridge::nodeVisibilityChanged );
connect( QgsProject::instance(), &QgsProject::layerOrderChanged, this, &QgsLayerTreeMapCanvasBridge::projectLayerOrderChanged );
connect( root, &QgsLayerTree::layerOrderChanged, this, &QgsLayerTreeMapCanvasBridge::deferredSetCanvasLayers );
setCanvasLayers();
}
void QgsLayerTreeMapCanvasBridge::clear()
{
setHasCustomLayerOrder( false );
setCustomLayerOrder( defaultLayerOrder() );
}
QStringList QgsLayerTreeMapCanvasBridge::defaultLayerOrder() const
{
QStringList order;
defaultLayerOrder( mRoot, order );
return order;
}
void QgsLayerTreeMapCanvasBridge::defaultLayerOrder( QgsLayerTreeNode *node, QStringList &order ) const
{
if ( QgsLayerTree::isLayer( node ) )
{
QgsLayerTreeLayer *nodeLayer = QgsLayerTree::toLayer( node );
order << nodeLayer->layerId();
}
Q_FOREACH ( QgsLayerTreeNode *child, node->children() )
defaultLayerOrder( child, order );
}
void QgsLayerTreeMapCanvasBridge::setHasCustomLayerOrder( bool state )
{
if ( mHasCustomLayerOrder == state )
return;
mHasCustomLayerOrder = state;
emit hasCustomLayerOrderChanged( mHasCustomLayerOrder );
deferredSetCanvasLayers();
}
void QgsLayerTreeMapCanvasBridge::setCustomLayerOrder( const QStringList &order )
{
if ( mCustomLayerOrder == order )
return;
// verify that the new order is correct
QStringList defOrder( defaultLayerOrder() );
QStringList newOrder( order );
QStringList sortedNewOrder( order );
std::sort( defOrder.begin(), defOrder.end() );
std::sort( sortedNewOrder.begin(), sortedNewOrder.end() );
if ( defOrder.size() < sortedNewOrder.size() )
{
// might contain bad layers, but also duplicates
QSet<QString> ids( defOrder.toSet() );
for ( int i = 0; i < sortedNewOrder.size(); i++ )
{
if ( !ids.contains( sortedNewOrder[i] ) )
{
newOrder.removeAll( sortedNewOrder[i] );
sortedNewOrder.removeAt( i-- );
}
}
}
if ( defOrder != sortedNewOrder )
return; // must be permutation of the default order
mCustomLayerOrder = newOrder;
emit customLayerOrderChanged( mCustomLayerOrder );
if ( mHasCustomLayerOrder )
deferredSetCanvasLayers();
}
void QgsLayerTreeMapCanvasBridge::setCanvasLayers()
{
QList<QgsMapLayer *> canvasLayers, overviewLayers, allLayerOrder;
if ( mHasCustomLayerOrder )
if ( mRoot->hasCustomLayerOrder() )
{
Q_FOREACH ( const QString &layerId, mCustomLayerOrder )
Q_FOREACH ( QgsMapLayer *layer, mRoot->customLayerOrder() )
{
QgsLayerTreeLayer *nodeLayer = mRoot->findLayer( layerId );
QgsLayerTreeLayer *nodeLayer = mRoot->findLayer( layer->id() );
if ( nodeLayer )
{
allLayerOrder << nodeLayer->layer();
@ -142,9 +65,6 @@ void QgsLayerTreeMapCanvasBridge::setCanvasLayers()
int currentLayerCount = layerNodes.count();
bool firstLayers = mAutoSetupOnFirstLayer && mLastLayerCount == 0 && currentLayerCount != 0;
mUpdatingProjectLayerOrder = true;
QgsProject::instance()->setLayerOrder( allLayerOrder );
mUpdatingProjectLayerOrder = false;
mCanvas->setLayers( canvasLayers );
if ( mOverviewCanvas )
mOverviewCanvas->setLayers( overviewLayers );
@ -182,39 +102,6 @@ void QgsLayerTreeMapCanvasBridge::setCanvasLayers()
emit canvasLayersChanged( canvasLayers );
}
void QgsLayerTreeMapCanvasBridge::readProject( const QDomDocument &doc )
{
mFirstCRS = QgsCoordinateReferenceSystem(); // invalidate on project load
QDomElement elem = doc.documentElement().firstChildElement( QStringLiteral( "layer-tree-canvas" ) );
if ( elem.isNull() )
{
bool oldEnabled;
QStringList oldOrder;
if ( QgsLayerTreeUtils::readOldLegendLayerOrder( doc.documentElement().firstChildElement( QStringLiteral( "legend" ) ), oldEnabled, oldOrder ) )
{
setHasCustomLayerOrder( oldEnabled );
// oldOrder is now unused!
}
return;
}
QDomElement customOrderElem = elem.firstChildElement( QStringLiteral( "custom-order" ) );
if ( !customOrderElem.isNull() )
{
setHasCustomLayerOrder( customOrderElem.attribute( QStringLiteral( "enabled" ), QString() ).toInt() );
}
}
void QgsLayerTreeMapCanvasBridge::writeProject( QDomDocument &doc )
{
QDomElement elem = doc.createElement( QStringLiteral( "layer-tree-canvas" ) );
QDomElement customOrderElem = doc.createElement( QStringLiteral( "custom-order" ) );
customOrderElem.setAttribute( QStringLiteral( "enabled" ), mHasCustomLayerOrder ? 1 : 0 );
elem.appendChild( customOrderElem );
doc.documentElement().appendChild( elem );
}
void QgsLayerTreeMapCanvasBridge::setCanvasLayers( QgsLayerTreeNode *node, QList<QgsMapLayer *> &canvasLayers, QList<QgsMapLayer *> &overviewLayers, QList<QgsMapLayer *> &allLayers )
{
if ( QgsLayerTree::isLayer( node ) )
@ -240,57 +127,6 @@ void QgsLayerTreeMapCanvasBridge::deferredSetCanvasLayers()
QMetaObject::invokeMethod( this, "setCanvasLayers", Qt::QueuedConnection );
}
void QgsLayerTreeMapCanvasBridge::nodeAddedChildren( QgsLayerTreeNode *node, int indexFrom, int indexTo )
{
Q_ASSERT( node );
// collect layer IDs that have been added in order to put them into custom layer order
QStringList layerIds;
QList<QgsLayerTreeNode *> children = node->children();
for ( int i = indexFrom; i <= indexTo; ++i )
{
QgsLayerTreeNode *child = children.at( i );
if ( QgsLayerTree::isLayer( child ) )
{
layerIds << QgsLayerTree::toLayer( child )->layerId();
}
else if ( QgsLayerTree::isGroup( child ) )
{
Q_FOREACH ( QgsLayerTreeLayer *nodeL, QgsLayerTree::toGroup( child )->findLayers() )
layerIds << nodeL->layerId();
}
}
Q_FOREACH ( const QString &layerId, layerIds )
{
if ( !mCustomLayerOrder.contains( layerId ) )
mCustomLayerOrder.append( layerId );
}
emit customLayerOrderChanged( mCustomLayerOrder );
deferredSetCanvasLayers();
}
void QgsLayerTreeMapCanvasBridge::nodeRemovedChildren()
{
// no need to disconnect from removed nodes as they are deleted
// check whether the layers are still there, if not, remove them from the layer order!
QList<int> toRemove;
for ( int i = 0; i < mCustomLayerOrder.count(); ++i )
{
QgsLayerTreeLayer *node = mRoot->findLayer( mCustomLayerOrder[i] );
if ( !node )
toRemove << i;
}
for ( int i = toRemove.count() - 1; i >= 0; --i )
mCustomLayerOrder.removeAt( toRemove[i] );
emit customLayerOrderChanged( mCustomLayerOrder );
deferredSetCanvasLayers();
}
void QgsLayerTreeMapCanvasBridge::nodeVisibilityChanged()
{
deferredSetCanvasLayers();
@ -302,19 +138,3 @@ void QgsLayerTreeMapCanvasBridge::nodeCustomPropertyChanged( QgsLayerTreeNode *n
if ( key == QLatin1String( "overview" ) )
deferredSetCanvasLayers();
}
void QgsLayerTreeMapCanvasBridge::projectLayerOrderChanged()
{
if ( mUpdatingProjectLayerOrder )
return;
setHasCustomLayerOrder( true );
QStringList ids;
Q_FOREACH ( QgsMapLayer *layer, QgsProject::instance()->layerOrder() )
{
if ( layer )
ids << layer->id();
}
setCustomLayerOrder( ids );
}

View File

@ -27,6 +27,7 @@ class QgsMapLayer;
class QgsMapOverviewCanvas;
class QgsLayerTreeGroup;
class QgsLayerTreeNode;
class QgsLayerTree;
/**
* \ingroup gui
@ -49,11 +50,9 @@ class GUI_EXPORT QgsLayerTreeMapCanvasBridge : public QObject
Q_OBJECT
public:
//! Constructor: does not take ownership of the layer tree nor canvas
QgsLayerTreeMapCanvasBridge( QgsLayerTreeGroup *root, QgsMapCanvas *canvas, QObject *parent = nullptr );
QgsLayerTreeMapCanvasBridge( QgsLayerTree *root, QgsMapCanvas *canvas, QObject *parent = nullptr );
void clear();
QgsLayerTreeGroup *rootGroup() const { return mRoot; }
QgsLayerTree *rootGroup() const { return mRoot; }
QgsMapCanvas *mapCanvas() const { return mCanvas; }
//! Associates overview canvas with the bridge, so the overview will be updated whenever main canvas is updated
@ -63,29 +62,15 @@ class GUI_EXPORT QgsLayerTreeMapCanvasBridge : public QObject
//! @note added in 3.0
QgsMapOverviewCanvas *overviewCanvas() const { return mOverviewCanvas; }
bool hasCustomLayerOrder() const { return mHasCustomLayerOrder; }
QStringList customLayerOrder() const { return mCustomLayerOrder; }
QStringList defaultLayerOrder() const;
//! if enabled, will automatically set full canvas extent and destination CRS + map units
//! when first layer(s) are added
void setAutoSetupOnFirstLayer( bool enabled ) { mAutoSetupOnFirstLayer = enabled; }
bool autoSetupOnFirstLayer() const { return mAutoSetupOnFirstLayer; }
public slots:
void setHasCustomLayerOrder( bool state );
void setCustomLayerOrder( const QStringList &order );
//! force update of canvas layers from the layer tree. Normally this should not be needed to be called.
void setCanvasLayers();
void readProject( const QDomDocument &doc );
void writeProject( QDomDocument &doc );
Q_INVOKABLE void setCanvasLayers();
signals:
void hasCustomLayerOrderChanged( bool );
void customLayerOrderChanged( const QStringList &order );
/**
* Emitted when the set of layers (or order of layers) visible in the
@ -94,36 +79,23 @@ class GUI_EXPORT QgsLayerTreeMapCanvasBridge : public QObject
*/
void canvasLayersChanged( const QList< QgsMapLayer * > &layers );
protected:
void defaultLayerOrder( QgsLayerTreeNode *node, QStringList &order ) const;
private slots:
void nodeVisibilityChanged();
void nodeCustomPropertyChanged( QgsLayerTreeNode *node, const QString &key );
private:
//! Fill canvasLayers and overviewLayers lists from node and its descendants
void setCanvasLayers( QgsLayerTreeNode *node, QList<QgsMapLayer *> &canvasLayers, QList<QgsMapLayer *> &overviewLayers,
QList<QgsMapLayer *> &allLayers );
void deferredSetCanvasLayers();
protected slots:
void nodeAddedChildren( QgsLayerTreeNode *node, int indexFrom, int indexTo );
void nodeRemovedChildren();
void nodeVisibilityChanged();
void nodeCustomPropertyChanged( QgsLayerTreeNode *node, const QString &key );
private slots:
void projectLayerOrderChanged();
protected:
QgsLayerTreeGroup *mRoot = nullptr;
QgsLayerTree *mRoot = nullptr;
QgsMapCanvas *mCanvas = nullptr;
QgsMapOverviewCanvas *mOverviewCanvas = nullptr;
bool mPendingCanvasUpdate;
bool mHasCustomLayerOrder;
QStringList mCustomLayerOrder;
bool mAutoSetupOnFirstLayer;
bool mHasFirstLayer;

View File

@ -31,7 +31,7 @@
#include <QMessageBox>
QgsSelectLayerTreeModel::QgsSelectLayerTreeModel( QgsLayerTreeGroup *rootNode, QObject *parent )
QgsSelectLayerTreeModel::QgsSelectLayerTreeModel( QgsLayerTree *rootNode, QObject *parent )
: QgsLayerTreeModel( rootNode, parent )
{
setFlag( QgsLayerTreeModel::ShowLegend, false );
@ -76,7 +76,7 @@ QgsOfflineEditingPluginGui::QgsOfflineEditingPluginGui( QWidget *parent, Qt::Win
mOfflineDbFile = QStringLiteral( "offline.sqlite" );
mOfflineDataPathLineEdit->setText( QDir( mOfflineDataPath ).absoluteFilePath( mOfflineDbFile ) );
QgsLayerTreeGroup *rootNode = QgsLayerTree::toGroup( QgsProject::instance()->layerTreeRoot()->clone() );
QgsLayerTree *rootNode = QgsProject::instance()->layerTreeRoot()->clone();
QgsLayerTreeModel *treeModel = new QgsSelectLayerTreeModel( rootNode, this );
mLayerTree->setModel( treeModel );

View File

@ -29,7 +29,7 @@ class QgsSelectLayerTreeModel : public QgsLayerTreeModel
{
Q_OBJECT
public:
QgsSelectLayerTreeModel( QgsLayerTreeGroup *rootNode, QObject *parent = nullptr );
QgsSelectLayerTreeModel( QgsLayerTree *rootNode, QObject *parent = nullptr );
~QgsSelectLayerTreeModel();
QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const override;

View File

@ -25,6 +25,7 @@ email : hugo dot mercier at oslandia dot com
#include <layertree/qgslayertreemodel.h>
#include <layertree/qgslayertreegroup.h>
#include <layertree/qgslayertreelayer.h>
#include <layertree/qgslayertree.h>
#include <qgsproviderregistry.h>
#include <qgsvectordataprovider.h>

View File

@ -26,6 +26,7 @@ email : hugo dot mercier at oslandia dot com
#include <layertree/qgslayertreemodel.h>
#include <layertree/qgslayertreegroup.h>
#include <layertree/qgslayertreelayer.h>
#include <layertree/qgslayertree.h>
#include <qgsproviderregistry.h>
#include "qgsembeddedlayerselectdialog.h"

View File

@ -33,6 +33,7 @@
#include "qgslayertreegroup.h"
#include "qgslayertreelayer.h"
#include "qgslayertree.h"
#include "qgsrenderer.h"
#include "qgsvectordataprovider.h"
@ -553,7 +554,7 @@ void QgsWmsConfigParser::setLayerIdsToLegendModel( QgsLegendModel *model, const
}
// get model and layer tree root of the legend
QgsLayerTreeGroup *root = model->rootGroup();
QgsLayerTree *root = model->rootGroup();
// get layerIds find in the layer tree root

View File

@ -41,6 +41,7 @@
#include "qgslayertreeutils.h"
#include "qgslayertreegroup.h"
#include "qgslayertreelayer.h"
#include "qgslayertree.h"
#include "qgsaccesscontrol.h"
#include <QFileInfo>
@ -493,7 +494,7 @@ QgsComposition *QgsWmsProjectParser::initComposition( const QString &composerTem
const QgsComposerMap *map = legend->composerMap();
if ( !map )
{
QgsLayerTreeGroup *root = model->rootGroup();
QgsLayerTree *root = model->rootGroup();
QStringList layerIds = root->findLayerIds();
// for each layer find in the layer tree
// load it if the layer id is not QgsProject
@ -2297,9 +2298,9 @@ QDomElement QgsWmsProjectParser::composerByName( const QString &composerName ) c
return composerElem;
}
QgsLayerTreeGroup *QgsWmsProjectParser::projectLayerTreeGroup() const
QgsLayerTree *QgsWmsProjectParser::projectLayerTreeGroup() const
{
QgsLayerTreeGroup *rootGroup = new QgsLayerTreeGroup;
QgsLayerTree *rootGroup = new QgsLayerTree;
const QDomDocument *projectDoc = mProjectParser->xmlDocument();
if ( !projectDoc )
{
@ -2317,7 +2318,7 @@ QgsLayerTreeGroup *QgsWmsProjectParser::projectLayerTreeGroup() const
QgsLayerTreeUtils::readOldLegend( rootGroup, mProjectParser->legendElem() );
return rootGroup;
}
return QgsLayerTreeGroup::readXml( layerTreeElem, QgsProject::instance() );
return QgsLayerTree::readXml( layerTreeElem );
}
bool QgsWmsProjectParser::annotationPosition( const QDomElement &elem, double scaleFactor, double &xPos, double &yPos )

View File

@ -20,7 +20,6 @@
#include "qgswmsconfigparser.h"
#include "qgsserverprojectparser.h"
#include "qgslayertreegroup.h"
#include "qgis_server.h"
class QgsAccessControl;
@ -28,6 +27,7 @@ class QgsAccessControl;
class QTextDocument;
class QSvgRenderer;
class QgsMapSettings;
class QgsLayerTree;
class SERVER_EXPORT QgsWmsProjectParser : public QgsWmsConfigParser
{
@ -165,7 +165,7 @@ class SERVER_EXPORT QgsWmsProjectParser : public QgsWmsConfigParser
void addLayersFromGroup( const QDomElement &legendGroupElem, QMap< int, QgsMapLayer *> &layers, bool useCache = true ) const;
QDomElement composerByName( const QString &composerName ) const;
QgsLayerTreeGroup *projectLayerTreeGroup() const;
QgsLayerTree *projectLayerTreeGroup() const;
static bool annotationPosition( const QDomElement &elem, double scaleFactor, double &xPos, double &yPos );
static void drawAnnotationRectangle( QPainter *p, const QDomElement &elem, double scaleFactor, double xPos, double yPos, int itemWidth, int itemHeight );

View File

@ -227,7 +227,7 @@ namespace QgsWms
showFeatureCount = QVariant( mParameters[ QStringLiteral( "SHOWFEATURECOUNT" )] ).toBool();
// Create the layer tree root
QgsLayerTreeGroup rootGroup;
QgsLayerTree rootGroup;
// Store layers' name to reset them
QMap<QString, QString> layerNameMap;
// Create tree layer node for each layer

View File

@ -300,7 +300,7 @@ void TestQgsLayerTree::testShowHideAllSymbolNodes()
vl->setRenderer( renderer );
//create legend with symbology nodes for categorized renderer
QgsLayerTreeGroup *root = new QgsLayerTreeGroup();
QgsLayerTree *root = new QgsLayerTree();
QgsLayerTreeLayer *n = new QgsLayerTreeLayer( vl );
root->addChildNode( n );
QgsLayerTreeModel *m = new QgsLayerTreeModel( root, 0 );
@ -350,7 +350,7 @@ void TestQgsLayerTree::testFindLegendNode()
vl->setRenderer( renderer );
//create legend with symbology nodes for categorized renderer
QgsLayerTreeGroup *root = new QgsLayerTreeGroup();
QgsLayerTree *root = new QgsLayerTree();
QgsLayerTreeModel *m = new QgsLayerTreeModel( root, 0 );
QVERIFY( !m->findLegendNode( QString( "id" ), QString( "rule" ) ) );
QgsLayerTreeLayer *n = new QgsLayerTreeLayer( vl );
@ -481,7 +481,7 @@ void TestQgsLayerTree::testRendererLegend( QgsFeatureRenderer *renderer )
vl->setRenderer( renderer );
//create legend with symbology nodes for renderer
QgsLayerTreeGroup *root = new QgsLayerTreeGroup();
QgsLayerTree *root = new QgsLayerTree();
QgsLayerTreeLayer *n = new QgsLayerTreeLayer( vl );
root->addChildNode( n );
QgsLayerTreeModel *m = new QgsLayerTreeModel( root, 0 );

View File

@ -128,7 +128,7 @@ class TestQgsLegendRenderer : public QObject
void testDiagramSizeLegend();
private:
QgsLayerTreeGroup *mRoot = nullptr;
QgsLayerTree *mRoot = nullptr;
QgsVectorLayer *mVL1; // line
QgsVectorLayer *mVL2; // polygon
QgsVectorLayer *mVL3; // point
@ -223,7 +223,7 @@ void TestQgsLegendRenderer::init()
QgsCategorizedSymbolRenderer *r3 = new QgsCategorizedSymbolRenderer( QStringLiteral( "test_attr" ), cats );
mVL3->setRenderer( r3 );
mRoot = new QgsLayerTreeGroup();
mRoot = new QgsLayerTree();
QgsLayerTreeGroup *grp1 = mRoot->addGroup( QStringLiteral( "Line + Polygon" ) );
grp1->addLayer( mVL1 );
grp1->addLayer( mVL2 );
@ -327,7 +327,7 @@ void TestQgsLegendRenderer::testMapUnits()
sym->setSizeUnit( QgsUnitTypes::RenderMillimeters );
catRenderer->updateCategorySymbol( 2, sym );
std::unique_ptr< QgsLayerTreeGroup > root( new QgsLayerTreeGroup() );
std::unique_ptr< QgsLayerTree > root( new QgsLayerTree() );
root->addLayer( mVL3 );
QgsLayerTreeModel legendModel( root.get() );
@ -481,7 +481,7 @@ void TestQgsLegendRenderer::testFilterByMapSameSymbol()
QString testName = QStringLiteral( "legend_filter_by_map_dupe" );
std::unique_ptr< QgsLayerTreeGroup > root( new QgsLayerTreeGroup() );
std::unique_ptr< QgsLayerTree > root( new QgsLayerTree() );
root->addLayer( vl4 );
QgsLayerTreeModel legendModel( root.get() );
@ -507,7 +507,7 @@ bool TestQgsLegendRenderer::_testLegendColumns( int itemCount, int columnCount,
QgsFillSymbol *sym = new QgsFillSymbol();
sym->setColor( Qt::cyan );
std::unique_ptr< QgsLayerTreeGroup > root( new QgsLayerTreeGroup() );
std::unique_ptr< QgsLayerTree > root( new QgsLayerTree() );
QList< QgsVectorLayer * > layers;
for ( int i = 1; i <= itemCount; ++i )
@ -565,7 +565,7 @@ void TestQgsLegendRenderer::testRasterStroke()
{
QString testName = QStringLiteral( "legend_raster_border" );
std::unique_ptr< QgsLayerTreeGroup > root( new QgsLayerTreeGroup() );
std::unique_ptr< QgsLayerTree > root( new QgsLayerTree() );
root->addLayer( mRL );
QgsLayerTreeModel legendModel( root.get() );
@ -673,7 +673,7 @@ void TestQgsLegendRenderer::testDiagramAttributeLegend()
dls.setShowAllDiagrams( true );
vl4->setDiagramLayerSettings( dls );
std::unique_ptr< QgsLayerTreeGroup > root( new QgsLayerTreeGroup() );
std::unique_ptr< QgsLayerTree > root( new QgsLayerTree() );
root->addLayer( vl4 );
QgsLayerTreeModel legendModel( root.get() );
@ -713,7 +713,7 @@ void TestQgsLegendRenderer::testDiagramSizeLegend()
dls.setShowAllDiagrams( true );
vl4->setDiagramLayerSettings( dls );
std::unique_ptr< QgsLayerTreeGroup > root( new QgsLayerTreeGroup() );
std::unique_ptr< QgsLayerTree > root( new QgsLayerTree() );
root->addLayer( vl4 );
QgsLayerTreeModel legendModel( root.get() );

View File

@ -27,6 +27,7 @@
#include <qgsvectorlayerjoinbuffer.h>
#include <qgslayerdefinition.h>
#include <qgsproject.h>
#include "qgslayertree.h"
/** @ingroup UnitTests
* This is a unit test for the vector layer join buffer