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 }