Skip to content

Commit

Permalink
remap attribute by name not index on paste (fixes #5425)
Browse files Browse the repository at this point in the history
  • Loading branch information
jef-n committed Apr 20, 2012
1 parent a65c788 commit 46adf1a
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 81 deletions.
116 changes: 52 additions & 64 deletions src/app/qgisapp.cpp
Expand Up @@ -4282,23 +4282,16 @@ void QgisApp::editCut( QgsMapLayer * layerContainingSelection )
return;
}

QgsMapLayer *selectionLayer = layerContainingSelection ? layerContainingSelection : activeLayer();
// Test for feature support in this layer
QgsVectorLayer* selectionVectorLayer = qobject_cast<QgsVectorLayer *>( layerContainingSelection ? layerContainingSelection : activeLayer() );
if ( !selectionVectorLayer )
return;

if ( selectionLayer )
{
// Test for feature support in this layer
QgsVectorLayer* selectionVectorLayer = qobject_cast<QgsVectorLayer *>( selectionLayer );
clipboard()->replaceWithCopyOf( selectionVectorLayer );

if ( selectionVectorLayer != 0 )
{
QgsFeatureList features = selectionVectorLayer->selectedFeatures();
clipboard()->replaceWithCopyOf( selectionVectorLayer->pendingFields(), features );
clipboard()->setCRS( selectionVectorLayer->crs() );
selectionVectorLayer->beginEditCommand( tr( "Features cut" ) );
selectionVectorLayer->deleteSelectedFeatures();
selectionVectorLayer->endEditCommand();
}
}
selectionVectorLayer->beginEditCommand( tr( "Features cut" ) );
selectionVectorLayer->deleteSelectedFeatures();
selectionVectorLayer->endEditCommand();
}

void QgisApp::editCopy( QgsMapLayer * layerContainingSelection )
Expand All @@ -4308,20 +4301,12 @@ void QgisApp::editCopy( QgsMapLayer * layerContainingSelection )
return;
}

QgsMapLayer *selectionLayer = layerContainingSelection ? layerContainingSelection : activeLayer();

if ( selectionLayer )
{
// Test for feature support in this layer
QgsVectorLayer* selectionVectorLayer = qobject_cast<QgsVectorLayer *>( selectionLayer );
QgsVectorLayer* selectionVectorLayer = qobject_cast<QgsVectorLayer *>( layerContainingSelection ? layerContainingSelection : activeLayer() );
if ( !selectionVectorLayer )
return;

if ( selectionVectorLayer != 0 )
{
QgsFeatureList features = selectionVectorLayer->selectedFeatures();
clipboard()->replaceWithCopyOf( selectionVectorLayer->pendingFields(), features );
clipboard()->setCRS( selectionVectorLayer->crs() );
}
}
// Test for feature support in this layer
clipboard()->replaceWithCopyOf( selectionVectorLayer );
}


Expand All @@ -4332,51 +4317,54 @@ void QgisApp::editPaste( QgsMapLayer *destinationLayer )
return;
}

QgsMapLayer *pasteLayer = destinationLayer ? destinationLayer : activeLayer();
QgsVectorLayer *pasteVectorLayer = qobject_cast<QgsVectorLayer *>( destinationLayer ? destinationLayer : activeLayer() );
if ( !pasteVectorLayer )
return;

if ( pasteLayer )
pasteVectorLayer->beginEditCommand( tr( "Features pasted" ) );
QgsFeatureList features;
if ( mMapCanvas->mapRenderer()->hasCrsTransformEnabled() )
{
features = clipboard()->transformedCopyOf( pasteVectorLayer->crs() );
}
else
{
// Test for feature support in this layer
QgsVectorLayer* pasteVectorLayer = qobject_cast<QgsVectorLayer *>( pasteLayer );
features = clipboard()->copyOf();
}

if ( pasteVectorLayer != 0 )
QHash<int, int> remap;
const QgsFieldMap &fields = clipboard()->fields();
for ( QgsFieldMap::const_iterator it = fields.begin(); it != fields.end(); it++ )
{
int dst = pasteVectorLayer->fieldNameIndex( it->name() );
if ( dst < 0 )
{
pasteVectorLayer->beginEditCommand( tr( "Features pasted" ) );
QgsFeatureList features;
if ( mMapCanvas->mapRenderer()->hasCrsTransformEnabled() )
{
features = clipboard()->transformedCopyOf( pasteVectorLayer->crs() );
}
else
{
features = clipboard()->copyOf();
}

QgsAttributeList dstAttr = pasteVectorLayer->pendingAllAttributesList();

for ( int i = 0; i < features.size(); i++ )
{
QgsFeature &f = features[i];
QgsAttributeMap srcMap = f.attributeMap();
QgsAttributeMap dstMap;

int j = 0;
foreach( int id, srcMap.keys() )
{
if ( j >= dstAttr.size() )
break;
continue;
}
remap.insert( it.key(), dst );
}

dstMap[ dstAttr[j++] ] = srcMap[id];
}
for ( int i = 0; i < features.size(); i++ )
{
QgsFeature &f = features[i];
const QgsAttributeMap &srcMap = f.attributeMap();
QgsAttributeMap dstMap;

f.setAttributeMap( dstMap );
}
foreach( int src, srcMap.keys() )
{
int dst = remap.value( src, -1 );
if ( dst < 0 )
continue;

pasteVectorLayer->addFeatures( features );
pasteVectorLayer->endEditCommand();
mMapCanvas->refresh();
dstMap.insert( dst, srcMap[ src ] );
}

f.setAttributeMap( dstMap );
}

