28#include <QDomDocument>
47 m_cell.addInlineElement(element);
52 m_cell.addElement(element, horizontalAlignment);
56 m_cell.addVariable(variable);
60 m_cell.addVerticalSpacing(space);
71 if (testForErrorAndFillErrorDetails())
74 const QString name = element.tagName();
76 const int row = element.attribute(QStringLiteral(
"row")).toInt();
77 const int column = element.attribute(QStringLiteral(
"column")).toInt();
78 const int rowSpan = element.attribute(QStringLiteral(
"rowspan"), QStringLiteral(
"1")).toInt();
79 const int colSpan = element.attribute(QStringLiteral(
"colspan"), QStringLiteral(
"1")).toInt();
87 cellReportBuilder.copyStateFrom(builder);
89 if (m_xmlElementHandler && !m_xmlElementHandler->
startCell(cell, element))
92 if (!processNode(element, &cellReportBuilder, inHeader, inFooter))
95 if (m_xmlElementHandler && !m_xmlElementHandler->
endCell(cell, element))
100 if (testForErrorAndFillErrorDetails())
106void KDReports::XmlParser::parseCommonTableAttributes(KDReports::AbstractTableElement &tableElement,
QDomElement &element)
110 tableElement.setBackground(bgColor);
112 tableElement.setBorder(element.
attribute(QStringLiteral(
"border")).toDouble());
119 tableElement.setWidth(widthStr.
toInt());
127 if (element.
hasAttribute(QStringLiteral(
"pointsize"))) {
128 const int pointSize = element.
attribute(QStringLiteral(
"pointsize")).
toInt();
142 header.setDefaultFont(font);
151 error(
QObject::tr(
"Expected \"<report>\" as the topmost element, but found \"<%1>\"").arg(docElement.
tagName()));
156 if (docElement.
hasAttribute(QStringLiteral(
"orientation"))) {
157 const QString orientation = docElement.
attribute(QStringLiteral(
"orientation"));
165 double marginTop = 20.0;
166 if (docElement.
hasAttribute(QStringLiteral(
"margin-top")))
168 double marginLeft = 20.0;
169 if (docElement.
hasAttribute(QStringLiteral(
"margin-left")))
171 double marginBottom = 20.0;
172 if (docElement.
hasAttribute(QStringLiteral(
"margin-bottom")))
174 double marginRight = 20.0;
175 if (docElement.
hasAttribute(QStringLiteral(
"margin-right")))
177 m_report->setMargins(marginTop, marginLeft, marginBottom, marginRight);
179 if (docElement.
hasAttribute(QStringLiteral(
"header-body-spacing")))
180 m_report->setHeaderBodySpacing(docElement.
attribute(QStringLiteral(
"header-body-spacing")).toDouble());
181 if (docElement.
hasAttribute(QStringLiteral(
"footer-body-spacing")))
182 m_report->setFooterBodySpacing(docElement.
attribute(QStringLiteral(
"footer-body-spacing")).toDouble());
187 m_report->setDefaultFont(font);
190 if (m_xmlElementHandler && !m_xmlElementHandler->startReport(*m_report, docElement)) {
192 *m_errorDetails = m_xmlElementHandler->errorDetails();
197 if (!processNode(docElement, builder,
false,
false))
200 if (m_xmlElementHandler)
201 m_xmlElementHandler->endReport(*m_report, docElement);
203 if (testForErrorAndFillErrorDetails())
212 error(
QObject::tr(
"<%1> is only supported in WordProcessing mode").arg(element.
tagName()));
230 if (testForErrorAndFillErrorDetails())
238 const QString text = extractText(element, &
id, m_report->d->m_currentModel, m_report->d->m_currentRow);
240 textElement.
setId(
id);
244 if (element.
hasAttribute(QStringLiteral(
"pointsize"))) {
245 const int pointSize = element.
attribute(QStringLiteral(
"pointsize")).
toInt();
268 if (element.
hasAttribute(QStringLiteral(
"strikeout"))) {
269 bool strikeOut =
false;
274 if (element.
hasAttribute(QStringLiteral(
"underline"))) {
275 bool underline =
false;
283 if (m_xmlElementHandler && !m_xmlElementHandler->textElement(textElement, element))
286 if (textElement.
id() != oldId) {
289 if (it != m_textValues.constEnd()) {
295 error(
QObject::tr(
"<text> is only supported in WordProcessing mode"));
312 const QString text = extractText(element, &
id);
314 htmlElement.
setId(
id);
321 if (m_xmlElementHandler && !m_xmlElementHandler->htmlElement(htmlElement, element))
324 if (htmlElement.
id() != oldId) {
327 if (it != m_textValues.constEnd()) {
332 addElement(htmlElement, builder, element);
337 error(
QObject::tr(
"<tabs> is only supported in WordProcessing mode"));
339 parseTabs(builder, element);
345 error(
QObject::tr(
"<paragraph-margins> is only supported in WordProcessing mode"));
347 parseParagraphMargins(builder, element);
353 htmlElement.
setHtml(QStringLiteral(
"<hr>"));
354 if (m_xmlElementHandler && !m_xmlElementHandler->htmlElement(htmlElement, element))
357 addElement(htmlElement, builder, element);
365 error(
QObject::tr(
"<vspace> is only supported in WordProcessing mode"));
367 if (builder != m_report->d->builder()) {
368 error(
QObject::tr(
"<vspace> not allowed in headers, footers, or table cells"));
372 if (m_xmlElementHandler && !m_xmlElementHandler->vspace(size, element))
374 m_report->addVerticalSpacing(size);
380 error(
QObject::tr(
"<table> without a model is only supported in WordProcessing mode"));
384 const int headerRowCount = element.
attribute(QStringLiteral(
"headerRowCount")).
toInt();
386 if (element.
hasAttribute(QStringLiteral(
"cellpadding")))
387 tableElement.setPadding(element.
attribute(QStringLiteral(
"cellpadding")).toInt());
388 parseCommonTableAttributes(tableElement, element);
390 if (m_xmlElementHandler && !m_xmlElementHandler->startTableElement(tableElement, element))
393 if (!parseTableContents(tableElement, element, *builder, inHeader, inFooter))
396 if (m_xmlElementHandler && !m_xmlElementHandler->endTableElement(tableElement, element))
399 addElement(tableElement, builder, element);
404 tableElement.setVerticalHeaderVisible(
false);
406 tableElement.setHorizontalHeaderVisible(
false);
409 tableElement.setHeaderBackground(headerBgColor);
410 parseCommonTableAttributes(tableElement, element);
411 if (m_xmlElementHandler && !m_xmlElementHandler->autoTableElement(tableElement, element))
415 m_report->mainTable()->setAutoTableElement(tableElement);
417 addElement(tableElement, builder, element);
426 chartElement.setBackground(bgColor);
444 height = str.
toInt();
446 chartElement.setSize(width, height, unit);
448 if (m_xmlElementHandler && !m_xmlElementHandler->chartElement(chartElement, element))
451 addElement(chartElement, builder, element);
457 QImage image = extractImage(element, &
id);
459 imageElement.setId(
id);
466 imageElement.setWidth(widthStr.
toInt());
468 }
else if (element.
hasAttribute(QStringLiteral(
"height"))) {
474 imageElement.setHeight(heightStr.
toInt());
476 }
else if (element.
hasAttribute(QStringLiteral(
"fitToPage"))) {
477 imageElement.setFitToPage();
480 if (m_xmlElementHandler && !m_xmlElementHandler->imageElement(imageElement, element))
483 addElement(imageElement, builder, element);
487 KDReports::Header &header = m_report->header(loc);
489 if (m_xmlElementHandler && !m_xmlElementHandler->startHeader(header, element))
491 if (!processNode(element, &header.d->m_builder,
true,
false))
493 if (m_xmlElementHandler)
494 m_xmlElementHandler->endHeader(header, element);
497 KDReports::Footer &footer = m_report->footer(loc);
499 if (m_xmlElementHandler && !m_xmlElementHandler->startFooter(footer, element))
501 if (!processNode(element, &footer.d->m_builder,
false,
true))
503 if (m_xmlElementHandler)
504 m_xmlElementHandler->endFooter(footer, element);
506 if (!inHeader && !inFooter) {
507 error(
QObject::tr(
"<variable> tags only allowed in headers and footers"));
511 error(
QObject::tr(
"<variable> tags must have a 'type' attribute"));
518 if (m_xmlElementHandler && !m_xmlElementHandler->variable(vt, element))
523 if (m_xmlElementHandler && !m_xmlElementHandler->pageBreak(element))
525 m_report->addPageBreak();
529 const bool skip = m_textValues.value(
id).
isEmpty();
531 if (!processNode(element, builder, inHeader, inFooter))
536 if (m_xmlElementHandler)
537 m_xmlElementHandler->customElement(element);
541 if (element.
hasAttribute(QStringLiteral(
"thickness"))) {
542 const double thickness = element.
attribute(QStringLiteral(
"thickness")).
toDouble();
552 const int margin = element.
attribute(QStringLiteral(
"margin")).
toInt();
556 if (m_xmlElementHandler && !m_xmlElementHandler->hLineElement(hLineElement, element))
559 addElement(hLineElement, builder, element);
561 error(
QObject::tr(
"KDReports::Report::loadFromXML(): Unknown element %1").arg(name));
565 if (testForErrorAndFillErrorDetails())
591 tab.delimiter = delimiter.
at(0);
604 if (!m_xmlElementHandler || m_xmlElementHandler->tabs(tabs, tabsElement))
614 if (!m_xmlElementHandler || m_xmlElementHandler->paragraphMargin(left, top, right, bottom, element))
624 if (it != m_imageValues.end()) {
632 if (!image.
load(fileName)) {
633 qWarning(
"Image not found or invalid: %s", qPrintable(fileName));
645 if (it != m_textValues.end()) {
648 }
else if (element.
hasAttribute(QStringLiteral(
"model"))) {
653 if (model == currentModel && currentRow > -1) {
658 const int column = element.
attribute(QStringLiteral(
"column")).
toInt();
664 return element.
text();
667bool KDReports::XmlParser::testForErrorAndFillErrorDetails()
669 if (m_xmlElementHandler && m_xmlElementHandler->errorDetails().hasError()) {
671 *m_errorDetails = m_xmlElementHandler->errorDetails();
677void KDReports::XmlParser::error(
const QString &errorString)
680 m_errorDetails->setDriverMessage(errorString);
682 qWarning(
"%s", qPrintable(errorString));
#define REPORTBUILDER_CTOR_ARGNAMES
#define REPORTBUILDER_CTOR_ARGDEFS
static QFont parseFontAttributes(const QDomElement &element)
static void parseHeaderFooterAttribute(KDReports::Header &header, const QDomElement &element)
void setColumnSpan(int columnSpan)
void setRowSpan(int rowSpan)
void setBackground(const QBrush &brush)
void setThickness(qreal t)
void setColor(const QColor &color)
void setHtml(const QString &html)
void setId(const QString &id)
ReportBuilder(KDReports::TextDocumentData &contentDocument, const QTextCursor &cursor, Report *report)
void setTabPositions(const QList< QTextOption::Tab > &tabs)
QTextCursor & contentDocumentCursor()
virtual void addVerticalSpacingPublic(qreal space)
virtual void addBlockElementPublic(const Element &element, Qt::AlignmentFlag horizontalAlignment, const QColor &backgroundColor=QColor())
virtual void addVariablePublic(KDReports::VariableType variable)
virtual void addInlineElementPublic(const Element &element)
void setParagraphMargins(qreal left, qreal top, qreal right, qreal bottom)
TextDocumentData & contentDocumentData()
void setHeaderRowCount(int count)
Cell & cell(int row, int column)
void setTextColor(const QColor &color)
void setFontFamily(const QString &family)
Set font attribute: family.
void setUnderline(bool underline)
Set font attribute: underline.
void setStrikeOut(bool strikeout)
Set font attribute: strike out.
void setItalic(bool italic)
Set font attribute: italic.
void setText(const QString &text)
void setPointSize(qreal size)
Set font attribute: size in points. Can be integer or decimal.
void setBold(bool bold)
Set font attribute: bold.
void setId(const QString &id)
virtual bool startCell(KDReports::Cell &cell, QDomElement &xmlElement)
virtual bool endCell(KDReports::Cell &cell, QDomElement &xmlElement)
static KDReports::VariableType stringToVariableType(const QString &type)
static Qt::AlignmentFlag stringToAlignment(const QString &str)
static QColor readBackground(const QDomElement &element)
static QColor readColor(const QDomElement &element, const char *attributeName)
static KDReports::HeaderLocations parseHeaderLocation(const QString &xmlAttr)
bool processDocument(const QDomDocument &document, KDReports::ReportBuilder *builder)
@ Percent
Percentage of the text width, i.e. the page width minus margins.
@ Millimeters
Millimeters (the default)
QAbstractItemModel * modelForKey(const QString &key)
virtual QVariant data(const QModelIndex &index, int role) const const=0
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const=0
bool isValid() const const
QDomElement documentElement() const const
QString attribute(const QString &name, const QString &defValue) const const
bool hasAttribute(const QString &name) const const
QString tagName() const const
QString text() const const
QDomElement firstChildElement(const QString &tagName) const const
bool isNull() const const
QDomElement nextSiblingElement(const QString &tagName) const const
void setFamily(const QString &family)
void setPointSize(int pointSize)
bool load(QIODevice *device, const char *format)
void append(const T &value)
QString tr(const char *sourceText, const char *disambiguation, int n)
const QChar at(int position) const const
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
double toDouble(bool *ok) const const
int toInt(bool *ok, int base) const const
void truncate(int position)
QTextStream & left(QTextStream &stream)
QTextStream & right(QTextStream &stream)
QString toString() const const