Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Implement basic copy/paste of styles between layers

  • Loading branch information...
commit 6b54dff90c45b08c676df2192e3f82006dd77b73 1 parent 23d5362
Hugo Mercier authored April 15, 2012
11  src/app/legend/qgslegend.cpp
@@ -42,6 +42,7 @@
42 42
 #include <QMouseEvent>
43 43
 #include <QPixmap>
44 44
 #include <QTreeWidgetItem>
  45
+#include <QClipboard>
45 46
 
46 47
 const int AUTOSCROLL_MARGIN = 16;
47 48
 
@@ -697,6 +698,16 @@ void QgsLegend::handleRightClickEvent( QTreeWidgetItem* item, const QPoint& posi
697 698
     // ends here
698 699
   }
699 700
 
  701
+  if ( selectedLayers().length() == 1 )
  702
+  {
  703
+    QgisApp* app = QgisApp::instance();
  704
+    theMenu.addAction( tr( "Copy Style" ), app, SLOT( copyStyle() ) );
  705
+    if ( QApplication::clipboard()->mimeData()->hasFormat( "application/qgis.style" ) )
  706
+    {
  707
+      theMenu.addAction( tr( "Paste Style" ), app, SLOT( pasteStyle() ) );
  708
+    }
  709
+  }
  710
+
700 711
   theMenu.addAction( QgisApp::getThemeIcon( "/folder_new.png" ), tr( "&Add New Group" ), this, SLOT( addGroupToCurrentItem() ) );
701 712
   theMenu.addAction( QgisApp::getThemeIcon( "/mActionExpandTree.png" ), tr( "&Expand All" ), this, SLOT( expandAll() ) );
702 713
   theMenu.addAction( QgisApp::getThemeIcon( "/mActionCollapseTree.png" ), tr( "&Collapse All" ), this, SLOT( collapseAll() ) );
78  src/app/qgisapp.cpp
@@ -824,6 +824,8 @@ void QgisApp::createActions()
824 824
   connect( mActionCutFeatures, SIGNAL( triggered() ), this, SLOT( editCut() ) );
825 825
   connect( mActionCopyFeatures, SIGNAL( triggered() ), this, SLOT( editCopy() ) );
826 826
   connect( mActionPasteFeatures, SIGNAL( triggered() ), this, SLOT( editPaste() ) );
  827
+  connect( mActionCopyStyle, SIGNAL( triggered() ), this, SLOT( copyStyle() ) );
  828
+  connect( mActionPasteStyle, SIGNAL( triggered() ), this, SLOT( pasteStyle() ) );
827 829
   connect( mActionAddFeature, SIGNAL( triggered() ), this, SLOT( addFeature() ) );
828 830
   connect( mActionMoveFeature, SIGNAL( triggered() ), this, SLOT( moveFeature() ) );
829 831
   connect( mActionReshapeFeatures, SIGNAL( triggered() ), this, SLOT( reshapeFeatures() ) );
@@ -4294,7 +4296,6 @@ void QgisApp::editCut( QgsMapLayer * layerContainingSelection )
4294 4296
   }
4295 4297
 }
4296 4298
 
4297  
-
4298 4299
 void QgisApp::editCopy( QgsMapLayer * layerContainingSelection )
4299 4300
 {
4300 4301
   if ( mMapCanvas && mMapCanvas->isDrawing() )
@@ -4373,6 +4374,76 @@ void QgisApp::editPaste( QgsMapLayer *destinationLayer )
4373 4374
   }
4374 4375
 }
4375 4376
 
  4377
+void QgisApp::copyStyle( QgsMapLayer * sourceLayer )
  4378
+{
  4379
+  QgsMapLayer *selectionLayer = sourceLayer ? sourceLayer : activeLayer();
  4380
+  if ( selectionLayer )
  4381
+  {
  4382
+    QDomImplementation DomImplementation;
  4383
+    QDomDocumentType documentType =
  4384
+      DomImplementation.createDocumentType(
  4385
+					   "qgis", "http://mrcc.com/qgis.dtd", "SYSTEM" );
  4386
+    QDomDocument doc( documentType );
  4387
+    QDomElement rootNode = doc.createElement( "qgis" );
  4388
+    rootNode.setAttribute( "version", QString( "%1" ).arg( QGis::QGIS_VERSION ) );
  4389
+    doc.appendChild( rootNode );
  4390
+    QString errorMsg;
  4391
+    if ( !selectionLayer->writeSymbology( rootNode, doc, errorMsg ) )
  4392
+    {
  4393
+      QMessageBox::warning( this,
  4394
+			    tr( "Error" ),
  4395
+			    tr( "Cannot copy style: %1" )
  4396
+			    .arg( errorMsg ),
  4397
+			    QMessageBox::Ok );
  4398
+      return;
  4399
+    }
  4400
+    QClipboard* clipboard = QApplication::clipboard();
  4401
+    QMimeData *mimeData = new QMimeData();
  4402
+    mimeData->setData( "application/qgis.style", doc.toByteArray() );
  4403
+    // transfers the ownership to the clipboard object
  4404
+    clipboard->setMimeData( mimeData );
  4405
+  }
  4406
+}
  4407
+
  4408
+void QgisApp::pasteStyle( QgsMapLayer * destinationLayer )
  4409
