Skip to content

Commit

Permalink
[FEATURE][needs-docs] Copy&Paste Group/Layers
Browse files Browse the repository at this point in the history
  • Loading branch information
slarosa committed Mar 18, 2018
1 parent 9e01a04 commit 3d7a460
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 7 deletions.
62 changes: 56 additions & 6 deletions src/app/qgisapp.cpp
Expand Up @@ -1913,6 +1913,8 @@ void QgisApp::createActions()
connect( mActionPasteAsNewMemoryVector, &QAction::triggered, this, [ = ] { pasteAsNewMemoryVector(); } );
connect( mActionCopyStyle, &QAction::triggered, this, [ = ] { copyStyle(); } );
connect( mActionPasteStyle, &QAction::triggered, this, [ = ] { pasteStyle(); } );
connect( mActionCopyLayer, &QAction::triggered, this, [ = ] { copyLayer(); } );
connect( mActionPasteLayer, &QAction::triggered, this, [ = ] { pasteLayer(); } );
connect( mActionAddFeature, &QAction::triggered, this, &QgisApp::addFeature );
connect( mActionCircularStringCurvePoint, &QAction::triggered, this, [ = ] { setMapTool( mMapTools.mCircularStringCurvePoint ); } );
connect( mActionCircularStringRadius, &QAction::triggered, this, [ = ] { setMapTool( mMapTools.mCircularStringRadius ); } );
Expand Down Expand Up @@ -8517,12 +8519,6 @@ void QgisApp::copyStyle( QgsMapLayer *sourceLayer )
}
}

/**
\param destinationLayer The layer that the clipboard will be pasted to
(defaults to the active layer on the legend)
*/


void QgisApp::pasteStyle( QgsMapLayer *destinationLayer )
{
QgsMapLayer *selectionLayer = destinationLayer ? destinationLayer : activeLayer();
Expand Down Expand Up @@ -8563,6 +8559,56 @@ void QgisApp::pasteStyle( QgsMapLayer *destinationLayer )
}
}

void QgisApp::copyLayer()
{
QString errorMessage;
QgsReadWriteContext readWriteContext;
QDomDocument doc( QStringLiteral( "qgis-layer-definition" ) );

bool saved = QgsLayerDefinition::exportLayerDefinition( doc, mLayerTreeView->selectedNodes(), errorMessage, readWriteContext );

if ( !saved )
{
messageBar()->pushMessage( tr( "Error copying layer" ), errorMessage, Qgis::Warning );
}

// Copies data in text form as well, so the XML can be pasted into a text editor
clipboard()->setData( QGSCLIPBOARD_MAPLAYER_MIME, doc.toByteArray(), doc.toString() );
// Enables the paste menu element
mActionPasteLayer->setEnabled( true );
}

void QgisApp::pasteLayer()
{
if ( clipboard()->hasFormat( QGSCLIPBOARD_MAPLAYER_MIME ) )
{
QDomDocument doc;
QString errorMessage;
QgsReadWriteContext readWriteContext;
doc.setContent( clipboard()->data( QGSCLIPBOARD_MAPLAYER_MIME ) );

QgsLayerTreeNode *currentNode = mLayerTreeView->currentNode();
QgsLayerTreeGroup *root = nullptr;
if ( QgsLayerTree::isGroup( currentNode ) )
{
root = QgsLayerTree::toGroup( currentNode );
}
else
{
root = QgsProject::instance()->layerTreeRoot();
}

bool loaded = QgsLayerDefinition::loadLayerDefinition( doc, QgsProject::instance(), root,
errorMessage, readWriteContext );

if ( !loaded )
{
QgsDebugMsg( errorMessage );
messageBar()->pushMessage( tr( "Error pasting layer" ), errorMessage, Qgis::Warning );
}
}
}

void QgisApp::copyFeatures( QgsFeatureStore &featureStore )
{
clipboard()->replaceWithCopyOf( featureStore );
Expand Down Expand Up @@ -11543,6 +11589,8 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer )
mActionPasteFeatures->setEnabled( false );
mActionCopyStyle->setEnabled( false );
mActionPasteStyle->setEnabled( false );
mActionCopyLayer->setEnabled( false );
mActionPasteLayer->setEnabled( false );

mUndoDock->widget()->setEnabled( false );
mActionUndo->setEnabled( false );
Expand Down Expand Up @@ -11589,6 +11637,8 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer )

