Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsabstractreportsection.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 QGSABSTRACTREPORTSECTION_H 17 : : #define QGSABSTRACTREPORTSECTION_H 18 : : 19 : : #include "qgis_core.h" 20 : : #include "qgsabstractlayoutiterator.h" 21 : : #include "qgslayoutreportcontext.h" 22 : : #include "qgsvectorlayerref.h" 23 : : 24 : : 25 : : ///@cond NOT_STABLE 26 : : 27 : : // This is not considered stable API - it is exposed to python bindings only for unit testing! 28 : : 29 : : /** 30 : : * \ingroup core 31 : : * \class QgsReportSectionContext 32 : : * \brief Current context for a report section. 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 : : * \since QGIS 3.0 36 : : */ 37 : 0 : class CORE_EXPORT QgsReportSectionContext 38 : : { 39 : : public: 40 : : 41 : : //! Current feature 42 : : QgsFeature feature; 43 : : 44 : : //! Current coverage layer 45 : 0 : QgsVectorLayer *currentLayer = nullptr; 46 : : 47 : : //! Current field filters 48 : : QVariantMap fieldFilters; 49 : : }; 50 : : 51 : : /** 52 : : * \ingroup core 53 : : * \class QgsAbstractReportSection 54 : : * \brief An abstract base class for QgsReport subsections. 55 : : * \warning This is not considered stable API, and may change in future QGIS releases. It is 56 : : * exposed to the Python bindings for unit testing purposes only. 57 : : * \since QGIS 3.0 58 : : */ 59 : : class CORE_EXPORT QgsAbstractReportSection : public QgsAbstractLayoutIterator 60 : : { 61 : : 62 : : #ifdef SIP_RUN 63 : : SIP_CONVERT_TO_SUBCLASS_CODE 64 : : if ( dynamic_cast< QgsReportSectionFieldGroup * >( sipCpp ) ) 65 : : sipType = sipType_QgsReportSectionFieldGroup; 66 : : else if ( dynamic_cast< QgsReportSectionLayout * >( sipCpp ) ) 67 : : sipType = sipType_QgsReportSectionLayout; 68 : : else 69 : : sipType = NULL; 70 : : SIP_END 71 : : #endif 72 : : 73 : : public: 74 : : 75 : : /** 76 : : * Constructor for QgsAbstractReportSection, attached to the specified \a parent section. 77 : : * Note that ownership is not transferred to \a parent. 78 : : */ 79 : : QgsAbstractReportSection( QgsAbstractReportSection *parentSection = nullptr ); 80 : : 81 : : ~QgsAbstractReportSection() override; 82 : : 83 : : //! QgsAbstractReportSection cannot be copied 84 : : QgsAbstractReportSection( const QgsAbstractReportSection &other ) = delete; 85 : : 86 : : //! QgsAbstractReportSection cannot be copied 87 : : QgsAbstractReportSection &operator=( const QgsAbstractReportSection &other ) = delete; 88 : : 89 : : /** 90 : : * Returns the section subclass type. 91 : : */ 92 : : virtual QString type() const = 0; 93 : : 94 : : /** 95 : : * Returns a user-visible, translated description of the section. 96 : : */ 97 : : virtual QString description() const = 0; 98 : : 99 : : /** 100 : : * Returns an icon representing the section. 101 : : */ 102 : : virtual QIcon icon() const = 0; 103 : : 104 : : /** 105 : : * Clones the report section. Ownership of the returned section is 106 : : * transferred to the caller. 107 : : * 108 : : * Subclasses should call copyCommonProperties() in their clone() 109 : : * implementations. 110 : : */ 111 : : virtual QgsAbstractReportSection *clone() const = 0 SIP_FACTORY; 112 : : 113 : : /** 114 : : * Returns the parent report section. 115 : : */ 116 : 0 : QgsAbstractReportSection *parentSection() { return mParent; } 117 : : 118 : : /** 119 : : * Returns the associated project. 120 : : */ 121 : : QgsProject *project(); 122 : : 123 : : // TODO - how to handle this? 124 : 0 : int count() const override { return -1; } 125 : : 126 : : QString filePath( const QString &baseFilePath, const QString &extension ) override; 127 : : QgsLayout *layout() override; 128 : : bool beginRender() override; 129 : : bool next() override; 130 : : bool endRender() override; 131 : : 132 : : /** 133 : : * Resets the section, ready for a new iteration. 134 : : */ 135 : : virtual void reset(); 136 : : 137 : : /** 138 : : * Called just before rendering the section's header. Should return TRUE if the header 139 : : * is to be included for this section, or FALSE to skip the header for the current 140 : : * section. 141 : : * \see prepareFooter() 142 : : */ 143 : : virtual bool prepareHeader(); 144 : : 145 : : /** 146 : : * Called just before rendering the section's footer. Should return TRUE if the footer 147 : : * is to be included for this section, or FALSE to skip the footerfor the current 148 : : * section. 149 : : * \see prepareHeader() 150 : : */ 151 : : virtual bool prepareFooter(); 152 : : 153 : : /** 154 : : * Returns the next body layout to export, or NULLPTR if 155 : : * no body layout is required this iteration. 156 : : * 157 : : * \a ok will be set to FALSE if no bodies remain for this section. 158 : : */ 159 : 0 : virtual QgsLayout *nextBody( bool &ok SIP_OUT ) { ok = false; return nullptr; } 160 : : 161 : : /** 162 : : * Returns TRUE if the header for the section is enabled. 163 : : * \see setHeaderEnabled() 164 : : * \see header() 165 : : * \see setHeader() 166 : : */ 167 : : bool headerEnabled() const { return mHeaderEnabled; } 168 : : 169 : : /** 170 : : * Sets whether the header for the section is \a enabled. 171 : : * \see headerEnabled() 172 : : * \see header() 173 : : * \see setHeader() 174 : : */ 175 : : void setHeaderEnabled( bool enabled ) { mHeaderEnabled = enabled; } 176 : : 177 : : /** 178 : : * Returns the header for the section. Note that the header is only 179 : : * included if headerEnabled() is TRUE. 180 : : * \see setHeaderEnabled() 181 : : * \see headerEnabled() 182 : : * \see setHeader() 183 : : */ 184 : 0 : QgsLayout *header() { return mHeader.get(); } 185 : : 186 : : /** 187 : : * Sets the \a header for the section. Note that the header is only 188 : : * included if headerEnabled() is TRUE. Ownership of \a header 189 : : * is transferred to the report section. 190 : : * \see setHeaderEnabled() 191 : : * \see headerEnabled() 192 : : * \see header() 193 : : */ 194 : : void setHeader( QgsLayout *header SIP_TRANSFER ); 195 : : 196 : : /** 197 : : * Returns TRUE if the footer for the section is enabled. 198 : : * \see setFooterEnabled() 199 : : * \see footer() 200 : : * \see setFooter() 201 : : */ 202 : : bool footerEnabled() const { return mFooterEnabled; } 203 : : 204 : : /** 205 : : * Sets whether the footer for the section is \a enabled. 206 : : * \see footerEnabled() 207 : : * \see footer() 208 : : * \see setFooter() 209 : : */ 210 : : void setFooterEnabled( bool enabled ) { mFooterEnabled = enabled; } 211 : : 212 : : /** 213 : : * Returns the footer for the section. Note that the footer is only 214 : : * included if footerEnabled() is TRUE. 215 : : * \see setFooterEnabled() 216 : : * \see footerEnabled() 217 : : * \see setFooter() 218 : : */ 219 : 0 : QgsLayout *footer() { return mFooter.get(); } 220 : : 221 : : /** 222 : : * Sets the \a footer for the section. Note that the footer is only 223 : : * included if footerEnabled() is TRUE. Ownership of \a footer 224 : : * is transferred to the report section. 225 : : * \see setFooterEnabled() 226 : : * \see footerEnabled() 227 : : * \see footer() 228 : : */ 229 : : void setFooter( QgsLayout *footer SIP_TRANSFER ); 230 : : 231 : : /** 232 : : * Returns the number of child sections for this report section. The child 233 : : * sections form the body of the report section. 234 : : * \see children() 235 : : */ 236 : : int childCount() const { return mChildren.count(); } 237 : : 238 : : /** 239 : : * Returns the row number of the section within it's parent section. 240 : : */ 241 : : int row() const; 242 : : 243 : : /** 244 : : * Returns all child sections for this report section. The child 245 : : * sections form the body of the report section. 246 : : * \see childCount() 247 : : * \see child() 248 : : * \see appendChild() 249 : : * \see insertChild() 250 : : * \see removeChild() 251 : : */ 252 : 0 : QList< QgsAbstractReportSection * > childSections() const { return mChildren; } 253 : : 254 : : /** 255 : : * Returns the child section at the specified \a index. 256 : : * \see children() 257 : : */ 258 : : QgsAbstractReportSection *childSection( int index ); 259 : : 260 : : /** 261 : : * Adds a child \a section, transferring ownership of the section to this section. 262 : : * \see children() 263 : : * \see insertChild() 264 : : */ 265 : : void appendChild( QgsAbstractReportSection *section SIP_TRANSFER ); 266 : : 267 : : /** 268 : : * Inserts a child \a section at the specified \a index, transferring ownership of the section to this section. 269 : : * \see children() 270 : : * \see appendChild() 271 : : */ 272 : : void insertChild( int index, QgsAbstractReportSection *section SIP_TRANSFER ); 273 : : 274 : : /** 275 : : * Removes a child \a section, deleting it. 276 : : * \see children() 277 : : */ 278 : : void removeChild( QgsAbstractReportSection *section ); 279 : : 280 : : /** 281 : : * Removes the child section at the specified \a index, deleting it. 282 : : * \see children() 283 : : */ 284 : : void removeChildAt( int index ); 285 : : 286 : : /** 287 : : * Sets the current \a context for this section. 288 : : * \see context() 289 : : */ 290 : : void setContext( const QgsReportSectionContext &context ); 291 : : 292 : : /** 293 : : * Returns the current context for this section. 294 : : * \see setContext() 295 : : */ 296 : 0 : const QgsReportSectionContext &context() const { return mContext; } 297 : : 298 : : /** 299 : : * Stores the section state in a DOM element. 300 : : * \see readXml() 301 : : */ 302 : : bool writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context ) const; 303 : : 304 : : /** 305 : : * Sets the item state from a DOM element. 306 : : * \see writeXml() 307 : : */ 308 : : bool readXml( const QDomElement §ionElement, const QDomDocument &document, const QgsReadWriteContext &context ); 309 : : 310 : : /** 311 : : * Refreshes the section when global layout related options change. 312 : : */ 313 : : virtual void reloadSettings(); 314 : : 315 : : /** 316 : : * Accepts the specified style entity \a visitor, causing it to visit all style entities associated 317 : : * with the report. 318 : : * 319 : : * Returns TRUE if the visitor should continue visiting other objects, or FALSE if visiting 320 : : * should be canceled. 321 : : * 322 : : * \since QGIS 3.10 323 : : */ 324 : : bool accept( QgsStyleEntityVisitorInterface *visitor ) const; 325 : : 326 : : protected: 327 : : 328 : : //! Report sub-sections 329 : : enum SubSection 330 : : { 331 : : Header, //!< Header for section 332 : : Body, //!< Body of section 333 : : Children, //!< Child sections 334 : : Footer, //!< Footer for section 335 : : End, //!< End of section (i.e. past all available content) 336 : : }; 337 : : 338 : : /** 339 : : * Copies the common properties of a report section to a \a destination section. 340 : : * This method should be called from clone() implementations. 341 : : */ 342 : : void copyCommonProperties( QgsAbstractReportSection *destination ) const; 343 : : 344 : : /** 345 : : * Sets the \a parent report section. 346 : : */ 347 : 0 : virtual void setParentSection( QgsAbstractReportSection *parent ) { mParent = parent; } 348 : : 349 : : /** 350 : : * Stores section state within an XML DOM element. 351 : : * \see writeXml() 352 : : * \see readPropertiesFromElement() 353 : : */ 354 : : virtual bool writePropertiesToElement( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const; 355 : : 356 : : /** 357 : : * Sets section state from a DOM element. 358 : : * \see writePropertiesToElement() 359 : : * \see readXml() 360 : : */ 361 : : virtual bool readPropertiesFromElement( const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context ); 362 : : 363 : : private: 364 : : 365 : : QgsAbstractReportSection *mParent = nullptr; 366 : : 367 : : int mSectionNumber = 0; 368 : : SubSection mNextSection = Header; 369 : : int mNextChild = 0; 370 : : QgsLayout *mCurrentLayout = nullptr; 371 : : 372 : : bool mHeaderEnabled = false; 373 : : bool mFooterEnabled = false; 374 : : std::unique_ptr< QgsLayout > mHeader; 375 : : std::unique_ptr< QgsLayout > mFooter; 376 : : 377 : : QList< QgsAbstractReportSection * > mChildren; 378 : : 379 : : QgsReportSectionContext mContext; 380 : : 381 : : #ifdef SIP_RUN 382 : : QgsAbstractReportSection( const QgsAbstractReportSection &other ); 383 : : #endif 384 : : }; 385 : : 386 : : ///@endcond 387 : : 388 : : #endif //QGSABSTRACTREPORTSECTION_H