KD Reports API Documentation  2.2
KDReportsImageElement.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 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
6 **
7 ** SPDX-License-Identifier: MIT
8 **
9 ****************************************************************************/
10 
11 #include "KDReportsImageElement.h"
13 #include "KDReportsReport.h"
14 #include "KDReportsReport_p.h"
15 #include <QDebug>
16 #include <QPainter>
17 #include <QPixmap>
18 #include <QTextDocument>
19 #include <QUrl>
20 
21 class KDReports::ImageElementPrivate
22 {
23 public:
24  QVariant m_pixmap; // pixmap or image, can't use QPixmap directly in threads
25  QSize m_pixmapSize; // = m_pixmap.size()
26 
27  // size in final document, chosen by the user:
28  qreal m_width = 0;
29  qreal m_height = 0;
30  bool m_fitToPage = false;
32  QString m_id;
33 };
34 
36  : d(new ImageElementPrivate)
37 {
39 }
40 
42  : d(new ImageElementPrivate)
43 {
44  setImage(image);
45 }
46 
48  : Element(other)
49  , d(new ImageElementPrivate(*other.d))
50 {
51 }
52 
54 {
55  if (&other == this)
56  return *this;
57  Element::operator=(other);
58  *d = *other.d;
59  return *this;
60 }
61 
63 {
64 }
65 
66 void KDReports::ImageElement::setPixmap(const QPixmap &pixmap)
67 {
68  // the call to toImage() is a workaround for a bug in QTextOdfWriter
69  // https://codereview.qt-project.org/c/qt/qtbase/+/369642
70  d->m_pixmap = QVariant::fromValue(pixmap.toImage());
71  d->m_pixmapSize = pixmap.size();
72 }
73 
75 {
76  return d->m_pixmap.value<QPixmap>();
77 }
78 
79 void KDReports::ImageElement::setImage(const QImage &image)
80 {
81  d->m_pixmap = QVariant::fromValue(image);
82  d->m_pixmapSize = image.size();
83 }
84 
86 {
87  return d->m_pixmap.value<QImage>();
88 }
89 
90 void KDReports::ImageElement::setWidth(qreal width, Unit unit)
91 {
92  d->m_width = width;
93  d->m_unit = unit;
94  d->m_height = 0; // mutually exclusive!
95  d->m_fitToPage = false; // "
96 }
97 
99 {
100  return d->m_width;
101 }
102 
103 void KDReports::ImageElement::setHeight(qreal height, Unit unit)
104 {
105  d->m_height = height;
106  d->m_unit = unit;
107  d->m_width = 0; // mutually exclusive!
108  d->m_fitToPage = false; // "
109 }
110 
112 {
113  return d->m_height;
114 }
115 
117 {
118  d->m_width = 0; // mutually exclusive!
119  d->m_height = 0; // mutually exclusive!
120  d->m_fitToPage = true;
121 }
122 
124 {
125  return d->m_fitToPage;
126 }
127 
129 {
130 #if 0
131  if ( d->m_width && d->m_unit == Millimeters ) {
132  const QSize sz( qRound( mmToPixels( d->m_width.width() ) ),
133  qRound( mmToPixels( d->m_width.height() ) ) );
134  d->m_pixmap = d->m_pixmap.scaled( sz, Qt::KeepAspectRatio, Qt::SmoothTransformation );
135  qDebug() << "ImageElement: m_width (mm) =" << d->m_width << " sz (pixels) =" << sz;
136  }
137 #endif
138 
139  if (d->m_pixmapSize.isNull())
140  return;
141 
142  static int imageNumber = 0;
143  const QString name = QStringLiteral("image%1.png").arg(++imageNumber);
144  builder.currentDocument().addResource(QTextDocument::ImageResource, QUrl(name), d->m_pixmap);
145  builder.currentDocumentData().addResourceName(name);
146 
147  QTextImageFormat imageFormat;
148  imageFormat.setName(name);
149  imageFormat.setWidth(d->m_pixmapSize.width());
150  imageFormat.setHeight(d->m_pixmapSize.height());
151 #if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
152  // Another workaround for https://codereview.qt-project.org/c/qt/qtbase/+/369642
153  imageFormat.setQuality(100);
154 #endif
155 
156  if (d->m_width) {
157  if (d->m_unit == Millimeters) {
158  const qreal pixelWidth = mmToPixels(d->m_width);
159  const qreal pixelHeight = pixelWidth * imageFormat.height() / imageFormat.width();
160  imageFormat.setWidth(pixelWidth);
161  imageFormat.setHeight(pixelHeight);
162  } else {
163  imageFormat.setProperty(ResizableImageProperty, QString(QLatin1Char('W') + QString::number(d->m_width)));
164  KDReports::TextDocumentData::updatePercentSize(imageFormat, QSizeF(builder.report()->d->textDocumentWidth(), -1 /*unknown*/));
166  }
167  } else if (d->m_height) {
168  if (d->m_unit == Millimeters) {
169  const qreal pixelHeight = qRound(mmToPixels(d->m_height));
170  const qreal pixelWidth = pixelHeight * imageFormat.width() / imageFormat.height();
171  imageFormat.setHeight(pixelHeight);
172  imageFormat.setWidth(pixelWidth);
173  } else {
174  imageFormat.setProperty(ResizableImageProperty, QString(QLatin1Char('H') + QString::number(d->m_height)));
176  // can't calc size yet, will be done at layouting time... hopefully.
177  }
178  } else if (d->m_fitToPage) {
179  imageFormat.setProperty(ResizableImageProperty, QString(QLatin1Char('T')));
181  }
182 
183  QTextCursor &cursor = builder.cursor();
184  cursor.insertImage(imageFormat);
185 }
186 
187 void KDReports::ImageElement::setId(const QString &id)
188 {
189  d->m_id = id;
190 }
191 
193 {
194  return d->m_id;
195 }
196 
198 {
199  return new ImageElement(*this);
200 }
201 
203 {
204  return d->m_unit;
205 }
206 
208 {
209  d->m_unit = unit;
210 }
Element & operator=(const Element &other)
void setHeight(qreal height, Unit unit=Millimeters)
void setImage(const QImage &image)
ImageElement & operator=(const ImageElement &other)
void build(ReportBuilder &) const override
ImageElement(const QPixmap &pixmap)
void setWidth(qreal width, Unit unit=Millimeters)
void setId(const QString &id)
Element * clone() const override
void setPixmap(const QPixmap &pixmap)
TextDocumentData & currentDocumentData()
void addResourceName(const QString &resourceName)
static void updatePercentSize(QTextImageFormat &format, QSizeF size)
@ Millimeters
Millimeters (the default)
Definition: KDReportsUnit.h:21
KDREPORTS_EXPORT qreal mmToPixels(qreal mm)
static const int ResizableImageProperty

© 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 by doxygen 1.9.1