22 QgsReportSectionFieldGroup::QgsReportSectionFieldGroup( QgsAbstractReportSection *parent )
23 : QgsAbstractReportSection( parent )
28 QString QgsReportSectionFieldGroup::description()
const 30 if ( mCoverageLayer.get() )
31 return QObject::tr(
"Group: %1 - %2" ).arg( mCoverageLayer->name(), mField );
33 return QObject::tr(
"Group" );
36 QIcon QgsReportSectionFieldGroup::icon()
const 41 QgsReportSectionFieldGroup *QgsReportSectionFieldGroup::clone()
const 43 std::unique_ptr< QgsReportSectionFieldGroup > copy = qgis::make_unique< QgsReportSectionFieldGroup >( nullptr );
44 copyCommonProperties( copy.get() );
48 copy->mBody.reset( mBody->clone() );
53 copy->setLayer( mCoverageLayer.get() );
54 copy->setField( mField );
55 copy->setSortAscending( mSortAscending );
56 copy->setBodyEnabled( mBodyEnabled );
58 return copy.release();
61 bool QgsReportSectionFieldGroup::beginRender()
63 if ( !mCoverageLayer.get() )
66 if ( !mField.isEmpty() )
68 mFieldIndex = mCoverageLayer->fields().lookupField( mField );
69 if ( mFieldIndex < 0 )
73 mBody->reportContext().setLayer( mCoverageLayer.get() );
77 return QgsAbstractReportSection::beginRender();
80 bool QgsReportSectionFieldGroup::prepareHeader()
85 if ( !mFeatures.isValid() )
87 mFeatures = mCoverageLayer->getFeatures( buildFeatureRequest() );
90 mHeaderFeature = getNextFeature();
91 header()->reportContext().blockSignals(
true );
92 header()->reportContext().setLayer( mCoverageLayer.get() );
93 header()->reportContext().blockSignals(
false );
94 header()->reportContext().setFeature( mHeaderFeature );
95 mSkipNextRequest =
true;
96 mNoFeatures = !mHeaderFeature.isValid();
97 return mHeaderVisibility == AlwaysInclude || !mNoFeatures;
100 bool QgsReportSectionFieldGroup::prepareFooter()
102 return mFooterVisibility == AlwaysInclude || !mNoFeatures;
105 QgsLayout *QgsReportSectionFieldGroup::nextBody(
bool &ok )
107 if ( !mFeatures.isValid() )
109 mFeatures = mCoverageLayer->getFeatures( buildFeatureRequest() );
113 if ( !mSkipNextRequest )
115 f = getNextFeature();
120 mSkipNextRequest =
false;
130 footer()->reportContext().blockSignals(
true );
131 footer()->reportContext().setLayer( mCoverageLayer.get() );
132 footer()->reportContext().blockSignals(
false );
133 footer()->reportContext().setFeature( mLastFeature );
141 updateChildContexts( f );
144 if ( mBody && mBodyEnabled )
146 mBody->reportContext().blockSignals(
true );
147 mBody->reportContext().setLayer( mCoverageLayer.get() );
148 mBody->reportContext().blockSignals(
false );
149 mBody->reportContext().setFeature( f );
152 return mBodyEnabled ? mBody.get() :
nullptr;
155 void QgsReportSectionFieldGroup::reset()
157 QgsAbstractReportSection::reset();
158 mEncounteredValues.clear();
159 mSkipNextRequest =
false;
166 void QgsReportSectionFieldGroup::setParentSection( QgsAbstractReportSection *parent )
168 QgsAbstractReportSection::setParentSection( parent );
169 if ( !mCoverageLayer )
170 mCoverageLayer.resolveWeakly(
project() );
173 void QgsReportSectionFieldGroup::reloadSettings()
175 QgsAbstractReportSection::reloadSettings();
177 mBody->reloadSettings();
180 bool QgsReportSectionFieldGroup::writePropertiesToElement( QDomElement &element, QDomDocument &doc,
const QgsReadWriteContext &context )
const 182 element.setAttribute( QStringLiteral(
"headerVisibility" ), static_cast< int >( mHeaderVisibility ) );
183 element.setAttribute( QStringLiteral(
"footerVisibility" ), static_cast< int >( mFooterVisibility ) );
184 element.setAttribute( QStringLiteral(
"field" ), mField );
185 element.setAttribute( QStringLiteral(
"ascending" ), mSortAscending ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
186 element.setAttribute( QStringLiteral(
"bodyEnabled" ), mBodyEnabled ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
187 if ( mCoverageLayer )
189 element.setAttribute( QStringLiteral(
"coverageLayer" ), mCoverageLayer.layerId );
190 element.setAttribute( QStringLiteral(
"coverageLayerName" ), mCoverageLayer.name );
191 element.setAttribute( QStringLiteral(
"coverageLayerSource" ), mCoverageLayer.source );
192 element.setAttribute( QStringLiteral(
"coverageLayerProvider" ), mCoverageLayer.provider );
197 QDomElement bodyElement = doc.createElement( QStringLiteral(
"body" ) );
198 bodyElement.appendChild( mBody->writeXml( doc, context ) );
199 element.appendChild( bodyElement );
204 bool QgsReportSectionFieldGroup::readPropertiesFromElement(
const QDomElement &element,
const QDomDocument &doc,
const QgsReadWriteContext &context )
206 mHeaderVisibility =
static_cast< SectionVisibility
>( element.attribute( QStringLiteral(
"headerVisibility" ) ).toInt() );
207 mFooterVisibility =
static_cast< SectionVisibility
>( element.attribute( QStringLiteral(
"footerVisibility" ) ).toInt() );
208 mField = element.attribute( QStringLiteral(
"field" ) );
209 mSortAscending = element.attribute( QStringLiteral(
"ascending" ) ).toInt();
210 mBodyEnabled = element.attribute( QStringLiteral(
"bodyEnabled" ) ).toInt();
211 QString layerId = element.attribute( QStringLiteral(
"coverageLayer" ) );
212 QString layerName = element.attribute( QStringLiteral(
"coverageLayerName" ) );
213 QString layerSource = element.attribute( QStringLiteral(
"coverageLayerSource" ) );
214 QString layerProvider = element.attribute( QStringLiteral(
"coverageLayerProvider" ) );
215 mCoverageLayer =
QgsVectorLayerRef( layerId, layerName, layerSource, layerProvider );
216 mCoverageLayer.resolveWeakly(
project() );
218 const QDomElement bodyElement = element.firstChildElement( QStringLiteral(
"body" ) );
219 if ( !bodyElement.isNull() )
221 const QDomElement bodyLayoutElem = bodyElement.firstChild().toElement();
222 std::unique_ptr< QgsLayout > body = qgis::make_unique< QgsLayout >(
project() );
223 body->readXml( bodyLayoutElem, doc, context );
224 mBody = std::move( body );
229 bool QgsReportSectionFieldGroup::sortAscending()
const 231 return mSortAscending;
234 void QgsReportSectionFieldGroup::setSortAscending(
bool sortAscending )
236 mSortAscending = sortAscending;
242 QVariantMap filter = context().fieldFilters;
244 QStringList filterParts;
245 for (
auto filterIt = filter.constBegin(); filterIt != filter.constEnd(); ++filterIt )
248 int fieldIndex = mCoverageLayer->fields().lookupField( filterIt.key() );
249 if ( fieldIndex >= 0 )
255 if ( !filterParts.empty() )
257 QString filterString = QStringLiteral(
"(%1)" ).arg( filterParts.join( QStringLiteral(
") AND (" ) ) );
265 QgsFeature QgsReportSectionFieldGroup::getNextFeature()
268 QVariant currentValue;
270 while ( first || ( ( !mBody || !mBodyEnabled ) && mEncounteredValues.contains( currentValue ) ) )
272 if ( !mFeatures.nextFeature( f ) )
278 currentValue = f.
attribute( mFieldIndex );
281 mEncounteredValues.insert( currentValue );
285 void QgsReportSectionFieldGroup::updateChildContexts(
const QgsFeature &feature )
287 QgsReportSectionContext
c = context();
289 if ( mCoverageLayer )
290 c.currentLayer = mCoverageLayer.get();
292 QVariantMap currentFilter = c.fieldFilters;
293 currentFilter.insert( mField, feature.
attribute( mFieldIndex ) );
294 c.fieldFilters = currentFilter;
296 const QList< QgsAbstractReportSection * > sections = childSections();
297 for ( QgsAbstractReportSection *section : qgis::as_const( sections ) )
299 section->setContext( c );
bool isValid() const
Returns the validity of this feature.
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.
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
QgsFeatureRequest & addOrderBy(const QString &expression, bool ascending=true)
Adds a new OrderByClause, appending it as the least important one.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
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
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
static QString createFieldEqualityExpression(const QString &fieldName, const QVariant &value)
Create an expression allowing to evaluate if a field is equal to a value.
_LayerRef< QgsVectorLayer > QgsVectorLayerRef
QgsProject * project() const
The project associated with the layout.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.