Skip to content

Commit

Permalink
[BACKPORT] to 1.8. Further improvements to multiple layer removal in …
Browse files Browse the repository at this point in the history
…one operation support for the registry and apply suggested improvements from Jürgen.
  • Loading branch information
timlinux committed Apr 4, 2012
1 parent 985e453 commit 8d4a656
Show file tree
Hide file tree
Showing 9 changed files with 256 additions and 148 deletions.
59 changes: 47 additions & 12 deletions python/core/qgsmaplayerregistry.sip
Expand Up @@ -26,6 +26,23 @@ public:
//! Retrieve the mapLayers collection (mainly intended for use by projection)
QMap<QString,QgsMapLayer*> & mapLayers();

/** Add a list of layers to the map of loaded layers
@returns QList<QgsMapLayer *> - a list of the map layers that were added
successfully. If a layer is invalid, or already exists in the registry,
it will not be part of the returned QList.
@note added in QGIS 1.8

As a side-effect QgsProject is made dirty.

If theEmitSignal is true (by default), a layersAdded( QList<QgsMapLayer *>)
signal will be emitted indicating that a batch of layers were added.
Not emitting signal is useful when you want to use registry for layers
on a different canvas and don't want them added to the main canvas automatically.
*/
QList<QgsMapLayer *> addMapLayers( QList<QgsMapLayer *> theMapLayers,
bool theEmitSignal = true ) /Deprecated/;


/** Add a layer to the map of loaded layers
@returns NULL if unable to add layer, otherwise pointer to newly added layer
@note
Expand All @@ -38,17 +55,26 @@ public:
*/
QgsMapLayer * addMapLayer(QgsMapLayer * theMapLayer /Transfer/, bool theEmitSignal = TRUE);

/** Remove a layer from qgis
/** Remove a set of layers from qgis
@note As a side-effect QgsProject is made dirty.
Any canvases using the affected layers will need to remove them

@note
If theEmitSignal is true (by default), a layersRemoved( QStringList theLayerIds )
signal will be emitted indicating to any listeners that the layers are being removed.

As a side-effect QgsProject is made dirty.
The layer being removed is deleted as well as the registry
table entry.
*/
void removeMapLayers( QStringList theLayerIds, bool theEmitSignal = true );


/** Remove a layer from qgis
@note
As a side-effect QgsProject is made dirty.
Any canvases using that layer will need to remove it

theEmitSignal - see addMapLayer()
*/
void removeMapLayer(QString theLayerId, bool theEmitSignal = TRUE);
void removeMapLayer(QString theLayerId, bool theEmitSignal = TRUE) /Deprecated/;

/** Remove all registered layers

Expand All @@ -72,17 +98,26 @@ public:
void reloadAllLayers();

signals:
/** Emitted when one or more layers are removed from the registry
@note intended to replace layerWillBeRemoved in QGIS 1.8
*/
void layersWillBeRemoved( QStringList theLayerIds );

/** emitted when a layer is removed from the registry

connected to main map canvas and overview map canvas remove()
*/
/** emitted when a layer is removed from the registry
connected to main map canvas and overview map canvas remove()
@note rather use layersWillBeRemoved
*/
void layerWillBeRemoved(QString theLayerId);

/** emitted when a layer is added to the registry
/** Emitted when one or more layers are added to the registry
@note intended to replace layerWasAdded in QGIS 1.8
*/
void layersAdded( QList<QgsMapLayer *> theMapLayers );

connected to main map canvas and overview map canvas addLayer()
*/
/** emitted when a layer is added to the registry
connected to main map canvas and overview map canvas addLayer()
@note rather use layersWereAdded
*/
void layerWasAdded(QgsMapLayer * theMapLayer);

