1 /***************************************************************************
2                              qgsreportsectionfieldgroup.h
3                              ---------------------------
4     begin                : December 2017
5     copyright            : (C) 2017 by Nyall Dawson
6     email                : nyall dot dawson at gmail dot com
7  ***************************************************************************/
8 /***************************************************************************
9  *                                                                         *
10  *   This program is free software; you can redistribute it and/or modify  *
11  *   it under the terms of the GNU General Public License as published by  *
12  *   the Free Software Foundation; either version 2 of the License, or     *
13  *   (at your option) any later version.                                   *
14  *                                                                         *
15  ***************************************************************************/
16 #ifndef QGSREPORTSECTIONFIELDGROUP_H
17 #define QGSREPORTSECTIONFIELDGROUP_H
18 
19 #include "qgis_core.h"
20 #include "qgsabstractreportsection.h"
21 #include "qgsfeatureiterator.h"
22 
23 
24 ///@cond NOT_STABLE
25 
26 // This is not considered stable API - it is exposed to python bindings only for unit testing!
27 
28 /**
29  * \ingroup core
30  * \class QgsReportSectionFieldGroup
31  * \brief A report section consisting of a features
32  *
33  * \warning This is not considered stable API, and may change in future QGIS releases. It is
34  * exposed to the Python bindings for unit testing purposes only.
35  *
36  * \since QGIS 3.0
37  */
38 class CORE_EXPORT QgsReportSectionFieldGroup : public QgsAbstractReportSection
39 {
40   public:
41 
42     /**
43      * Visibility modes for header and footer sections
44      */
45     enum SectionVisibility
46     {
47       IncludeWhenFeaturesFound,      //!< The section will be included when features are found
48       AlwaysInclude                  //!< The section will always be included
49     };
50 
51     /**
52      * Constructor for QgsReportSectionFieldGroup, attached to the specified \a parent section.
53      * Note that ownership is not transferred to \a parent.
54      */
55     QgsReportSectionFieldGroup( QgsAbstractReportSection *parentSection = nullptr );
56 
type()57     QString type() const override { return QStringLiteral( "SectionFieldGroup" ); }
58     QString description() const override;
59     QIcon icon() const override;
60 
61     /**
62      * Returns the body layout for the section.
63      * \see setBody()
64      * \see bodyEnabled()
65      * \see setBodyEnabled()
66      */
body()67     QgsLayout *body() { return mBody.get(); }
68 
69     /**
70      * Sets the \a body layout for the section. Ownership of \a body
71      * is transferred to the report section.
72      * \see body()
73      * \see bodyEnabled()
74      * \see setBodyEnabled()
75      */
setBody(QgsLayout * body SIP_TRANSFER)76     void setBody( QgsLayout *body SIP_TRANSFER ) { mBody.reset( body ); }
77 
78     /**
79      * Returns TRUE if the body for the section is enabled.
80      * \see setBodyEnabled()
81      * \see body()
82      * \see setBody()
83      */
bodyEnabled()84     bool bodyEnabled() const { return mBodyEnabled; }
85 
86     /**
87      * Sets whether the body for the section is \a enabled.
88      * \see bodyEnabled()
89      * \see body()
90      * \see setBody()
91      */
setBodyEnabled(bool enabled)92     void setBodyEnabled( bool enabled ) { mBodyEnabled = enabled; }
93 
94 
95     /**
96      * Returns the vector layer associated with this section.
97      * \see setLayer()
98      */
layer()99     QgsVectorLayer *layer() { return mCoverageLayer.get(); }
100 
101     /**
102      * Sets the vector \a layer associated with this section.
103      * \see layer()
104      */
setLayer(QgsVectorLayer * layer)105     void setLayer( QgsVectorLayer *layer ) { mCoverageLayer = layer; }
106 
107     /**
108      * Returns the field associated with this section.
109      * \see setField()
110      */
field()111     QString field() const { return mField; }
112 
113     /**
114      * Sets the \a field associated with this section.
115      * \see field()
116      */
setField(const QString & field)117     void setField( const QString &field ) { mField = field; }
118 
119     /**
120      * Returns TRUE if the field values should be sorted ascending,
121      * or FALSE for descending sort.
122      * \see setSortAscending()
123      */
124     bool sortAscending() const;
125 
126     /**
127      * Sets whether the field values should be sorted ascending. Set to TRUE to sort
128      * ascending, or FALSE for descending sort.
129      * \see sortAscending()
130      */
131     void setSortAscending( bool sortAscending );
132 
133     /**
134      * Returns the header visibility mode.
135      * \see setHeaderVisibility()
136      */
headerVisibility()137     SectionVisibility headerVisibility() const { return mHeaderVisibility; }
138 
139     /**
140      * Sets the visibility mode for the header.
141      * \see headerVisibility()
142      */
setHeaderVisibility(SectionVisibility visibility)143     void setHeaderVisibility( SectionVisibility visibility ) { mHeaderVisibility = visibility; }
144 
145     /**
146      * Returns the footer visibility mode.
147      * \see setFooterVisibility()
148      */
footerVisibility()149     SectionVisibility footerVisibility() const { return mFooterVisibility; }
150 
151     /**
152      * Sets the visibility mode for the footer.
153      * \see footerVisibility()
154      */
setFooterVisibility(SectionVisibility visibility)155     void setFooterVisibility( SectionVisibility visibility ) { mFooterVisibility = visibility; }
156 
157     QgsReportSectionFieldGroup *clone() const override SIP_FACTORY;
158     bool beginRender() override;
159     bool prepareHeader() override;
160     bool prepareFooter() override;
161     QgsLayout *nextBody( bool &ok ) override;
162     void reset() override;
163     void setParentSection( QgsAbstractReportSection *parentSection ) override;
164     void reloadSettings() override;
165 
166   protected:
167 
168     bool writePropertiesToElement( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const override;
169     bool readPropertiesFromElement( const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context ) override;
170 
171   private:
172 
173     QgsVectorLayerRef mCoverageLayer;
174     QString mField;
175     bool mSortAscending = true;
176     int mFieldIndex = -1;
177     QgsFeatureIterator mFeatures;
178     bool mSkipNextRequest = false;
179     bool mNoFeatures = false;
180     SectionVisibility mHeaderVisibility = IncludeWhenFeaturesFound;
181     SectionVisibility mFooterVisibility = IncludeWhenFeaturesFound;
182     QgsFeature mHeaderFeature;
183     QgsFeature mLastFeature;
184     QSet< QVariant > mEncounteredValues;
185 
186     bool mBodyEnabled = false;
187     std::unique_ptr< QgsLayout > mBody;
188 
189     QgsFeatureRequest buildFeatureRequest() const;
190 
191     QgsFeature getNextFeature();
192     void updateChildContexts( const QgsFeature &feature );
193 
194 };
195 
196 
197 ///@endcond
198 
199 #endif //QGSREPORTSECTIONFIELDGROUP_H
200