15#include <QAbstractItemModel>
24 : m_tableBreakingPageOrder(
Report::DownThenRight)
25 , m_numHorizontalPages(1)
26 , m_numVerticalPages(0)
28 , m_userRequestedFontScalingFactor(1.0)
42 m_tableLayout.m_cellFont = font;
43 m_tableLayout.m_horizontalHeaderFont = font;
44 m_tableLayout.m_verticalHeaderFont = font;
50 return m_tableLayout.m_cellFont;
53qreal KDReports::SpreadsheetReportLayout::paintTableVerticalHeader(qreal x, qreal y,
QPainter &painter,
int row)
57 const QRectF cellRect(x, y, m_tableLayout.vHeaderWidth(), m_tableLayout.rowHeight());
59 painter.
setFont(m_tableLayout.verticalHeaderScaledFont());
60 painter.
fillRect(cellRect, m_tableSettings.m_headerBackground);
61 drawBorder(cellRect, painter);
65 painter.
setPen(foreground);
68 const qreal padding = m_tableLayout.scaledCellPadding();
73 const QRectF cellContentsRect = cellRect.
adjusted(padding, padding, -padding, -padding);
75 paintTextAndIcon(painter, cellContentsRect, cellText, cellDecoration, decorationAlignment, alignment);
80 x += cellRect.width();
84void KDReports::SpreadsheetReportLayout::paintTableHorizontalHeader(
const QRectF &cellRect,
QPainter &painter,
int col)
88 painter.
setFont(m_tableLayout.horizontalHeaderScaledFont());
90 painter.
fillRect(cellRect.
adjusted(-0.5, -0.5, -0.5, -0.5), m_tableSettings.m_headerBackground);
91 drawBorder(cellRect, painter);
95 painter.
setPen(foreground);
98 const qreal padding = m_tableLayout.scaledCellPadding();
103 const QRectF cellContentsRect = cellRect.
adjusted(padding, padding, -padding, -padding);
105 paintTextAndIcon(painter, cellContentsRect, cellText, cellDecoration, decorationAlignment, alignment);
111void KDReports::SpreadsheetReportLayout::paintIcon(
QPainter &painter,
const QRectF &cellContentsRect,
const QVariant &cellDecoration)
const
113 QPixmap pix = qvariant_cast<QPixmap>(cellDecoration);
115 pix = qvariant_cast<QIcon>(cellDecoration).pixmap(m_tableLayout.m_iconSize);
117 qreal height = pix.
height();
120 img = qvariant_cast<QImage>(cellDecoration);
129 if (m_tableLayout.scalingFactor() != 1.) {
140 const int y = qMax(0,
int((cellContentsRect.
height() - height) / 2.0));
152void KDReports::SpreadsheetReportLayout::paintTextAndIcon(
QPainter &painter,
const QRectF &cellContentsRect,
const QString &cellText,
const QVariant &cellDecoration,
155 QRectF textRect = cellContentsRect;
157 const bool hasIcon = !cellDecoration.
isNull();
161 iconWidth = m_tableLayout.decorationSize(cellDecoration).width() * m_tableLayout.scalingFactor();
163 if (!iconAfterText) {
164 paintIcon(painter, cellContentsRect, cellDecoration);
172 painter.
drawText(textRect, alignment, cellText);
174 if (hasIcon && iconAfterText) {
175 QRectF iconRect = cellContentsRect;
178 paintIcon(painter, iconRect, cellDecoration);
182void KDReports::SpreadsheetReportLayout::drawBorder(
const QRectF &cellRect,
QPainter &painter)
const
184 if (m_tableSettings.m_border > 0) {
185 const QPen oldPen = painter.
pen();
189 painter.
setPen(
QPen(m_tableSettings.m_borderBrush.color(), m_tableSettings.m_border));
199 const qreal padding = m_tableLayout.scaledCellPadding();
200 const QRect cellCoords = m_pageRects[pageNumber];
203 const qreal rowHeight = m_tableLayout.rowHeight();
205 if (m_tableLayout.m_horizontalHeaderVisible) {
207 if (m_tableLayout.m_verticalHeaderVisible) {
208 x += m_tableLayout.vHeaderWidth();
210 for (
int col = cellCoords.
left(); col <= cellCoords.
right(); ++col) {
211 const QRectF cellRect(x, y, m_tableLayout.m_columnWidths[col], m_tableLayout.hHeaderHeight());
212 paintTableHorizontalHeader(cellRect, painter, col);
213 x += cellRect.
width();
215 y += m_tableLayout.hHeaderHeight();
218 const int firstRow = cellCoords.
top();
219 const int firstColumn = cellCoords.
left();
220 const int numRows = cellCoords.
height();
221 const int numColumns = cellCoords.
width();
225 coveredCells.
resize(numRows);
226 for (
int row = firstRow; row <= cellCoords.
bottom(); ++row)
227 coveredCells[row - firstRow].resize(numColumns);
229 for (
int row = firstRow; row <= cellCoords.
bottom(); ++row) {
231 if (m_tableLayout.m_verticalHeaderVisible) {
232 x = paintTableVerticalHeader(x, y, painter, row);
234 painter.
setFont(m_tableLayout.scaledFont());
235 for (
int col = cellCoords.
left(); col <= cellCoords.
right(); ++col) {
236 if (coveredCells[row - firstRow].testBit(col - firstColumn)) {
237 x += m_tableLayout.m_columnWidths[col];
245 for (
int r = row; r < row + span.
height() && r < numRows; ++r) {
246 for (
int c = col; c < col + span.
width() && c < numColumns; ++c) {
247 coveredCells[r - firstRow].setBit(c - firstColumn);
252 const QRectF cellRect(x, y, cellWidth(col, span.
width()), qMax(1, span.
height()) * rowHeight);
253 const QRectF cellContentsRect = cellRect.
adjusted(padding, padding, -padding, -padding);
268 drawBorder(cellRect, painter);
280 painter.
setPen(foreground);
282 paintTextAndIcon(painter, cellContentsRect, cellText, cellDecoration, decorationAlignment, alignment);
287 x += m_tableLayout.m_columnWidths[col];
297 return m_pageRects.count();
302 m_tableLayout.setInitialFontScalingFactor(m_userRequestedFontScalingFactor);
306 m_tableLayout.updateColumnWidths();
307 const qreal total = totalWidth();
309 qDebug() <<
"idealWidth:" << total <<
"pixels";
315qreal KDReports::SpreadsheetReportLayout::totalWidth()
const
317 qreal totalWidth = 0;
318 for (
int col = 0; col < m_tableLayout.m_columnWidths.size(); ++col) {
319 totalWidth += m_tableLayout.m_columnWidths[col];
321 if (m_tableLayout.m_verticalHeaderVisible)
322 totalWidth += m_tableLayout.vHeaderWidth();
326qreal KDReports::SpreadsheetReportLayout::cellWidth(
int col,
int horizSpan)
const
328 qreal cellWidth = m_tableLayout.m_columnWidths[col];
329 for (
int extraCol = 1; extraCol < horizSpan; ++extraCol) {
330 cellWidth += m_tableLayout.m_columnWidths[col + extraCol];
337 m_pageContentSize = size;
339 qDebug() <<
"page content size" << m_pageContentSize;
348 if (m_pageContentSize.isEmpty()) {
349 qWarning(
"No paper size specified!");
353 m_tableLayout.setInitialFontScalingFactor(m_userRequestedFontScalingFactor);
364 m_tableLayout.updateColumnWidths();
374 const int horizPages = columnsPerPage.
count();
379 const qreal horizMargins = 0 + 0 ;
380 const qreal verticalMargins = 0 + 0 ;
381 const qreal usablePageWidth = m_pageContentSize.width() - horizMargins;
382 const qreal usablePageHeight = m_pageContentSize.height() - verticalMargins - m_tableLayout.hHeaderHeight();
385 qDebug() <<
"usablePageHeight=" << m_pageContentSize.height() <<
"minus hHeaderHeight" << m_tableLayout.hHeaderHeight();
391 qreal bestScalingFactor = 1000000;
392 for (
int page = 0; page < horizPages; ++page) {
393 const qreal width = widthPerPage[page] + m_tableLayout.vHeaderWidth();
394 if (width > usablePageWidth) {
395 const qreal scalingFactor = usablePageWidth / width;
397 qDebug() <<
"page" << page <<
"sum of column widths:" << width <<
"usablePageWidth=" << usablePageWidth;
398 qDebug() <<
"scaling factor so that it fits horizontally:" << scalingFactor;
400 bestScalingFactor = qMin(bestScalingFactor, scalingFactor);
406 m_tableLayout.ensureScalingFactorForWidth(bestScalingFactor);
411 const int rowCount = m_tableLayout.m_model->rowCount();
412 if (m_numVerticalPages > 0) {
413 const qreal rowHeight = m_tableLayout.rowHeight();
423 const int maxRowsPerPage = qCeil(
static_cast<qreal
>(rowCount) / m_numVerticalPages);
424 const qreal maxRowHeight = usablePageHeight / maxRowsPerPage;
426 qDebug() <<
"usablePageHeight=" << usablePageHeight <<
"rowHeight=" << rowHeight <<
"maxRowsPerPage=" << maxRowsPerPage <<
"maxRowHeight=" << usablePageHeight <<
"/" << maxRowsPerPage <<
"="
429 if (rowHeight > maxRowHeight) {
430 m_tableLayout.ensureScalingFactorForHeight(maxRowHeight);
438 qDebug() <<
"final scaling factor" << m_tableLayout.scalingFactor();
439 qDebug() <<
"final fonts: cells:" << m_tableLayout.scaledFont().pointSizeF() <<
"hHeader:" << m_tableLayout.horizontalHeaderScaledFont().pointSizeF()
440 <<
"vHeader:" << m_tableLayout.verticalHeaderScaledFont().pointSizeF();
447 m_tableLayout.updateColumnWidths();
450 qDebug() <<
"New total width:" << totalWidth();
456 for (
int page = 0; page < horizPages; ++page ) {
457 const int numColumnsInPage = columnsPerPage[page];
458 widthPerPage[page] = 0;
459 for (
int col = column; col < column + numColumnsInPage; ++col) {
460 widthPerPage[page] += m_tableLayout.m_columnWidths[col];
463 const qreal width = widthPerPage[page] + m_tableLayout.vHeaderWidth();
464 if ( width > usablePageWidth ) {
465 qWarning() <<
"Too much width on page" << page;
468 column += numColumnsInPage;
470 qDebug() <<
"widthPerPage:" << widthPerPage;
474 const qreal rowHeight = m_tableLayout.rowHeight();
478 const int maxRowsPerPage = qFloor(usablePageHeight / rowHeight);
479 int verticPages = qCeil(qreal(rowCount) / qreal(maxRowsPerPage));
482 qDebug() <<
"maxRowsPerPage=" << usablePageHeight <<
"/" << rowHeight <<
"=" << maxRowsPerPage;
483 qDebug() <<
"pages:" << horizPages <<
"x" << verticPages;
484 qDebug() <<
"verticPages = qCeil(" << rowCount <<
"/" << maxRowsPerPage <<
") =" << verticPages;
489 if (m_numVerticalPages > 0) {
490 Q_ASSERT(verticPages <= m_numVerticalPages);
499 for (
int y = 0; y < verticPages; ++y) {
501 const int numRowsInPage = qMin(maxRowsPerPage, rowCount - row);
502 for (
int x = 0; x < horizPages; ++x) {
503 const int numColumnsInPage = columnsPerPage[x];
504 m_pageRects.
append(
QRect(column, row, numColumnsInPage, numRowsInPage));
505 column += numColumnsInPage;
507 row += maxRowsPerPage;
512 for (
int x = 0; x < horizPages; ++x) {
514 const int numColumnsInPage = columnsPerPage[x];
515 for (
int y = 0; y < verticPages; ++y) {
516 const int numRowsInPage = qMin(maxRowsPerPage, rowCount - row);
517 m_pageRects.append(
QRect(column, row, numColumnsInPage, numRowsInPage));
518 row += maxRowsPerPage;
520 column += numColumnsInPage;
524 m_layoutDirty =
false;
536 m_tableLayout.setInitialFontScalingFactor(m_userRequestedFontScalingFactor);
537 const int rowCount = m_tableLayout.m_model->rowCount();
538 const qreal usableTotalHeight = m_tableLayout.rowHeight() * rowCount;
539 const qreal pageContentHeight = usableTotalHeight + 0 + m_tableLayout.hHeaderHeight();
541 m_pageContentSize =
QSizeF(width, pageContentHeight);
543 qDebug() <<
"layoutAsOnePage: page content size" << m_pageContentSize << rowCount <<
"*" << m_tableLayout.rowHeight() <<
"+" << m_tableLayout.hHeaderHeight();
546 return pageContentHeight;
551 return QStringLiteral(
"Not implemented");
561 m_numHorizontalPages = numPagesHorizontally;
562 m_numVerticalPages = numPagesVertically;
569 m_tableLayout.m_fixedRowHeight = height;
574 return m_numHorizontalPages;
579 return m_numVerticalPages;
585 m_userRequestedFontScalingFactor = factor;
586 m_numHorizontalPages = 1;
587 m_numVerticalPages = 0;
593 return m_userRequestedFontScalingFactor;
606 m_tableBreakingPageOrder = order;
613 m_tableLayout.m_horizontalHeaderFont = font;
619 m_tableLayout.m_verticalHeaderFont = font;
626 m_tableLayout.m_model = model;
632 m_tableLayout.m_verticalHeaderVisible = visible;
638 m_tableLayout.m_horizontalHeaderVisible = visible;
652 m_tableLayout.m_iconSize = iconSize;
657 m_tableSettings.m_border = border;
658 m_tableSettings.m_borderBrush = borderBrush;
664 m_tableSettings.m_headerBackground = headerBackground;
@ DecorationAlignmentRole
This model role allows to specify whether the icon should go before the text (Qt::AlignLeft) or after...
int maximumNumberOfPagesForVerticalScaling() const override
Reimplemented for internal purposes. .
void setTableBreakingPageOrder(KDReports::Report::TableBreakingPageOrder order)
int maximumNumberOfPagesForHorizontalScaling() const override
Reimplemented for internal purposes. .
QString toHtml() const override
Reimplemented for internal purposes. .
SpreadsheetReportLayout(KDReports::Report *report)
int numberOfPages() override
Reimplemented for internal purposes. .
void setVerticalHeaderVisible(bool visible)
void setIconSize(QSize iconSize)
void setCellBorder(qreal border, const QBrush &borderBrush)
void setUserRequestedFontScalingFactor(qreal factor) override
Reimplemented for internal purposes. .
void ensureLayouted() override
Reimplemented for internal purposes. .
bool scaleTo(int numPagesHorizontally, int numPagesVertically) override
Reimplemented for internal purposes. .
void setPageContentSize(QSizeF size) override
Reimplemented for internal purposes. .
void updateTextValue(const QString &id, const QString &newValue) override
Reimplemented for internal purposes. .
void setHorizontalHeaderFont(const QFont &font)
QFont defaultFont() const override
Reimplemented for internal purposes. .
void setHeaderBackground(const QBrush &headerBackground)
qreal idealWidth() override
Reimplemented for internal purposes. .
void paintPageContent(int pageNumber, QPainter &painter) override
Reimplemented for internal purposes. .
QString anchorAt(int pageNumber, QPoint pos) override
Reimplemented for internal purposes. .
void setCellPadding(qreal padding)
void finishHtmlExport() override
Reimplemented for internal purposes. .
void setDefaultFont(const QFont &font) override
Reimplemented for internal purposes. .
qreal userRequestedFontScalingFactor() const override
Reimplemented for internal purposes. .
qreal layoutAsOnePage(qreal width) override
Reimplemented for internal purposes. .
void setVerticalHeaderFont(const QFont &font)
void setFixedRowHeight(qreal height) override
Reimplemented for internal purposes. .
void setHorizontalHeaderVisible(bool visible)
void setModel(QAbstractItemModel *model)
void setLayoutDirty() override
Reimplemented for internal purposes. .
QVector< int > columnsPerPage() const
void setColumnWidths(const WidthVector &widths)
WidthVector widthPerPage(const QVector< int > &colPerPage) const
void setPageCount(int pages)
KDREPORTS_EXPORT qreal mmToPixels(qreal mm)
virtual QVariant data(const QModelIndex &index, int role) const const=0
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const=0
virtual QSize span(const QModelIndex &index) const const
bool isValid() const const
bool isNull() const const
QImage scaledToWidth(int width, Qt::TransformationMode mode) const const
void drawImage(const QRectF &target, const QImage &image, const QRectF &source, Qt::ImageConversionFlags flags)
void drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)
void drawRect(const QRectF &rectangle)
void drawText(const QPointF &position, const QString &text)
void fillRect(const QRectF &rectangle, const QBrush &brush)
const QPen & pen() const const
void setFont(const QFont &font)
void setPen(const QColor &color)
bool isNull() const const
QPixmap scaledToWidth(int width, Qt::TransformationMode mode) const const
QPoint toPoint() const const
QRectF adjusted(qreal dx1, qreal dy1, qreal dx2, qreal dy2) const const
qreal height() const const
qreal right() const const
void setWidth(qreal width)
QPointF topLeft() const const
qreal width() const const
bool isValid() const const
bool canConvert(int targetTypeId) const const
bool isNull() const const
bool isValid() const const
int toInt(bool *ok) const const
QString toString() const const
void append(const T &value)
int count(const T &value) const const