Skip to content

Commit

Permalink
[FEATURE] Duplicate map layer(s)
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
dakcarto committed Nov 2, 2012
1 parent 42104d7 commit c11df1a
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 0 deletions.
2 changes: 2 additions & 0 deletions python/gui/qgisinterface.sip
Expand Up @@ -364,6 +364,8 @@ class QgisInterface : QObject
virtual QAction *actionLayerSaveAs() = 0;
virtual QAction *actionLayerSelectionSaveAs() = 0;
virtual QAction *actionRemoveLayer() = 0;
/** @note added in 2.0 */
virtual QAction *actionDuplicateLayer() = 0;
virtual QAction *actionLayerProperties() = 0;
virtual QAction *actionLayerSeparator2() = 0 /Deprecated/;
virtual QAction *actionAddToOverview() = 0;
Expand Down
3 changes: 3 additions & 0 deletions src/app/legend/qgslegendlayer.cpp
Expand Up @@ -430,6 +430,9 @@ void QgsLegendLayer::addToPopupMenu( QMenu& theMenu )
// remove from canvas
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
theMenu.addAction( QgsApplication::getThemeIcon( "/mActionSetCRS.png" ), tr( "&Set Layer CRS" ), QgisApp::instance(), SLOT( setLayerCRS() ) );

