Skip to content

Commit 81f99d6

Browse files
committed
Fix for #6658, update duplicateLayers() to work around odd layer group segfault bug
- Move QgsLegend::findLegendLayer() methods to public
1 parent 474bd24 commit 81f99d6

File tree

2 files changed

+35
-31
lines changed

2 files changed

+35
-31
lines changed

src/app/legend/qgslegend.h

+6-7
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,13 @@ class QgsLegend : public QTreeWidget
206206
/** return canvas */
207207
QgsMapCanvas *canvas() { return mMapCanvas; }
208208

209-
public slots:
209+
/**Returns the legend layer to which a map layer belongs to*/
210+
QgsLegendLayer* findLegendLayer( const QString& layerKey );
210211

212+
/**Returns the legend layer to which a map layer belongs to*/
213+
QgsLegendLayer* findLegendLayer( const QgsMapLayer *layer );
214+
215+
public slots:
211216

212217
/*!Adds a new layer group with the maplayers to the canvas*/
213218
void addLayers( QList<QgsMapLayer *> );
@@ -372,12 +377,6 @@ class QgsLegend : public QTreeWidget
372377
void mouseReleaseEvent( QMouseEvent * e );
373378
void mouseDoubleClickEvent( QMouseEvent* e );
374379

375-
/**Returns the legend layer to which a map layer belongs to*/
376-
QgsLegendLayer* findLegendLayer( const QString& layerKey );
377-
378-
/**Returns the legend layer to which a map layer belongs to*/
379-
QgsLegendLayer* findLegendLayer( const QgsMapLayer *layer );
380-
381380
/**Checks mPixmapWidthValues and mPixmapHeightValues and sets a new icon size if necessary*/
382381
void adjustIconSize();
383382

src/app/qgisapp.cpp

+29-24
Original file line numberDiff line numberDiff line change
@@ -5372,7 +5372,7 @@ void QgisApp::duplicateLayers( QList<QgsMapLayer *> lyrList )
53725372
return;
53735373
}
53745374

5375-
QList<QgsMapLayer *> selectedLyrs = lyrList.empty() ? mMapLegend->selectedLayers() : lyrList;
5375+
const QList<QgsMapLayer *> selectedLyrs = lyrList.empty() ? mMapLegend->selectedLayers() : lyrList;
53765376
if ( selectedLyrs.empty() )
53775377
{
53785378
return;
@@ -5389,16 +5389,6 @@ void QgisApp::duplicateLayers( QList<QgsMapLayer *> lyrList )
53895389
unSppType = QString( "" );
53905390
layerDupName = selectedLyr->name() + " " + tr( "copy" );
53915391

5392-
// setup for placing duplicated layer below source layer, regardless of group depth
5393-
mMapLegend->blockSignals( true );
5394-
if ( !mMapLegend->setCurrentLayer( selectedLyr ) )
5395-
{
5396-
mMapLegend->blockSignals( false );
5397-
continue; // legend item doesn't exist for map layer
5398-
}
5399-
mMapLegend->blockSignals( false );
5400-
QgsLegendLayer *sourcellayer = mMapLegend->currentLegendLayer();
5401-
54025392
if ( selectedLyr->type() == QgsMapLayer::PluginLayer )
54035393
{
54045394
unSppType = tr( "Plugin layer" );
@@ -5409,7 +5399,7 @@ void QgisApp::duplicateLayers( QList<QgsMapLayer *> lyrList )
54095399
if ( unSppType.isEmpty() )
54105400
{
54115401
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer*>( selectedLyr );
5412-
// TODO: check for other layer types that won't duplicate correctly
5402+
// TODO: add other layer types that can be duplicated
54135403
// currently memory and plugin layers are skipped
54145404
if ( vlayer && vlayer->storageType() == "Memory storage" )
54155405
{
@@ -5421,7 +5411,6 @@ void QgisApp::duplicateLayers( QList<QgsMapLayer *> lyrList )
54215411
}
54225412
}
54235413

5424-
54255414
if ( unSppType.isEmpty() && !dupLayer )
54265415
{
54275416
QgsRasterLayer *rlayer = qobject_cast<QgsRasterLayer*>( selectedLyr );
@@ -5453,23 +5442,39 @@ void QgisApp::duplicateLayers( QList<QgsMapLayer *> lyrList )
54535442
continue;
54545443
}
54555444

5456-
// add layer to project and layer registry
5445+
// add layer to layer registry and legend
54575446
QList<QgsMapLayer *> myList;
54585447
myList << dupLayer;
54595448
QgsMapLayerRegistry::instance()->addMapLayers( myList );
54605449

5461-
// duplicate the layer style
5462-
copyStyle( selectedLyr );
5463-
pasteStyle( dupLayer );
5450+
// verify layer has been added to legend
5451+
QgsLegendLayer *duplLayer = 0;
5452+
duplLayer = mMapLegend->findLegendLayer( dupLayer );
5453+
if ( !duplLayer )
5454+
{
5455+
// some source layers, like items > 4th in a container, have their layer
5456+
// registered but do not show up in the legend, so manually add them
5457+
QgsLegendLayer* llayer = new QgsLegendLayer( dupLayer );
5458+
mMapLegend->insertTopLevelItem( 0, llayer );
5459+
// double-check, or move of non-existent legend layer will segfault
5460+
duplLayer = mMapLegend->findLegendLayer( dupLayer );
5461+
}
5462+
5463+
QgsLegendLayer *srclLayer = mMapLegend->findLegendLayer( selectedLyr );
5464+
if ( duplLayer && srclLayer )
5465+
{
5466+
// move layer to just below source layer
5467+
mMapLegend->moveItem( duplLayer, srclLayer );
54645468

5465-
// move layer to just below source layer
5466-
QgsLegendLayer *dupllayer = mMapLegend->currentLegendLayer();
5467-
mMapLegend->moveItem( dupllayer, sourcellayer );
5469+
// duplicate the layer style
5470+
copyStyle( selectedLyr );
5471+
pasteStyle( dupLayer );
54685472

5469-
// always set duplicated layers to not visible
5470-
// so layer can be configured before being turned on,
5471-
// and no map canvas refresh needed when doing multiple duplications
5472-
mMapLegend->setLayerVisible( dupLayer, false );
5473+
// always set duplicated layers to not visible
5474+
// so layer can be configured before being turned on,
5475+
// and no map canvas refresh needed when doing multiple duplications
5476+
mMapLegend->setLayerVisible( dupLayer, false );
5477+
}
54735478
}
54745479

54755480
dupLayer = 0;

0 commit comments

Comments
 (0)