KReport

KoOdtFrameReportDocument.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2012 by Dag Andersen (danders@get2net.dk)
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18*/
19
20#include "KoOdtFrameReportDocument.h"
21#include "KoOdtFrameReportPrimitive.h"
22#include "KReportRenderObjects.h"
23
24#include <KoOdfWriteStore.h>
25#include <KoXmlWriter.h>
26#include <KoStore.h>
27#include <KoOdfGraphicStyles.h>
28#include <KoGenStyles.h>
29#include <KoGenStyle.h>
30#include <KReportDpi.h>
31
32#include <QVarLengthArray>
33#include "kreport_debug.h"
34
35KoOdtFrameReportDocument::KoOdtFrameReportDocument()
36 : manifestWriter(0)
37{
38}
39
40KoOdtFrameReportDocument::~KoOdtFrameReportDocument()
41{
42 foreach (const QList<KoOdtFrameReportPrimitive*> &lst, m_pagemap) {
43 foreach(KoOdtFrameReportPrimitive *p, lst) {
44 delete p;
45 }
46 }
47}
48
49void KoOdtFrameReportDocument::setPageOptions(const ReportPageOptions &pageOptions)
50{
51 m_pageOptions = pageOptions;
52}
53
54void KoOdtFrameReportDocument::startTable(OROSection* section)
55{
56 Q_UNUSED(section);
57}
58
59void KoOdtFrameReportDocument::addPrimitive(KoOdtFrameReportPrimitive *data)
60{
61 m_pagemap[data->pageNumber()].append( data);
62}
63
64QFile::FileError KoOdtFrameReportDocument::saveDocument(const QString& path)
65{
66 // create output store
67 KoStore *store = KoStore::createStore(path, KoStore::Write,
68 "application/vnd.oasis.opendocument.text", KoStore::Zip);
69 if (!store) {
70 kreportWarning() << "Couldn't open the requested file.";
71 return QFile::OpenError;
72 }
73
74 KoOdfWriteStore oasisStore(store);
75 manifestWriter = oasisStore.manifestWriter("application/vnd.oasis.opendocument.text");
76 if (!manifestWriter) {
77 return QFile::NoError;
78 }
79 // save extra data like images...
80 foreach (const QList<KoOdtFrameReportPrimitive*> &lst, m_pagemap) {
81 foreach(KoOdtFrameReportPrimitive *p, lst) {
82 p->saveData(store, manifestWriter);
83 }
84 }
85 //kreportDebug()<<"data saved";
86 KoGenStyles coll;
87 createStyles(&coll); // create basic styles
88 bool ok = createContent(&oasisStore, coll);
89 if (ok) {
90 // save styles to styles.xml
91 ok = coll.saveOdfStylesDotXml(store, manifestWriter);
92 }
93 ok = oasisStore.closeManifestWriter() && ok;
94 delete oasisStore.store();
96
97}
98
99void KoOdtFrameReportDocument::createStyles(KoGenStyles *coll)
100{
101 // convert to inches
102 qreal pw = m_pageOptions.widthPx() / KReportPrivate::dpiX();
103 qreal ph = m_pageOptions.heightPx() / KReportPrivate::dpiY();
104 qreal topMargin = m_pageOptions.getMarginTop() / KReportPrivate::dpiY();
105 qreal bottomMargin = m_pageOptions.getMarginBottom() / KReportPrivate::dpiY();
106 qreal leftMargin = m_pageOptions.getMarginLeft() / KReportPrivate::dpiX();
107 qreal rightMargin = m_pageOptions.getMarginRight() / KReportPrivate::dpiX();
108 QString orientation = m_pageOptions.isPortrait() ? "portrait" : "landscape";
109
110 //kreportDebug()<<"Page:"<<pw<<ph<<orientation;
111 //kreportDebug()<<"Margin:"<<topMargin<<bottomMargin<<leftMargin<<rightMargin;
112 KoGenStyle page(KoGenStyle::PageLayoutStyle, "page-layout");
113 page.addProperty("style:num-format", "1");
114 page.addProperty("style:print-orientation", orientation);
115 page.addProperty("style:writing-mode", "lr-tb");
116 page.addProperty("style:footnote-max-height", "0cm");
117
118 page.addProperty("fo:page-width", QString("%1in").arg(pw));
119 page.addProperty("fo:page-height", QString("%1in").arg(ph));
120 page.addProperty("fo:margin-top", QString("%1in").arg(topMargin));
121 page.addProperty("fo:margin-bottom", QString("%1in").arg(bottomMargin));
122 page.addProperty("fo:margin-left", QString("%1in").arg(leftMargin));
123 page.addProperty("fo:margin-right", QString("%1in").arg(rightMargin));
124 page.setAutoStyleInStylesDotXml(true);
125 QString pagename = coll->insert(page, "pm");
126
127 KoGenStyle master(KoGenStyle::MasterPageStyle, "master-page");
128 master.addAttribute("style:page-layout-name", pagename);
129 coll->insert(master, "Standard", KoGenStyles::DontAddNumberToName);
130
131 KoGenStyle fs(KoGenStyle::GraphicStyle, "graphic");
132 fs.addProperty("vertical-pos", "from-top");
133 fs.addProperty("vertical-rel", "page");
134 fs.addProperty("horizontal-pos", "from-left");
135 fs.addProperty("horizontal-rel", "page");
136 coll->insert(fs, "Frame", KoGenStyles::DontAddNumberToName);
137
138 KoGenStyle ps(KoGenStyle::ParagraphStyle, "paragraph");
139 ps.addAttribute("style:parent-style-name", "Standard");
140 coll->insert(ps, "P1", KoGenStyles::DontAddNumberToName);
141}
142
143bool KoOdtFrameReportDocument::createContent(KoOdfWriteStore* store, KoGenStyles *coll)
144{
145 KoXmlWriter* bodyWriter = store->bodyWriter();
146 KoXmlWriter* contentWriter = store->contentWriter();
147
148 if (!bodyWriter || !contentWriter || !manifestWriter) {
149 kreportWarning()<<"Failed to created odt writer";
150 return false;
151 }
152
153 // OpenDocument spec requires the manifest to include a list of the files in this package
154 manifestWriter->addManifestEntry("content.xml", "text/xml");
155// manifestWriter->addManifestEntry("styles.xml", "text/xml");
156
157 contentWriter->startElement("office:automatic-styles");
158
159 //new page
160 contentWriter->startElement("style:style");
161 contentWriter->addAttribute("style:name", "NewPage");
162 contentWriter->addAttribute("style:master-page-name", "Standard");
163 contentWriter->addAttribute("style:family", "paragraph");
164 contentWriter->startElement("style:paragraph-properties");
165 contentWriter->addAttribute("fo:font-family", "Arial");
166 contentWriter->addAttribute("fo:break-before", "page"); // needed by LibreOffice
167 contentWriter->endElement(); // style:paragraph-properties
168 contentWriter->endElement(); // style:style
169
170 contentWriter->startElement("text:sequence-decls");
171 contentWriter->startElement("text:sequence-decl");
172 contentWriter->addAttribute("text:display-outline-level", "0");
173 contentWriter->addAttribute("text:name", "Illustration");
174 contentWriter->endElement(); //text:sequence-decl
175 contentWriter->startElement("text:sequence-decl");
176 contentWriter->addAttribute("text:display-outline-level", "0");
177 contentWriter->addAttribute("text:name", "Table");
178 contentWriter->endElement(); //text:sequence-decl
179 contentWriter->startElement("text:sequence-decl");
180 contentWriter->addAttribute("text:display-outline-level", "0");
181 contentWriter->addAttribute("text:name", "Text");
182 contentWriter->endElement(); //text:sequence-decl
183 contentWriter->startElement("text:sequence-decl");
184 contentWriter->addAttribute("text:display-outline-level", "0");
185 contentWriter->addAttribute("text:name", "Drawing");
186 contentWriter->endElement(); //text:sequence-decl
187 contentWriter->endElement(); //text:sequence-decls
188 contentWriter->endElement(); // office:automatic-styles
189
190 // office:body
191 bodyWriter->startElement("office:body");
192 bodyWriter->startElement("office:text");
193
194 createPages(bodyWriter, coll);
195
196 bodyWriter->endElement(); // office:text
197 bodyWriter->endElement(); // office:body
198
199 return store->closeContentWriter();
200}
201
202void KoOdtFrameReportDocument::createPages(KoXmlWriter* bodyWriter, KoGenStyles *coll)
203{
205 for (it = m_pagemap.constBegin(); it != m_pagemap.constEnd(); ++it) {
206 bodyWriter->startElement("text:p");
207 bodyWriter->addAttribute("text:style-name", "NewPage");
208 // all frames need to be *inside* or else LibreWriter shows nothing
209 foreach (KoOdtFrameReportPrimitive *data, it.value()) {
210 data->createStyle(coll);
211 data->createBody(bodyWriter);
212 }
213 bodyWriter->endElement(); // text:p
214 }
215 if (m_pagemap.isEmpty()) {
216 // words crashes if there is no text element
217 bodyWriter->startElement("text:p");
218 bodyWriter->addAttribute("text:style-name", "P1");
219 bodyWriter->endElement(); // text:p
220 }
221}
Represents a single a single row in a document and may contain zero or more OROPrimitives.
const_iterator constBegin() const const
const_iterator constEnd() const const
bool isEmpty() const const
T value(const Key &key, const T &defaultValue) const const
QString & insert(qsizetype position, QChar ch)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:21:31 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.