KReport

KReportDocument.cpp
1 /* This file is part of the KDE project
2  * Copyright (C) 2007-2008 by Adam Pigg ([email protected])
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "KReportDocument.h"
19 #include "KReportUnit.h"
20 #include "KReportDetailSectionData.h"
21 #include "KReportItemBase.h"
22 #include "KReportUtils_p.h"
23 #include "KReportPageSize.h"
24 
25 #include <QDomElement>
26 #include <QApplication>
27 #include "kreport_debug.h"
28 
29 class Q_DECL_HIDDEN KReportDocument::Private
30 {
31 public:
32  bool valid;
33  QString title;
34  QString name;
35  QString query;
36 #ifdef KREPORT_SCRIPTING
37  QString script;
38  QString interpreter;
39 #endif
40  bool externalData;
41  KReportPrivate::PageLayout pageLayout;
43  QString labelType;
44 
45  KReportSectionData * pageHeaderFirst = nullptr;
46  KReportSectionData * pageHeaderOdd = nullptr;
47  KReportSectionData * pageHeaderEven = nullptr;
48  KReportSectionData * pageHeaderLast = nullptr;
49  KReportSectionData * pageHeaderAny = nullptr;
50 
51  KReportSectionData * reportHeader = nullptr;
52  KReportSectionData * reportFooter = nullptr;
53 
54  KReportSectionData * pageFooterFirst = nullptr;
55  KReportSectionData * pageFooterOdd = nullptr;
56  KReportSectionData * pageFooterEven = nullptr;
57  KReportSectionData * pageFooterLast = nullptr;
58  KReportSectionData * pageFooterAny = nullptr;
59 
60  KReportDetailSectionData* detailSection = nullptr;
61 };
62 
64  : QObject(parent),
65  d(new Private)
66 {
67  d->valid = true;
68 }
69 
71  : QObject(parent),
72  d(new Private)
73 {
74  d->valid = false;
75 
76  if (elemSource.tagName() != QLatin1String("report:content")) {
77  kreportWarning() << "QDomElement is not <report:content> tag"
78  << elemSource.text();
79  return;
80  }
81 
82  QDomNodeList sections = elemSource.childNodes();
83  for (int nodeCounter = 0; nodeCounter < sections.count(); nodeCounter++) {
84  QDomElement elemThis = sections.item(nodeCounter).toElement();
85  if (elemThis.tagName() == QLatin1String("report:title")) {
86  d->title = elemThis.text();
87 #ifdef KREPORT_SCRIPTING
88  } else if (elemThis.tagName() == QLatin1String("report:script")) {
89  d->script = elemThis.text();
90  d->interpreter = elemThis.attribute(QLatin1String("report:script-interpreter"));
91 #endif
92  } else if (elemThis.tagName() == QLatin1String("report:page-style")) {
93  QString pagetype = elemThis.firstChild().nodeValue();
94 
95  //Full page mode is required to allow margins to be set to whatever the user has specified
96  d->pageLayout.setMode(QPageLayout::FullPageMode);
97 
98  if (pagetype == QLatin1String("predefined")) {
99  setPageSize(elemThis.attribute(QLatin1String("report:page-size"), QLatin1String("A4")));
100  d->pageLayout.setPageSize(QPageSize(KReportPageSize::pageSize(pageSize())));
101  } else if (pagetype == QLatin1String("custom")) {
102  kreportDebug() << "Setting custom page size in document to " << KReportUnit::parseValue(elemThis.attribute(QLatin1String("report:custom-page-width"), QLatin1String("5.0cm"))) << KReportUnit::parseValue(elemThis.attribute(QLatin1String("report:custom-page-height"), QLatin1String("5.0cm"))) ;
103  QPageSize custom(QSize(KReportUnit::parseValue(elemThis.attribute(QLatin1String("report:custom-page-width"), QLatin1String("5.0cm"))) , KReportUnit::parseValue(elemThis.attribute(QLatin1String("report:custom-page-height"), QLatin1String("5.0cm"))) ), QString(), QPageSize::ExactMatch);
104 
105  d->pageLayout.setPageSize(custom);
106  } else if (pagetype == QLatin1String("label")) {
107  setLabelType(elemThis.firstChild().nodeValue());
108  }
109  //! @todo add config for default margins or add within templates support
110  d->pageLayout.setUnits(QPageLayout::Point);
111  d->pageLayout.setLeftMargin(KReportUnit::parseValue(elemThis.attribute(
112  QLatin1String("fo:margin-left"), DEFAULT_PAGE_MARGIN_STRING)));
113  d->pageLayout.setRightMargin(KReportUnit::parseValue(elemThis.attribute(
114  QLatin1String("fo:margin-right"), DEFAULT_PAGE_MARGIN_STRING)));
115  d->pageLayout.setTopMargin(KReportUnit::parseValue(elemThis.attribute(
116  QLatin1String("fo:margin-top"), DEFAULT_PAGE_MARGIN_STRING)));
117  d->pageLayout.setBottomMargin(KReportUnit::parseValue(elemThis.attribute(
118  QLatin1String("fo:margin-bottom"), DEFAULT_PAGE_MARGIN_STRING)));
119  d->pageLayout.setOrientation(
120  elemThis.attribute(QLatin1String("report:print-orientation"),
121  QLatin1String("portrait"))
122  == QLatin1String("portrait")
125  } else if (elemThis.tagName() == QLatin1String("report:body")) {
126  QDomNodeList sectionlist = elemThis.childNodes();
127  QDomNode sec;
128 
129  for (int s = 0; s < sectionlist.count(); ++s) {
130  sec = sectionlist.item(s);
131  if (sec.isElement()) {
132  QString sn = sec.nodeName().toLower();
133  //kreportDebug() << sn;
134  if (sn == QLatin1String("report:section")) {
135  KReportSectionData * sd = new KReportSectionData(sec.toElement(), this);
136  if (!sd->isValid()) {
137  kreportDebug() << "Invalid section";
138  delete sd;
139  } else {
140  //kreportDebug() << "Adding section of type " << sd->type();
141  switch (sd->type()) {
142  case KReportSectionData::Type::PageHeaderFirst:
143  d->pageHeaderFirst = sd;
144  break;
145  case KReportSectionData::Type::PageHeaderOdd:
146  d->pageHeaderOdd = sd;
147  break;
148  case KReportSectionData::Type::PageHeaderEven:
149  d->pageHeaderEven = sd;
150  break;
151  case KReportSectionData::Type::PageHeaderLast:
152  d->pageHeaderLast = sd;
153  break;
154  case KReportSectionData::Type::PageHeaderAny:
155  d->pageHeaderAny = sd;
156  break;
157  case KReportSectionData::Type::ReportHeader:
158  d->reportHeader = sd;
159  break;
160  case KReportSectionData::Type::ReportFooter:
161  d->reportFooter = sd;
162  break;
163  case KReportSectionData::Type::PageFooterFirst:
164  d->pageFooterFirst = sd;
165  break;
166  case KReportSectionData::Type::PageFooterOdd:
167  d->pageFooterOdd = sd;
168  break;
169  case KReportSectionData::Type::PageFooterEven:
170  d->pageFooterEven = sd;
171  break;
172  case KReportSectionData::Type::PageFooterLast:
173  d->pageFooterLast = sd;
174  break;
175  case KReportSectionData::Type::PageFooterAny:
176  d->pageFooterAny = sd;
177  break;
178  default:
179  ;
180  }
181  }
182 
183  } else if (sn == QLatin1String("report:detail")) {
184  KReportDetailSectionData * dsd = new KReportDetailSectionData(sec.toElement(), this);
185 
186  if (dsd->isValid()) {
187  d->detailSection = dsd;
188  } else {
189  kreportDebug() << "Invalid detail section";
190  delete dsd;
191  }
192  }
193  } else {
194  kreportWarning() << "Encountered an unknown Element: " << elemThis.tagName();
195  }
196  }
197  }
198 
199  d->valid = true;
200  }
201 }
202 
203 KReportDocument::~KReportDocument()
204 {
205  delete d;
206 }
207 
209 {
211  for (int i = static_cast<int>(KReportSectionData::Type::PageHeaderFirst);
212  i <= static_cast<int>(KReportSectionData::Type::PageFooterAny); i++)
213  {
214  KReportSectionData *sec = section(static_cast<KReportSectionData::Type>(i));
215  if (sec) {
216  obs << sec->objects();
217  }
218  }
219 
220  if (d->detailSection) {
221  //kreportDebug() << "Number of groups: " << m_detailSection->m_groupList.count();
222  foreach(KReportDetailGroupSectionData* g, d->detailSection->groupList) {
223  if (g->groupHeader) {
224  obs << g->groupHeader->objects();
225  }
226  if (g->groupFooter) {
227  obs << g->groupFooter->objects();
228  }
229  }
230  if (d->detailSection->detailSection)
231  obs << d->detailSection->detailSection->objects();
232  }
233 
234  /*kreportDebug() << "Object List:";
235  foreach(KReportItemBase* o, obs) {
236  kreportDebug() << o->entityName();
237  }*/
238  return obs;
239 }
240 
242 {
244 
245  foreach(KReportItemBase* o, obs) {
246  if (o->entityName() == n) {
247  return o;
248  }
249  }
250  return nullptr;
251 }
252 
254 {
256  for (int i = static_cast<int>(KReportSectionData::Type::PageHeaderFirst);
257  i <= static_cast<int>(KReportSectionData::Type::PageFooterAny); i++)
258  {
259  KReportSectionData *sec = section(static_cast<KReportSectionData::Type>(i));
260  if (sec) {
261  secs << sec;
262  }
263  }
264 
265  if (d->detailSection) {
266  //kreportDebug() << "Number of groups: " << m_detailSection->m_groupList.count();
267  foreach(KReportDetailGroupSectionData* g, d->detailSection->groupList) {
268  if (g->groupHeader) {
269  secs << g->groupHeader;
270  }
271  if (g->groupFooter) {
272  secs << g->groupFooter;
273  }
274  }
275  if (d->detailSection->detailSection)
276  secs << d->detailSection->detailSection;
277  }
278 
279  return secs;
280 }
281 
283 {
285 
286  foreach(KReportSectionData *sec, secs) {
287  if (sec->name() == sn) {
288  return sec;
289  }
290  }
291  return nullptr;
292 }
293 
294 KReportSectionData* KReportDocument::section(KReportSectionData::Type type) const
295 {
296  KReportSectionData *sec;
297  switch (type) {
298  case KReportSectionData::Type::PageHeaderAny:
299  sec = d->pageHeaderAny;
300  break;
301  case KReportSectionData::Type::PageHeaderEven:
302  sec = d->pageHeaderEven;
303  break;
304  case KReportSectionData::Type::PageHeaderOdd:
305  sec = d->pageHeaderOdd;
306  break;
307  case KReportSectionData::Type::PageHeaderFirst:
308  sec = d->pageHeaderFirst;
309  break;
310  case KReportSectionData::Type::PageHeaderLast:
311  sec = d->pageHeaderLast;
312  break;
313  case KReportSectionData::Type::PageFooterAny:
314  sec = d->pageFooterAny;
315  break;
316  case KReportSectionData::Type::PageFooterEven:
317  sec = d->pageFooterEven;
318  break;
319  case KReportSectionData::Type::PageFooterOdd:
320  sec = d->pageFooterOdd;
321  break;
322  case KReportSectionData::Type::PageFooterFirst:
323  sec = d->pageFooterFirst;
324  break;
325  case KReportSectionData::Type::PageFooterLast:
326  sec = d->pageFooterLast;
327  break;
328  case KReportSectionData::Type::ReportHeader:
329  sec = d->reportHeader;
330  break;
331  case KReportSectionData::Type::ReportFooter:
332  sec = d->reportFooter;
333  break;
334  default:
335  sec = nullptr;
336  }
337  return sec;
338 }
339 
340 QPageLayout KReportDocument::pageLayout() const
341 {
342  return d->pageLayout;
343 }
344 
345 bool KReportDocument::isValid() const
346 {
347  return d->valid;
348 }
349 
350 QString KReportDocument::title() const
351 {
352  return d->title;
353 }
354 
355 bool KReportDocument::externalData() const
356 {
357  return d->externalData;
358 }
359 
360 #ifdef KREPORT_SCRIPTING
361 QString KReportDocument::script() const
362 {
363  return d->script;
364 }
365 
366 QString KReportDocument::interpreter() const
367 {
368  return d->interpreter;
369 }
370 #endif
371 
372 QString KReportDocument::name() const
373 {
374  return d->name;
375 }
376 
377 void KReportDocument::setName(const QString& n)
378 {
379  d->name = n;
380 }
381 
382 QString KReportDocument::query() const
383 {
384  return d->query;
385 }
386 
387 QString KReportDocument::pageSize()
388 {
389  return d->pageSize;
390 }
391 
392 void KReportDocument::setPageSize(const QString& size)
393 {
394  d->pageSize = size;
395 }
396 
397 QString KReportDocument::labelType() const
398 {
399  return d->labelType;
400 }
401 
402 void KReportDocument::setLabelType(const QString& label)
403 {
404  d->labelType = label;
405 }
406 
407 KReportDetailSectionData * KReportDocument::detail() const
408 {
409  return d->detailSection;
410 }
411 
Base class for items that are drawn syncronously.
int count() const const
QString text() const const
QDomNode firstChild() const const
QDomElement toElement() const const
QString tagName() const const
QList< KReportItemBase * > objects() const
KReportSectionData is used to store the information about a specific report section.
QString nodeValue() const const
KSERVICE_EXPORT KService::List query(FilterFunc filterFunc)
QDomNode item(int index) const const
static qreal parseValue(const QString &value, qreal defaultVal=0.0)
Parses common KReport and ODF values, like "10cm", "5mm" to pt.
KReportDocument(const QDomElement &elemSource, QObject *parent=nullptr)
KReportSectionData * section(KReportSectionData::Type type) const
QDomNodeList childNodes() const const
QList< KReportSectionData * > sections() const
QString nodeName() const const
QString label(StandardShortcut id)
QString toLower() const const
KReportItemBase * object(const QString &) const
QString name(StandardShortcut id)
QString attribute(const QString &name, const QString &defValue) const const
Top level report document definition. A KReportDocment defines the design of a document,...
bool isElement() const const
KREPORT_EXPORT QPageSize::PageSizeId pageSize(const QString &key)
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Tue Jun 28 2022 04:12:21 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.