Expand Down
74 changes: 74 additions & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -961,6 +961,7 @@ void QgisApp::createActions()
connect( mActionLayerSaveAs, SIGNAL( triggered() ), this, SLOT( saveAsFile() ) );
connect( mActionLayerSelectionSaveAs, SIGNAL( triggered() ), this, SLOT( saveSelectionAsVectorFile() ) );
connect( mActionRemoveLayer, SIGNAL( triggered() ), this, SLOT( removeLayer() ) );
connect( mActionDuplicateLayer, SIGNAL( triggered() ), this, SLOT( duplicateLayers() ) );
connect( mActionSetLayerCRS, SIGNAL( triggered() ), this, SLOT( setLayerCRS() ) );
connect( mActionSetProjectCRSFromLayer, SIGNAL( triggered() ), this, SLOT( setProjectCRSFromLayer() ) );
connect( mActionLayerProperties, SIGNAL( triggered() ), this, SLOT( layerProperties() ) );
Expand Down Expand Up @@ -1630,6 +1631,7 @@ void QgisApp::setTheme( QString theThemeName )
mActionAddMssqlLayer->setIcon( QgsApplication::getThemeIcon( "/mActionAddMssqlLayer.png" ) );
#endif
mActionRemoveLayer->setIcon( QgsApplication::getThemeIcon( "/mActionRemoveLayer.png" ) );
mActionDuplicateLayer->setIcon( QgsApplication::getThemeIcon( "/mActionAddMap.png" ) );
mActionSetLayerCRS->setIcon( QgsApplication::getThemeIcon( "/mActionSetLayerCRS.png" ) );
mActionSetProjectCRSFromLayer->setIcon( QgsApplication::getThemeIcon( "/mActionSetProjectCRSFromLayer.png" ) );
mActionNewVectorLayer->setIcon( QgsApplication::getThemeIcon( "/mActionNewVectorLayer.png" ) );
Expand Down Expand Up @@ -5341,6 +5343,77 @@ void QgisApp::removeLayer()
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()
{
if ( mMapCanvas && mMapCanvas->isDrawing() )
Expand Down Expand Up @@ -6833,6 +6906,7 @@ void QgisApp::selectionChanged( QgsMapLayer *layer )
void QgisApp::legendLayerSelectionChanged( void )
{
mActionRemoveLayer->setEnabled( mMapLegend && mMapLegend->selectedLayers().size() > 0 );
mActionDuplicateLayer->setEnabled( mMapLegend && mMapLegend->selectedLayers().size() > 0 );
mActionSetLayerCRS->setEnabled( mMapLegend && mMapLegend->selectedLayers().size() > 0 );
mActionSetProjectCRSFromLayer->setEnabled( mMapLegend && mMapLegend->selectedLayers().size() == 1 );
}
Expand Down
5 changes: 5 additions & 0 deletions src/app/qgisapp.h
Expand Up @@ -290,6 +290,8 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
QAction *actionLayerSaveAs() { return mActionLayerSaveAs; }
QAction *actionLayerSelectionSaveAs() { return mActionLayerSelectionSaveAs; }
QAction *actionRemoveLayer() { return mActionRemoveLayer; }
/** @note added in 2.0 */
QAction *actionDuplicateLayer() { return mActionDuplicateLayer; }
QAction *actionSetLayerCRS() { return mActionSetLayerCRS; }
QAction *actionSetProjectCRSFromLayer() { return mActionSetProjectCRSFromLayer; }
QAction *actionLayerProperties() { return mActionLayerProperties; }
Expand Down Expand Up @@ -543,6 +545,9 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
void userCenter();
//! Remove a layer from the map and legend
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
void setLayerCRS();
//! Assign layer CRS to project
Expand Down
1 change: 1 addition & 0 deletions src/app/qgisappinterface.cpp
Expand Up @@ -465,6 +465,7 @@ QAction *QgisAppInterface::actionToggleEditing() { return qgis->actionToggleEdit
QAction *QgisAppInterface::actionLayerSaveAs() { return qgis->actionLayerSaveAs(); }
QAction *QgisAppInterface::actionLayerSelectionSaveAs() { return qgis->actionLayerSelectionSaveAs(); }
QAction *QgisAppInterface::actionRemoveLayer() { return qgis->actionRemoveLayer(); }
QAction *QgisAppInterface::actionDuplicateLayer() { return qgis->actionDuplicateLayer(); }
QAction *QgisAppInterface::actionLayerProperties() { return qgis->actionLayerProperties(); }
QAction *QgisAppInterface::actionLayerSeparator2() { return 0; }
QAction *QgisAppInterface::actionAddToOverview() { return qgis->actionAddToOverview(); }
Expand Down
2 changes: 2 additions & 0 deletions src/app/qgisappinterface.h
Expand Up @@ -313,6 +313,8 @@ class QgisAppInterface : public QgisInterface
virtual QAction *actionLayerSaveAs();
virtual QAction *actionLayerSelectionSaveAs();
virtual QAction *actionRemoveLayer();
/** @note added in 2.0 */
virtual QAction *actionDuplicateLayer();
virtual QAction *actionLayerProperties();
virtual QAction *actionLayerSeparator2();
virtual QAction *actionAddToOverview();
Expand Down
2 changes: 2 additions & 0 deletions src/gui/qgisinterface.h
Expand Up @@ -466,6 +466,8 @@ class GUI_EXPORT QgisInterface : public QObject
virtual QAction *actionLayerSaveAs() = 0;
virtual QAction *actionLayerSelectionSaveAs() = 0;
virtual QAction *actionRemoveLayer() = 0;
/** @note added in 2.0 */
virtual QAction *actionDuplicateLayer() = 0;
virtual QAction *actionLayerProperties() = 0;
#ifndef Q_MOC_RUN
Q_DECL_DEPRECATED
Expand Down
13 changes: 13 additions & 0 deletions src/ui/qgisapp.ui
Expand Up @@ -168,6 +168,7 @@
<addaction name="mActionLayerSaveAs"/>
<addaction name="mActionLayerSelectionSaveAs"/>
<addaction name="mActionRemoveLayer"/>
<addaction name="mActionDuplicateLayer"/>
<addaction name="mActionSetLayerCRS"/>
<addaction name="mActionSetProjectCRSFromLayer"/>
<addaction name="mActionLayerProperties"/>
Expand Down Expand Up @@ -1821,6 +1822,18 @@ Acts on currently active editable layer</string>
<string>Html Annotation</string>
</property>
</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>
<resources>
<include location="../../images/images.qrc"/>
Expand Down

0 comments on commit c11df1a

Please sign in to comment.