File indexing completed on 2024-05-05 04:43:22
0001 /* This file is part of the KDE project 0002 * Copyright (C) 2001-2007 by OpenMFG, LLC (info@openmfg.com) 0003 * Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk) 0004 * 0005 * This library is free software; you can redistribute it and/or 0006 * modify it under the terms of the GNU Lesser General Public 0007 * License as published by the Free Software Foundation; either 0008 * version 2.1 of the License, or (at your option) any later version. 0009 * 0010 * This library is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 * Lesser General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU Lesser General Public 0016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 0017 */ 0018 0019 #include "KReportPreRenderer.h" 0020 #include "KReportPreRenderer_p.h" 0021 #include "KReportAsyncItemManager_p.h" 0022 #include "KReportOneRecordDataSource_p.h" 0023 0024 #include "KReportRenderObjects.h" 0025 #include "KReportDataSource.h" 0026 #include "KReportItemBase.h" 0027 #include "KReportDocument.h" 0028 #include "KReportDetailSectionData.h" 0029 #include "KReportLabelSizeInfo.h" 0030 #include "KReportPageSize.h" 0031 #include "KReportUtils_p.h" 0032 0033 #ifdef KREPORT_SCRIPTING 0034 #include "KReportScriptHandler.h" 0035 #include "KReportGroupTracker.h" 0036 #endif 0037 0038 #include <QDomElement> 0039 #include <QApplication> 0040 #include "kreport_debug.h" 0041 0042 KReportPreRendererPrivate::KReportPreRendererPrivate(KReportPreRenderer *preRenderer) 0043 : m_preRenderer(preRenderer) 0044 { 0045 m_valid = false; 0046 m_document = nullptr; 0047 m_reportDocument = nullptr; 0048 m_page = nullptr; 0049 m_yOffset = 0.0; 0050 m_topMargin = m_bottomMargin = 0.0; 0051 m_leftMargin = m_rightMargin = 0.0; 0052 m_pageCounter = 0; 0053 m_maxHeight = m_maxWidth = 0.0; 0054 m_oneRecord = new KReportPrivate::OneRecordDataSource(); 0055 m_dataSource = nullptr; 0056 #ifdef KREPORT_SCRIPTING 0057 m_scriptHandler = nullptr; 0058 #endif 0059 asyncManager = new KReportPrivate::AsyncItemManager(this); 0060 0061 connect(asyncManager, SIGNAL(finished()), this, SLOT(asyncItemsFinished())); 0062 } 0063 0064 KReportPreRendererPrivate::~KReportPreRendererPrivate() 0065 { 0066 delete m_reportDocument; 0067 delete m_document; 0068 delete m_oneRecord; 0069 m_postProcText.clear(); 0070 } 0071 0072 void KReportPreRendererPrivate::createNewPage() 0073 { 0074 //kreportDebug(); 0075 if (m_pageCounter > 0) 0076 finishCurPage(false); 0077 0078 m_pageCounter++; 0079 0080 #ifdef KREPORT_SCRIPTING 0081 //Update the page count script value 0082 m_scriptHandler->setPageNumber(m_pageCounter); 0083 m_scriptHandler->newPage(); 0084 #endif 0085 0086 m_page = new OROPage(nullptr); 0087 m_document->addPage(m_page); 0088 0089 //! @todo calculate past page 0090 bool lastPage = false; 0091 0092 m_yOffset = m_topMargin; 0093 0094 if (m_pageCounter == 1 && m_reportDocument->section(KReportSectionData::Type::PageHeaderFirst)) 0095 renderSection(*(m_reportDocument->section(KReportSectionData::Type::PageHeaderFirst))); 0096 else if (lastPage == true && m_reportDocument->section(KReportSectionData::Type::PageHeaderLast)) 0097 renderSection(*(m_reportDocument->section(KReportSectionData::Type::PageHeaderLast))); 0098 else if ((m_pageCounter % 2) == 1 && m_reportDocument->section(KReportSectionData::Type::PageHeaderOdd)) 0099 renderSection(*(m_reportDocument->section(KReportSectionData::Type::PageHeaderOdd))); 0100 else if ((m_pageCounter % 2) == 0 && m_reportDocument->section(KReportSectionData::Type::PageHeaderEven)) 0101 renderSection(*(m_reportDocument->section(KReportSectionData::Type::PageHeaderEven))); 0102 else if (m_reportDocument->section(KReportSectionData::Type::PageHeaderAny)) 0103 renderSection(*(m_reportDocument->section(KReportSectionData::Type::PageHeaderAny))); 0104 } 0105 0106 qreal KReportPreRendererPrivate::finishCurPageSize(bool lastPage) 0107 { 0108 qreal retval = 0.0; 0109 0110 if (lastPage && m_reportDocument->section(KReportSectionData::Type::PageFooterLast)) 0111 retval = renderSectionSize(* (m_reportDocument->section(KReportSectionData::Type::PageFooterLast))); 0112 else if (m_pageCounter == 1 && m_reportDocument->section(KReportSectionData::Type::PageFooterFirst)) 0113 retval = renderSectionSize(* (m_reportDocument->section(KReportSectionData::Type::PageFooterFirst))); 0114 else if ((m_pageCounter % 2) == 1 && m_reportDocument->section(KReportSectionData::Type::PageFooterOdd)) 0115 retval = renderSectionSize(* (m_reportDocument->section(KReportSectionData::Type::PageFooterOdd))); 0116 else if ((m_pageCounter % 2) == 0 && m_reportDocument->section(KReportSectionData::Type::PageFooterEven)) 0117 retval = renderSectionSize(* (m_reportDocument->section(KReportSectionData::Type::PageFooterEven))); 0118 else if (m_reportDocument->section(KReportSectionData::Type::PageFooterAny)) 0119 retval = renderSectionSize(* (m_reportDocument->section(KReportSectionData::Type::PageFooterAny))); 0120 0121 //kreportDebug() << retval; 0122 return retval; 0123 } 0124 0125 qreal KReportPreRendererPrivate::finishCurPage(bool lastPage) 0126 { 0127 0128 qreal offset = m_maxHeight - m_bottomMargin; 0129 qreal retval = 0.0; 0130 //kreportDebug() << offset; 0131 0132 if (lastPage && m_reportDocument->section(KReportSectionData::Type::PageFooterLast)) { 0133 //kreportDebug() << "Last Footer"; 0134 m_yOffset = offset - renderSectionSize(* (m_reportDocument->section(KReportSectionData::Type::PageFooterLast))); 0135 retval = renderSection(* (m_reportDocument->section(KReportSectionData::Type::PageFooterLast))); 0136 } else if (m_pageCounter == 1 && m_reportDocument->section(KReportSectionData::Type::PageFooterFirst)) { 0137 //kreportDebug() << "First Footer"; 0138 m_yOffset = offset - renderSectionSize(* (m_reportDocument->section(KReportSectionData::Type::PageFooterFirst))); 0139 retval = renderSection(* (m_reportDocument->section(KReportSectionData::Type::PageFooterFirst))); 0140 } else if ((m_pageCounter % 2) == 1 && m_reportDocument->section(KReportSectionData::Type::PageFooterOdd)) { 0141 //kreportDebug() << "Odd Footer"; 0142 m_yOffset = offset - renderSectionSize(* (m_reportDocument->section(KReportSectionData::Type::PageFooterOdd))); 0143 retval = renderSection(* (m_reportDocument->section(KReportSectionData::Type::PageFooterOdd))); 0144 } else if ((m_pageCounter % 2) == 0 && m_reportDocument->section(KReportSectionData::Type::PageFooterEven)) { 0145 //kreportDebug() << "Even Footer"; 0146 m_yOffset = offset - renderSectionSize(* (m_reportDocument->section(KReportSectionData::Type::PageFooterEven))); 0147 retval = renderSection(* (m_reportDocument->section(KReportSectionData::Type::PageFooterEven))); 0148 } else if (m_reportDocument->section(KReportSectionData::Type::PageFooterAny)) { 0149 //kreportDebug() << "Any Footer"; 0150 m_yOffset = offset - renderSectionSize(* (m_reportDocument->section(KReportSectionData::Type::PageFooterAny))); 0151 retval = renderSection(* (m_reportDocument->section(KReportSectionData::Type::PageFooterAny))); 0152 } 0153 0154 return retval; 0155 } 0156 0157 void KReportPreRendererPrivate::renderDetailSection(KReportDetailSectionData *detailData) 0158 { 0159 if (detailData->detailSection) { 0160 if (m_dataSource/* && !curs->eof()*/) { 0161 QStringList keys; 0162 QStringList keyValues; 0163 QList<int> shownGroups; 0164 KReportDetailGroupSectionData * grp = nullptr; 0165 0166 bool status = m_dataSource->moveFirst(); 0167 int recordCount = m_dataSource->recordCount(); 0168 0169 //kreportDebug() << "Record Count:" << recordCount; 0170 0171 for (int i = 0; i < (int) detailData->groupList.count(); ++i) { 0172 grp = detailData->groupList[i]; 0173 //If the group has a header or footer, then emit a change of group value 0174 if(grp->groupFooter || grp->groupHeader) { 0175 // we get here only if group is *shown* 0176 shownGroups << i; 0177 keys.append(grp->column); 0178 if (!keys.last().isEmpty()) 0179 keyValues.append(m_dataSource->value(m_dataSource->fieldNumber(keys.last())).toString()); 0180 else 0181 keyValues.append(QString()); 0182 0183 //Tell interested parties we're about to render a header 0184 emit(enteredGroup(keys.last(), keyValues.last())); 0185 } 0186 if (grp->groupHeader) 0187 renderSection(*(grp->groupHeader)); 0188 } 0189 0190 while (status) { 0191 const qint64 pos = m_dataSource->at(); 0192 //kreportDebug() << "At:" << l << "Y:" << m_yOffset << "Max Height:" << m_maxHeight; 0193 if ((renderSectionSize(*detailData->detailSection) 0194 + finishCurPageSize((pos + 1 == recordCount)) 0195 + m_bottomMargin + m_yOffset) >= m_maxHeight) 0196 { 0197 //kreportDebug() << "Next section is too big for this page"; 0198 if (pos > 0) { 0199 m_dataSource->movePrevious(); 0200 createNewPage(); 0201 m_dataSource->moveNext(); 0202 } 0203 } 0204 0205 renderSection(*(detailData->detailSection)); 0206 status = m_dataSource->moveNext(); 0207 0208 if (status == true && keys.count() > 0) { 0209 // check to see where it is we need to start 0210 int pos = -1; // if it's still -1 by the time we are done then no keyValues changed 0211 for (int i = 0; i < keys.count(); ++i) { 0212 if (keyValues[i] != m_dataSource->value(m_dataSource->fieldNumber(keys[i])).toString()) { 0213 pos = i; 0214 break; 0215 } 0216 } 0217 // don't bother if nothing has changed 0218 if (pos != -1) { 0219 // roll back the query and go ahead if all is good 0220 status = m_dataSource->movePrevious(); 0221 if (status == true) { 0222 // print the footers as needed 0223 // any changes made in this for loop need to be duplicated 0224 // below where the footers are finished. 0225 bool do_break = false; 0226 for (int i = shownGroups.count() - 1; i >= 0; i--) { 0227 if (do_break) 0228 createNewPage(); 0229 do_break = false; 0230 grp = detailData->groupList[shownGroups.at(i)]; 0231 0232 if (grp->groupFooter) { 0233 if (renderSectionSize(*(grp->groupFooter)) + finishCurPageSize(false) + m_bottomMargin + m_yOffset >= m_maxHeight) 0234 createNewPage(); 0235 renderSection(*(grp->groupFooter)); 0236 } 0237 0238 if (KReportDetailGroupSectionData::PageBreak::AfterGroupFooter == grp->pagebreak) 0239 do_break = true; 0240 } 0241 // step ahead to where we should be and print the needed headers 0242 // if all is good 0243 status = m_dataSource->moveNext(); 0244 if (do_break) 0245 createNewPage(); 0246 if (status == true) { 0247 for (int i = 0; i < shownGroups.count(); ++i) { 0248 grp = detailData->groupList[shownGroups.at(i)]; 0249 0250 if (grp->groupHeader) { 0251 if (renderSectionSize(*(grp->groupHeader)) + finishCurPageSize(false) + m_bottomMargin + m_yOffset >= m_maxHeight) { 0252 m_dataSource->movePrevious(); 0253 createNewPage(); 0254 m_dataSource->moveNext(); 0255 } 0256 0257 if (!keys[i].isEmpty()) 0258 keyValues[i] = m_dataSource->value(m_dataSource->fieldNumber(keys[i])).toString(); 0259 0260 //Tell interested parties thak key values changed 0261 renderSection(*(grp->groupHeader)); 0262 } 0263 0264 0265 } 0266 } 0267 } 0268 } 0269 } 0270 } 0271 0272 if (keys.size() > 0 && m_dataSource->movePrevious()) { 0273 // finish footers 0274 // duplicated changes from above here 0275 for (int i = shownGroups.count() - 1; i >= 0; i--) { 0276 grp = detailData->groupList[shownGroups.at(i)]; 0277 0278 if (grp->groupFooter) { 0279 if (renderSectionSize(*(grp->groupFooter)) + finishCurPageSize(false) + m_bottomMargin + m_yOffset >= m_maxHeight) 0280 createNewPage(); 0281 renderSection(*(grp->groupFooter)); 0282 emit(exitedGroup(keys[i], keyValues[i])); 0283 } 0284 } 0285 } 0286 } 0287 if (KReportDetailSectionData::PageBreak::AtEnd == detailData->pageBreak) 0288 createNewPage(); 0289 } 0290 } 0291 0292 qreal KReportPreRendererPrivate::renderSectionSize(const KReportSectionData & sectionData) 0293 { 0294 qreal intHeight = POINT_TO_INCH(sectionData.height()) * KReportPrivate::dpiX(); 0295 0296 if (sectionData.objects().count() == 0) 0297 return intHeight; 0298 0299 QList<KReportItemBase*> objects = sectionData.objects(); 0300 foreach(KReportItemBase *ob, objects) { 0301 QPointF offset(m_leftMargin, m_yOffset); 0302 //ASync objects cannot alter the section height 0303 KReportAsyncItemBase *async_ob = qobject_cast<KReportAsyncItemBase*>(ob); 0304 if (!async_ob) { 0305 QVariant itemData; 0306 if (m_dataSource) { 0307 itemData = m_dataSource->value(ob->itemDataSource()); 0308 } 0309 const int itemHeight = ob->renderSimpleData(nullptr, nullptr, offset, itemData, m_scriptHandler); 0310 if (itemHeight > intHeight) { 0311 intHeight = itemHeight; 0312 } 0313 } 0314 } 0315 0316 return intHeight; 0317 } 0318 0319 qreal KReportPreRendererPrivate::renderSection(const KReportSectionData & sectionData) 0320 { 0321 qreal sectionHeight = POINT_TO_INCH(sectionData.height()) * KReportPrivate::dpiX(); 0322 0323 int itemHeight = 0; 0324 //kreportDebug() << "Name: " << sectionData.name() << " Height: " << sectionHeight 0325 // << "Objects: " << sectionData.objects().count(); 0326 emit(renderingSection(const_cast<KReportSectionData*>(§ionData), m_page, QPointF(m_leftMargin, m_yOffset))); 0327 0328 //Create a pre-rendered section for this section and add it to the document 0329 OROSection *sec = new OROSection(m_document); 0330 sec->setHeight(sectionData.height()); 0331 sec->setBackgroundColor(sectionData.backgroundColor()); 0332 sec->setType(sectionData.type()); 0333 m_document->addSection(sec); 0334 0335 //Render section background 0336 ORORect* bg = new ORORect(); 0337 bg->setPen(QPen(Qt::NoPen)); 0338 bg->setBrush(sectionData.backgroundColor()); 0339 qreal w = m_page->document()->pageLayout().fullRectPixels(KReportPrivate::dpiX()).width() - m_page->document()->pageLayout().marginsPixels(KReportPrivate::dpiX()).right() - m_leftMargin; 0340 0341 bg->setRect(QRectF(m_leftMargin, m_yOffset, w, sectionHeight)); 0342 m_page->insertPrimitive(bg, 0); 0343 0344 QList<KReportItemBase*> objects = sectionData.objects(); 0345 foreach(KReportItemBase *ob, objects) { 0346 QPointF offset(m_leftMargin, m_yOffset); 0347 QVariant itemData = m_dataSource->value(ob->itemDataSource()); 0348 0349 if (ob->supportsSubQuery()) { 0350 itemHeight = ob->renderReportData(m_page, sec, offset, m_dataSource, m_scriptHandler); 0351 } else { 0352 KReportAsyncItemBase *async_ob = qobject_cast<KReportAsyncItemBase*>(ob); 0353 if (async_ob){ 0354 //kreportDebug() << "async object"; 0355 asyncManager->addItem(async_ob, m_page, sec, offset, async_ob->realItemData(itemData), m_scriptHandler); 0356 } else { 0357 //kreportDebug() << "sync object"; 0358 itemHeight = ob->renderSimpleData(m_page, sec, offset, itemData, m_scriptHandler); 0359 } 0360 } 0361 0362 if (itemHeight > sectionHeight) { 0363 sectionHeight = itemHeight; 0364 } 0365 } 0366 for (int i = 0; i < m_page->primitiveCount(); ++i) { 0367 OROPrimitive *prim = m_page->primitive(i); 0368 if (OROTextBox *text = dynamic_cast<OROTextBox*>(prim)) { 0369 if (text->requiresPostProcessing()) { 0370 m_postProcText.append(text); 0371 } 0372 } 0373 } 0374 m_yOffset += sectionHeight; 0375 0376 return sectionHeight; 0377 } 0378 0379 #ifdef KREPORT_SCRIPTING 0380 void KReportPreRendererPrivate::initEngine() 0381 { 0382 delete m_scriptHandler; 0383 m_scriptHandler = new KReportScriptHandler(m_dataSource, scriptSource, m_reportDocument); 0384 0385 connect(this, SIGNAL(enteredGroup(QString,QVariant)), m_scriptHandler, SLOT(slotEnteredGroup(QString,QVariant))); 0386 0387 connect(this, SIGNAL(exitedGroup(QString,QVariant)), m_scriptHandler, SLOT(slotExitedGroup(QString,QVariant))); 0388 0389 connect(this, SIGNAL(renderingSection(KReportSectionData*,OROPage*,QPointF)), m_scriptHandler, SLOT(slotEnteredSection(KReportSectionData*,OROPage*,QPointF))); 0390 } 0391 #endif 0392 0393 void KReportPreRendererPrivate::asyncItemsFinished() 0394 { 0395 //kreportDebug() << "Finished rendering async items"; 0396 asyncManager->deleteLater(); 0397 emit finishedAllASyncItems(); 0398 } 0399 0400 bool KReportPreRendererPrivate::generateDocument() 0401 { 0402 if (!m_dataSource) { 0403 m_dataSource = m_oneRecord; 0404 } 0405 0406 if (!m_valid || !m_reportDocument) { 0407 return false; 0408 } 0409 0410 // Do this check now so we don't have to undo a lot of work later if it fails 0411 KReportLabelSizeInfo label; 0412 if (m_reportDocument->pageSize() == QLatin1String("Labels")) { 0413 label = KReportLabelSizeInfo::find(m_reportDocument->labelType()); 0414 if (label.isNull()) { 0415 return false; 0416 } 0417 } 0418 //kreportDebug() << "Creating Document"; 0419 m_document = new ORODocument(m_reportDocument->title()); 0420 0421 m_pageCounter = 0; 0422 m_yOffset = 0.0; 0423 0424 //kreportDebug() << "Calculating Margins"; 0425 if (!label.isNull()) { 0426 if (m_reportDocument->pageLayout().orientation() == QPageLayout::Portrait) { 0427 m_topMargin = (label.startY() / 100.0); 0428 m_bottomMargin = 0; 0429 m_rightMargin = 0; 0430 m_leftMargin = (label.startX() / 100.0); 0431 } else { 0432 m_topMargin = (label.startX() / 100.0); 0433 m_bottomMargin = 0; 0434 m_rightMargin = 0; 0435 m_leftMargin = (label.startY() / 100.0); 0436 } 0437 } else { 0438 0439 m_topMargin = m_reportDocument->pageLayout().marginsPoints().top(); 0440 m_bottomMargin = m_reportDocument->pageLayout().marginsPoints().bottom(); 0441 m_rightMargin = m_reportDocument->pageLayout().marginsPoints().right(); 0442 m_leftMargin = m_reportDocument->pageLayout().marginsPoints().left(); 0443 //kreportDebug() << "Margins:" << m_topMargin << m_bottomMargin << m_rightMargin << m_leftMargin; 0444 } 0445 0446 //kreportDebug() << "Calculating Page Size"; 0447 QPageLayout layout = m_reportDocument->pageLayout(); 0448 // This should reflect the information of the report page size 0449 if (m_reportDocument->pageSize() == QLatin1String("Custom")) { 0450 m_maxWidth = m_reportDocument->pageLayout().fullRectPoints().width(); 0451 m_maxHeight = m_reportDocument->pageLayout().fullRectPoints().height(); 0452 } else { 0453 if (!label.isNull()) { 0454 m_maxWidth = label.width(); 0455 m_maxHeight = label.height(); 0456 m_reportDocument->pageLayout().setPageSize(QPageSize(KReportPageSize::pageSize(label.paper()))); 0457 } else { 0458 // lookup the correct size information for the specified size paper 0459 QSizeF pageSizePx = m_reportDocument->pageLayout().fullRectPixels(KReportPrivate::dpiX()).size(); 0460 0461 m_maxWidth = pageSizePx.width(); 0462 m_maxHeight = pageSizePx.height(); 0463 } 0464 } 0465 0466 if (m_reportDocument->pageLayout().orientation() == QPageLayout::Landscape) { 0467 qreal tmp = m_maxWidth; 0468 m_maxWidth = m_maxHeight; 0469 m_maxHeight = tmp; 0470 } 0471 0472 //kreportDebug() << "Page Size:" << m_maxWidth << m_maxHeight; 0473 0474 m_document->setPageLayout(m_reportDocument->pageLayout()); 0475 m_dataSource->setSorting(m_reportDocument->detail()->sortedFields); 0476 if (!m_dataSource->open()) { 0477 return false; 0478 } 0479 0480 #ifdef KREPORT_SCRIPTING 0481 initEngine(); 0482 connect(m_scriptHandler, SIGNAL(groupChanged(QMap<QString, QVariant>)), 0483 m_preRenderer, SIGNAL(groupChanged(QMap<QString, QVariant>))); 0484 0485 //Loop through all abjects that have been registered, and register them with the script handler 0486 if (m_scriptHandler) { 0487 QMapIterator<QString, QObject*> i(m_scriptObjects); 0488 while (i.hasNext()) { 0489 i.next(); 0490 m_scriptHandler->registerScriptObject(i.value(), i.key()); 0491 } 0492 //execute the script, if it fails, abort and return the empty document 0493 if (!m_scriptHandler->trigger()) { 0494 m_scriptHandler->displayErrors(); 0495 return m_document; 0496 } 0497 } 0498 #endif 0499 0500 createNewPage(); 0501 if (!label.isNull()) { 0502 // Label Print Run 0503 // remember the initial margin setting as we will be modifying 0504 // the value and restoring it as we move around 0505 qreal margin = m_leftMargin; 0506 0507 m_yOffset = m_topMargin; 0508 0509 qreal w = (label.width() / 100.0); 0510 qreal wg = (label.xGap() / 100.0); 0511 qreal h = (label.height() / 100.0); 0512 qreal hg = (label.yGap() / 100.0); 0513 int numCols = label.columns(); 0514 int numRows = label.rows(); 0515 qreal tmp; 0516 0517 // flip the value around if we are printing landscape 0518 if (!(m_reportDocument->pageLayout().orientation() == QPageLayout::Portrait)) { 0519 w = (label.height() / 100.0); 0520 wg = (label.yGap() / 100.0); 0521 h = (label.width() / 100.0); 0522 hg = (label.xGap() / 100.0); 0523 numCols = label.rows(); 0524 numRows = label.columns(); 0525 } 0526 0527 KReportDetailSectionData * detailData = m_reportDocument->detail(); 0528 if (detailData->detailSection) { 0529 KReportDataSource *mydata = m_dataSource; 0530 0531 if (mydata && mydata->recordCount() > 0) { /* && !((query = orqThis->getQuery())->eof()))*/ 0532 if (!mydata->moveFirst()) { 0533 return false; 0534 } 0535 int row = 0; 0536 int col = 0; 0537 do { 0538 tmp = m_yOffset; // store the value as renderSection changes it 0539 renderSection(*(detailData->detailSection)); 0540 m_yOffset = tmp; // restore the value that renderSection modified 0541 0542 col++; 0543 m_leftMargin += w + wg; 0544 if (col >= numCols) { 0545 m_leftMargin = margin; // reset back to original value 0546 col = 0; 0547 row++; 0548 m_yOffset += h + hg; 0549 if (row >= numRows) { 0550 m_yOffset = m_topMargin; 0551 row = 0; 0552 createNewPage(); 0553 } 0554 } 0555 } while (mydata->moveNext()); 0556 } 0557 } 0558 0559 } else { 0560 // Normal Print Run 0561 if (m_reportDocument->section(KReportSectionData::Type::ReportHeader)) { 0562 renderSection(*(m_reportDocument->section(KReportSectionData::Type::ReportHeader))); 0563 } 0564 0565 if (m_reportDocument->detail()) { 0566 renderDetailSection(m_reportDocument->detail()); 0567 } 0568 0569 if (m_reportDocument->section(KReportSectionData::Type::ReportFooter)) { 0570 if (renderSectionSize(*(m_reportDocument->section(KReportSectionData::Type::ReportFooter))) + finishCurPageSize(true) + m_bottomMargin + m_yOffset >= m_maxHeight) { 0571 createNewPage(); 0572 } 0573 renderSection(*(m_reportDocument->section(KReportSectionData::Type::ReportFooter))); 0574 } 0575 } 0576 finishCurPage(true); 0577 0578 #ifdef KREPORT_SCRIPTING 0579 // _postProcText contains those text boxes that need to be updated 0580 // with information that wasn't available at the time it was added to the document 0581 m_scriptHandler->setPageTotal(m_document->pageCount()); 0582 0583 for (int i = 0; i < m_postProcText.size(); i++) { 0584 OROTextBox * tb = m_postProcText.at(i); 0585 0586 m_scriptHandler->setPageNumber(tb->page()->pageNumber() + 1); 0587 0588 tb->setText(m_scriptHandler->evaluate(tb->text()).toString()); 0589 } 0590 #endif 0591 0592 asyncManager->startRendering(); 0593 0594 #ifdef KREPORT_SCRIPTING 0595 m_scriptHandler->displayErrors(); 0596 #endif 0597 0598 if (!m_dataSource->close()) { 0599 return false; 0600 } 0601 #ifdef KREPORT_SCRIPTING 0602 delete m_scriptHandler; 0603 m_scriptHandler = nullptr; 0604 #endif 0605 0606 if (m_dataSource != m_oneRecord) { 0607 delete m_dataSource; 0608 m_dataSource = nullptr; 0609 } 0610 m_postProcText.clear(); 0611 0612 return true; 0613 } 0614 0615 //===========================KReportPreRenderer=============================== 0616 0617 KReportPreRenderer::KReportPreRenderer(const QDomElement &document) : d(new KReportPreRendererPrivate(this)) 0618 { 0619 setDocument(document); 0620 connect(d, &KReportPreRendererPrivate::finishedAllASyncItems, this, &KReportPreRenderer::finishedAllASyncItems); 0621 } 0622 0623 KReportPreRenderer::~KReportPreRenderer() 0624 { 0625 delete d; 0626 } 0627 0628 void KReportPreRenderer::setName(const QString &n) 0629 { 0630 d->m_reportDocument->setName(n); 0631 } 0632 0633 bool KReportPreRenderer::isValid() const 0634 { 0635 if (d && d->m_valid) 0636 return true; 0637 return false; 0638 } 0639 0640 ORODocument* KReportPreRenderer::document() 0641 { 0642 return d->m_document; 0643 } 0644 0645 bool KReportPreRenderer::generateDocument() 0646 { 0647 // delete d->m_document; 0648 if (!d->generateDocument()) { 0649 delete d->m_document; 0650 d->m_document = nullptr; 0651 } 0652 return d->m_document; 0653 } 0654 0655 void KReportPreRenderer::setDataSource(KReportDataSource *dataSource) 0656 { 0657 if (d && dataSource != d->m_dataSource) { 0658 delete d->m_dataSource; 0659 d->m_dataSource = dataSource; 0660 } 0661 } 0662 0663 bool KReportPreRenderer::setDocument(const QDomElement &document) 0664 { 0665 delete d->m_document; 0666 d->m_valid = false; 0667 0668 if (document.tagName() != QLatin1String("report:content")) { 0669 kreportWarning() << "report schema is invalid"; 0670 return false; 0671 } 0672 0673 d->m_reportDocument = new KReportDocument(document); 0674 d->m_valid = d->m_reportDocument->isValid(); 0675 return isValid(); 0676 } 0677 0678 #ifdef KREPORT_SCRIPTING 0679 void KReportPreRenderer::setScriptSource(KReportScriptSource *source) 0680 { 0681 if (d) { 0682 d->scriptSource = source; 0683 } 0684 } 0685 0686 void KReportPreRenderer::registerScriptObject(QObject* obj, const QString& name) 0687 { 0688 //kreportDebug() << name; 0689 d->m_scriptObjects[name] = obj; 0690 } 0691 0692 KReportScriptHandler *KReportPreRenderer::scriptHandler() 0693 { 0694 return d->m_scriptHandler; 0695 } 0696 #endif 0697 0698 const KReportDocument* KReportPreRenderer::reportData() const 0699 { 0700 return d->m_reportDocument; 0701 }