QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
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 "qgsactionmanager.h"
22 #include "qgseditorwidgetfactory.h"
23 #include "qgsexpression.h"
24 #include "qgsfeatureiterator.h"
25 #include "qgsconditionalstyle.h"
26 #include "qgsfields.h"
27 #include "qgsfieldformatter.h"
28 #include "qgslogger.h"
29 #include "qgsmapcanvas.h"
31 #include "qgsrenderer.h"
32 #include "qgsvectorlayer.h"
33 #include "qgsvectordataprovider.h"
34 #include "qgssymbollayerutils.h"
36 #include "qgsgui.h"
37 #include "qgsexpressionnodeimpl.h"
38 #include "qgsvectorlayerjoininfo.h"
40 #include "qgsfieldmodel.h"
43 #include "qgsvectorlayerutils.h"
44 
45 #include <QVariant>
46 
47 #include <limits>
48 
50  : QAbstractTableModel( parent )
51  , mLayerCache( layerCache )
52 {
54 
56  {
57  mFeatureRequest.setFlags( QgsFeatureRequest::NoGeometry );
58  }
59 
60  mFeat.setId( std::numeric_limits<int>::min() );
61 
62  if ( !layer()->isSpatial() )
63  mFeatureRequest.setFlags( QgsFeatureRequest::NoGeometry );
64 
65  loadAttributes();
66 
67  connect( layer(), &QgsVectorLayer::featuresDeleted, this, &QgsAttributeTableModel::featuresDeleted );
68  connect( layer(), &QgsVectorLayer::attributeDeleted, this, &QgsAttributeTableModel::attributeDeleted );
69  connect( layer(), &QgsVectorLayer::updatedFields, this, &QgsAttributeTableModel::updatedFields );
70 
71  connect( layer(), &QgsVectorLayer::editCommandStarted, this, &QgsAttributeTableModel::bulkEditCommandStarted );
72  connect( layer(), &QgsVectorLayer::beforeRollBack, this, &QgsAttributeTableModel::bulkEditCommandStarted );
73  connect( layer(), &QgsVectorLayer::afterRollBack, this, &QgsAttributeTableModel::bulkEditCommandEnded );
74 
75  connect( layer(), &QgsVectorLayer::editCommandEnded, this, &QgsAttributeTableModel::editCommandEnded );
76  connect( mLayerCache, &QgsVectorLayerCache::attributeValueChanged, this, &QgsAttributeTableModel::attributeValueChanged );
77  connect( mLayerCache, &QgsVectorLayerCache::featureAdded, this, [ = ]( QgsFeatureId id ) { featureAdded( id ); } );
78  connect( mLayerCache, &QgsVectorLayerCache::cachedLayerDeleted, this, &QgsAttributeTableModel::layerDeleted );
79 
80 }
81 
82 bool QgsAttributeTableModel::loadFeatureAtId( QgsFeatureId fid ) const
83 {
84  QgsDebugMsgLevel( QStringLiteral( "loading feature %1" ).arg( fid ), 3 );
85 
86  if ( fid == std::numeric_limits<int>::min() )
87  {
88  return false;
89  }
90 
91  return mLayerCache->featureAtId( fid, mFeat );
92 }
93 
95 {
96  return mExtraColumns;
97 }
98 
100 {
101  mExtraColumns = extraColumns;
102  loadAttributes();
103 }
104 
105 void QgsAttributeTableModel::featuresDeleted( const QgsFeatureIds &fids )
106 {
107  QList<int> rows;
108 
109  const auto constFids = fids;
110  for ( QgsFeatureId fid : constFids )
111  {
112  QgsDebugMsgLevel( QStringLiteral( "(%2) fid: %1, size: %3" ).arg( fid ).arg( mFeatureRequest.filterType() ).arg( mIdRowMap.size() ), 4 );
113 
114  int row = idToRow( fid );
115  if ( row != -1 )
116  rows << row;
117  }
118 
119  std::sort( rows.begin(), rows.end() );
120 
121  int lastRow = -1;
122  int beginRow = -1;
123  int currentRowCount = 0;
124  int removedRows = 0;
125  bool reset = false;
126 
127  const auto constRows = rows;
128  for ( int row : constRows )
129  {
130 #if 0
131  qDebug() << "Row: " << row << ", begin " << beginRow << ", last " << lastRow << ", current " << currentRowCount << ", removed " << removedRows;
132 #endif
133  if ( lastRow == -1 )
134  {
135  beginRow = row;
136  }
137 
138  if ( row != lastRow + 1 && lastRow != -1 )
139  {
140  if ( rows.count() > 100 && currentRowCount < 10 )
141  {
142  reset = true;
143  break;
144  }
145  removeRows( beginRow - removedRows, currentRowCount );
146 
147  beginRow = row;
148  removedRows += currentRowCount;
149  currentRowCount = 0;
150  }
151 
152  currentRowCount++;
153 
154  lastRow = row;
155  }
156 
157  if ( !reset )
158  removeRows( beginRow - removedRows, currentRowCount );
159  else
160  resetModel();
161 }
162 
163 bool QgsAttributeTableModel::removeRows( int row, int count, const QModelIndex &parent )
164 {
165 
166  if ( row < 0 || count < 1 )
167  return false;
168 
169  if ( !mResettingModel )
170  beginRemoveRows( parent, row, row + count - 1 );
171 
172 #ifdef QGISDEBUG
173  if ( 3 <= QgsLogger::debugLevel() )
174  QgsDebugMsgLevel( QStringLiteral( "remove %2 rows at %1 (rows %3, ids %4)" ).arg( row ).arg( count ).arg( mRowIdMap.size() ).arg( mIdRowMap.size() ), 3 );
175 #endif
176 
177  // clean old references
178  for ( int i = row; i < row + count; i++ )
179  {
180  for ( SortCache &cache : mSortCaches )
181  cache.sortCache.remove( mRowIdMap[i] );
182  mIdRowMap.remove( mRowIdMap[i] );
183  mRowIdMap.remove( i );
184  }
185 
186  // update maps
187  int n = mRowIdMap.size() + count;
188  for ( int i = row + count; i < n; i++ )
189  {
190  QgsFeatureId id = mRowIdMap[i];
191  mIdRowMap[id] -= count;
192  mRowIdMap[i - count] = id;
193  mRowIdMap.remove( i );
194  }
195 
196 #ifdef QGISDEBUG
197  if ( 4 <= QgsLogger::debugLevel() )
198  {
199  QgsDebugMsgLevel( QStringLiteral( "after removal rows %1, ids %2" ).arg( mRowIdMap.size() ).arg( mIdRowMap.size() ), 4 );
200  QgsDebugMsgLevel( QStringLiteral( "id->row" ), 4 );
201  for ( QHash<QgsFeatureId, int>::const_iterator it = mIdRowMap.constBegin(); it != mIdRowMap.constEnd(); ++it )
202  QgsDebugMsgLevel( QStringLiteral( "%1->%2" ).arg( FID_TO_STRING( it.key() ) ).arg( *it ), 4 );
203 
204  QgsDebugMsgLevel( QStringLiteral( "row->id" ), 4 );
205  for ( QHash<int, QgsFeatureId>::const_iterator it = mRowIdMap.constBegin(); it != mRowIdMap.constEnd(); ++it )
206  QgsDebugMsgLevel( QStringLiteral( "%1->%2" ).arg( it.key() ).arg( FID_TO_STRING( *it ) ), 4 );
207  }
208 #endif
209 
210  Q_ASSERT( mRowIdMap.size() == mIdRowMap.size() );
211 
212  if ( !mResettingModel )
213  endRemoveRows();
214 
215  return true;
216 }
217 
218 void QgsAttributeTableModel::featureAdded( QgsFeatureId fid )
219 {
220  QgsDebugMsgLevel( QStringLiteral( "(%2) fid: %1" ).arg( fid ).arg( mFeatureRequest.filterType() ), 4 );
221  bool featOk = true;
222 
223  if ( mFeat.id() != fid )
224  featOk = loadFeatureAtId( fid );
225 
226  if ( featOk && mFeatureRequest.acceptFeature( mFeat ) )
227  {
228  for ( SortCache &cache : mSortCaches )
229  {
230  if ( cache.sortFieldIndex >= 0 )
231  {
232  QgsFieldFormatter *fieldFormatter = mFieldFormatters.at( cache.sortFieldIndex );
233  const QVariant &widgetCache = mAttributeWidgetCaches.at( cache.sortFieldIndex );
234  const QVariantMap &widgetConfig = mWidgetConfigs.at( cache.sortFieldIndex );
235  QVariant sortValue = fieldFormatter->representValue( layer(), cache.sortFieldIndex, widgetConfig, widgetCache, mFeat.attribute( cache.sortFieldIndex ) );
236  cache.sortCache.insert( mFeat.id(), sortValue );
237  }
238  else if ( cache.sortCacheExpression.isValid() )
239  {
240  mExpressionContext.setFeature( mFeat );
241  cache.sortCache[mFeat.id()] = cache.sortCacheExpression.evaluate( &mExpressionContext );
242  }
243  }
244 
245  // Skip if the fid is already in the map (do not add twice)!
246  if ( ! mIdRowMap.contains( fid ) )
247  {
248  int n = mRowIdMap.size();
249  if ( !mResettingModel )
250  beginInsertRows( QModelIndex(), n, n );
251  mIdRowMap.insert( fid, n );
252  mRowIdMap.insert( n, fid );
253  if ( !mResettingModel )
254  endInsertRows();
255  reload( index( rowCount() - 1, 0 ), index( rowCount() - 1, columnCount() ) );
256  }
257  }
258 }
259 
260 void QgsAttributeTableModel::updatedFields()
261 {
262  loadAttributes();
263  emit modelChanged();
264 }
265 
266 void QgsAttributeTableModel::editCommandEnded()
267 {
268  // do not do reload(...) due would trigger (dataChanged) row sort
269  // giving issue: https://github.com/qgis/QGIS/issues/23892
270  bulkEditCommandEnded( );
271 }
272 
273 void QgsAttributeTableModel::attributeDeleted( int idx )
274 {
275  int cacheIndex = 0;
276  for ( const SortCache &cache : mSortCaches )
277  {
278  if ( cache.sortCacheAttributes.contains( idx ) )
279  {
280  prefetchSortData( QString(), cacheIndex );
281  }
282  cacheIndex++;
283  }
284 }
285 
286 void QgsAttributeTableModel::layerDeleted()
287 {
288  mLayerCache = nullptr;
289  removeRows( 0, rowCount() );
290 
291  mAttributeWidgetCaches.clear();
292  mAttributes.clear();
293  mWidgetFactories.clear();
294  mWidgetConfigs.clear();
295  mFieldFormatters.clear();
296 }
297 
298 void QgsAttributeTableModel::fieldFormatterRemoved( QgsFieldFormatter *fieldFormatter )
299 {
300  for ( int i = 0; i < mFieldFormatters.size(); ++i )
301  {
302  if ( mFieldFormatters.at( i ) == fieldFormatter )
304  }
305 }
306 
307 void QgsAttributeTableModel::attributeValueChanged( QgsFeatureId fid, int idx, const QVariant &value )
308 {
309  // Defer all updates if a bulk edit/rollback command is running
310  if ( mBulkEditCommandRunning )
311  {
312  mAttributeValueChanges.insert( QPair<QgsFeatureId, int>( fid, idx ), value );
313  return;
314  }
315  QgsDebugMsgLevel( QStringLiteral( "(%4) fid: %1, idx: %2, value: %3" ).arg( fid ).arg( idx ).arg( value.toString() ).arg( mFeatureRequest.filterType() ), 2 );
316 
317  for ( SortCache &cache : mSortCaches )
318  {
319  if ( cache.sortCacheAttributes.contains( idx ) )
320  {
321  if ( cache.sortFieldIndex == -1 )
322  {
323  if ( loadFeatureAtId( fid ) )
324  {
325  mExpressionContext.setFeature( mFeat );
326  cache.sortCache[fid] = cache.sortCacheExpression.evaluate( &mExpressionContext );
327  }
328  }
329  else
330  {
331  QgsFieldFormatter *fieldFormatter = mFieldFormatters.at( cache.sortFieldIndex );
332  const QVariant &widgetCache = mAttributeWidgetCaches.at( cache.sortFieldIndex );
333  const QVariantMap &widgetConfig = mWidgetConfigs.at( cache.sortFieldIndex );
334  QVariant sortValue = fieldFormatter->representValue( layer(), cache.sortFieldIndex, widgetConfig, widgetCache, value );
335  cache.sortCache.insert( fid, sortValue );
336  }
337  }
338  }
339  // No filter request: skip all possibly heavy checks
340  if ( mFeatureRequest.filterType() == QgsFeatureRequest::FilterNone )
341  {
342  if ( loadFeatureAtId( fid ) )
343  setData( index( idToRow( fid ), fieldCol( idx ) ), value, Qt::EditRole );
344  }
345  else
346  {
347  if ( loadFeatureAtId( fid ) )
348  {
349  if ( mFeatureRequest.acceptFeature( mFeat ) )
350  {
351  if ( !mIdRowMap.contains( fid ) )
352  {
353  // Feature changed in such a way, it will be shown now
354  featureAdded( fid );
355  }
356  else
357  {
358  // Update representation
359  setData( index( idToRow( fid ), fieldCol( idx ) ), value, Qt::EditRole );
360  }
361  }
362  else
363  {
364  if ( mIdRowMap.contains( fid ) )
365  {
366  // Feature changed such, that it is no longer shown
367  featuresDeleted( QgsFeatureIds() << fid );
368  }
369  // else: we don't care
370  }
371  }
372  }
373 }
374 
375 void QgsAttributeTableModel::loadAttributes()
376 {
377  if ( !layer() )
378  {
379  return;
380  }
381 
382  bool ins = false, rm = false;
383 
384  QgsAttributeList attributes;
385  const QgsFields &fields = layer()->fields();
386 
387  mWidgetFactories.clear();
388  mAttributeWidgetCaches.clear();
389  mWidgetConfigs.clear();
390 
391  for ( int idx = 0; idx < fields.count(); ++idx )
392  {
393  const QgsEditorWidgetSetup setup = QgsGui::editorWidgetRegistry()->findBest( layer(), fields[idx].name() );
394  QgsEditorWidgetFactory *widgetFactory = QgsGui::editorWidgetRegistry()->factory( setup.type() );
396 
397  mWidgetFactories.append( widgetFactory );
398  mWidgetConfigs.append( setup.config() );
399  mAttributeWidgetCaches.append( fieldFormatter->createCache( layer(), idx, setup.config() ) );
400  mFieldFormatters.append( fieldFormatter );
401 
402  attributes << idx;
403  }
404 
405  if ( mFieldCount + mExtraColumns < attributes.size() + mExtraColumns )
406  {
407  ins = true;
408  beginInsertColumns( QModelIndex(), mFieldCount + mExtraColumns, attributes.size() - 1 );
409  }
410  else if ( attributes.size() + mExtraColumns < mFieldCount + mExtraColumns )
411  {
412  rm = true;
413  beginRemoveColumns( QModelIndex(), attributes.size(), mFieldCount + mExtraColumns - 1 );
414  }
415 
416  mFieldCount = attributes.size();
417  mAttributes = attributes;
418 
419  for ( SortCache &cache : mSortCaches )
420  {
421  if ( cache.sortFieldIndex >= mAttributes.count() )
422  cache.sortFieldIndex = -1;
423  }
424 
425  if ( ins )
426  {
427  endInsertColumns();
428  }
429  else if ( rm )
430  {
431  endRemoveColumns();
432  }
433 }
434 
436 {
437  // make sure attributes are properly updated before caching the data
438  // (emit of progress() signal may enter event loop and thus attribute
439  // table view may be updated with inconsistent model which may assume
440  // wrong number of attributes)
441 
442  loadAttributes();
443 
444  mResettingModel = true;
445  beginResetModel();
446 
447  if ( rowCount() != 0 )
448  {
449  removeRows( 0, rowCount() );
450  }
451 
452  // Layer might have been deleted and cache set to nullptr!
453  if ( mLayerCache )
454  {
455  QgsFeatureIterator features = mLayerCache->getFeatures( mFeatureRequest );
456 
457  int i = 0;
458 
459  QElapsedTimer t;
460  t.start();
461 
462  while ( features.nextFeature( mFeat ) )
463  {
464  ++i;
465 
466  if ( t.elapsed() > 1000 )
467  {
468  bool cancel = false;
469  emit progress( i, cancel );
470  if ( cancel )
471  break;
472 
473  t.restart();
474  }
475  featureAdded( mFeat.id() );
476  }
477 
478  emit finished();
479  connect( mLayerCache, &QgsVectorLayerCache::invalidated, this, &QgsAttributeTableModel::loadLayer, Qt::UniqueConnection );
480  }
481 
482  endResetModel();
483 
484  mResettingModel = false;
485 }
486 
487 
489 {
490  if ( fieldName.isNull() )
491  {
492  mRowStylesMap.clear();
493  emit dataChanged( index( 0, 0 ), index( rowCount() - 1, columnCount() - 1 ) );
494  return;
495  }
496 
497  int fieldIndex = mLayerCache->layer()->fields().lookupField( fieldName );
498  if ( fieldIndex == -1 )
499  return;
500 
501  //whole column has changed
502  int col = fieldCol( fieldIndex );
503  emit dataChanged( index( 0, col ), index( rowCount() - 1, col ) );
504 }
505 
507 {
508  if ( a == b )
509  return;
510 
511  int rowA = idToRow( a );
512  int rowB = idToRow( b );
513 
514  //emit layoutAboutToBeChanged();
515 
516  mRowIdMap.remove( rowA );
517  mRowIdMap.remove( rowB );
518  mRowIdMap.insert( rowA, b );
519  mRowIdMap.insert( rowB, a );
520 
521  mIdRowMap.remove( a );
522  mIdRowMap.remove( b );
523  mIdRowMap.insert( a, rowB );
524  mIdRowMap.insert( b, rowA );
525  Q_ASSERT( mRowIdMap.size() == mIdRowMap.size() );
526 
527 
528  //emit layoutChanged();
529 }
530 
532 {
533  if ( !mIdRowMap.contains( id ) )
534  {
535  QgsDebugMsg( QStringLiteral( "idToRow: id %1 not in the map" ).arg( id ) );
536  return -1;
537  }
538 
539  return mIdRowMap[id];
540 }
541 
543 {
544  return index( idToRow( id ), 0 );
545 }
546 
548 {
549  QModelIndexList indexes;
550 
551  int row = idToRow( id );
552  int columns = columnCount();
553  indexes.reserve( columns );
554  for ( int column = 0; column < columns; ++column )
555  {
556  indexes.append( index( row, column ) );
557  }
558 
559  return indexes;
560 }
561 
563 {
564  if ( !mRowIdMap.contains( row ) )
565  {
566  QgsDebugMsg( QStringLiteral( "rowToId: row %1 not in the map" ).arg( row ) );
567  // return negative infinite (to avoid collision with newly added features)
568  return std::numeric_limits<int>::min();
569  }
570 
571  return mRowIdMap[row];
572 }
573 
575 {
576  return mAttributes[col];
577 }
578 
580 {
581  return mAttributes.indexOf( idx );
582 }
583 
584 int QgsAttributeTableModel::rowCount( const QModelIndex &parent ) const
585 {
586  Q_UNUSED( parent )
587  return mRowIdMap.size();
588 }
589 
590 int QgsAttributeTableModel::columnCount( const QModelIndex &parent ) const
591 {
592  Q_UNUSED( parent )
593  return std::max( 1, mFieldCount + mExtraColumns ); // if there are zero columns all model indices will be considered invalid
594 }
595 
596 QVariant QgsAttributeTableModel::headerData( int section, Qt::Orientation orientation, int role ) const
597 {
598  if ( !layer() )
599  return QVariant();
600 
601  if ( role == Qt::DisplayRole )
602  {
603  if ( orientation == Qt::Vertical ) //row
604  {
605  return QVariant( section );
606  }
607  else if ( section >= 0 && section < mFieldCount )
608  {
609  QString attributeName = layer()->fields().at( mAttributes.at( section ) ).displayName();
610  return QVariant( attributeName );
611  }
612  else
613  {
614  return tr( "extra column" );
615  }
616  }
617  else if ( role == Qt::ToolTipRole )
618  {
619  if ( orientation == Qt::Vertical )
620  {
621  // TODO show DisplayExpression
622  return tr( "Feature ID: %1" ).arg( rowToId( section ) );
623  }
624  else
625  {
626  const QgsField field = layer()->fields().at( mAttributes.at( section ) );
628  }
629  }
630  else
631  {
632  return QVariant();
633  }
634 }
635 
636 QVariant QgsAttributeTableModel::data( const QModelIndex &index, int role ) const
637 {
638  if ( !index.isValid() || !layer() ||
639  ( role != Qt::TextAlignmentRole
640  && role != Qt::DisplayRole
641  && role != Qt::ToolTipRole
642  && role != Qt::EditRole
643  && role != FeatureIdRole
644  && role != FieldIndexRole
645 #if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
646  && role != Qt::BackgroundColorRole
647  && role != Qt::TextColorRole
648 #else
649  && role != Qt::BackgroundRole
650  && role != Qt::ForegroundRole
651 #endif
652  && role != Qt::DecorationRole
653  && role != Qt::FontRole
654  && role < SortRole
655  )
656  )
657  return QVariant();
658 
659  QgsFeatureId rowId = rowToId( index.row() );
660 
661  if ( role == FeatureIdRole )
662  return rowId;
663 
664  if ( index.column() >= mFieldCount )
665  return QVariant();
666 
667  int fieldId = mAttributes.at( index.column() );
668 
669  if ( role == FieldIndexRole )
670  return fieldId;
671 
672  if ( role >= SortRole )
673  {
674  unsigned long cacheIndex = role - SortRole;
675  if ( cacheIndex < mSortCaches.size() )
676  return mSortCaches.at( cacheIndex ).sortCache.value( rowId );
677  else
678  return QVariant();
679  }
680 
681  QgsField field = layer()->fields().at( fieldId );
682 
683  if ( role == Qt::TextAlignmentRole )
684  {
685  return QVariant( mFieldFormatters.at( index.column() )->alignmentFlag( layer(), fieldId, mWidgetConfigs.at( index.column() ) ) | Qt::AlignVCenter );
686  }
687 
688  if ( mFeat.id() != rowId || !mFeat.isValid() )
689  {
690  if ( !loadFeatureAtId( rowId ) )
691  return QVariant( "ERROR" );
692 
693  if ( mFeat.id() != rowId )
694  return QVariant( "ERROR" );
695  }
696 
697  QVariant val = mFeat.attribute( fieldId );
698 
699  switch ( role )
700  {
701  case Qt::DisplayRole:
702  case Qt::ToolTipRole:
703  return mFieldFormatters.at( index.column() )->representValue( layer(),
704  fieldId,
705  mWidgetConfigs.at( index.column() ),
706  mAttributeWidgetCaches.at( index.column() ),
707  val );
708 
709  case Qt::EditRole:
710  return val;
711 
712  case Qt::BackgroundRole:
713 #if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
714  case Qt::TextColorRole:
715 #else
716  case Qt::ForegroundRole:
717 #endif
718  case Qt::DecorationRole:
719  case Qt::FontRole:
720  {
721  mExpressionContext.setFeature( mFeat );
722  QList<QgsConditionalStyle> styles;
723  if ( mRowStylesMap.contains( mFeat.id() ) )
724  {
725  styles = mRowStylesMap[mFeat.id()];
726  }
727  else
728  {
729  styles = QgsConditionalStyle::matchingConditionalStyles( layer()->conditionalStyles()->rowStyles(), QVariant(), mExpressionContext );
730  mRowStylesMap.insert( mFeat.id(), styles );
731  }
732 
734  styles = layer()->conditionalStyles()->fieldStyles( field.name() );
735  styles = QgsConditionalStyle::matchingConditionalStyles( styles, val, mExpressionContext );
736  styles.insert( 0, rowstyle );
738 
739  if ( style.isValid() )
740  {
741  if ( role == Qt::BackgroundRole && style.validBackgroundColor() )
742  return style.backgroundColor();
743 #if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
744  if ( role == Qt::TextColorRole && style.validTextColor() )
745 #else
746  if ( role == Qt::ForegroundRole && style.validTextColor() )
747 #endif
748  return style.textColor();
749  if ( role == Qt::DecorationRole )
750  return style.icon();
751  if ( role == Qt::FontRole )
752  return style.font();
753  }
754 
755  return QVariant();
756  }
757  }
758 
759  return QVariant();
760 }
761 
762 bool QgsAttributeTableModel::setData( const QModelIndex &index, const QVariant &value, int role )
763 {
764  Q_UNUSED( value )
765 
766  if ( !index.isValid() || index.column() >= mFieldCount || role != Qt::EditRole || !layer()->isEditable() )
767  return false;
768 
769  if ( !layer()->isModified() )
770  return false;
771 
772  mRowStylesMap.remove( mFeat.id() );
773 
774  return true;
775 }
776 
777 Qt::ItemFlags QgsAttributeTableModel::flags( const QModelIndex &index ) const
778 {
779  if ( !index.isValid() )
780  return Qt::ItemIsEnabled;
781 
782  if ( index.column() >= mFieldCount || !layer() )
783  return Qt::NoItemFlags;
784 
785  Qt::ItemFlags flags = QAbstractTableModel::flags( index );
786 
787  const int fieldIndex = mAttributes[index.column()];
788  const QgsFeatureId fid = rowToId( index.row() );
789 
790  if ( QgsVectorLayerUtils::fieldIsEditable( layer(), fieldIndex, fid ) )
791  flags |= Qt::ItemIsEditable;
792 
793  return flags;
794 }
795 
796 void QgsAttributeTableModel::bulkEditCommandStarted()
797 {
798  mBulkEditCommandRunning = true;
799  mAttributeValueChanges.clear();
800 }
801 
802 void QgsAttributeTableModel::bulkEditCommandEnded()
803 {
804  mBulkEditCommandRunning = false;
805  // Full model update if the changed rows are more than half the total rows
806  // or if their count is > layer cache size
807  int changeCount( mAttributeValueChanges.count() );
808  bool fullModelUpdate = changeCount > mLayerCache->cacheSize() ||
809  changeCount > rowCount() * 0.5;
810 
811  QgsDebugMsgLevel( QStringLiteral( "Bulk edit command ended with %1 modified rows over (%4), cache size is %2, starting %3 update." )
812  .arg( changeCount )
813  .arg( mLayerCache->cacheSize() )
814  .arg( fullModelUpdate ? QStringLiteral( "full" ) : QStringLiteral( "incremental" ) )
815  .arg( rowCount() ),
816  3 );
817  // Invalidates the whole model
818  if ( fullModelUpdate )
819  {
820  // Invalidates the cache (there is no API for doing this directly)
821  emit mLayerCache->layer()->dataChanged();
822  emit dataChanged( createIndex( 0, 0 ), createIndex( rowCount() - 1, columnCount() - 1 ) );
823  }
824  else
825  {
826  int minRow = rowCount();
827  int minCol = columnCount();
828  int maxRow = 0;
829  int maxCol = 0;
830  const auto keys = mAttributeValueChanges.keys();
831  for ( const auto &key : keys )
832  {
833  attributeValueChanged( key.first, key.second, mAttributeValueChanges.value( key ) );
834  int row( idToRow( key.first ) );
835  int col( fieldCol( key.second ) );
836  minRow = std::min<int>( row, minRow );
837  minCol = std::min<int>( col, minCol );
838  maxRow = std::max<int>( row, maxRow );
839  maxCol = std::max<int>( col, maxCol );
840  }
841  emit dataChanged( createIndex( minRow, minCol ), createIndex( maxRow, maxCol ) );
842  }
843  mAttributeValueChanges.clear();
844 }
845 
846 void QgsAttributeTableModel::reload( const QModelIndex &index1, const QModelIndex &index2 )
847 {
848  mFeat.setId( std::numeric_limits<int>::min() );
849  emit dataChanged( index1, index2 );
850 }
851 
852 
853 void QgsAttributeTableModel::executeAction( QUuid action, const QModelIndex &idx ) const
854 {
855  QgsFeature f = feature( idx );
856  layer()->actions()->doAction( action, f, fieldIdx( idx.column() ) );
857 }
858 
859 void QgsAttributeTableModel::executeMapLayerAction( QgsMapLayerAction *action, const QModelIndex &idx ) const
860 {
861  QgsFeature f = feature( idx );
862  action->triggerForFeature( layer(), f );
863 }
864 
865 QgsFeature QgsAttributeTableModel::feature( const QModelIndex &idx ) const
866 {
867  QgsFeature f( mLayerCache->layer()->fields() );
868  f.initAttributes( mAttributes.size() );
869  f.setId( rowToId( idx.row() ) );
870  for ( int i = 0; i < mAttributes.size(); i++ )
871  {
872  f.setAttribute( mAttributes[i], data( index( idx.row(), i ), Qt::EditRole ) );
873  }
874 
875  return f;
876 }
877 
879 {
880  if ( column == -1 || column >= mAttributes.count() )
881  {
882  prefetchSortData( QString() );
883  }
884  else
885  {
886  prefetchSortData( QgsExpression::quotedColumnRef( mLayerCache->layer()->fields().at( mAttributes.at( column ) ).name() ) );
887  }
888 }
889 
890 void QgsAttributeTableModel::prefetchSortData( const QString &expressionString, unsigned long cacheIndex )
891 {
892  if ( cacheIndex >= mSortCaches.size() )
893  {
894  mSortCaches.resize( cacheIndex + 1 );
895  }
896  SortCache &cache = mSortCaches[cacheIndex];
897  cache.sortCache.clear();
898  cache.sortCacheAttributes.clear();
899  cache.sortFieldIndex = -1;
900  if ( !expressionString.isEmpty() )
901  cache.sortCacheExpression = QgsExpression( expressionString );
902  else
903  {
904  // no sorting
905  cache.sortCacheExpression = QgsExpression();
906  return;
907  }
908 
909  QgsFieldFormatter *fieldFormatter = nullptr;
910  QVariant widgetCache;
911  QVariantMap widgetConfig;
912 
913  if ( cache.sortCacheExpression.isField() )
914  {
915  QString fieldName = static_cast<const QgsExpressionNodeColumnRef *>( cache.sortCacheExpression.rootNode() )->name();
916  cache.sortFieldIndex = mLayerCache->layer()->fields().lookupField( fieldName );
917  }
918 
919  if ( cache.sortFieldIndex == -1 )
920  {
921  cache.sortCacheExpression.prepare( &mExpressionContext );
922 
923  const QSet<QString> &referencedColumns = cache.sortCacheExpression.referencedColumns();
924 
925  for ( const QString &col : referencedColumns )
926  {
927  cache.sortCacheAttributes.append( mLayerCache->layer()->fields().lookupField( col ) );
928  }
929  }
930  else
931  {
932  cache.sortCacheAttributes.append( cache.sortFieldIndex );
933 
934  widgetCache = mAttributeWidgetCaches.at( cache.sortFieldIndex );
935  widgetConfig = mWidgetConfigs.at( cache.sortFieldIndex );
936  fieldFormatter = mFieldFormatters.at( cache.sortFieldIndex );
937  }
938 
939  QgsFeatureRequest request = QgsFeatureRequest( mFeatureRequest )
941  .setSubsetOfAttributes( cache.sortCacheAttributes );
942  QgsFeatureIterator it = mLayerCache->getFeatures( request );
943 
944  QgsFeature f;
945  while ( it.nextFeature( f ) )
946  {
947  if ( cache.sortFieldIndex == -1 )
948  {
949  mExpressionContext.setFeature( f );
950  const QVariant cacheValue = cache.sortCacheExpression.evaluate( &mExpressionContext );
951  cache.sortCache.insert( f.id(), cacheValue );
952  }
953  else
954  {
955  QVariant sortValue = fieldFormatter->sortValue( layer(), cache.sortFieldIndex, widgetConfig, widgetCache, f.attribute( cache.sortFieldIndex ) );
956  cache.sortCache.insert( f.id(), sortValue );
957  }
958  }
959 }
960 
961 QString QgsAttributeTableModel::sortCacheExpression( unsigned long cacheIndex ) const
962 {
963  QString expressionString;
964 
965  if ( cacheIndex >= mSortCaches.size() )
966  return expressionString;
967 
968  const QgsExpression &expression = mSortCaches[cacheIndex].sortCacheExpression;
969 
970  if ( expression.isValid() )
971  expressionString = expression.expression();
972  else
973  expressionString = QString();
974 
975  return expressionString;
976 }
977 
979 {
980  mFeatureRequest = request;
981  if ( layer() && !layer()->isSpatial() )
982  mFeatureRequest.setFlags( mFeatureRequest.flags() | QgsFeatureRequest::NoGeometry );
983 }
984 
986 {
987  return mFeatureRequest;
988 }
QgsMapLayerAction::triggerForFeature
void triggerForFeature(QgsMapLayer *layer, const QgsFeature &feature)
Triggers the action with the specified layer and feature.
Definition: qgsmaplayeractionregistry.cpp:95
QgsFeatureRequest::NoGeometry
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
Definition: qgsfeaturerequest.h:81
qgsfields.h
qgsexpressioncontextutils.h
QgsExpressionContext::appendScopes
void appendScopes(const QList< QgsExpressionContextScope * > &scopes)
Appends a list of scopes to the end of the context.
Definition: qgsexpressioncontext.cpp:495
QgsGui::editorWidgetRegistry
static QgsEditorWidgetRegistry * editorWidgetRegistry()
Returns the global editor widget registry, used for managing all known edit widget factories.
Definition: qgsgui.cpp:74
qgsconditionalstyle.h
QgsAttributeTableModel::headerData
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
Returns header data.
Definition: qgsattributetablemodel.cpp:596
QgsFeature::id
Q_GADGET QgsFeatureId id
Definition: qgsfeature.h:64
QgsConditionalStyle::isValid
bool isValid() const
isValid Check if this rule is valid.
Definition: qgsconditionalstyle.h:243
QgsEditorWidgetFactory
Every attribute editor widget needs a factory, which inherits this class.
Definition: qgseditorwidgetfactory.h:43
QgsAttributeTableModel::idToIndexList
QModelIndexList idToIndexList(QgsFeatureId id) const
Definition: qgsattributetablemodel.cpp:547
QgsMapLayerAction
An action which can run on map layers.
Definition: qgsmaplayeractionregistry.h:35
QgsActionManager::doAction
void doAction(QUuid actionId, const QgsFeature &feature, int defaultValueIndex=0, const QgsExpressionContextScope &scope=QgsExpressionContextScope())
Does the given action.
Definition: qgsactionmanager.cpp:127
QgsFieldFormatter::createCache
virtual QVariant createCache(QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config) const
Create a cache for a given field.
Definition: qgsfieldformatter.cpp:64
QgsVectorLayerCache
This class caches features of a given QgsVectorLayer.
Definition: qgsvectorlayercache.h:46
QgsAttributeTableModel::progress
void progress(int i, bool &cancel)
QgsFeatureRequest::acceptFeature
bool acceptFeature(const QgsFeature &feature)
Check if a feature is accepted by this requests filter.
Definition: qgsfeaturerequest.cpp:271
qgsmapcanvas.h
QgsEditorWidgetSetup
Holder for the widget type and its configuration for a field.
Definition: qgseditorwidgetsetup.h:29
QgsWkbTypes::NullGeometry
@ NullGeometry
Definition: qgswkbtypes.h:146
QgsVectorLayer::featuresDeleted
void featuresDeleted(const QgsFeatureIds &fids)
Emitted when features have been deleted.
QgsFeature::setId
void setId(QgsFeatureId id)
Sets the feature ID for this feature.
Definition: qgsfeature.cpp:114
QgsFeature::initAttributes
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
Definition: qgsfeature.cpp:204
QgsDebugMsgLevel
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
qgsexpression.h
QgsFeatureRequest::flags
const Flags & flags() const
Definition: qgsfeaturerequest.h:503
qgsgui.h
QgsVectorLayer::beforeRollBack
void beforeRollBack()
Emitted before changes are rolled back.
QgsFeatureRequest::filterType
FilterType filterType() const
Returns the filter type which is currently set on this request.
Definition: qgsfeaturerequest.h:312
QgsExpressionNodeColumnRef
An expression node which takes it value from a feature's field.
Definition: qgsexpressionnodeimpl.h:401
qgssymbollayerutils.h
qgsfeatureiterator.h
QgsFields::count
int count() const
Returns number of items.
Definition: qgsfields.cpp:133
QgsFields
Container of fields for a vector layer.
Definition: qgsfields.h:45
QgsEditorWidgetSetup::config
QVariantMap config() const
Definition: qgseditorwidgetsetup.h:51
QgsExpression::isValid
bool isValid() const
Checks if this expression is valid.
Definition: qgsexpression.cpp:197
QgsVectorLayer::attributeDeleted
void attributeDeleted(int idx)
Will be emitted, when an attribute has been deleted from this vector layer.
qgsfieldformatterregistry.h
QgsAttributeTableModel::modelChanged
void modelChanged()
Model has been changed.
QgsFieldModel::fieldToolTipExtended
static QString fieldToolTipExtended(const QgsField &field, const QgsVectorLayer *layer)
Returns a HTML formatted tooltip string for a field, containing details like the field name,...
Definition: qgsfieldmodel.cpp:500
QgsExpressionContextUtils::globalProjectLayerScopes
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Definition: qgsexpressioncontextutils.cpp:307
QgsAttributeTableModel::QgsAttributeTableModel
QgsAttributeTableModel(QgsVectorLayerCache *layerCache, QObject *parent=nullptr)
Constructor.
Definition: qgsattributetablemodel.cpp:49
QgsFeatureRequest::setSubsetOfAttributes
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
Definition: qgsfeaturerequest.cpp:185
QgsAttributeTableModel::fieldIdx
int fieldIdx(int col) const
Gets field index from column.
Definition: qgsattributetablemodel.cpp:574
QgsVectorLayerCache::getFeatures
QgsFeatureIterator getFeatures(const QgsFeatureRequest &featureRequest=QgsFeatureRequest())
Query this VectorLayerCache for features.
Definition: qgsvectorlayercache.cpp:378
field
const QgsField & field
Definition: qgsfield.h:456
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsVectorLayerCache::invalidated
void invalidated()
The cache has been invalidated and cleared.
QgsFieldFormatter::sortValue
virtual QVariant sortValue(QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config, const QVariant &cache, const QVariant &value) const
If the default sort order should be overwritten for this widget, you can transform the value in here.
Definition: qgsfieldformatter.cpp:43
QgsAttributeTableModel::rowCount
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Returns the number of rows.
Definition: qgsattributetablemodel.cpp:584
FID_TO_STRING
#define FID_TO_STRING(fid)
Definition: qgsfeatureid.h:33
QgsAttributeTableModel::idToRow
int idToRow(QgsFeatureId id) const
Maps feature id to table row.
Definition: qgsattributetablemodel.cpp:531
QgsAttributeList
QList< int > QgsAttributeList
Definition: qgsfield.h:26
QgsAttributeTableModel::executeAction
void executeAction(QUuid action, const QModelIndex &idx) const
Execute an action.
Definition: qgsattributetablemodel.cpp:853
QgsField::name
QString name
Definition: qgsfield.h:59
QgsConditionalStyle
Conditional styling for a rule.
Definition: qgsconditionalstyle.h:113
QgsConditionalStyle::compressStyles
static QgsConditionalStyle compressStyles(const QList< QgsConditionalStyle > &styles)
Compress a list of styles into a single style.
Definition: qgsconditionalstyle.cpp:261
qgsvectorlayerjoininfo.h
QgsAttributeTableModel::executeMapLayerAction
void executeMapLayerAction(QgsMapLayerAction *action, const QModelIndex &idx) const
Execute a QgsMapLayerAction.
Definition: qgsattributetablemodel.cpp:859
qgsapplication.h
QgsVectorLayerCache::attributeValueChanged
void attributeValueChanged(QgsFeatureId fid, int field, const QVariant &value)
Emitted when an attribute is changed.
QgsAttributeTableModel::fieldCol
int fieldCol(int idx) const
Gets column from field index.
Definition: qgsattributetablemodel.cpp:579
QgsVectorLayer::fields
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Definition: qgsvectorlayer.cpp:3283
QgsEditorWidgetSetup::type
QString type() const
Definition: qgseditorwidgetsetup.h:46
QgsFeatureRequest
This class wraps a request for features to a vector layer (or directly its vector data provider).
Definition: qgsfeaturerequest.h:76
QgsConditionalStyle::icon
QPixmap icon() const
The icon set for style generated from the set symbol.
Definition: qgsconditionalstyle.h:191
QgsAttributeTableModel::FieldIndexRole
@ FieldIndexRole
Get the field index of this column.
Definition: qgsattributetablemodel.h:57
QgsLogger::debugLevel
static int debugLevel()
Reads the environment variable QGIS_DEBUG and converts it to int.
Definition: qgslogger.h:107
QgsAttributeTableModel::swapRows
void swapRows(QgsFeatureId a, QgsFeatureId b)
Swaps two rows.
Definition: qgsattributetablemodel.cpp:506
QgsAttributeTableModel::flags
Qt::ItemFlags flags(const QModelIndex &index) const override
Returns item flags for the index.
Definition: qgsattributetablemodel.cpp:777
qgsvectorlayerjoinbuffer.h
qgsactionmanager.h
QgsFeature::isValid
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:185
QgsAttributeTableModel::rowToId
QgsFeatureId rowToId(int row) const
Maps row to feature id.
Definition: qgsattributetablemodel.cpp:562
QgsAttributeTableModel::setRequest
void setRequest(const QgsFeatureRequest &request)
Set a request that will be used to fill this attribute table model.
Definition: qgsattributetablemodel.cpp:978
QgsConditionalStyle::validBackgroundColor
bool validBackgroundColor() const
Check if the background color is valid for render.
Definition: qgsconditionalstyle.cpp:228
QgsConditionalStyle::backgroundColor
QColor backgroundColor() const
The background color for style.
Definition: qgsconditionalstyle.h:216
qgsattributetablefiltermodel.h
QgsVectorLayerCache::featureAdded
void featureAdded(QgsFeatureId fid)
Emitted when a new feature has been added to the layer and this cache.
QgsVectorLayer::afterRollBack
void afterRollBack()
Emitted after changes are rolled back.
qgsvectordataprovider.h
QgsEditorWidgetRegistry::findBest
QgsEditorWidgetSetup findBest(const QgsVectorLayer *vl, const QString &fieldName) const
Find the best editor widget and its configuration for a given field.
Definition: qgseditorwidgetregistry.cpp:76
qgsvectorlayerutils.h
QgsAttributeTableModel::prefetchSortData
void prefetchSortData(const QString &expression, unsigned long cacheIndex=0)
Prefetches the entire data for an expression.
Definition: qgsattributetablemodel.cpp:890
QgsFeature::attribute
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:264
QgsAttributeTableModel::finished
void finished()
QgsVectorLayer::actions
QgsActionManager * actions()
Returns all layer actions defined on this layer.
Definition: qgsvectorlayer.h:730
QgsAttributeTableModel::setData
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
Updates data on given index.
Definition: qgsattributetablemodel.cpp:762
qgsattributetablemodel.h
QgsVectorLayerCache::layer
QgsVectorLayer * layer()
Returns the layer to which this cache belongs.
Definition: qgsvectorlayercache.cpp:179
QgsAttributeTableModel::extraColumns
int extraColumns() const
Empty extra columns to announce from this model.
Definition: qgsattributetablemodel.cpp:94
QgsAttributeTableModel::layer
QgsVectorLayer * layer() const
Returns the layer this model uses as backend.
Definition: qgsattributetablemodel.h:168
qgsrenderer.h
qgsmaplayeractionregistry.h
QgsAttributeTableModel::prefetchColumnData
void prefetchColumnData(int column)
Caches the entire data for one column.
Definition: qgsattributetablemodel.cpp:878
QgsAttributeTableModel::loadLayer
virtual void loadLayer()
Loads the layer into the model Preferably to be called, before using this model as source for any oth...
Definition: qgsattributetablemodel.cpp:435
QgsConditionalStyle::matchingConditionalStyles
static QList< QgsConditionalStyle > matchingConditionalStyles(const QList< QgsConditionalStyle > &styles, const QVariant &value, QgsExpressionContext &context)
Find and return the matching styles for the value and feature.
Definition: qgsconditionalstyle.cpp:238
QgsVectorLayerCache::featureAtId
bool featureAtId(QgsFeatureId featureId, QgsFeature &feature, bool skipCache=false)
Gets the feature at the given feature id.
Definition: qgsvectorlayercache.cpp:145
QgsFeatureIds
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:37
QgsEditorWidgetRegistry::factory
QgsEditorWidgetFactory * factory(const QString &widgetId)
Gets a factory for the given widget type id.
Definition: qgseditorwidgetregistry.cpp:172
QgsVectorLayerCache::cachedLayerDeleted
void cachedLayerDeleted()
Is emitted when the cached layer is deleted.
QgsAttributeTableModel::sortCacheExpression
QString sortCacheExpression(unsigned long cacheIndex=0) const
The expression which was used to fill the sorting cache at index cacheIndex.
Definition: qgsattributetablemodel.cpp:961
QgsApplication::fieldFormatterRegistry
static QgsFieldFormatterRegistry * fieldFormatterRegistry()
Gets the registry of available field formatters.
Definition: qgsapplication.cpp:2278
QgsConditionalStyle::font
QFont font() const
The font for the style.
Definition: qgsconditionalstyle.h:229
qgsvectorlayer.h
QgsAttributeTableModel::FeatureIdRole
@ FeatureIdRole
Get the feature id of the feature in this row.
Definition: qgsattributetablemodel.h:56
QgsMapLayer::dataChanged
void dataChanged()
Data of layer changed.
QgsFieldFormatter::representValue
virtual QString representValue(QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config, const QVariant &cache, const QVariant &value) const
Create a pretty String representation of the value.
Definition: qgsfieldformatter.cpp:24
QgsFeature::setAttribute
bool setAttribute(int field, const QVariant &attr)
Set an attribute's value by field index.
Definition: qgsfeature.cpp:213
qgseditorwidgetregistry.h
QgsAttributeTableModel::data
QVariant data(const QModelIndex &index, int role) const override
Returns data on the given index.
Definition: qgsattributetablemodel.cpp:636
QgsAttributeTableModel::feature
QgsFeature feature(const QModelIndex &idx) const
Returns the feature attributes at given model index.
Definition: qgsattributetablemodel.cpp:865
QgsVectorLayerCache::cacheSize
int cacheSize()
Returns the maximum number of features this cache will hold.
Definition: qgsvectorlayercache.cpp:58
QgsAttributeTableModel::fieldConditionalStyleChanged
void fieldConditionalStyleChanged(const QString &fieldName)
Handles updating the model when the conditional style for a field changes.
Definition: qgsattributetablemodel.cpp:488
qgsexpressionnodeimpl.h
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:374
QgsConditionalStyle::textColor
QColor textColor() const
The text color set for style.
Definition: qgsconditionalstyle.h:203
qgseditorwidgetfactory.h
QgsAttributeTableModel::reload
void reload(const QModelIndex &index1, const QModelIndex &index2)
Reloads the model data between indices.
Definition: qgsattributetablemodel.cpp:846
QgsVectorLayer::editCommandStarted
void editCommandStarted(const QString &text)
Signal emitted when a new edit command has been started.
QgsFieldFormatterRegistry::fallbackFieldFormatter
QgsFieldFormatter * fallbackFieldFormatter() const
Returns a basic fallback field formatter which can be used to represent any field in an unspectacular...
Definition: qgsfieldformatterregistry.cpp:77
QgsVectorLayerUtils::fieldIsEditable
static bool fieldIsEditable(const QgsVectorLayer *layer, int fieldIndex, const QgsFeature &feature)
Definition: qgsvectorlayerutils.cpp:861
QgsFieldFormatterRegistry::fieldFormatter
QgsFieldFormatter * fieldFormatter(const QString &id) const
Gets a field formatter by its id.
Definition: qgsfieldformatterregistry.cpp:72
qgsfieldmodel.h
QgsVectorLayer::conditionalStyles
QgsConditionalLayerStyles * conditionalStyles() const
Returns the conditional styles that are set for this layer.
Definition: qgsvectorlayer.cpp:988
QgsExpression::quotedColumnRef
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
Definition: qgsexpression.cpp:65
QgsAttributeTableModel::setExtraColumns
void setExtraColumns(int extraColumns)
Empty extra columns to announce from this model.
Definition: qgsattributetablemodel.cpp:99
QgsFeatureRequest::FilterNone
@ FilterNone
No filter is applied.
Definition: qgsfeaturerequest.h:92
QgsConditionalLayerStyles::fieldStyles
QList< QgsConditionalStyle > fieldStyles(const QString &fieldName) const
Returns the conditional styles set for the field with matching fieldName.
Definition: qgsconditionalstyle.cpp:50
qgstexteditwidgetfactory.h
QgsField::displayName
QString displayName() const
Returns the name to use when displaying this field.
Definition: qgsfield.cpp:88
QgsFeature
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:56
QgsVectorLayer::updatedFields
void updatedFields()
Emitted whenever the fields available from this layer have been changed.
QgsAttributeTableModel::SortRole
@ SortRole
Role used for sorting start here.
Definition: qgsattributetablemodel.h:60
QgsAttributeTableModel::removeRows
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
Remove rows.
Definition: qgsattributetablemodel.cpp:163
qgslogger.h
QgsAttributeTableModel::columnCount
int columnCount(const QModelIndex &parent=QModelIndex()) const override
Returns the number of columns.
Definition: qgsattributetablemodel.cpp:590
QgsFields::lookupField
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
Definition: qgsfields.cpp:344
QgsAttributeTableModel::request
const QgsFeatureRequest & request() const
Gets the the feature request.
Definition: qgsattributetablemodel.cpp:985
QgsFields::at
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:163
QgsAttributeTableModel::idToIndex
QModelIndex idToIndex(QgsFeatureId id) const
Definition: qgsattributetablemodel.cpp:542
QgsExpression
Class for parsing and evaluation of expressions (formerly called "search strings").
Definition: qgsexpression.h:105
QgsFeatureIterator
Wrapper for iterator of features from vector data provider or vector layer.
Definition: qgsfeatureiterator.h:265
QgsVectorLayer::geometryType
Q_INVOKABLE QgsWkbTypes::GeometryType geometryType() const
Returns point, line or polygon.
Definition: qgsvectorlayer.cpp:659
QgsConditionalStyle::validTextColor
bool validTextColor() const
Check if the text color is valid for render.
Definition: qgsconditionalstyle.cpp:233
QgsFieldFormatter
A field formatter helps to handle and display values for a field.
Definition: qgsfieldformatter.h:73
QgsFeatureRequest::setFlags
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.
Definition: qgsfeaturerequest.cpp:179
QgsExpression::expression
QString expression() const
Returns the original, unmodified expression string.
Definition: qgsexpression.cpp:57
QgsAttributeTableModel::resetModel
void resetModel()
Resets the model.
Definition: qgsattributetablemodel.h:130
QgsAttributeTableModel::layerCache
QgsVectorLayerCache * layerCache() const
Returns the layer cache this model uses as backend.
Definition: qgsattributetablemodel.h:173
qgsfieldformatter.h
QgsFeatureId
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
Definition: qgsfeatureid.h:28
QgsVectorLayer::editCommandEnded
void editCommandEnded()
Signal emitted, when an edit command successfully ended.
QgsExpressionContext::setFeature
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Definition: qgsexpressioncontext.cpp:521
QgsField
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:50