00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "KoOasisStore.h"
00020
00021 #include "KoDocument.h"
00022 #include "KoXmlNS.h"
00023 #include "KoDom.h"
00024 #include <KoStore.h>
00025 #include <KoStoreDevice.h>
00026 #include <KoXmlReader.h>
00027 #include <KoXmlWriter.h>
00028
00029 #include <ktemporaryfile.h>
00030 #include <kdebug.h>
00031 #include <klocale.h>
00032
00033 #include <QFile>
00034 #include <QtXml>
00035 #include <QBuffer>
00036
00037 KoOasisStore::KoOasisStore( KoStore* store )
00038 : m_store( store ),
00039 m_storeDevice( 0 ),
00040 m_contentWriter( 0 ),
00041 m_bodyWriter( 0 ),
00042 m_manifestWriter( 0 ),
00043 m_contentTmpFile( 0 )
00044 {
00045 }
00046
00047 KoOasisStore::~KoOasisStore()
00048 {
00049
00050
00051 Q_ASSERT( !m_contentWriter );
00052 delete m_contentWriter;
00053 Q_ASSERT( !m_bodyWriter );
00054 delete m_bodyWriter;
00055 Q_ASSERT( !m_storeDevice );
00056 delete m_storeDevice;
00057 Q_ASSERT( !m_contentTmpFile );
00058 delete m_contentTmpFile;
00059 Q_ASSERT( !m_manifestWriter );
00060 delete m_manifestWriter;
00061 }
00062
00063 KoXmlWriter* KoOasisStore::contentWriter()
00064 {
00065 if ( !m_contentWriter )
00066 {
00067 if ( !m_store->open( "content.xml" ) )
00068 return 0;
00069 m_storeDevice = new KoStoreDevice( m_store );
00070 m_contentWriter = KoDocument::createOasisXmlWriter( m_storeDevice, "office:document-content" );
00071 }
00072 return m_contentWriter;
00073 }
00074
00075 KoXmlWriter* KoOasisStore::bodyWriter()
00076 {
00077 if ( !m_bodyWriter )
00078 {
00079 Q_ASSERT( !m_contentTmpFile );
00080 m_contentTmpFile = new KTemporaryFile;
00081 m_contentTmpFile->open();
00082 m_bodyWriter = new KoXmlWriter( m_contentTmpFile, 1 );
00083 }
00084 return m_bodyWriter;
00085 }
00086
00087 bool KoOasisStore::closeContentWriter()
00088 {
00089 Q_ASSERT( m_bodyWriter );
00090 Q_ASSERT( m_contentTmpFile );
00091
00092 delete m_bodyWriter; m_bodyWriter = 0;
00093
00094 m_contentTmpFile->close();
00095 m_contentWriter->addCompleteElement( m_contentTmpFile );
00096 m_contentTmpFile->close();
00097 delete m_contentTmpFile; m_contentTmpFile = 0;
00098
00099 Q_ASSERT( m_contentWriter );
00100 m_contentWriter->endElement();
00101 m_contentWriter->endDocument();
00102 delete m_contentWriter; m_contentWriter = 0;
00103 delete m_storeDevice; m_storeDevice = 0;
00104 if ( !m_store->close() )
00105 return false;
00106 return true;
00107 }
00108
00109 KoXmlWriter* KoOasisStore::manifestWriter( const char* mimeType )
00110 {
00111 if ( !m_manifestWriter )
00112 {
00113
00114 QBuffer *manifestBuffer = new QBuffer;
00115 manifestBuffer->open( QIODevice::WriteOnly );
00116 m_manifestWriter = new KoXmlWriter( manifestBuffer );
00117 m_manifestWriter->startDocument( "manifest:manifest" );
00118 m_manifestWriter->startElement( "manifest:manifest" );
00119 m_manifestWriter->addAttribute( "xmlns:manifest", KoXmlNS::manifest );
00120 m_manifestWriter->addManifestEntry( "/", mimeType );
00121 }
00122 return m_manifestWriter;
00123 }
00124
00125 bool KoOasisStore::closeManifestWriter()
00126 {
00127 m_manifestWriter->endElement();
00128 m_manifestWriter->endDocument();
00129 QBuffer* buffer = static_cast<QBuffer *>( m_manifestWriter->device() );
00130 delete m_manifestWriter; m_manifestWriter = 0;
00131 bool ok = false;
00132 if ( m_store->open( "META-INF/manifest.xml" ) )
00133 {
00134 qint64 written = m_store->write( buffer->buffer() );
00135 ok = ( written == (qint64) buffer->buffer().size() && m_store->close() );
00136 }
00137 delete buffer;
00138 return ok;
00139 }
00140
00141 bool KoOasisStore::loadAndParse( const QString& fileName, KoXmlDocument& doc, QString& errorMessage )
00142 {
00143
00144
00145 if (!m_store->open(fileName))
00146 {
00147 kWarning(30003) << "Entry " << fileName << " not found!" << endl;
00148 errorMessage = i18n( "Could not find %1", fileName );
00149 return false;
00150 }
00151
00152 QString errorMsg;
00153 int errorLine, errorColumn;
00154
00155
00156
00157
00158
00159 QXmlInputSource source( m_store->device() );
00160
00161 QXmlSimpleReader reader;
00162 KoDocument::setupXmlReader( reader, true );
00163
00164 bool ok = doc.setContent( &source, &reader, &errorMsg, &errorLine, &errorColumn );
00165 if ( !ok )
00166 {
00167 kError(30003) << "Parsing error in " << fileName << "! Aborting!" << endl
00168 << " In line: " << errorLine << ", column: " << errorColumn << endl
00169 << " Error message: " << errorMsg << endl;
00170 errorMessage = i18n( "Parsing error in the main document at line %1, column %2\nError message: %3"
00171 ,errorLine ,errorColumn ,i18n ( "QXml", errorMsg ) );
00172 }
00173 else
00174 {
00175 kDebug(30003) << "File " << fileName << " loaded and parsed" << endl;
00176 }
00177 m_store->close();
00178 return ok;
00179 }
00180
00181 QString KoOasisStore::mimeForPath( const KoXmlDocument& doc, const QString& fullPath )
00182 {
00183 KoXmlElement docElem = doc.documentElement();
00184 KoXmlElement elem;
00185 forEachElement( elem, docElem )
00186 {
00187 if ( elem.localName() == "file-entry" && elem.namespaceURI() == KoXmlNS::manifest )
00188 {
00189 if ( elem.attributeNS( KoXmlNS::manifest, "full-path", QString::null ) == fullPath )
00190 return elem.attributeNS( KoXmlNS::manifest, "media-type", QString::null );
00191 }
00192 }
00193 return QString();
00194 }