27 QgsAbstractReportSection::QgsAbstractReportSection( QgsAbstractReportSection *parent )
31 QgsAbstractReportSection::~QgsAbstractReportSection()
33 qDeleteAll( mChildren );
36 QgsProject *QgsAbstractReportSection::project()
38 if ( QgsReport *report =
dynamic_cast< QgsReport *
>(
this ) )
39 return report->layoutProject();
41 QgsAbstractReportSection *current =
this;
42 while ( QgsAbstractReportSection *parent = current->parentSection() )
44 if ( QgsReport *report =
dynamic_cast< QgsReport *
>( parent ) )
45 return report->layoutProject();
52 void QgsAbstractReportSection::setContext(
const QgsReportSectionContext &context )
54 auto setReportContext = [&context](
QgsLayout * layout )
56 if ( context.currentLayer )
58 layout->reportContext().blockSignals(
true );
59 layout->reportContext().setLayer( context.currentLayer );
60 layout->reportContext().blockSignals(
false );
62 layout->reportContext().setFeature( context.feature );
67 setReportContext( mHeader.get() );
69 setReportContext( mFooter.get() );
71 for ( QgsAbstractReportSection *section : qgis::as_const( mChildren ) )
73 section->setContext( mContext );
77 bool QgsAbstractReportSection::writeXml( QDomElement &parentElement, QDomDocument &doc,
const QgsReadWriteContext &context )
const
79 QDomElement element = doc.createElement( QStringLiteral(
"Section" ) );
80 element.setAttribute( QStringLiteral(
"type" ), type() );
82 element.setAttribute( QStringLiteral(
"headerEnabled" ), mHeaderEnabled ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
85 QDomElement headerElement = doc.createElement( QStringLiteral(
"header" ) );
86 headerElement.appendChild( mHeader->writeXml( doc, context ) );
87 element.appendChild( headerElement );
89 element.setAttribute( QStringLiteral(
"footerEnabled" ), mFooterEnabled ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
92 QDomElement footerElement = doc.createElement( QStringLiteral(
"footer" ) );
93 footerElement.appendChild( mFooter->writeXml( doc, context ) );
94 element.appendChild( footerElement );
97 for ( QgsAbstractReportSection *section : mChildren )
99 section->writeXml( element, doc, context );
102 writePropertiesToElement( element, doc, context );
104 parentElement.appendChild( element );
108 bool QgsAbstractReportSection::readXml(
const QDomElement &element,
const QDomDocument &doc,
const QgsReadWriteContext &context )
110 if ( element.nodeName() != QLatin1String(
"Section" ) )
115 mHeaderEnabled = element.attribute( QStringLiteral(
"headerEnabled" ), QStringLiteral(
"0" ) ).toInt();
116 mFooterEnabled = element.attribute( QStringLiteral(
"footerEnabled" ), QStringLiteral(
"0" ) ).toInt();
117 const QDomElement headerElement = element.firstChildElement( QStringLiteral(
"header" ) );
118 if ( !headerElement.isNull() )
120 const QDomElement headerLayoutElem = headerElement.firstChild().toElement();
121 std::unique_ptr< QgsLayout > header = qgis::make_unique< QgsLayout >( project() );
122 header->readXml( headerLayoutElem, doc, context );
123 mHeader = std::move( header );
125 const QDomElement footerElement = element.firstChildElement( QStringLiteral(
"footer" ) );
126 if ( !footerElement.isNull() )
128 const QDomElement footerLayoutElem = footerElement.firstChild().toElement();
129 std::unique_ptr< QgsLayout > footer = qgis::make_unique< QgsLayout >( project() );
130 footer->readXml( footerLayoutElem, doc, context );
131 mFooter = std::move( footer );
134 const QDomNodeList sectionItemList = element.childNodes();
135 for (
int i = 0; i < sectionItemList.size(); ++i )
137 const QDomElement currentSectionElem = sectionItemList.at( i ).toElement();
138 if ( currentSectionElem.nodeName() != QLatin1String(
"Section" ) )
141 const QString sectionType = currentSectionElem.attribute( QStringLiteral(
"type" ) );
144 std::unique_ptr< QgsAbstractReportSection > section;
145 if ( sectionType == QLatin1String(
"SectionFieldGroup" ) )
147 section = qgis::make_unique< QgsReportSectionFieldGroup >();
149 else if ( sectionType == QLatin1String(
"SectionLayout" ) )
151 section = qgis::make_unique< QgsReportSectionLayout >();
156 appendChild( section.get() );
157 section->readXml( currentSectionElem, doc, context );
158 ( void )section.release();
162 bool result = readPropertiesFromElement( element, doc, context );
166 void QgsAbstractReportSection::reloadSettings()
169 mHeader->reloadSettings();
171 mFooter->reloadSettings();
185 if ( !mHeader->accept( visitor ) )
193 for (
const QgsAbstractReportSection *child : mChildren )
195 if ( !child->accept( visitor ) )
204 if ( !mFooter->accept( visitor ) )
218 QString QgsAbstractReportSection::filePath(
const QString &baseFilePath,
const QString &extension )
220 QString base = QStringLiteral(
"%1_%2" ).arg( baseFilePath ).arg( mSectionNumber, 4, 10, QChar(
'0' ) );
221 if ( !extension.startsWith(
'.' ) )
227 QgsLayout *QgsAbstractReportSection::layout()
229 return mCurrentLayout;
232 bool QgsAbstractReportSection::beginRender()
240 for ( QgsAbstractReportSection *child : qgis::as_const( mChildren ) )
242 result = result && child->beginRender();
247 bool QgsAbstractReportSection::next()
251 if ( mNextSection == Header )
257 if ( mHeaderEnabled && mHeader )
259 if ( prepareHeader() )
261 mCurrentLayout = mHeader.get();
270 if ( mNextSection == Body )
272 mNextSection = Children;
280 mCurrentLayout = body;
285 if ( mNextSection == Children )
287 bool bodiesAvailable =
false;
291 while ( mNextChild < mChildren.count() )
294 if ( mChildren.at( mNextChild )->next() )
296 mCurrentLayout = mChildren.at( mNextChild )->layout();
308 QgsLayout *body = nextBody( bodiesAvailable );
309 if ( bodiesAvailable )
313 for ( QgsAbstractReportSection *section : qgis::as_const( mChildren ) )
320 mCurrentLayout = body;
324 while ( bodiesAvailable );
327 mNextSection = Footer;
330 if ( mNextSection == Footer )
336 if ( mFooterEnabled && mFooter )
338 if ( prepareFooter() )
340 mCurrentLayout = mFooter.get();
348 mCurrentLayout =
nullptr;
352 bool QgsAbstractReportSection::endRender()
359 for ( QgsAbstractReportSection *child : qgis::as_const( mChildren ) )
361 result = result && child->endRender();
366 void QgsAbstractReportSection::reset()
368 mCurrentLayout =
nullptr;
370 mNextSection = Header;
371 for ( QgsAbstractReportSection *section : qgis::as_const( mChildren ) )
377 bool QgsAbstractReportSection::prepareHeader()
382 bool QgsAbstractReportSection::prepareFooter()
387 void QgsAbstractReportSection::setHeader(
QgsLayout *header )
389 mHeader.reset( header );
392 void QgsAbstractReportSection::setFooter(
QgsLayout *footer )
394 mFooter.reset( footer );
397 int QgsAbstractReportSection::row()
const
400 return mParent->childSections().indexOf(
const_cast<QgsAbstractReportSection *
>(
this ) );
405 QgsAbstractReportSection *QgsAbstractReportSection::childSection(
int index )
407 return mChildren.value( index );
410 void QgsAbstractReportSection::appendChild( QgsAbstractReportSection *section )
412 section->setParentSection(
this );
413 mChildren.append( section );
416 void QgsAbstractReportSection::insertChild(
int index, QgsAbstractReportSection *section )
418 section->setParentSection(
this );
419 index = std::max( 0, index );
420 index = std::min( index, mChildren.count() );
421 mChildren.insert( index, section );
424 void QgsAbstractReportSection::removeChild( QgsAbstractReportSection *section )
426 mChildren.removeAll( section );
430 void QgsAbstractReportSection::removeChildAt(
int index )
432 if ( index < 0 || index >= mChildren.count() )
435 QgsAbstractReportSection *section = mChildren.at( index );
436 removeChild( section );
439 void QgsAbstractReportSection::copyCommonProperties( QgsAbstractReportSection *destination )
const
441 destination->mHeaderEnabled = mHeaderEnabled;
443 destination->mHeader.reset( mHeader->clone() );
445 destination->mHeader.reset();
447 destination->mFooterEnabled = mFooterEnabled;
449 destination->mFooter.reset( mFooter->clone() );
451 destination->mFooter.reset();
453 qDeleteAll( destination->mChildren );
454 destination->mChildren.clear();
456 for ( QgsAbstractReportSection *child : qgis::as_const( mChildren ) )
458 destination->appendChild( child->clone() );
462 bool QgsAbstractReportSection::writePropertiesToElement( QDomElement &, QDomDocument &,
const QgsReadWriteContext & )
const
467 bool QgsAbstractReportSection::readPropertiesFromElement(
const QDomElement &,
const QDomDocument &,
const QgsReadWriteContext & )