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 )
56 if ( context.currentLayer )
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() != QStringLiteral(
"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() != QStringLiteral(
"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 switch ( mNextSection )
259 if ( mHeaderEnabled && mHeader )
261 if ( prepareHeader() )
263 mCurrentLayout = mHeader.get();
275 mNextSection = Children;
283 mCurrentLayout = body;
292 bool bodiesAvailable =
false;
296 while ( mNextChild < mChildren.count() )
299 if ( mChildren.at( mNextChild )->next() )
301 mCurrentLayout = mChildren.at( mNextChild )->layout();
313 QgsLayout *body = nextBody( bodiesAvailable );
314 if ( bodiesAvailable )
318 for ( QgsAbstractReportSection *section : qgis::as_const( mChildren ) )
325 mCurrentLayout = body;
329 while ( bodiesAvailable );
332 mNextSection = Footer;
342 if ( mFooterEnabled && mFooter )
344 if ( prepareFooter() )
346 mCurrentLayout = mFooter.get();
359 mCurrentLayout =
nullptr;
363 bool QgsAbstractReportSection::endRender()
370 for ( QgsAbstractReportSection *child : qgis::as_const( mChildren ) )
372 result = result && child->endRender();
377 void QgsAbstractReportSection::reset()
379 mCurrentLayout =
nullptr;
381 mNextSection = Header;
382 for ( QgsAbstractReportSection *section : qgis::as_const( mChildren ) )
388 bool QgsAbstractReportSection::prepareHeader()
393 bool QgsAbstractReportSection::prepareFooter()
398 void QgsAbstractReportSection::setHeader(
QgsLayout *header )
400 mHeader.reset( header );
403 void QgsAbstractReportSection::setFooter(
QgsLayout *footer )
405 mFooter.reset( footer );
408 int QgsAbstractReportSection::row()
const 411 return mParent->childSections().indexOf( const_cast<QgsAbstractReportSection *>(
this ) );
416 QgsAbstractReportSection *QgsAbstractReportSection::childSection(
int index )
418 return mChildren.value( index );
421 void QgsAbstractReportSection::appendChild( QgsAbstractReportSection *section )
423 section->setParentSection(
this );
424 mChildren.append( section );
427 void QgsAbstractReportSection::insertChild(
int index, QgsAbstractReportSection *section )
429 section->setParentSection(
this );
430 index = std::max( 0, index );
431 index = std::min( index, mChildren.count() );
432 mChildren.insert( index, section );
435 void QgsAbstractReportSection::removeChild( QgsAbstractReportSection *section )
437 mChildren.removeAll( section );
441 void QgsAbstractReportSection::removeChildAt(
int index )
443 if ( index < 0 || index >= mChildren.count() )
446 QgsAbstractReportSection *section = mChildren.at( index );
447 removeChild( section );
450 void QgsAbstractReportSection::copyCommonProperties( QgsAbstractReportSection *destination )
const 452 destination->mHeaderEnabled = mHeaderEnabled;
454 destination->mHeader.reset( mHeader->clone() );
456 destination->mHeader.reset();
458 destination->mFooterEnabled = mFooterEnabled;
460 destination->mFooter.reset( mFooter->clone() );
462 destination->mFooter.reset();
464 qDeleteAll( destination->mChildren );
465 destination->mChildren.clear();
467 for ( QgsAbstractReportSection *child : qgis::as_const( mChildren ) )
469 destination->appendChild( child->clone() );
473 bool QgsAbstractReportSection::writePropertiesToElement( QDomElement &, QDomDocument &,
const QgsReadWriteContext & )
const 478 bool QgsAbstractReportSection::readPropertiesFromElement(
const QDomElement &,
const QDomDocument &,
const QgsReadWriteContext & )
The class is used as a container of context for various read/write operations on other objects...
An interface for classes which can visit style entity (e.g.
virtual bool visitExit(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor stops visiting a node.
void setLayer(QgsVectorLayer *layer)
Sets the vector layer associated with the layout's context.
Contains information relating to a node (i.e.
virtual QgsLayout * layout()=0
Returns the layout associated with the iterator.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts, annotations, canvases, etc.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
QgsLayoutReportContext & reportContext()
Returns a reference to the layout's report context, which stores information relating to the current ...
virtual bool visitEnter(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor starts visiting a node.
void setFeature(const QgsFeature &feature)
Sets the current feature for evaluating the layout.