Skip to content
Permalink
Browse files

Layer tree model support replacement of layer tree + layer node handl…

…es removal of layer cleanly
  • Loading branch information
wonder-sk committed Aug 12, 2014
1 parent 0fc7fc7 commit e6c6aa2137841080fb305975d07c960eeb5a7642
@@ -67,7 +67,7 @@ class QgsSimpleLegendNode : QgsLayerTreeModelLegendNode
#include <qgslayertreemodellegendnode.h>
%End
public:
QgsSimpleLegendNode( QgsLayerTreeLayer* nodeLayer, const QString& label, const QIcon& icon = QIcon() );
QgsSimpleLegendNode( QgsLayerTreeLayer* nodeLayer, const QString& label, const QString& id, const QIcon& icon = QIcon() );

virtual QVariant data( int role ) const;
};
@@ -57,6 +57,8 @@ void QgsLayerTreeLayer::attachToLayer()
{
mLayer = l;
mLayerName = l->name();
// make sure we are notified if the layer is removed
connect( QgsMapLayerRegistry::instance(), SIGNAL( layersWillBeRemoved( QStringList ) ), this, SLOT( registryLayersWillBeRemoved( QStringList ) ) );
}
else
{
@@ -153,3 +155,17 @@ void QgsLayerTreeLayer::registryLayersAdded( QList<QgsMapLayer*> layers )
}
}
}

void QgsLayerTreeLayer::registryLayersWillBeRemoved( const QStringList& layerIds )
{
if ( layerIds.contains( mLayerId ) )
{
emit layerWillBeUnloaded();

// stop listening to removal signals and start hoping that the layer may be added again
disconnect( QgsMapLayerRegistry::instance(), SIGNAL( layersWillBeRemoved( QStringList ) ), this, SLOT( registryLayersWillBeRemoved( QStringList ) ) );
connect( QgsMapLayerRegistry::instance(), SIGNAL( layersAdded( QList<QgsMapLayer*> ) ), this, SLOT( registryLayersAdded( QList<QgsMapLayer*> ) ) );

mLayer = 0;
}
}
@@ -66,10 +66,14 @@ class CORE_EXPORT QgsLayerTreeLayer : public QgsLayerTreeNode

protected slots:
void registryLayersAdded( QList<QgsMapLayer*> layers );
void registryLayersWillBeRemoved( const QStringList& layerIds );

signals:
//! emitted when a previously unavailable layer got loaded
void layerLoaded();
//! emitted when a previously available layer got unloaded (from layer registry)
//! @note added in 2.6
void layerWillBeUnloaded();

protected:
void attachToLayer();
@@ -36,19 +36,9 @@ QgsLayerTreeModel::QgsLayerTreeModel( QgsLayerTreeGroup* rootNode, QObject *pare
, mFlags( ShowSymbology | AllowSymbologyChangeState )
, mAutoCollapseSymNodesCount( -1 )
{
Q_ASSERT( mRootNode );

connect( mRootNode, SIGNAL( willAddChildren( QgsLayerTreeNode*, int, int ) ), this, SLOT( nodeWillAddChildren( QgsLayerTreeNode*, int, int ) ) );
connect( mRootNode, SIGNAL( addedChildren( QgsLayerTreeNode*, int, int ) ), this, SLOT( nodeAddedChildren( QgsLayerTreeNode*, int, int ) ) );
connect( mRootNode, SIGNAL( willRemoveChildren( QgsLayerTreeNode*, int, int ) ), this, SLOT( nodeWillRemoveChildren( QgsLayerTreeNode*, int, int ) ) );
connect( mRootNode, SIGNAL( removedChildren( QgsLayerTreeNode*, int, int ) ), this, SLOT( nodeRemovedChildren() ) );
connect( mRootNode, SIGNAL( visibilityChanged( QgsLayerTreeNode*, Qt::CheckState ) ), this, SLOT( nodeVisibilityChanged( QgsLayerTreeNode* ) ) );

connect( mRootNode, SIGNAL( customPropertyChanged( QgsLayerTreeNode*, QString ) ), this, SLOT( nodeCustomPropertyChanged( QgsLayerTreeNode*, QString ) ) );
connectToRootNode();

mFontLayer.setBold( true );

connectToLayers( mRootNode );
}

QgsLayerTreeModel::~QgsLayerTreeModel()
@@ -461,6 +451,21 @@ QgsLayerTreeGroup*QgsLayerTreeModel::rootGroup()
return mRootNode;
}

void QgsLayerTreeModel::setRootGroup( QgsLayerTreeGroup* newRootGroup )
{
beginResetModel();

disconnectFromRootNode();

Q_ASSERT( mSymbologyNodes.isEmpty() );

mRootNode = newRootGroup;

connectToRootNode();

endResetModel();
}

void QgsLayerTreeModel::refreshLayerSymbology( QgsLayerTreeLayer* nodeLayer )
{
// update title
@@ -609,6 +614,18 @@ void QgsLayerTreeModel::nodeLayerLoaded()
connectToLayer( nodeLayer );
}

void QgsLayerTreeModel::nodeLayerWillBeUnloaded()
{
QgsLayerTreeLayer* nodeLayer = qobject_cast<QgsLayerTreeLayer*>( sender() );
if ( !nodeLayer )
return;

disconnectFromLayer( nodeLayer );

// wait for the layer to appear again
connect( nodeLayer, SIGNAL( layerLoaded() ), this, SLOT( nodeLayerLoaded() ) );
}

void QgsLayerTreeModel::layerLegendChanged()
{
if ( !testFlag( ShowSymbology ) )
@@ -685,6 +702,9 @@ void QgsLayerTreeModel::connectToLayer( QgsLayerTreeLayer* nodeLayer )
return;
}

