QGIS API Documentation  2.8.2-Wien
 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  QList<QgsLayerTreeNode*> nodes;
53  foreach ( QgsMapLayer* layer, layers )
54  {
55  QgsLayerTreeLayer* nodeLayer = new QgsLayerTreeLayer( layer );
56  nodeLayer->setVisible( mNewLayersVisible ? Qt::Checked : Qt::Unchecked );
57 
58  nodes << nodeLayer;
59 
60  // check whether the layer is marked as embedded
61  QString projectFile = QgsProject::instance()->layerIsEmbedded( nodeLayer->layerId() );
62  if ( !projectFile.isEmpty() )
63  {
64  nodeLayer->setCustomProperty( "embedded", 1 );
65  nodeLayer->setCustomProperty( "embedded_project", projectFile );
66  }
67  }
68 
69  // add new layers to the right place
71 
72  // tell other components that layers have been added - this signal is used in QGIS to auto-select the first layer
73  emit addedLayersToLayerTree( layers );
74 }
75 
77 {
78  QgsDebugMsg( QString( "%1 layers will be removed, enabled:%2" ).arg( layerIds.count() ).arg( mEnabled ) );
79 
80  if ( !mEnabled )
81  return;
82 
83  // when we start removing child nodes, the bridge would try to remove those layers from
84  // the registry _again_ in groupRemovedChildren() - this prevents it
86 
87  foreach ( QString layerId, layerIds )
88  {
89  QgsLayerTreeLayer* nodeLayer = mRoot->findLayer( layerId );
90  if ( nodeLayer )
91  qobject_cast<QgsLayerTreeGroup*>( nodeLayer->parent() )->removeChildNode( nodeLayer );
92  }
93 
95 }
96 
97 
98 static void _collectLayerIdsInGroup( QgsLayerTreeGroup* group, int indexFrom, int indexTo, QStringList& lst )
99 {
100  for ( int i = indexFrom; i <= indexTo; ++i )
101  {
102  QgsLayerTreeNode* child = group->children()[i];
103  if ( QgsLayerTree::isLayer( child ) )
104  {
105  lst << QgsLayerTree::toLayer( child )->layerId();
106  }
107  else if ( QgsLayerTree::isGroup( child ) )
108  {
109  _collectLayerIdsInGroup( QgsLayerTree::toGroup( child ), 0, child->children().count() - 1, lst );
110  }
111  }
112 }
113 
115 {
117  return; // do not try to remove those layers again
118 
119  Q_ASSERT( mLayerIdsForRemoval.isEmpty() );
120 
121  Q_ASSERT( QgsLayerTree::isGroup( node ) );
122  QgsLayerTreeGroup* group = QgsLayerTree::toGroup( node );
123 
124  _collectLayerIdsInGroup( group, indexFrom, indexTo, mLayerIdsForRemoval );
125 }
126 
128 {
130  return; // do not try to remove those layers again
131 
132  // remove only those that really do not exist in the tree
133  // (ignores layers that were dragged'n'dropped: 1. drop new 2. remove old)
134  QStringList toRemove;
135  foreach ( QString layerId, mLayerIdsForRemoval )
136  if ( !mRoot->findLayer( layerId ) )
137  toRemove << layerId;
138  mLayerIdsForRemoval.clear();
139 
140  QgsDebugMsg( QString( "%1 layers will be removed" ).arg( toRemove.count() ) );
141 
142  // delay the removal of layers from the registry. There may be other slots connected to map layer registry's signals
143  // that might disrupt the execution flow - e.g. a processEvents() call may force update of layer tree view with
144  // semi-broken tree model
145  QMetaObject::invokeMethod( this, "removeLayersFromRegistry", Qt::QueuedConnection, Q_ARG( QStringList, toRemove ) );
146 }
147 
149 {
151 }