KD Reports API Documentation  2.0
KDReportsSpreadsheetReportLayout.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** This file is part of the KD Reports library.
4 **
5 ** SPDX-FileCopyrightText: 2007-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
6 **
7 ** SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDAB-KDReports OR LicenseRef-KDAB-KDReports-US
8 **
9 ** Licensees holding valid commercial KD Reports licenses may use this file in
10 ** accordance with the KD Reports Commercial License Agreement provided with
11 ** the Software.
12 **
13 ** Contact info@kdab.com if any conditions of this licensing are not clear to you.
14 **
15 ****************************************************************************/
16 
21 #include <QAbstractItemModel>
22 
23 #include <QBitArray>
24 #include <QDebug>
25 #include <QIcon>
26 #include <QPainter>
27 #include <qmath.h> // qCeil
28 
30  : m_tableBreakingPageOrder(Report::DownThenRight)
31  , m_numHorizontalPages(1)
32  , m_numVerticalPages(0)
33  , m_layoutDirty(true)
34  , m_userRequestedFontScalingFactor(1.0)
35  , m_tableSettings()
36 
37 {
38  Q_UNUSED(report); // for later
39 }
40 
42 {
43  m_layoutDirty = true;
44 }
45 
47 {
48  m_tableLayout.m_cellFont = font;
49  m_tableLayout.m_horizontalHeaderFont = font;
50  m_tableLayout.m_verticalHeaderFont = font;
51  setLayoutDirty();
52 }
53 
55 {
56  return m_tableLayout.m_cellFont;
57 }
58 
59 qreal KDReports::SpreadsheetReportLayout::paintTableVerticalHeader(qreal x, qreal y, QPainter &painter, int row)
60 {
61  QAbstractItemModel *model = m_tableLayout.m_model;
62 
63  const QRectF cellRect(x, y, m_tableLayout.vHeaderWidth(), m_tableLayout.rowHeight());
64 
65  painter.setFont(m_tableLayout.verticalHeaderScaledFont());
66  painter.fillRect(cellRect, m_tableSettings.m_headerBackground);
67  drawBorder(cellRect, painter);
68 
69  const QColor foreground = qvariant_cast<QColor>(model->headerData(row, Qt::Vertical, Qt::ForegroundRole));
70  if (foreground.isValid())
71  painter.setPen(foreground);
72 
73  const QString cellText = model->headerData(row, Qt::Vertical).toString();
74  const qreal padding = m_tableLayout.scaledCellPadding();
75  const Qt::Alignment alignment(model->headerData(row, Qt::Vertical, Qt::TextAlignmentRole).toInt());
76  const QVariant cellDecoration = model->headerData(row, Qt::Vertical, Qt::DecorationRole);
77  const QVariant decorationAlignment = model->headerData(row, Qt::Vertical, KDReports::AutoTableElement::DecorationAlignmentRole);
78 
79  const QRectF cellContentsRect = cellRect.adjusted(padding, padding, -padding, -padding);
80  // painter.drawText( cellContentsRect, alignment, cellText );
81  paintTextAndIcon(painter, cellContentsRect, cellText, cellDecoration, decorationAlignment, alignment);
82 
83  if (foreground.isValid())
84  painter.setPen(Qt::black);
85 
86  x += cellRect.width();
87  return x;
88 }
89 
90 void KDReports::SpreadsheetReportLayout::paintTableHorizontalHeader(const QRectF &cellRect, QPainter &painter, int col)
91 {
92  QAbstractItemModel *model = m_tableLayout.m_model;
93 
94  painter.setFont(m_tableLayout.horizontalHeaderScaledFont());
95  // adjust rect so that it's really under the lines; we get some white space otherwise, sometimes
96  painter.fillRect(cellRect.adjusted(-0.5, -0.5, -0.5, -0.5), m_tableSettings.m_headerBackground);
97  drawBorder(cellRect, painter);
98 
99  const QColor foreground = qvariant_cast<QColor>(model->headerData(col, Qt::Horizontal, Qt::ForegroundRole));
100  if (foreground.isValid())
101  painter.setPen(foreground);
102 
103  const QString cellText = model->headerData(col, Qt::Horizontal).toString();
104  const qreal padding = m_tableLayout.scaledCellPadding();
105  const Qt::Alignment alignment(model->headerData(col, Qt::Horizontal, Qt::TextAlignmentRole).toInt());
106  const QVariant cellDecoration = model->headerData(col, Qt::Horizontal, Qt::DecorationRole);
107  const QVariant decorationAlignment = model->headerData(col, Qt::Horizontal, KDReports::AutoTableElement::DecorationAlignmentRole);
108 
109  const QRectF cellContentsRect = cellRect.adjusted(padding, padding, -padding, -padding);
110  // painter.drawText( cellContentsRect, alignment, cellText );
111  paintTextAndIcon(painter, cellContentsRect, cellText, cellDecoration, decorationAlignment, alignment);
112 
113  if (foreground.isValid())
114  painter.setPen(Qt::black);
115 }
116 
117 void KDReports::SpreadsheetReportLayout::paintIcon(QPainter &painter, const QRectF &cellContentsRect, const QVariant &cellDecoration) const
118 {
119  QPixmap pix = qvariant_cast<QPixmap>(cellDecoration);
120  if (pix.isNull()) {
121  pix = qvariant_cast<QIcon>(cellDecoration).pixmap(m_tableLayout.m_iconSize);
122  }
123  qreal height = pix.height();
124  QImage img;
125  if (pix.isNull()) {
126  img = qvariant_cast<QImage>(cellDecoration);
127  if (img.isNull())
128  return;
129  height = img.height();
130  }
131 
132  // Now either img or pix is set.
133 
134  // Apply scaling factor
135  if (m_tableLayout.scalingFactor() != 1.) {
136  if (!pix.isNull()) {
137  pix = pix.scaledToWidth(qRound(pix.width() * m_tableLayout.scalingFactor()));
138  height = pix.height();
139  } else {
140  img = img.scaledToWidth(qRound(img.width() * m_tableLayout.scalingFactor()));
141  height = img.height();
142  }
143  }
144 
145  // Vertical centering
146  const int y = qMax(0, int((cellContentsRect.height() - height) / 2.0));
147  const QPoint topLeft = cellContentsRect.topLeft().toPoint() + QPoint(0, y);
148  if (!img.isNull()) {
149  // Draw img
150  painter.drawImage(topLeft, img);
151  } else {
152  // Draw pix
153  painter.drawPixmap(topLeft, pix);
154  }
155 }
156 
157 // We could use QItemDelegate::paint instead, but it does so much more, it looks slow.
158 void KDReports::SpreadsheetReportLayout::paintTextAndIcon(QPainter &painter, const QRectF &cellContentsRect, const QString &cellText, const QVariant &cellDecoration,
159  const QVariant &decorationAlignment, Qt::Alignment alignment)
160 {
161  QRectF textRect = cellContentsRect;
162 
163  const bool hasIcon = !cellDecoration.isNull();
164  qreal iconWidth = 0;
165  const bool iconAfterText = decorationAlignment.isValid() && (decorationAlignment.toInt() & Qt::AlignRight);
166  if (hasIcon) {
167  iconWidth = m_tableLayout.decorationSize(cellDecoration).width() * m_tableLayout.scalingFactor();
168  // qDebug() << "row" << row << "hasIcon=" << hasIcon << "iconAfterText=" << iconAfterText << "iconWidth=" << iconWidth;
169  if (!iconAfterText) {
170  paintIcon(painter, cellContentsRect, cellDecoration);
171  textRect.setLeft(textRect.left() + iconWidth + 2);
172  } else {
173  textRect.setWidth(textRect.width() - iconWidth - 2);
174  }
175  }
176 
177  // qDebug() << "Drawing text in" << textRect;
178  painter.drawText(textRect, alignment, cellText);
179 
180  if (hasIcon && iconAfterText) {
181  QRectF iconRect = cellContentsRect;
182  iconRect.setLeft(iconRect.right() - iconWidth);
183  // qDebug() << "iconRect=" << iconRect;
184  paintIcon(painter, iconRect, cellDecoration);
185  }
186 }
187 
188 void KDReports::SpreadsheetReportLayout::drawBorder(const QRectF &cellRect, QPainter &painter) const
189 {
190  if (m_tableSettings.m_border > 0) {
191  const QPen oldPen = painter.pen();
192  // QTextDocumentLayoutPrivate::drawBorder draws 4 rects using a brush
193  // But that's more work, and it doesn't always look good anyway.
194  // So we just use it as a color for now.
195  painter.setPen(QPen(m_tableSettings.m_borderBrush.color(), m_tableSettings.m_border));
196  painter.drawRect(cellRect);
197  painter.setPen(oldPen);
198  }
199 }
200 
201 void KDReports::SpreadsheetReportLayout::paintPageContent(int pageNumber, QPainter &painter)
202 {
203  // qDebug() << "painting with" << m_tableLayout.scaledFont();
204  QAbstractItemModel *model = m_tableLayout.m_model;
205  const qreal padding = m_tableLayout.scaledCellPadding();
206  const QRect cellCoords = m_pageRects[pageNumber];
207  // qDebug() << "painting page" << pageNumber << "cellCoords=" << cellCoords;
208  qreal y = 0 /*m_topMargin*/; // in pixels
209  const qreal rowHeight = m_tableLayout.rowHeight();
210 
211  if (m_tableLayout.m_horizontalHeaderVisible) {
212  qreal x = 0 /*m_leftMargin*/;
213  if (m_tableLayout.m_verticalHeaderVisible) {
214  x += m_tableLayout.vHeaderWidth();
215  }
216  for (int col = cellCoords.left(); col <= cellCoords.right(); ++col) {
217  const QRectF cellRect(x, y, m_tableLayout.m_columnWidths[col], m_tableLayout.hHeaderHeight());
218  paintTableHorizontalHeader(cellRect, painter, col);
219  x += cellRect.width();
220  }
221  y += m_tableLayout.hHeaderHeight();
222  }
223 
224  const int firstRow = cellCoords.top();
225  const int firstColumn = cellCoords.left();
226  const int numRows = cellCoords.height();
227  const int numColumns = cellCoords.width();
228 
229  // This won't work across page breaks....
230  QVector<QBitArray> coveredCells;
231  coveredCells.resize(numRows);
232  for (int row = firstRow; row <= cellCoords.bottom(); ++row)
233  coveredCells[row - firstRow].resize(numColumns);
234 
235  for (int row = firstRow; row <= cellCoords.bottom(); ++row) {
236  qreal x = 0 /*m_leftMargin*/;
237  if (m_tableLayout.m_verticalHeaderVisible) {
238  x = paintTableVerticalHeader(x, y, painter, row);
239  }
240  painter.setFont(m_tableLayout.scaledFont());
241  for (int col = cellCoords.left(); col <= cellCoords.right(); ++col) {
242  if (coveredCells[row - firstRow].testBit(col - firstColumn)) {
243  x += m_tableLayout.m_columnWidths[col];
244  continue;
245  }
246 
247  const QModelIndex index = model->index(row, col);
248 
249  const QSize span = model->span(index);
250  if (span.isValid()) {
251  for (int r = row; r < row + span.height() && r < numRows; ++r) {
252  for (int c = col; c < col + span.width() && c < numColumns; ++c) {
253  coveredCells[r - firstRow].setBit(c - firstColumn);
254  }
255  }
256  }
257 
258  const QRectF cellRect(x, y, cellWidth(col, span.width()), qMax(1, span.height()) * rowHeight);
259  const QRectF cellContentsRect = cellRect.adjusted(padding, padding, -padding, -padding);
260  // qDebug() << "cell" << row << col << "rect=" << cellRect;
261 
262  const QString cellText = model->data(index, Qt::DisplayRole).toString();
263  const QColor foreground = qvariant_cast<QColor>(model->data(index, Qt::ForegroundRole));
264  const QVariant background = model->data(index, Qt::BackgroundRole);
265  const Qt::Alignment alignment(model->data(index, Qt::TextAlignmentRole).toInt());
266  const QVariant decorationAlignment(model->data(index, KDReports::AutoTableElement::DecorationAlignmentRole));
267  const QVariant cellDecoration(model->data(index, Qt::DecorationRole));
268 
269  if (background.canConvert<QBrush>()) {
270  painter.fillRect(cellRect, background.value<QBrush>());
271  } else if (span.isValid()) {
272  painter.fillRect(cellRect, Qt::white);
273  }
274  drawBorder(cellRect, painter);
275 
276  // Per-cell font is not supported, on purpose. All rows use the same font,
277  // otherwise the calculations for making things fit into a number of pages
278  // become quite complex and slow.
279  // const QVariant cellFont = model->data( index, Qt::FontRole );
280  // if ( cellFont.isValid() )
281  // painter.setFont( qvariant_cast<QFont>( cellFont ) );
282  // else
283  // painter.setFont( scaledFont );
284 
285  if (foreground.isValid())
286  painter.setPen(foreground);
287 
288  paintTextAndIcon(painter, cellContentsRect, cellText, cellDecoration, decorationAlignment, alignment);
289 
290  if (foreground.isValid())
291  painter.setPen(Qt::black);
292 
293  x += m_tableLayout.m_columnWidths[col];
294  }
295  y += rowHeight;
296  }
297 }
298 
299 //@cond PRIVATE
301 {
302  ensureLayouted();
303  return m_pageRects.count();
304 }
305 
307 {
308  m_tableLayout.setInitialFontScalingFactor(m_userRequestedFontScalingFactor);
309  QAbstractItemModel *model = m_tableLayout.m_model;
310  if (!model)
311  return -1;
312  m_tableLayout.updateColumnWidths();
313  const qreal total = totalWidth();
314 #ifdef DEBUG_LAYOUT
315  qDebug() << "idealWidth:" << total << "pixels";
316 #endif
317  return total;
318 }
319 //@endcond
320 
321 qreal KDReports::SpreadsheetReportLayout::totalWidth() const
322 {
323  qreal totalWidth = 0;
324  for (int col = 0; col < m_tableLayout.m_columnWidths.size(); ++col) {
325  totalWidth += m_tableLayout.m_columnWidths[col];
326  }
327  if (m_tableLayout.m_verticalHeaderVisible)
328  totalWidth += m_tableLayout.vHeaderWidth();
329  return totalWidth;
330 }
331 
332 qreal KDReports::SpreadsheetReportLayout::cellWidth(int col, int horizSpan) const
333 {
334  qreal cellWidth = m_tableLayout.m_columnWidths[col];
335  for (int extraCol = 1; extraCol < horizSpan; ++extraCol) {
336  cellWidth += m_tableLayout.m_columnWidths[col + extraCol];
337  }
338  return cellWidth;
339 }
340 
342 {
343  m_pageContentSize = size;
344 #ifdef DEBUG_LAYOUT
345  qDebug() << "page content size" << m_pageContentSize;
346 #endif
347  setLayoutDirty();
348 }
349 
351 {
352  if (!m_layoutDirty)
353  return;
354  if (m_pageContentSize.isEmpty()) {
355  qWarning("No paper size specified!");
356  return;
357  }
358 
359  m_tableLayout.setInitialFontScalingFactor(m_userRequestedFontScalingFactor);
360  m_pageRects.clear();
361 
362  QAbstractItemModel *model = m_tableLayout.m_model;
363  if (!model)
364  return;
365 
366  // Here's the whole layouting logic
367 
368  // Step 1: determine "ideal" column widths, based on contents
369 
370  m_tableLayout.updateColumnWidths();
371 
372  // Step 2: based on that and the number of horiz pages wanted,
373  // determine actual column widths (horizontal table breaking)
374 
376  optimizer.setColumnWidths(m_tableLayout.m_columnWidths);
377  optimizer.setPageCount(m_numHorizontalPages);
378  const QVector<int> columnsPerPage = optimizer.columnsPerPage();
379  QVector<qreal> widthPerPage = optimizer.widthPerPage(columnsPerPage);
380  const int horizPages = columnsPerPage.count();
381  bool scaled = false;
382 
383  // Step 3: check everything fits horizontally, otherwise calculate font scaling factor for this
384 
385  const qreal horizMargins = 0 /*m_leftMargin*/ + 0 /*m_rightMargin*/;
386  const qreal verticalMargins = 0 /*m_topMargin*/ + 0 /*m_bottomMargin*/;
387  const qreal usablePageWidth = m_pageContentSize.width() - horizMargins;
388  const qreal usablePageHeight = m_pageContentSize.height() - verticalMargins - m_tableLayout.hHeaderHeight();
389 
390 #ifdef DEBUG_LAYOUT
391  qDebug() << "usablePageHeight=" << m_pageContentSize.height() << "minus hHeaderHeight" << m_tableLayout.hHeaderHeight();
392 #endif
393 
394  // for each page, if (sum of column widths) > usablePageWidth,
395  // then we need to scale everything (font and padding)
396  // by the ratio of those two numbers.
397  qreal bestScalingFactor = 1000000;
398  for (int page = 0; page < horizPages; ++page) {
399  const qreal width = widthPerPage[page] + m_tableLayout.vHeaderWidth();
400  if (width > usablePageWidth) {
401  const qreal scalingFactor = usablePageWidth / width;
402 #ifdef DEBUG_LAYOUT
403  qDebug() << "page" << page << "sum of column widths:" << width << "usablePageWidth=" << usablePageWidth;
404  qDebug() << "scaling factor so that it fits horizontally:" << scalingFactor;
405 #endif
406  bestScalingFactor = qMin(bestScalingFactor, scalingFactor);
407  scaled = true;
408  }
409  }
410 
411  if (scaled) {
412  m_tableLayout.ensureScalingFactorForWidth(bestScalingFactor);
413  }
414 
415  // Step 4: check everything fits vertically, otherwise calculate font scaling factor for this
416 
417  const int rowCount = m_tableLayout.m_model->rowCount();
418  if (m_numVerticalPages > 0) {
419  const qreal rowHeight = m_tableLayout.rowHeight();
420 
421  // We can't do a global division of heights, it assumes rows can be over page borders, partially truncated
422  // const qreal maxTotalHeight = m_numVerticalPages * usablePageHeight;
423  // const qreal maxRowHeight = maxTotalHeight / rowCount;
424 
425  // Example: 5 rows over 2 pages, and the usablePageHeight is 100. What do you do?
426  // 2.5 rows per page means truncation. 2 rows per page (as in the division above) is not enough.
427  // The right solution is qCeil, i.e. max 3 rows per page, and maxRowHeight = 100 / 3 = 33.3.
428 
429  const int maxRowsPerPage = qCeil(static_cast<qreal>(rowCount) / m_numVerticalPages);
430  const qreal maxRowHeight = usablePageHeight / maxRowsPerPage;
431 #ifdef DEBUG_LAYOUT
432  qDebug() << "usablePageHeight=" << usablePageHeight << "rowHeight=" << rowHeight << "maxRowsPerPage=" << maxRowsPerPage << "maxRowHeight=" << usablePageHeight << "/" << maxRowsPerPage << "="
433  << maxRowHeight;
434 #endif
435  if (rowHeight > maxRowHeight) { // more than authorized maximum
436  m_tableLayout.ensureScalingFactorForHeight(maxRowHeight);
437  scaled = true;
438  }
439  }
440 
441  // Step 5: update font and calculations based on final font scaling
442  if (scaled) {
443 #ifdef DEBUG_LAYOUT
444  qDebug() << "final scaling factor" << m_tableLayout.scalingFactor();
445  qDebug() << "final fonts: cells:" << m_tableLayout.scaledFont().pointSizeF() << "hHeader:" << m_tableLayout.horizontalHeaderScaledFont().pointSizeF()
446  << "vHeader:" << m_tableLayout.verticalHeaderScaledFont().pointSizeF();
447 #endif
448  // With this new scaling factor [when step 4 changed the factor], what should be the column widths?
449  // If we just call
450  // m_tableLayout.updateColumnWidthsByFactor( m_tableLayout.scalingFactor() / m_userRequestedFontScalingFactor );
451  // then we risk truncating column text (because fonts are not proportional).
452  // Testcase: LongReport with font size 8, padding 3, 10 columns, 300 rows, and scaleTo(1,10) (or none);
453  m_tableLayout.updateColumnWidths();
454 
455 #ifdef DEBUG_LAYOUT
456  qDebug() << "New total width:" << totalWidth();
457 #endif
458 
459 #if 0 // not used right now, but could be useful, especially if we want to goto step 3 again, to resize down
460  // Update the widthPerPage array
461  int column = 0;
462  for ( int page = 0; page < horizPages; ++page ) {
463  const int numColumnsInPage = columnsPerPage[page];
464  widthPerPage[page] = 0;
465  for ( int col = column; col < column + numColumnsInPage; ++col) {
466  widthPerPage[page] += m_tableLayout.m_columnWidths[col];
467  }
468 
469  const qreal width = widthPerPage[page] + m_tableLayout.vHeaderWidth();
470  if ( width > usablePageWidth ) {
471  qWarning() << "Too much width on page" << page;
472  }
473 
474  column += numColumnsInPage;
475  }
476  qDebug() << "widthPerPage:" << widthPerPage;
477 #endif
478  }
479 
480  const qreal rowHeight = m_tableLayout.rowHeight(); // do it now so that the scaling is included
481 
482  // Step 6: determine number of pages for all rows to fit
483 
484  const int maxRowsPerPage = qFloor(usablePageHeight / rowHeight); // no qCeil here, the last row would be truncated...
485  int verticPages = qCeil(qreal(rowCount) / qreal(maxRowsPerPage));
486 
487 #ifdef DEBUG_LAYOUT
488  qDebug() << "maxRowsPerPage=" << usablePageHeight << "/" << rowHeight << "=" << maxRowsPerPage;
489  qDebug() << "pages:" << horizPages << "x" << verticPages;
490  qDebug() << "verticPages = qCeil(" << rowCount << "/" << maxRowsPerPage << ") =" << verticPages;
491 #endif
492 
493  // avoid rounding problems (or the font not zooming down enough vertically),
494  // obey m_numVerticalPages in all cases
495  if (m_numVerticalPages > 0) {
496  Q_ASSERT(verticPages <= m_numVerticalPages);
497  // verticPages = qMin( m_numVerticalPages, verticPages );
498  }
499 
500  // Step 7: now we can record all this in terms of cell areas
501 
502  if (m_tableBreakingPageOrder == Report::RightThenDown) {
503  // qDebug() << "Doing right then down layout";
504  int row = 0;
505  for (int y = 0; y < verticPages; ++y) {
506  int column = 0;
507  const int numRowsInPage = qMin(maxRowsPerPage, rowCount - row);
508  for (int x = 0; x < horizPages; ++x) {
509  const int numColumnsInPage = columnsPerPage[x];
510  m_pageRects.append(QRect(column, row, numColumnsInPage, numRowsInPage));
511  column += numColumnsInPage;
512  }
513  row += maxRowsPerPage;
514  }
515  } else {
516  // qDebug() << "Doing down then right layout";
517  int column = 0;
518  for (int x = 0; x < horizPages; ++x) {
519  int row = 0;
520  const int numColumnsInPage = columnsPerPage[x];
521  for (int y = 0; y < verticPages; ++y) {
522  const int numRowsInPage = qMin(maxRowsPerPage, rowCount - row);
523  m_pageRects.append(QRect(column, row, numColumnsInPage, numRowsInPage));
524  row += maxRowsPerPage;
525  }
526  column += numColumnsInPage;
527  }
528  }
529 
530  m_layoutDirty = false;
531 }
532 
533 void KDReports::SpreadsheetReportLayout::updateTextValue(const QString &id, const QString &newValue)
534 {
535  // Not implemented, there is no support for this in spreadsheet mode currently.
536  Q_UNUSED(id);
537  Q_UNUSED(newValue);
538 }
539 
541 {
542  m_tableLayout.setInitialFontScalingFactor(m_userRequestedFontScalingFactor);
543  const int rowCount = m_tableLayout.m_model->rowCount();
544  const qreal usableTotalHeight = m_tableLayout.rowHeight() * rowCount;
545  const qreal pageContentHeight = usableTotalHeight + 0 /*verticalMargins*/ + m_tableLayout.hHeaderHeight();
546 
547  m_pageContentSize = QSizeF(width, pageContentHeight);
548 #ifdef DEBUG_LAYOUT
549  qDebug() << "layoutAsOnePage: page content size" << m_pageContentSize << rowCount << "*" << m_tableLayout.rowHeight() << "+" << m_tableLayout.hHeaderHeight();
550 #endif
551  setLayoutDirty();
552  return pageContentHeight;
553 }
554 
556 {
557  return QStringLiteral("Not implemented");
558 }
559 
561 
562 //@cond PRIVATE
563 bool KDReports::SpreadsheetReportLayout::scaleTo(int numPagesHorizontally, int numPagesVertically)
564 {
565  m_numHorizontalPages = numPagesHorizontally;
566  m_numVerticalPages = numPagesVertically;
567  setLayoutDirty();
568  return true;
569 }
570 
572 {
573  m_tableLayout.m_fixedRowHeight = height;
574 }
575 
577 {
578  return m_numHorizontalPages;
579 }
580 
582 {
583  return m_numVerticalPages;
584 }
585 //@endcond
586 
588 {
589  m_userRequestedFontScalingFactor = factor;
590  m_numHorizontalPages = 1;
591  m_numVerticalPages = 0;
592  setLayoutDirty();
593 }
594 
596 {
597  return m_userRequestedFontScalingFactor;
598 }
599 
600 QString KDReports::SpreadsheetReportLayout::anchorAt(int pageNumber, QPoint pos)
601 {
602  // Not implemented
603  Q_UNUSED(pageNumber)
604  Q_UNUSED(pos)
605  return {};
606 }
607 
609 {
610  m_tableBreakingPageOrder = order;
611  setLayoutDirty();
612 }
613 
614 //@cond PRIVATE
616 {
617  m_tableLayout.m_horizontalHeaderFont = font;
618  setLayoutDirty();
619 }
620 
622 {
623  m_tableLayout.m_verticalHeaderFont = font;
624  setLayoutDirty();
625 }
626 //@endcond
627 
628 void KDReports::SpreadsheetReportLayout::setModel(QAbstractItemModel *model)
629 {
630  m_tableLayout.m_model = model;
631 }
632 
633 //@cond PRIVATE
635 {
636  m_tableLayout.m_verticalHeaderVisible = visible;
637  setLayoutDirty();
638 }
639 
641 {
642  m_tableLayout.m_horizontalHeaderVisible = visible;
643  setLayoutDirty();
644 }
645 
647 {
648  m_tableLayout.m_cellPadding = KDReports::mmToPixels(padding);
649  // qDebug() << "setting cellpadding: mm=" << padding << "pixels=" << m_tableLayout.m_cellPadding;
650  setLayoutDirty();
651 }
652 //@endcond
653 
655 {
656  m_tableLayout.m_iconSize = iconSize;
657 }
658 
659 void KDReports::SpreadsheetReportLayout::setCellBorder(qreal border, const QBrush &borderBrush)
660 {
661  m_tableSettings.m_border = border;
662  m_tableSettings.m_borderBrush = borderBrush;
663 }
664 
665 //@cond PRIVATE
666 void KDReports::SpreadsheetReportLayout::setHeaderBackground(const QBrush &headerBackground)
667 {
668  m_tableSettings.m_headerBackground = headerBackground;
669 }
670 //@endcond
KDReports::SpreadsheetReportLayout::layoutAsOnePage
qreal layoutAsOnePage(qreal width) override
Reimplemented for internal purposes. .
Definition: KDReportsSpreadsheetReportLayout.cpp:540
KDReportsTableBreakingLogic_p.h
KDReports::SpreadsheetReportLayout::paintPageContent
void paintPageContent(int pageNumber, QPainter &painter) override
Reimplemented for internal purposes. .
Definition: KDReportsSpreadsheetReportLayout.cpp:201
KDReportsSpreadsheetReportLayout_p.h
KDReports::SpreadsheetReportLayout::setModel
void setModel(QAbstractItemModel *model)
Definition: KDReportsSpreadsheetReportLayout.cpp:628
KDReports::AutoTableElement::DecorationAlignmentRole
@ DecorationAlignmentRole
This model role allows to specify whether the icon should go before the text (Qt::AlignLeft) or after...
Definition: KDReportsAutoTableElement.h:155
KDReports::SpreadsheetReportLayout::userRequestedFontScalingFactor
qreal userRequestedFontScalingFactor() const override
Reimplemented for internal purposes. .
Definition: KDReportsSpreadsheetReportLayout.cpp:595
KDReports::SpreadsheetReportLayout::ensureLayouted
void ensureLayouted() override
Reimplemented for internal purposes. .
Definition: KDReportsSpreadsheetReportLayout.cpp:350
KDReports::SpreadsheetReportLayout::finishHtmlExport
void finishHtmlExport() override
Reimplemented for internal purposes. .
Definition: KDReportsSpreadsheetReportLayout.cpp:560
KDReports::SpreadsheetReportLayout::setPageContentSize
void setPageContentSize(QSizeF size) override
Reimplemented for internal purposes. .
Definition: KDReportsSpreadsheetReportLayout.cpp:341
KDReports::SpreadsheetReportLayout::SpreadsheetReportLayout
SpreadsheetReportLayout(KDReports::Report *report)
Definition: KDReportsSpreadsheetReportLayout.cpp:29
KDReports::SpreadsheetReportLayout::toHtml
QString toHtml() const override
Reimplemented for internal purposes. .
Definition: KDReportsSpreadsheetReportLayout.cpp:555
KDReports::SpreadsheetReportLayout::setHorizontalHeaderFont
void setHorizontalHeaderFont(const QFont &font)
KDReports::SpreadsheetReportLayout::maximumNumberOfPagesForVerticalScaling
int maximumNumberOfPagesForVerticalScaling() const override
Reimplemented for internal purposes. .
KDReports::SpreadsheetReportLayout::updateTextValue
void updateTextValue(const QString &id, const QString &newValue) override
Reimplemented for internal purposes. .
Definition: KDReportsSpreadsheetReportLayout.cpp:533
KDReports::Report
Definition: KDReportsReport.h:80
KDReports::Report::RightThenDown
@ RightThenDown
Definition: KDReportsReport.h:612
KDReports::SpreadsheetReportLayout::setLayoutDirty
void setLayoutDirty() override
Reimplemented for internal purposes. .
Definition: KDReportsSpreadsheetReportLayout.cpp:41
KDReports::SpreadsheetReportLayout::setUserRequestedFontScalingFactor
void setUserRequestedFontScalingFactor(qreal factor) override
Reimplemented for internal purposes. .
Definition: KDReportsSpreadsheetReportLayout.cpp:587
KDReports::TableBreakingLogic::widthPerPage
WidthVector widthPerPage(const QVector< int > &colPerPage) const
Definition: KDReportsTableBreakingLogic.cpp:89
KDReports::SpreadsheetReportLayout::setVerticalHeaderFont
void setVerticalHeaderFont(const QFont &font)
KDReports::SpreadsheetReportLayout::anchorAt
QString anchorAt(int pageNumber, QPoint pos) override
Reimplemented for internal purposes. .
Definition: KDReportsSpreadsheetReportLayout.cpp:600
KDReports::TableBreakingLogic::setColumnWidths
void setColumnWidths(const WidthVector &widths)
KDReports::SpreadsheetReportLayout::setHorizontalHeaderVisible
void setHorizontalHeaderVisible(bool visible)
KDReports::SpreadsheetReportLayout::setVerticalHeaderVisible
void setVerticalHeaderVisible(bool visible)
KDReports::SpreadsheetReportLayout::numberOfPages
int numberOfPages() override
Reimplemented for internal purposes. .
KDReports::TableBreakingLogic::setPageCount
void setPageCount(int pages)
Definition: KDReportsTableBreakingLogic.cpp:33
KDReports::SpreadsheetReportLayout::setTableBreakingPageOrder
void setTableBreakingPageOrder(KDReports::Report::TableBreakingPageOrder order)
Definition: KDReportsSpreadsheetReportLayout.cpp:608
KDReports::SpreadsheetReportLayout::scaleTo
bool scaleTo(int numPagesHorizontally, int numPagesVertically) override
Reimplemented for internal purposes. .
KDReports::SpreadsheetReportLayout::maximumNumberOfPagesForHorizontalScaling
int maximumNumberOfPagesForHorizontalScaling() const override
Reimplemented for internal purposes. .
KDReportsAutoTableElement.h
KDReports::SpreadsheetReportLayout::idealWidth
qreal idealWidth() override
Reimplemented for internal purposes. .
KDReports::SpreadsheetReportLayout::setCellPadding
void setCellPadding(qreal padding)
KDReports::mmToPixels
KDREPORTS_EXPORT qreal mmToPixels(qreal mm)
Definition: KDReportsLayoutHelper.cpp:23
KDReports::SpreadsheetReportLayout::setCellBorder
void setCellBorder(qreal border, const QBrush &borderBrush)
Definition: KDReportsSpreadsheetReportLayout.cpp:659
KDReports::SpreadsheetReportLayout::setDefaultFont
void setDefaultFont(const QFont &font) override
Reimplemented for internal purposes. .
Definition: KDReportsSpreadsheetReportLayout.cpp:46
KDReportsLayoutHelper_p.h
KDReports::TableBreakingLogic
Definition: KDReportsTableBreakingLogic_p.h:40
KDReports::SpreadsheetReportLayout::setHeaderBackground
void setHeaderBackground(const QBrush &headerBackground)
KDReports::SpreadsheetReportLayout::setFixedRowHeight
void setFixedRowHeight(qreal height) override
Reimplemented for internal purposes. .
KDReports::SpreadsheetReportLayout::setIconSize
void setIconSize(QSize iconSize)
Definition: KDReportsSpreadsheetReportLayout.cpp:654
KDReports::Report::TableBreakingPageOrder
TableBreakingPageOrder
Definition: KDReportsReport.h:611
KDReports::SpreadsheetReportLayout::defaultFont
QFont defaultFont() const override
Reimplemented for internal purposes. .
Definition: KDReportsSpreadsheetReportLayout.cpp:54
KDReports::TableBreakingLogic::columnsPerPage
QVector< int > columnsPerPage() const
Definition: KDReportsTableBreakingLogic.cpp:38

© 2007-2021 Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/
https://www.kdab.com/development-resources/qt-tools/kd-reports/
Generated on Sat Jan 8 2022 02:38:32 for KD Reports API Documentation by doxygen 1.8.17