1 /*************************************************************************** 2 qgslayouttable.h 3 ---------------- 4 begin : November 2017 5 copyright : (C) 2017 by Nyall Dawson 6 email : nyall dot dawson at gmail dot com 7 ***************************************************************************/ 8 9 /*************************************************************************** 10 * * 11 * This program is free software; you can redistribute it and/or modify * 12 * it under the terms of the GNU General Public License as published by * 13 * the Free Software Foundation; either version 2 of the License, or * 14 * (at your option) any later version. * 15 * * 16 ***************************************************************************/ 17 18 #ifndef QGSLAYOUTTABLE_H 19 #define QGSLAYOUTTABLE_H 20 21 #include "qgis_core.h" 22 #include "qgis_sip.h" 23 #include "qgslayoutmultiframe.h" 24 #include "qgsconditionalstyle.h" 25 #include "qgstextformat.h" 26 #include <QFont> 27 #include <QColor> 28 #include <QPair> 29 30 class QgsLayoutTableColumn; 31 32 /** 33 * \ingroup core 34 * \brief List of QVariants, representing a the contents of a single row in 35 * a QgsLayoutTable 36 * \since QGIS 3.0 37 */ 38 typedef QVector< QVariant > QgsLayoutTableRow; 39 40 /** 41 * \ingroup core 42 * \brief List of QgsLayoutTableRows, representing rows and column cell contents 43 * for a QgsLayoutTable 44 * \since QGIS 3.0 45 */ 46 #ifndef SIP_RUN 47 typedef QVector< QgsLayoutTableRow > QgsLayoutTableContents; 48 #else 49 typedef QVector< QVector< QVariant > > QgsLayoutTableContents; 50 #endif 51 52 53 /** 54 * \ingroup core 55 * \brief List of column definitions for a QgsLayoutTable 56 * \since QGIS 3.0 57 */ 58 typedef QVector<QgsLayoutTableColumn> QgsLayoutTableColumns; 59 60 /** 61 * \ingroup core 62 * \brief List of column definitions for sorting a QgsLayoutTable 63 * \since QGIS 3.14 64 */ 65 typedef QVector<QgsLayoutTableColumn> QgsLayoutTableSortColumns; 66 67 68 69 /** 70 * \ingroup core 71 * \class QgsLayoutTableStyle 72 * \brief Styling option for a layout table cell 73 * \since QGIS 3.0 74 */ 75 76 class CORE_EXPORT QgsLayoutTableStyle 77 { 78 public: 79 80 //! Constructor for QgsLayoutTableStyle 81 QgsLayoutTableStyle() = default; 82 83 //! Whether the styling option is enabled 84 bool enabled = false; 85 86 //! Cell background color 87 QColor cellBackgroundColor = QColor( 255, 255, 255, 255 ); 88 89 /** 90 * Writes the style's properties to XML for storage. 91 * \param styleElem an existing QDomElement in which to store the style's properties. 92 * \param doc QDomDocument for the destination XML. 93 * \see readXml 94 */ 95 bool writeXml( QDomElement &styleElem, QDomDocument &doc ) const; 96 97 /** 98 * Reads the style's properties from XML. 99 * \param styleElem a QDomElement holding the style's desired properties. 100 * \see writeXml 101 */ 102 bool readXml( const QDomElement &styleElem ); 103 104 }; 105 106 /** 107 * \brief A class to display a table in the print layout, and allow 108 * the table to span over multiple frames 109 * \ingroup core 110 * \since QGIS 3.0 111 */ 112 class CORE_EXPORT QgsLayoutTable: public QgsLayoutMultiFrame 113 { 114 Q_OBJECT 115 116 public: 117 118 /** 119 * Controls how headers are horizontally aligned in a table 120 */ 121 enum HeaderHAlignment 122 { 123 FollowColumn, //!< Header uses the same alignment as the column 124 HeaderLeft, //!< Align headers left 125 HeaderCenter, //!< Align headers to center 126 HeaderRight //!< Align headers right 127 }; 128 129 /** 130 * Controls where headers are shown in the table 131 */ 132 enum HeaderMode 133 { 134 FirstFrame = 0, //!< Header shown on first frame only 135 AllFrames, //!< Headers shown on all frames 136 NoHeaders //!< No headers shown for table 137 }; 138 139 /** 140 * Controls how empty tables are displayed 141 */ 142 enum EmptyTableMode 143 { 144 HeadersOnly = 0, //!< Show header rows only 145 HideTable, //!< Hides entire table if empty 146 ShowMessage //!< Shows preset message instead of table contents 147 }; 148 149 /** 150 * Controls how long strings in the table are handled 151 */ 152 enum WrapBehavior 153 { 154 TruncateText = 0, //!< Text which doesn't fit inside the cell is truncated 155 WrapText //!< Text which doesn't fit inside the cell is wrapped. Note that this only applies to text in columns with a fixed width. 156 }; 157 158 /** 159 * Row or column groups for cell styling 160 */ 161 enum CellStyleGroup 162 { 163 OddColumns, //!< Style odd numbered columns 164 EvenColumns, //!< Style even numbered columns 165 OddRows, //!< Style odd numbered rows 166 EvenRows, //!< Style even numbered rows 167 FirstColumn, //!< Style first column only 168 LastColumn, //!< Style last column only 169 HeaderRow, //!< Style header row 170 FirstRow, //!< Style first row only 171 LastRow //!< Style last row only 172 }; 173 174 /** 175 * Constructor for QgsLayoutTable, belonging to the specified \a layout. 176 */ 177 QgsLayoutTable( QgsLayout *layout ); 178 179 ~QgsLayoutTable() override; 180 181 /** 182 * Sets the \a margin distance in mm between cell borders and their contents. 183 * \see cellMargin() 184 */ 185 void setCellMargin( double margin ); 186 187 /** 188 * Returns the margin distance between cell borders and their contents in mm. 189 * \see setCellMargin() 190 */ cellMargin()191 double cellMargin() const { return mCellMargin; } 192 193 /** 194 * Sets the behavior \a mode for empty tables with no content rows. 195 * \see emptyTableBehavior() 196 */ 197 void setEmptyTableBehavior( EmptyTableMode mode ); 198 199 /** 200 * Returns the behavior mode for empty tables. This property controls 201 * how the table is drawn if it contains no content rows. 202 * \see setEmptyTableBehavior() 203 */ emptyTableBehavior()204 EmptyTableMode emptyTableBehavior() const { return mEmptyTableMode; } 205 206 /** 207 * Sets the \a message for empty tables with no content rows. This message 208 * is displayed in the table body if the empty table behavior is 209 * set to ShowMessage. 210 * \see emptyTableMessage() 211 * \see setEmptyTableBehavior() 212 */ 213 void setEmptyTableMessage( const QString &message ); 214 215 /** 216 * Returns the message for empty tables with no content rows. This message 217 * is displayed in the table body if the empty table behavior is 218 * set to ShowMessage. 219 * \see setEmptyTableMessage() 220 * \see emptyTableBehavior() 221 */ emptyTableMessage()222 QString emptyTableMessage() const { return mEmptyTableMessage; } 223 224 /** 225 * Sets whether empty rows should be drawn. Tables default to hiding empty rows. 226 * \param showEmpty set to TRUE to show empty rows in the table 227 * \see showEmptyRows() 228 */ 229 void setShowEmptyRows( bool showEmpty ); 230 231 /** 232 * Returns whether empty rows are drawn in the table. 233 * \see setShowEmptyRows() 234 */ showEmptyRows()235 bool showEmptyRows() const { return mShowEmptyRows; } 236 237 /** 238 * Sets the \a font used to draw header text in the table. 239 * \see headerFont() 240 * \see setContentFont() 241 * \deprecated use setHeaderTextFormat() instead 242 */ 243 Q_DECL_DEPRECATED void setHeaderFont( const QFont &font ) SIP_DEPRECATED; 244 245 /** 246 * Returns the font used to draw header text in the table. 247 * \see setHeaderFont() 248 * \see contentFont() 249 * \deprecated use headerTextFormat() instead 250 */ 251 Q_DECL_DEPRECATED QFont headerFont() const SIP_DEPRECATED; 252 253 /** 254 * Sets the \a color used to draw header text in the table. 255 * \see headerFontColor() 256 * \see setHeaderFont() 257 * \see setContentFontColor() 258 * \deprecated use setHeaderTextFormat() instead 259 */ 260 Q_DECL_DEPRECATED void setHeaderFontColor( const QColor &color ) SIP_DEPRECATED; 261 262 /** 263 * Returns the color used to draw header text in the table. 264 * \see setHeaderFontColor() 265 * \see headerFont() 266 * \see contentFontColor() 267 * \deprecated use headerTextFormat() instead 268 */ 269 Q_DECL_DEPRECATED QColor headerFontColor() const SIP_DEPRECATED; 270 271 /** 272 * Sets the \a format used to draw header text in the table. 273 * \see headerTextFormat() 274 * \see setContentTextFormat() 275 * \since QGIS 3.16 276 */ 277 void setHeaderTextFormat( const QgsTextFormat &format ); 278 279 /** 280 * Returns the format used to draw header text in the table. 281 * \see setHeaderTextFormat() 282 * \see contentTextFormat() 283 * \since QGIS 3.16 284 */ 285 QgsTextFormat headerTextFormat() const; 286 287 /** 288 * Sets the horizontal \a alignment for table headers. 289 * \see headerHAlignment() 290 */ 291 void setHeaderHAlignment( HeaderHAlignment alignment ); 292 293 /** 294 * Returns the horizontal alignment for table headers. 295 * \see setHeaderHAlignment() 296 */ headerHAlignment()297 HeaderHAlignment headerHAlignment() const { return mHeaderHAlignment; } 298 299 /** 300 * Sets the display \a mode for headers in the table. This property controls 301 * if and where headers are shown in the table. 302 * \see headerMode() 303 */ 304 void setHeaderMode( HeaderMode mode ); 305 306 /** 307 * Returns the display mode for headers in the table. This property controls 308 * if and where headers are shown in the table. 309 * \see setHeaderMode() 310 */ headerMode()311 HeaderMode headerMode() const { return mHeaderMode; } 312 313 /** 314 * Sets the \a font used to draw text in table body cells. 315 * \see contentFont() 316 * \see setHeaderFont() 317 * \deprecated use setContentTextFormat() instead 318 */ 319 Q_DECL_DEPRECATED void setContentFont( const QFont &font ) SIP_DEPRECATED; 320 321 /** 322 * Returns the font used to draw text in table body cells. 323 * \see setContentFont() 324 * \see headerFont() 325 * \deprecated use contextTextFormat() instead 326 */ 327 Q_DECL_DEPRECATED QFont contentFont() const SIP_DEPRECATED; 328 329 /** 330 * Sets the \a color used to draw text in table body cells. 331 * \see contentFontColor() 332 * \see setContentFont() 333 * \see setHeaderFontColor() 334 * \deprecated use setContentTextFormat() instead 335 */ 336 Q_DECL_DEPRECATED void setContentFontColor( const QColor &color ) SIP_DEPRECATED; 337 338 /** 339 * Returns the color used to draw text in table body cells. 340 * \see setContentFontColor() 341 * \see contentFont() 342 * \see headerFontColor() 343 * \deprecated use contextTextFormat() instead 344 */ 345 Q_DECL_DEPRECATED QColor contentFontColor() const SIP_DEPRECATED; 346 347 /** 348 * Sets the \a format used to draw content text in the table. 349 * \see contentTextFormat() 350 * \see setHeaderTextFormat() 351 * \since QGIS 3.16 352 */ 353 void setContentTextFormat( const QgsTextFormat &format ); 354 355 /** 356 * Returns the format used to draw content text in the table. 357 * \see setContentTextFormat() 358 * \see headerTextFormat() 359 * \since QGIS 3.16 360 */ 361 QgsTextFormat contentTextFormat() const; 362 363 /** 364 * Sets whether grid lines should be drawn in the table 365 * \param showGrid set to TRUE to show grid lines 366 * \see showGrid() 367 * \see setGridStrokeWidth() 368 * \see setGridColor() 369 */ 370 void setShowGrid( bool showGrid ); 371 372 /** 373 * Returns whether grid lines are drawn in the table 374 * \see setShowGrid() 375 * \see gridStrokeWidth() 376 * \see gridColor() 377 */ showGrid()378 bool showGrid() const { return mShowGrid; } 379 380 /** 381 * Sets the \a width in mm for grid lines in the table. 382 * \see gridStrokeWidth() 383 * \see setShowGrid() 384 * \see setGridColor() 385 */ 386 void setGridStrokeWidth( double width ); 387 388 /** 389 * Returns the width of grid lines in the table in mm. 390 * \see setGridStrokeWidth() 391 * \see showGrid() 392 * \see gridColor() 393 */ gridStrokeWidth()394 double gridStrokeWidth() const { return mGridStrokeWidth; } 395 396 /** 397 * Sets the \a color used for grid lines in the table. 398 * \see gridColor() 399 * \see setShowGrid() 400 * \see setGridStrokeWidth() 401 */ 402 void setGridColor( const QColor &color ); 403 404 /** 405 * Returns the color used for grid lines in the table. 406 * \see setGridColor() 407 * \see showGrid() 408 * \see gridStrokeWidth() 409 */ gridColor()410 QColor gridColor() const { return mGridColor; } 411 412 /** 413 * Sets whether the grid's horizontal lines should be drawn in the table 414 * \param horizontalGrid set to TRUE to draw grid's horizontal lines 415 * \see setShowGrid() 416 * \see setGridStrokeWidth() 417 * \see setGridColor() 418 * \see setVerticalGrid() 419 */ 420 void setHorizontalGrid( bool horizontalGrid ); 421 422 /** 423 * Returns whether the grid's horizontal lines are drawn in the table. 424 * \see setShowGrid() 425 * \see setGridStrokeWidth() 426 * \see setGridColor() 427 * \see setVerticalGrid() 428 */ horizontalGrid()429 bool horizontalGrid() const { return mHorizontalGrid; } 430 431 /** 432 * Sets whether the grid's vertical lines should be drawn in the table 433 * \param verticalGrid set to TRUE to draw grid's vertical lines 434 * \see setShowGrid() 435 * \see setGridStrokeWidth() 436 * \see setGridColor() 437 * \see setHorizontalGrid() 438 */ 439 void setVerticalGrid( bool verticalGrid ); 440 441 /** 442 * Returns whether the grid's vertical lines are drawn in the table. 443 * \see setShowGrid() 444 * \see setGridStrokeWidth() 445 * \see setGridColor() 446 * \see setHorizontalGrid() 447 */ verticalGrid()448 bool verticalGrid() const { return mVerticalGrid; } 449 450 /** 451 * Sets the \a color used for background of table. 452 * \see backgroundColor() 453 * \see setGridColor() 454 */ 455 void setBackgroundColor( const QColor &color ); 456 457 /** 458 * Returns the color used for the background of the table. 459 * \see setBackgroundColor() 460 * \see gridColor() 461 */ backgroundColor()462 QColor backgroundColor() const { return mBackgroundColor; } 463 464 /** 465 * Sets the wrap \a behavior for the table, which controls how text within cells is 466 * automatically wrapped. 467 * \see wrapBehavior() 468 */ 469 void setWrapBehavior( WrapBehavior behavior ); 470 471 /** 472 * Returns the wrap behavior for the table, which controls how text within cells is 473 * automatically wrapped. 474 * \see setWrapBehavior() 475 */ wrapBehavior()476 WrapBehavior wrapBehavior() const { return mWrapBehavior; } 477 478 /** 479 * Returns a reference to the list of QgsLayoutTableColumns shown in the table 480 * \see setColumns() 481 */ columns()482 QgsLayoutTableColumns &columns() { return mColumns; } 483 484 /** 485 * Replaces the columns in the table with a specified list of QgsLayoutTableColumns. 486 * \param columns list of QgsLayoutTableColumns to show in table. 487 * \see columns() 488 */ 489 void setColumns( const QgsLayoutTableColumns &columns ); 490 491 /** 492 * Returns a reference to the list of QgsLayoutTableSortColumns shown in the table 493 * \see setSortColumns() 494 * \since QGIS 3.14 495 */ sortColumns()496 QgsLayoutTableSortColumns &sortColumns() { return mSortColumns; } 497 498 /** 499 * Replaces the sorting columns in the table with a specified list of QgsLayoutTableSortColumns. 500 * \param sortColumns list of QgsLayoutTableColumns used to sort the table. 501 * \see sortColumns() 502 * \since QGIS 3.14 503 */ 504 void setSortColumns( const QgsLayoutTableSortColumns &sortColumns ); 505 506 /** 507 * Sets the cell \a style for a cell \a group. 508 * \see cellStyle() 509 */ 510 void setCellStyle( CellStyleGroup group, const QgsLayoutTableStyle &style ); 511 512 /** 513 * Returns the cell style for a cell \a group. 514 * \see setCellStyle() 515 */ 516 const QgsLayoutTableStyle *cellStyle( CellStyleGroup group ) const; 517 518 /** 519 * Returns the text used in the column headers for the table. 520 * \returns QMap of int to QString, where the int is the column index (starting at 0), 521 * and the string is the text to use for the column's header 522 * \note not available in Python bindings 523 */ 524 virtual QMap<int, QString> headerLabels() const SIP_SKIP; 525 526 /** 527 * Fetches the contents used for the cells in the table. 528 * \returns TRUE if table contents were successfully retrieved. 529 * \param contents QgsLayoutTableContents to store retrieved row data in 530 */ 531 virtual bool getTableContents( QgsLayoutTableContents &contents ) = 0; 532 533 /** 534 * Returns the conditional style to use for the cell at \a row, \a column. 535 * 536 * \since QGIS 3.12 537 */ 538 virtual QgsConditionalStyle conditionalCellStyle( int row, int column ) const; 539 540 /** 541 * Creates a new QgsExpressionContextScope for the cell at \a row, \a column. 542 * 543 * \since QGIS 3.16 544 */ 545 virtual QgsExpressionContextScope *scopeForCell( int row, int column ) const SIP_FACTORY; 546 547 /** 548 * Returns the current contents of the table. Excludes header cells. 549 */ contents()550 QgsLayoutTableContents &contents() { return mTableContents; } 551 552 QSizeF fixedFrameSize( int frameIndex = -1 ) const override; 553 QSizeF minFrameSize( int frameIndex = -1 ) const override; 554 555 bool writePropertiesToElement( QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context ) const override; 556 bool readPropertiesFromElement( const QDomElement &itemElem, const QDomDocument &doc, const QgsReadWriteContext &context ) override; 557 QSizeF totalSize() const override; 558 void render( QgsLayoutItemRenderContext &context, const QRectF &renderExtent, int frameIndex ) override; 559 560 public slots: 561 562 void refresh() override; 563 564 /** 565 * Refreshes the contents shown in the table by querying for new data. 566 * This also causes the column widths and size of the table to change to accommodate the 567 * new data. 568 */ 569 virtual void refreshAttributes(); 570 571 void recalculateFrameSizes() override; 572 573 protected: 574 //! Margin between cell borders and cell text 575 double mCellMargin = 1.0; 576 577 //! Behavior for empty tables 578 EmptyTableMode mEmptyTableMode = HeadersOnly; 579 580 //! String to show in empty tables 581 QString mEmptyTableMessage; 582 583 //! True if empty rows should be shown in the table 584 bool mShowEmptyRows = false; 585 586 587 //! Alignment for table headers 588 HeaderHAlignment mHeaderHAlignment = FollowColumn; 589 590 //! Header display mode 591 HeaderMode mHeaderMode = FirstFrame; 592 593 QgsTextFormat mHeaderTextFormat; 594 QgsTextFormat mContentTextFormat; 595 596 //! True if grid should be shown 597 bool mShowGrid = true; 598 599 //! Width of grid lines 600 double mGridStrokeWidth = 0.5; 601 602 //! Color for grid lines 603 QColor mGridColor = Qt::black; 604 605 //! True if grid should be shown 606 bool mHorizontalGrid = true; 607 608 //! True if grid should be shown 609 bool mVerticalGrid = true; 610 611 //! Color for table background 612 QColor mBackgroundColor = Qt::white; 613 614 //! Columns to show in table 615 QgsLayoutTableColumns mColumns; 616 617 //! Columns to sort the table 618 QgsLayoutTableSortColumns mSortColumns; 619 620 //! Contents to show in table 621 QgsLayoutTableContents mTableContents; 622 623 //! Map of maximum width for each column 624 QMap<int, double> mMaxColumnWidthMap; 625 626 //! Map of maximum height for each row 627 QMap<int, double> mMaxRowHeightMap; 628 629 QSizeF mTableSize; 630 631 WrapBehavior mWrapBehavior = TruncateText; 632 633 QMap< CellStyleGroup, QgsLayoutTableStyle * > mCellStyles; 634 635 /** 636 * Calculates the maximum width of text shown in columns. 637 */ 638 virtual bool calculateMaxColumnWidths(); 639 640 /** 641 * Calculates the maximum height of text shown in rows. 642 */ 643 virtual bool calculateMaxRowHeights(); 644 645 /** 646 * Returns total width of table contents. 647 * \returns table width 648 * \see totalHeight 649 */ 650 //not const, as needs to call calculateMaxColumnWidths() 651 double totalWidth(); 652 653 /** 654 * Returns total height of table contents. 655 * \see totalWidth() 656 */ 657 //not const, as needs to call calculateMaxRowHeights() 658 double totalHeight(); 659 660 /** 661 * Calculates how many content rows would be visible within a frame of the specified 662 * height. 663 * \param context render context 664 * \param frameHeight height of frame 665 * \param firstRow index of first row visible in frame (where 0 = first row in table) 666 * \param includeHeader set to TRUE if frame would include a header row 667 * \param includeEmptyRows set to TRUE to also include rows which would be empty in the returned count. For instance, 668 * if the frame would include all table content rows and have space left for extra rows then setting this parameter 669 * to TRUE would also include a count of these extra blank rows. 670 * \returns number of visible content rows (excluding header row) 671 */ 672 int rowsVisible( QgsRenderContext &context, double frameHeight, int firstRow, bool includeHeader, bool includeEmptyRows ) const; 673 674 /** 675 * Calculates how many content rows are visible within a given frame. 676 * \param context render context 677 * \param frameIndex index number for frame 678 * \param firstRow index of first row visible in frame (where 0 = first row in table) 679 * \param includeEmptyRows set to TRUE to also include rows which would be empty in the returned count. For instance, 680 * if the frame would include all table content rows and have space left for extra rows then setting this parameter 681 * to TRUE would also include a count of these extra blank rows. 682 * \returns number of visible content rows (excludes header rows) 683 */ 684 int rowsVisible( QgsRenderContext &context, int frameIndex, int firstRow, bool includeEmptyRows ) const; 685 686 /** 687 * Calculates a range of rows which should be visible in a given frame. 688 * \param context render context 689 * \param frameIndex index number for frame 690 * \returns row range 691 */ 692 QPair<int, int> rowRange( QgsRenderContext &context, int frameIndex ) const; 693 694 /** 695 * Draws the horizontal grid lines for the table. 696 * \param context destination render context 697 * \param firstRow index corresponding to first row shown in frame 698 * \param lastRow index corresponding to last row shown in frame. If greater than the number of content rows in the 699 * table, then the default row height will be used for the remaining rows. 700 * \param drawHeaderLines set to TRUE to include for the table header 701 * \see drawVerticalGridLines() 702 */ 703 void drawHorizontalGridLines( QgsLayoutItemRenderContext &context, int firstRow, int lastRow, bool drawHeaderLines ) const; 704 705 /** 706 * Draws the vertical grid lines for the table. 707 * \param context destination render context 708 * \param maxWidthMap QMap of int to double, where the int contains the column number and the double is the 709 * maximum width of text present in the column. 710 * \param firstRow index corresponding to first row shown in frame 711 * \param lastRow index corresponding to last row shown in frame. If greater than the number of content rows in the 712 * table, then the default row height will be used for the remaining rows. 713 * \param hasHeader set to TRUE if table frame includes header cells 714 * \param mergeCells set to TRUE to merge table content cells 715 * \note not available in Python bindings 716 * \see drawVerticalGridLines() 717 * \see calculateMaxColumnWidths() 718 * \note not available in Python bindings 719 */ 720 void drawVerticalGridLines( QgsLayoutItemRenderContext &context, const QMap<int, double> &maxWidthMap, int firstRow, int lastRow, bool hasHeader, bool mergeCells = false ) const SIP_SKIP; 721 722 /** 723 * Recalculates and updates the size of the table and all table frames. 724 */ 725 void recalculateTableSize(); 726 727 /** 728 * Checks whether a table contents contains a given row 729 * \param contents table contents to check 730 * \param row row to check for 731 * \returns TRUE if contents contains rows 732 */ 733 bool contentsContainsRow( const QgsLayoutTableContents &contents, const QgsLayoutTableRow &row ) const; 734 735 /** 736 * Returns the text format to use for the cell at the specified \a row and \a column. 737 * 738 * \see textFormatForHeader() 739 * \since QGIS 3.16 740 */ 741 virtual QgsTextFormat textFormatForCell( int row, int column ) const; 742 743 /** 744 * Returns the text format to use for the header cell at the specified \a column. 745 * 746 * \see textFormatForCell() 747 * \since QGIS 3.16 748 */ 749 virtual QgsTextFormat textFormatForHeader( int column ) const; 750 751 /** 752 * Returns the horizontal alignment to use for the cell at the specified \a row and \a column. 753 * 754 * \see verticalAlignmentForCell() 755 * \since QGIS 3.16 756 */ 757 virtual Qt::Alignment horizontalAlignmentForCell( int row, int column ) const; 758 759 /** 760 * Returns the vertical alignment to use for the cell at the specified \a row and \a column. 761 * 762 * \see horizontalAlignmentForCell() 763 * \since QGIS 3.16 764 */ 765 virtual Qt::Alignment verticalAlignmentForCell( int row, int column ) const; 766 767 private: 768 769 QMap< CellStyleGroup, QString > mCellStyleNames; 770 771 //! Initializes cell style map 772 void initStyles(); 773 774 bool textRequiresWrapping( QgsRenderContext &context, const QString &text, double columnWidth, const QgsTextFormat &format ) const; 775 776 QStringList wrappedText( QgsRenderContext &context, const QString &value, double columnWidth, const QgsTextFormat &format ) const; 777 778 /** 779 * Returns the calculated background color for a row and column combination. 780 * \param row row number, where -1 is the header row, and 0 is the first body row 781 * \param column column number, where 0 is the first column 782 * \returns background color, or invalid QColor if no background should be drawn 783 */ 784 QColor backgroundColor( int row, int column ) const; 785 786 friend class TestQgsLayoutTable; 787 friend class TestQgsLayoutManualTable; 788 friend class QgsCompositionConverter; 789 }; 790 791 #endif // QGSLAYOUTTABLE_H 792