File indexing completed on 2024-04-21 04:41:49
0001 /* This file is part of the KDE project 0002 * Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk) 0003 * 0004 * This library is free software; you can redistribute it and/or 0005 * modify it under the terms of the GNU Lesser General Public 0006 * License as published by the Free Software Foundation; either 0007 * version 2.1 of the License, or (at your option) any later version. 0008 * 0009 * This library is distributed in the hope that it will be useful, 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 * Lesser General Public License for more details. 0013 * 0014 * You should have received a copy of the GNU Lesser General Public 0015 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 0016 */ 0017 0018 #include "KReportDocument.h" 0019 #include "KReportUnit.h" 0020 #include "KReportDetailSectionData.h" 0021 #include "KReportItemBase.h" 0022 #include "KReportUtils_p.h" 0023 #include "KReportPageSize.h" 0024 0025 #include <QDomElement> 0026 #include <QApplication> 0027 #include "kreport_debug.h" 0028 0029 class Q_DECL_HIDDEN KReportDocument::Private 0030 { 0031 public: 0032 bool valid; 0033 QString title; 0034 QString name; 0035 QString query; 0036 #ifdef KREPORT_SCRIPTING 0037 QString script; 0038 QString interpreter; 0039 #endif 0040 bool externalData; 0041 KReportPrivate::PageLayout pageLayout; 0042 QString pageSize; 0043 QString labelType; 0044 0045 KReportSectionData * pageHeaderFirst = nullptr; 0046 KReportSectionData * pageHeaderOdd = nullptr; 0047 KReportSectionData * pageHeaderEven = nullptr; 0048 KReportSectionData * pageHeaderLast = nullptr; 0049 KReportSectionData * pageHeaderAny = nullptr; 0050 0051 KReportSectionData * reportHeader = nullptr; 0052 KReportSectionData * reportFooter = nullptr; 0053 0054 KReportSectionData * pageFooterFirst = nullptr; 0055 KReportSectionData * pageFooterOdd = nullptr; 0056 KReportSectionData * pageFooterEven = nullptr; 0057 KReportSectionData * pageFooterLast = nullptr; 0058 KReportSectionData * pageFooterAny = nullptr; 0059 0060 KReportDetailSectionData* detailSection = nullptr; 0061 }; 0062 0063 KReportDocument::KReportDocument(QObject *parent) 0064 : QObject(parent), 0065 d(new Private) 0066 { 0067 d->valid = true; 0068 } 0069 0070 KReportDocument::KReportDocument(const QDomElement & elemSource, QObject *parent) 0071 : QObject(parent), 0072 d(new Private) 0073 { 0074 d->valid = false; 0075 0076 if (elemSource.tagName() != QLatin1String("report:content")) { 0077 kreportWarning() << "QDomElement is not <report:content> tag" 0078 << elemSource.text(); 0079 return; 0080 } 0081 0082 QDomNodeList sections = elemSource.childNodes(); 0083 for (int nodeCounter = 0; nodeCounter < sections.count(); nodeCounter++) { 0084 QDomElement elemThis = sections.item(nodeCounter).toElement(); 0085 if (elemThis.tagName() == QLatin1String("report:title")) { 0086 d->title = elemThis.text(); 0087 #ifdef KREPORT_SCRIPTING 0088 } else if (elemThis.tagName() == QLatin1String("report:script")) { 0089 d->script = elemThis.text(); 0090 d->interpreter = elemThis.attribute(QLatin1String("report:script-interpreter")); 0091 #endif 0092 } else if (elemThis.tagName() == QLatin1String("report:page-style")) { 0093 QString pagetype = elemThis.firstChild().nodeValue(); 0094 0095 //Full page mode is required to allow margins to be set to whatever the user has specified 0096 d->pageLayout.setMode(QPageLayout::FullPageMode); 0097 0098 if (pagetype == QLatin1String("predefined")) { 0099 setPageSize(elemThis.attribute(QLatin1String("report:page-size"), QLatin1String("A4"))); 0100 d->pageLayout.setPageSize(QPageSize(KReportPageSize::pageSize(pageSize()))); 0101 } else if (pagetype == QLatin1String("custom")) { 0102 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"))) ; 0103 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); 0104 0105 d->pageLayout.setPageSize(custom); 0106 } else if (pagetype == QLatin1String("label")) { 0107 setLabelType(elemThis.firstChild().nodeValue()); 0108 } 0109 //! @todo add config for default margins or add within templates support 0110 d->pageLayout.setUnits(QPageLayout::Point); 0111 d->pageLayout.setLeftMargin(KReportUnit::parseValue(elemThis.attribute( 0112 QLatin1String("fo:margin-left"), DEFAULT_PAGE_MARGIN_STRING))); 0113 d->pageLayout.setRightMargin(KReportUnit::parseValue(elemThis.attribute( 0114 QLatin1String("fo:margin-right"), DEFAULT_PAGE_MARGIN_STRING))); 0115 d->pageLayout.setTopMargin(KReportUnit::parseValue(elemThis.attribute( 0116 QLatin1String("fo:margin-top"), DEFAULT_PAGE_MARGIN_STRING))); 0117 d->pageLayout.setBottomMargin(KReportUnit::parseValue(elemThis.attribute( 0118 QLatin1String("fo:margin-bottom"), DEFAULT_PAGE_MARGIN_STRING))); 0119 d->pageLayout.setOrientation( 0120 elemThis.attribute(QLatin1String("report:print-orientation"), 0121 QLatin1String("portrait")) 0122 == QLatin1String("portrait") 0123 ? QPageLayout::Portrait 0124 : QPageLayout::Landscape); 0125 } else if (elemThis.tagName() == QLatin1String("report:body")) { 0126 QDomNodeList sectionlist = elemThis.childNodes(); 0127 QDomNode sec; 0128 0129 for (int s = 0; s < sectionlist.count(); ++s) { 0130 sec = sectionlist.item(s); 0131 if (sec.isElement()) { 0132 QString sn = sec.nodeName().toLower(); 0133 //kreportDebug() << sn; 0134 if (sn == QLatin1String("report:section")) { 0135 KReportSectionData * sd = new KReportSectionData(sec.toElement(), this); 0136 if (!sd->isValid()) { 0137 kreportDebug() << "Invalid section"; 0138 delete sd; 0139 } else { 0140 //kreportDebug() << "Adding section of type " << sd->type(); 0141 switch (sd->type()) { 0142 case KReportSectionData::Type::PageHeaderFirst: 0143 d->pageHeaderFirst = sd; 0144 break; 0145 case KReportSectionData::Type::PageHeaderOdd: 0146 d->pageHeaderOdd = sd; 0147 break; 0148 case KReportSectionData::Type::PageHeaderEven: 0149 d->pageHeaderEven = sd; 0150 break; 0151 case KReportSectionData::Type::PageHeaderLast: 0152 d->pageHeaderLast = sd; 0153 break; 0154 case KReportSectionData::Type::PageHeaderAny: 0155 d->pageHeaderAny = sd; 0156 break; 0157 case KReportSectionData::Type::ReportHeader: 0158 d->reportHeader = sd; 0159 break; 0160 case KReportSectionData::Type::ReportFooter: 0161 d->reportFooter = sd; 0162 break; 0163 case KReportSectionData::Type::PageFooterFirst: 0164 d->pageFooterFirst = sd; 0165 break; 0166 case KReportSectionData::Type::PageFooterOdd: 0167 d->pageFooterOdd = sd; 0168 break; 0169 case KReportSectionData::Type::PageFooterEven: 0170 d->pageFooterEven = sd; 0171 break; 0172 case KReportSectionData::Type::PageFooterLast: 0173 d->pageFooterLast = sd; 0174 break; 0175 case KReportSectionData::Type::PageFooterAny: 0176 d->pageFooterAny = sd; 0177 break; 0178 default: 0179 ; 0180 } 0181 } 0182 0183 } else if (sn == QLatin1String("report:detail")) { 0184 KReportDetailSectionData * dsd = new KReportDetailSectionData(sec.toElement(), this); 0185 0186 if (dsd->isValid()) { 0187 d->detailSection = dsd; 0188 } else { 0189 kreportDebug() << "Invalid detail section"; 0190 delete dsd; 0191 } 0192 } 0193 } else { 0194 kreportWarning() << "Encountered an unknown Element: " << elemThis.tagName(); 0195 } 0196 } 0197 } 0198 0199 d->valid = true; 0200 } 0201 } 0202 0203 KReportDocument::~KReportDocument() 0204 { 0205 delete d; 0206 } 0207 0208 QList<KReportItemBase*> KReportDocument::objects() const 0209 { 0210 QList<KReportItemBase*> obs; 0211 for (int i = static_cast<int>(KReportSectionData::Type::PageHeaderFirst); 0212 i <= static_cast<int>(KReportSectionData::Type::PageFooterAny); i++) 0213 { 0214 KReportSectionData *sec = section(static_cast<KReportSectionData::Type>(i)); 0215 if (sec) { 0216 obs << sec->objects(); 0217 } 0218 } 0219 0220 if (d->detailSection) { 0221 //kreportDebug() << "Number of groups: " << m_detailSection->m_groupList.count(); 0222 foreach(KReportDetailGroupSectionData* g, d->detailSection->groupList) { 0223 if (g->groupHeader) { 0224 obs << g->groupHeader->objects(); 0225 } 0226 if (g->groupFooter) { 0227 obs << g->groupFooter->objects(); 0228 } 0229 } 0230 if (d->detailSection->detailSection) 0231 obs << d->detailSection->detailSection->objects(); 0232 } 0233 0234 /*kreportDebug() << "Object List:"; 0235 foreach(KReportItemBase* o, obs) { 0236 kreportDebug() << o->entityName(); 0237 }*/ 0238 return obs; 0239 } 0240 0241 KReportItemBase* KReportDocument::object(const QString& n) const 0242 { 0243 QList<KReportItemBase*> obs = objects(); 0244 0245 foreach(KReportItemBase* o, obs) { 0246 if (o->entityName() == n) { 0247 return o; 0248 } 0249 } 0250 return nullptr; 0251 } 0252 0253 QList<KReportSectionData*> KReportDocument::sections() const 0254 { 0255 QList<KReportSectionData*> secs; 0256 for (int i = static_cast<int>(KReportSectionData::Type::PageHeaderFirst); 0257 i <= static_cast<int>(KReportSectionData::Type::PageFooterAny); i++) 0258 { 0259 KReportSectionData *sec = section(static_cast<KReportSectionData::Type>(i)); 0260 if (sec) { 0261 secs << sec; 0262 } 0263 } 0264 0265 if (d->detailSection) { 0266 //kreportDebug() << "Number of groups: " << m_detailSection->m_groupList.count(); 0267 foreach(KReportDetailGroupSectionData* g, d->detailSection->groupList) { 0268 if (g->groupHeader) { 0269 secs << g->groupHeader; 0270 } 0271 if (g->groupFooter) { 0272 secs << g->groupFooter; 0273 } 0274 } 0275 if (d->detailSection->detailSection) 0276 secs << d->detailSection->detailSection; 0277 } 0278 0279 return secs; 0280 } 0281 0282 KReportSectionData* KReportDocument::section(const QString& sn) const 0283 { 0284 QList<KReportSectionData*> secs = sections(); 0285 0286 foreach(KReportSectionData *sec, secs) { 0287 if (sec->name() == sn) { 0288 return sec; 0289 } 0290 } 0291 return nullptr; 0292 } 0293 0294 KReportSectionData* KReportDocument::section(KReportSectionData::Type type) const 0295 { 0296 KReportSectionData *sec; 0297 switch (type) { 0298 case KReportSectionData::Type::PageHeaderAny: 0299 sec = d->pageHeaderAny; 0300 break; 0301 case KReportSectionData::Type::PageHeaderEven: 0302 sec = d->pageHeaderEven; 0303 break; 0304 case KReportSectionData::Type::PageHeaderOdd: 0305 sec = d->pageHeaderOdd; 0306 break; 0307 case KReportSectionData::Type::PageHeaderFirst: 0308 sec = d->pageHeaderFirst; 0309 break; 0310 case KReportSectionData::Type::PageHeaderLast: 0311 sec = d->pageHeaderLast; 0312 break; 0313 case KReportSectionData::Type::PageFooterAny: 0314 sec = d->pageFooterAny; 0315 break; 0316 case KReportSectionData::Type::PageFooterEven: 0317 sec = d->pageFooterEven; 0318 break; 0319 case KReportSectionData::Type::PageFooterOdd: 0320 sec = d->pageFooterOdd; 0321 break; 0322 case KReportSectionData::Type::PageFooterFirst: 0323 sec = d->pageFooterFirst; 0324 break; 0325 case KReportSectionData::Type::PageFooterLast: 0326 sec = d->pageFooterLast; 0327 break; 0328 case KReportSectionData::Type::ReportHeader: 0329 sec = d->reportHeader; 0330 break; 0331 case KReportSectionData::Type::ReportFooter: 0332 sec = d->reportFooter; 0333 break; 0334 default: 0335 sec = nullptr; 0336 } 0337 return sec; 0338 } 0339 0340 QPageLayout KReportDocument::pageLayout() const 0341 { 0342 return d->pageLayout; 0343 } 0344 0345 bool KReportDocument::isValid() const 0346 { 0347 return d->valid; 0348 } 0349 0350 QString KReportDocument::title() const 0351 { 0352 return d->title; 0353 } 0354 0355 bool KReportDocument::externalData() const 0356 { 0357 return d->externalData; 0358 } 0359 0360 #ifdef KREPORT_SCRIPTING 0361 QString KReportDocument::script() const 0362 { 0363 return d->script; 0364 } 0365 0366 QString KReportDocument::interpreter() const 0367 { 0368 return d->interpreter; 0369 } 0370 #endif 0371 0372 QString KReportDocument::name() const 0373 { 0374 return d->name; 0375 } 0376 0377 void KReportDocument::setName(const QString& n) 0378 { 0379 d->name = n; 0380 } 0381 0382 QString KReportDocument::query() const 0383 { 0384 return d->query; 0385 } 0386 0387 QString KReportDocument::pageSize() 0388 { 0389 return d->pageSize; 0390 } 0391 0392 void KReportDocument::setPageSize(const QString& size) 0393 { 0394 d->pageSize = size; 0395 } 0396 0397 QString KReportDocument::labelType() const 0398 { 0399 return d->labelType; 0400 } 0401 0402 void KReportDocument::setLabelType(const QString& label) 0403 { 0404 d->labelType = label; 0405 } 0406 0407 KReportDetailSectionData * KReportDocument::detail() const 0408 { 0409 return d->detailSection; 0410 } 0411