QGIS API Documentation  3.2.0-Bonn (bc43194)
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 
556 {
558 
561  {
562  mDataDefinedVectorLayer = nullptr;
563 
564  QString currentLayerIdentifier;
565  if ( QgsVectorLayer *currentLayer = mVectorLayer.get() )
566  currentLayerIdentifier = currentLayer->id();
567 
568  const QString layerIdentifier = mDataDefinedProperties.valueAsString( QgsLayoutObject::AttributeTableSourceLayer, context, currentLayerIdentifier );
569  QgsVectorLayer *ddLayer = qobject_cast< QgsVectorLayer * >( QgsLayoutUtils::mapLayerFromString( layerIdentifier, mLayout->project() ) );
570  if ( ddLayer )
571  mDataDefinedVectorLayer = ddLayer;
572  }
573 
575 }
576 
577 QVariant QgsLayoutItemAttributeTable::replaceWrapChar( const QVariant &variant ) const
578 {
579  //avoid converting variants to string if not required (try to maintain original type for sorting)
580  if ( mWrapString.isEmpty() || !variant.toString().contains( mWrapString ) )
581  return variant;
582 
583  QString replaced = variant.toString();
584  replaced.replace( mWrapString, QLatin1String( "\n" ) );
585  return replaced;
586 }
587 
589 {
590  switch ( mSource )
591  {
593  return mLayout->reportContext().layer();
595  {
596  if ( mDataDefinedVectorLayer )
597  return mDataDefinedVectorLayer;
598  else
599  return mVectorLayer.get();
600  }
602  {
603  QgsRelation relation = mLayout->project()->relationManager()->relation( mRelationId );
604  return relation.referencingLayer();
605  }
606  }
607  return nullptr;
608 }
609 
610 void QgsLayoutItemAttributeTable::removeLayer( const QString &layerId )
611 {
612  if ( mVectorLayer && mSource == QgsLayoutItemAttributeTable::LayerAttributes )
613  {
614  if ( layerId == mVectorLayer->id() )
615  {
616  mVectorLayer.setLayer( nullptr );
617  //remove existing columns
618  qDeleteAll( mColumns );
619  mColumns.clear();
620  }
621  }
622 }
623 
624 static bool columnsBySortRank( QPair<int, QgsLayoutTableColumn * > a, QPair<int, QgsLayoutTableColumn * > b )
625 {
626  return a.second->sortByRank() < b.second->sortByRank();
627 }
628 
629 QVector<QPair<int, bool> > QgsLayoutItemAttributeTable::sortAttributes() const
630 {
631  //generate list of all sorted columns
632  QVector< QPair<int, QgsLayoutTableColumn * > > sortedColumns;
633  int idx = 0;
634  for ( QgsLayoutTableColumn *column : mColumns )
635  {
636  if ( column->sortByRank() > 0 )
637  {
638  sortedColumns.append( qMakePair( idx, column ) );
639  }
640  idx++;
641  }
642 
643  //sort columns by rank
644  std::sort( sortedColumns.begin(), sortedColumns.end(), columnsBySortRank );
645 
646  //generate list of column index, bool for sort direction (to match 2.0 api)
647  QVector<QPair<int, bool> > attributesBySortRank;
648  for ( auto &column : qgis::as_const( sortedColumns ) )
649  {
650  attributesBySortRank.append( qMakePair( column.first,
651  column.second->sortOrder() == Qt::AscendingOrder ) );
652  }
653  return attributesBySortRank;
654 }
655 
657 {
658  if ( wrapString == mWrapString )
659  {
660  return;
661  }
662 
663  mWrapString = wrapString;
665  emit changed();
666 }
667 
668 bool QgsLayoutItemAttributeTable::writePropertiesToElement( QDomElement &tableElem, QDomDocument &doc, const QgsReadWriteContext &context ) const
669 {
670  if ( !QgsLayoutTable::writePropertiesToElement( tableElem, doc, context ) )
671  return false;
672 
673  tableElem.setAttribute( QStringLiteral( "source" ), QString::number( static_cast< int >( mSource ) ) );
674  tableElem.setAttribute( QStringLiteral( "relationId" ), mRelationId );
675  tableElem.setAttribute( QStringLiteral( "showUniqueRowsOnly" ), mShowUniqueRowsOnly );
676  tableElem.setAttribute( QStringLiteral( "showOnlyVisibleFeatures" ), mShowOnlyVisibleFeatures );
677  tableElem.setAttribute( QStringLiteral( "filterToAtlasIntersection" ), mFilterToAtlasIntersection );
678  tableElem.setAttribute( QStringLiteral( "maxFeatures" ), mMaximumNumberOfFeatures );
679  tableElem.setAttribute( QStringLiteral( "filterFeatures" ), mFilterFeatures ? QStringLiteral( "true" ) : QStringLiteral( "false" ) );
680  tableElem.setAttribute( QStringLiteral( "featureFilter" ), mFeatureFilter );
681  tableElem.setAttribute( QStringLiteral( "wrapString" ), mWrapString );
682 
683  if ( mMap )
684  {
685  tableElem.setAttribute( QStringLiteral( "mapUuid" ), mMap->uuid() );
686  }
687 
688  if ( mVectorLayer )
689  {
690  tableElem.setAttribute( QStringLiteral( "vectorLayer" ), mVectorLayer.layerId );
691  tableElem.setAttribute( QStringLiteral( "vectorLayerName" ), mVectorLayer.name );
692  tableElem.setAttribute( QStringLiteral( "vectorLayerSource" ), mVectorLayer.source );
693  tableElem.setAttribute( QStringLiteral( "vectorLayerProvider" ), mVectorLayer.provider );
694  }
695  return true;
696 }
697 
698 bool QgsLayoutItemAttributeTable::readPropertiesFromElement( const QDomElement &itemElem, const QDomDocument &doc, const QgsReadWriteContext &context )
699 {
700  QgsVectorLayer *prevLayer = sourceLayer();
701  if ( prevLayer )
702  {
703  //disconnect from previous layer
704  disconnect( prevLayer, &QgsVectorLayer::layerModified, this, &QgsLayoutTable::refreshAttributes );
705  }
706 
707  if ( !QgsLayoutTable::readPropertiesFromElement( itemElem, doc, context ) )
708  return false;
709 
710  mSource = QgsLayoutItemAttributeTable::ContentSource( itemElem.attribute( QStringLiteral( "source" ), QStringLiteral( "0" ) ).toInt() );
711  mRelationId = itemElem.attribute( QStringLiteral( "relationId" ), QLatin1String( "" ) );
712 
714  {
715  mCurrentAtlasLayer = mLayout->reportContext().layer();
716  }
717 
718  mShowUniqueRowsOnly = itemElem.attribute( QStringLiteral( "showUniqueRowsOnly" ), QStringLiteral( "0" ) ).toInt();
719  mShowOnlyVisibleFeatures = itemElem.attribute( QStringLiteral( "showOnlyVisibleFeatures" ), QStringLiteral( "1" ) ).toInt();
720  mFilterToAtlasIntersection = itemElem.attribute( QStringLiteral( "filterToAtlasIntersection" ), QStringLiteral( "0" ) ).toInt();
721  mFilterFeatures = itemElem.attribute( QStringLiteral( "filterFeatures" ), QStringLiteral( "false" ) ) == QLatin1String( "true" );
722  mFeatureFilter = itemElem.attribute( QStringLiteral( "featureFilter" ), QLatin1String( "" ) );
723  mMaximumNumberOfFeatures = itemElem.attribute( QStringLiteral( "maxFeatures" ), QStringLiteral( "5" ) ).toInt();
724  mWrapString = itemElem.attribute( QStringLiteral( "wrapString" ) );
725 
726  //map
727  mMapUuid = itemElem.attribute( QStringLiteral( "mapUuid" ) );
728  if ( mMap )
729  {
731  mMap = nullptr;
732  }
733  // setting new mMap occurs in finalizeRestoreFromXml
734 
735  //vector layer
736  QString layerId = itemElem.attribute( QStringLiteral( "vectorLayer" ) );
737  QString layerName = itemElem.attribute( QStringLiteral( "vectorLayerName" ) );
738  QString layerSource = itemElem.attribute( QStringLiteral( "vectorLayerSource" ) );
739  QString layerProvider = itemElem.attribute( QStringLiteral( "vectorLayerProvider" ) );
740  mVectorLayer = QgsVectorLayerRef( layerId, layerName, layerSource, layerProvider );
741  mVectorLayer.resolveWeakly( mLayout->project() );
742 
743  //connect to new layer
745 
747 
748  emit changed();
749  return true;
750 }
751 
753 {
754  if ( source == mSource )
755  {
756  return;
757  }
758 
759  QgsVectorLayer *prevLayer = sourceLayer();
760  mSource = source;
761  QgsVectorLayer *newLayer = sourceLayer();
762 
763  if ( newLayer != prevLayer )
764  {
765  //disconnect from previous layer
766  if ( prevLayer )
767  {
768  disconnect( prevLayer, &QgsVectorLayer::layerModified, this, &QgsLayoutTable::refreshAttributes );
769  }
770 
771  //connect to new layer
774  {
775  mCurrentAtlasLayer = newLayer;
776  }
777 
778  //layer has changed as a result of the source change, so reset column list
779  resetColumns();
780  }
781 
783  emit changed();
784 }
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:40
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
Gets 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.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
Attribute table source layer.
QgsFeatureRequest & setFilterFid(QgsFeatureId fid)
Sets 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.
QgsPropertyCollection mDataDefinedProperties
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.
Definition: qgsrectangle.h:419
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:85
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 QgsMapLayer * mapLayerFromString(const QString &string, QgsProject *project)
Resolves a string into a map layer from a given project.
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.
QString valueAsString(int key, const QgsExpressionContext &context, const QString &defaultString=QString(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a string...
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 refreshDataDefinedProperty(QgsLayoutObject::DataDefinedProperty property=QgsLayoutObject::AllProperties) override
Refreshes a data defined property for the multi frame by reevaluating the property&#39;s value and redraw...
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...
DataDefinedProperty
Data defined properties for different item types.
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)
Sets 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.
All properties for item.
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
virtual void refreshDataDefinedProperty(QgsLayoutObject::DataDefinedProperty property=QgsLayoutObject::AllProperties)
Refreshes a data defined property for the multi frame by reevaluating the property&#39;s value and redraw...