diff --git a/src/app/legend/qgslegend.h b/src/app/legend/qgslegend.h index e0cb20716cac..760f07abb36e 100644 --- a/src/app/legend/qgslegend.h +++ b/src/app/legend/qgslegend.h @@ -206,8 +206,13 @@ class QgsLegend : public QTreeWidget /** return canvas */ QgsMapCanvas *canvas() { return mMapCanvas; } - public slots: + /**Returns the legend layer to which a map layer belongs to*/ + QgsLegendLayer* findLegendLayer( const QString& layerKey ); + /**Returns the legend layer to which a map layer belongs to*/ + QgsLegendLayer* findLegendLayer( const QgsMapLayer *layer ); + + public slots: /*!Adds a new layer group with the maplayers to the canvas*/ void addLayers( QList ); @@ -372,12 +377,6 @@ class QgsLegend : public QTreeWidget void mouseReleaseEvent( QMouseEvent * e ); void mouseDoubleClickEvent( QMouseEvent* e ); - /**Returns the legend layer to which a map layer belongs to*/ - QgsLegendLayer* findLegendLayer( const QString& layerKey ); - - /**Returns the legend layer to which a map layer belongs to*/ - QgsLegendLayer* findLegendLayer( const QgsMapLayer *layer ); - /**Checks mPixmapWidthValues and mPixmapHeightValues and sets a new icon size if necessary*/ void adjustIconSize(); diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index 19b915f339bd..989b2a1361f5 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -5372,7 +5372,7 @@ void QgisApp::duplicateLayers( QList lyrList ) return; } - QList selectedLyrs = lyrList.empty() ? mMapLegend->selectedLayers() : lyrList; + const QList selectedLyrs = lyrList.empty() ? mMapLegend->selectedLayers() : lyrList; if ( selectedLyrs.empty() ) { return; @@ -5389,16 +5389,6 @@ void QgisApp::duplicateLayers( QList lyrList ) unSppType = QString( "" ); layerDupName = selectedLyr->name() + " " + tr( "copy" ); - // setup for placing duplicated layer below source layer, regardless of group depth - mMapLegend->blockSignals( true ); - if ( !mMapLegend->setCurrentLayer( selectedLyr ) ) - { - mMapLegend->blockSignals( false ); - continue; // legend item doesn't exist for map layer - } - mMapLegend->blockSignals( false ); - QgsLegendLayer *sourcellayer = mMapLegend->currentLegendLayer(); - if ( selectedLyr->type() == QgsMapLayer::PluginLayer ) { unSppType = tr( "Plugin layer" ); @@ -5409,7 +5399,7 @@ void QgisApp::duplicateLayers( QList lyrList ) if ( unSppType.isEmpty() ) { QgsVectorLayer *vlayer = qobject_cast( selectedLyr ); - // TODO: check for other layer types that won't duplicate correctly + // TODO: add other layer types that can be duplicated // currently memory and plugin layers are skipped if ( vlayer && vlayer->storageType() == "Memory storage" ) { @@ -5421,7 +5411,6 @@ void QgisApp::duplicateLayers( QList lyrList ) } } - if ( unSppType.isEmpty() && !dupLayer ) { QgsRasterLayer *rlayer = qobject_cast( selectedLyr ); @@ -5453,23 +5442,39 @@ void QgisApp::duplicateLayers( QList lyrList ) continue; } - // add layer to project and layer registry + // add layer to layer registry and legend QList myList; myList << dupLayer; QgsMapLayerRegistry::instance()->addMapLayers( myList ); - // duplicate the layer style - copyStyle( selectedLyr ); - pasteStyle( dupLayer ); + // verify layer has been added to legend + QgsLegendLayer *duplLayer = 0; + duplLayer = mMapLegend->findLegendLayer( dupLayer ); + if ( !duplLayer ) + { + // some source layers, like items > 4th in a container, have their layer + // registered but do not show up in the legend, so manually add them + QgsLegendLayer* llayer = new QgsLegendLayer( dupLayer ); + mMapLegend->insertTopLevelItem( 0, llayer ); + // double-check, or move of non-existent legend layer will segfault + duplLayer = mMapLegend->findLegendLayer( dupLayer ); + } + + QgsLegendLayer *srclLayer = mMapLegend->findLegendLayer( selectedLyr ); + if ( duplLayer && srclLayer ) + { + // move layer to just below source layer + mMapLegend->moveItem( duplLayer, srclLayer ); - // move layer to just below source layer - QgsLegendLayer *dupllayer = mMapLegend->currentLegendLayer(); - mMapLegend->moveItem( dupllayer, sourcellayer ); + // duplicate the layer style + copyStyle( selectedLyr ); + pasteStyle( dupLayer ); - // always set duplicated layers to not visible - // so layer can be configured before being turned on, - // and no map canvas refresh needed when doing multiple duplications - mMapLegend->setLayerVisible( dupLayer, false ); + // always set duplicated layers to not visible + // so layer can be configured before being turned on, + // and no map canvas refresh needed when doing multiple duplications + mMapLegend->setLayerVisible( dupLayer, false ); + } } dupLayer = 0;