Bug report #18591
"Duplicate layers" action does not work with memory layer
Status: | Open | ||
---|---|---|---|
Priority: | Normal | ||
Assignee: | - | ||
Category: | Map Legend | ||
Affected QGIS version: | 3.4.4 | Regression?: | No |
Operating System: | Easy fix?: | No | |
Pull Request or Patch supplied: | No | Resolution: | |
Crashes QGIS or corrupts data: | No | Copied to github as #: | 26479 |
Description
create a temporary layer (i used centroids alg on a layer)
right-click on the layer: the "Duplicate layer" action is grayed.
Click on Layer menu, the "Duplicate Layer(s)" action is NOT grayed. (Btw, it could be nice to have the same label). Click on that menu action, nothing happens. That tool however works if you use a not memory layer.
Also, you can however use the Copy and Paste layer actions in the Layer menu to duplicate the memory layer.
History
#1 Updated by Andrea Giudiceandrea over 5 years ago
- Affected QGIS version changed from 3.1(master) to 3.4.4
Confirmed in 3.4.4 and master (3.5 407adc761e).
It seems that QgisApp::duplicateLayers cannot duplicate memory layers (and plugin layers):
https://github.com/qgis/QGIS/blob/master/src/app/qgisapp.cpp#L10059
void QgisApp::duplicateLayers( const QList<QgsMapLayer *> &lyrList ) [...] // currently memory and plugin layers are skipped
So it's correct that the "Duplicate layer" action is greyed out in the contextual menu of a memory layer. while it's incorrect that is not greyed out in the "Layer" menu.
This inconsistent behaviour seems to lay in different logic applied in createContextMenu() and legendLayerSelectionChanged().
In the the first case, the "Duplicate layer" action is disabled if the layer is of memory or plugin type
https://github.com/qgis/QGIS/blob/master/src/app/qgsapplayertreeviewmenuprovider.cpp#L234-L235
if ( vlayer->storageType() == QLatin1String( "Memory storage" ) && mView->selectedLayerNodes().count() == 1 ) duplicateLayersAction->setEnabled( false );
https://github.com/qgis/QGIS/blob/master/src/app/qgsapplayertreeviewmenuprovider.cpp#L331-L335
else if ( layer && layer->type() == QgsMapLayer::PluginLayer && mView->selectedLayerNodes().count() == 1 ) { // disable duplication of plugin layers duplicateLayersAction->setEnabled( false ); }
in the latter case, the menu item is disabled only if the there are no layers selected
https://github.com/qgis/QGIS/blob/master/src/app/qgsapplayertreeviewmenuprovider.cpp#L331-L335
mActionDuplicateLayer->setEnabled( !selectedLayers.isEmpty() );
In order to make the behaviour consistent, I think it should be sufficient to change the line this way (not tested):
mActionDuplicateLayer->setEnabled( selectedLayers.count() == 1 && selectedLayers.front().type() != QgsMapLayer::PluginLayer && selectedLayers.front().providerType() != QLatin1String( "memory" ) || !selectedLayers.isEmpty() );
or
if ( selectedLayers.count() == 1 ) mActionDuplicateLayer->setEnabled( selectedLayers.front().type() != QgsMapLayer::PluginLayer && selectedLayers.front().providerType() != QLatin1String( "Memory storage" ) ) else mActionDuplicateLayer->setEnabled( !selectedLayers.isEmpty() )