/** emitted when ALL layers are removed at once
Expand Down
12 changes: 8 additions & 4 deletions src/app/gps/qgsgpsinformationwidget.cpp
Expand Up @@ -1073,13 +1073,17 @@ void QgsGPSInformationWidget::updateCloseFeatureButton( QgsMapLayer * lyr )
{
if ( mpLastLayer ) // disconnect previous layer
{
disconnect( mpLastLayer, SIGNAL( editingStarted() ), this, SLOT( layerEditStateChanged() ) );
disconnect( mpLastLayer, SIGNAL( editingStopped() ), this, SLOT( layerEditStateChanged() ) );
disconnect( mpLastLayer, SIGNAL( editingStarted() ),
this, SLOT( layerEditStateChanged() ) );
disconnect( mpLastLayer, SIGNAL( editingStopped() ),
this, SLOT( layerEditStateChanged() ) );
}
if ( vlayer ) // connect new layer
{
connect( vlayer, SIGNAL( editingStarted() ), this, SLOT( layerEditStateChanged() ) );
connect( vlayer, SIGNAL( editingStopped() ), this, SLOT( layerEditStateChanged() ) );
connect( vlayer, SIGNAL( editingStarted() ),
this, SLOT( layerEditStateChanged() ) );
connect( vlayer, SIGNAL( editingStopped() ),
this, SLOT( layerEditStateChanged() ) );
}
mpLastLayer = vlayer;
}
Expand Down
171 changes: 102 additions & 69 deletions src/app/legend/qgslegend.cpp
Expand Up @@ -95,12 +95,14 @@ QgsLegend::QgsLegend( QgsMapCanvas *canvas, QWidget * parent, const char *name )
this, SLOT( writeProject( QDomDocument & ) ) );

// connect map layer registry signal to legend
connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWillBeRemoved( QString ) ),
this, SLOT( removeLayer( QString ) ) );
connect( QgsMapLayerRegistry::instance(),
SIGNAL( layersWillBeRemoved( QStringList ) ),
this, SLOT( removeLayers( QStringList ) ) );
connect( QgsMapLayerRegistry::instance(), SIGNAL( removedAll() ),
this, SLOT( removeAll() ) );
connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWasAdded( QgsMapLayer* ) ),
this, SLOT( addLayer( QgsMapLayer * ) ) );
connect( QgsMapLayerRegistry::instance(),
SIGNAL( layersAdded( QList<QgsMapLayer*> ) ),
this, SLOT( addLayers( QList<QgsMapLayer *> ) ) );

connect( mMapCanvas, SIGNAL( layersChanged() ),
this, SLOT( refreshCheckStates() ) );
Expand Down Expand Up @@ -279,38 +281,48 @@ void QgsLegend::removeGroup( int groupIndex )
}
}

void QgsLegend::removeLayer( QString layerId )
void QgsLegend::removeLayers( QStringList theLayers )
{
QgsDebugMsg( "Entering." );

bool invLayerRemoved = false;

for ( QTreeWidgetItem* theItem = firstItem(); theItem; theItem = nextItem( theItem ) )
foreach (const QString &myId, theLayers)
{
QgsLegendItem *li = dynamic_cast<QgsLegendItem *>( theItem );
if ( li )
{
// save legend layer (parent of a legend layer file we're going to delete)
QgsLegendLayer* ll = qobject_cast<QgsLegendLayer *>( li );
bool invLayerRemoved = false;

if ( ll && ll->layer() && ll->layer()->id() == layerId )
for ( QTreeWidgetItem* theItem = firstItem();
theItem; theItem = nextItem( theItem ) )
{
QgsLegendItem *li = dynamic_cast<QgsLegendItem *>( theItem );
if ( li )
{
if ( !ll->isVisible() )
// save legend layer (parent of a legend layer file we're going to delete)
QgsLegendLayer* ll = qobject_cast<QgsLegendLayer *>( li );

if ( ll && ll->layer() && ll->layer()->id() == myId )
{
invLayerRemoved = true;
if ( !ll->isVisible() )
{
invLayerRemoved = true;
}
removeItem( ll );
delete ll;
break;
}
removeItem( ll );
delete ll;
break;
}
}
emit itemRemoved();
if ( invLayerRemoved )
emit invisibleLayerRemoved();
}
updateMapCanvasLayerSet();
adjustIconSize();
}

emit itemRemoved();
if ( invLayerRemoved )
emit invisibleLayerRemoved();
//deprecated delegates to removeLayers now
void QgsLegend::removeLayer( QString theLayer )
{
QStringList myList;
myList << theLayer;
removeLayers(myList);
}

void QgsLegend::mousePressEvent( QMouseEvent * e )
Expand Down Expand Up @@ -846,77 +858,98 @@ int QgsLegend::getItemPos( QTreeWidgetItem* item )
return -1;
}

void QgsLegend::addLayer( QgsMapLayer * layer )
//introduced in QGIS 1.8 - add layers in a batch
void QgsLegend::addLayers( QList<QgsMapLayer *> theLayerList )
{
QgsDebugMsg( "Entering." );
if ( !mMapCanvas || mMapCanvas->isDrawing() )
{
return;
}

QgsLegendLayer* llayer = new QgsLegendLayer( layer );
if ( !QgsProject::instance()->layerIsEmbedded( layer->id() ).isEmpty() )
{
QFont itemFont;
itemFont.setItalic( true );
llayer->setFont( 0, itemFont );
}
QSettings settings;

//set the correct check states
blockSignals( true );
llayer->setCheckState( 0, llayer->isVisible() ? Qt::Checked : Qt::Unchecked );
blockSignals( false );
//Note if the canvas was previously blank so we can
//zoom to all layers at the end if neeeded
bool myFirstLayerFlag = false;
if ( layers().count() > 0 ) myFirstLayerFlag = true;

QgsLegendGroup *lg = dynamic_cast<QgsLegendGroup *>( currentItem() );
if ( !lg && currentItem() )
//iteratively add the layers to the canvas
for (int i = 0; i < theLayerList.size(); ++i)
{
lg = dynamic_cast<QgsLegendGroup *>( currentItem()->parent() );
}
QgsMapLayer * layer = theLayerList.at(i);
QgsLegendLayer* llayer = new QgsLegendLayer( layer );
if ( !QgsProject::instance()->layerIsEmbedded( layer->id() ).isEmpty() )
{
QFont itemFont;
itemFont.setItalic( true );
llayer->setFont( 0, itemFont );
}

int index;
if ( lg )
{
index = lg->indexOfChild( currentItem() );
}
else
{
index = indexOfTopLevelItem( currentItem() );
}
//set the correct check states
blockSignals( true );
llayer->setCheckState( 0, llayer->isVisible() ? Qt::Checked : Qt::Unchecked );
blockSignals( false );

if ( index < 0 )
{
index = 0;
}
QgsLegendGroup *lg = dynamic_cast<QgsLegendGroup *>( currentItem() );
if ( !lg && currentItem() )
{
lg = dynamic_cast<QgsLegendGroup *>( currentItem()->parent() );
}

QSettings settings;
if ( lg && settings.value( "/qgis/addNewLayersToCurrentGroup", false ).toBool() )
{
lg->insertChild( index, llayer );
}
else
{
insertTopLevelItem( index, llayer );
setCurrentItem( llayer );
}
int index = 0;
if ( lg )
{
index = lg->indexOfChild( currentItem() );
}
else
{
index = indexOfTopLevelItem( currentItem() );
}

setItemExpanded( llayer, true );
//don't expand raster items by default, there could be too many
refreshLayerSymbology( layer->id(), layer->type() != QgsMapLayer::RasterLayer );
if ( index < 0 )
{
index = 0;
}

updateMapCanvasLayerSet();
if ( lg && settings.value( "/qgis/addNewLayersToCurrentGroup", false ).toBool() )
{
lg->insertChild( index, llayer );
}
else
{
insertTopLevelItem( index, llayer );
setCurrentItem( llayer );
}

setItemExpanded( llayer, true );
//don't expand raster items by default, there could be too many
refreshLayerSymbology( layer->id(), layer->type() != QgsMapLayer::RasterLayer );

updateMapCanvasLayerSet();
emit itemAdded( indexFromItem( llayer ) );
}
// first layer?
if ( layers().count() == 1 )
if ( myFirstLayerFlag )
{
QgsMapLayer * myFirstLayer = theLayerList.at(0);
if ( !mMapCanvas->mapRenderer()->hasCrsTransformEnabled() )
mMapCanvas->mapRenderer()->setDestinationCrs( layer->crs() );
mMapCanvas->mapRenderer()->setDestinationCrs( myFirstLayer->crs() );
mMapCanvas->zoomToFullExtent();
mMapCanvas->clearExtentHistory();
}
//make the QTreeWidget item up-to-date
doItemsLayout();

emit itemAdded( indexFromItem( llayer ) );

}

//deprecated since 1.8 - delegates to addLayers
void QgsLegend::addLayer( QgsMapLayer * layer )
{
QList<QgsMapLayer *> myList;
myList << layer;
addLayers( myList );
}

void QgsLegend::setLayerVisible( QgsMapLayer * layer, bool visible )
Expand Down
14 changes: 13 additions & 1 deletion src/app/legend/qgslegend.h
Expand Up @@ -207,7 +207,13 @@ class QgsLegend : public QTreeWidget

public slots:

/*!Adds a new layer group with the maplayer to the canvas*/

/*!Adds a new layer group with the maplayers to the canvas*/
void addLayers( QList<QgsMapLayer *> );

/** Adds a new layer group with the maplayer to the canvas
* @note Deprecated since 1.8 - use addLayers rather
*/
void addLayer( QgsMapLayer * layer );

void setLayerVisible( QgsMapLayer * layer, bool visible );
Expand Down Expand Up @@ -264,8 +270,14 @@ class QgsLegend : public QTreeWidget
*/
void removeGroup( int groupIndex );

/*!
* @deprecated - use removeLayers() rather
*/
void removeLayer( QString );

/** Remove one or more layers from the legend */
void removeLayers( QStringList theLayers );

/** called to read legend settings from project */
void readProject( const QDomDocument & );

Expand Down

0 comments on commit 8d4a656

Please sign in to comment.