mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-19 00:04:52 -04:00
[FEATURE] Duplicate map layer(s)
- Action available in Layer menu and legend contextual menu - Layer style copy/pasted to duplicate - Memory and plugin layers skipped - Add sip binding to action in app interface
This commit is contained in:
parent
42104d7f3d
commit
c11df1aa79
@ -364,6 +364,8 @@ class QgisInterface : QObject
|
|||||||
virtual QAction *actionLayerSaveAs() = 0;
|
virtual QAction *actionLayerSaveAs() = 0;
|
||||||
virtual QAction *actionLayerSelectionSaveAs() = 0;
|
virtual QAction *actionLayerSelectionSaveAs() = 0;
|
||||||
virtual QAction *actionRemoveLayer() = 0;
|
virtual QAction *actionRemoveLayer() = 0;
|
||||||
|
/** @note added in 2.0 */
|
||||||
|
virtual QAction *actionDuplicateLayer() = 0;
|
||||||
virtual QAction *actionLayerProperties() = 0;
|
virtual QAction *actionLayerProperties() = 0;
|
||||||
virtual QAction *actionLayerSeparator2() = 0 /Deprecated/;
|
virtual QAction *actionLayerSeparator2() = 0 /Deprecated/;
|
||||||
virtual QAction *actionAddToOverview() = 0;
|
virtual QAction *actionAddToOverview() = 0;
|
||||||
|
@ -430,6 +430,9 @@ void QgsLegendLayer::addToPopupMenu( QMenu& theMenu )
|
|||||||
// remove from canvas
|
// remove from canvas
|
||||||
theMenu.addAction( QgsApplication::getThemeIcon( "/mActionRemoveLayer.png" ), tr( "&Remove" ), QgisApp::instance(), SLOT( removeLayer() ) );
|
theMenu.addAction( QgsApplication::getThemeIcon( "/mActionRemoveLayer.png" ), tr( "&Remove" ), QgisApp::instance(), SLOT( removeLayer() ) );
|
||||||
|
|
||||||
|
// duplicate layer
|
||||||
|
theMenu.addAction( QgsApplication::getThemeIcon( "/mActionAddMap.png" ), tr( "&Duplicate" ), QgisApp::instance(), SLOT( duplicateLayers() ) );
|
||||||
|
|
||||||
// set layer crs
|
// set layer crs
|
||||||
theMenu.addAction( QgsApplication::getThemeIcon( "/mActionSetCRS.png" ), tr( "&Set Layer CRS" ), QgisApp::instance(), SLOT( setLayerCRS() ) );
|
theMenu.addAction( QgsApplication::getThemeIcon( "/mActionSetCRS.png" ), tr( "&Set Layer CRS" ), QgisApp::instance(), SLOT( setLayerCRS() ) );
|
||||||
|
|
||||||
|
@ -961,6 +961,7 @@ void QgisApp::createActions()
|
|||||||
connect( mActionLayerSaveAs, SIGNAL( triggered() ), this, SLOT( saveAsFile() ) );
|
connect( mActionLayerSaveAs, SIGNAL( triggered() ), this, SLOT( saveAsFile() ) );
|
||||||
connect( mActionLayerSelectionSaveAs, SIGNAL( triggered() ), this, SLOT( saveSelectionAsVectorFile() ) );
|
connect( mActionLayerSelectionSaveAs, SIGNAL( triggered() ), this, SLOT( saveSelectionAsVectorFile() ) );
|
||||||
connect( mActionRemoveLayer, SIGNAL( triggered() ), this, SLOT( removeLayer() ) );
|
connect( mActionRemoveLayer, SIGNAL( triggered() ), this, SLOT( removeLayer() ) );
|
||||||
|
connect( mActionDuplicateLayer, SIGNAL( triggered() ), this, SLOT( duplicateLayers() ) );
|
||||||
connect( mActionSetLayerCRS, SIGNAL( triggered() ), this, SLOT( setLayerCRS() ) );
|
connect( mActionSetLayerCRS, SIGNAL( triggered() ), this, SLOT( setLayerCRS() ) );
|
||||||
connect( mActionSetProjectCRSFromLayer, SIGNAL( triggered() ), this, SLOT( setProjectCRSFromLayer() ) );
|
connect( mActionSetProjectCRSFromLayer, SIGNAL( triggered() ), this, SLOT( setProjectCRSFromLayer() ) );
|
||||||
connect( mActionLayerProperties, SIGNAL( triggered() ), this, SLOT( layerProperties() ) );
|
connect( mActionLayerProperties, SIGNAL( triggered() ), this, SLOT( layerProperties() ) );
|
||||||
@ -1630,6 +1631,7 @@ void QgisApp::setTheme( QString theThemeName )
|
|||||||
mActionAddMssqlLayer->setIcon( QgsApplication::getThemeIcon( "/mActionAddMssqlLayer.png" ) );
|
mActionAddMssqlLayer->setIcon( QgsApplication::getThemeIcon( "/mActionAddMssqlLayer.png" ) );
|
||||||
#endif
|
#endif
|
||||||
mActionRemoveLayer->setIcon( QgsApplication::getThemeIcon( "/mActionRemoveLayer.png" ) );
|
mActionRemoveLayer->setIcon( QgsApplication::getThemeIcon( "/mActionRemoveLayer.png" ) );
|
||||||
|
mActionDuplicateLayer->setIcon( QgsApplication::getThemeIcon( "/mActionAddMap.png" ) );
|
||||||
mActionSetLayerCRS->setIcon( QgsApplication::getThemeIcon( "/mActionSetLayerCRS.png" ) );
|
mActionSetLayerCRS->setIcon( QgsApplication::getThemeIcon( "/mActionSetLayerCRS.png" ) );
|
||||||
mActionSetProjectCRSFromLayer->setIcon( QgsApplication::getThemeIcon( "/mActionSetProjectCRSFromLayer.png" ) );
|
mActionSetProjectCRSFromLayer->setIcon( QgsApplication::getThemeIcon( "/mActionSetProjectCRSFromLayer.png" ) );
|
||||||
mActionNewVectorLayer->setIcon( QgsApplication::getThemeIcon( "/mActionNewVectorLayer.png" ) );
|
mActionNewVectorLayer->setIcon( QgsApplication::getThemeIcon( "/mActionNewVectorLayer.png" ) );
|
||||||
@ -5341,6 +5343,77 @@ void QgisApp::removeLayer()
|
|||||||
mMapCanvas->refresh();
|
mMapCanvas->refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QgisApp::duplicateLayers( QList<QgsMapLayer *> lyrList )
|
||||||
|
{
|
||||||
|
if ( mMapCanvas && mMapCanvas->isDrawing() )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !mMapLegend )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QgsMapLayer *> selectedLyrs = lyrList.empty() ? mMapLegend->selectedLayers() : lyrList;
|
||||||
|
if ( selectedLyrs.empty() )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mMapCanvas->freeze();
|
||||||
|
QgsMapLayer *dupLayer;
|
||||||
|
foreach ( QgsMapLayer * selectedLyr, selectedLyrs )
|
||||||
|
{
|
||||||
|
dupLayer = 0;
|
||||||
|
QString layerDupName = selectedLyr->name() + " " + tr( "copy" );
|
||||||
|
|
||||||
|
// duplicate the layer's basic parameters
|
||||||
|
|
||||||
|
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer*>( selectedLyr );
|
||||||
|
// TODO: check for other layer types that won't duplicate correctly
|
||||||
|
// currently memory and plugin layers are skipped
|
||||||
|
if ( vlayer && vlayer->storageType() != "Memory storage" )
|
||||||
|
{
|
||||||
|
dupLayer = new QgsVectorLayer( vlayer->source(), layerDupName, vlayer->providerType() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !dupLayer )
|
||||||
|
{
|
||||||
|
QgsRasterLayer *rlayer = qobject_cast<QgsRasterLayer*>( selectedLyr );
|
||||||
|
if ( rlayer )
|
||||||
|
{
|
||||||
|
dupLayer = new QgsRasterLayer( rlayer->source(), layerDupName );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( dupLayer && !dupLayer->isValid() )
|
||||||
|
{
|
||||||
|
QgsDebugMsg( "Duplicated layer was invalid" );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !dupLayer )
|
||||||
|
{
|
||||||
|
QMessageBox::information( this,
|
||||||
|
tr( "Unsupported Layer" ),
|
||||||
|
tr( "%1\n\nDuplication of layer type is unsupported." ).arg( selectedLyr->name() ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add layer to project and layer registry
|
||||||
|
addMapLayer( dupLayer );
|
||||||
|
|
||||||
|
// duplicate the layer style
|
||||||
|
copyStyle( selectedLyr );
|
||||||
|
pasteStyle( dupLayer );
|
||||||
|
}
|
||||||
|
|
||||||
|
dupLayer = 0;
|
||||||
|
mMapCanvas->freeze( false );
|
||||||
|
mMapCanvas->refresh();
|
||||||
|
}
|
||||||
|
|
||||||
void QgisApp::setLayerCRS()
|
void QgisApp::setLayerCRS()
|
||||||
{
|
{
|
||||||
if ( mMapCanvas && mMapCanvas->isDrawing() )
|
if ( mMapCanvas && mMapCanvas->isDrawing() )
|
||||||
@ -6833,6 +6906,7 @@ void QgisApp::selectionChanged( QgsMapLayer *layer )
|
|||||||
void QgisApp::legendLayerSelectionChanged( void )
|
void QgisApp::legendLayerSelectionChanged( void )
|
||||||
{
|
{
|
||||||
mActionRemoveLayer->setEnabled( mMapLegend && mMapLegend->selectedLayers().size() > 0 );
|
mActionRemoveLayer->setEnabled( mMapLegend && mMapLegend->selectedLayers().size() > 0 );
|
||||||
|
mActionDuplicateLayer->setEnabled( mMapLegend && mMapLegend->selectedLayers().size() > 0 );
|
||||||
mActionSetLayerCRS->setEnabled( mMapLegend && mMapLegend->selectedLayers().size() > 0 );
|
mActionSetLayerCRS->setEnabled( mMapLegend && mMapLegend->selectedLayers().size() > 0 );
|
||||||
mActionSetProjectCRSFromLayer->setEnabled( mMapLegend && mMapLegend->selectedLayers().size() == 1 );
|
mActionSetProjectCRSFromLayer->setEnabled( mMapLegend && mMapLegend->selectedLayers().size() == 1 );
|
||||||
}
|
}
|
||||||
|
@ -290,6 +290,8 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
|
|||||||
QAction *actionLayerSaveAs() { return mActionLayerSaveAs; }
|
QAction *actionLayerSaveAs() { return mActionLayerSaveAs; }
|
||||||
QAction *actionLayerSelectionSaveAs() { return mActionLayerSelectionSaveAs; }
|
QAction *actionLayerSelectionSaveAs() { return mActionLayerSelectionSaveAs; }
|
||||||
QAction *actionRemoveLayer() { return mActionRemoveLayer; }
|
QAction *actionRemoveLayer() { return mActionRemoveLayer; }
|
||||||
|
/** @note added in 2.0 */
|
||||||
|
QAction *actionDuplicateLayer() { return mActionDuplicateLayer; }
|
||||||
QAction *actionSetLayerCRS() { return mActionSetLayerCRS; }
|
QAction *actionSetLayerCRS() { return mActionSetLayerCRS; }
|
||||||
QAction *actionSetProjectCRSFromLayer() { return mActionSetProjectCRSFromLayer; }
|
QAction *actionSetProjectCRSFromLayer() { return mActionSetProjectCRSFromLayer; }
|
||||||
QAction *actionLayerProperties() { return mActionLayerProperties; }
|
QAction *actionLayerProperties() { return mActionLayerProperties; }
|
||||||
@ -543,6 +545,9 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
|
|||||||
void userCenter();
|
void userCenter();
|
||||||
//! Remove a layer from the map and legend
|
//! Remove a layer from the map and legend
|
||||||
void removeLayer();
|
void removeLayer();
|
||||||
|
/** Duplicate map layer(s) in legend
|
||||||
|
* @note added in 2.0 */
|
||||||
|
void duplicateLayers( const QList<QgsMapLayer *> lyrList = QList<QgsMapLayer *>() );
|
||||||
//! Set CRS of a layer
|
//! Set CRS of a layer
|
||||||
void setLayerCRS();
|
void setLayerCRS();
|
||||||
//! Assign layer CRS to project
|
//! Assign layer CRS to project
|
||||||
|
@ -465,6 +465,7 @@ QAction *QgisAppInterface::actionToggleEditing() { return qgis->actionToggleEdit
|
|||||||
QAction *QgisAppInterface::actionLayerSaveAs() { return qgis->actionLayerSaveAs(); }
|
QAction *QgisAppInterface::actionLayerSaveAs() { return qgis->actionLayerSaveAs(); }
|
||||||
QAction *QgisAppInterface::actionLayerSelectionSaveAs() { return qgis->actionLayerSelectionSaveAs(); }
|
QAction *QgisAppInterface::actionLayerSelectionSaveAs() { return qgis->actionLayerSelectionSaveAs(); }
|
||||||
QAction *QgisAppInterface::actionRemoveLayer() { return qgis->actionRemoveLayer(); }
|
QAction *QgisAppInterface::actionRemoveLayer() { return qgis->actionRemoveLayer(); }
|
||||||
|
QAction *QgisAppInterface::actionDuplicateLayer() { return qgis->actionDuplicateLayer(); }
|
||||||
QAction *QgisAppInterface::actionLayerProperties() { return qgis->actionLayerProperties(); }
|
QAction *QgisAppInterface::actionLayerProperties() { return qgis->actionLayerProperties(); }
|
||||||
QAction *QgisAppInterface::actionLayerSeparator2() { return 0; }
|
QAction *QgisAppInterface::actionLayerSeparator2() { return 0; }
|
||||||
QAction *QgisAppInterface::actionAddToOverview() { return qgis->actionAddToOverview(); }
|
QAction *QgisAppInterface::actionAddToOverview() { return qgis->actionAddToOverview(); }
|
||||||
|
@ -313,6 +313,8 @@ class QgisAppInterface : public QgisInterface
|
|||||||
virtual QAction *actionLayerSaveAs();
|
virtual QAction *actionLayerSaveAs();
|
||||||
virtual QAction *actionLayerSelectionSaveAs();
|
virtual QAction *actionLayerSelectionSaveAs();
|
||||||
virtual QAction *actionRemoveLayer();
|
virtual QAction *actionRemoveLayer();
|
||||||
|
/** @note added in 2.0 */
|
||||||
|
virtual QAction *actionDuplicateLayer();
|
||||||
virtual QAction *actionLayerProperties();
|
virtual QAction *actionLayerProperties();
|
||||||
virtual QAction *actionLayerSeparator2();
|
virtual QAction *actionLayerSeparator2();
|
||||||
virtual QAction *actionAddToOverview();
|
virtual QAction *actionAddToOverview();
|
||||||
|
@ -466,6 +466,8 @@ class GUI_EXPORT QgisInterface : public QObject
|
|||||||
virtual QAction *actionLayerSaveAs() = 0;
|
virtual QAction *actionLayerSaveAs() = 0;
|
||||||
virtual QAction *actionLayerSelectionSaveAs() = 0;
|
virtual QAction *actionLayerSelectionSaveAs() = 0;
|
||||||
virtual QAction *actionRemoveLayer() = 0;
|
virtual QAction *actionRemoveLayer() = 0;
|
||||||
|
/** @note added in 2.0 */
|
||||||
|
virtual QAction *actionDuplicateLayer() = 0;
|
||||||
virtual QAction *actionLayerProperties() = 0;
|
virtual QAction *actionLayerProperties() = 0;
|
||||||
#ifndef Q_MOC_RUN
|
#ifndef Q_MOC_RUN
|
||||||
Q_DECL_DEPRECATED
|
Q_DECL_DEPRECATED
|
||||||
|
@ -168,6 +168,7 @@
|
|||||||
<addaction name="mActionLayerSaveAs"/>
|
<addaction name="mActionLayerSaveAs"/>
|
||||||
<addaction name="mActionLayerSelectionSaveAs"/>
|
<addaction name="mActionLayerSelectionSaveAs"/>
|
||||||
<addaction name="mActionRemoveLayer"/>
|
<addaction name="mActionRemoveLayer"/>
|
||||||
|
<addaction name="mActionDuplicateLayer"/>
|
||||||
<addaction name="mActionSetLayerCRS"/>
|
<addaction name="mActionSetLayerCRS"/>
|
||||||
<addaction name="mActionSetProjectCRSFromLayer"/>
|
<addaction name="mActionSetProjectCRSFromLayer"/>
|
||||||
<addaction name="mActionLayerProperties"/>
|
<addaction name="mActionLayerProperties"/>
|
||||||
@ -1821,6 +1822,18 @@ Acts on currently active editable layer</string>
|
|||||||
<string>Html Annotation</string>
|
<string>Html Annotation</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="mActionDuplicateLayer">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../images/images.qrc">
|
||||||
|
<normaloff>:/images/themes/default/mActionAddMap.png</normaloff>:/images/themes/default/mActionAddMap.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Duplicate Layer(s)</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Duplicate Layer(s)</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../../images/images.qrc"/>
|
<include location="../../images/images.qrc"/>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user