QGIS API Documentation  3.0.2-Girona (307d082)
qgslayoutitemattributetable.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayoutitemattributetable.cpp
3  -------------------------------
4  begin : November 2017
5  copyright : (C) 2017 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
19 #include "qgslayout.h"
20 #include "qgslayouttablecolumn.h"
21 #include "qgslayoutitemmap.h"
22 #include "qgslayoututils.h"
23 #include "qgsfeatureiterator.h"
24 #include "qgsvectorlayer.h"
25 #include "qgslayoutframe.h"
26 #include "qgsproject.h"
27 #include "qgsrelationmanager.h"
28 #include "qgsgeometry.h"
29 #include "qgsexception.h"
30 #include "qgsmapsettings.h"
31 
32 //QgsLayoutAttributeTableCompare
33 
35 
39 class CORE_EXPORT QgsLayoutAttributeTableCompare
40 {
41  public:
42 
46  QgsLayoutAttributeTableCompare() = default;
47  bool operator()( const QgsLayoutTableRow &m1, const QgsLayoutTableRow &m2 )
48  {
49  return ( mAscending ? qgsVariantLessThan( m1[mCurrentSortColumn], m2[mCurrentSortColumn] )
50  : qgsVariantGreaterThan( m1[mCurrentSortColumn], m2[mCurrentSortColumn] ) );
51  }
52 
56  void setSortColumn( int column ) { mCurrentSortColumn = column; }
57 
62  void setAscending( bool ascending ) { mAscending = ascending; }
63 
64  private:
65  int mCurrentSortColumn = 0;
66  bool mAscending = true;
67 };
68 
70 
71 //
72 // QgsLayoutItemAttributeTable
73 //
74 
76  : QgsLayoutTable( layout )
77 {
78  if ( mLayout )
79  {
80  connect( mLayout->project(), static_cast < void ( QgsProject::* )( const QString & ) >( &QgsProject::layerWillBeRemoved ), this, &QgsLayoutItemAttributeTable::removeLayer );
81 
82  //coverage layer change = regenerate columns
83  connect( &mLayout->reportContext(), &QgsLayoutReportContext::layerChanged, this, &QgsLayoutItemAttributeTable::atlasLayerChanged );
84  }
86 }
87 
89 {
91 }
92 
94 {
95  return QgsApplication::getThemeIcon( QStringLiteral( "/mLayoutItemTable.svg" ) );
96 }
97 
99 {
100  return new QgsLayoutItemAttributeTable( layout );
101 }
102 
104 {
105  return tr( "<Attribute table frame>" );
106 }
107 
109 {
110  if ( layer == mVectorLayer.get() )
111  {
112  //no change
113  return;
114  }
115 
116  QgsVectorLayer *prevLayer = sourceLayer();
117  mVectorLayer.setLayer( layer );
118 
119  if ( mSource == QgsLayoutItemAttributeTable::LayerAttributes && layer != prevLayer )
120  {
121  if ( prevLayer )
122  {
123  //disconnect from previous layer
124  disconnect( prevLayer, &QgsVectorLayer::layerModified, this, &QgsLayoutTable::refreshAttributes );
125  }
126 
127  //rebuild column list to match all columns from layer
128  resetColumns();
129 
130  //listen for modifications to layer and refresh table when they occur
131  connect( mVectorLayer.get(), &QgsVectorLayer::layerModified, this, &QgsLayoutTable::refreshAttributes );
132  }
133 
135  emit changed();
136 }
137 
139 {
140  if ( relationId == mRelationId )
141  {
142  //no change
143  return;
144  }
145 
146  QgsVectorLayer *prevLayer = sourceLayer();
147  mRelationId = relationId;
148  QgsRelation relation = mLayout->project()->relationManager()->relation( mRelationId );
149  QgsVectorLayer *newLayer = relation.referencingLayer();
150 
151  if ( mSource == QgsLayoutItemAttributeTable::RelationChildren && newLayer != prevLayer )
152  {
153  if ( prevLayer )
154  {
155  //disconnect from previous layer
156  disconnect( prevLayer, &QgsVectorLayer::layerModified, this, &QgsLayoutTable::refreshAttributes );
157  }
158 
159  //rebuild column list to match all columns from layer
160  resetColumns();
161 
162  //listen for modifications to layer and refresh table when they occur
164  }
165 
167  emit changed();
168 }
169 
170 void QgsLayoutItemAttributeTable::atlasLayerChanged( QgsVectorLayer *layer )
171 {
172  if ( mSource != QgsLayoutItemAttributeTable::AtlasFeature || layer == mCurrentAtlasLayer )
173  {
174  //nothing to do
175  return;
176  }
177 
178  //atlas feature mode, atlas layer changed, so we need to reset columns
179  if ( mCurrentAtlasLayer )
180  {
181  //disconnect from previous layer
182  disconnect( mCurrentAtlasLayer, &QgsVectorLayer::layerModified, this, &QgsLayoutTable::refreshAttributes );
183  }
184 
185  mCurrentAtlasLayer = layer;
186 
187  //rebuild column list to match all columns from layer
188  resetColumns();
190 
191  //listen for modifications to layer and refresh table when they occur
193 }
194 
196 {
198  if ( !source )
199  {
200  return;
201  }
202 
203  //remove existing columns
204  qDeleteAll( mColumns );
205  mColumns.clear();
206 
207  //rebuild columns list from vector layer fields
208  int idx = 0;
209  const QgsFields sourceFields = source->fields();
210  for ( const auto &field : sourceFields )
211  {
212  QString currentAlias = source->attributeDisplayName( idx );
213  std::unique_ptr< QgsLayoutTableColumn > col = qgis::make_unique< QgsLayoutTableColumn >();
214  col->setAttribute( field.name() );
215  col->setHeading( currentAlias );
216  mColumns.append( col.release() );
217  idx++;
218  }
219 }
220 
222 {
223  if ( map == mMap )
224  {
225  //no change
226  return;
227  }
228 
229  if ( mMap )
230  {
231  //disconnect from previous map
233  }
234  mMap = map;
235  if ( mMap )
236  {
237  //listen out for extent changes in linked map
239  }
241  emit changed();
242 }
243 
245 {
246  if ( features == mMaximumNumberOfFeatures )
247  {
248  return;
249  }
250 
251  mMaximumNumberOfFeatures = features;
253  emit changed();
254 }
255 
257 {
258  if ( uniqueOnly == mShowUniqueRowsOnly )
259  {
260  return;
261  }
262 
263  mShowUniqueRowsOnly = uniqueOnly;
265  emit changed();
266 }
267 
269 {
270  if ( visibleOnly == mShowOnlyVisibleFeatures )
271  {
272  return;
273  }
274 
275  mShowOnlyVisibleFeatures = visibleOnly;
277  emit changed();
278 }
279 
281 {
282  if ( filterToAtlas == mFilterToAtlasIntersection )
283  {
284  return;
285  }
286 
287  mFilterToAtlasIntersection = filterToAtlas;
289  emit changed();
290 }
291 
293 {
294  if ( filter == mFilterFeatures )
295  {
296  return;
297  }
298 
299  mFilterFeatures = filter;
301  emit changed();
302 }
303 
304 void QgsLayoutItemAttributeTable::setFeatureFilter( const QString &expression )
305 {
306  if ( expression == mFeatureFilter )
307  {
308  return;
309  }
310 
311  mFeatureFilter = expression;
313  emit changed();
314 }
315 
316 void QgsLayoutItemAttributeTable::setDisplayedFields( const QStringList &fields, bool refresh )
317 {
319  if ( !source )
320  {
321  return;
322  }
323 
324  //rebuild columns list, taking only fields contained in supplied list
325  qDeleteAll( mColumns );
326  mColumns.clear();
327 
328  const QgsFields layerFields = source->fields();
329 
330  if ( !fields.isEmpty() )
331  {
332  for ( const QString &field : fields )
333  {
334  int attrIdx = layerFields.lookupField( field );
335  if ( attrIdx < 0 )
336  continue;
337 
338  QString currentAlias = source->attributeDisplayName( attrIdx );
339  std::unique_ptr< QgsLayoutTableColumn > col = qgis::make_unique< QgsLayoutTableColumn >();
340  col->setAttribute( layerFields.at( attrIdx ).name() );
341  col->setHeading( currentAlias );
342  mColumns.append( col.release() );
343  }
344  }
345  else
346  {
347  //resetting, so add all attributes to columns
348  int idx = 0;
349  for ( const QgsField &field : layerFields )
350  {
351  QString currentAlias = source->attributeDisplayName( idx );
352  std::unique_ptr< QgsLayoutTableColumn > col = qgis::make_unique< QgsLayoutTableColumn >();
353  col->setAttribute( field.name() );
354  col->setHeading( currentAlias );
355  mColumns.append( col.release() );
356  idx++;
357  }
358  }
359 
360  if ( refresh )
361  {
363  }
364 }
365 
366 void QgsLayoutItemAttributeTable::restoreFieldAliasMap( const QMap<int, QString> &map )
367 {
369  if ( !source )
370  {
371  return;
372  }
373 
374  for ( QgsLayoutTableColumn *column : qgis::as_const( mColumns ) )
375  {
376  int attrIdx = source->fields().lookupField( column->attribute() );
377  if ( map.contains( attrIdx ) )
378  {
379  column->setHeading( map.value( attrIdx ) );
380  }
381  else
382  {
383  column->setHeading( source->attributeDisplayName( attrIdx ) );
384  }
385  }
386 }
387 
389 {
390  contents.clear();
391 
392  QgsVectorLayer *layer = sourceLayer();
393  if ( !layer )
394  {
395  //no source layer
396  return false;
397  }
398 
400  context.setFields( layer->fields() );
401 
402  //prepare filter expression
403  std::unique_ptr<QgsExpression> filterExpression;
404  bool activeFilter = false;
405  if ( mFilterFeatures && !mFeatureFilter.isEmpty() )
406  {
407  filterExpression = qgis::make_unique< QgsExpression >( mFeatureFilter );
408  if ( !filterExpression->hasParserError() )
409  {
410  activeFilter = true;
411  }
412  }
413 
414  QgsRectangle selectionRect;
415  if ( mMap && mShowOnlyVisibleFeatures )
416  {
417  selectionRect = mMap->extent();
418  if ( layer )
419  {
420  //transform back to layer CRS
421  QgsCoordinateTransform coordTransform( layer->crs(), mMap->crs(), mLayout->project() );
422  try
423  {
424  selectionRect = coordTransform.transformBoundingBox( selectionRect, QgsCoordinateTransform::ReverseTransform );
425  }
426  catch ( QgsCsException &cse )
427  {
428  Q_UNUSED( cse );
429  return false;
430  }
431  }
432  }
433 
434  QgsFeatureRequest req;
435 
437  {
438  QgsRelation relation = mLayout->project()->relationManager()->relation( mRelationId );
439  QgsFeature atlasFeature = mLayout->reportContext().feature();
440  req = relation.getRelatedFeaturesRequest( atlasFeature );
441  }
442 
443  if ( !selectionRect.isEmpty() )
444  req.setFilterRect( selectionRect );
445 
446  req.setFlags( mShowOnlyVisibleFeatures ? QgsFeatureRequest::ExactIntersect : QgsFeatureRequest::NoFlags );
447 
449  {
450  //source mode is current atlas feature
451  QgsFeature atlasFeature = mLayout->reportContext().feature();
452  req.setFilterFid( atlasFeature.id() );
453  }
454 
455  QgsFeature f;
456  int counter = 0;
457  QgsFeatureIterator fit = layer->getFeatures( req );
458 
459  while ( fit.nextFeature( f ) && counter < mMaximumNumberOfFeatures )
460  {
461  context.setFeature( f );
462  //check feature against filter
463  if ( activeFilter && filterExpression )
464  {
465  QVariant result = filterExpression->evaluate( &context );
466  // skip this feature if the filter evaluation is false
467  if ( !result.toBool() )
468  {
469  continue;
470  }
471  }
472  //check against atlas feature intersection
473  if ( mFilterToAtlasIntersection )
474  {
475  if ( !f.hasGeometry() )
476  {
477  continue;
478  }
479  QgsFeature atlasFeature = mLayout->reportContext().feature();
480  if ( !atlasFeature.hasGeometry() ||
481  !f.geometry().intersects( atlasFeature.geometry() ) )
482  {
483  //feature falls outside current atlas feature
484  continue;
485  }
486  }
487 
488  QgsLayoutTableRow currentRow;
489 
490  for ( QgsLayoutTableColumn *column : qgis::as_const( mColumns ) )
491  {
492  int idx = layer->fields().lookupField( column->attribute() );
493  if ( idx != -1 )
494  {
495  currentRow << replaceWrapChar( f.attributes().at( idx ) );
496  }
497  else
498  {
499  // Lets assume it's an expression
500  std::unique_ptr< QgsExpression > expression = qgis::make_unique< QgsExpression >( column->attribute() );
501  context.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "row_number" ), counter + 1, true ) );
502  expression->prepare( &context );
503  QVariant value = expression->evaluate( &context );
504  currentRow << value;
505  }
506  }
507 
508  if ( !mShowUniqueRowsOnly || !contentsContainsRow( contents, currentRow ) )
509  {
510  contents << currentRow;
511  ++counter;
512  }
513  }
514 
515  //sort the list, starting with the last attribute
516  QgsLayoutAttributeTableCompare c;
517  QVector< QPair<int, bool> > sortColumns = sortAttributes();
518  for ( int i = sortColumns.size() - 1; i >= 0; --i )
519  {
520  c.setSortColumn( sortColumns.at( i ).first );
521  c.setAscending( sortColumns.at( i ).second );
522  std::stable_sort( contents.begin(), contents.end(), c );
523  }
524 
526  return true;
527 }
528 
530 {
532 
533  if ( mSource == LayerAttributes )
534  {
535  context.appendScope( QgsExpressionContextUtils::layerScope( mVectorLayer.get() ) );
536  }
537 
538  return context;
539 }
540 
542 {
544  if ( !mMap && !mMapUuid.isEmpty() && mLayout )
545  {
546  mMap = qobject_cast< QgsLayoutItemMap *>( mLayout->itemByUuid( mMapUuid, true ) );
547  if ( mMap )
548  {
549  //if we have found a valid map item, listen out to extent changes on it and refresh the table
551  }
552  }
553 }
554 
555 QVariant QgsLayoutItemAttributeTable::replaceWrapChar( const QVariant &variant ) const
556 {
557  //avoid converting variants to string if not required (try to maintain original type for sorting)
558  if ( mWrapString.isEmpty() || !variant.toString().contains( mWrapString ) )
559  return variant;
560 
561  QString replaced = variant.toString();
562  replaced.replace( mWrapString, QLatin1String( "\n" ) );
563  return replaced;
564 }
565 
567 {
568  switch ( mSource )
569  {
571  return mLayout->reportContext().layer();
573  return mVectorLayer.get();
575  {
576  QgsRelation relation = mLayout->project()->relationManager()->relation( mRelationId );
577  return relation.referencingLayer();
578  }
579  }
580  return nullptr;
581 }
582 
583 void QgsLayoutItemAttributeTable::removeLayer( const QString &layerId )
584 {
585  if ( mVectorLayer && mSource == QgsLayoutItemAttributeTable::LayerAttributes )
586  {
587  if ( layerId == mVectorLayer->id() )
588  {
589  mVectorLayer.setLayer( nullptr );
590  //remove existing columns
591  qDeleteAll( mColumns );
592  mColumns.clear();
593  }
594  }
595 }
596 
597 static bool columnsBySortRank( QPair<int, QgsLayoutTableColumn * > a, QPair<int, QgsLayoutTableColumn * > b )
598 {
599  return a.second->sortByRank() < b.second->sortByRank();
600 }
601 
602 QVector<QPair<int, bool> > QgsLayoutItemAttributeTable::sortAttributes() const
603 {
604  //generate list of all sorted columns
605  QVector< QPair<int, QgsLayoutTableColumn * > > sortedColumns;
606  int idx = 0;
607  for ( QgsLayoutTableColumn *column : mColumns )
608  {
609  if ( column->sortByRank() > 0 )
610  {
611  sortedColumns.append( qMakePair( idx, column ) );
612  }
613  idx++;
614  }
615 
616  //sort columns by rank
617  std::sort( sortedColumns.begin(), sortedColumns.end(), columnsBySortRank );
618 
619  //generate list of column index, bool for sort direction (to match 2.0 api)
620  QVector<QPair<int, bool> > attributesBySortRank;
621  for ( auto &column : qgis::as_const( sortedColumns ) )
622  {
623  attributesBySortRank.append( qMakePair( column.first,
624  column.second->sortOrder() == Qt::AscendingOrder ) );
625  }
626  return attributesBySortRank;
627 }
628 
630 {
631  if ( wrapString == mWrapString )
632  {
633  return;
634  }
635 
636  mWrapString = wrapString;
638  emit changed();
639 }
640 
641 bool QgsLayoutItemAttributeTable::writePropertiesToElement( QDomElement &tableElem, QDomDocument &doc, const QgsReadWriteContext &context ) const
642 {
643  if ( !QgsLayoutTable::writePropertiesToElement( tableElem, doc, context ) )
644  return false;
645 
646  tableElem.setAttribute( QStringLiteral( "source" ), QString::number( static_cast< int >( mSource ) ) );
647  tableElem.setAttribute( QStringLiteral( "relationId" ), mRelationId );
648  tableElem.setAttribute( QStringLiteral( "showUniqueRowsOnly" ), mShowUniqueRowsOnly );
649  tableElem.setAttribute( QStringLiteral( "showOnlyVisibleFeatures" ), mShowOnlyVisibleFeatures );
650  tableElem.setAttribute( QStringLiteral( "filterToAtlasIntersection" ), mFilterToAtlasIntersection );
651  tableElem.setAttribute( QStringLiteral( "maxFeatures" ), mMaximumNumberOfFeatures );
652  tableElem.setAttribute( QStringLiteral( "filterFeatures" ), mFilterFeatures ? QStringLiteral( "true" ) : QStringLiteral( "false" ) );
653  tableElem.setAttribute( QStringLiteral( "featureFilter" ), mFeatureFilter );
654  tableElem.setAttribute( QStringLiteral( "wrapString" ), mWrapString );
655 
656  if ( mMap )
657  {
658  tableElem.setAttribute( QStringLiteral( "mapUuid" ), mMap->uuid() );
659  }
660 
661  if ( mVectorLayer )
662  {
663  tableElem.setAttribute( QStringLiteral( "vectorLayer" ), mVectorLayer.layerId );
664  tableElem.setAttribute( QStringLiteral( "vectorLayerName" ), mVectorLayer.name );
665  tableElem.setAttribute( QStringLiteral( "vectorLayerSource" ), mVectorLayer.source );
666  tableElem.setAttribute( QStringLiteral( "vectorLayerProvider" ), mVectorLayer.provider );
667  }
668  return true;
669 }
670 
671 bool QgsLayoutItemAttributeTable::readPropertiesFromElement( const QDomElement &itemElem, const QDomDocument &doc, const QgsReadWriteContext &context )
672 {
673  QgsVectorLayer *prevLayer = sourceLayer();
674  if ( prevLayer )
675  {
676  //disconnect from previous layer
677  disconnect( prevLayer, &QgsVectorLayer::layerModified, this, &QgsLayoutTable::refreshAttributes );
678  }
679 
680  if ( !QgsLayoutTable::readPropertiesFromElement( itemElem, doc, context ) )
681  return false;
682 
683  mSource = QgsLayoutItemAttributeTable::ContentSource( itemElem.attribute( QStringLiteral( "source" ), QStringLiteral( "0" ) ).toInt() );
684  mRelationId = itemElem.attribute( QStringLiteral( "relationId" ), QLatin1String( "" ) );
685 
687  {
688  mCurrentAtlasLayer = mLayout->reportContext().layer();
689  }
690 
691  mShowUniqueRowsOnly = itemElem.attribute( QStringLiteral( "showUniqueRowsOnly" ), QStringLiteral( "0" ) ).toInt();
692  mShowOnlyVisibleFeatures = itemElem.attribute( QStringLiteral( "showOnlyVisibleFeatures" ), QStringLiteral( "1" ) ).toInt();
693  mFilterToAtlasIntersection = itemElem.attribute( QStringLiteral( "filterToAtlasIntersection" ), QStringLiteral( "0" ) ).toInt();
694  mFilterFeatures = itemElem.attribute( QStringLiteral( "filterFeatures" ), QStringLiteral( "false" ) ) == QLatin1String( "true" );
695  mFeatureFilter = itemElem.attribute( QStringLiteral( "featureFilter" ), QLatin1String( "" ) );
696  mMaximumNumberOfFeatures = itemElem.attribute( QStringLiteral( "maxFeatures" ), QStringLiteral( "5" ) ).toInt();
697  mWrapString = itemElem.attribute( QStringLiteral( "wrapString" ) );
698 
699  //map
700  mMapUuid = itemElem.attribute( QStringLiteral( "mapUuid" ) );
701  if ( mMap )
702  {
704  mMap = nullptr;
705  }
706  // setting new mMap occurs in finalizeRestoreFromXml
707 
708  //vector layer
709  QString layerId = itemElem.attribute( QStringLiteral( "vectorLayer" ) );
710  QString layerName = itemElem.attribute( QStringLiteral( "vectorLayerName" ) );
711  QString layerSource = itemElem.attribute( QStringLiteral( "vectorLayerSource" ) );
712  QString layerProvider = itemElem.attribute( QStringLiteral( "vectorLayerProvider" ) );
713  mVectorLayer = QgsVectorLayerRef( layerId, layerName, layerSource, layerProvider );
714  mVectorLayer.resolveWeakly( mLayout->project() );
715 
716  //connect to new layer
718 
720 
721  emit changed();
722  return true;
723 }
724 
726 {
727  if ( source == mSource )
728  {
729  return;
730  }
731 
732  QgsVectorLayer *prevLayer = sourceLayer();
733  mSource = source;
734  QgsVectorLayer *newLayer = sourceLayer();
735 
736  if ( newLayer != prevLayer )
737  {
738  //disconnect from previous layer
739  if ( prevLayer )
740  {
741  disconnect( prevLayer, &QgsVectorLayer::layerModified, this, &QgsLayoutTable::refreshAttributes );
742  }
743 
744  //connect to new layer
747  {
748  mCurrentAtlasLayer = newLayer;
749  }
750 
751  //layer has changed as a result of the source change, so reset column list
752  resetColumns();
753  }
754 
756  emit changed();
757 }
int lookupField(const QString &fieldName) const
Look up field&#39;s index from the field name.
Definition: qgsfields.cpp:299
QString displayName() const override
Returns the multiframe display name.
QgsFeatureId id
Definition: qgsfeature.h:71
The class is used as a container of context for various read/write operations on other objects...
Wrapper for iterator of features from vector data provider or vector layer.
Single variable definition for use within a QgsExpressionContextScope.
A rectangle specified with double values.
Definition: qgsrectangle.h:39
QString relationId() const
Returns the relation id which the table displays child features from.
QgsExpressionContext createExpressionContext() const override
Creates an expression context relating to the objects&#39; current state.
void setMaximumNumberOfFeatures(int features)
Sets the maximum number of features shown by the table.
QString name
Definition: qgsfield.h:57
Use exact geometry intersection (slower) instead of bounding boxes.
int type() const override
Returns unique multiframe type id.
A class to display a table in the print layout, and allow the table to span over multiple frames...
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
void extentChanged()
Is emitted when the map&#39;s extent changes.
QgsVectorLayer referencingLayer
Definition: qgsrelation.h:43
bool writePropertiesToElement(QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context) const override
Stores multiframe state within an XML DOM element.
TYPE * resolveWeakly(const QgsProject *project)
Resolves the map layer by attempting to find a matching layer in a project using a weak match...
virtual void refreshAttributes()
Refreshes the contents shown in the table by querying for new data.
Container of fields for a vector layer.
Definition: qgsfields.h:42
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
bool readPropertiesFromElement(const QDomElement &itemElem, const QDomDocument &doc, const QgsReadWriteContext &context) override
Sets multiframe state from a DOM element.
Table shows attributes from related child features.
QString wrapString() const
Returns the string used to wrap the contents of the table cells by.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:62
bool qgsVariantGreaterThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is greater than the second.
Definition: qgis.cpp:214
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:190
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
Table shows attributes from features in a vector layer.
bool qgsVariantLessThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is less than the second.
Definition: qgis.cpp:146
Stores properties of a column for a QgsLayoutTable.
QgsField at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:145
void setFilterToAtlasFeature(bool filterToAtlas)
Sets attribute table to only show features which intersect the current atlas feature.
void resetColumns()
Resets the attribute table&#39;s columns to match the vector layer&#39;s fields.
bool intersects(const QgsRectangle &rectangle) const
Returns true if this geometry exactly intersects with a rectangle.
QgsFeatureRequest & setFilterFid(QgsFeatureId fid)
Set feature ID that should be fetched.
QgsExpressionContextScope * lastScope()
Returns the last scope added to the context.
QgsRectangle extent() const
Returns the current map extent.
Layout graphical items for displaying a map.
QString provider
Weak reference to layer provider.
QString layerId
Original layer ID.
QString id() const
Returns the layer&#39;s unique ID, which is used to access this layer from QgsProject.
const QgsLayout * layout() const
Returns the layout the object is attached to.
QgsFields fields() const override
Returns the list of fields of this layer.
bool isEmpty() const
Returns true if the rectangle is empty.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QString name
Weak reference to layer name.
void setFeatureFilter(const QString &expression)
Sets the expression used for filtering features in the table.
QPointer< QgsLayout > mLayout
QgsVectorLayer * sourceLayer() const
Returns the source layer for the table, considering the table source mode.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
void setFilterFeatures(bool filter)
Sets whether the feature filter is active for the attribute table.
void setDisplayOnlyVisibleFeatures(bool visibleOnly)
Sets the attribute table to only show features which are visible in a map item.
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
QgsCoordinateReferenceSystem crs() const
Returns the layer&#39;s spatial reference system.
Reads and writes project states.
Definition: qgsproject.h:82
A layout table subclass that displays attributes from a vector layer.
Table shows attributes from the current atlas feature.
void layerChanged(QgsVectorLayer *layer)
Emitted when the context&#39;s layer is changed.
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:48
QgsFeatureRequest getRelatedFeaturesRequest(const QgsFeature &feature) const
Creates a request to return all the features on the referencing (child) layer which have a foreign ke...
QgsGeometry geometry() const
Returns the geometry associated with this feature.
Definition: qgsfeature.cpp:101
virtual void finalizeRestoreFromXml()
Called after all pending items have been restored from XML.
void setLayer(TYPE *l)
Sets the reference to point to a specified layer.
QString source
Weak reference to layer public source.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition: qgslayout.h:49
static QgsLayoutItemAttributeTable * create(QgsLayout *layout)
Returns a new QgsLayoutItemAttributeTable for the specified parent layout.
void setFields(const QgsFields &fields)
Convenience function for setting a fields for the context.
QVector< QPair< int, bool > > sortAttributes() const
Returns the attributes used to sort the table&#39;s features.
void setVectorLayer(QgsVectorLayer *layer)
Sets the vector layer from which to display feature attributes.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
void setSource(ContentSource source)
Sets the source for attributes to show in table body.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const override
Query the layer for features specified in request.
void setDisplayedFields(const QStringList &fields, bool refresh=true)
Sets the attributes to display in the table.
void layerWillBeRemoved(const QString &layerId)
Emitted when a layer is about to be removed from the registry.
QgsLayoutTableColumns mColumns
Columns to show in table.
void setUniqueRowsOnly(bool uniqueOnly)
Sets attribute table to only show unique rows.
void finalizeRestoreFromXml() override
Called after all pending items have been restored from XML.
Transform from destination to source CRS.
QgsLayoutTableContents & contents()
Returns the current contents of the table.
bool writePropertiesToElement(QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context) const override
Stores multiframe state within an XML DOM element.
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used for rendering the map.
QgsLayoutItemAttributeTable(QgsLayout *layout)
Constructor for QgsLayoutItemAttributeTable, attached to the specified layout.
void setWrapString(const QString &wrapString)
Sets a string to wrap the contents of the table cells by.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
virtual QString uuid() const
Returns the item identification string.
_LayerRef< QgsVectorLayer > QgsVectorLayerRef
Class for doing transforms between two map coordinate systems.
void setRelationId(const QString &id)
Sets the relation id from which to display child features.
void setMap(QgsLayoutItemMap *map)
Sets a layout map to use to limit the extent of features shown in the attribute table.
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65
ContentSource
Specifies the content source for the attribute table.
ContentSource source() const
Returns the source for attributes shown in the table body.
QgsLayoutItemMap * map() const
Returns the layout map whose extents are controlling the features shown in the table.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
bool nextFeature(QgsFeature &f)
void changed()
Emitted when the object&#39;s properties change.
Represents a vector layer which manages a vector based data sets.
TYPE * get() const
Returns a pointer to the layer, or nullptr if the reference has not yet been matched to a layer...
bool getTableContents(QgsLayoutTableContents &contents) override
Queries the attribute table&#39;s vector layer for attributes to show in the table.
QIcon icon() const override
Returns the item&#39;s icon.
void layerModified()
This signal is emitted when modifications has been done on layer.
QString attributeDisplayName(int index) const
Convenience function that returns the attribute alias if defined or the field name else...
bool contentsContainsRow(const QgsLayoutTableContents &contents, const QgsLayoutTableRow &row) const
Checks whether a table contents contains a given row.
QgsAttributes attributes
Definition: qgsfeature.h:72
QVector< QgsLayoutTableRow > QgsLayoutTableContents
List of QgsLayoutTableRows, representing rows and column cell contents for a QgsLayoutTable.
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Set flags that affect how features will be fetched.
bool readPropertiesFromElement(const QDomElement &itemElem, const QDomDocument &doc, const QgsReadWriteContext &context) override
Sets multiframe state from a DOM element.
QVector< QVariant > QgsLayoutTableRow
List of QVariants, representing a the contents of a single row in a QgsComposerTable.
void recalculateTableSize()
Recalculates and updates the size of the table and all table frames.
void refresh() override