QGIS API Documentation  3.6.0-Noosa (5873452)
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"
32 
33 //QgsLayoutAttributeTableCompare
34 
36 
40 class CORE_EXPORT QgsLayoutAttributeTableCompare
41 {
42  public:
43 
47  QgsLayoutAttributeTableCompare() = default;
48  bool operator()( const QgsLayoutTableRow &m1, const QgsLayoutTableRow &m2 )
49  {
50  return ( mAscending ? qgsVariantLessThan( m1[mCurrentSortColumn], m2[mCurrentSortColumn] )
51  : qgsVariantGreaterThan( m1[mCurrentSortColumn], m2[mCurrentSortColumn] ) );
52  }
53 
57  void setSortColumn( int column ) { mCurrentSortColumn = column; }
58 
63  void setAscending( bool ascending ) { mAscending = ascending; }
64 
65  private:
66  int mCurrentSortColumn = 0;
67  bool mAscending = true;
68 };
69 
71 
72 //
73 // QgsLayoutItemAttributeTable
74 //
75 
77  : QgsLayoutTable( layout )
78 {
79  if ( mLayout )
80  {
81  connect( mLayout->project(), static_cast < void ( QgsProject::* )( const QString & ) >( &QgsProject::layerWillBeRemoved ), this, &QgsLayoutItemAttributeTable::removeLayer );
82 
83  //coverage layer change = regenerate columns
84  connect( &mLayout->reportContext(), &QgsLayoutReportContext::layerChanged, this, &QgsLayoutItemAttributeTable::atlasLayerChanged );
85  }
87 }
88 
90 {
92 }
93 
95 {
96  return QgsApplication::getThemeIcon( QStringLiteral( "/mLayoutItemTable.svg" ) );
97 }
98 
100 {
101  return new QgsLayoutItemAttributeTable( layout );
102 }
103 
105 {
106  return tr( "<Attribute table frame>" );
107 }
108 
110 {
111  if ( layer == mVectorLayer.get() )
112  {
113  //no change
114  return;
115  }
116 
117  QgsVectorLayer *prevLayer = sourceLayer();
118  mVectorLayer.setLayer( layer );
119 
120  if ( mSource == QgsLayoutItemAttributeTable::LayerAttributes && layer != prevLayer )
121  {
122  if ( prevLayer )
123  {
124  //disconnect from previous layer
125  disconnect( prevLayer, &QgsVectorLayer::layerModified, this, &QgsLayoutTable::refreshAttributes );
126  }
127 
128  //rebuild column list to match all columns from layer
129  resetColumns();
130 
131  //listen for modifications to layer and refresh table when they occur
132  connect( mVectorLayer.get(), &QgsVectorLayer::layerModified, this, &QgsLayoutTable::refreshAttributes );
133  }
134 
136  emit changed();
137 }
138 
140 {
141  if ( relationId == mRelationId )
142  {
143  //no change
144  return;
145  }
146 
147  QgsVectorLayer *prevLayer = sourceLayer();
148  mRelationId = relationId;
149  QgsRelation relation = mLayout->project()->relationManager()->relation( mRelationId );
150  QgsVectorLayer *newLayer = relation.referencingLayer();
151 
152  if ( mSource == QgsLayoutItemAttributeTable::RelationChildren && newLayer != prevLayer )
153  {
154  if ( prevLayer )
155  {
156  //disconnect from previous layer
157  disconnect( prevLayer, &QgsVectorLayer::layerModified, this, &QgsLayoutTable::refreshAttributes );
158  }
159 
160  //rebuild column list to match all columns from layer
161  resetColumns();
162 
163  //listen for modifications to layer and refresh table when they occur
165  }
166 
168  emit changed();
169 }
170 
171 void QgsLayoutItemAttributeTable::atlasLayerChanged( QgsVectorLayer *layer )
172 {
173  if ( mSource != QgsLayoutItemAttributeTable::AtlasFeature || layer == mCurrentAtlasLayer )
174  {
175  //nothing to do
176  return;
177  }
178 
179  //atlas feature mode, atlas layer changed, so we need to reset columns
180  if ( mCurrentAtlasLayer )
181  {
182  //disconnect from previous layer
183  disconnect( mCurrentAtlasLayer, &QgsVectorLayer::layerModified, this, &QgsLayoutTable::refreshAttributes );
184  }
185 
186  mCurrentAtlasLayer = layer;
187 
188  //rebuild column list to match all columns from layer
189  resetColumns();
191 
192  //listen for modifications to layer and refresh table when they occur
194 }
195 
197 {
199  if ( !source )
200  {
201  return;
202  }
203 
204  //remove existing columns
205  qDeleteAll( mColumns );
206  mColumns.clear();
207 
208  //rebuild columns list from vector layer fields
209  int idx = 0;
210  const QgsFields sourceFields = source->fields();
211  for ( const auto &field : sourceFields )
212  {
213  QString currentAlias = source->attributeDisplayName( idx );
214  std::unique_ptr< QgsLayoutTableColumn > col = qgis::make_unique< QgsLayoutTableColumn >();
215  col->setAttribute( field.name() );
216  col->setHeading( currentAlias );
217  mColumns.append( col.release() );
218  idx++;
219  }
220 }
221 
223 {
224  if ( map == mMap )
225  {
226  //no change
227  return;
228  }
229 
230  if ( mMap )
231  {
232  //disconnect from previous map
234  }
235  mMap = map;
236  if ( mMap )
237  {
238  //listen out for extent changes in linked map
240  }
242  emit changed();
243 }
244 
246 {
247  if ( features == mMaximumNumberOfFeatures )
248  {
249  return;
250  }
251 
252  mMaximumNumberOfFeatures = features;
254  emit changed();
255 }
256 
258 {
259  if ( uniqueOnly == mShowUniqueRowsOnly )
260  {
261  return;
262  }
263 
264  mShowUniqueRowsOnly = uniqueOnly;
266  emit changed();
267 }
268 
270 {
271  if ( visibleOnly == mShowOnlyVisibleFeatures )
272  {
273  return;
274  }
275 
276  mShowOnlyVisibleFeatures = visibleOnly;
278  emit changed();
279 }
280 
282 {
283  if ( filterToAtlas == mFilterToAtlasIntersection )
284  {
285  return;
286  }
287 
288  mFilterToAtlasIntersection = filterToAtlas;
290  emit changed();
291 }
292 
294 {
295  if ( filter == mFilterFeatures )
296  {
297  return;
298  }
299 
300  mFilterFeatures = filter;
302  emit changed();
303 }
304 
305 void QgsLayoutItemAttributeTable::setFeatureFilter( const QString &expression )
306 {
307  if ( expression == mFeatureFilter )
308  {
309  return;
310  }
311 
312  mFeatureFilter = expression;
314  emit changed();
315 }
316 
317 void QgsLayoutItemAttributeTable::setDisplayedFields( const QStringList &fields, bool refresh )
318 {
320  if ( !source )
321  {
322  return;
323  }
324 
325  //rebuild columns list, taking only fields contained in supplied list
326  qDeleteAll( mColumns );
327  mColumns.clear();
328 
329  const QgsFields layerFields = source->fields();
330 
331  if ( !fields.isEmpty() )
332  {
333  for ( const QString &field : fields )
334  {
335  int attrIdx = layerFields.lookupField( field );
336  if ( attrIdx < 0 )
337  continue;
338 
339  QString currentAlias = source->attributeDisplayName( attrIdx );
340  std::unique_ptr< QgsLayoutTableColumn > col = qgis::make_unique< QgsLayoutTableColumn >();
341  col->setAttribute( layerFields.at( attrIdx ).name() );
342  col->setHeading( currentAlias );
343  mColumns.append( col.release() );
344  }
345  }
346  else
347  {
348  //resetting, so add all attributes to columns
349  int idx = 0;
350  for ( const QgsField &field : layerFields )
351  {
352  QString currentAlias = source->attributeDisplayName( idx );
353  std::unique_ptr< QgsLayoutTableColumn > col = qgis::make_unique< QgsLayoutTableColumn >();
354  col->setAttribute( field.name() );
355  col->setHeading( currentAlias );
356  mColumns.append( col.release() );
357  idx++;
358  }
359  }
360 
361  if ( refresh )
362  {
364  }
365 }
366 
367 void QgsLayoutItemAttributeTable::restoreFieldAliasMap( const QMap<int, QString> &map )
368 {
370  if ( !source )
371  {
372  return;
373  }
374 
375  for ( QgsLayoutTableColumn *column : qgis::as_const( mColumns ) )
376  {
377  int attrIdx = source->fields().lookupField( column->attribute() );
378  if ( map.contains( attrIdx ) )
379  {
380  column->setHeading( map.value( attrIdx ) );
381  }
382  else
383  {
384  column->setHeading( source->attributeDisplayName( attrIdx ) );
385  }
386  }
387 }
388 
390 {
391  contents.clear();
392 
393  QgsVectorLayer *layer = sourceLayer();
394  if ( !layer )
395  {
396  //no source layer
397  return false;
398  }
399 
401  context.setFields( layer->fields() );
402 
403  QgsFeatureRequest req;
404 
405  //prepare filter expression
406  std::unique_ptr<QgsExpression> filterExpression;
407  bool activeFilter = false;
408  if ( mFilterFeatures && !mFeatureFilter.isEmpty() )
409  {
410  filterExpression = qgis::make_unique< QgsExpression >( mFeatureFilter );
411  if ( !filterExpression->hasParserError() )
412  {
413  activeFilter = true;
414  req.setFilterExpression( mFeatureFilter );
415  req.setExpressionContext( context );
416  }
417  }
418 
419  QgsRectangle selectionRect;
420  if ( mMap && mShowOnlyVisibleFeatures )
421  {
422  selectionRect = mMap->extent();
423  if ( layer )
424  {
425  //transform back to layer CRS
426  QgsCoordinateTransform coordTransform( layer->crs(), mMap->crs(), mLayout->project() );
427  try
428  {
429  selectionRect = coordTransform.transformBoundingBox( selectionRect, QgsCoordinateTransform::ReverseTransform );
430  }
431  catch ( QgsCsException &cse )
432  {
433  Q_UNUSED( cse );
434  return false;
435  }
436  }
437  }
438 
440  {
441  QgsRelation relation = mLayout->project()->relationManager()->relation( mRelationId );
442  QgsFeature atlasFeature = mLayout->reportContext().feature();
443  req = relation.getRelatedFeaturesRequest( atlasFeature );
444  }
445 
446  if ( !selectionRect.isEmpty() )
447  req.setFilterRect( selectionRect );
448 
449  req.setFlags( mShowOnlyVisibleFeatures ? QgsFeatureRequest::ExactIntersect : QgsFeatureRequest::NoFlags );
450 
452  {
453  //source mode is current atlas feature
454  QgsFeature atlasFeature = mLayout->reportContext().feature();
455  req.setFilterFid( atlasFeature.id() );
456  }
457 
458  QgsFeature f;
459  int counter = 0;
460  QgsFeatureIterator fit = layer->getFeatures( req );
461 
462  while ( fit.nextFeature( f ) && counter < mMaximumNumberOfFeatures )
463  {
464  context.setFeature( f );
465  //check feature against filter
466  if ( activeFilter && filterExpression )
467  {
468  QVariant result = filterExpression->evaluate( &context );
469  // skip this feature if the filter evaluation is false
470  if ( !result.toBool() )
471  {
472  continue;
473  }
474  }
475  //check against atlas feature intersection
476  if ( mFilterToAtlasIntersection )
477  {
478  if ( !f.hasGeometry() )
479  {
480  continue;
481  }
482  QgsFeature atlasFeature = mLayout->reportContext().feature();
483  if ( !atlasFeature.hasGeometry() ||
484  !f.geometry().intersects( atlasFeature.geometry() ) )
485  {
486  //feature falls outside current atlas feature
487  continue;
488  }
489  }
490 
491  QgsLayoutTableRow currentRow;
492 
493  for ( QgsLayoutTableColumn *column : qgis::as_const( mColumns ) )
494  {
495  int idx = layer->fields().lookupField( column->attribute() );
496  if ( idx != -1 )
497  {
498  currentRow << replaceWrapChar( f.attributes().at( idx ) );
499  }
500  else
501  {
502  // Lets assume it's an expression
503  std::unique_ptr< QgsExpression > expression = qgis::make_unique< QgsExpression >( column->attribute() );
504  context.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "row_number" ), counter + 1, true ) );
505  expression->prepare( &context );
506  QVariant value = expression->evaluate( &context );
507  currentRow << value;
508  }
509  }
510 
511  if ( !mShowUniqueRowsOnly || !contentsContainsRow( contents, currentRow ) )
512  {
513  contents << currentRow;
514  ++counter;
515  }
516  }
517 
518  //sort the list, starting with the last attribute
519  QgsLayoutAttributeTableCompare c;
520  QVector< QPair<int, bool> > sortColumns = sortAttributes();
521  for ( int i = sortColumns.size() - 1; i >= 0; --i )
522  {
523  c.setSortColumn( sortColumns.at( i ).first );
524  c.setAscending( sortColumns.at( i ).second );
525  std::stable_sort( contents.begin(), contents.end(), c );
526  }
527 
529  return true;
530 }
531 
533 {
535 
536  if ( mSource == LayerAttributes )
537  {
538  context.appendScope( QgsExpressionContextUtils::layerScope( mVectorLayer.get() ) );
539  }
540 
541  return context;
542 }
543 
545 {
547  if ( !mMap && !mMapUuid.isEmpty() && mLayout )
548  {
549  mMap = qobject_cast< QgsLayoutItemMap *>( mLayout->itemByUuid( mMapUuid, true ) );
550  if ( mMap )
551  {
552  //if we have found a valid map item, listen out to extent changes on it and refresh the table
554  }
555  }
556 }
557 
559 {
561 
564  {
565  mDataDefinedVectorLayer = nullptr;
566 
567  QString currentLayerIdentifier;
568  if ( QgsVectorLayer *currentLayer = mVectorLayer.get() )
569  currentLayerIdentifier = currentLayer->id();
570 
571  const QString layerIdentifier = mDataDefinedProperties.valueAsString( QgsLayoutObject::AttributeTableSourceLayer, context, currentLayerIdentifier );
572  QgsVectorLayer *ddLayer = qobject_cast< QgsVectorLayer * >( QgsLayoutUtils::mapLayerFromString( layerIdentifier, mLayout->project() ) );
573  if ( ddLayer )
574  mDataDefinedVectorLayer = ddLayer;
575  }
576 
578 }
579 
580 QVariant QgsLayoutItemAttributeTable::replaceWrapChar( const QVariant &variant ) const
581 {
582  //avoid converting variants to string if not required (try to maintain original type for sorting)
583  if ( mWrapString.isEmpty() || !variant.toString().contains( mWrapString ) )
584  return variant;
585 
586  QString replaced = variant.toString();
587  replaced.replace( mWrapString, QLatin1String( "\n" ) );
588  return replaced;
589 }
590 
592 {
593  switch ( mSource )
594  {
596  return mLayout->reportContext().layer();
598  {
599  if ( mDataDefinedVectorLayer )
600  return mDataDefinedVectorLayer;
601  else
602  return mVectorLayer.get();
603  }
605  {
606  QgsRelation relation = mLayout->project()->relationManager()->relation( mRelationId );
607  return relation.referencingLayer();
608  }
609  }
610  return nullptr;
611 }
612 
613 void QgsLayoutItemAttributeTable::removeLayer( const QString &layerId )
614 {
615  if ( mVectorLayer && mSource == QgsLayoutItemAttributeTable::LayerAttributes )
616  {
617  if ( layerId == mVectorLayer->id() )
618  {
619  mVectorLayer.setLayer( nullptr );
620  //remove existing columns
621  qDeleteAll( mColumns );
622  mColumns.clear();
623  }
624  }
625 }
626 
627 static bool columnsBySortRank( QPair<int, QgsLayoutTableColumn * > a, QPair<int, QgsLayoutTableColumn * > b )
628 {
629  return a.second->sortByRank() < b.second->sortByRank();
630 }
631 
632 QVector<QPair<int, bool> > QgsLayoutItemAttributeTable::sortAttributes() const
633 {
634  //generate list of all sorted columns
635  QVector< QPair<int, QgsLayoutTableColumn * > > sortedColumns;
636  int idx = 0;
637  for ( QgsLayoutTableColumn *column : mColumns )
638  {
639  if ( column->sortByRank() > 0 )
640  {
641  sortedColumns.append( qMakePair( idx, column ) );
642  }
643  idx++;
644  }
645 
646  //sort columns by rank
647  std::sort( sortedColumns.begin(), sortedColumns.end(), columnsBySortRank );
648 
649  //generate list of column index, bool for sort direction (to match 2.0 api)
650  QVector<QPair<int, bool> > attributesBySortRank;
651  for ( auto &column : qgis::as_const( sortedColumns ) )
652  {
653  attributesBySortRank.append( qMakePair( column.first,
654  column.second->sortOrder() == Qt::AscendingOrder ) );
655  }
656  return attributesBySortRank;
657 }
658 
660 {
661  if ( wrapString == mWrapString )
662  {
663  return;
664  }
665 
666  mWrapString = wrapString;
668  emit changed();
669 }
670 
671 bool QgsLayoutItemAttributeTable::writePropertiesToElement( QDomElement &tableElem, QDomDocument &doc, const QgsReadWriteContext &context ) const
672 {
673  if ( !QgsLayoutTable::writePropertiesToElement( tableElem, doc, context ) )
674  return false;
675 
676  tableElem.setAttribute( QStringLiteral( "source" ), QString::number( static_cast< int >( mSource ) ) );
677  tableElem.setAttribute( QStringLiteral( "relationId" ), mRelationId );
678  tableElem.setAttribute( QStringLiteral( "showUniqueRowsOnly" ), mShowUniqueRowsOnly );
679  tableElem.setAttribute( QStringLiteral( "showOnlyVisibleFeatures" ), mShowOnlyVisibleFeatures );
680  tableElem.setAttribute( QStringLiteral( "filterToAtlasIntersection" ), mFilterToAtlasIntersection );
681  tableElem.setAttribute( QStringLiteral( "maxFeatures" ), mMaximumNumberOfFeatures );
682  tableElem.setAttribute( QStringLiteral( "filterFeatures" ), mFilterFeatures ? QStringLiteral( "true" ) : QStringLiteral( "false" ) );
683  tableElem.setAttribute( QStringLiteral( "featureFilter" ), mFeatureFilter );
684  tableElem.setAttribute( QStringLiteral( "wrapString" ), mWrapString );
685 
686  if ( mMap )
687  {
688  tableElem.setAttribute( QStringLiteral( "mapUuid" ), mMap->uuid() );
689  }
690 
691  if ( mVectorLayer )
692  {
693  tableElem.setAttribute( QStringLiteral( "vectorLayer" ), mVectorLayer.layerId );
694  tableElem.setAttribute( QStringLiteral( "vectorLayerName" ), mVectorLayer.name );
695  tableElem.setAttribute( QStringLiteral( "vectorLayerSource" ), mVectorLayer.source );
696  tableElem.setAttribute( QStringLiteral( "vectorLayerProvider" ), mVectorLayer.provider );
697  }
698  return true;
699 }
700 
701 bool QgsLayoutItemAttributeTable::readPropertiesFromElement( const QDomElement &itemElem, const QDomDocument &doc, const QgsReadWriteContext &context )
702 {
703  QgsVectorLayer *prevLayer = sourceLayer();
704  if ( prevLayer )
705  {
706  //disconnect from previous layer
707  disconnect( prevLayer, &QgsVectorLayer::layerModified, this, &QgsLayoutTable::refreshAttributes );
708  }
709 
710  if ( !QgsLayoutTable::readPropertiesFromElement( itemElem, doc, context ) )
711  return false;
712 
713  mSource = QgsLayoutItemAttributeTable::ContentSource( itemElem.attribute( QStringLiteral( "source" ), QStringLiteral( "0" ) ).toInt() );
714  mRelationId = itemElem.attribute( QStringLiteral( "relationId" ), QString() );
715 
717  {
718  mCurrentAtlasLayer = mLayout->reportContext().layer();
719  }
720 
721  mShowUniqueRowsOnly = itemElem.attribute( QStringLiteral( "showUniqueRowsOnly" ), QStringLiteral( "0" ) ).toInt();
722  mShowOnlyVisibleFeatures = itemElem.attribute( QStringLiteral( "showOnlyVisibleFeatures" ), QStringLiteral( "1" ) ).toInt();
723  mFilterToAtlasIntersection = itemElem.attribute( QStringLiteral( "filterToAtlasIntersection" ), QStringLiteral( "0" ) ).toInt();
724  mFilterFeatures = itemElem.attribute( QStringLiteral( "filterFeatures" ), QStringLiteral( "false" ) ) == QLatin1String( "true" );
725  mFeatureFilter = itemElem.attribute( QStringLiteral( "featureFilter" ), QString() );
726  mMaximumNumberOfFeatures = itemElem.attribute( QStringLiteral( "maxFeatures" ), QStringLiteral( "5" ) ).toInt();
727  mWrapString = itemElem.attribute( QStringLiteral( "wrapString" ) );
728 
729  //map
730  mMapUuid = itemElem.attribute( QStringLiteral( "mapUuid" ) );
731  if ( mMap )
732  {
734  mMap = nullptr;
735  }
736  // setting new mMap occurs in finalizeRestoreFromXml
737 
738  //vector layer
739  QString layerId = itemElem.attribute( QStringLiteral( "vectorLayer" ) );
740  QString layerName = itemElem.attribute( QStringLiteral( "vectorLayerName" ) );
741  QString layerSource = itemElem.attribute( QStringLiteral( "vectorLayerSource" ) );
742  QString layerProvider = itemElem.attribute( QStringLiteral( "vectorLayerProvider" ) );
743  mVectorLayer = QgsVectorLayerRef( layerId, layerName, layerSource, layerProvider );
744  mVectorLayer.resolveWeakly( mLayout->project() );
745 
746  //connect to new layer
748 
750 
751  emit changed();
752  return true;
753 }
754 
756 {
757  if ( source == mSource )
758  {
759  return;
760  }
761 
762  QgsVectorLayer *prevLayer = sourceLayer();
763  mSource = source;
764  QgsVectorLayer *newLayer = sourceLayer();
765 
766  if ( newLayer != prevLayer )
767  {
768  //disconnect from previous layer
769  if ( prevLayer )
770  {
771  disconnect( prevLayer, &QgsVectorLayer::layerModified, this, &QgsLayoutTable::refreshAttributes );
772  }
773 
774  //connect to new layer
777  {
778  mCurrentAtlasLayer = newLayer;
779  }
780 
781  //layer has changed as a result of the source change, so reset column list
782  resetColumns();
783  }
784 
786  emit changed();
787 }
int lookupField(const QString &fieldName) const
Looks up field&#39;s index from the field name.
Definition: qgsfields.cpp:324
QString displayName() const override
Returns the multiframe display name.
QgsFeatureId id
Definition: qgsfeature.h:64
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:41
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:58
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:46
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:55
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:221
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:197
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:153
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:163
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 & setExpressionContext(const QgsExpressionContext &context)
Sets the expression context used to evaluate filter expressions.
QgsFeatureRequest & setFilterFid(QgsFeatureId fid)
Sets feature ID that should be fetched.
QgsExpressionContextScope * lastScope()
Returns the last scope added to the context.
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
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 FINAL
Returns the list of fields of this layer.
bool isEmpty() const
Returns true if the rectangle is empty.
Definition: qgsrectangle.h:426
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.
Reads and writes project states.
Definition: qgsproject.h:89
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...
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.
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...
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Query the layer for features specified in request.
QgsGeometry geometry
Definition: qgsfeature.h:67
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:65
QVector< QgsLayoutTableRow > QgsLayoutTableContents
List of QgsLayoutTableRows, representing rows and column cell contents for a QgsLayoutTable.
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:71
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...