KD Reports API Documentation  2.2
KDReportsReportBuilder.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** This file is part of the KD Reports library.
4 **
5 ** SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
6 **
7 ** SPDX-License-Identifier: MIT
8 **
9 ****************************************************************************/
10 
11 #include "KDReportsHeader_p.h" // for variableValue and setVariableMarker
12 #include "KDReportsLayoutHelper_p.h" // mmToPixels
14 #include "KDReportsTextElement.h"
15 
16 #include <QDebug>
17 #include <QTextBlock>
18 
19 //@cond PRIVATE
20 KDReports::ReportBuilder::ReportBuilder(KDReports::TextDocumentData &contentDocument, const QTextCursor &cursor, KDReports::Report *report)
21  : m_contentDocument(contentDocument)
22  , m_cursor(cursor)
23  , m_report(report)
24 {
25 }
26 //@endcond
27 
29 {
30  QTextCursor &cursor = this->cursor();
31  cursor.beginEditBlock();
32  // Save/restore the char format, otherwise insertHtml("<font size=\"+8\">My Title</font>")
33  // leaves us with a large-font char format, which would affect subsequent insertText().
34  // So: char format change must be done inside a single html element, not across.
35  // This is also true for charts and images, and variables, which all set things into the char format.
36  const QTextCharFormat origCharFormat = cursor.charFormat();
37  element.build(*this);
38  cursor.setCharFormat(origCharFormat);
39  cursor.endEditBlock();
40 }
41 
42 void KDReports::ReportBuilder::addBlockElement(const Element &element, Qt::AlignmentFlag horizontalAlignment, const QColor &backgroundColor)
43 {
44  QTextCursor &cursor = this->cursor();
45  cursor.beginEditBlock();
46 
47  if (!m_first) {
48  cursor.insertBlock();
49  } else {
50  m_first = false;
51  }
52 
53  // Set the default font again, the previous block should have no effect on this one
54  QTextCharFormat charFormat = cursor.charFormat();
55  charFormat.setFont(m_defaultFont);
56  cursor.setCharFormat(charFormat);
57 
58  QTextBlockFormat blockFormat;
59  blockFormat.setAlignment(horizontalAlignment);
60  setupBlockFormat(blockFormat);
61 
62  if (backgroundColor.isValid())
63  blockFormat.setBackground(backgroundColor);
64 
65  cursor.setBlockFormat(blockFormat);
66 
67  element.build(*this);
68 
69  cursor.setCharFormat(charFormat); // restore, we don't want addElement(bold text) + addInline(normal text) to make the normal text bold
70  cursor.endEditBlock();
71 
72 #if 0 // DEBUG CODE for tab positions
73  if (!m_tabPositions.isEmpty()) {
74  QTextBlock block = cursor.document()->firstBlock();
75  do {
76  qDebug() << "addBlock: Looking at block" << block.blockNumber() << "tabs:" << block.blockFormat().tabPositions().count();
77  block = block.next();
78  } while ( block.isValid() );
79  }
80 #endif
81 }
82 
84 {
85  QTextCursor &cursor = this->cursor();
86  const int charPosition = cursor.position();
87  // Don't ask for the value of PageCount yet -- it would create a documentlayout
88  // which would make any later insertion into the textdocument much, much slower.
89  const QString value = variable == KDReports::PageCount ? QStringLiteral("UNKNOWN YET") : variableValue(0 /*pageNumber*/, m_report, variable);
90  KDReports::TextElement element(value);
91 
92  const QTextCharFormat origCharFormat = cursor.charFormat();
93 
94  // Keep the current font (KDRE-91).
95  QTextCursor docCursor(&currentDocument());
96  docCursor.setPosition(charPosition);
97  cursor.setCharFormat(docCursor.charFormat());
98 
99  cursor.beginEditBlock();
100  element.build(*this);
101  cursor.endEditBlock();
102 
103  setVariableMarker(currentDocument(), charPosition, variable, value.length());
104 
105  cursor.setCharFormat(origCharFormat); // restore the orig format
106 }
107 
109 {
110  QTextCursor &cursor = this->cursor();
111  cursor.beginEditBlock();
112 
113  if (!m_first) {
114  cursor.insertBlock();
115  } else {
116  m_first = false;
117  }
118 
119  QTextBlockFormat blockFormat;
120  blockFormat.setTopMargin(KDReports::mmToPixels(space / 2));
121  blockFormat.setBottomMargin(KDReports::mmToPixels(space / 2));
122  cursor.setBlockFormat(blockFormat);
123  QTextCharFormat charFormat;
124  charFormat.setFontPointSize(1);
125  cursor.setCharFormat(charFormat);
126  cursor.insertText(QStringLiteral(" ")); // this ensures the point size 1 is actually used, making the paragraph much smaller
127  cursor.endEditBlock();
128 }
129 
130 //@cond PRIVATE
132 {
133  addInlineElement(element);
134 }
135 
136 void KDReports::ReportBuilder::addBlockElementPublic(const Element &element, Qt::AlignmentFlag horizontalAlignment, const QColor &backgroundColor)
137 {
138  addBlockElement(element, horizontalAlignment, backgroundColor);
139 }
140 
142 {
143  addVariable(variable);
144 }
145 
147 {
148  addVerticalSpacing(space);
149 }
150 //@endcond
151 
153 {
154  QTextBlockFormat blockFormat = m_cursor.blockFormat();
155  blockFormat.setPageBreakPolicy(QTextFormat::PageBreak_AlwaysAfter);
156  m_cursor.setBlockFormat(blockFormat);
157 }
158 
159 void KDReports::ReportBuilder::insertFragmentPublic(const QTextDocumentFragment &fragment)
160 {
161  m_cursor.insertFragment(fragment);
162 }
163 
165 {
166  m_tabPositions = tabs;
167  for (QTextOption::Tab &tab : m_tabPositions) {
168  tab.position = mmToPixels(tab.position);
169  }
170  m_contentDocument.setUsesTabPositions(true);
171 }
172 
174 {
175  m_tabPositions = parentBuilder.m_tabPositions;
176  m_leftMargin = parentBuilder.m_leftMargin;
177  m_rightMargin = parentBuilder.m_rightMargin;
178  m_topMargin = parentBuilder.m_topMargin;
179  m_bottomMargin = parentBuilder.m_bottomMargin;
180  m_defaultFont = parentBuilder.m_defaultFont;
181 }
182 
183 QDebug operator<<(QDebug &dbg, QTextOption::Tab tab) // clazy says: pass by value, small enough
184 {
185  static const char *types[] = {"LeftTab", "RightTab", "CenterTab", "DelimiterTab"};
186  dbg.space() << '(' << types[tab.type] << tab.position << "px" << ')';
187  return dbg;
188 }
189 
190 //@cond PRIVATE
191 void KDReports::ReportBuilder::setParagraphMargins(qreal left, qreal top, qreal right, qreal bottom)
192 {
193  m_leftMargin = mmToPixels(left);
194  m_topMargin = mmToPixels(top);
195  m_rightMargin = mmToPixels(right);
196  m_bottomMargin = mmToPixels(bottom);
197 }
198 //@endcond
199 
200 void KDReports::ReportBuilder::setupBlockFormat(QTextBlockFormat &blockFormat) const
201 {
202  blockFormat.setTabPositions(m_tabPositions);
203  blockFormat.setLeftMargin(m_leftMargin);
204  blockFormat.setRightMargin(m_rightMargin);
205  blockFormat.setTopMargin(m_topMargin);
206  blockFormat.setBottomMargin(m_bottomMargin);
207 }
208 
210 {
211  return m_cursor.position();
212 }
213 
214 QTextCharFormat::VerticalAlignment KDReports::ReportBuilder::toVerticalAlignment(Qt::Alignment alignment)
215 {
216  switch (alignment & Qt::AlignVertical_Mask) {
217  case Qt::AlignTop:
218  return QTextCharFormat::AlignTop;
219  case Qt::AlignBottom:
220  return QTextCharFormat::AlignBottom;
221  case Qt::AlignVCenter:
222  return QTextCharFormat::AlignMiddle;
223  case Qt::AlignBaseline:
224  return QTextCharFormat::AlignBaseline;
225  }
226  return QTextCharFormat::AlignNormal;
227 }
QDebug operator<<(QDebug &dbg, QTextOption::Tab tab)
virtual void build(ReportBuilder &) const =0
ReportBuilder(KDReports::TextDocumentData &contentDocument, const QTextCursor &cursor, Report *report)
void setTabPositions(const QList< QTextOption::Tab > &tabs)
virtual void insertFragmentPublic(const QTextDocumentFragment &fragment)
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 addVerticalSpacing(qreal space)
static QTextCharFormat::VerticalAlignment toVerticalAlignment(Qt::Alignment alignment)
virtual void addInlineElementPublic(const Element &element)
void setupBlockFormat(QTextBlockFormat &blockFormat) const
virtual void addBlockElement(const Element &element, Qt::AlignmentFlag horizontalAlignment, const QColor &backgroundColor=QColor())
void setParagraphMargins(qreal left, qreal top, qreal right, qreal bottom)
virtual void addVariable(KDReports::VariableType variable)
virtual void addInlineElement(const Element &element)
void copyStateFrom(const ReportBuilder &parentBuilder)
void build(ReportBuilder &builder) const override
QString variableValue(int pageNumber, KDReports::Report *report, VariableType type)
@ PageCount
Page count.
KDREPORTS_EXPORT qreal mmToPixels(qreal mm)
void setVariableMarker(QTextDocument &textDoc, int pos, KDReports::VariableType variableType, int valueLength)

© Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/
https://www.kdab.com/development-resources/qt-tools/kd-reports/
Generated by doxygen 1.9.1