From 2a002c558e923d51142ca1e4c280b2e58826b291 Mon Sep 17 00:00:00 2001 From: "Juergen E. Fischer" Date: Sun, 6 Jan 2013 04:48:37 +0100 Subject: [PATCH] [API] make primary key field indexes available: - add QgsVectorLayer::pendingPkAttributeList() - add QgsVectorDataProvider::pkAttributeIndexes() - skip primary key attribute when pasting features (fixes #6164) - default to skip primary key attribute in when merging features/attributes - reset primary key attributes to default value when splitting features (better fix for #6060) - comment out unused QgsPasteTransformations --- src/app/CMakeLists.txt | 4 +- src/app/qgisapp.cpp | 9 +++-- src/app/qgisapp.h | 2 +- src/app/qgsmergeattributesdialog.cpp | 16 +++++--- src/core/qgsvectordataprovider.h | 6 +++ src/core/qgsvectorlayer.cpp | 40 ++++++++++++++++---- src/core/qgsvectorlayer.h | 5 +++ src/providers/postgres/qgspostgresprovider.h | 4 +- 8 files changed, 66 insertions(+), 20 deletions(-) diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 60ce9f6cb874..d7745a31b2d3 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -91,7 +91,7 @@ SET(QGIS_APP_SRCS qgsmeasuretool.cpp qgsmergeattributesdialog.cpp qgsoptions.cpp - qgspastetransformations.cpp + #qgspastetransformations.cpp qgspointrotationitem.cpp qgspluginitem.cpp qgspluginmanager.cpp @@ -244,7 +244,7 @@ SET (QGIS_APP_MOC_HDRS qgsmeasuretool.h qgsmergeattributesdialog.h qgsoptions.h - qgspastetransformations.h + #qgspastetransformations.h qgspluginmanager.h qgsprojectlayergroupdialog.h qgsprojectproperties.h diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index 2b9fa08bedca..d5444395e699 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -147,7 +147,7 @@ #include "qgsmultibandcolorrenderer.h" #include "qgsnewvectorlayerdialog.h" #include "qgsoptions.h" -#include "qgspastetransformations.h" +// #include "qgspastetransformations.h" #include "qgspluginitem.h" #include "qgspluginlayer.h" #include "qgspluginlayerregistry.h" @@ -4964,11 +4964,13 @@ void QgisApp::editPaste( QgsMapLayer *destinationLayer ) QHash remap; const QgsFieldMap &fields = clipboard()->fields(); + QgsAttributeList pkAttrList = pasteVectorLayer->pendingPkAttributesList(); for ( QgsFieldMap::const_iterator it = fields.begin(); it != fields.end(); it++ ) { int dst = pasteVectorLayer->fieldNameIndex( it->name() ); - if ( dst < 0 ) + if ( dst < 0 || pkAttrList.contains( dst ) ) { + // skip primary key attributes continue; } remap.insert( it.key(), dst ); @@ -5064,6 +5066,7 @@ void QgisApp::pasteStyle( QgsMapLayer * destinationLayer ) } } +#if 0 void QgisApp::pasteTransformations() { QgsPasteTransformations *pt = new QgsPasteTransformations(); @@ -5072,7 +5075,7 @@ void QgisApp::pasteTransformations() pt->exec(); } - +#endif void QgisApp::refreshMapCanvas() { diff --git a/src/app/qgisapp.h b/src/app/qgisapp.h index 58d0963d7eb5..9f20b874de96 100644 --- a/src/app/qgisapp.h +++ b/src/app/qgisapp.h @@ -1048,7 +1048,7 @@ class QgisApp : public QMainWindow, private Ui::MainWindow //! Read Well Known Binary stream from PostGIS //void readWKB(const char *, QStringList tables); //! shows the paste-transformations dialog - void pasteTransformations(); + // void pasteTransformations(); //! check to see if file is dirty and if so, prompt the user th save it bool saveDirty(); /** Helper function to union several geometries together (used in function mergeSelectedFeatures) diff --git a/src/app/qgsmergeattributesdialog.cpp b/src/app/qgsmergeattributesdialog.cpp index 94368bbf256d..0f279cacee93 100644 --- a/src/app/qgsmergeattributesdialog.cpp +++ b/src/app/qgsmergeattributesdialog.cpp @@ -84,6 +84,7 @@ void QgsMergeAttributesDialog::createTableWidgetContents() //create combo boxes and insert attribute names const QgsFieldMap& fieldMap = mVectorLayer->pendingFields(); + QgsAttributeList pkAttrList = mVectorLayer->pendingPkAttributesList(); int col = 0; for ( QgsFieldMap::const_iterator fieldIt = fieldMap.constBegin(); @@ -96,7 +97,12 @@ void QgsMergeAttributesDialog::createTableWidgetContents() mTableWidget->setColumnCount( col + 1 ); - mTableWidget->setCellWidget( 0, col, createMergeComboBox( fieldIt->type() ) ); + QComboBox *cb = createMergeComboBox( fieldIt->type() ); + if ( pkAttrList.contains( fieldIt.key() ) ) + { + cb->setCurrentIndex( cb->findText( tr( "Skip attribute" ) ) ); + } + mTableWidget->setCellWidget( 0, col, cb ); QTableWidgetItem *item = new QTableWidgetItem( fieldIt.value().name() ); item->setData( Qt::UserRole, fieldIt.key() ); @@ -135,14 +141,14 @@ void QgsMergeAttributesDialog::createTableWidgetContents() } } -QComboBox* QgsMergeAttributesDialog::createMergeComboBox( QVariant::Type columnType ) const +QComboBox *QgsMergeAttributesDialog::createMergeComboBox( QVariant::Type columnType ) const { - QComboBox* newComboBox = new QComboBox(); + QComboBox *newComboBox = new QComboBox(); //add items for feature QgsFeatureList::const_iterator f_it = mFeatureList.constBegin(); for ( ; f_it != mFeatureList.constEnd(); ++f_it ) { - newComboBox->addItem( tr( "feature %1" ).arg( f_it->id() ) ); + newComboBox->addItem( tr( "Feature %1" ).arg( f_it->id() ) ); } if ( columnType == QVariant::Double || columnType == QVariant::Int ) @@ -183,7 +189,7 @@ int QgsMergeAttributesDialog::findComboColumn( QComboBox* c ) const void QgsMergeAttributesDialog::comboValueChanged( const QString &text ) { Q_UNUSED( text ); - QComboBox* senderComboBox = qobject_cast( sender() ); + QComboBox *senderComboBox = qobject_cast( sender() ); if ( !senderComboBox ) { return; diff --git a/src/core/qgsvectordataprovider.h b/src/core/qgsvectordataprovider.h index 077d8e1653c2..541173d9e05d 100644 --- a/src/core/qgsvectordataprovider.h +++ b/src/core/qgsvectordataprovider.h @@ -300,6 +300,12 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider */ virtual QgsAttributeList attributeIndexes(); + /** + * Return list of indexes of fields that make up the primary key + * @note added in 2.0 + */ + virtual QgsAttributeList pkAttributeIndexes() { return QgsAttributeList(); } + /** * Set whether provider should also return features that don't have * associated geometry. false by default diff --git a/src/core/qgsvectorlayer.cpp b/src/core/qgsvectorlayer.cpp index 8b46cbdd6f68..b814073cae2e 100644 --- a/src/core/qgsvectorlayer.cpp +++ b/src/core/qgsvectorlayer.cpp @@ -2513,16 +2513,13 @@ int QgsVectorLayer::splitFeatures( const QList& splitLine, bool topolo if ( mDataProvider ) { - //use default value where possible (primary key issue), otherwise the value from the original (split) feature QgsAttributeMap newAttributes = select_it->attributeMap(); - QVariant defaultValue; - foreach ( int j, newAttributes.keys() ) + + // overwrite primary key field with default values + foreach ( int idx, pendingPkAttributesList() ) { - defaultValue = mDataProvider->defaultValue( j ); - if ( !defaultValue.isNull() ) - { - newAttributes.insert( j, defaultValue ); - } + if( newAttributes.contains( idx ) ) + newAttributes.insert( idx, mDataProvider->defaultValue( idx ) ); } newFeature.setAttributeMap( newAttributes ); @@ -3890,6 +3887,21 @@ QgsAttributeList QgsVectorLayer::pendingAllAttributesList() return mUpdatedFields.keys(); } +QgsAttributeList QgsVectorLayer::pendingPkAttributesList() +{ + QgsAttributeList pkAttributesList; + + foreach ( int idx, mDataProvider->pkAttributeIndexes() ) + { + if ( !mUpdatedFields.contains( idx ) ) + continue; + + pkAttributesList << idx; + } + + return pkAttributesList; +} + int QgsVectorLayer::pendingFeatureCount() { return mDataProvider->featureCount() @@ -5792,6 +5804,18 @@ QString QgsVectorLayer::metadata() myMetadata += ""; } + QgsAttributeList pkAttrList = pendingPkAttributesList(); + if ( !pkAttrList.isEmpty() ) + { + myMetadata += ""; + myMetadata += tr( "Primary key attributes: " ); + foreach( int idx, pkAttrList ) + { + myMetadata += pendingFields()[ idx ].name() + " "; + } + myMetadata += ""; + } + //feature count myMetadata += ""; diff --git a/src/core/qgsvectorlayer.h b/src/core/qgsvectorlayer.h index af6fef28d949..286dab43f0c5 100644 --- a/src/core/qgsvectorlayer.h +++ b/src/core/qgsvectorlayer.h @@ -632,6 +632,11 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer /** returns list of attributes */ QgsAttributeList pendingAllAttributesList(); + /** returns list of attribute making up the primary key + * @note added in 2.0 + */ + QgsAttributeList pendingPkAttributesList(); + /** returns feature count after commit */ int pendingFeatureCount(); diff --git a/src/providers/postgres/qgspostgresprovider.h b/src/providers/postgres/qgspostgresprovider.h index 923b81149204..8162c9f913b8 100644 --- a/src/providers/postgres/qgspostgresprovider.h +++ b/src/providers/postgres/qgspostgresprovider.h @@ -205,6 +205,8 @@ class QgsPostgresProvider : public QgsVectorDataProvider QgsAttributeList attributeIndexes(); + QgsAttributeList pkAttributeIndexes() { return mPrimaryKeyAttrs; } + /**Returns the default value for field specified by @c fieldName */ QVariant defaultValue( QString fieldName, QString tableName = QString::null, QString schemaName = QString::null ); @@ -445,7 +447,7 @@ class QgsPostgresProvider : public QgsVectorDataProvider long layerId; }; - TopoLayerInfo mTopoLayerInfo; + TopoLayerInfo mTopoLayerInfo; bool getTopoLayerInfo();