mActionCopyStyle->setEnabled( true );
mActionPasteStyle->setEnabled( clipboard()->hasFormat( QGSCLIPBOARD_STYLE_MIME ) );
mActionCopyLayer->setEnabled( true );
mActionPasteLayer->setEnabled( clipboard()->hasFormat( QGSCLIPBOARD_MAPLAYER_MIME ) );

/***********Vector layers****************/
if ( layer->type() == QgsMapLayer::VectorLayer )
Expand Down
4 changes: 4 additions & 0 deletions src/app/qgisapp.h
Expand Up @@ -821,6 +821,10 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
(defaults to the active layer on the legend)
*/
void pasteStyle( QgsMapLayer *destinationLayer = nullptr );
//! copies group or layer on the clipboard
void copyLayer();
//! pastes group or layer from the clipboard to layer tree
void pasteLayer();

//! copies features to internal clipboard
void copyFeatures( QgsFeatureStore &featureStore );
Expand Down
9 changes: 9 additions & 0 deletions src/app/qgsapplayertreeviewmenuprovider.cpp
Expand Up @@ -56,6 +56,8 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu()
{
// global menu
menu->addAction( actions->actionAddGroup( menu ) );
menu->addAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionEditPaste.svg" ) ),
tr( "Paste Layer/Group" ), QgisApp::instance(), SLOT( pasteLayer() ) );

menu->addAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionExpandTree.svg" ) ), tr( "&Expand All" ), mView, SLOT( expandAll() ) );
menu->addAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionCollapseTree.svg" ) ), tr( "&Collapse All" ), mView, SLOT( collapseAll() ) );
Expand Down Expand Up @@ -92,6 +94,12 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu()
menu->addAction( tr( "Paste Style" ), QgisApp::instance(), SLOT( applyStyleToGroup() ) );
}

menu->addAction( tr( "Copy Group" ), QgisApp::instance(), SLOT( copyLayer() ) );
if ( QgisApp::instance()->clipboard()->hasFormat( QGSCLIPBOARD_MAPLAYER_MIME ) )
{
menu->addAction( tr( "Paste Layer/Group" ), QgisApp::instance(), SLOT( pasteLayer() ) );
}

menu->addAction( tr( "Save As Layer Definition File…" ), QgisApp::instance(), SLOT( saveAsLayerDefinition() ) );

menu->addAction( actions->actionAddGroup( menu ) );
Expand Down Expand Up @@ -207,6 +215,7 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu()
}

menu->addSeparator();
menu->addAction( tr( "Copy Layer" ), QgisApp::instance(), SLOT( copyLayer() ) );

if ( vlayer )
{
Expand Down
5 changes: 5 additions & 0 deletions src/core/qgsmaplayer.h
Expand Up @@ -48,6 +48,11 @@ class QDomDocument;
class QKeyEvent;
class QPainter;

/*
* Constants used to describe copy-paste MIME types
*/
#define QGSCLIPBOARD_MAPLAYER_MIME "application/qgis.layer"

/**
* \ingroup core
* Base class for all map layer types.
Expand Down
23 changes: 22 additions & 1 deletion src/ui/qgisapp.ui
Expand Up @@ -17,7 +17,7 @@
<x>0</x>
<y>0</y>
<width>1030</width>
<height>28</height>
<height>22</height>
</rect>
</property>
<property name="toolTip">
Expand Down Expand Up @@ -173,6 +173,9 @@
<addaction name="mActionCopyStyle"/>
<addaction name="mActionPasteStyle"/>
<addaction name="separator"/>
<addaction name="mActionCopyLayer"/>
<addaction name="mActionPasteLayer"/>
<addaction name="separator"/>
<addaction name="mActionOpenTable"/>
<addaction name="mActionToggleEditing"/>
<addaction name="mActionSaveLayerEdits"/>
Expand Down Expand Up @@ -2983,6 +2986,24 @@ Acts on currently active editable layer</string>
<string>Revert Project to Saved version</string>
</property>
</action>
<action name="mActionCopyLayer">
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mActionEditCopy.svg</normaloff>:/images/themes/default/mActionEditCopy.svg</iconset>
</property>
<property name="text">
<string>Copy Layer</string>
</property>
</action>
<action name="mActionPasteLayer">
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mActionEditPaste.svg</normaloff>:/images/themes/default/mActionEditPaste.svg</iconset>
</property>
<property name="text">
<string>Paste Layer</string>
</property>
</action>
</widget>
<resources>
<include location="../../images/images.qrc"/>
Expand Down

0 comments on commit 3d7a460

Please sign in to comment.