QGIS API Documentation  2.8.6-Wien
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"
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 #include "qgsvectordataprovider.h"
31 
32 #include <QVariant>
33 
34 #include <limits>
35 
37  : QAbstractTableModel( parent )
38  , mLayerCache( layerCache )
39  , mFieldCount( 0 )
40  , mCachedField( -1 )
41 {
42  QgsDebugMsg( "entered." );
43 
44  if ( layerCache->layer()->geometryType() == QGis::NoGeometry )
45  {
46  mFeatureRequest.setFlags( QgsFeatureRequest::NoGeometry );
47  }
48 
50 
51  if ( !layer()->hasGeometryType() )
52  mFeatureRequest.setFlags( QgsFeatureRequest::NoGeometry );
53 
55 
56  connect( mLayerCache, SIGNAL( attributeValueChanged( QgsFeatureId, int, const QVariant& ) ), this, SLOT( attributeValueChanged( QgsFeatureId, int, const QVariant& ) ) );
57  connect( layer(), SIGNAL( featureDeleted( QgsFeatureId ) ), this, SLOT( featureDeleted( QgsFeatureId ) ) );
58  connect( layer(), SIGNAL( attributeDeleted( int ) ), this, SLOT( attributeDeleted( int ) ) );
59  connect( layer(), SIGNAL( updatedFields() ), this, SLOT( updatedFields() ) );
60  connect( layer(), SIGNAL( editCommandEnded() ), this, SLOT( editCommandEnded() ) );
61  connect( mLayerCache, SIGNAL( featureAdded( QgsFeatureId ) ), this, SLOT( featureAdded( QgsFeatureId ) ) );
62  connect( mLayerCache, SIGNAL( cachedLayerDeleted() ), this, SLOT( layerDeleted() ) );
63 }
64 
65 bool QgsAttributeTableModel::loadFeatureAtId( QgsFeatureId fid ) const
66 {
67  QgsDebugMsgLevel( QString( "loading feature %1" ).arg( fid ), 3 );
68 
69  if ( fid == std::numeric_limits<int>::min() )
70  {
71  return false;
72  }
73 
74  return mLayerCache->featureAtId( fid, mFeat );
75 }
76 
78 {
79  QgsDebugMsgLevel( QString( "(%2) fid: %1" ).arg( fid ).arg( mFeatureRequest.filterType() ), 4 );
80  mFieldCache.remove( fid );
81 
82  int row = idToRow( fid );
83 
84  if ( row != -1 )
85  {
86  beginRemoveRows( QModelIndex(), row, row );
87  removeRow( row );
88  endRemoveRows();
89  }
90 }
91 
92 bool QgsAttributeTableModel::removeRows( int row, int count, const QModelIndex &parent )
93 {
94  Q_UNUSED( parent );
95  QgsDebugMsgLevel( QString( "remove %2 rows at %1 (rows %3, ids %4)" ).arg( row ).arg( count ).arg( mRowIdMap.size() ).arg( mIdRowMap.size() ), 3 );
96 
97  // clean old references
98  for ( int i = row; i < row + count; i++ )
99  {
100  mIdRowMap.remove( mRowIdMap[ i ] );
101  mRowIdMap.remove( i );
102  }
103 
104  // update maps
105  int n = mRowIdMap.size() + count;
106  for ( int i = row + count; i < n; i++ )
107  {
108  QgsFeatureId id = mRowIdMap[i];
109  mIdRowMap[ id ] -= count;
110  mRowIdMap[ i-count ] = id;
111  mRowIdMap.remove( i );
112  }
113 
114 #ifdef QGISDEBUG
115  QgsDebugMsgLevel( QString( "after removal rows %1, ids %2" ).arg( mRowIdMap.size() ).arg( mIdRowMap.size() ), 4 );
116  QgsDebugMsgLevel( "id->row", 4 );
117  for ( QHash<QgsFeatureId, int>::iterator it = mIdRowMap.begin(); it != mIdRowMap.end(); ++it )
118  QgsDebugMsgLevel( QString( "%1->%2" ).arg( FID_TO_STRING( it.key() ) ).arg( *it ), 4 );
119 
120  QHash<QgsFeatureId, int>::iterator idit;
121 
122  QgsDebugMsgLevel( "row->id", 4 );
123  for ( QHash<int, QgsFeatureId>::iterator it = mRowIdMap.begin(); it != mRowIdMap.end(); ++it )
124  QgsDebugMsgLevel( QString( "%1->%2" ).arg( it.key() ).arg( FID_TO_STRING( *it ) ), 4 );
125 #endif
126 
127  Q_ASSERT( mRowIdMap.size() == mIdRowMap.size() );
128 
129  return true;
130 }
131 
133 {
134  QgsDebugMsgLevel( QString( "(%2) fid: %1" ).arg( fid ).arg( mFeatureRequest.filterType() ), 4 );
135  bool featOk = true;
136 
137  if ( mFeat.id() != fid )
138  featOk = loadFeatureAtId( fid );
139 
140  if ( featOk && mFeatureRequest.acceptFeature( mFeat ) )
141  {
142  mFieldCache[ fid ] = mFeat.attribute( mCachedField );
143 
144  int n = mRowIdMap.size();
145  beginInsertRows( QModelIndex(), n, n );
146 
147  mIdRowMap.insert( fid, n );
148  mRowIdMap.insert( n, fid );
149 
150  endInsertRows();
151 
152  reload( index( rowCount() - 1, 0 ), index( rowCount() - 1, columnCount() ) );
153  }
154 }
155 
156 void QgsAttributeTableModel::updatedFields()
157 {
158  QgsDebugMsg( "entered." );
159  loadAttributes();
160  emit modelChanged();
161 }
162 
163 void QgsAttributeTableModel::editCommandEnded()
164 {
165  reload( createIndex( mChangedCellBounds.top(), mChangedCellBounds.left() ),
166  createIndex( mChangedCellBounds.bottom(), mChangedCellBounds.right() ) );
167 
168  mChangedCellBounds = QRect();
169 }
170 
171 void QgsAttributeTableModel::attributeDeleted( int idx )
172 {
173  if ( idx == mCachedField )
174  {
175  prefetchColumnData( -1 );
176  }
177 }
178 
180 {
181  QgsDebugMsg( "entered." );
182 
183  beginRemoveRows( QModelIndex(), 0, rowCount() - 1 );
184  removeRows( 0, rowCount() );
185  endRemoveRows();
186 
187  mAttributeWidgetCaches.clear();
188  mAttributes.clear();
189  mWidgetFactories.clear();
190  mWidgetConfigs.clear();
191 }
192 
193 void QgsAttributeTableModel::attributeValueChanged( QgsFeatureId fid, int idx, const QVariant &value )
194 {
195  QgsDebugMsgLevel( QString( "(%4) fid: %1, idx: %2, value: %3" ).arg( fid ).arg( idx ).arg( value.toString() ).arg( mFeatureRequest.filterType() ), 3 );
196 
197  if ( idx == mCachedField )
198  mFieldCache[ fid ] = value;
199 
200  // No filter request: skip all possibly heavy checks
201  if ( mFeatureRequest.filterType() == QgsFeatureRequest::FilterNone )
202  {
203  setData( index( idToRow( fid ), fieldCol( idx ) ), value, Qt::EditRole );
204  }
205  else
206  {
207  if ( loadFeatureAtId( fid ) )
208  {
209  if ( mFeatureRequest.acceptFeature( mFeat ) )
210  {
211  if ( !mIdRowMap.contains( fid ) )
212  {
213  // Feature changed in such a way, it will be shown now
214  featureAdded( fid );
215  }
216  else
217  {
218  // Update representation
219  setData( index( idToRow( fid ), fieldCol( idx ) ), value, Qt::EditRole );
220  }
221  }
222  else
223  {
224  if ( mIdRowMap.contains( fid ) )
225  {
226  // Feature changed such, that it is no longer shown
227  featureDeleted( fid );
228  }
229  // else: we don't care
230  }
231  }
232  }
233 }
234 
236 {
237  if ( !layer() )
238  {
239  return;
240  }
241 
242  bool ins = false, rm = false;
243 
244  QgsAttributeList attributes;
245  const QgsFields& fields = layer()->pendingFields();
246 
247  mWidgetFactories.clear();
248  mAttributeWidgetCaches.clear();
249  mWidgetConfigs.clear();
250 
251  for ( int idx = 0; idx < fields.count(); ++idx )
252  {
253  const QString widgetType = layer()->editorWidgetV2( idx );
254  QgsEditorWidgetFactory* widgetFactory = QgsEditorWidgetRegistry::instance()->factory( widgetType );
255  if ( widgetFactory && widgetType != "Hidden" )
256  {
257  mWidgetFactories.append( widgetFactory );
258  mWidgetConfigs.append( layer()->editorWidgetV2Config( idx ) );
259  mAttributeWidgetCaches.append( widgetFactory->createCache( layer(), idx, mWidgetConfigs.last() ) );
260 
261  attributes << idx;
262  }
263  }
264 
265  if ( mFieldCount < attributes.size() )
266  {
267  ins = true;
268  beginInsertColumns( QModelIndex(), mFieldCount, attributes.size() - 1 );
269  }
270  else if ( attributes.size() < mFieldCount )
271  {
272  rm = true;
273  beginRemoveColumns( QModelIndex(), attributes.size(), mFieldCount - 1 );
274  }
275 
276  mFieldCount = attributes.size();
277  mAttributes = attributes;
278 
279  if ( ins )
280  {
281  endInsertColumns();
282  }
283  else if ( rm )
284  {
285  endRemoveColumns();
286  }
287 }
288 
290 {
291  QgsDebugMsg( "entered." );
292 
293  if ( rowCount() != 0 )
294  {
295  beginRemoveRows( QModelIndex(), 0, rowCount() - 1 );
296  removeRows( 0, rowCount() );
297  endRemoveRows();
298  }
299 
300  QgsFeatureIterator features = mLayerCache->getFeatures( mFeatureRequest );
301 
302  int i = 0;
303 
304  QTime t;
305  t.start();
306 
307  QgsFeature feat;
308  while ( features.nextFeature( feat ) )
309  {
310  ++i;
311 
312  if ( t.elapsed() > 1000 )
313  {
314  bool cancel = false;
315  emit progress( i, cancel );
316  if ( cancel )
317  break;
318 
319  t.restart();
320  }
321  mFeat = feat;
322  featureAdded( feat.id() );
323  }
324 
325  emit finished();
326 
327  mFieldCount = mAttributes.size();
328 }
329 
331 {
332  if ( a == b )
333  return;
334 
335  int rowA = idToRow( a );
336  int rowB = idToRow( b );
337 
338  //emit layoutAboutToBeChanged();
339 
340  mRowIdMap.remove( rowA );
341  mRowIdMap.remove( rowB );
342  mRowIdMap.insert( rowA, b );
343  mRowIdMap.insert( rowB, a );
344 
345  mIdRowMap.remove( a );
346  mIdRowMap.remove( b );
347  mIdRowMap.insert( a, rowB );
348  mIdRowMap.insert( b, rowA );
349 
350  //emit layoutChanged();
351 }
352 
354 {
355  if ( !mIdRowMap.contains( id ) )
356  {
357  QgsDebugMsg( QString( "idToRow: id %1 not in the map" ).arg( id ) );
358  return -1;
359  }
360 
361  return mIdRowMap[id];
362 }
363 
365 {
366  return index( idToRow( id ), 0 );
367 }
368 
370 {
371  QModelIndexList indexes;
372 
373  int row = idToRow( id );
374  for ( int column = 0; column < columnCount(); ++column )
375  {
376  indexes.append( index( row, column ) );
377  }
378 
379  return indexes;
380 }
381 
383 {
384  if ( !mRowIdMap.contains( row ) )
385  {
386  QgsDebugMsg( QString( "rowToId: row %1 not in the map" ).arg( row ) );
387  // return negative infinite (to avoid collision with newly added features)
389  }
390 
391  return mRowIdMap[row];
392 }
393 
395 {
396  return mAttributes[ col ];
397 }
398 
400 {
401  return mAttributes.indexOf( idx );
402 }
403 
404 int QgsAttributeTableModel::rowCount( const QModelIndex &parent ) const
405 {
406  Q_UNUSED( parent );
407  return mRowIdMap.size();
408 }
409 
410 int QgsAttributeTableModel::columnCount( const QModelIndex &parent ) const
411 {
412  Q_UNUSED( parent );
413  return qMax( 1, mFieldCount ); // if there are zero columns all model indices will be considered invalid
414 }
415 
416 QVariant QgsAttributeTableModel::headerData( int section, Qt::Orientation orientation, int role ) const
417 {
418  if ( !layer() )
419  return QVariant();
420 
421  if ( role == Qt::DisplayRole )
422  {
423  if ( orientation == Qt::Vertical ) //row
424  {
425  return QVariant( section );
426  }
427  else if ( section >= 0 && section < mFieldCount )
428  {
429  QString attributeName = layer()->attributeAlias( mAttributes[section] );
430  if ( attributeName.isEmpty() )
431  {
432  QgsField field = layer()->pendingFields()[ mAttributes[section] ];
433  attributeName = field.name();
434  }
435  return QVariant( attributeName );
436  }
437  else
438  {
439  return tr( "feature id" );
440  }
441  }
442  else
443  {
444  return QVariant();
445  }
446 }
447 
448 QVariant QgsAttributeTableModel::data( const QModelIndex &index, int role ) const
449 {
450  if ( !index.isValid() ||
451  ( role != Qt::TextAlignmentRole
452  && role != Qt::DisplayRole
453  && role != Qt::EditRole
454  && role != SortRole
455  && role != FeatureIdRole
456  && role != FieldIndexRole
457  )
458  )
459  return QVariant();
460 
461  QgsFeatureId rowId = rowToId( index.row() );
462 
463  if ( role == FeatureIdRole )
464  return rowId;
465 
466  if ( index.column() >= mFieldCount )
467  return role == Qt::DisplayRole ? rowId : QVariant();
468 
469  int fieldId = mAttributes[ index.column()];
470 
471  if ( role == FieldIndexRole )
472  return fieldId;
473 
474  const QgsField& field = layer()->pendingFields()[ fieldId ];
475 
476  QVariant::Type fldType = field.type();
477  bool fldNumeric = ( fldType == QVariant::Int || fldType == QVariant::Double || fldType == QVariant::LongLong );
478 
479  if ( role == Qt::TextAlignmentRole )
480  {
481  if ( fldNumeric )
482  return QVariant( Qt::AlignRight );
483  else
484  return QVariant( Qt::AlignLeft );
485  }
486 
487  QVariant val;
488 
489  // if we don't have the row in current cache, load it from layer first
490  if ( mCachedField == fieldId )
491  {
492  val = mFieldCache[ rowId ];
493  }
494  else
495  {
496  if ( mFeat.id() != rowId || !mFeat.isValid() )
497  {
498  if ( !loadFeatureAtId( rowId ) )
499  return QVariant( "ERROR" );
500 
501  if ( mFeat.id() != rowId )
502  return QVariant( "ERROR" );
503  }
504 
505  val = mFeat.attribute( fieldId );
506  }
507 
508  if ( role == Qt::DisplayRole )
509  {
510  return mWidgetFactories[ index.column()]->representValue( layer(), fieldId, mWidgetConfigs[ index.column()], mAttributeWidgetCaches[ index.column()], val );
511  }
512 
513  return val;
514 }
515 
516 bool QgsAttributeTableModel::setData( const QModelIndex &index, const QVariant &value, int role )
517 {
518  Q_UNUSED( value )
519 
520  if ( !index.isValid() || index.column() >= mFieldCount || role != Qt::EditRole || !layer()->isEditable() )
521  return false;
522 
523  if ( !layer()->isModified() )
524  return false;
525 
526  if ( mChangedCellBounds.isNull() )
527  {
528  mChangedCellBounds = QRect( index.column(), index.row(), 1, 1 );
529  }
530  else
531  {
532  if ( index.column() < mChangedCellBounds.left() )
533  {
534  mChangedCellBounds.setLeft( index.column() );
535  }
536  if ( index.row() < mChangedCellBounds.top() )
537  {
538  mChangedCellBounds.setTop( index.row() );
539  }
540  if ( index.column() > mChangedCellBounds.right() )
541  {
542  mChangedCellBounds.setRight( index.column() );
543  }
544  if ( index.row() > mChangedCellBounds.bottom() )
545  {
546  mChangedCellBounds.setBottom( index.row() );
547  }
548  }
549 
550  return true;
551 }
552 
553 Qt::ItemFlags QgsAttributeTableModel::flags( const QModelIndex &index ) const
554 {
555  if ( !index.isValid() )
556  return Qt::ItemIsEnabled;
557 
558  if ( index.column() >= mFieldCount )
559  return Qt::NoItemFlags;
560 
561  Qt::ItemFlags flags = QAbstractItemModel::flags( index );
562 
563  if ( layer()->isEditable() &&
564  layer()->fieldEditable( mAttributes[ index.column()] ) &&
565  (( layer()->dataProvider() && layer()->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues ) ||
566  FID_IS_NEW( rowToId( index.row() ) ) ) )
567  flags |= Qt::ItemIsEditable;
568 
569  return flags;
570 }
571 
572 void QgsAttributeTableModel::reload( const QModelIndex &index1, const QModelIndex &index2 )
573 {
575  emit dataChanged( index1, index2 );
576 }
577 
579 {
580  beginResetModel();
581  endResetModel();
582 }
583 
584 void QgsAttributeTableModel::executeAction( int action, const QModelIndex &idx ) const
585 {
586  QgsFeature f = feature( idx );
587  layer()->actions()->doAction( action, f, fieldIdx( idx.column() ) );
588 }
589 
590 void QgsAttributeTableModel::executeMapLayerAction( QgsMapLayerAction* action, const QModelIndex &idx ) const
591 {
592  QgsFeature f = feature( idx );
593  action->triggerForFeature( layer(), &f );
594 }
595 
596 QgsFeature QgsAttributeTableModel::feature( const QModelIndex &idx ) const
597 {
598  QgsFeature f;
599  f.initAttributes( mAttributes.size() );
600  f.setFeatureId( rowToId( idx.row() ) );
601  for ( int i = 0; i < mAttributes.size(); i++ )
602  {
603  f.setAttribute( mAttributes[i], data( index( idx.row(), i ), Qt::EditRole ) );
604  }
605 
606  return f;
607 }
608 
610 {
611  mFieldCache.clear();
612 
613  if ( column == -1 )
614  {
615  mCachedField = -1;
616  }
617  else
618  {
619  if ( column >= mAttributes.count() )
620  return;
621  int fieldId = mAttributes[ column ];
622  const QgsFields& fields = layer()->pendingFields();
623  QStringList fldNames;
624  fldNames << fields[ fieldId ].name();
625 
626  QgsFeatureRequest r( mFeatureRequest );
628 
629  QgsFeature f;
630  while ( it.nextFeature( f ) )
631  {
632  mFieldCache.insert( f.id(), f.attribute( fieldId ) );
633  }
634 
635  mCachedField = fieldId;
636  }
637 }
638 
640 {
641  mFeatureRequest = request;
642  if ( layer() && !layer()->hasGeometryType() )
643  mFeatureRequest.setFlags( mFeatureRequest.flags() | QgsFeatureRequest::NoGeometry );
644 }
645 
647 {
648  return mFeatureRequest;
649 }
QgsFeatureId id() const
Get the feature id for this feature.
Definition: qgsfeature.cpp:100
void setRequest(const QgsFeatureRequest &request)
Set a request that will be used to fill this attribute table model.
const QString & name() const
Gets the name of the field.
Definition: qgsfield.cpp:60
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()
QgsEditorWidgetFactory * factory(const QString &widgetId)
Get a factory for the given widget type id.
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
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
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QModelIndex idToIndex(QgsFeatureId id) const
Container of fields for a vector layer.
Definition: qgsfield.h:172
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.
const QgsFeatureRequest & request() const
Get the the feature request.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:156
virtual bool isEditable() const override
Returns true if the provider is in editing mode.
static QgsEditorWidgetRegistry * instance()
This class is a singleton and has therefore to be accessed with this method instead of a constructor...
void resetModel()
Resets the model.
virtual QVariant createCache(QgsVectorLayer *vl, int fieldIdx, const QgsEditorWidgetConfig &config)
Create a cache for a given field.
QgsVectorLayerCache * mLayerCache
virtual void attributeValueChanged(QgsFeatureId fid, int idx, const QVariant &value)
Launched when attribute value has been changed.
virtual QVariant data(const QModelIndex &index, int role) const override
Returns data on the given index.
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
Returns header data.
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:34
int columnCount(const QModelIndex &parent=QModelIndex()) const override
Returns the number of columns.
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.
Every attribute editor widget needs a factory, which inherits this class.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QList< int > QgsAttributeList
QVector< QgsEditorWidgetConfig > mWidgetConfigs
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
Remove rows.
int count() const
Return number of items.
Definition: qgsfield.h:214
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:33
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 featureAdded(QgsFeatureId fid)
Launched when a feature has been added.
int min(int a, int b)
Definition: util.h:93
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
No filter is applied.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:230
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const override
Returns the number of rows.
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 void loadAttributes()
Gets mFieldCount, mAttributes and mValueMaps.
int idToRow(QgsFeatureId id) const
Maps feature id to table row.
void doAction(int index, const QgsFeature &feat, int defaultValueIndex=0)
qint64 QgsFeatureId
Definition: qgsfeature.h:30
#define FID_IS_NEW(fid)
Definition: qgsfeature.h:81
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
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.
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 setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
Updates data on given index.
void triggerForFeature(QgsMapLayer *layer, const QgsFeature *feature)
Triggers the action with the specified layer and feature.
QgsAttributeTableModel(QgsVectorLayerCache *layerCache, QObject *parent=0)
Constructor.
allows modification of attribute values
An action which can run on map layers.
void prefetchColumnData(int column)
Caches the entire data for one column.
Qt::ItemFlags flags(const QModelIndex &index) const override
Returns item flags for the index.
QVariant::Type type() const
Gets variant type of the field as it will be retrieved from data source.
Definition: qgsfield.cpp:65
#define tr(sourceText)