KReport

KReportPreRenderer.cpp
1/* This file is part of the KDE project
2 * Copyright (C) 2001-2007 by OpenMFG, LLC (info@openmfg.com)
3 * Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk)
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
42KReportPreRendererPrivate::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
64KReportPreRendererPrivate::~KReportPreRendererPrivate()
65{
66 delete m_reportDocument;
67 delete m_document;
68 delete m_oneRecord;
69 m_postProcText.clear();
70}
71
72void 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
106qreal 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
125qreal 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
157void 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
292qreal 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
319qreal 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, 0);
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
380void 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
393void KReportPreRendererPrivate::asyncItemsFinished()
394{
395 //kreportDebug() << "Finished rendering async items";
396 asyncManager->deleteLater();
397 emit finishedAllASyncItems();
398}
399
400bool 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
617KReportPreRenderer::KReportPreRenderer(const QDomElement &document) : d(new KReportPreRendererPrivate(this))
618{
619 setDocument(document);
620 connect(d, &KReportPreRendererPrivate::finishedAllASyncItems, this, &KReportPreRenderer::finishedAllASyncItems);
621}
622
623KReportPreRenderer::~KReportPreRenderer()
624{
625 delete d;
626}
627
629{
630 d->m_reportDocument->setName(n);
631}
632
633bool KReportPreRenderer::isValid() const
634{
635 if (d && d->m_valid)
636 return true;
637 return false;
638}
639
640ORODocument* KReportPreRenderer::document()
641{
642 return d->m_document;
643}
644
645bool 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
663bool 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
679void KReportPreRenderer::setScriptSource(KReportScriptSource *source)
680{
681 if (d) {
682 d->scriptSource = source;
683 }
684}
685
686void KReportPreRenderer::registerScriptObject(QObject* obj, const QString& name)
687{
688 //kreportDebug() << name;
689 d->m_scriptObjects[name] = obj;
690}
691
692KReportScriptHandler *KReportPreRenderer::scriptHandler()
693{
694 return d->m_scriptHandler;
695}
696#endif
697
698const KReportDocument* KReportPreRenderer::reportData() const
699{
700 return d->m_reportDocument;
701}
Base class for items that are drawn asyncronously due to unknown loading times.
Abstraction of report data source.
virtual bool moveNext()=0
Move to the next record.
virtual qint64 recordCount() const =0
Return the total number of records.
virtual bool moveFirst()=0
Move to the first record.
Top level report document definition. A KReportDocment defines the design of a document,...
Base class for items that are drawn syncronously.
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.
virtual bool supportsSubQuery() const
Override if the item uses a sub query and linked fields, such as a chart or sub-report.
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.
QString itemDataSource() const
Takes a report definition and prerenders the result to an ORODocument that can be used to pass to any...
void setName(const QString &)
Set the name of the report so that it can be used internally by the script engine.
void setDataSource(KReportDataSource *dataSource)
Sets data source to data, takes ownership.
Abstraction of report script source.
KReportSectionData is used to store the information about a specific report section.
Represents a single document containing one or more OROPage elements.
Represents a single page in a document and may contain zero or more OROPrimitive objects all of which...
Represents the basic primitive with a position and type. Other primitives are subclasses with a defin...
Defines a rectangle.
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,...
Q_SCRIPTABLE CaptureState status()
KREPORT_EXPORT QPageSize::PageSizeId pageSize(const QString &key)
QAction * lastPage(const QObject *recvr, const char *slot, QObject *parent)
QString name(StandardAction id)
QString label(StandardShortcut id)
QString tagName() const const
void append(QList< T > &&value)
const_reference at(qsizetype i) const const
qsizetype count() const const
T & last()
qsizetype size() const const
T value(qsizetype i) const const
qreal height() const const
qreal width() const const
bool isNull() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
T value() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 17:06:04 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.