KReport

KReportPreRenderer.cpp
1 /* This file is part of the KDE project
2  * Copyright (C) 2001-2007 by OpenMFG, LLC ([email protected])
3  * Copyright (C) 2007-2008 by Adam Pigg ([email protected])
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 "KReportPreRenderer.h"
20 #include "KReportPreRenderer_p.h"
21 #include "KReportAsyncItemManager_p.h"
22 #include "KReportOneRecordDataSource_p.h"
23 
24 #include "KReportRenderObjects.h"
25 #include "KReportDataSource.h"
26 #include "KReportItemBase.h"
27 #include "KReportDocument.h"
28 #include "KReportDetailSectionData.h"
29 #include "KReportLabelSizeInfo.h"
30 #include "KReportPageSize.h"
31 #include "KReportUtils_p.h"
32 
33 #ifdef KREPORT_SCRIPTING
34 #include "KReportScriptHandler.h"
35 #include "KReportGroupTracker.h"
36 #endif
37 
38 #include <QDomElement>
39 #include <QApplication>
40 #include "kreport_debug.h"
41 
42 KReportPreRendererPrivate::KReportPreRendererPrivate(KReportPreRenderer *preRenderer)
43  : m_preRenderer(preRenderer)
44 {
45  m_valid = false;
46  m_document = nullptr;
47  m_reportDocument = nullptr;
48  m_page = nullptr;
49  m_yOffset = 0.0;
50  m_topMargin = m_bottomMargin = 0.0;
51  m_leftMargin = m_rightMargin = 0.0;
52  m_pageCounter = 0;
53  m_maxHeight = m_maxWidth = 0.0;
54  m_oneRecord = new KReportPrivate::OneRecordDataSource();
55  m_dataSource = nullptr;
56 #ifdef KREPORT_SCRIPTING
57  m_scriptHandler = nullptr;
58 #endif
59  asyncManager = new KReportPrivate::AsyncItemManager(this);
60 
61  connect(asyncManager, SIGNAL(finished()), this, SLOT(asyncItemsFinished()));
62 }
63 
64 KReportPreRendererPrivate::~KReportPreRendererPrivate()
65 {
66  delete m_reportDocument;
67  delete m_document;
68  delete m_oneRecord;
69  m_postProcText.clear();
70 }
71 
72 void KReportPreRendererPrivate::createNewPage()
73 {
74  //kreportDebug();
75  if (m_pageCounter > 0)
76  finishCurPage(false);
77 
78  m_pageCounter++;
79 
80 #ifdef KREPORT_SCRIPTING
81  //Update the page count script value
82  m_scriptHandler->setPageNumber(m_pageCounter);
83  m_scriptHandler->newPage();
84 #endif
85 
86  m_page = new OROPage(nullptr);
87  m_document->addPage(m_page);
88 
89  //! @todo calculate past page
90  bool lastPage = false;
91 
92  m_yOffset = m_topMargin;
93 
94  if (m_pageCounter == 1 && m_reportDocument->section(KReportSectionData::Type::PageHeaderFirst))
95  renderSection(*(m_reportDocument->section(KReportSectionData::Type::PageHeaderFirst)));
96  else if (lastPage == true && m_reportDocument->section(KReportSectionData::Type::PageHeaderLast))
97  renderSection(*(m_reportDocument->section(KReportSectionData::Type::PageHeaderLast)));
98  else if ((m_pageCounter % 2) == 1 && m_reportDocument->section(KReportSectionData::Type::PageHeaderOdd))
99  renderSection(*(m_reportDocument->section(KReportSectionData::Type::PageHeaderOdd)));
100  else if ((m_pageCounter % 2) == 0 && m_reportDocument->section(KReportSectionData::Type::PageHeaderEven))
101  renderSection(*(m_reportDocument->section(KReportSectionData::Type::PageHeaderEven)));
102  else if (m_reportDocument->section(KReportSectionData::Type::PageHeaderAny))
103  renderSection(*(m_reportDocument->section(KReportSectionData::Type::PageHeaderAny)));
104 }
105 
106 qreal KReportPreRendererPrivate::finishCurPageSize(bool lastPage)
107 {
108  qreal retval = 0.0;
109 
110  if (lastPage && m_reportDocument->section(KReportSectionData::Type::PageFooterLast))
111  retval = renderSectionSize(* (m_reportDocument->section(KReportSectionData::Type::PageFooterLast)));
112  else if (m_pageCounter == 1 && m_reportDocument->section(KReportSectionData::Type::PageFooterFirst))
113  retval = renderSectionSize(* (m_reportDocument->section(KReportSectionData::Type::PageFooterFirst)));
114  else if ((m_pageCounter % 2) == 1 && m_reportDocument->section(KReportSectionData::Type::PageFooterOdd))
115  retval = renderSectionSize(* (m_reportDocument->section(KReportSectionData::Type::PageFooterOdd)));
116  else if ((m_pageCounter % 2) == 0 && m_reportDocument->section(KReportSectionData::Type::PageFooterEven))
117  retval = renderSectionSize(* (m_reportDocument->section(KReportSectionData::Type::PageFooterEven)));
118  else if (m_reportDocument->section(KReportSectionData::Type::PageFooterAny))
119  retval = renderSectionSize(* (m_reportDocument->section(KReportSectionData::Type::PageFooterAny)));
120 
121  //kreportDebug() << retval;
122  return retval;
123 }
124 
125 qreal KReportPreRendererPrivate::finishCurPage(bool lastPage)
126 {
127 
128  qreal offset = m_maxHeight - m_bottomMargin;
129  qreal retval = 0.0;
130  //kreportDebug() << offset;
131 
132  if (lastPage && m_reportDocument->section(KReportSectionData::Type::PageFooterLast)) {
133  //kreportDebug() << "Last Footer";
134  m_yOffset = offset - renderSectionSize(* (m_reportDocument->section(KReportSectionData::Type::PageFooterLast)));
135  retval = renderSection(* (m_reportDocument->section(KReportSectionData::Type::PageFooterLast)));
136  } else if (m_pageCounter == 1 && m_reportDocument->section(KReportSectionData::Type::PageFooterFirst)) {
137  //kreportDebug() << "First Footer";
138  m_yOffset = offset - renderSectionSize(* (m_reportDocument->section(KReportSectionData::Type::PageFooterFirst)));
139  retval = renderSection(* (m_reportDocument->section(KReportSectionData::Type::PageFooterFirst)));
140  } else if ((m_pageCounter % 2) == 1 && m_reportDocument->section(KReportSectionData::Type::PageFooterOdd)) {
141  //kreportDebug() << "Odd Footer";
142  m_yOffset = offset - renderSectionSize(* (m_reportDocument->section(KReportSectionData::Type::PageFooterOdd)));
143  retval = renderSection(* (m_reportDocument->section(KReportSectionData::Type::PageFooterOdd)));
144  } else if ((m_pageCounter % 2) == 0 && m_reportDocument->section(KReportSectionData::Type::PageFooterEven)) {
145  //kreportDebug() << "Even Footer";
146  m_yOffset = offset - renderSectionSize(* (m_reportDocument->section(KReportSectionData::Type::PageFooterEven)));
147  retval = renderSection(* (m_reportDocument->section(KReportSectionData::Type::PageFooterEven)));
148  } else if (m_reportDocument->section(KReportSectionData::Type::PageFooterAny)) {
149  //kreportDebug() << "Any Footer";
150  m_yOffset = offset - renderSectionSize(* (m_reportDocument->section(KReportSectionData::Type::PageFooterAny)));
151  retval = renderSection(* (m_reportDocument->section(KReportSectionData::Type::PageFooterAny)));
152  }
153 
154  return retval;
155 }
156 
157 void KReportPreRendererPrivate::renderDetailSection(KReportDetailSectionData *detailData)
158 {
159  if (detailData->detailSection) {
160  if (m_dataSource/* && !curs->eof()*/) {
161  QStringList keys;
162  QStringList keyValues;
163  QList<int> shownGroups;
164  KReportDetailGroupSectionData * grp = nullptr;
165 
166  bool status = m_dataSource->moveFirst();
167  int recordCount = m_dataSource->recordCount();
168 
169  //kreportDebug() << "Record Count:" << recordCount;
170 
171  for (int i = 0; i < (int) detailData->groupList.count(); ++i) {
172  grp = detailData->groupList[i];
173  //If the group has a header or footer, then emit a change of group value
174  if(grp->groupFooter || grp->groupHeader) {
175  // we get here only if group is *shown*
176  shownGroups << i;
177  keys.append(grp->column);
178  if (!keys.last().isEmpty())
179  keyValues.append(m_dataSource->value(m_dataSource->fieldNumber(keys.last())).toString());
180  else
181  keyValues.append(QString());
182 
183  //Tell interested parties we're about to render a header
184  emit(enteredGroup(keys.last(), keyValues.last()));
185  }
186  if (grp->groupHeader)
187  renderSection(*(grp->groupHeader));
188  }
189 
190  while (status) {
191  const qint64 pos = m_dataSource->at();
192  //kreportDebug() << "At:" << l << "Y:" << m_yOffset << "Max Height:" << m_maxHeight;
193  if ((renderSectionSize(*detailData->detailSection)
194  + finishCurPageSize((pos + 1 == recordCount))
195  + m_bottomMargin + m_yOffset) >= m_maxHeight)
196  {
197  //kreportDebug() << "Next section is too big for this page";
198  if (pos > 0) {
199  m_dataSource->movePrevious();
200  createNewPage();
201  m_dataSource->moveNext();
202  }
203  }
204 
205  renderSection(*(detailData->detailSection));
206  status = m_dataSource->moveNext();
207 
208  if (status == true && keys.count() > 0) {
209  // check to see where it is we need to start
210  int pos = -1; // if it's still -1 by the time we are done then no keyValues changed
211  for (int i = 0; i < keys.count(); ++i) {
212  if (keyValues[i] != m_dataSource->value(m_dataSource->fieldNumber(keys[i])).toString()) {
213  pos = i;
214  break;
215  }
216  }
217  // don't bother if nothing has changed
218  if (pos != -1) {
219  // roll back the query and go ahead if all is good
220  status = m_dataSource->movePrevious();
221  if (status == true) {
222  // print the footers as needed
223  // any changes made in this for loop need to be duplicated
224  // below where the footers are finished.
225  bool do_break = false;
226  for (int i = shownGroups.count() - 1; i >= 0; i--) {
227  if (do_break)
228  createNewPage();
229  do_break = false;
230  grp = detailData->groupList[shownGroups.at(i)];
231 
232  if (grp->groupFooter) {
233  if (renderSectionSize(*(grp->groupFooter)) + finishCurPageSize(false) + m_bottomMargin + m_yOffset >= m_maxHeight)
234  createNewPage();
235  renderSection(*(grp->groupFooter));
236  }
237 
238  if (KReportDetailGroupSectionData::PageBreak::AfterGroupFooter == grp->pagebreak)
239  do_break = true;
240  }
241  // step ahead to where we should be and print the needed headers
242  // if all is good
243  status = m_dataSource->moveNext();
244  if (do_break)
245  createNewPage();
246  if (status == true) {
247  for (int i = 0; i < shownGroups.count(); ++i) {
248  grp = detailData->groupList[shownGroups.at(i)];
249 
250  if (grp->groupHeader) {
251  if (renderSectionSize(*(grp->groupHeader)) + finishCurPageSize(false) + m_bottomMargin + m_yOffset >= m_maxHeight) {
252  m_dataSource->movePrevious();
253  createNewPage();
254  m_dataSource->moveNext();
255  }
256 
257  if (!keys[i].isEmpty())
258  keyValues[i] = m_dataSource->value(m_dataSource->fieldNumber(keys[i])).toString();
259 
260  //Tell interested parties thak key values changed
261  renderSection(*(grp->groupHeader));
262  }
263 
264 
265  }
266  }
267  }
268  }
269  }
270  }
271 
272  if (keys.size() > 0 && m_dataSource->movePrevious()) {
273  // finish footers
274  // duplicated changes from above here
275  for (int i = shownGroups.count() - 1; i >= 0; i--) {
276  grp = detailData->groupList[shownGroups.at(i)];
277 
278  if (grp->groupFooter) {
279  if (renderSectionSize(*(grp->groupFooter)) + finishCurPageSize(false) + m_bottomMargin + m_yOffset >= m_maxHeight)
280  createNewPage();
281  renderSection(*(grp->groupFooter));
282  emit(exitedGroup(keys[i], keyValues[i]));
283  }
284  }
285  }
286  }
287  if (KReportDetailSectionData::PageBreak::AtEnd == detailData->pageBreak)
288  createNewPage();
289  }
290 }
291 
292 qreal KReportPreRendererPrivate::renderSectionSize(const KReportSectionData & sectionData)
293 {
294  qreal intHeight = POINT_TO_INCH(sectionData.height()) * KReportPrivate::dpiX();
295 
296  if (sectionData.objects().count() == 0)
297  return intHeight;
298 
299  QList<KReportItemBase*> objects = sectionData.objects();
300  foreach(KReportItemBase *ob, objects) {
301  QPointF offset(m_leftMargin, m_yOffset);
302  //ASync objects cannot alter the section height
303  KReportAsyncItemBase *async_ob = qobject_cast<KReportAsyncItemBase*>(ob);
304  if (!async_ob) {
305  QVariant itemData;
306  if (m_dataSource) {
307  itemData = m_dataSource->value(ob->itemDataSource());
308  }
309  const int itemHeight = ob->renderSimpleData(nullptr, nullptr, offset, itemData, m_scriptHandler);
310  if (itemHeight > intHeight) {
311  intHeight = itemHeight;
312  }
313  }
314  }
315 
316  return intHeight;
317 }
318 
319 qreal KReportPreRendererPrivate::renderSection(const KReportSectionData & sectionData)
320 {
321  qreal sectionHeight = POINT_TO_INCH(sectionData.height()) * KReportPrivate::dpiX();
322 
323  int itemHeight = 0;
324  //kreportDebug() << "Name: " << sectionData.name() << " Height: " << sectionHeight
325  // << "Objects: " << sectionData.objects().count();
326  emit(renderingSection(const_cast<KReportSectionData*>(&sectionData), m_page, QPointF(m_leftMargin, m_yOffset)));
327 
328  //Create a pre-rendered section for this section and add it to the document
329  OROSection *sec = new OROSection(m_document);
330  sec->setHeight(sectionData.height());
331  sec->setBackgroundColor(sectionData.backgroundColor());
332  sec->setType(sectionData.type());
333  m_document->addSection(sec);
334 
335  //Render section background
336  ORORect* bg = new ORORect();
337  bg->setPen(QPen(Qt::NoPen));
338  bg->setBrush(sectionData.backgroundColor());
339  qreal w = m_page->document()->pageLayout().fullRectPixels(KReportPrivate::dpiX()).width() - m_page->document()->pageLayout().marginsPixels(KReportPrivate::dpiX()).right() - m_leftMargin;
340 
341  bg->setRect(QRectF(m_leftMargin, m_yOffset, w, sectionHeight));
342  m_page->insertPrimitive(bg, true);
343 
344  QList<KReportItemBase*> objects = sectionData.objects();
345  foreach(KReportItemBase *ob, objects) {
346  QPointF offset(m_leftMargin, m_yOffset);
347  QVariant itemData = m_dataSource->value(ob->itemDataSource());
348 
349  if (ob->supportsSubQuery()) {
350  itemHeight = ob->renderReportData(m_page, sec, offset, m_dataSource, m_scriptHandler);
351  } else {
352  KReportAsyncItemBase *async_ob = qobject_cast<KReportAsyncItemBase*>(ob);
353  if (async_ob){
354  //kreportDebug() << "async object";
355  asyncManager->addItem(async_ob, m_page, sec, offset, async_ob->realItemData(itemData), m_scriptHandler);
356  } else {
357  //kreportDebug() << "sync object";
358  itemHeight = ob->renderSimpleData(m_page, sec, offset, itemData, m_scriptHandler);
359  }
360  }
361 
362  if (itemHeight > sectionHeight) {
363  sectionHeight = itemHeight;
364  }
365  }
366  for (int i = 0; i < m_page->primitiveCount(); ++i) {
367  OROPrimitive *prim = m_page->primitive(i);
368  if (OROTextBox *text = dynamic_cast<OROTextBox*>(prim)) {
369  if (text->requiresPostProcessing()) {
370  m_postProcText.append(text);
371  }
372  }
373  }
374  m_yOffset += sectionHeight;
375 
376  return sectionHeight;
377 }
378 
379 #ifdef KREPORT_SCRIPTING
380 void KReportPreRendererPrivate::initEngine()
381 {
382  delete m_scriptHandler;
383  m_scriptHandler = new KReportScriptHandler(m_dataSource, scriptSource, m_reportDocument);
384 
385  connect(this, SIGNAL(enteredGroup(QString,QVariant)), m_scriptHandler, SLOT(slotEnteredGroup(QString,QVariant)));
386 
387  connect(this, SIGNAL(exitedGroup(QString,QVariant)), m_scriptHandler, SLOT(slotExitedGroup(QString,QVariant)));
388 
389  connect(this, SIGNAL(renderingSection(KReportSectionData*,OROPage*,QPointF)), m_scriptHandler, SLOT(slotEnteredSection(KReportSectionData*,OROPage*,QPointF)));
390 }
391 #endif
392 
393 void KReportPreRendererPrivate::asyncItemsFinished()
394 {
395  //kreportDebug() << "Finished rendering async items";
396  asyncManager->deleteLater();
397  emit finishedAllASyncItems();
398 }
399 
400 bool KReportPreRendererPrivate::generateDocument()
401 {
402  if (!m_dataSource) {
403  m_dataSource = m_oneRecord;
404  }
405 
406  if (!m_valid || !m_reportDocument) {
407  return false;
408  }
409 
410  // Do this check now so we don't have to undo a lot of work later if it fails
411  KReportLabelSizeInfo label;
412  if (m_reportDocument->pageSize() == QLatin1String("Labels")) {
413  label = KReportLabelSizeInfo::find(m_reportDocument->labelType());
414  if (label.isNull()) {
415  return false;
416  }
417  }
418  //kreportDebug() << "Creating Document";
419  m_document = new ORODocument(m_reportDocument->title());
420 
421  m_pageCounter = 0;
422  m_yOffset = 0.0;
423 
424  //kreportDebug() << "Calculating Margins";
425  if (!label.isNull()) {
426  if (m_reportDocument->pageLayout().orientation() == QPageLayout::Portrait) {
427  m_topMargin = (label.startY() / 100.0);
428  m_bottomMargin = 0;
429  m_rightMargin = 0;
430  m_leftMargin = (label.startX() / 100.0);
431  } else {
432  m_topMargin = (label.startX() / 100.0);
433  m_bottomMargin = 0;
434  m_rightMargin = 0;
435  m_leftMargin = (label.startY() / 100.0);
436  }
437  } else {
438 
439  m_topMargin = m_reportDocument->pageLayout().marginsPoints().top();
440  m_bottomMargin = m_reportDocument->pageLayout().marginsPoints().bottom();
441  m_rightMargin = m_reportDocument->pageLayout().marginsPoints().right();
442  m_leftMargin = m_reportDocument->pageLayout().marginsPoints().left();
443  //kreportDebug() << "Margins:" << m_topMargin << m_bottomMargin << m_rightMargin << m_leftMargin;
444  }
445 
446  //kreportDebug() << "Calculating Page Size";
447  QPageLayout layout = m_reportDocument->pageLayout();
448  // This should reflect the information of the report page size
449  if (m_reportDocument->pageSize() == QLatin1String("Custom")) {
450  m_maxWidth = m_reportDocument->pageLayout().fullRectPoints().width();
451  m_maxHeight = m_reportDocument->pageLayout().fullRectPoints().height();
452  } else {
453  if (!label.isNull()) {
454  m_maxWidth = label.width();
455  m_maxHeight = label.height();
456  m_reportDocument->pageLayout().setPageSize(QPageSize(KReportPageSize::pageSize(label.paper())));
457  } else {
458  // lookup the correct size information for the specified size paper
459  QSizeF pageSizePx = m_reportDocument->pageLayout().fullRectPixels(KReportPrivate::dpiX()).size();
460 
461  m_maxWidth = pageSizePx.width();
462  m_maxHeight = pageSizePx.height();
463  }
464  }
465 
466  if (m_reportDocument->pageLayout().orientation() == QPageLayout::Landscape) {
467  qreal tmp = m_maxWidth;
468  m_maxWidth = m_maxHeight;
469  m_maxHeight = tmp;
470  }
471 
472  //kreportDebug() << "Page Size:" << m_maxWidth << m_maxHeight;
473 
474  m_document->setPageLayout(m_reportDocument->pageLayout());
475  m_dataSource->setSorting(m_reportDocument->detail()->sortedFields);
476  if (!m_dataSource->open()) {
477  return false;
478  }
479 
480  #ifdef KREPORT_SCRIPTING
481  initEngine();
482  connect(m_scriptHandler, SIGNAL(groupChanged(QMap<QString, QVariant>)),
483  m_preRenderer, SIGNAL(groupChanged(QMap<QString, QVariant>)));
484 
485  //Loop through all abjects that have been registered, and register them with the script handler
486  if (m_scriptHandler) {
487  QMapIterator<QString, QObject*> i(m_scriptObjects);
488  while (i.hasNext()) {
489  i.next();
490  m_scriptHandler->registerScriptObject(i.value(), i.key());
491  }
492  //execute the script, if it fails, abort and return the empty document
493  if (!m_scriptHandler->trigger()) {
494  m_scriptHandler->displayErrors();
495  return m_document;
496  }
497  }
498  #endif
499 
500  createNewPage();
501  if (!label.isNull()) {
502  // Label Print Run
503  // remember the initial margin setting as we will be modifying
504  // the value and restoring it as we move around
505  qreal margin = m_leftMargin;
506 
507  m_yOffset = m_topMargin;
508 
509  qreal w = (label.width() / 100.0);
510  qreal wg = (label.xGap() / 100.0);
511  qreal h = (label.height() / 100.0);
512  qreal hg = (label.yGap() / 100.0);
513  int numCols = label.columns();
514  int numRows = label.rows();
515  qreal tmp;
516 
517  // flip the value around if we are printing landscape
518  if (!(m_reportDocument->pageLayout().orientation() == QPageLayout::Portrait)) {
519  w = (label.height() / 100.0);
520  wg = (label.yGap() / 100.0);
521  h = (label.width() / 100.0);
522  hg = (label.xGap() / 100.0);
523  numCols = label.rows();
524  numRows = label.columns();
525  }
526 
527  KReportDetailSectionData * detailData = m_reportDocument->detail();
528  if (detailData->detailSection) {
529  KReportDataSource *mydata = m_dataSource;
530 
531  if (mydata && mydata->recordCount() > 0) { /* && !((query = orqThis->getQuery())->eof()))*/
532  if (!mydata->moveFirst()) {
533  return false;
534  }
535  int row = 0;
536  int col = 0;
537  do {
538  tmp = m_yOffset; // store the value as renderSection changes it
539  renderSection(*(detailData->detailSection));
540  m_yOffset = tmp; // restore the value that renderSection modified
541 
542  col++;
543  m_leftMargin += w + wg;
544  if (col >= numCols) {
545  m_leftMargin = margin; // reset back to original value
546  col = 0;
547  row++;
548  m_yOffset += h + hg;
549  if (row >= numRows) {
550  m_yOffset = m_topMargin;
551  row = 0;
552  createNewPage();
553  }
554  }
555  } while (mydata->moveNext());
556  }
557  }
558 
559  } else {
560  // Normal Print Run
561  if (m_reportDocument->section(KReportSectionData::Type::ReportHeader)) {
562  renderSection(*(m_reportDocument->section(KReportSectionData::Type::ReportHeader)));
563  }
564 
565  if (m_reportDocument->detail()) {
566  renderDetailSection(m_reportDocument->detail());
567  }
568 
569  if (m_reportDocument->section(KReportSectionData::Type::ReportFooter)) {
570  if (renderSectionSize(*(m_reportDocument->section(KReportSectionData::Type::ReportFooter))) + finishCurPageSize(true) + m_bottomMargin + m_yOffset >= m_maxHeight) {
571  createNewPage();
572  }
573  renderSection(*(m_reportDocument->section(KReportSectionData::Type::ReportFooter)));
574  }
575  }
576  finishCurPage(true);
577 
578  #ifdef KREPORT_SCRIPTING
579  // _postProcText contains those text boxes that need to be updated
580  // with information that wasn't available at the time it was added to the document
581  m_scriptHandler->setPageTotal(m_document->pageCount());
582 
583  for (int i = 0; i < m_postProcText.size(); i++) {
584  OROTextBox * tb = m_postProcText.at(i);
585 
586  m_scriptHandler->setPageNumber(tb->page()->pageNumber() + 1);
587 
588  tb->setText(m_scriptHandler->evaluate(tb->text()).toString());
589  }
590  #endif
591 
592  asyncManager->startRendering();
593 
594  #ifdef KREPORT_SCRIPTING
595  m_scriptHandler->displayErrors();
596  #endif
597 
598  if (!m_dataSource->close()) {
599  return false;
600  }
601  #ifdef KREPORT_SCRIPTING
602  delete m_scriptHandler;
603  m_scriptHandler = nullptr;
604  #endif
605 
606  if (m_dataSource != m_oneRecord) {
607  delete m_dataSource;
608  m_dataSource = nullptr;
609  }
610  m_postProcText.clear();
611 
612  return true;
613 }
614 
615 //===========================KReportPreRenderer===============================
616 
617 KReportPreRenderer::KReportPreRenderer(const QDomElement &document) : d(new KReportPreRendererPrivate(this))
618 {
619  setDocument(document);
620  connect(d, &KReportPreRendererPrivate::finishedAllASyncItems, this, &KReportPreRenderer::finishedAllASyncItems);
621 }
622 
623 KReportPreRenderer::~KReportPreRenderer()
624 {
625  delete d;
626 }
627 
629 {
630  d->m_reportDocument->setName(n);
631 }
632 
633 bool KReportPreRenderer::isValid() const
634 {
635  if (d && d->m_valid)
636  return true;
637  return false;
638 }
639 
640 ORODocument* KReportPreRenderer::document()
641 {
642  return d->m_document;
643 }
644 
645 bool KReportPreRenderer::generateDocument()
646 {
647 // delete d->m_document;
648  if (!d->generateDocument()) {
649  delete d->m_document;
650  d->m_document = nullptr;
651  }
652  return d->m_document;
653 }
654 
656 {
657  if (d && dataSource != d->m_dataSource) {
658  delete d->m_dataSource;
659  d->m_dataSource = dataSource;
660  }
661 }
662 
663 bool KReportPreRenderer::setDocument(const QDomElement &document)
664 {
665  delete d->m_document;
666  d->m_valid = false;
667 
668  if (document.tagName() != QLatin1String("report:content")) {
669  kreportWarning() << "report schema is invalid";
670  return false;
671  }
672 
673  d->m_reportDocument = new KReportDocument(document);
674  d->m_valid = d->m_reportDocument->isValid();
675  return isValid();
676 }
677 
678 #ifdef KREPORT_SCRIPTING
679 void KReportPreRenderer::setScriptSource(KReportScriptSource *source)
680 {
681  if (d) {
682  d->scriptSource = source;
683  }
684 }
685 
686 void KReportPreRenderer::registerScriptObject(QObject* obj, const QString& name)
687 {
688  //kreportDebug() << name;
689  d->m_scriptObjects[name] = obj;
690 }
691 
692 KReportScriptHandler *KReportPreRenderer::scriptHandler()
693 {
694  return d->m_scriptHandler;
695 }
696 #endif
697 
698 const KReportDocument* KReportPreRenderer::reportData() const
699 {
700  return d->m_reportDocument;
701 }
void append(const T &value)
Base class for items that are drawn syncronously.
bool isNull() const const
qreal height() const const
virtual int renderSimpleData(OROPage *page, OROSection *section, const QPointF &offset, const QVariant &data, KReportScriptHandler *script)
Render the item into a primitive which is used by the second stage renderer.
A text box primitive it defines a box region and text that will be rendered inside that region,...
virtual bool moveNext()=0
Move to the next record.
void setName(const QString &)
Set the name of the report so that it can be used internally by the script engine.
QString tagName() const const
int count(const T &value) const const
T value() const const
Takes a report definition and prerenders the result to an ORODocument that can be used to pass to any...
virtual int renderReportData(OROPage *page, OROSection *section, const QPointF &offset, KReportDataSource *dataSource, KReportScriptHandler *script)
Render a complex item that uses a sub query as a data source.
void setDataSource(KReportDataSource *dataSource)
Sets data source to data, takes ownership.
int width() const const
KReportSectionData is used to store the information about a specific report section.
Represents a single page in a document and may contain zero or more OROPrimitive objects all of which...
Defines a rectangle.
int size() const const
virtual bool moveFirst()=0
Move to the first record.
Represents a single document containing one or more OROPage elements.
const T & at(int i) const const
Abstraction of report data source.
Q_SCRIPTABLE CaptureState status()
T & last()
QString itemDataSource() const
QString label(StandardShortcut id)
Represents a single a single row in a document and may contain zero or more OROPrimitives.
QRect fullRectPoints() const const
Abstraction of report script source.
QString name(StandardShortcut id)
Represents the basic primitive with a position and type. Other primitives are subclasses with a defin...
QAction * lastPage(const QObject *recvr, const char *slot, QObject *parent)
virtual qint64 recordCount() const =0
Return the total number of records.
Base class for items that are drawn asyncronously due to unknown loading times.
Top level report document definition. A KReportDocment defines the design of a document,...
T value(int i) const const
virtual bool supportsSubQuery() const
Override if the item uses a sub query and linked fields, such as a chart or sub-report.
qreal width() const const
KREPORT_EXPORT QPageSize::PageSizeId pageSize(const QString &key)
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Feb 7 2023 04:17:37 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.