LCOV - code coverage report
Current view: top level - core/layertree - qgslayertreeregistrybridge.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 52 83 62.7 %
Date: 2021-03-26 12:19:53 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       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                 :            : 
      16                 :            : #include "qgslayertreeregistrybridge.h"
      17                 :            : 
      18                 :            : #include "qgslayertree.h"
      19                 :            : 
      20                 :            : #include "qgsproject.h"
      21                 :            : #include "qgslogger.h"
      22                 :            : 
      23                 :          5 : QgsLayerTreeRegistryBridge::QgsLayerTreeRegistryBridge( QgsLayerTreeGroup *root, QgsProject *project, QObject *parent )
      24                 :          5 :   : QObject( parent )
      25                 :          5 :   , mRoot( root )
      26                 :          5 :   , mProject( project )
      27                 :          5 :   , mRegistryRemovingLayers( false )
      28                 :          5 :   , mEnabled( true )
      29                 :          5 :   , mNewLayersVisible( true )
      30                 :          5 :   , mInsertionPoint( root, 0 )
      31                 :         10 : {
      32                 :          5 :   connect( mProject, &QgsProject::legendLayersAdded, this, &QgsLayerTreeRegistryBridge::layersAdded );
      33                 :          5 :   connect( mProject, qOverload<const QStringList &>( &QgsProject::layersWillBeRemoved ), this, &QgsLayerTreeRegistryBridge::layersWillBeRemoved );
      34                 :            : 
      35                 :          5 :   connect( mRoot, &QgsLayerTreeNode::willRemoveChildren, this, &QgsLayerTreeRegistryBridge::groupWillRemoveChildren );
      36                 :          5 :   connect( mRoot, &QgsLayerTreeNode::removedChildren, this, &QgsLayerTreeRegistryBridge::groupRemovedChildren );
      37                 :          5 : }
      38                 :            : 
      39                 :          0 : void QgsLayerTreeRegistryBridge::setLayerInsertionPoint( QgsLayerTreeGroup *parentGroup, int index )
      40                 :            : {
      41                 :          0 :   mInsertionPoint.group = parentGroup;
      42                 :          0 :   mInsertionPoint.position = index;
      43                 :          0 : }
      44                 :            : 
      45                 :          0 : void QgsLayerTreeRegistryBridge::setLayerInsertionPoint( const InsertionPoint &insertionPoint )
      46                 :            : {
      47                 :          0 :   mInsertionPoint = insertionPoint;
      48                 :          0 : }
      49                 :            : 
      50                 :          1 : void QgsLayerTreeRegistryBridge::layersAdded( const QList<QgsMapLayer *> &layers )
      51                 :            : {
      52                 :          1 :   if ( !mEnabled )
      53                 :          0 :     return;
      54                 :            : 
      55                 :          1 :   QList<QgsLayerTreeNode *> nodes;
      56                 :          1 :   const auto constLayers = layers;
      57                 :          2 :   for ( QgsMapLayer *layer : constLayers )
      58                 :            :   {
      59                 :          1 :     QgsLayerTreeLayer *nodeLayer = new QgsLayerTreeLayer( layer );
      60                 :          1 :     nodeLayer->setItemVisibilityChecked( mNewLayersVisible );
      61                 :            : 
      62                 :          1 :     nodes << nodeLayer;
      63                 :            : 
      64                 :            :     // check whether the layer is marked as embedded
      65                 :          1 :     QString projectFile = mProject->layerIsEmbedded( nodeLayer->layerId() );
      66                 :          1 :     if ( !projectFile.isEmpty() )
      67                 :            :     {
      68                 :          0 :       nodeLayer->setCustomProperty( QStringLiteral( "embedded" ), 1 );
      69                 :          0 :       nodeLayer->setCustomProperty( QStringLiteral( "embedded_project" ), projectFile );
      70                 :          0 :     }
      71                 :          1 :   }
      72                 :            : 
      73                 :            :   // add new layers to the right place
      74                 :          1 :   mInsertionPoint.group->insertChildNodes( mInsertionPoint.position, nodes );
      75                 :            : 
      76                 :            :   // tell other components that layers have been added - this signal is used in QGIS to auto-select the first layer
      77                 :          1 :   emit addedLayersToLayerTree( layers );
      78                 :          1 : }
      79                 :            : 
      80                 :          0 : void QgsLayerTreeRegistryBridge::layersWillBeRemoved( const QStringList &layerIds )
      81                 :            : {
      82                 :          0 :   QgsDebugMsgLevel( QStringLiteral( "%1 layers will be removed, enabled:%2" ).arg( layerIds.count() ).arg( mEnabled ), 4 );
      83                 :            : 
      84                 :          0 :   if ( !mEnabled )
      85                 :          0 :     return;
      86                 :            : 
      87                 :            :   // when we start removing child nodes, the bridge would try to remove those layers from
      88                 :            :   // the registry _again_ in groupRemovedChildren() - this prevents it
      89                 :          0 :   mRegistryRemovingLayers = true;
      90                 :            : 
      91                 :          0 :   const auto constLayerIds = layerIds;
      92                 :          0 :   for ( const QString &layerId : constLayerIds )
      93                 :            :   {
      94                 :          0 :     QgsLayerTreeLayer *nodeLayer = mRoot->findLayer( layerId );
      95                 :          0 :     if ( nodeLayer )
      96                 :          0 :       qobject_cast<QgsLayerTreeGroup *>( nodeLayer->parent() )->removeChildNode( nodeLayer );
      97                 :            :   }
      98                 :            : 
      99                 :          0 :   mRegistryRemovingLayers = false;
     100                 :          0 : }
     101                 :            : 
     102                 :            : 
     103                 :          1 : static void _collectLayerIdsInGroup( QgsLayerTreeGroup *group, int indexFrom, int indexTo, QStringList &lst )
     104                 :            : {
     105                 :          2 :   for ( int i = indexFrom; i <= indexTo; ++i )
     106                 :            :   {
     107                 :          1 :     QgsLayerTreeNode *child = group->children().at( i );
     108                 :          1 :     if ( QgsLayerTree::isLayer( child ) )
     109                 :            :     {
     110                 :          1 :       lst << QgsLayerTree::toLayer( child )->layerId();
     111                 :          1 :     }
     112                 :          0 :     else if ( QgsLayerTree::isGroup( child ) )
     113                 :            :     {
     114                 :          0 :       _collectLayerIdsInGroup( QgsLayerTree::toGroup( child ), 0, child->children().count() - 1, lst );
     115                 :          0 :     }
     116                 :          1 :   }
     117                 :          1 : }
     118                 :            : 
     119                 :          1 : void QgsLayerTreeRegistryBridge::groupWillRemoveChildren( QgsLayerTreeNode *node, int indexFrom, int indexTo )
     120                 :            : {
     121                 :          1 :   if ( mRegistryRemovingLayers )
     122                 :          0 :     return; // do not try to remove those layers again
     123                 :            : 
     124                 :            :   Q_ASSERT( mLayerIdsForRemoval.isEmpty() );
     125                 :            : 
     126                 :            :   Q_ASSERT( QgsLayerTree::isGroup( node ) );
     127                 :          1 :   QgsLayerTreeGroup *group = QgsLayerTree::toGroup( node );
     128                 :            : 
     129                 :          1 :   _collectLayerIdsInGroup( group, indexFrom, indexTo, mLayerIdsForRemoval );
     130                 :          1 : }
     131                 :            : 
     132                 :          1 : void QgsLayerTreeRegistryBridge::groupRemovedChildren()
     133                 :            : {
     134                 :          1 :   if ( mRegistryRemovingLayers )
     135                 :          0 :     return; // do not try to remove those layers again
     136                 :            : 
     137                 :            :   // remove only those that really do not exist in the tree
     138                 :            :   // (ignores layers that were dragged'n'dropped: 1. drop new 2. remove old)
     139                 :          1 :   QStringList toRemove;
     140                 :          1 :   const auto constMLayerIdsForRemoval = mLayerIdsForRemoval;
     141                 :          2 :   for ( const QString &layerId : constMLayerIdsForRemoval )
     142                 :          1 :     if ( !mRoot->findLayer( layerId ) )
     143                 :          1 :       toRemove << layerId;
     144                 :          1 :   mLayerIdsForRemoval.clear();
     145                 :            : 
     146                 :          1 :   QgsDebugMsgLevel( QStringLiteral( "%1 layers will be removed" ).arg( toRemove.count() ), 4 );
     147                 :            : 
     148                 :            :   // delay the removal of layers from the registry. There may be other slots connected to map layer registry's signals
     149                 :            :   // that might disrupt the execution flow - e.g. a processEvents() call may force update of layer tree view with
     150                 :            :   // semi-broken tree model
     151                 :          1 :   QMetaObject::invokeMethod( this, "removeLayersFromRegistry", Qt::QueuedConnection, Q_ARG( QStringList, toRemove ) );
     152                 :          1 : }
     153                 :            : 
     154                 :          0 : void QgsLayerTreeRegistryBridge::removeLayersFromRegistry( const QStringList &layerIds )
     155                 :            : {
     156                 :          0 :   mProject->removeMapLayers( layerIds );
     157                 :          0 : }

Generated by: LCOV version 1.14