// watch if the layer is getting removed
connect( nodeLayer, SIGNAL( layerWillBeUnloaded() ), this, SLOT( nodeLayerWillBeUnloaded() ) );

if ( testFlag( ShowSymbology ) )
{
addSymbologyToLayer( nodeLayer );
@@ -733,6 +753,8 @@ static int _numLayerCount( QgsLayerTreeGroup* group, const QString& layerId )

void QgsLayerTreeModel::disconnectFromLayer( QgsLayerTreeLayer* nodeLayer )
{
disconnect( nodeLayer, 0, this, 0 ); // disconnect from delayed load of layer

if ( !nodeLayer->layer() )
return; // we were never connected

@@ -759,6 +781,39 @@ void QgsLayerTreeModel::connectToLayers( QgsLayerTreeGroup* parentGroup )
}
}

void QgsLayerTreeModel::disconnectFromLayers( QgsLayerTreeGroup* parentGroup )
{
foreach ( QgsLayerTreeNode* node, parentGroup->children() )
{
if ( QgsLayerTree::isGroup( node ) )
disconnectFromLayers( QgsLayerTree::toGroup( node ) );
else if ( QgsLayerTree::isLayer( node ) )
disconnectFromLayer( QgsLayerTree::toLayer( node ) );
}
}

void QgsLayerTreeModel::connectToRootNode()
{
Q_ASSERT( mRootNode );

connect( mRootNode, SIGNAL( willAddChildren( QgsLayerTreeNode*, int, int ) ), this, SLOT( nodeWillAddChildren( QgsLayerTreeNode*, int, int ) ) );
connect( mRootNode, SIGNAL( addedChildren( QgsLayerTreeNode*, int, int ) ), this, SLOT( nodeAddedChildren( QgsLayerTreeNode*, int, int ) ) );
connect( mRootNode, SIGNAL( willRemoveChildren( QgsLayerTreeNode*, int, int ) ), this, SLOT( nodeWillRemoveChildren( QgsLayerTreeNode*, int, int ) ) );
connect( mRootNode, SIGNAL( removedChildren( QgsLayerTreeNode*, int, int ) ), this, SLOT( nodeRemovedChildren() ) );
connect( mRootNode, SIGNAL( visibilityChanged( QgsLayerTreeNode*, Qt::CheckState ) ), this, SLOT( nodeVisibilityChanged( QgsLayerTreeNode* ) ) );

connect( mRootNode, SIGNAL( customPropertyChanged( QgsLayerTreeNode*, QString ) ), this, SLOT( nodeCustomPropertyChanged( QgsLayerTreeNode*, QString ) ) );

connectToLayers( mRootNode );
}

void QgsLayerTreeModel::disconnectFromRootNode()
{
disconnect( mRootNode, 0, this, 0 );

disconnectFromLayers( mRootNode );
}

void QgsLayerTreeModel::recursivelyEmitDataChanged( const QModelIndex& idx )
{
QgsLayerTreeNode* node = index2node( idx );
@@ -110,6 +110,9 @@ class CORE_EXPORT QgsLayerTreeModel : public QAbstractItemModel

//! Return pointer to the root node of the layer tree. Always a non-null pointer.
QgsLayerTreeGroup* rootGroup();
//! Reset the model and use a new root group node
//! @note added in 2.6
void setRootGroup( QgsLayerTreeGroup* newRootGroup );

//! Force a refresh of symbology of layer node.
//! Not necessary to call when layer's renderer is changed as the model listens to these events.
@@ -143,6 +146,7 @@ class CORE_EXPORT QgsLayerTreeModel : public QAbstractItemModel
void nodeCustomPropertyChanged( QgsLayerTreeNode* node, const QString& key );

void nodeLayerLoaded();
void nodeLayerWillBeUnloaded();
void layerLegendChanged();

void layerNeedsUpdate();
@@ -154,7 +158,10 @@ class CORE_EXPORT QgsLayerTreeModel : public QAbstractItemModel
void connectToLayer( QgsLayerTreeLayer* nodeLayer );
void disconnectFromLayer( QgsLayerTreeLayer* nodeLayer );

void connectToLayers(QgsLayerTreeGroup* parentGroup );
void connectToLayers( QgsLayerTreeGroup* parentGroup );
void disconnectFromLayers( QgsLayerTreeGroup* parentGroup );
void connectToRootNode();
void disconnectFromRootNode();

//! emit dataChanged() for layer tree node items
void recursivelyEmitDataChanged( const QModelIndex& index = QModelIndex() );
@@ -61,6 +61,8 @@ void QgsLayerTreeView::setModel( QAbstractItemModel* model )

connect( selectionModel(), SIGNAL( currentChanged( QModelIndex, QModelIndex ) ), this, SLOT( onCurrentChanged() ) );

connect( layerTreeModel(), SIGNAL( modelReset() ), this, SLOT( onModelReset() ) );

updateExpandedStateFromNode( layerTreeModel()->rootGroup() );
}

@@ -172,6 +174,11 @@ void QgsLayerTreeView::onExpandedChanged( QgsLayerTreeNode* node, bool expanded
setExpanded( idx, expanded );
}

void QgsLayerTreeView::onModelReset()
{
updateExpandedStateFromNode( layerTreeModel()->rootGroup() );
}

void QgsLayerTreeView::updateExpandedStateFromNode( QgsLayerTreeNode* node )
{
QModelIndex idx = layerTreeModel()->node2index( node );
@@ -105,6 +105,7 @@ class GUI_EXPORT QgsLayerTreeView : public QTreeView

void onCurrentChanged();
void onExpandedChanged( QgsLayerTreeNode* node, bool expanded );
void onModelReset();

protected:
//! helper class with default actions. Lazily initialized.

0 comments on commit e6c6aa2

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