QGIS API Documentation  3.14.0-Pi (9f7028fd23)
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 ) );
627  return QgsFieldModel::fieldToolTipExtended( field, layer() );
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  && role != Qt::BackgroundColorRole
646  && role != Qt::TextColorRole
647  && role != Qt::DecorationRole
648  && role != Qt::FontRole
649  && role < SortRole
650  )
651  )
652  return QVariant();
653 
654  QgsFeatureId rowId = rowToId( index.row() );
655 
656  if ( role == FeatureIdRole )
657  return rowId;
658 
659  if ( index.column() >= mFieldCount )
660  return QVariant();
661 
662  int fieldId = mAttributes.at( index.column() );
663 
664  if ( role == FieldIndexRole )
665  return fieldId;
666 
667  if ( role >= SortRole )
668  {
669  unsigned long cacheIndex = role - SortRole;
670  if ( cacheIndex < mSortCaches.size() )
671  return mSortCaches.at( cacheIndex ).sortCache.value( rowId );
672  else
673  return QVariant();
674  }
675 
676  QgsField field = layer()->fields().at( fieldId );
677 
678  if ( role == Qt::TextAlignmentRole )
679  {
680  return QVariant( mFieldFormatters.at( index.column() )->alignmentFlag( layer(), fieldId, mWidgetConfigs.at( index.column() ) ) | Qt::AlignVCenter );
681  }
682 
683  if ( mFeat.id() != rowId || !mFeat.isValid() )
684  {
685  if ( !loadFeatureAtId( rowId ) )
686  return QVariant( "ERROR" );
687 
688  if ( mFeat.id() != rowId )
689  return QVariant( "ERROR" );
690  }
691 
692  QVariant val = mFeat.attribute( fieldId );
693 
694  switch ( role )
695  {
696  case Qt::DisplayRole:
697  case Qt::ToolTipRole:
698  return mFieldFormatters.at( index.column() )->representValue( layer(),
699  fieldId,
700  mWidgetConfigs.at( index.column() ),
701  mAttributeWidgetCaches.at( index.column() ),
702  val );
703 
704  case Qt::EditRole:
705  return val;
706 
707  case Qt::BackgroundRole:
708  case Qt::TextColorRole:
709  case Qt::DecorationRole:
710  case Qt::FontRole:
711  {
712  mExpressionContext.setFeature( mFeat );
713  QList<QgsConditionalStyle> styles;
714  if ( mRowStylesMap.contains( mFeat.id() ) )
715  {
716  styles = mRowStylesMap[mFeat.id()];
717  }
718  else
719  {
720  styles = QgsConditionalStyle::matchingConditionalStyles( layer()->conditionalStyles()->rowStyles(), QVariant(), mExpressionContext );
721  mRowStylesMap.insert( mFeat.id(), styles );
722  }
723 
725  styles = layer()->conditionalStyles()->fieldStyles( field.name() );
726  styles = QgsConditionalStyle::matchingConditionalStyles( styles, val, mExpressionContext );
727  styles.insert( 0, rowstyle );
729 
730  if ( style.isValid() )
731  {
732  if ( role == Qt::BackgroundRole && style.validBackgroundColor() )
733  return style.backgroundColor();
734  if ( role == Qt::TextColorRole && style.validTextColor() )
735  return style.textColor();
736  if ( role == Qt::DecorationRole )
737  return style.icon();
738  if ( role == Qt::FontRole )
739  return style.font();
740  }
741 
742  return QVariant();
743  }
744  }
745 
746  return QVariant();
747 }
748 
749 bool QgsAttributeTableModel::setData( const QModelIndex &index, const QVariant &value, int role )
750 {
751  Q_UNUSED( value )
752 
753  if ( !index.isValid() || index.column() >= mFieldCount || role != Qt::EditRole || !layer()->isEditable() )
754  return false;
755 
756  if ( !layer()->isModified() )
757  return false;
758 
759  mRowStylesMap.remove( mFeat.id() );
760 
761  return true;
762 }
763 
764 Qt::ItemFlags QgsAttributeTableModel::flags( const QModelIndex &index ) const
765 {
766  if ( !index.isValid() )
767  return Qt::ItemIsEnabled;
768 
769  if ( index.column() >= mFieldCount || !layer() )
770  return Qt::NoItemFlags;
771 
772  Qt::ItemFlags flags = QAbstractTableModel::flags( index );
773 
774  const int fieldIndex = mAttributes[index.column()];
775  const QgsFeatureId fid = rowToId( index.row() );
776 
777  if ( QgsVectorLayerUtils::fieldIsEditable( layer(), fieldIndex, fid ) )
778  flags |= Qt::ItemIsEditable;
779 
780  return flags;
781 }
782 
783 void QgsAttributeTableModel::bulkEditCommandStarted()
784 {
785  mBulkEditCommandRunning = true;
786  mAttributeValueChanges.clear();
787 }
788 
789 void QgsAttributeTableModel::bulkEditCommandEnded()
790 {
791  mBulkEditCommandRunning = false;
792  // Full model update if the changed rows are more than half the total rows
793  // or if their count is > layer cache size
794  int changeCount( mAttributeValueChanges.count() );
795  bool fullModelUpdate = changeCount > mLayerCache->cacheSize() ||
796  changeCount > rowCount() * 0.5;
797 
798  QgsDebugMsgLevel( QStringLiteral( "Bulk edit command ended with %1 modified rows over (%4), cache size is %2, starting %3 update." )
799  .arg( changeCount )
800  .arg( mLayerCache->cacheSize() )
801  .arg( fullModelUpdate ? QStringLiteral( "full" ) : QStringLiteral( "incremental" ) )
802  .arg( rowCount() ),
803  3 );
804  // Invalidates the whole model
805  if ( fullModelUpdate )
806  {
807  // Invalidates the cache (there is no API for doing this directly)
808  emit mLayerCache->layer()->dataChanged();
809  emit dataChanged( createIndex( 0, 0 ), createIndex( rowCount() - 1, columnCount() - 1 ) );
810  }
811  else
812  {
813  int minRow = rowCount();
814  int minCol = columnCount();
815  int maxRow = 0;
816  int maxCol = 0;
817  const auto keys = mAttributeValueChanges.keys();
818  for ( const auto &key : keys )
819  {
820  attributeValueChanged( key.first, key.second, mAttributeValueChanges.value( key ) );
821  int row( idToRow( key.first ) );
822  int col( fieldCol( key.second ) );
823  minRow = std::min<int>( row, minRow );
824  minCol = std::min<int>( col, minCol );
825  maxRow = std::max<int>( row, maxRow );
826  maxCol = std::max<int>( col, maxCol );
827  }
828  emit dataChanged( createIndex( minRow, minCol ), createIndex( maxRow, maxCol ) );
829  }
830  mAttributeValueChanges.clear();
831 }
832 
833 void QgsAttributeTableModel::reload( const QModelIndex &index1, const QModelIndex &index2 )
834 {
835  mFeat.setId( std::numeric_limits<int>::min() );
836  emit dataChanged( index1, index2 );
837 }
838 
839 
840 void QgsAttributeTableModel::executeAction( QUuid action, const QModelIndex &idx ) const
841 {
842  QgsFeature f = feature( idx );
843  layer()->actions()->doAction( action, f, fieldIdx( idx.column() ) );
844 }
845 
846 void QgsAttributeTableModel::executeMapLayerAction( QgsMapLayerAction *action, const QModelIndex &idx ) const
847 {
848  QgsFeature f = feature( idx );
849  action->triggerForFeature( layer(), f );
850 }
851 
852 QgsFeature QgsAttributeTableModel::feature( const QModelIndex &idx ) const
853 {
854  QgsFeature f;
855  f.initAttributes( mAttributes.size() );
856  f.setId( rowToId( idx.row() ) );
857  for ( int i = 0; i < mAttributes.size(); i++ )
858  {
859  f.setAttribute( mAttributes[i], data( index( idx.row(), i ), Qt::EditRole ) );
860  }
861 
862  return f;
863 }
864 
866 {
867  if ( column == -1 || column >= mAttributes.count() )
868  {
869  prefetchSortData( QString() );
870  }
871  else
872  {
873  prefetchSortData( QgsExpression::quotedColumnRef( mLayerCache->layer()->fields().at( mAttributes.at( column ) ).name() ) );
874  }
875 }
876 
877 void QgsAttributeTableModel::prefetchSortData( const QString &expressionString, unsigned long cacheIndex )
878 {
879  if ( cacheIndex >= mSortCaches.size() )
880  {
881  mSortCaches.resize( cacheIndex + 1 );
882  }
883  SortCache &cache = mSortCaches[cacheIndex];
884  cache.sortCache.clear();
885  cache.sortCacheAttributes.clear();
886  cache.sortFieldIndex = -1;
887  if ( !expressionString.isEmpty() )
888  cache.sortCacheExpression = QgsExpression( expressionString );
889  else
890  {
891  // no sorting
892  cache.sortCacheExpression = QgsExpression();
893  return;
894  }
895 
896  QgsFieldFormatter *fieldFormatter = nullptr;
897  QVariant widgetCache;
898  QVariantMap widgetConfig;
899 
900  if ( cache.sortCacheExpression.isField() )
901  {
902  QString fieldName = static_cast<const QgsExpressionNodeColumnRef *>( cache.sortCacheExpression.rootNode() )->name();
903  cache.sortFieldIndex = mLayerCache->layer()->fields().lookupField( fieldName );
904  }
905 
906  if ( cache.sortFieldIndex == -1 )
907  {
908  cache.sortCacheExpression.prepare( &mExpressionContext );
909 
910  const QSet<QString> &referencedColumns = cache.sortCacheExpression.referencedColumns();
911 
912  for ( const QString &col : referencedColumns )
913  {
914  cache.sortCacheAttributes.append( mLayerCache->layer()->fields().lookupField( col ) );
915  }
916  }
917  else
918  {
919  cache.sortCacheAttributes.append( cache.sortFieldIndex );
920 
921  widgetCache = mAttributeWidgetCaches.at( cache.sortFieldIndex );
922  widgetConfig = mWidgetConfigs.at( cache.sortFieldIndex );
923  fieldFormatter = mFieldFormatters.at( cache.sortFieldIndex );
924  }
925 
926  QgsFeatureRequest request = QgsFeatureRequest( mFeatureRequest )
928  .setSubsetOfAttributes( cache.sortCacheAttributes );
929  QgsFeatureIterator it = mLayerCache->getFeatures( request );
930 
931  QgsFeature f;
932  while ( it.nextFeature( f ) )
933  {
934  if ( cache.sortFieldIndex == -1 )
935  {
936  mExpressionContext.setFeature( f );
937  const QVariant cacheValue = cache.sortCacheExpression.evaluate( &mExpressionContext );
938  cache.sortCache.insert( f.id(), cacheValue );
939  }
940  else
941  {
942  QVariant sortValue = fieldFormatter->sortValue( layer(), cache.sortFieldIndex, widgetConfig, widgetCache, f.attribute( cache.sortFieldIndex ) );
943  cache.sortCache.insert( f.id(), sortValue );
944  }
945  }
946 }
947 
948 QString QgsAttributeTableModel::sortCacheExpression( unsigned long cacheIndex ) const
949 {
950  QString expressionString;
951 
952  if ( cacheIndex >= mSortCaches.size() )
953  return expressionString;
954 
955  const QgsExpression &expression = mSortCaches[cacheIndex].sortCacheExpression;
956 
957  if ( expression.isValid() )
958  expressionString = expression.expression();
959  else
960  expressionString = QString();
961 
962  return expressionString;
963 }
964 
966 {
967  mFeatureRequest = request;
968  if ( layer() && !layer()->isSpatial() )
969  mFeatureRequest.setFlags( mFeatureRequest.flags() | QgsFeatureRequest::NoGeometry );
970 }
971 
973 {
974  return mFeatureRequest;
975 }
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:107
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:73
qgsconditionalstyle.h
QgsAttributeTableModel::headerData
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
Returns header data.
Definition: qgsattributetablemodel.cpp:596
QgsConditionalStyle::isValid
bool isValid() const
isValid Check if this rule is valid.
Definition: qgsconditionalstyle.h:243
QgsEditorWidgetFactory
Definition: qgseditorwidgetfactory.h:42
QgsAttributeTableModel::idToIndexList
QModelIndexList idToIndexList(QgsFeatureId id) const
Definition: qgsattributetablemodel.cpp:547
QgsMapLayerAction
Definition: qgsmaplayeractionregistry.h:34
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
The cached features can be indexed by QgsAbstractCacheIndex.
Definition: qgsvectorlayercache.h:45
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:276
qgsmapcanvas.h
QgsEditorWidgetSetup
Definition: qgseditorwidgetsetup.h:28
QgsWkbTypes::NullGeometry
@ NullGeometry
Definition: qgswkbtypes.h:145
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:112
QgsFeature::initAttributes
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
Definition: qgsfeature.cpp:202
QgsDebugMsgLevel
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
qgsexpression.h
QgsFeatureRequest::flags
const Flags & flags() const
Definition: qgsfeaturerequest.h:516
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:325
QgsExpressionNodeColumnRef
An expression node which takes it value from a feature's field.
Definition: qgsexpressionnodeimpl.h:400
qgssymbollayerutils.h
qgsfeatureiterator.h
QgsFields::count
int count() const
Returns number of items.
Definition: qgsfields.cpp:133
QgsFields
Definition: qgsfields.h:44
QgsEditorWidgetSetup::config
QVariantMap config() const
Definition: qgseditorwidgetsetup.h:64
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:306
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:190
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
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:30
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:840
QgsField::name
QString name
Definition: qgsfield.h:59
QgsConditionalStyle
Definition: qgsconditionalstyle.h:112
QgsConditionalStyle::compressStyles
static QgsConditionalStyle compressStyles(const QList< QgsConditionalStyle > &styles)
Compress a list of styles into a single style.
Definition: qgsconditionalstyle.cpp:262
qgsvectorlayerjoininfo.h
QgsAttributeTableModel::executeMapLayerAction
void executeMapLayerAction(QgsMapLayerAction *action, const QModelIndex &idx) const
Execute a QgsMapLayerAction.
Definition: qgsattributetablemodel.cpp:846
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:3280
QgsFeature::id
QgsFeatureId id
Definition: qgsfeature.h:68
QgsEditorWidgetSetup::type
QString type() const
Definition: qgseditorwidgetsetup.h:59
QgsFeatureRequest
Definition: qgsfeaturerequest.h:75
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:105
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:764
qgsvectorlayerjoinbuffer.h
qgsactionmanager.h
QgsFeature::isValid
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:183
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:965
QgsConditionalStyle::validBackgroundColor
bool validBackgroundColor() const
Check if the background color is valid for render.
Definition: qgsconditionalstyle.cpp:229
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:877
QgsFeature::attribute
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:262
QgsAttributeTableModel::finished
void finished()
QgsVectorLayer::actions
QgsActionManager * actions()
Returns all layer actions defined on this layer.
Definition: qgsvectorlayer.h:719
QgsAttributeTableModel::setData
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
Updates data on given index.
Definition: qgsattributetablemodel.cpp:749
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:865
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:239
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:34
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:948
QgsApplication::fieldFormatterRegistry
static QgsFieldFormatterRegistry * fieldFormatterRegistry()
Gets the registry of available field formatters.
Definition: qgsapplication.cpp:2219
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:211
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:852
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:373
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:833
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:847
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:105
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:89
QgsFeature
Definition: qgsfeature.h:55
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:324
QgsAttributeTableModel::request
const QgsFeatureRequest & request() const
Gets the the feature request.
Definition: qgsattributetablemodel.cpp:972
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
Definition: qgsexpression.h:113
QgsFeatureIterator
Definition: qgsfeatureiterator.h:263
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:234
QgsFieldFormatter
Definition: qgsfieldformatter.h:72
QgsFeatureRequest::setFlags
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.
Definition: qgsfeaturerequest.cpp:184
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
Definition: qgsfeatureid.h:25
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
Definition: qgsfield.h:49