[QGIS Commit] r12869 - in trunk/qgis/src: app/attributetable core
providers/grass providers/ogr providers/postgres
providers/spatialite
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Wed Feb 3 19:18:16 EST 2010
Author: jef
Date: 2010-02-03 19:18:15 -0500 (Wed, 03 Feb 2010)
New Revision: 12869
Modified:
trunk/qgis/src/app/attributetable/qgsattributetablemodel.cpp
trunk/qgis/src/app/attributetable/qgsattributetablemodel.h
trunk/qgis/src/core/qgsfeature.cpp
trunk/qgis/src/core/qgsfeature.h
trunk/qgis/src/core/qgsvectorlayer.cpp
trunk/qgis/src/core/qgsvectorlayer.h
trunk/qgis/src/providers/grass/qgsgrassprovider.cpp
trunk/qgis/src/providers/ogr/qgsogrprovider.cpp
trunk/qgis/src/providers/postgres/qgspostgresprovider.cpp
trunk/qgis/src/providers/spatialite/qgsspatialiteprovider.cpp
Log:
fix #2397 by clearing attribute maps when retrieving features
Modified: trunk/qgis/src/app/attributetable/qgsattributetablemodel.cpp
===================================================================
--- trunk/qgis/src/app/attributetable/qgsattributetablemodel.cpp 2010-02-03 16:44:29 UTC (rev 12868)
+++ trunk/qgis/src/app/attributetable/qgsattributetablemodel.cpp 2010-02-04 00:18:15 UTC (rev 12869)
@@ -32,16 +32,12 @@
QgsAttributeTableModel::QgsAttributeTableModel( QgsVectorLayer *theLayer, QObject *parent )
: QAbstractTableModel( parent )
{
- mLastRowId = -1;
- mLastRow = NULL;
mLayer = theLayer;
mFeatureCount = mLayer->pendingFeatureCount();
loadAttributes();
connect( mLayer, SIGNAL( layerModified( bool ) ), this, SLOT( layerModified( bool ) ) );
- //connect(mLayer, SIGNAL(attributeAdded(int)), this, SLOT( attributeAdded(int)));
- //connect(mLayer, SIGNAL(attributeDeleted(int)), this, SLOT( attributeDeleted(int)));
//connect(mLayer, SIGNAL(attributeValueChanged(int, int, const QVariant&)), this, SLOT( attributeValueChanged(int, int, const QVariant&)));
//connect(mLayer, SIGNAL(featureDeleted(int)), this, SLOT( featureDeleted(int)));
//connect(mLayer, SIGNAL(featureAdded(int)), this, SLOT( featureAdded(int)));
@@ -49,7 +45,7 @@
loadLayer();
}
-bool QgsAttributeTableModel::featureAtId( int fid )
+bool QgsAttributeTableModel::featureAtId( int fid ) const
{
return mLayer->featureAtId( fid, mFeat, false, true );
}
@@ -201,14 +197,12 @@
QgsDebugMsg( "ins" );
ins = true;
beginInsertRows( QModelIndex(), mFeatureCount, pendingFeatureCount - 1 );
-// QgsDebugMsg(QString("%1, %2").arg(mFeatureCount).arg(mLayer->pendingFeatureCount() - 1));
}
else if ( mFeatureCount > pendingFeatureCount )
{
QgsDebugMsg( "rm" );
rm = true;
beginRemoveRows( QModelIndex(), pendingFeatureCount, mFeatureCount - 1 );
-// QgsDebugMsg(QString("%1, %2").arg(mFeatureCount).arg(mLayer->pendingFeatureCount() -1));
}
mLayer->select( mAttributes, QgsRectangle(), false );
@@ -369,15 +363,12 @@
QVariant QgsAttributeTableModel::data( const QModelIndex &index, int role ) const
{
- return (( QgsAttributeTableModel * ) this )->data( index, role );
-}
-
-QVariant QgsAttributeTableModel::data( const QModelIndex &index, int role )
-{
if ( !index.isValid() || ( role != Qt::TextAlignmentRole && role != Qt::DisplayRole && role != Qt::EditRole ) )
return QVariant();
- QVariant::Type fldType = mLayer->pendingFields()[ mAttributes[index.column()] ].type();
+ int fieldId = mAttributes[ index.column()];
+
+ QVariant::Type fldType = mLayer->pendingFields()[ fieldId ].type();
bool fldNumeric = ( fldType == QVariant::Int || fldType == QVariant::Double );
if ( role == Qt::TextAlignmentRole )
@@ -389,21 +380,17 @@
}
// if we don't have the row in current cache, load it from layer first
- if ( mLastRowId != rowToId( index.row() ) )
+ int rowId = rowToId( index.row() );
+ if ( mFeat.id() != rowId )
{
- bool res = featureAtId( rowToId( index.row() ) );
-
- if ( !res )
+ if ( !featureAtId( rowId ) )
return QVariant( "ERROR" );
-
- mLastRowId = rowToId( index.row() );
- mLastRow = ( QgsAttributeMap * ) & mFeat.attributeMap();
}
- if ( !mLastRow )
+ if ( mFeat.id() != rowId )
return QVariant( "ERROR" );
- const QVariant &val = ( *mLastRow )[ mAttributes[index.column()] ];
+ const QVariant &val = mFeat.attributeMap()[ fieldId ];
if ( val.isNull() )
{
@@ -428,26 +415,21 @@
bool QgsAttributeTableModel::setData( const QModelIndex &index, const QVariant &value, int role )
{
- if ( !index.isValid() || role != Qt::EditRole )
+ if ( !index.isValid() || role != Qt::EditRole || !mLayer->isEditable() )
return false;
- if ( !mLayer->isEditable() )
- return false;
-
- bool res = featureAtId( rowToId( index.row() ) );
-
- if ( res )
+ int rowId = rowToId( index.row() );
+ if ( mFeat.id() == rowId || featureAtId( rowId ) )
{
- mLastRowId = rowToId( index.row() );
- mLastRow = ( QgsAttributeMap * ) & mFeat.attributeMap();
+ int fieldId = mAttributes[ index.column()];
disconnect( mLayer, SIGNAL( layerModified( bool ) ), this, SLOT( layerModified( bool ) ) );
mLayer->beginEditCommand( tr( "Attribute changed" ) );
- mLayer->changeAttributeValue( rowToId( index.row() ), mAttributes[ index.column()], value, true );
+ mLayer->changeAttributeValue( rowId, fieldId, value, true );
mLayer->endEditCommand();
- ( *mLastRow )[ mAttributes[index.column()] ] = value;
+ mFeat.changeAttribute( fieldId, value );
connect( mLayer, SIGNAL( layerModified( bool ) ), this, SLOT( layerModified( bool ) ) );
}
@@ -456,6 +438,7 @@
return false;
emit dataChanged( index, index );
+
return true;
}
@@ -466,7 +449,8 @@
Qt::ItemFlags flags = QAbstractItemModel::flags( index );
- if ( mLayer->isEditable() )
+ if ( mLayer->isEditable() &&
+ mLayer->editType( mAttributes[ index.column()] ) != QgsVectorLayer::Immutable )
flags |= Qt::ItemIsEditable;
return flags;
Modified: trunk/qgis/src/app/attributetable/qgsattributetablemodel.h
===================================================================
--- trunk/qgis/src/app/attributetable/qgsattributetablemodel.h 2010-02-03 16:44:29 UTC (rev 12868)
+++ trunk/qgis/src/app/attributetable/qgsattributetablemodel.h 2010-02-04 00:18:15 UTC (rev 12869)
@@ -185,10 +185,9 @@
QgsVectorLayer *mLayer;
int mFeatureCount;
int mFieldCount;
- mutable int mLastRowId;
+
mutable QgsFeature mFeat;
- mutable QgsAttributeMap *mLastRow;
QgsAttributeList mAttributes;
QMap< int, const QMap<QString, QVariant> * > mValueMaps;
@@ -200,6 +199,7 @@
* Initializes id <-> row maps
*/
void initIdMaps();
+
/**
* Loads the layer into the model
*/
@@ -215,9 +215,7 @@
* @param fid feature id
* @return feature exists
*/
- virtual bool featureAtId( int fid );
-
- QVariant data( const QModelIndex &index, int role );
+ virtual bool featureAtId( int fid ) const;
};
Modified: trunk/qgis/src/core/qgsfeature.cpp
===================================================================
--- trunk/qgis/src/core/qgsfeature.cpp 2010-02-03 16:44:29 UTC (rev 12868)
+++ trunk/qgis/src/core/qgsfeature.cpp 2010-02-04 00:18:15 UTC (rev 12869)
@@ -109,6 +109,12 @@
mAttributes = attributes;
}
+/**Clear attribute map for this feature*/
+void QgsFeature::clearAttributeMap()
+{
+ mAttributes.clear();
+}
+
/**
* Add an attribute to the map
*/
Modified: trunk/qgis/src/core/qgsfeature.h
===================================================================
--- trunk/qgis/src/core/qgsfeature.h 2010-02-03 16:44:29 UTC (rev 12868)
+++ trunk/qgis/src/core/qgsfeature.h 2010-02-04 00:18:15 UTC (rev 12869)
@@ -93,6 +93,11 @@
/**Sets all the attributes in one go*/
void setAttributeMap( const QgsAttributeMap& attributeMap );
+ /** Clear attribute map
+ * added in 1.5
+ */
+ void clearAttributeMap();
+
/**
* Add an attribute to the map
*/
Modified: trunk/qgis/src/core/qgsvectorlayer.cpp
===================================================================
--- trunk/qgis/src/core/qgsvectorlayer.cpp 2010-02-03 16:44:29 UTC (rev 12868)
+++ trunk/qgis/src/core/qgsvectorlayer.cpp 2010-02-04 00:18:15 UTC (rev 12869)
@@ -1434,7 +1434,7 @@
return res;
}
-void QgsVectorLayer::updateFeatureAttributes( QgsFeature &f )
+void QgsVectorLayer::updateFeatureAttributes( QgsFeature &f, bool all )
{
// do not update when we aren't in editing mode
if ( !mEditable )
@@ -1455,7 +1455,7 @@
// null/add all attributes that were added, but don't exist in the feature yet
for ( QgsFieldMap::const_iterator it = mUpdatedFields.begin(); it != mUpdatedFields.end(); it++ )
- if ( !map.contains( it.key() ) )
+ if ( !map.contains( it.key() ) && ( all || mFetchAttributes.contains( it.key() ) ) )
f.changeAttribute( it.key(), QVariant( QString::null ) );
}
@@ -1490,16 +1490,16 @@
if ( mEditable )
{
// fetch only available field from provider
- QgsAttributeList provAttributes;
+ mFetchProvAttributes.clear();
for ( QgsAttributeList::iterator it = mFetchAttributes.begin(); it != mFetchAttributes.end(); it++ )
{
if ( !mUpdatedFields.contains( *it ) || mAddedAttributeIds.contains( *it ) )
continue;
- provAttributes << *it;
+ mFetchProvAttributes << *it;
}
- mDataProvider->select( provAttributes, rect, fetchGeometries, useIntersect );
+ mDataProvider->select( mFetchProvAttributes, rect, fetchGeometries, useIntersect );
}
else
mDataProvider->select( mFetchAttributes, rect, fetchGeometries, useIntersect );
@@ -1564,7 +1564,7 @@
{
// retrieve attributes from provider
QgsFeature tmp;
- mDataProvider->featureAtId( fid, tmp, false, mDataProvider->attributeIndexes() );
+ mDataProvider->featureAtId( fid, tmp, false, mFetchProvAttributes );
updateFeatureAttributes( tmp );
f.setAttributeMap( tmp.attributeMap() );
}
@@ -1666,10 +1666,9 @@
// retrieve attributes from provider
QgsFeature tmp;
mDataProvider->featureAtId( featureId, tmp, false, mDataProvider->attributeIndexes() );
- updateFeatureAttributes( tmp );
f.setAttributeMap( tmp.attributeMap() );
}
- updateFeatureAttributes( f );
+ updateFeatureAttributes( f, true );
}
return true;
}
@@ -1696,7 +1695,7 @@
{
if ( mDataProvider->featureAtId( featureId, f, fetchGeometries, mDataProvider->attributeIndexes() ) )
{
- updateFeatureAttributes( f );
+ updateFeatureAttributes( f, true );
return true;
}
}
Modified: trunk/qgis/src/core/qgsvectorlayer.h
===================================================================
--- trunk/qgis/src/core/qgsvectorlayer.h 2010-02-03 16:44:29 UTC (rev 12868)
+++ trunk/qgis/src/core/qgsvectorlayer.h 2010-02-04 00:18:15 UTC (rev 12869)
@@ -643,7 +643,7 @@
static int currentVertexMarkerSize();
/**Update feature with uncommited attribute updates*/
- void updateFeatureAttributes( QgsFeature &f );
+ void updateFeatureAttributes( QgsFeature &f, bool all = false );
/**Update feature with uncommited geometry updates*/
void updateFeatureGeometry( QgsFeature &f );
@@ -774,6 +774,7 @@
bool mFetching;
QgsRectangle mFetchRect;
QgsAttributeList mFetchAttributes;
+ QgsAttributeList mFetchProvAttributes;
bool mFetchGeometry;
QSet<int> mFetchConsidered;
Modified: trunk/qgis/src/providers/grass/qgsgrassprovider.cpp
===================================================================
--- trunk/qgis/src/providers/grass/qgsgrassprovider.cpp 2010-02-03 16:44:29 UTC (rev 12868)
+++ trunk/qgis/src/providers/grass/qgsgrassprovider.cpp 2010-02-04 00:18:15 UTC (rev 12869)
@@ -327,6 +327,7 @@
#endif
feature.setFeatureId( id );
+ feature.clearAttributeMap();
// TODO int may be 64 bits (memcpy)
if ( type & ( GV_POINTS | GV_LINES ) ) /* points or lines */
@@ -491,7 +492,7 @@
Polygon = Vect_new_line_struct();
- // Using z coor -PORT_DOUBLE_MAX/PORT_DOUBLE_MAX we cover 3D, Vect_select_lines_by_polygon is
+ // Using z coor -PORT_DOUBLE_MAX/PORT_DOUBLE_MAX we cover 3D, Vect_select_lines_by_polygon is
// using dig_line_box to get the box, it is not perfect, Vect_select_lines_by_polygon
// should clarify better how 2D/3D is treated
Vect_append_point( Polygon, rect.xMinimum(), rect.yMinimum(), -PORT_DOUBLE_MAX );
Modified: trunk/qgis/src/providers/ogr/qgsogrprovider.cpp
===================================================================
--- trunk/qgis/src/providers/ogr/qgsogrprovider.cpp 2010-02-03 16:44:29 UTC (rev 12868)
+++ trunk/qgis/src/providers/ogr/qgsogrprovider.cpp 2010-02-04 00:18:15 UTC (rev 12869)
@@ -387,6 +387,7 @@
return false;
feature.setFeatureId( OGR_F_GetFID( fet ) );
+ feature.clearAttributeMap();
// skip features without geometry
if ( OGR_F_GetGeometryRef( fet ) == NULL && !mFetchFeaturesWithoutGeom )
{
@@ -451,6 +452,7 @@
OGRFeatureDefnH featureDefinition = OGR_F_GetDefnRef( fet );
QString featureTypeName = featureDefinition ? QString( OGR_FD_GetName( featureDefinition ) ) : QString( "" );
feature.setFeatureId( OGR_F_GetFID( fet ) );
+ feature.clearAttributeMap();
feature.setTypeName( featureTypeName );
/* fetch geometry */
Modified: trunk/qgis/src/providers/postgres/qgspostgresprovider.cpp
===================================================================
--- trunk/qgis/src/providers/postgres/qgspostgresprovider.cpp 2010-02-03 16:44:29 UTC (rev 12868)
+++ trunk/qgis/src/providers/postgres/qgspostgresprovider.cpp 2010-02-04 00:18:15 UTC (rev 12869)
@@ -553,6 +553,7 @@
}
feature.setFeatureId( oid );
+ feature.clearAttributeMap();
int col; // first attribute column after geometry
Modified: trunk/qgis/src/providers/spatialite/qgsspatialiteprovider.cpp
===================================================================
--- trunk/qgis/src/providers/spatialite/qgsspatialiteprovider.cpp 2010-02-03 16:44:29 UTC (rev 12868)
+++ trunk/qgis/src/providers/spatialite/qgsspatialiteprovider.cpp 2010-02-04 00:18:15 UTC (rev 12869)
@@ -258,6 +258,8 @@
feature.setGeometryAndOwnership( 0, 0 );
}
+ feature.clearAttributeMap();
+
int ic;
int n_columns = sqlite3_column_count( stmt );
for ( ic = 0; ic < n_columns; ic++ )
@@ -380,6 +382,8 @@
feature.setGeometryAndOwnership( 0, 0 );
}
+ feature.clearAttributeMap();
+
int ic;
int n_columns = sqlite3_column_count( sqliteStatement );
for ( ic = 0; ic < n_columns; ic++ )
More information about the QGIS-commit
mailing list