Warning, file /office/calligra/libs/odf/KoOdfWriteStore.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) 2005 David Faure <faure@kde.org> 0003 Copyright (C) 2007 Thorsten Zachmann <zachmann@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 "KoOdfWriteStore.h" 0022 0023 #include <QBuffer> 0024 0025 #include <QTemporaryFile> 0026 #include <OdfDebug.h> 0027 #include <klocalizedstring.h> 0028 0029 #include <KoStore.h> 0030 #include <KoStoreDevice.h> 0031 #include <KoXmlWriter.h> 0032 0033 #include "KoXmlNS.h" 0034 0035 struct Q_DECL_HIDDEN KoOdfWriteStore::Private { 0036 Private(KoStore * store) 0037 : store(store) 0038 , storeDevice(0) 0039 , contentWriter(0) 0040 , bodyWriter(0) 0041 , manifestWriter(0) 0042 , contentTmpFile(0) {} 0043 0044 0045 ~Private() { 0046 // If all the right close methods were called, nothing should remain, 0047 // so those deletes are really just in case. 0048 Q_ASSERT(!contentWriter); 0049 delete contentWriter; 0050 Q_ASSERT(!bodyWriter); 0051 delete bodyWriter; 0052 Q_ASSERT(!storeDevice); 0053 delete storeDevice; 0054 Q_ASSERT(!manifestWriter); 0055 delete manifestWriter; 0056 } 0057 0058 KoStore * store; 0059 KoStoreDevice * storeDevice; 0060 KoXmlWriter * contentWriter; 0061 0062 KoXmlWriter * bodyWriter; 0063 KoXmlWriter * manifestWriter; 0064 QTemporaryFile * contentTmpFile; 0065 }; 0066 0067 KoOdfWriteStore::KoOdfWriteStore(KoStore* store) 0068 : d(new Private(store)) 0069 { 0070 } 0071 0072 KoOdfWriteStore::~KoOdfWriteStore() 0073 { 0074 delete d; 0075 } 0076 0077 KoXmlWriter* KoOdfWriteStore::createOasisXmlWriter(QIODevice* dev, const char* rootElementName) 0078 { 0079 KoXmlWriter* writer = new KoXmlWriter(dev); 0080 writer->startDocument(rootElementName); 0081 writer->startElement(rootElementName); 0082 0083 if (qstrcmp(rootElementName, "VL:version-list") == 0) { 0084 writer->addAttribute("xmlns:VL", KoXmlNS::VL); 0085 writer->addAttribute("xmlns:dc", KoXmlNS::dc); 0086 return writer; 0087 } 0088 0089 writer->addAttribute("xmlns:office", KoXmlNS::office); 0090 writer->addAttribute("xmlns:meta", KoXmlNS::meta); 0091 0092 if (qstrcmp(rootElementName, "office:document-meta") != 0) { 0093 writer->addAttribute("xmlns:config", KoXmlNS::config); 0094 writer->addAttribute("xmlns:text", KoXmlNS::text); 0095 writer->addAttribute("xmlns:table", KoXmlNS::table); 0096 writer->addAttribute("xmlns:draw", KoXmlNS::draw); 0097 writer->addAttribute("xmlns:presentation", KoXmlNS::presentation); 0098 writer->addAttribute("xmlns:dr3d", KoXmlNS::dr3d); 0099 writer->addAttribute("xmlns:chart", KoXmlNS::chart); 0100 writer->addAttribute("xmlns:form", KoXmlNS::form); 0101 writer->addAttribute("xmlns:script", KoXmlNS::script); 0102 writer->addAttribute("xmlns:style", KoXmlNS::style); 0103 writer->addAttribute("xmlns:number", KoXmlNS::number); 0104 writer->addAttribute("xmlns:math", KoXmlNS::math); 0105 writer->addAttribute("xmlns:svg", KoXmlNS::svg); 0106 writer->addAttribute("xmlns:fo", KoXmlNS::fo); 0107 writer->addAttribute("xmlns:anim", KoXmlNS::anim); 0108 writer->addAttribute("xmlns:smil", KoXmlNS::smil); 0109 writer->addAttribute("xmlns:calligra", KoXmlNS::calligra); 0110 writer->addAttribute("xmlns:officeooo", KoXmlNS::officeooo); 0111 writer->addAttribute("xmlns:delta", KoXmlNS::delta); 0112 writer->addAttribute("xmlns:split", KoXmlNS::split); 0113 writer->addAttribute("xmlns:ac", KoXmlNS::ac); 0114 } 0115 0116 if (qstrcmp(rootElementName, "office:document-settings") == 0) { 0117 writer->addAttribute("xmlns:ooo", KoXmlNS::ooo); 0118 } 0119 0120 writer->addAttribute("office:version", "1.2"); 0121 0122 writer->addAttribute("xmlns:dc", KoXmlNS::dc); 0123 writer->addAttribute("xmlns:xlink", KoXmlNS::xlink); 0124 return writer; 0125 } 0126 0127 KoStore* KoOdfWriteStore::store() const 0128 { 0129 return d->store; 0130 } 0131 0132 KoXmlWriter* KoOdfWriteStore::contentWriter() 0133 { 0134 if (!d->contentWriter) { 0135 if (!d->store->open("content.xml")) { 0136 return 0; 0137 } 0138 d->storeDevice = new KoStoreDevice(d->store); 0139 d->contentWriter = createOasisXmlWriter(d->storeDevice, "office:document-content"); 0140 } 0141 return d->contentWriter; 0142 } 0143 0144 KoXmlWriter* KoOdfWriteStore::bodyWriter() 0145 { 0146 if (!d->bodyWriter) { 0147 Q_ASSERT(!d->contentTmpFile); 0148 d->contentTmpFile = new QTemporaryFile; 0149 if (!d->contentTmpFile->open()) { 0150 warnOdf << "Failed to open the temporary content file"; 0151 delete d->contentTmpFile; 0152 d->contentTmpFile = 0; 0153 return 0; 0154 } 0155 d->bodyWriter = new KoXmlWriter(d->contentTmpFile, 1); 0156 } 0157 return d->bodyWriter; 0158 } 0159 0160 bool KoOdfWriteStore::closeContentWriter() 0161 { 0162 Q_ASSERT(d->bodyWriter); 0163 Q_ASSERT(d->contentTmpFile); 0164 0165 delete d->bodyWriter; d->bodyWriter = 0; 0166 0167 // copy over the contents from the tempfile to the real one 0168 d->contentTmpFile->close(); // does not really close but seeks to the beginning of the file 0169 if (d->contentWriter) { 0170 d->contentWriter->addCompleteElement(d->contentTmpFile); 0171 } 0172 d->contentTmpFile->close(); // seek again to the beginning 0173 delete d->contentTmpFile; d->contentTmpFile = 0; // and finally close and remove the QTemporaryFile 0174 0175 if (d->contentWriter) { 0176 d->contentWriter->endElement(); // document-content 0177 d->contentWriter->endDocument(); 0178 delete d->contentWriter; 0179 d->contentWriter = 0; 0180 } 0181 0182 delete d->storeDevice; d->storeDevice = 0; 0183 if (!d->store->close()) { // done with content.xml 0184 return false; 0185 } 0186 return true; 0187 } 0188 0189 KoXmlWriter* KoOdfWriteStore::manifestWriter(const char* mimeType) 0190 { 0191 if (!d->manifestWriter) { 0192 // the pointer to the buffer is already stored in the KoXmlWriter, no need to store it here as well 0193 QBuffer *manifestBuffer = new QBuffer; 0194 manifestBuffer->open(QIODevice::WriteOnly); 0195 d->manifestWriter = new KoXmlWriter(manifestBuffer); 0196 d->manifestWriter->startDocument("manifest:manifest"); 0197 d->manifestWriter->startElement("manifest:manifest"); 0198 d->manifestWriter->addAttribute("xmlns:manifest", KoXmlNS::manifest); 0199 d->manifestWriter->addAttribute("manifest:version", "1.2"); 0200 d->manifestWriter->addManifestEntry("/", mimeType); 0201 } 0202 return d->manifestWriter; 0203 } 0204 0205 KoXmlWriter* KoOdfWriteStore::manifestWriter() 0206 { 0207 Q_ASSERT(d->manifestWriter); 0208 return d->manifestWriter; 0209 } 0210 0211 bool KoOdfWriteStore::closeManifestWriter(bool writeMainfest) 0212 { 0213 Q_ASSERT(d->manifestWriter); 0214 bool ok = true; 0215 if (writeMainfest) { 0216 d->manifestWriter->endElement(); 0217 d->manifestWriter->endDocument(); 0218 QBuffer* buffer = static_cast<QBuffer *>(d->manifestWriter->device()); 0219 if (d->store->open("META-INF/manifest.xml")) { 0220 qint64 written = d->store->write(buffer->buffer()); 0221 ok = (written == (qint64) buffer->buffer().size() && d->store->close()); 0222 } else { 0223 ok = false; 0224 } 0225 delete buffer; 0226 } 0227 delete d->manifestWriter; d->manifestWriter = 0; 0228 return ok; 0229 }