28QgsAbstractReportSection::QgsAbstractReportSection( QgsAbstractReportSection *parent )
32QgsAbstractReportSection::~QgsAbstractReportSection()
34 qDeleteAll( mChildren );
39 if ( QgsReport *report =
dynamic_cast< QgsReport *
>(
this ) )
40 return report->layoutProject();
42 QgsAbstractReportSection *current =
this;
43 while ( QgsAbstractReportSection *parent = current->parentSection() )
45 if ( QgsReport *report =
dynamic_cast< QgsReport *
>( parent ) )
46 return report->layoutProject();
53void QgsAbstractReportSection::setContext(
const QgsReportSectionContext &context )
55 auto setReportContext = [&context](
QgsLayout * layout )
57 if ( context.currentLayer )
59 layout->reportContext().blockSignals(
true );
60 layout->reportContext().setLayer( context.currentLayer );
61 layout->reportContext().blockSignals(
false );
63 layout->reportContext().setFeature( context.feature );
68 setReportContext( mHeader.get() );
70 setReportContext( mFooter.get() );
72 for ( QgsAbstractReportSection *section : std::as_const( mChildren ) )
74 section->setContext( mContext );
78bool QgsAbstractReportSection::writeXml( QDomElement &parentElement, QDomDocument &doc,
const QgsReadWriteContext &context )
const
80 QDomElement element = doc.createElement( QStringLiteral(
"Section" ) );
81 element.setAttribute( QStringLiteral(
"type" ), type() );
83 element.setAttribute( QStringLiteral(
"headerEnabled" ), mHeaderEnabled ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
86 QDomElement headerElement = doc.createElement( QStringLiteral(
"header" ) );
87 headerElement.appendChild( mHeader->writeXml( doc, context ) );
88 element.appendChild( headerElement );
90 element.setAttribute( QStringLiteral(
"footerEnabled" ), mFooterEnabled ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
93 QDomElement footerElement = doc.createElement( QStringLiteral(
"footer" ) );
94 footerElement.appendChild( mFooter->writeXml( doc, context ) );
95 element.appendChild( footerElement );
98 for ( QgsAbstractReportSection *section : mChildren )
100 section->writeXml( element, doc, context );
103 writePropertiesToElement( element, doc, context );
105 parentElement.appendChild( element );
109bool QgsAbstractReportSection::readXml(
const QDomElement &element,
const QDomDocument &doc,
const QgsReadWriteContext &context )
111 if ( element.nodeName() != QLatin1String(
"Section" ) )
116 mHeaderEnabled = element.attribute( QStringLiteral(
"headerEnabled" ), QStringLiteral(
"0" ) ).toInt();
117 mFooterEnabled = element.attribute( QStringLiteral(
"footerEnabled" ), QStringLiteral(
"0" ) ).toInt();
118 const QDomElement headerElement = element.firstChildElement( QStringLiteral(
"header" ) );
119 if ( !headerElement.isNull() )
121 const QDomElement headerLayoutElem = headerElement.firstChild().toElement();
122 auto header = std::make_unique< QgsLayout >( project() );
123 header->readXml( headerLayoutElem, doc, context );
124 mHeader = std::move( header );
126 const QDomElement footerElement = element.firstChildElement( QStringLiteral(
"footer" ) );
127 if ( !footerElement.isNull() )
129 const QDomElement footerLayoutElem = footerElement.firstChild().toElement();
130 auto footer = std::make_unique< QgsLayout >( project() );
131 footer->readXml( footerLayoutElem, doc, context );
132 mFooter = std::move( footer );
135 const QDomNodeList sectionItemList = element.childNodes();
136 for (
int i = 0; i < sectionItemList.size(); ++i )
138 const QDomElement currentSectionElem = sectionItemList.at( i ).toElement();
139 if ( currentSectionElem.nodeName() != QLatin1String(
"Section" ) )
142 const QString sectionType = currentSectionElem.attribute( QStringLiteral(
"type" ) );
145 std::unique_ptr< QgsAbstractReportSection > section;
146 if ( sectionType == QLatin1String(
"SectionFieldGroup" ) )
148 section = std::make_unique< QgsReportSectionFieldGroup >();
150 else if ( sectionType == QLatin1String(
"SectionLayout" ) )
152 section = std::make_unique< QgsReportSectionLayout >();
157 appendChild( section.get() );
158 section->readXml( currentSectionElem, doc, context );
159 ( void )section.release();
163 bool result = readPropertiesFromElement( element, doc, context );
167void QgsAbstractReportSection::reloadSettings()
170 mHeader->reloadSettings();
172 mFooter->reloadSettings();
186 if ( !mHeader->accept( visitor ) )
194 for (
const QgsAbstractReportSection *child : mChildren )
196 if ( !child->accept( visitor ) )
205 if ( !mFooter->accept( visitor ) )
219QString QgsAbstractReportSection::filePath(
const QString &baseFilePath,
const QString &extension )
221 QString base = QStringLiteral(
"%1_%2" ).arg( baseFilePath ).arg( mSectionNumber, 4, 10, QChar(
'0' ) );
222 if ( !extension.startsWith(
'.' ) )
228QgsLayout *QgsAbstractReportSection::layout()
230 return mCurrentLayout;
233bool QgsAbstractReportSection::beginRender()
241 for ( QgsAbstractReportSection *child : std::as_const( mChildren ) )
243 result = result && child->beginRender();
248bool QgsAbstractReportSection::next()
252 if ( mNextSection == Header )
258 if ( mHeaderEnabled && mHeader )
260 if ( prepareHeader() )
262 mCurrentLayout = mHeader.get();
271 if ( mNextSection == Body )
273 mNextSection = Children;
281 mCurrentLayout = body;
286 if ( mNextSection == Children )
288 bool bodiesAvailable =
false;
292 while ( mNextChild < mChildren.count() )
295 if ( mChildren.at( mNextChild )->next() )
297 mCurrentLayout = mChildren.at( mNextChild )->layout();
309 QgsLayout *body = nextBody( bodiesAvailable );
310 if ( bodiesAvailable )
314 for ( QgsAbstractReportSection *section : std::as_const( mChildren ) )
321 mCurrentLayout = body;
325 while ( bodiesAvailable );
328 mNextSection = Footer;
331 if ( mNextSection == Footer )
337 if ( mFooterEnabled && mFooter )
339 if ( prepareFooter() )
341 mCurrentLayout = mFooter.get();
349 mCurrentLayout =
nullptr;
353bool QgsAbstractReportSection::endRender()
360 for ( QgsAbstractReportSection *child : std::as_const( mChildren ) )
362 result = result && child->endRender();
367void QgsAbstractReportSection::reset()
369 mCurrentLayout =
nullptr;
371 mNextSection = Header;
372 for ( QgsAbstractReportSection *section : std::as_const( mChildren ) )
378bool QgsAbstractReportSection::prepareHeader()
383bool QgsAbstractReportSection::prepareFooter()
388void QgsAbstractReportSection::setHeader(
QgsLayout *header )
390 mHeader.reset( header );
393void QgsAbstractReportSection::setFooter(
QgsLayout *footer )
395 mFooter.reset( footer );
398int QgsAbstractReportSection::row()
const
401 return mParent->childSections().indexOf(
const_cast<QgsAbstractReportSection *
>(
this ) );
406QgsAbstractReportSection *QgsAbstractReportSection::childSection(
int index )
408 return mChildren.value( index );
411void QgsAbstractReportSection::appendChild( QgsAbstractReportSection *section )
413 section->setParentSection(
this );
414 mChildren.append( section );
417void QgsAbstractReportSection::insertChild(
int index, QgsAbstractReportSection *section )
419 section->setParentSection(
this );
420 index = std::max( 0, index );
421 index = std::min( index,
static_cast<int>( mChildren.count() ) );
422 mChildren.insert( index, section );
425void QgsAbstractReportSection::removeChild( QgsAbstractReportSection *section )
427 mChildren.removeAll( section );
431void QgsAbstractReportSection::removeChildAt(
int index )
433 if ( index < 0 || index >= mChildren.count() )
436 QgsAbstractReportSection *section = mChildren.at( index );
437 removeChild( section );
440void QgsAbstractReportSection::copyCommonProperties( QgsAbstractReportSection *destination )
const
442 destination->mHeaderEnabled = mHeaderEnabled;
444 destination->mHeader.reset( mHeader->clone() );
446 destination->mHeader.reset();
448 destination->mFooterEnabled = mFooterEnabled;
450 destination->mFooter.reset( mFooter->clone() );
452 destination->mFooter.reset();
454 qDeleteAll( destination->mChildren );
455 destination->mChildren.clear();
457 for ( QgsAbstractReportSection *child : std::as_const( mChildren ) )
459 destination->appendChild( child->clone() );
463bool QgsAbstractReportSection::writePropertiesToElement( QDomElement &, QDomDocument &,
const QgsReadWriteContext & )
const
468bool QgsAbstractReportSection::readPropertiesFromElement(
const QDomElement &,
const QDomDocument &,
const QgsReadWriteContext & )
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
A container for the context for various read/write operations on objects.
An interface for classes which can visit style entity (e.g.
@ ReportFooter
Report footer section.
@ ReportSection
Report sub section.
@ ReportHeader
Report header section.
virtual bool visitExit(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor stops visiting a node.
virtual bool visitEnter(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor starts visiting a node.
Contains information relating to a node (i.e.