00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "KWOasisLoader.h"
00020 #include "KWDocument.h"
00021 #include "KWTextDocument.h"
00022 #include "KWTextFrameSet.h"
00023 #include "KWFrameSet.h"
00024 #include "KWPictureFrameSet.h"
00025 #include "KWLoadingInfo.h"
00026 #include "KWTableFrameSet.h"
00027 #include "KWPartFrameSet.h"
00028 #include "KWPageManager.h"
00029
00030 #include <KoStore.h>
00031 #include <KoOasisContext.h>
00032 #include <KoOasisStyles.h>
00033 #include <KoOasisStore.h>
00034 #include <KoOasisSettings.h>
00035 #include <KoXmlNS.h>
00036 #include <KoDom.h>
00037 #include <KoXmlNS.h>
00038
00039 #include <kdebug.h>
00040 #include <klocale.h>
00041
00042 #include <qvaluelist.h>
00043 #include <qdom.h>
00044
00045 KWOasisLoader::KWOasisLoader( KWDocument* doc )
00046 : m_doc( doc )
00047 {
00048 }
00049
00050
00051
00052 QValueList<KWFrame *> KWOasisLoader::insertOasisData( KoStore* store, KoTextCursor* cursor )
00053 {
00054 QValueList<KWFrame *> frames;
00055 if ( store->bad() || !store->hasFile( "content.xml" ) )
00056 {
00057 kdError(32001) << "Invalid ZIP store in memory" << endl;
00058 if ( !store->hasFile( "content.xml" ) )
00059 kdError(32001) << "No content.xml file" << endl;
00060 return frames;
00061 }
00062 store->disallowNameExpansion();
00063
00064 KoOasisStore oasisStore( store );
00065 QDomDocument contentDoc;
00066 QString errorMessage;
00067 bool ok = oasisStore.loadAndParse( "content.xml", contentDoc, errorMessage );
00068 if ( !ok ) {
00069 kdError(32001) << "Error parsing content.xml: " << errorMessage << endl;
00070 return frames;
00071 }
00072
00073 KoOasisStyles oasisStyles;
00074 QDomDocument stylesDoc;
00075 (void)oasisStore.loadAndParse( "styles.xml", stylesDoc, errorMessage );
00076
00077 oasisStyles.createStyleMap( stylesDoc, true );
00078
00079 oasisStyles.createStyleMap( contentDoc, false );
00080
00081 m_doc->createLoadingInfo();
00082
00083 QDomElement content = contentDoc.documentElement();
00084
00085 QDomElement body( KoDom::namedItemNS( content, KoXmlNS::office, "body" ) );
00086 if ( body.isNull() ) {
00087 kdError(32001) << "No office:body found!" << endl;
00088 return frames;
00089 }
00090
00091
00092 QDomElement iter, realBody;
00093 forEachElement( iter, body ) {
00094 realBody = iter;
00095 }
00096 if ( realBody.isNull() ) {
00097 kdError(32001) << "No element found inside office:body!" << endl;
00098 return frames;
00099 }
00100
00101 KoOasisContext context( m_doc, *m_doc->variableCollection(), oasisStyles, store );
00102 if ( cursor )
00103 {
00104 KWTextDocument * textdoc = static_cast<KWTextDocument *>(cursor->parag()->document());
00105 KWTextFrameSet * textFs = textdoc->textFrameSet();
00106
00107 *cursor = textFs->textObject()->pasteOasisText( realBody, context, *cursor, m_doc->styleCollection() );
00108
00109 textFs->textObject()->setNeedSpellCheck( true );
00110 }
00111 else
00112 {
00113
00114
00115 QDomElement tag;
00116 forEachElement( tag, realBody )
00117 {
00118 context.styleStack().save();
00119 const QString bodyTagLocalName = tag.localName();
00120 kdDebug() << k_funcinfo << bodyTagLocalName << endl;
00121 if ( bodyTagLocalName == "frame" && tag.namespaceURI() == KoXmlNS::draw )
00122 {
00123 KWFrame * frame = loadFrame( tag, context, KoPoint( 10, 10 ) );
00124 if ( frame )
00125 {
00126 frames.append( frame );
00127 }
00128 }
00129 #if 0 // TODO OASIS table:table
00130 else if ( bodyTagLocalName == "table" && tag.namespaceURI() == KoXmlNS::table )
00131 ;
00132 #endif
00133 }
00134 }
00135
00136
00137 m_doc->completeOasisPasting();
00138 m_doc->deleteLoadingInfo();
00139 return frames;
00140 }
00141
00142 void KWOasisLoader::loadOasisSettings( const QDomDocument& settingsDoc )
00143 {
00144 KoOasisSettings settings( settingsDoc );
00145 KoOasisSettings::Items viewSettings = settings.itemSet( "view-settings" );
00146 if ( !viewSettings.isNull() )
00147 {
00148 m_doc->setUnit( KoUnit::unit(viewSettings.parseConfigItemString("unit")) );
00149 }
00150 loadOasisIgnoreList( settings );
00151 m_doc->variableCollection()->variableSetting()->loadOasis( settings );
00152 }
00153
00154 static QString headerTypeToFramesetName( const QString& localName, bool hasEvenOdd )
00155 {
00156 if ( localName == "header" )
00157 return hasEvenOdd ? i18n("Odd Pages Header") : i18n( "Header" );
00158 if ( localName == "header-left" )
00159 return i18n("Even Pages Header");
00160 if ( localName == "footer" )
00161 return hasEvenOdd ? i18n("Odd Pages Footer") : i18n( "Footer" );
00162 if ( localName == "footer-left" )
00163 return i18n("Even Pages Footer");
00164 if ( localName == "header-first" )
00165 return i18n("First Page Header");
00166 if ( localName == "footer-first" )
00167 return i18n("First Page Footer");
00168 kdWarning(32001) << "Unknown tag in headerTypeToFramesetName: " << localName << endl;
00169 return QString::null;
00170 }
00171
00172 static KWFrameSet::Info headerTypeToFrameInfo( const QString& localName, bool )
00173 {
00174 if ( localName == "header" )
00175 return KWFrameSet::FI_ODD_HEADER;
00176 if ( localName == "header-left" )
00177 return KWFrameSet::FI_EVEN_HEADER;
00178 if ( localName == "footer" )
00179 return KWFrameSet::FI_ODD_FOOTER;
00180 if ( localName == "footer-left" )
00181 return KWFrameSet::FI_EVEN_FOOTER;
00182
00183
00184
00185 if ( localName == "header-first" )
00186 return KWFrameSet::FI_FIRST_HEADER;
00187 if ( localName == "footer-first" )
00188 return KWFrameSet::FI_FIRST_FOOTER;
00189 return KWFrameSet::FI_BODY;
00190 }
00191
00192 void KWOasisLoader::loadOasisHeaderFooter( const QDomElement& headerFooter, bool hasEvenOdd, QDomElement& style, KoOasisContext& context )
00193 {
00194 const QString localName = headerFooter.localName();
00195 bool isHeader = localName.startsWith( "header" );
00196
00197 KWTextFrameSet *fs = new KWTextFrameSet( m_doc, headerTypeToFramesetName( localName, hasEvenOdd ) );
00198 fs->setFrameSetInfo( headerTypeToFrameInfo( localName, hasEvenOdd ) );
00199 m_doc->addFrameSet( fs, false );
00200
00201 if ( !style.isNull() )
00202 context.styleStack().push( style );
00203 KWFrame* frame = new KWFrame( fs, 29, isHeader?0:567, 798-29, 41 );
00204 frame->loadCommonOasisProperties( context, fs, "header-footer" );
00205 const QString minHeight = context.styleStack().attributeNS( KoXmlNS::fo, "min-height" );
00206 if ( !minHeight.isEmpty() )
00207 frame->setMinimumFrameHeight( KoUnit::parseValue( minHeight ) );
00208
00209 frame->setFrameBehavior( KWFrame::AutoExtendFrame );
00210 frame->setNewFrameBehavior( KWFrame::Copy );
00211 fs->addFrame( frame );
00212 if ( !style.isNull() )
00213 context.styleStack().pop();
00214
00215 context.setUseStylesAutoStyles( true );
00216 fs->loadOasisContent( headerFooter, context );
00217 context.setUseStylesAutoStyles( false );
00218
00219 if ( isHeader )
00220 m_doc->m_headerVisible = true;
00221 else
00222 m_doc->m_footerVisible = true;
00223 }
00224
00225 void KWOasisLoader::loadOasisIgnoreList( const KoOasisSettings& settings )
00226 {
00227 KoOasisSettings::Items configurationSettings = settings.itemSet( "configuration-settings" );
00228 if ( !configurationSettings.isNull() )
00229 {
00230 const QString ignorelist = configurationSettings.parseConfigItemString( "SpellCheckerIgnoreList" );
00231 kdDebug()<<" ignorelist :"<<ignorelist<<endl;
00232 m_doc->setSpellCheckIgnoreList( QStringList::split( ',', ignorelist ) );
00233 }
00234 }
00235
00236 KWFrame* KWOasisLoader::loadFrame( const QDomElement& frameTag, KoOasisContext& context, const KoPoint& offset )
00237 {
00238 KWFrame* frame = 0;
00239 QDomElement elem;
00240 forEachElement( elem, frameTag )
00241 {
00242 if ( elem.namespaceURI() != KoXmlNS::draw )
00243 continue;
00244 const QString localName = elem.localName();
00245 if ( localName == "text-box" )
00246 {
00247
00248 frame = loadOasisTextBox( frameTag, elem, context );
00249 break;
00250 }
00251 else if ( localName == "image" )
00252 {
00253 KWFrameSet* fs = new KWPictureFrameSet( m_doc, frameTag, elem, context );
00254 m_doc->addFrameSet( fs, false );
00255 frame = fs->frame(0);
00256 break;
00257 } else if ( localName == "object" )
00258 {
00259 KWPartFrameSet* fs = new KWPartFrameSet( m_doc, frameTag, elem, context );
00260 m_doc->addFrameSet( fs, false );
00261 frame = fs->frame(0);
00262 break;
00263 }
00264 }
00265 if ( frame ) {
00266 const QString anchorType = frameTag.attributeNS( KoXmlNS::text, "anchor-type", QString::null );
00267 if ( anchorType == "page" ) {
00268 double x = KoUnit::parseValue( frameTag.attributeNS( KoXmlNS::svg, "x", QString::null ) );
00269 double y = KoUnit::parseValue( frameTag.attributeNS( KoXmlNS::svg, "y", QString::null ) );
00270 int pageNum = frameTag.attributeNS( KoXmlNS::text, "anchor-page-number", QString::null ).toInt();
00271
00272 KWPageManager* pageManager = m_doc->pageManager();
00273 while ( pageNum > pageManager->lastPageNumber() )
00274 pageManager->appendPage();
00275 frame->moveTopLeft( KoPoint( x, y + pageManager->topOfPage(pageNum) ) );
00276 }
00277 frame->moveBy( offset.x(), offset.y() );
00278 }
00279 return frame;
00280 }
00281
00282 KWFrame* KWOasisLoader::loadOasisTextBox( const QDomElement& frameTag, const QDomElement& tag,
00283 KoOasisContext& context )
00284 {
00285
00286
00287
00288
00289
00290
00291
00292 KWLoadingInfo* loadingInfo = m_doc->loadingInfo();
00293 KWTextFrameSet* fs = 0;
00294 QString frameName = frameTag.attributeNS( KoXmlNS::draw, "name", QString::null );
00295 QString chainNextName = tag.attributeNS( KoXmlNS::draw, "chain-next-name", QString::null );
00296 if ( !chainNextName.isEmpty() && loadingInfo ) {
00297 kdDebug(32001) << "Loading " << frameName << " : next-in-chain=" << chainNextName << endl;
00298
00299 KWFrame* nextFrame = loadingInfo->frameByName( chainNextName );
00300 if ( nextFrame ) {
00301 fs = dynamic_cast<KWTextFrameSet *>( nextFrame->frameSet() );
00302 chainNextName = QString::null;
00303 kdDebug(32001) << " found " << nextFrame << " -> frameset " << ( fs ? fs->name() : QString::null ) << endl;
00304 }
00305 }
00306 KWFrame* prevFrame = loadingInfo->chainPrevFrame( frameName );
00307
00308 if ( prevFrame ) {
00309 if ( fs )
00310 Q_ASSERT( fs == prevFrame->frameSet() );
00311 fs = dynamic_cast<KWTextFrameSet *>( prevFrame->frameSet() );
00312
00313 }
00314 KWFrame* frame = 0;
00315 if ( !fs ) {
00316 fs = new KWTextFrameSet( m_doc, frameTag, context );
00317 m_doc->addFrameSet( fs, false );
00318 frame = fs->loadOasis( frameTag, tag, context );
00319 } else {
00320 context.styleStack().save();
00321 context.fillStyleStack( frameTag, KoXmlNS::draw, "style-name", "graphic" );
00322 frame = fs->loadOasisTextFrame( frameTag, tag, context );
00323 context.styleStack().restore();
00324 }
00325
00326 loadingInfo->storeFrameName( frame, frameName );
00327
00328 if ( !chainNextName.isEmpty() ) {
00329 loadingInfo->storeNextFrame( frame, chainNextName );
00330 }
00331 return frame;
00332 }
00333
00334 KWTableFrameSet* KWOasisLoader::loadOasisTable( const QDomElement& tag,
00335 KoOasisContext& context )
00336 {
00337 const QString name = tag.attributeNS( KoXmlNS::table, "name", i18n( "Unnamed Table" ) );
00338 KWTableFrameSet* table = new KWTableFrameSet( m_doc, name );
00339 table->loadOasis( tag, context );
00340 m_doc->addFrameSet(table, false);
00341 return table;
00342 }