Warning, file /office/calligra/filters/libmsooxml/KoOdfExporter.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* This file is part of the KDE project 0002 Copyright (C) 2007 Thorsten Zachmann <zachmann@kde.org> 0003 Copyright (C) 2009 Jarosław Staniek <staniek@kde.org> 0004 0005 This library is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU Library General Public 0007 License as published by the Free Software Foundation; either 0008 version 2 of the License, or (at your option) any later version. 0009 0010 This library is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 Library General Public License for more details. 0014 0015 You should have received a copy of the GNU Library General Public License 0016 along with this library; see the file COPYING.LIB. If not, write to 0017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 * Boston, MA 02110-1301, USA. 0019 */ 0020 0021 #include "KoOdfExporter.h" 0022 #include "MsooXmlUtils.h" 0023 0024 #include <QBuffer> 0025 #include <QByteArray> 0026 0027 #include "MsooXmlDebug.h" 0028 0029 #include <KoOdfWriteStore.h> 0030 #include <KoStoreDevice.h> 0031 #include <KoFilterChain.h> 0032 #include <KoGenStyles.h> 0033 #include <KoXmlWriter.h> 0034 0035 #include <memory> 0036 0037 KoOdfWriters::KoOdfWriters() 0038 : content(0), body(0), meta(0), manifest(0), mainStyles(0) 0039 { 0040 } 0041 0042 //------------------------------------------ 0043 0044 class Q_DECL_HIDDEN KoOdfExporter::Private 0045 { 0046 public: 0047 Private() {} 0048 QByteArray bodyContentElement; 0049 }; 0050 0051 //------------------------------------------ 0052 0053 KoOdfExporter::KoOdfExporter(const QString& bodyContentElement, QObject* parent) 0054 : KoFilter(parent) 0055 , d(new Private) 0056 { 0057 d->bodyContentElement = QByteArray("office:") + bodyContentElement.toLatin1(); 0058 } 0059 0060 KoOdfExporter::~KoOdfExporter() 0061 { 0062 delete d; 0063 } 0064 0065 KoFilter::ConversionStatus KoOdfExporter::convert(const QByteArray& from, const QByteArray& to) 0066 { 0067 // check for proper conversion 0068 if (!acceptsSourceMimeType(from)) { 0069 warnMsooXml << "Invalid source mimetype" << from; 0070 return KoFilter::NotImplemented; 0071 } 0072 if (!acceptsDestinationMimeType(to)) { 0073 warnMsooXml << "Invalid destination mimetype" << to; 0074 return KoFilter::NotImplemented; 0075 } 0076 0077 //create output files 0078 KoStore *outputStore = KoStore::createStore(m_chain->outputFile(), KoStore::Write, to, KoStore::Zip); 0079 if (!outputStore || outputStore->bad()) { 0080 warnMsooXml << "Unable to open output file!"; 0081 delete outputStore; 0082 return KoFilter::FileNotFound; 0083 } 0084 debugMsooXml << "created outputStore."; 0085 KoOdfWriteStore oasisStore(outputStore); 0086 0087 debugMsooXml << "created oasisStore."; 0088 0089 // KoGenStyles for writing styles while we're parsing 0090 KoGenStyles mainStyles; 0091 0092 KoOdfWriters writers; 0093 writers.mainStyles = &mainStyles; 0094 0095 // create a writer for meta.xml 0096 QBuffer buf; 0097 buf.open(QIODevice::WriteOnly); 0098 KoXmlWriter metaWriter(&buf); 0099 writers.meta = &metaWriter; 0100 0101 // create a writer for manifest.xml 0102 QBuffer manifestBuf; 0103 manifestBuf.open(QIODevice::WriteOnly); 0104 KoXmlWriter manifestWriter(&manifestBuf); 0105 writers.manifest = &manifestWriter; 0106 0107 //open contentWriter & bodyWriter *temp* writers 0108 //so we can write picture files while we parse 0109 QBuffer contentBuf; 0110 KoXmlWriter contentWriter(&contentBuf); 0111 writers.content = &contentWriter; 0112 QBuffer bodyBuf; 0113 KoXmlWriter bodyWriter(&bodyBuf); 0114 writers.body = &bodyWriter; 0115 0116 // open main tags 0117 bodyWriter.startElement("office:body"); 0118 bodyWriter.startElement(d->bodyContentElement.constData()); 0119 0120 RETURN_IF_ERROR( createDocument(outputStore, &writers) ) 0121 0122 //save the office:automatic-styles & and fonts in content.xml 0123 mainStyles.saveOdfStyles(KoGenStyles::FontFaceDecls, &contentWriter); 0124 mainStyles.saveOdfStyles(KoGenStyles::DocumentAutomaticStyles, &contentWriter); 0125 0126 //close tags in body 0127 bodyWriter.endElement();//office:* 0128 bodyWriter.endElement();//office:body 0129 0130 //now create real content/body writers & dump the information there 0131 KoXmlWriter* realContentWriter = oasisStore.contentWriter(); 0132 if (!realContentWriter) { 0133 warnMsooXml << "Error creating the content writer."; 0134 delete outputStore; 0135 return KoFilter::CreationError; 0136 } 0137 realContentWriter->addCompleteElement(&contentBuf); 0138 0139 KoXmlWriter* realBodyWriter = oasisStore.bodyWriter(); 0140 if (!realBodyWriter) { 0141 warnMsooXml << "Error creating the body writer."; 0142 delete outputStore; 0143 return KoFilter::CreationError; 0144 } 0145 realBodyWriter->addCompleteElement(&bodyBuf); 0146 0147 //now close content & body writers 0148 if (!oasisStore.closeContentWriter()) { 0149 warnMsooXml << "Error closing content."; 0150 delete outputStore; 0151 return KoFilter::CreationError; 0152 } 0153 0154 debugMsooXml << "closed content & body writers."; 0155 0156 //create the manifest file 0157 KoXmlWriter* realManifestWriter = oasisStore.manifestWriter(to); 0158 //create the styles.xml file 0159 mainStyles.saveOdfStylesDotXml(outputStore, realManifestWriter); 0160 realManifestWriter->addManifestEntry("content.xml", "text/xml"); 0161 realManifestWriter->addCompleteElement(&manifestBuf); 0162 0163 debugMsooXml << "created manifest and styles.xml"; 0164 0165 // create settings.xml, apparently it is used to note calligra that msoffice files should 0166 // have different behavior with some things 0167 if (!outputStore->open("settings.xml")) { 0168 delete outputStore; 0169 return KoFilter::CreationError; 0170 } 0171 0172 KoStoreDevice settingsDev(outputStore); 0173 KoXmlWriter* settings = KoOdfWriteStore::createOasisXmlWriter(&settingsDev, "office:document-settings"); 0174 settings->startElement("office:settings"); 0175 settings->startElement("config:config-item-set"); 0176 settings->addAttribute("config:name", "ooo:configuration-settings"); 0177 writeConfigurationSettings(settings); 0178 settings->endElement(); // config:config-item-set 0179 settings->endElement(); // office:settings 0180 settings->endElement(); // office:document-settings 0181 settings->endDocument(); 0182 delete settings; 0183 realManifestWriter->addManifestEntry("settings.xml", "text/xml"); 0184 if (!outputStore->close()) { 0185 delete outputStore; 0186 return KoFilter::CreationError; 0187 } 0188 0189 //create meta.xml 0190 if (!outputStore->open("meta.xml")) { 0191 delete outputStore; 0192 return KoFilter::CreationError; 0193 } 0194 KoStoreDevice metaDev(outputStore); 0195 KoXmlWriter* meta = KoOdfWriteStore::createOasisXmlWriter(&metaDev, "office:document-meta"); 0196 meta->startElement("office:meta"); 0197 meta->addCompleteElement(&buf); 0198 meta->endElement(); //office:meta 0199 meta->endElement(); //office:document-meta 0200 meta->endDocument(); 0201 delete meta; 0202 if (!outputStore->close()) { 0203 delete outputStore; 0204 return KoFilter::CreationError; 0205 } 0206 realManifestWriter->addManifestEntry("meta.xml", "text/xml"); 0207 oasisStore.closeManifestWriter(); 0208 delete outputStore; 0209 0210 return KoFilter::OK; 0211 }