QGIS API Documentation  2.5.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgslayertreeregistrybridge.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayertreeregistrybridge.cpp
3  --------------------------------------
4  Date : May 2014
5  Copyright : (C) 2014 by Martin Dobias
6  Email : wonder dot sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 
18 #include "qgsmaplayerregistry.h"
19 
20 #include "qgslayertree.h"
21 
22 #include "qgsproject.h"
23 #include "qgslogger.h"
24 
26  : QObject( parent )
27  , mRoot( root )
28  , mRegistryRemovingLayers( false )
29  , mEnabled( true )
30  , mNewLayersVisible( true )
31  , mInsertionPointGroup( root )
32  , mInsertionPointIndex( 0 )
33 {
34  connect( QgsMapLayerRegistry::instance(), SIGNAL( legendLayersAdded( QList<QgsMapLayer*> ) ), this, SLOT( layersAdded( QList<QgsMapLayer*> ) ) );
35  connect( QgsMapLayerRegistry::instance(), SIGNAL( layersWillBeRemoved( QStringList ) ), this, SLOT( layersWillBeRemoved( QStringList ) ) );
36 
37  connect( mRoot, SIGNAL( willRemoveChildren( QgsLayerTreeNode*, int, int ) ), this, SLOT( groupWillRemoveChildren( QgsLayerTreeNode*, int, int ) ) );
38  connect( mRoot, SIGNAL( removedChildren( QgsLayerTreeNode*, int, int ) ), this, SLOT( groupRemovedChildren() ) );
39 }
40 
42 {
43  mInsertionPointGroup = parentGroup;
45 }
46 
47 void QgsLayerTreeRegistryBridge::layersAdded( QList<QgsMapLayer*> layers )
48 {
49  if ( !mEnabled )
50  return;
51 
52  int i = 0;
53  foreach ( QgsMapLayer* layer, layers )
54  {
55  QgsLayerTreeLayer* nodeLayer = new QgsLayerTreeLayer( layer );
56  nodeLayer->setVisible( mNewLayersVisible ? Qt::Checked : Qt::Unchecked );
57 
58  // add new layer to the top
60 
61  // check whether the layer is marked as embedded
62  QString projectFile = QgsProject::instance()->layerIsEmbedded( nodeLayer->layerId() );
63  if ( !projectFile.isEmpty() )
64  {
65  nodeLayer->setCustomProperty( "embedded", 1 );
66  nodeLayer->setCustomProperty( "embedded_project", projectFile );
67  }
68  }
69 }
70 
72 {
73  QgsDebugMsg( QString( "%1 layers will be removed, enabled:%2" ).arg( layerIds.count() ).arg( mEnabled ) );
74 
75  if ( !mEnabled )
76  return;
77 
78  // when we start removing child nodes, the bridge would try to remove those layers from
79  // the registry _again_ in groupRemovedChildren() - this prevents it
81 
82  foreach ( QString layerId, layerIds )
83  {
84  QgsLayerTreeLayer* nodeLayer = mRoot->findLayer( layerId );
85  if ( nodeLayer )
86  qobject_cast<QgsLayerTreeGroup*>( nodeLayer->parent() )->removeChildNode( nodeLayer );
87  }
88 
90 }
91 
92 
93 static void _collectLayerIdsInGroup( QgsLayerTreeGroup* group, int indexFrom, int indexTo, QStringList& lst )
94 {
95  for ( int i = indexFrom; i <= indexTo; ++i )
96  {
97  QgsLayerTreeNode* child = group->children()[i];
98  if ( QgsLayerTree::isLayer( child ) )
99  {
100  lst << QgsLayerTree::toLayer( child )->layerId();
101  }
102  else if ( QgsLayerTree::isGroup( child ) )
103  {
104  _collectLayerIdsInGroup( QgsLayerTree::toGroup( child ), 0, child->children().count() - 1, lst );
105  }
106  }
107 }
108 
110 {
112  return; // do not try to remove those layers again
113 
114  Q_ASSERT( mLayerIdsForRemoval.isEmpty() );
115 
116  Q_ASSERT( QgsLayerTree::isGroup( node ) );
117  QgsLayerTreeGroup* group = QgsLayerTree::toGroup( node );
118 
119  _collectLayerIdsInGroup( group, indexFrom, indexTo, mLayerIdsForRemoval );
120 }
121 
123 {
125  return; // do not try to remove those layers again
126 
127  // remove only those that really do not exist in the tree
128  // (ignores layers that were dragged'n'dropped: 1. drop new 2. remove old)
129  QStringList toRemove;
130  foreach ( QString layerId, mLayerIdsForRemoval )
131  if ( !mRoot->findLayer( layerId ) )
132  toRemove << layerId;
133  mLayerIdsForRemoval.clear();
134 
135  QgsDebugMsg( QString( "%1 layers will be removed" ).arg( toRemove.count() ) );
136 
137  // delay the removal of layers from the registry. There may be other slots connected to map layer registry's signals
138  // that might disrupt the execution flow - e.g. a processEvents() call may force update of layer tree view with
139  // semi-broken tree model
140  QMetaObject::invokeMethod( this, "removeLayersFromRegistry", Qt::QueuedConnection, Q_ARG( QStringList, toRemove ) );
141 }
142 
144 {
146 }
Layer tree group node serves as a container for layers and further groups.
static unsigned index
Base class for all map layer types.
Definition: qgsmaplayer.h:48
#define QgsDebugMsg(str)
Definition: qgslogger.h:36
QgsLayerTreeLayer * findLayer(const QString &layerId)
Find layer node representing the map layer specified by its ID. Searches recursively the whole sub-tr...
void layersAdded(QList< QgsMapLayer * > layers)
QString layerIsEmbedded(const QString &id) const
Returns project file path if layer is embedded from other project file.
void groupWillRemoveChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
QgsLayerTreeGroup * toGroup(QgsLayerTreeNode *node)
Cast node to a group. No type checking is done - use isGroup() to find out whether this operation is ...
Definition: qgslayertree.h:46
void removeLayersFromRegistry(QStringList layerIds)
static void _collectLayerIdsInGroup(QgsLayerTreeGroup *group, int indexFrom, int indexTo, QStringList &lst)
QgsLayerTreeNode * parent()
Get pointer to the parent. If parent is a null pointer, the node is a root node.
This class is a base class for nodes in a layer tree.
QString layerId() const
void setVisible(Qt::CheckState visible)
QList< QgsLayerTreeNode * > children()
Get list of children of the node. Children are owned by the parent.
bool isLayer(QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
Definition: qgslayertree.h:40
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
void insertChildNode(int index, QgsLayerTreeNode *node)
Insert existing node at specified position. The node must not have a parent yet. The node will be own...
QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer. No type checking is done - use isLayer() to find out whether this operation is ...
Definition: qgslayertree.h:52
void removeMapLayers(QStringList theLayerIds)
Remove a set of layers from the registry.
static QgsProject * instance()
access to canonical QgsProject instance
Definition: qgsproject.cpp:362
void setLayerInsertionPoint(QgsLayerTreeGroup *parentGroup, int index)
Set where the new layers should be inserted - can be used to follow current selection.
void layersWillBeRemoved(QStringList layerIds)
QgsLayerTreeRegistryBridge(QgsLayerTreeGroup *root, QObject *parent=0)
bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
Definition: qgslayertree.h:34
void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for the node.
Layer tree node points to a map layer.