KReport

KReportItemText.cpp
1/* This file is part of the KDE project
2 * Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk)
3 * Copyright (C) 2019 Jarosław Staniek <staniek@kde.org>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include "KReportItemText.h"
20#include "KReportRenderObjects.h"
21#include "KReportUtils.h"
22#include "KReportUtils_p.h"
23#include "kreportplugin_debug.h"
24
25#include <KPropertyListData>
26#include <KPropertySet>
27
28#include <QPrinter>
29#include <QApplication>
30#include <QPalette>
31#include <QFontMetrics>
32#include <QDomNodeList>
33#include <QRegularExpression>
34
35KReportItemText::KReportItemText()
36 : m_bottomPadding(0.0)
37{
38 createProperties();
39}
40
41KReportItemText::KReportItemText(const QDomNode & element)
42 : KReportItemText()
43{
44 nameProperty()->setValue(KReportUtils::readNameAttribute(element.toElement()));
45 setItemDataSource(element.toElement().attribute(QLatin1String("report:item-data-source")));
46 m_itemValue->setValue(element.toElement().attribute(QLatin1String("report:value")));
47 setZ(element.toElement().attribute(QLatin1String("report:z-index")).toDouble());
48 m_horizontalAlignment->setValue(element.toElement().attribute(QLatin1String("report:horizontal-align")));
49 m_verticalAlignment->setValue(element.toElement().attribute(QLatin1String("report:vertical-align")));
50 m_bottomPadding = element.toElement().attribute(QLatin1String("report:bottom-padding")).toDouble();
51
52 parseReportRect(element.toElement());
53
54 QDomNodeList nl = element.childNodes();
55 QString n;
56 QDomNode node;
57 for (int i = 0; i < nl.count(); i++) {
58 node = nl.item(i);
59 n = node.nodeName();
60
61 if (n == QLatin1String("report:text-style")) {
62 KReportTextStyleData ts;
63 if (parseReportTextStyleData(node.toElement(), &ts)) {
64 m_backgroundColor->setValue(ts.backgroundColor);
65 m_foregroundColor->setValue(ts.foregroundColor);
66 m_backgroundOpacity->setValue(ts.backgroundOpacity);
67 m_font->setValue(ts.font);
68
69 }
70 } else if (n == QLatin1String("report:line-style")) {
72 if (parseReportLineStyleData(node.toElement(), &ls)) {
73 m_lineWeight->setValue(ls.weight());
74 m_lineColor->setValue(ls.color());
75 m_lineStyle->setValue(static_cast<int>(ls.penStyle()));
76 }
77 } else {
78 kreportpluginWarning() << "while parsing field element encountered unknown element: " << n;
79 }
80 }
81
82}
83
84KReportItemText::~KReportItemText()
85{
86}
87
88Qt::Alignment KReportItemText::textFlags() const
89{
90 Qt::Alignment align;
91 QString t;
92 t = m_horizontalAlignment->value().toString();
93 if (t == QLatin1String("center"))
94 align = Qt::AlignHCenter;
95 else if (t == QLatin1String("right"))
96 align = Qt::AlignRight;
97 else
98 align = Qt::AlignLeft;
99
100 t = m_verticalAlignment->value().toString();
101 if (t == QLatin1String("center"))
102 align |= Qt::AlignVCenter;
103 else if (t == QLatin1String("bottom"))
104 align |= Qt::AlignBottom;
105 else
106 align |= Qt::AlignTop;
107
108 return align;
109}
110
111void KReportItemText::createProperties()
112{
113 createDataSourceProperty();
114
115 m_itemValue = new KProperty("value", QString(), tr("Value"), tr("Value used if not bound to a field"));
116
117 KPropertyListData *listData = new KPropertyListData(
118 { QLatin1String("left"), QLatin1String("center"), QLatin1String("right") },
119 QVariantList{ tr("Left"), tr("Center"), tr("Right") });
120 m_horizontalAlignment = new KProperty("horizontal-align", listData, QLatin1String("left"),
121 tr("Horizontal Alignment"));
122
123 listData = new KPropertyListData(
124 { QLatin1String("top"), QLatin1String("center"), QLatin1String("bottom") },
125 QVariantList{ tr("Top"), tr("Center"), tr("Bottom") });
126 m_verticalAlignment = new KProperty("vertical-align", listData, QLatin1String("center"),
127 tr("Vertical Alignment"));
128
129 m_font = new KProperty("font", QApplication::font(), tr("Font"));
130
131 m_backgroundColor = new KProperty("background-color", QColor(Qt::white), tr("Background Color"));
132 m_foregroundColor = new KProperty("foreground-color", QColor(Qt::black), tr("Foreground Color"));
133
134 m_lineWeight = new KProperty("line-weight", 1.0, tr("Line Weight"));
135 m_lineWeight->setOption("step", 1.0);
136 m_lineColor = new KProperty("line-color", QColor(Qt::black), tr("Line Color"));
137 m_lineStyle = new KProperty("line-style", static_cast<int>(Qt::NoPen), tr("Line Style"), QString(), KProperty::LineStyle);
138 m_backgroundOpacity = new KProperty("background-opacity", QVariant(0), tr("Background Opacity"));
139 m_backgroundOpacity->setOption("max", 100);
140 m_backgroundOpacity->setOption("min", 0);
141 m_backgroundOpacity->setOption("suffix", QLatin1String("%"));
142
143 propertySet()->addProperty(m_itemValue);
144 propertySet()->addProperty(m_horizontalAlignment);
145 propertySet()->addProperty(m_verticalAlignment);
146 propertySet()->addProperty(m_font);
147 propertySet()->addProperty(m_backgroundColor);
148 propertySet()->addProperty(m_foregroundColor);
149 propertySet()->addProperty(m_backgroundOpacity);
150 propertySet()->addProperty(m_lineWeight);
151 propertySet()->addProperty(m_lineColor);
152 propertySet()->addProperty(m_lineStyle);
153
154}
155
156qreal KReportItemText::bottomPadding() const
157{
158 return m_bottomPadding;
159}
160
161void KReportItemText::setBottomPadding(qreal bp)
162{
163 if (m_bottomPadding != bp) {
164 m_bottomPadding = bp;
165 }
166}
167
168KReportTextStyleData KReportItemText::textStyle() const
169{
170 KReportTextStyleData d;
171 d.backgroundColor = m_backgroundColor->value().value<QColor>();
172 d.foregroundColor = m_foregroundColor->value().value<QColor>();
173 d.font = m_font->value().value<QFont>();
174 d.backgroundOpacity = m_backgroundOpacity->value().toInt();
175 return d;
176}
177
178KReportLineStyle KReportItemText::lineStyle() const
179{
181 ls.setWeight(m_lineWeight->value().toReal());
182 ls.setColor(m_lineColor->value().value<QColor>());
183 ls.setPenStyle((Qt::PenStyle)m_lineStyle->value().toInt());
184 return ls;
185}
186
187// RTTI
188QString KReportItemText::typeName() const
189{
190 return QLatin1String("text");
191}
192
193int KReportItemText::renderSimpleData(OROPage *page, OROSection *section, const QPointF &offset,
194 const QVariant &data, KReportScriptHandler *script)
195
196{
197 Q_UNUSED(script);
198
199 QString qstrValue;
200
201 QString cs = itemDataSource();
202
203 if (!cs.isEmpty()) {
204 qstrValue = data.toString();
205 } else {
206 qstrValue = m_itemValue->value().toString();
207 }
208
210 QSizeF siz = sceneSize(size());
211 pos += offset;
212
213 QRectF trf(pos, siz);
214 qreal intStretch = trf.top() - offset.y();
215
216 if (!qstrValue.isEmpty()) {
217 QRectF rect = trf;
218
219 int pos = 0;
220 QChar separator;
222 const QFontMetricsF fm(font(), KReportPrivate::highResolutionPrinter());
223
224 const int intRectWidth
225 = (int)((size().width() / 72) * KReportPrivate::highResolutionPrinter()->resolution());
226 int intLineCounter = 0;
227 qreal intBaseTop = trf.top();
228 qreal intRectHeight = trf.height();
229
230 while (!qstrValue.isEmpty()) {
231 QRegularExpressionMatch match = re.match(qstrValue);
232 int idx = match.capturedStart(pos);
233 if (idx == -1) {
234 idx = qstrValue.length();
235 separator = QLatin1Char('\n');
236 } else
237 separator = qstrValue.at(idx);
238
239 if (fm.boundingRect(qstrValue.left(idx)).width() < intRectWidth || pos == 0) {
240 pos = idx + 1;
241 if (separator == QLatin1Char('\n')) {
242 QString line = qstrValue.left(idx);
243
244 qstrValue.remove(0, idx + 1);
245
246 pos = 0;
247
248 rect.setTop(intBaseTop + (intLineCounter * intRectHeight));
249 rect.setBottom(rect.top() + intRectHeight);
250
251 OROTextBox * tb = new OROTextBox();
252 tb->setPosition(rect.topLeft());
253 tb->setSize(rect.size());
254 tb->setFont(font());
255 tb->setText(line);
256 tb->setFlags(textFlags());
257 tb->setTextStyle(textStyle());
258 tb->setLineStyle(lineStyle());
259
260 if (page) {
261 page->insertPrimitive(tb);
262 }
263
264 if (section) {
265 OROTextBox *tb2 = dynamic_cast<OROTextBox*>(tb->clone());
266 if (tb2) {
267 tb2->setPosition(scenePosition(position()));
268 section->addPrimitive(tb2);
269 }
270 }
271
272 if (!page) {
273 delete tb;
274 }
275
276 intStretch += intRectHeight;
277 intLineCounter++;
278 }
279 } else {
280 QString line = qstrValue.left(pos - 1);
281 qstrValue.remove(0, pos);
282 pos = 0;
283
284 rect.setTop(intBaseTop + (intLineCounter * intRectHeight));
285 rect.setBottom(rect.top() + intRectHeight);
286
287 OROTextBox * tb = new OROTextBox();
288 tb->setPosition(rect.topLeft());
289 tb->setSize(rect.size());
290 tb->setFont(font());
291 tb->setText(line);
292 tb->setFlags(textFlags());
293 tb->setTextStyle(textStyle());
294 tb->setLineStyle(lineStyle());
295 if (page) {
296 page->insertPrimitive(tb);
297 } else {
298 delete tb;
299 }
300
301 intStretch += intRectHeight;
302 intLineCounter++;
303 }
304 }
305
306 intStretch += (m_bottomPadding / 100.0);
307 }
308
309 return intStretch; //Item returns its required section height
310}
void addProperty(KProperty *property, const QByteArray &group="common")
QVariant value() const
void setOption(const char *name, const QVariant &val)
static QPointF scenePosition(const QPointF &ptPos)
Helper function mapping to screen units (pixels), ptPos is in points.
QPointF position() const
Return the position in points.
static QSizeF sceneSize(const QSizeF &ptSize)
Helper function mapping to screen units (pixels), ptSize is in points.
QSizeF size() const
Return the size in points.
QString itemDataSource() const
The KReportLineStyle class represents line style.
Represents a single page in a document and may contain zero or more OROPrimitive objects all of which...
Represents a single a single row in a document and may contain zero or more OROPrimitives.
A text box primitive it defines a box region and text that will be rendered inside that region,...
KCOREADDONS_EXPORT Result match(QStringView pattern, QStringView str)
QFont font()
QString attribute(const QString &name, const QString &defValue) const const
QDomNodeList childNodes() const const
QString nodeName() const const
QDomElement toElement() const const
int count() const const
QDomNode item(int index) const const
QString tr(const char *sourceText, const char *disambiguation, int n)
qreal y() const const
void setBottom(qreal y)
void setTop(qreal y)
QSizeF size() const const
qreal top() const const
QPointF topLeft() const const
const QChar at(qsizetype position) const const
bool isEmpty() const const
QString left(qsizetype n) const const
qsizetype length() const const
QString & remove(QChar ch, Qt::CaseSensitivity cs)
double toDouble(bool *ok) const const
typedef Alignment
int toInt(bool *ok) const const
qreal toReal(bool *ok) const const
QString toString() const const
T value() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:21:31 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.