[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