Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsmaplayerstore.cpp 3 : : -------------------- 4 : : begin : May 2017 5 : : copyright : (C) 2017 by Nyall Dawson 6 : : email : nyall dot dawson at gmail dot com 7 : : ***************************************************************************/ 8 : : 9 : : /*************************************************************************** 10 : : * * 11 : : * This program is free software; you can redistribute it and/or modify * 12 : : * it under the terms of the GNU General Public License as published by * 13 : : * the Free Software Foundation; either version 2 of the License, or * 14 : : * (at your option) any later version. * 15 : : * * 16 : : ***************************************************************************/ 17 : : 18 : : #include "qgsmaplayerstore.h" 19 : : #include "qgsmaplayer.h" 20 : : #include "qgslogger.h" 21 : : #include <QList> 22 : : 23 : 5 : QgsMapLayerStore::QgsMapLayerStore( QObject *parent ) 24 : 5 : : QObject( parent ) 25 : 15 : {} 26 : : 27 : 6 : QgsMapLayerStore::~QgsMapLayerStore() 28 : 6 : { 29 : 3 : removeAllMapLayers(); 30 : 6 : } 31 : : 32 : 8 : int QgsMapLayerStore::count() const 33 : : { 34 : 8 : return mMapLayers.size(); 35 : : } 36 : : 37 : 0 : int QgsMapLayerStore::validCount() const 38 : : { 39 : 0 : int i = 0; 40 : 0 : const QList<QgsMapLayer *> cLayers = mMapLayers.values(); 41 : 0 : for ( const auto l : cLayers ) 42 : : { 43 : 0 : if ( l->isValid() ) 44 : 0 : i++; 45 : : } 46 : 0 : return i; 47 : 0 : } 48 : : 49 : 3 : QgsMapLayer *QgsMapLayerStore::mapLayer( const QString &layerId ) const 50 : : { 51 : 3 : return mMapLayers.value( layerId ); 52 : : } 53 : : 54 : 0 : QList<QgsMapLayer *> QgsMapLayerStore::mapLayersByName( const QString &layerName ) const 55 : : { 56 : 0 : QList<QgsMapLayer *> myResultList; 57 : 0 : const auto constMMapLayers = mMapLayers; 58 : 0 : for ( QgsMapLayer *layer : constMMapLayers ) 59 : : { 60 : 0 : if ( layer->name() == layerName ) 61 : : { 62 : 0 : myResultList << layer; 63 : 0 : } 64 : : } 65 : 0 : return myResultList; 66 : 0 : } 67 : : 68 : 1 : QList<QgsMapLayer *> QgsMapLayerStore::addMapLayers( const QList<QgsMapLayer *> &layers, bool takeOwnership ) 69 : : { 70 : 1 : QList<QgsMapLayer *> myResultList; 71 : 1 : const auto constLayers = layers; 72 : 2 : for ( QgsMapLayer *myLayer : constLayers ) 73 : : { 74 : 1 : if ( !myLayer ) 75 : : { 76 : 0 : QgsDebugMsg( QStringLiteral( "Cannot add null layers" ) ); 77 : 0 : continue; 78 : : } 79 : : // If the layer is already in the store but its validity has flipped to TRUE reset data source 80 : 1 : if ( mMapLayers.contains( myLayer->id() ) && ! mMapLayers[myLayer->id()]->isValid() && myLayer->isValid() && myLayer->dataProvider() ) 81 : : { 82 : 0 : mMapLayers[myLayer->id()]->setDataSource( myLayer->dataProvider()->dataSourceUri(), myLayer->name(), myLayer->providerType(), QgsDataProvider::ProviderOptions() ); 83 : 0 : } 84 : : //check the layer is not already registered! 85 : 1 : if ( !mMapLayers.contains( myLayer->id() ) ) 86 : : { 87 : 1 : mMapLayers[myLayer->id()] = myLayer; 88 : 1 : myResultList << mMapLayers[myLayer->id()]; 89 : 1 : if ( takeOwnership ) 90 : : { 91 : 0 : myLayer->setParent( this ); 92 : 0 : } 93 : 1 : connect( myLayer, &QObject::destroyed, this, &QgsMapLayerStore::onMapLayerDeleted ); 94 : 1 : emit layerWasAdded( myLayer ); 95 : 1 : } 96 : : } 97 : 1 : if ( !myResultList.isEmpty() ) 98 : : { 99 : 1 : emit layersAdded( myResultList ); 100 : 1 : } 101 : 1 : return myResultList; 102 : 1 : } 103 : : 104 : : QgsMapLayer * 105 : 0 : QgsMapLayerStore::addMapLayer( QgsMapLayer *layer, bool takeOwnership ) 106 : : { 107 : 0 : QList<QgsMapLayer *> addedLayers; 108 : 0 : addedLayers = addMapLayers( QList<QgsMapLayer *>() << layer, takeOwnership ); 109 : 0 : return addedLayers.isEmpty() ? nullptr : addedLayers[0]; 110 : 0 : } 111 : : 112 : 3 : void QgsMapLayerStore::removeMapLayers( const QStringList &layerIds ) 113 : : { 114 : 3 : QList<QgsMapLayer *> layers; 115 : 3 : const auto constLayerIds = layerIds; 116 : 3 : for ( const QString &myId : constLayerIds ) 117 : : { 118 : 0 : layers << mMapLayers.value( myId ); 119 : : } 120 : : 121 : 3 : removeMapLayers( layers ); 122 : 3 : } 123 : : 124 : 3 : void QgsMapLayerStore::removeMapLayers( const QList<QgsMapLayer *> &layers ) 125 : : { 126 : 3 : if ( layers.isEmpty() ) 127 : 3 : return; 128 : : 129 : 0 : QStringList layerIds; 130 : 0 : QList<QgsMapLayer *> layerList; 131 : : 132 : 0 : const auto constLayers = layers; 133 : 0 : for ( QgsMapLayer *layer : constLayers ) 134 : : { 135 : : // check layer and the store contains it 136 : 0 : if ( layer && mMapLayers.contains( layer->id() ) ) 137 : : { 138 : 0 : layerIds << layer->id(); 139 : 0 : layerList << layer; 140 : 0 : } 141 : : } 142 : : 143 : 0 : if ( layerIds.isEmpty() ) 144 : 0 : return; 145 : : 146 : 0 : emit layersWillBeRemoved( layerIds ); 147 : 0 : emit layersWillBeRemoved( layerList ); 148 : : 149 : 0 : const auto constLayerList = layerList; 150 : 0 : for ( QgsMapLayer *lyr : constLayerList ) 151 : : { 152 : 0 : QString myId( lyr->id() ); 153 : 0 : emit layerWillBeRemoved( myId ); 154 : 0 : emit layerWillBeRemoved( lyr ); 155 : 0 : mMapLayers.remove( myId ); 156 : 0 : if ( lyr->parent() == this ) 157 : : { 158 : 0 : delete lyr; 159 : 0 : } 160 : 0 : emit layerRemoved( myId ); 161 : 0 : } 162 : : 163 : 0 : emit layersRemoved( layerIds ); 164 : 3 : } 165 : : 166 : 0 : void QgsMapLayerStore::removeMapLayer( const QString &layerId ) 167 : : { 168 : 0 : removeMapLayers( QList<QgsMapLayer *>() << mMapLayers.value( layerId ) ); 169 : 0 : } 170 : : 171 : 0 : void QgsMapLayerStore::removeMapLayer( QgsMapLayer *layer ) 172 : : { 173 : 0 : if ( layer ) 174 : 0 : removeMapLayers( QList<QgsMapLayer *>() << layer ); 175 : 0 : } 176 : : 177 : 0 : QgsMapLayer *QgsMapLayerStore::takeMapLayer( QgsMapLayer *layer ) 178 : : { 179 : 0 : if ( !layer ) 180 : 0 : return nullptr; 181 : : 182 : 0 : if ( mMapLayers.contains( layer->id() ) ) 183 : : { 184 : 0 : emit layersWillBeRemoved( QStringList() << layer->id() ); 185 : 0 : emit layersWillBeRemoved( QList<QgsMapLayer *>() << layer ); 186 : 0 : emit layerWillBeRemoved( layer->id() ); 187 : 0 : emit layerWillBeRemoved( layer ); 188 : : 189 : 0 : mMapLayers.remove( layer->id() ); 190 : 0 : layer->setParent( nullptr ); 191 : 0 : emit layerRemoved( layer->id() ); 192 : 0 : emit layersRemoved( QStringList() << layer->id() ); 193 : 0 : return layer; 194 : : } 195 : 0 : return nullptr; //don't return layer - it wasn't owned and accordingly we aren't transferring ownership 196 : 0 : } 197 : : 198 : 3 : void QgsMapLayerStore::removeAllMapLayers() 199 : : { 200 : 3 : emit allLayersRemoved(); 201 : : // now let all observers know to clear themselves, 202 : : // and then consequently any of their map legends 203 : 3 : removeMapLayers( mMapLayers.keys() ); 204 : 3 : mMapLayers.clear(); 205 : 3 : } 206 : : 207 : 0 : void QgsMapLayerStore::transferLayersFromStore( QgsMapLayerStore *other ) 208 : : { 209 : 0 : if ( !other || other == this ) 210 : 0 : return; 211 : : 212 : : Q_ASSERT_X( other->thread() == thread(), "QgsMapLayerStore::transferLayersFromStore", "Cannot transfer layers from store with different thread affinity" ); 213 : : 214 : 0 : QMap<QString, QgsMapLayer *> otherLayers = other->mapLayers(); 215 : 0 : QMap<QString, QgsMapLayer *>::const_iterator it = otherLayers.constBegin(); 216 : 0 : for ( ; it != otherLayers.constEnd(); ++it ) 217 : : { 218 : 0 : QgsMapLayer *layer = other->takeMapLayer( it.value() ); 219 : 0 : if ( layer ) 220 : 0 : addMapLayer( layer ); 221 : 0 : } 222 : 0 : } 223 : : 224 : 1 : void QgsMapLayerStore::onMapLayerDeleted( QObject *obj ) 225 : : { 226 : 1 : QString id = mMapLayers.key( static_cast<QgsMapLayer *>( obj ) ); 227 : : 228 : 1 : if ( !id.isNull() ) 229 : : { 230 : 1 : QgsDebugMsg( QStringLiteral( "Map layer deleted without unregistering! %1" ).arg( id ) ); 231 : 1 : mMapLayers.remove( id ); 232 : 1 : } 233 : 1 : } 234 : : 235 : 15 : QMap<QString, QgsMapLayer *> QgsMapLayerStore::mapLayers() const 236 : : { 237 : 15 : return mMapLayers; 238 : : } 239 : : 240 : 0 : QMap<QString, QgsMapLayer *> QgsMapLayerStore::validMapLayers() const 241 : : { 242 : 0 : QMap<QString, QgsMapLayer *> validLayers; 243 : 0 : for ( const auto &id : mMapLayers.keys() ) 244 : : { 245 : 0 : if ( mMapLayers[id]->isValid() ) 246 : 0 : validLayers[id] = mMapLayers[id]; 247 : : } 248 : 0 : return validLayers; 249 : 0 : }