pasteVectorLayer->addFeatures( features );
pasteVectorLayer->endEditCommand();
mMapCanvas->refresh();
}

void QgisApp::copyStyle( QgsMapLayer * sourceLayer )
Expand Down
21 changes: 12 additions & 9 deletions src/app/qgsclipboard.cpp
Expand Up @@ -30,23 +30,31 @@
#include "qgsgeometry.h"
#include "qgscoordinatereferencesystem.h"
#include "qgslogger.h"
#include "qgsvectorlayer.h"

QgsClipboard::QgsClipboard()
: mFeatureClipboard()
, mFeatureFields()
{
}

QgsClipboard::~QgsClipboard()
{
}

void QgsClipboard::replaceWithCopyOf( const QgsFieldMap& fields, QgsFeatureList& features )
void QgsClipboard::replaceWithCopyOf( QgsVectorLayer *src )
{
if ( !src )
return;

QSettings settings;
bool copyWKT = settings.value( "qgis/copyGeometryAsWKT", true ).toBool();

// Replace the QGis clipboard.
mFeatureClipboard = features;
mFeatureFields = src->pendingFields();
mFeatureClipboard = src->selectedFeatures();
mCRS = src->crs();

QgsDebugMsg( "replaced QGis clipboard." );

// Replace the system clipboard.
Expand All @@ -59,15 +67,15 @@ void QgsClipboard::replaceWithCopyOf( const QgsFieldMap& fields, QgsFeatureList&
textFields += "wkt_geom";
}

for ( QgsFieldMap::const_iterator fit = fields.begin(); fit != fields.end(); ++fit )
for ( QgsFieldMap::const_iterator fit = mFeatureFields.begin(); fit != mFeatureFields.end(); ++fit )
{
textFields += fit->name();
}
textLines += textFields.join( "\t" );
textFields.clear();

// then the field contents
for ( QgsFeatureList::iterator it = features.begin(); it != features.end(); ++it )
for ( QgsFeatureList::iterator it = mFeatureClipboard.begin(); it != mFeatureClipboard.end(); ++it )
{
QgsAttributeMap attributes = it->attributeMap();

Expand Down Expand Up @@ -155,11 +163,6 @@ QgsFeatureList QgsClipboard::transformedCopyOf( QgsCoordinateReferenceSystem des
return featureList;
}

void QgsClipboard::setCRS( QgsCoordinateReferenceSystem crs )
{
mCRS = crs;
}

QgsCoordinateReferenceSystem QgsClipboard::crs()
{
return mCRS;
Expand Down
17 changes: 10 additions & 7 deletions src/app/qgsclipboard.h
Expand Up @@ -41,6 +41,8 @@
TODO: Make it work
*/

class QgsVectorLayer;

/*
* Constants used to describe copy-paste MIME types
*/
Expand All @@ -61,7 +63,7 @@ class QgsClipboard
* Place a copy of features on the internal clipboard,
* destroying the previous contents.
*/
void replaceWithCopyOf( const QgsFieldMap& fields, QgsFeatureList& features );
void replaceWithCopyOf( QgsVectorLayer *src );

/*
* Returns a copy of features on the internal clipboard,
Expand Down Expand Up @@ -93,11 +95,6 @@ class QgsClipboard
*/
QgsFeatureList transformedCopyOf( QgsCoordinateReferenceSystem destCRS );

/*
* Set the clipboard CRS
*/
void setCRS( QgsCoordinateReferenceSystem crs );

/*
* Get the clipboard CRS
*/
Expand Down Expand Up @@ -129,14 +126,20 @@ class QgsClipboard
* No copy is involved, since the return QByteArray is implicitly shared
*/
QByteArray data( const QString& mimeType );

/*
* source fields
*/
const QgsFieldMap &fields() { return mFeatureFields; }

private:

/** QGIS-internal vector feature clipboard.
Stored as values not pointers as each clipboard operation
involves a deep copy anyway.
*/
QgsFeatureList mFeatureClipboard;

QgsFieldMap mFeatureFields;
QgsCoordinateReferenceSystem mCRS;
};

Expand Down
2 changes: 1 addition & 1 deletion src/core/qgsvectorlayer.cpp
Expand Up @@ -4018,7 +4018,7 @@ QgsFeatureList QgsVectorLayer::selectedFeatures()
foreach( QgsFeatureId fid, mSelectedFeatureIds )
{
features.push_back( QgsFeature() );
featureAtId( fid, features.back(), true, true );
featureAtId( fid, features.back(), geometryType() != QGis::NoGeometry, true );
}

return features;
Expand Down

0 comments on commit 46adf1a

Please sign in to comment.