Skip to content

Commit

Permalink
[FEATURE] Reporting framework
Browse files Browse the repository at this point in the history
Reports are based on the new layouts engine. They consist of multiple
nested sections. Each individual section (and the report itself)
can have an optional header and footer (which are themselves layouts,
and can consist of multiple pages!).

Two different types of sections are implemented so far:
- a standard section, which has a single, static body layout. This
can be used to embed static layouts mid way through a report
- a "field group" section, which repeats its body layout for
every feature in a layer. The features are sorted by the selected
grouping feature (with an option for ascending/descending sort).
If a field group section has child sections (e.g. another field
group section with a different field, then only features
with unique values for the group feature are iterated over.
This allows nested reports, e.g.

Report
- Country: Australia
    - State: NSW
        - Town: Sydney
        - Town: Woolongong
    - State: QLD
        - Town: Beerburrum
        - Town: Brisbane
        - Town: Emerald
- Country: NZ
    - State: ... etc

In this example country, state or town groups can have their
own headers and footers which will be inserted in the report.

Reports are configured through a new panel in the layout designer
dialog, which is shown when editing a report (created through
the Layout Manager Dialog). The organizer allows for adding
(and removing) sections to the report, and for selecting which
layout (e.g. headers, footers, bodies) to edit within the
layout designer.
  • Loading branch information
nyalldawson committed Jan 5, 2018
1 parent 811145e commit 1ea5a5f
Show file tree
Hide file tree
Showing 7 changed files with 870 additions and 0 deletions.
1 change: 1 addition & 0 deletions python/core/core_auto.sip
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@
%Include composer/qgscomposertexttable.sip
%Include composer/qgspaperitem.sip
%Include layout/qgsabstractlayoutiterator.sip
%Include layout/qgsabstractreportsection.sip
%Include layout/qgslayoutaligner.sip
%Include layout/qgslayoutexporter.sip
%Include layout/qgslayoutgridsettings.sip
Expand Down
270 changes: 270 additions & 0 deletions python/core/layout/qgsabstractreportsection.sip
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/layout/qgsabstractreportsection.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/


class QgsAbstractReportSection : QgsAbstractLayoutIterator
{
%Docstring
An abstract base class for QgsReport subsections.

.. versionadded:: 3.0
%End

%TypeHeaderCode
#include "qgsabstractreportsection.h"
%End
public:

QgsAbstractReportSection();
%Docstring
Constructor for QgsAbstractReportSection
%End

~QgsAbstractReportSection();



virtual QgsAbstractReportSection *clone() const = 0 /Factory/;
%Docstring
Clones the report section. Ownership of the returned section is
transferred to the caller.

Subclasses should call copyCommonProperties() in their clone()
implementations.
%End


virtual QgsLayout *layout();

virtual bool beginRender();

virtual bool next();

virtual bool endRender();


bool headerEnabled() const;
%Docstring
Returns true if the header for the section is enabled.

.. seealso:: :py:func:`setHeaderEnabled()`

.. seealso:: :py:func:`header()`

.. seealso:: :py:func:`setHeader()`
%End

void setHeaderEnabled( bool enabled );
%Docstring
Sets whether the header for the section is ``enabled``.

.. seealso:: :py:func:`headerEnabled()`

.. seealso:: :py:func:`header()`

.. seealso:: :py:func:`setHeader()`
%End

QgsLayout *header();
%Docstring
Returns the header for the section. Note that the header is only
included if headerEnabled() is true.

.. seealso:: :py:func:`setHeaderEnabled()`

.. seealso:: :py:func:`headerEnabled()`

.. seealso:: :py:func:`setHeader()`
%End

void setHeader( QgsLayout *header /Transfer/ );
%Docstring
Sets the ``header`` for the section. Note that the header is only
included if headerEnabled() is true. Ownership of ``header``
is transferred to the report section.

.. seealso:: :py:func:`setHeaderEnabled()`

.. seealso:: :py:func:`headerEnabled()`

.. seealso:: :py:func:`header()`
%End

bool footerEnabled() const;
%Docstring
Returns true if the footer for the section is enabled.

.. seealso:: :py:func:`setFooterEnabled()`

.. seealso:: :py:func:`footer()`

.. seealso:: :py:func:`setFooter()`
%End

void setFooterEnabled( bool enabled );
%Docstring
Sets whether the footer for the section is ``enabled``.

.. seealso:: :py:func:`footerEnabled()`

.. seealso:: :py:func:`footer()`

.. seealso:: :py:func:`setFooter()`
%End

QgsLayout *footer();
%Docstring
Returns the footer for the section. Note that the footer is only
included if footerEnabled() is true.

.. seealso:: :py:func:`setFooterEnabled()`

.. seealso:: :py:func:`footerEnabled()`

.. seealso:: :py:func:`setFooter()`
%End

void setFooter( QgsLayout *footer /Transfer/ );
%Docstring
Sets the ``footer`` for the section. Note that the footer is only
included if footerEnabled() is true. Ownership of ``footer``
is transferred to the report section.

.. seealso:: :py:func:`setFooterEnabled()`

.. seealso:: :py:func:`footerEnabled()`

.. seealso:: :py:func:`footer()`
%End

int childCount() const;
%Docstring
Return the number of child sections for this report section. The child
sections form the body of the report section.

.. seealso:: :py:func:`children()`
%End

QList< QgsAbstractReportSection * > children();
%Docstring
Return all child sections for this report section. The child
sections form the body of the report section.

.. seealso:: :py:func:`childCount()`

.. seealso:: :py:func:`child()`

.. seealso:: :py:func:`appendChild()`

.. seealso:: :py:func:`insertChild()`

.. seealso:: :py:func:`removeChild()`
%End

QgsAbstractReportSection *child( int index );
%Docstring
Returns the child section at the specified ``index``.

.. seealso:: :py:func:`children()`
%End

void appendChild( QgsAbstractReportSection *section /Transfer/ );
%Docstring
Adds a child ``section``, transferring ownership of the section to this section.

.. seealso:: :py:func:`children()`

.. seealso:: :py:func:`insertChild()`
%End

void insertChild( int index, QgsAbstractReportSection *section /Transfer/ );
%Docstring
Inserts a child ``section`` at the specified ``index``, transferring ownership of the section to this section.

.. seealso:: :py:func:`children()`

.. seealso:: :py:func:`appendChild()`
%End

void removeChild( QgsAbstractReportSection *section );
%Docstring
Removes a child ``section``, deleting it.

.. seealso:: :py:func:`children()`
%End

void removeChildAt( int index );
%Docstring
Removes the child section at the specified ``index``, deleting it.

.. seealso:: :py:func:`children()`
%End

protected:

enum SubSection
{
Header,
Body,
Footer,
End,
};

void copyCommonProperties( QgsAbstractReportSection *destination ) const;
%Docstring
Copies the common properties of a report section to a ``destination`` section.
This method should be called from clone() implementations.
%End

private:
QgsAbstractReportSection( const QgsAbstractReportSection &other );
};


class QgsReport : QgsAbstractReportSection
{
%Docstring
Represents a report for use with the QgsLayout engine.

Reports consist of multiple sections, represented by QgsAbstractReportSection
subclasses.

.. versionadded:: 3.0
%End

%TypeHeaderCode
#include "qgsabstractreportsection.h"
%End
public:

QgsReport();
%Docstring
Constructor for QgsReport.
%End

virtual QgsReport *clone() const;


virtual int count();
virtual bool beginRender();

virtual bool next();


virtual QString filePath( const QString &baseFilePath, const QString &extension );


};

/************************************************************************
* This file has been generated automatically from *
* *
* src/core/layout/qgsabstractreportsection.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ SET(QGIS_CORE_SRCS
dxf/qgsdxfpaintengine.cpp
dxf/qgsdxfpallabeling.cpp

layout/qgsabstractreportsection.cpp
layout/qgslayout.cpp
layout/qgslayoutaligner.cpp
layout/qgslayoutatlas.cpp
Expand Down Expand Up @@ -1029,6 +1030,7 @@ SET(QGIS_CORE_HDRS
composer/qgspaperitem.h

layout/qgsabstractlayoutiterator.h
layout/qgsabstractreportsection.h
layout/qgslayoutaligner.h
layout/qgslayoutexporter.h
layout/qgslayoutgridsettings.h
Expand Down
Loading

0 comments on commit 1ea5a5f

Please sign in to comment.