+{
  4410
+  QgsMapLayer *selectionLayer = destinationLayer ? destinationLayer : activeLayer();
  4411
+  if ( selectionLayer )
  4412
+  {
  4413
+    QClipboard* clipboard = QApplication::clipboard();
  4414
+
  4415
+    const QMimeData* mimeData = clipboard->mimeData();
  4416
+    if ( mimeData->hasFormat( "application/qgis.style" ) )
  4417
+    {
  4418
+      QDomDocument doc( "qgis" );
  4419
+      QString errorMsg;
  4420
+      int errorLine, errorColumn;
  4421
+      if ( !doc.setContent ( mimeData->data( "application/qgis.style" ), false, &errorMsg, &errorLine, &errorColumn ) )
  4422
+      {
  4423
+	QMessageBox::information( this,
  4424
+				  tr( "Error" ),
  4425
+				  tr( "Cannot parse style: %1:%2:%3" )
  4426
+				  .arg( errorMsg )
  4427
+				  .arg( errorLine )
  4428
+				  .arg( errorColumn ),
  4429
+				  QMessageBox::Ok );
  4430
+	return;
  4431
+      }
  4432
+      QDomElement rootNode = doc.firstChildElement( "qgis" );
  4433
+      if ( !selectionLayer->readSymbology( rootNode, errorMsg ) )
  4434
+      {
  4435
+	QMessageBox::information( this,
  4436
+				  tr( "Error" ),
  4437
+				  tr( "Cannot read style: %1" )
  4438
+				  .arg( errorMsg ),
  4439
+				  QMessageBox::Ok );
  4440
+	return;
  4441
+      }
  4442
+
  4443
+      mMapLegend->refreshLayerSymbology( selectionLayer->id(), false );
  4444
+    }
  4445
+  }
  4446
+}
4376 4447
 
4377 4448
 void QgisApp::pasteTransformations()
4378 4449
 {
@@ -6296,6 +6367,8 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
6296 6367
     mActionCutFeatures->setEnabled( false );
6297 6368
     mActionCopyFeatures->setEnabled( false );
6298 6369
     mActionPasteFeatures->setEnabled( false );
  6370
+    mActionCopyStyle->setEnabled( false );
  6371
+    mActionPasteStyle->setEnabled( false );
6299 6372
 
6300 6373
     mActionUndo->setEnabled( false );
6301 6374
     mActionRedo->setEnabled( false );
@@ -6326,6 +6399,9 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
6326 6399
   mActionAddToOverview->setEnabled( true );
6327 6400
   mActionZoomToLayer->setEnabled( true );
6328 6401
 
  6402
+  mActionCopyStyle->setEnabled( true );
  6403
+  mActionPasteStyle->setEnabled( QApplication::clipboard()->mimeData()->hasFormat( "application/qgis.style" ) );
  6404
+
6329 6405
   /***********Vector layers****************/
6330 6406
   if ( layer->type() == QgsMapLayer::VectorLayer )
6331 6407
   {
11  src/app/qgisapp.h
@@ -429,6 +429,17 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
429 429
      */
430 430
     void editPaste( QgsMapLayer * destinationLayer = 0 );
431 431
 
  432
+    /**
  433
+       \param sourceLayer  The layer where the style will be taken from
  434
+                                        (defaults to the active layer on the legend)
  435
+     */
  436
+    void copyStyle( QgsMapLayer * sourceLayer = 0 );
  437
+    //! copies style on the clipboard to the active layer
  438
+    /**
  439
+       \param destinatioLayer  The layer that the clipboard will be pasted to
  440
+                                (defaults to the active layer on the legend)
  441
+     */
  442
+    void pasteStyle( QgsMapLayer * destinationLayer = 0 );
432 443
     void loadOGRSublayers( QString layertype, QString uri, QStringList list );
433 444
     void loadGDALSublayers( QString uri, QStringList list );
434 445
 
23  src/ui/qgisapp.ui
@@ -17,7 +17,7 @@
17 17
      <x>0</x>
18 18
      <y>0</y>
19 19
      <width>1052</width>
20  
-     <height>21</height>
  20
+     <height>25</height>
21 21
     </rect>
22 22
    </property>
23 23
    <widget class="QMenu" name="mEditMenu">
@@ -152,6 +152,9 @@
152 152
     <addaction name="mActionAddLayerSeparator"/>
153 153
     <addaction name="mActionAddWfsLayer"/>
154 154
     <addaction name="separator"/>
  155
+    <addaction name="mActionCopyStyle"/>
  156
+    <addaction name="mActionPasteStyle"/>
  157
+    <addaction name="separator"/>
155 158
     <addaction name="mActionOpenTable"/>
156 159
     <addaction name="mActionSaveEdits"/>
157 160
     <addaction name="mActionToggleEditing"/>
@@ -1648,6 +1651,24 @@
1648 1651
     <string>Offset Curve</string>
1649 1652
    </property>
1650 1653
   </action>
  1654
+  <action name="mActionCopyStyle">
  1655
+   <property name="icon">
  1656
+    <iconset resource="../../images/images.qrc">
  1657
+     <normaloff>:/images/themes/default/mActionEditCopy.png</normaloff>:/images/themes/default/mActionEditCopy.png</iconset>
  1658
+   </property>
  1659
+   <property name="text">
  1660
+    <string>Copy style</string>
  1661
+   </property>
  1662
+  </action>
  1663
+  <action name="mActionPasteStyle">
  1664
+   <property name="icon">
  1665
+    <iconset resource="../../images/images.qrc">
  1666
+     <normaloff>:/images/themes/default/mActionEditPaste.png</normaloff>:/images/themes/default/mActionEditPaste.png</iconset>
  1667
+   </property>
  1668
+   <property name="text">
  1669
+    <string>Paste style</string>
  1670
+   </property>
  1671
+  </action>
1651 1672
  </widget>
1652 1673
  <resources>
1653 1674
   <include location="../../images/images.qrc"/>

0 notes on commit 6b54dff

Please sign in to comment.
Something went wrong with that request. Please try again.