QGIS API Documentation  2.4.0-Chugiak
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgsattributetablemodel.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  QgsAttributeTableModel.cpp
3  --------------------------------------
4  Date : Feb 2009
5  Copyright : (C) 2009 Vita Cizek
6  Email : weetya (at) gmail.com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsapplication.h"
17 #include "qgsattributetablemodel.h"
19 
20 #include "qgsattributeaction.h"
21 #include "qgseditorwidgetregistry.h"
22 #include "qgsexpression.h"
23 #include "qgsfield.h"
24 #include "qgslogger.h"
25 #include "qgsmapcanvas.h"
27 #include "qgsmaplayerregistry.h"
28 #include "qgsrendererv2.h"
29 #include "qgsvectorlayer.h"
30 
31 #include <QVariant>
32 
33 #include <limits>
34 
36  : QAbstractTableModel( parent )
37  , mLayerCache( layerCache )
38  , mFieldCount( 0 )
39  , mCachedField( -1 )
40 {
41  QgsDebugMsg( "entered." );
42 
43  if ( layerCache->layer()->geometryType() == QGis::NoGeometry )
44  {
46  }
47 
49 
50  if ( !layer()->hasGeometryType() )
52 
54 
55  connect( mLayerCache, SIGNAL( attributeValueChanged( QgsFeatureId, int, const QVariant& ) ), this, SLOT( attributeValueChanged( QgsFeatureId, int, const QVariant& ) ) );
56  connect( layer(), SIGNAL( featureDeleted( QgsFeatureId ) ), this, SLOT( featureDeleted( QgsFeatureId ) ) );
57  connect( layer(), SIGNAL( attributeDeleted( int ) ), this, SLOT( attributeDeleted( int ) ) );
58  connect( layer(), SIGNAL( updatedFields() ), this, SLOT( updatedFields() ) );
59  connect( layer(), SIGNAL( editCommandEnded() ), this, SLOT( editCommandEnded() ) );
60  connect( mLayerCache, SIGNAL( featureAdded( QgsFeatureId ) ), this, SLOT( featureAdded( QgsFeatureId ) ) );
61  connect( mLayerCache, SIGNAL( cachedLayerDeleted() ), this, SLOT( layerDeleted() ) );
62 }
63 
65 {
66  QgsDebugMsgLevel( QString( "loading feature %1" ).arg( fid ), 3 );
67 
68  if ( fid == std::numeric_limits<int>::min() )
69  {
70  return false;
71  }
72 
73  return mLayerCache->featureAtId( fid, mFeat );
74 }
75 
77 {
78  QgsDebugMsgLevel( QString( "(%2) fid: %1" ).arg( fid ).arg( mFeatureRequest.filterType() ), 4 );
79  mFieldCache.remove( fid );
80 
81  int row = idToRow( fid );
82 
83  if ( row != -1 )
84  {
85  beginRemoveRows( QModelIndex(), row, row );
86  removeRow( row );
87  endRemoveRows();
88  }
89 }
90 
91 bool QgsAttributeTableModel::removeRows( int row, int count, const QModelIndex &parent )
92 {
93  Q_UNUSED( parent );
94  QgsDebugMsgLevel( QString( "remove %2 rows at %1 (rows %3, ids %4)" ).arg( row ).arg( count ).arg( mRowIdMap.size() ).arg( mIdRowMap.size() ), 3 );
95 
96  // clean old references
97  for ( int i = row; i < row + count; i++ )
98  {
99  mIdRowMap.remove( mRowIdMap[ i ] );
100  mRowIdMap.remove( i );
101  }
102 
103  // update maps
104  int n = mRowIdMap.size() + count;
105  for ( int i = row + count; i < n; i++ )
106  {
107  QgsFeatureId id = mRowIdMap[i];
108  mIdRowMap[ id ] -= count;
109  mRowIdMap[ i-count ] = id;
110  mRowIdMap.remove( i );
111  }
112 
113 #ifdef QGISDEBUG
114  QgsDebugMsgLevel( QString( "after removal rows %1, ids %2" ).arg( mRowIdMap.size() ).arg( mIdRowMap.size() ), 4 );
115  QgsDebugMsgLevel( "id->row", 4 );
116  for ( QHash<QgsFeatureId, int>::iterator it = mIdRowMap.begin(); it != mIdRowMap.end(); ++it )
117  QgsDebugMsgLevel( QString( "%1->%2" ).arg( FID_TO_STRING( it.key() ) ).arg( *it ), 4 );
118 
119  QHash<QgsFeatureId, int>::iterator idit;
120 
121  QgsDebugMsgLevel( "row->id", 4 );
122  for ( QHash<int, QgsFeatureId>::iterator it = mRowIdMap.begin(); it != mRowIdMap.end(); ++it )
123  QgsDebugMsgLevel( QString( "%1->%2" ).arg( it.key() ).arg( FID_TO_STRING( *it ) ), 4 );
124 #endif
125 
126  Q_ASSERT( mRowIdMap.size() == mIdRowMap.size() );
127 
128  return true;
129 }
130 
132 {
133  QgsDebugMsgLevel( QString( "(%2) fid: %1" ).arg( fid ).arg( mFeatureRequest.filterType() ), 4 );
134  bool featOk = true;
135 
136  if ( mFeat.id() != fid )
137  featOk = loadFeatureAtId( fid );
138 
139  if ( featOk && mFeatureRequest.acceptFeature( mFeat ) )
140  {
142 
143  int n = mRowIdMap.size();
144  beginInsertRows( QModelIndex(), n, n );
145 
146  mIdRowMap.insert( fid, n );
147  mRowIdMap.insert( n, fid );
148 
149  endInsertRows();
150 
151  reload( index( rowCount() - 1, 0 ), index( rowCount() - 1, columnCount() ) );
152  }
153 }
154 
156 {
157  QgsDebugMsg( "entered." );
158  loadAttributes();
159  emit modelChanged();
160 }
161 
163 {
164  reload( createIndex( mChangedCellBounds.top(), mChangedCellBounds.left() ),
165  createIndex( mChangedCellBounds.bottom(), mChangedCellBounds.right() ) );
166 
167  mChangedCellBounds = QRect();
168 }
169 
171 {
172  if ( idx == mCachedField )
173  {
174  prefetchColumnData( -1 );
175  }
176 }
177 
179 {
180  QgsDebugMsg( "entered." );
181 
182  beginRemoveRows( QModelIndex(), 0, rowCount() - 1 );
183  removeRows( 0, rowCount() );
184  endRemoveRows();
185 
186  mAttributeWidgetCaches.clear();
187  mAttributes.clear();
188  mWidgetFactories.clear();
189  mWidgetConfigs.clear();
190 }
191 
192 void QgsAttributeTableModel::attributeValueChanged( QgsFeatureId fid, int idx, const QVariant &value )
193 {
194  QgsDebugMsgLevel( QString( "(%4) fid: %1, idx: %2, value: %3" ).arg( fid ).arg( idx ).arg( value.toString() ).arg( mFeatureRequest.filterType() ), 3 );
195  // No filter request: skip all possibly heavy checks
197  {
198  setData( index( idToRow( fid ), fieldCol( idx ) ), value, Qt::EditRole );
199  }
200  else
201  {
202  if ( loadFeatureAtId( fid ) )
203  {
205  {
206  if ( !mIdRowMap.contains( fid ) )
207  {
208  // Feature changed in such a way, it will be shown now
209  featureAdded( fid );
210  }
211  else
212  {
213  if ( idx == mCachedField )
214  mFieldCache[ fid ] = value;
215  // Update representation
216  setData( index( idToRow( fid ), fieldCol( idx ) ), value, Qt::EditRole );
217  }
218  }
219  else
220  {
221  if ( mIdRowMap.contains( fid ) )
222  {
223  // Feature changed such, that it is no longer shown
224  featureDeleted( fid );
225  }
226  // else: we don't care
227  }
228  }
229  }
230 }
231 
233 {
234  if ( !layer() )
235  {
236  return;
237  }
238 
239  bool ins = false, rm = false;
240 
241  QgsAttributeList attributes;
242  const QgsFields& fields = layer()->pendingFields();
243 
244  mWidgetFactories.clear();
245  mAttributeWidgetCaches.clear();
246  mWidgetConfigs.clear();
247 
248  for ( int idx = 0; idx < fields.count(); ++idx )
249  {
250  const QString widgetType = layer()->editorWidgetV2( idx );
251  QgsEditorWidgetFactory* widgetFactory = QgsEditorWidgetRegistry::instance()->factory( widgetType );
252  if ( widgetFactory && widgetType != "Hidden" )
253  {
254  mWidgetFactories.append( widgetFactory );
255  mWidgetConfigs.append( layer()->editorWidgetV2Config( idx ) );
256  mAttributeWidgetCaches.append( widgetFactory->createCache( layer(), idx, mWidgetConfigs.last() ) );
257 
258  attributes << idx;
259  }
260  }
261 
262  if ( mFieldCount < attributes.size() )
263  {
264  ins = true;
265  beginInsertColumns( QModelIndex(), mFieldCount, attributes.size() - 1 );
266  }
267  else if ( attributes.size() < mFieldCount )
268  {
269  rm = true;
270  beginRemoveColumns( QModelIndex(), attributes.size(), mFieldCount - 1 );
271  }
272 
273  mFieldCount = attributes.size();
274  mAttributes = attributes;
275 
276  if ( ins )
277  {
278  endInsertColumns();
279  }
280  else if ( rm )
281  {
282  endRemoveColumns();
283  }
284 }
285 
287 {
288  QgsDebugMsg( "entered." );
289 
290  if ( rowCount() != 0 )
291  {
292  beginRemoveRows( QModelIndex(), 0, rowCount() - 1 );
293  removeRows( 0, rowCount() );
294  endRemoveRows();
295  }
296 
298 
299  int i = 0;
300 
301  QTime t;
302  t.start();
303 
304  QgsFeature feat;
305  while ( features.nextFeature( feat ) )
306  {
307  ++i;
308 
309  if ( t.elapsed() > 1000 )
310  {
311  bool cancel = false;
312  emit( progress( i, cancel ) );
313  if ( cancel )
314  break;
315 
316  t.restart();
317  }
318  mFeat = feat;
319  featureAdded( feat.id() );
320  }
321 
322  emit finished();
323 
324  mFieldCount = mAttributes.size();
325 }
326 
328 {
329  if ( a == b )
330  return;
331 
332  int rowA = idToRow( a );
333  int rowB = idToRow( b );
334 
335  //emit layoutAboutToBeChanged();
336 
337  mRowIdMap.remove( rowA );
338  mRowIdMap.remove( rowB );
339  mRowIdMap.insert( rowA, b );
340  mRowIdMap.insert( rowB, a );
341 
342  mIdRowMap.remove( a );
343  mIdRowMap.remove( b );
344  mIdRowMap.insert( a, rowB );
345  mIdRowMap.insert( b, rowA );
346 
347  //emit layoutChanged();
348 }
349 
351 {
352  if ( !mIdRowMap.contains( id ) )
353  {
354  QgsDebugMsg( QString( "idToRow: id %1 not in the map" ).arg( id ) );
355  return -1;
356  }
357 
358  return mIdRowMap[id];
359 }
360 
362 {
363  return index( idToRow( id ), 0 );
364 }
365 
367 {
368  QModelIndexList indexes;
369 
370  int row = idToRow( id );
371  for ( int column = 0; column < columnCount(); ++column )
372  {
373  indexes.append( index( row, column ) );
374  }
375 
376  return indexes;
377 }
378 
380 {
381  if ( !mRowIdMap.contains( row ) )
382  {
383  QgsDebugMsg( QString( "rowToId: row %1 not in the map" ).arg( row ) );
384  // return negative infinite (to avoid collision with newly added features)
386  }
387 
388  return mRowIdMap[row];
389 }
390 
392 {
393  return mAttributes[ col ];
394 }
395 
397 {
398  return mAttributes.indexOf( idx );
399 }
400 
401 int QgsAttributeTableModel::rowCount( const QModelIndex &parent ) const
402 {
403  Q_UNUSED( parent );
404  return mRowIdMap.size();
405 }
406 
407 int QgsAttributeTableModel::columnCount( const QModelIndex &parent ) const
408 {
409  Q_UNUSED( parent );
410  return qMax( 1, mFieldCount ); // if there are zero columns all model indices will be considered invalid
411 }
412 
413 QVariant QgsAttributeTableModel::headerData( int section, Qt::Orientation orientation, int role ) const
414 {
415  if ( !layer() )
416  return QVariant();
417 
418  if ( role == Qt::DisplayRole )
419  {
420  if ( orientation == Qt::Vertical ) //row
421  {
422  return QVariant( section );
423  }
424  else if ( section >= 0 && section < mFieldCount )
425  {
426  QString attributeName = layer()->attributeAlias( mAttributes[section] );
427  if ( attributeName.isEmpty() )
428  {
429  QgsField field = layer()->pendingFields()[ mAttributes[section] ];
430  attributeName = field.name();
431  }
432  return QVariant( attributeName );
433  }
434  else
435  {
436  return tr( "feature id" );
437  }
438  }
439  else
440  {
441  return QVariant();
442  }
443 }
444 
445 QVariant QgsAttributeTableModel::data( const QModelIndex &index, int role ) const
446 {
447  if ( !index.isValid() ||
448  ( role != Qt::TextAlignmentRole
449  && role != Qt::DisplayRole
450  && role != Qt::EditRole
451  && role != SortRole
452  && role != FeatureIdRole
453  && role != FieldIndexRole
454  )
455  )
456  return QVariant();
457 
458  QgsFeatureId rowId = rowToId( index.row() );
459 
460  if ( role == FeatureIdRole )
461  return rowId;
462 
463  if ( index.column() >= mFieldCount )
464  return role == Qt::DisplayRole ? rowId : QVariant();
465 
466  int fieldId = mAttributes[ index.column()];
467 
468  if ( role == FieldIndexRole )
469  return fieldId;
470 
471  const QgsField& field = layer()->pendingFields()[ fieldId ];
472 
473  QVariant::Type fldType = field.type();
474  bool fldNumeric = ( fldType == QVariant::Int || fldType == QVariant::Double || fldType == QVariant::LongLong );
475 
476  if ( role == Qt::TextAlignmentRole )
477  {
478  if ( fldNumeric )
479  return QVariant( Qt::AlignRight );
480  else
481  return QVariant( Qt::AlignLeft );
482  }
483 
484  QVariant val;
485 
486  // if we don't have the row in current cache, load it from layer first
487  if ( mCachedField == fieldId )
488  {
489  val = mFieldCache[ rowId ];
490  }
491  else
492  {
493  if ( mFeat.id() != rowId || !mFeat.isValid() )
494  {
495  if ( !loadFeatureAtId( rowId ) )
496  return QVariant( "ERROR" );
497 
498  if ( mFeat.id() != rowId )
499  return QVariant( "ERROR" );
500  }
501 
502  val = mFeat.attribute( fieldId );
503  }
504 
505  if ( role == Qt::DisplayRole )
506  {
507  return mWidgetFactories[ index.column()]->representValue( layer(), fieldId, mWidgetConfigs[ index.column()], mAttributeWidgetCaches[ index.column()], val );
508  }
509 
510  return val;
511 }
512 
513 bool QgsAttributeTableModel::setData( const QModelIndex &index, const QVariant &value, int role )
514 {
515  Q_UNUSED( value )
516 
517  if ( !index.isValid() || index.column() >= mFieldCount || role != Qt::EditRole || !layer()->isEditable() )
518  return false;
519 
520  if ( !layer()->isModified() )
521  return false;
522 
523  if ( mChangedCellBounds.isNull() )
524  {
525  mChangedCellBounds = QRect( index.column(), index.row(), 0, 1 );
526  }
527  else
528  {
529  if ( index.column() < mChangedCellBounds.left() )
530  {
531  mChangedCellBounds.setLeft( index.column() );
532  }
533  if ( index.row() < mChangedCellBounds.top() )
534  {
535  mChangedCellBounds.setTop( index.row() );
536  }
537  if ( index.column() > mChangedCellBounds.right() )
538  {
539  mChangedCellBounds.setRight( index.column() );
540  }
541  if ( index.row() > mChangedCellBounds.bottom() )
542  {
543  mChangedCellBounds.setBottom( index.row() );
544  }
545  }
546 
547  return true;
548 }
549 
550 Qt::ItemFlags QgsAttributeTableModel::flags( const QModelIndex &index ) const
551 {
552  if ( !index.isValid() )
553  return Qt::ItemIsEnabled;
554 
555  if ( index.column() >= mFieldCount )
556  return Qt::NoItemFlags;
557 
558  Qt::ItemFlags flags = QAbstractItemModel::flags( index );
559 
560  if ( layer()->isEditable() &&
561  layer()->fieldEditable( mAttributes[ index.column()] ) )
562  flags |= Qt::ItemIsEditable;
563 
564  return flags;
565 }
566 
567 void QgsAttributeTableModel::reload( const QModelIndex &index1, const QModelIndex &index2 )
568 {
570  emit dataChanged( index1, index2 );
571 }
572 
574 {
575  beginResetModel();
576  endResetModel();
577 }
578 
579 void QgsAttributeTableModel::executeAction( int action, const QModelIndex &idx ) const
580 {
581  QgsFeature f = feature( idx );
582  layer()->actions()->doAction( action, f, fieldIdx( idx.column() ) );
583 }
584 
585 void QgsAttributeTableModel::executeMapLayerAction( QgsMapLayerAction* action, const QModelIndex &idx ) const
586 {
587  QgsFeature f = feature( idx );
588  action->triggerForFeature( layer(), &f );
589 }
590 
591 QgsFeature QgsAttributeTableModel::feature( const QModelIndex &idx ) const
592 {
593  QgsFeature f;
594  f.initAttributes( mAttributes.size() );
595  f.setFeatureId( rowToId( idx.row() ) );
596  for ( int i = 0; i < mAttributes.size(); i++ )
597  {
598  f.setAttribute( mAttributes[i], data( index( idx.row(), i ), Qt::EditRole ) );
599  }
600 
601  return f;
602 }
603 
605 {
606  mFieldCache.clear();
607 
608  if ( column == -1 )
609  {
610  mCachedField = -1;
611  }
612  else
613  {
614  if ( column >= mAttributes.count() )
615  return;
616  int fieldId = mAttributes[ column ];
617  const QgsFields& fields = layer()->pendingFields();
618  QStringList fldNames;
619  fldNames << fields[ fieldId ].name();
620 
621  QgsFeatureIterator it = mLayerCache->getFeatures( QgsFeatureRequest().setFlags( QgsFeatureRequest::NoGeometry ).setSubsetOfAttributes( fldNames, fields ) );
622 
623  QgsFeature f;
624  while ( it.nextFeature( f ) )
625  {
626  mFieldCache.insert( f.id(), f.attribute( fieldId ) );
627  }
628 
629  mCachedField = fieldId;
630  }
631 }
632 
634 {
635  mFeatureRequest = request;
636  if ( layer() && !layer()->hasGeometryType() )
638 }
QgsFeatureId id() const
Get the feature id for this feature.
Definition: qgsfeature.cpp:100
void setRequest(const QgsFeatureRequest &request)
const QString & name() const
Gets the name of the field.
Definition: qgsfield.cpp:58
QRect mChangedCellBounds
Holds the bounds of changed cells while an update operation is running top = min row left = min colum...
Wrapper for iterator of features from vector data provider or vector layer.
static unsigned index
bool acceptFeature(const QgsFeature &feature)
Check if a feature is accepted by this requests filter.
const Flags & flags() const
virtual void loadLayer()
Loads the layer into the model Preferably to be called, before basing any other models on this model...
QModelIndexList idToIndexList(QgsFeatureId id) const
QHash< int, QgsFeatureId > mRowIdMap
bool isValid() const
Return the validity of this feature.
Definition: qgsfeature.cpp:171
QgsAttributeAction * actions()
QgsFeatureRequest mFeatureRequest
int columnCount(const QModelIndex &parent=QModelIndex()) const
Returns the number of columns.
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const
Returns the number of rows.
#define QgsDebugMsg(str)
Definition: qgslogger.h:36
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex())
Remove rows.
QHash< QgsFeatureId, QVariant > mFieldCache
Allows caching of one specific column (used for sorting)
virtual void layerDeleted()
Launched when layer has been deleted.
void reload(const QModelIndex &index1, const QModelIndex &index2)
Reloads the model data between indices.
#define FID_TO_STRING(fid)
Definition: qgsfeature.h:83
QModelIndex idToIndex(QgsFeatureId id) const
Container of fields for a vector layer.
Definition: qgsfield.h:161
bool setAttribute(int field, const QVariant &attr)
Set an attribute by id.
Definition: qgsfeature.cpp:190
QgsVectorLayer * layer()
Returns the layer to which this cache belongs.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:113
void resetModel()
Resets the model.
void triggerForFeature(QgsMapLayer *layer, QgsFeature *feature)
Triggers the action with the specified layer and feature.
QgsVectorLayerCache * mLayerCache
virtual void attributeValueChanged(QgsFeatureId fid, int idx, const QVariant &value)
Launched when attribute value has been changed.
int mCachedField
The currently cached column.
virtual void editCommandEnded()
Gets called when an edit command ends This will synchronize all fields which have been changed since ...
virtual bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole)
Updates data on given index.
void executeMapLayerAction(QgsMapLayerAction *action, const QModelIndex &idx) const
Execute a QgsMapLayerAction.
void setFeatureId(QgsFeatureId id)
Set the feature id for this feature.
Definition: qgsfeature.cpp:128
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:37
QVector< QgsEditorWidgetFactory * > mWidgetFactories
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
Definition: qgsfeature.cpp:181
const QString editorWidgetV2(int fieldIdx) const
Get the id for the editor widget used to represent the field at the given index.
void doAction(int index, QgsFeature &feat, int defaultValueIndex=0)
Qt::ItemFlags flags(const QModelIndex &index) const
Returns item flags for the index.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QList< int > QgsAttributeList
QVector< QgsEditorWidgetConfig > mWidgetConfigs
int count() const
Return number of items.
Definition: qgsfield.h:195
virtual bool isModified() const
Returns true if the provider has been modified since the last commit.
QGis::GeometryType geometryType() const
Returns point, line or polygon.
QHash< QgsFeatureId, int > mIdRowMap
FilterType filterType() const
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:31
QString attributeAlias(int attributeIndex) const
Returns the alias of an attribute name or an empty string if there is no alias.
void executeAction(int action, const QModelIndex &idx) const
Execute an action.
virtual void attributeDeleted(int idx)
Called whenever a column is removed;.
virtual void featureAdded(QgsFeatureId fid)
Launched when a feature has been added.
QgsFeature feature(const QModelIndex &idx) const
Return the feature attributes at given model index.
This class caches features of a given QgsVectorLayer.
void progress(int i, bool &cancel)
void modelChanged()
Model has been changed.
QVector< QVariant > mAttributeWidgetCaches
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const
Returns header data.
No filter is applied.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:230
int fieldCol(int idx) const
get column from field index
virtual void featureDeleted(QgsFeatureId fid)
Launched when a feature has been deleted.
bool featureAtId(QgsFeatureId featureId, QgsFeature &feature, bool skipCache=false)
Gets the feature at the given feature id.
QgsVectorLayer * layer() const
Returns the layer this model uses as backend.
virtual QVariant data(const QModelIndex &index, int role) const
Returns data on the given index.
virtual void loadAttributes()
Gets mFieldCount, mAttributes and mValueMaps.
int idToRow(QgsFeatureId id) const
Maps feature id to table row.
qint64 QgsFeatureId
Definition: qgsfeature.h:30
int fieldIdx(int col) const
get field index from column
QgsFeatureId rowToId(int row) const
Maps row to feature id.
const QgsFields & pendingFields() const
returns field list in the to-be-committed state
double ANALYSIS_EXPORT min(double x, double y)
returns the minimum of two doubles or the first argument if both are equal
void swapRows(QgsFeatureId a, QgsFeatureId b)
Swaps two rows.
bool nextFeature(QgsFeature &f)
Geometry is not required. It may still be returned if e.g. required for a filter condition.
virtual bool isEditable() const
Returns true if the provider is in editing mode.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &featureRequest=QgsFeatureRequest())
Query this VectorLayerCache for features.
QgsFeatureRequest & setFlags(Flags flags)
Set flags that affect how features will be fetched.
virtual bool loadFeatureAtId(QgsFeatureId fid) const
Load feature fid into local cache (mFeat)
QgsAttributeTableModel(QgsVectorLayerCache *layerCache, QObject *parent=0)
Constructor.
An action which can run on map layers.
void prefetchColumnData(int column)
Caches the entire data for one column.
QVariant::Type type() const
Gets variant type of the field as it will be retrieved from data source.
Definition: qgsfield.cpp:63
virtual void updatedFields()
Launched whenever the number of fields has changed.
#define tr(sourceText)