KReport

KoOdtFrameReportDocument.cpp
1 /* This file is part of the KDE project
2  Copyright (C) 2012 by Dag Andersen ([email protected])
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 
35 KoOdtFrameReportDocument::KoOdtFrameReportDocument()
36  : manifestWriter(0)
37 {
38 }
39 
40 KoOdtFrameReportDocument::~KoOdtFrameReportDocument()
41 {
42  foreach (const QList<KoOdtFrameReportPrimitive*> &lst, m_pagemap) {
43  foreach(KoOdtFrameReportPrimitive *p, lst) {
44  delete p;
45  }
46  }
47 }
48 
49 void KoOdtFrameReportDocument::setPageOptions(const ReportPageOptions &pageOptions)
50 {
51  m_pageOptions = pageOptions;
52 }
53 
54 void KoOdtFrameReportDocument::startTable(OROSection* section)
55 {
56  Q_UNUSED(section);
57 }
58 
59 void KoOdtFrameReportDocument::addPrimitive(KoOdtFrameReportPrimitive *data)
60 {
61  m_pagemap[data->pageNumber()].append( data);
62 }
63 
64 QFile::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 
99 void 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 
143 bool 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 
202 void KoOdtFrameReportDocument::createPages(KoXmlWriter* bodyWriter, KoGenStyles *coll)
203 {
204  QMap<int, QList<KoOdtFrameReportPrimitive*> >::const_iterator it;
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 }
const T value(const Key &key, const T &defaultValue) const const
Represents a single a single row in a document and may contain zero or more OROPrimitives.
QString & insert(int position, QChar ch)
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Feb 7 2023 04:17:37 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.