00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "ooimpressimport.h"
00023
00024 #include <math.h>
00025
00026 #include <qregexp.h>
00027 #include <qdatetime.h>
00028 #include <qfileinfo.h>
00029 #include <qdir.h>
00030
00031 #include <kzip.h>
00032 #include <karchive.h>
00033 #include <kdebug.h>
00034 #include <KoUnit.h>
00035 #include <KoDocumentInfo.h>
00036 #include <KoDocument.h>
00037
00038 #include <kgenericfactory.h>
00039 #include <KoFilterChain.h>
00040 #include <KoGlobal.h>
00041 #include <ooutils.h>
00042 #include <KoDom.h>
00043 #include <KoOasisSettings.h>
00044
00045 typedef KGenericFactory<OoImpressImport, KoFilter> OoImpressImportFactory;
00046 K_EXPORT_COMPONENT_FACTORY( libooimpressimport, OoImpressImportFactory( "kofficefilters" ) )
00047
00048
00049 OoImpressImport::OoImpressImport( KoFilter *, const char *, const QStringList & )
00050 : KoFilter(),
00051 m_numPicture( 1 ),
00052 m_numSound(1),
00053 m_styles( 23, true ),
00054 m_styleStack( ooNS::style, ooNS::fo )
00055 {
00056 m_styles.setAutoDelete( true );
00057 m_listStyles.setAutoDelete( true );
00058 }
00059
00060 OoImpressImport::~OoImpressImport()
00061 {
00062 QDictIterator<animationList> it( m_animations );
00063 for( ; it.current(); ++it )
00064 {
00065 delete it.current()->element;
00066 }
00067 m_animations.clear();
00068 }
00069
00070 KoFilter::ConversionStatus OoImpressImport::convert( QCString const & from, QCString const & to )
00071 {
00072 kdDebug(30518) << "Entering Ooimpress Import filter: " << from << " - " << to << endl;
00073
00074 if ( (from != "application/vnd.sun.xml.impress" && from != "application/vnd.sun.xml.impress.template" )
00075 || to != "application/x-kpresenter" )
00076 {
00077 kdWarning(30518) << "Invalid mimetypes " << from << " " << to << endl;
00078 return KoFilter::NotImplemented;
00079 }
00080
00081 m_zip = new KZip( m_chain->inputFile() );
00082
00083 if ( !m_zip->open( IO_ReadOnly ) )
00084 {
00085 kdError(30518) << "Couldn't open the requested file "<< m_chain->inputFile() << endl;
00086 delete m_zip;
00087 return KoFilter::FileNotFound;
00088 }
00089
00090 KoFilter::ConversionStatus preStatus = openFile();
00091
00092 if ( preStatus != KoFilter::OK )
00093 {
00094 m_zip->close();
00095 delete m_zip;
00096 return preStatus;
00097 }
00098
00099 QDomDocument docinfo;
00100 createDocumentInfo( docinfo );
00101
00102
00103 KoStoreDevice* out = m_chain->storageFile( "documentinfo.xml", KoStore::Write );
00104 if( out )
00105 {
00106 QCString info = docinfo.toCString();
00107
00108
00109 out->writeBlock( info , info.length() );
00110 }
00111
00112 QDomDocument doccontent;
00113 createDocumentContent( doccontent );
00114
00115
00116 out = m_chain->storageFile( "maindoc.xml", KoStore::Write );
00117 if( out )
00118 {
00119 QCString content = doccontent.toCString();
00120 kdDebug(30518) << " content :" << content << endl;
00121 out->writeBlock( content , content.length() );
00122 }
00123
00124 m_zip->close();
00125 delete m_zip;
00126
00127 kdDebug(30518) << "######################## OoImpressImport::convert done ####################" << endl;
00128 return KoFilter::OK;
00129 }
00130
00131
00132 KoFilter::ConversionStatus OoImpressImport::openFile()
00133 {
00134 KoFilter::ConversionStatus status = loadAndParse( "content.xml", m_content );
00135 if ( status != KoFilter::OK )
00136 {
00137 kdError(30518) << "Content.xml could not be parsed correctly! Aborting!" << endl;
00138 return status;
00139 }
00140
00141
00142 QDomDocument styles;
00143 loadAndParse( "styles.xml", styles );
00144 loadAndParse( "meta.xml", m_meta );
00145 loadAndParse( "settings.xml", m_settings );
00146
00147 emit sigProgress( 10 );
00148 createStyleMap( styles );
00149
00150 return KoFilter::OK;
00151 }
00152
00153 KoFilter::ConversionStatus OoImpressImport::loadAndParse(const QString& filename, QDomDocument& doc)
00154 {
00155 return OoUtils::loadAndParse( filename, doc, m_zip);
00156 }
00157
00158
00159 void OoImpressImport::createDocumentInfo( QDomDocument &docinfo )
00160 {
00161 docinfo = KoDocument::createDomDocument( "document-info" , "document-info" , "1.1" );
00162
00163 OoUtils::createDocumentInfo(m_meta, docinfo);
00164
00165 }
00166
00167 void OoImpressImport::createDocumentContent( QDomDocument &doccontent )
00168 {
00169 QDomDocument doc = KoDocument::createDomDocument( "kpresenter", "DOC", "1.2" );
00170 QDomElement docElement = doc.documentElement();
00171 docElement.setAttribute( "editor", "KPresenter" );
00172 docElement.setAttribute( "mime", "application/x-kpresenter" );
00173 docElement.setAttribute( "syntaxVersion", "2" );
00174
00175 QDomElement content = m_content.documentElement();
00176
00177
00178 QDomNode automaticStyles = KoDom::namedItemNS( content, ooNS::office, "automatic-styles" );
00179 if ( !automaticStyles.isNull() )
00180 insertStyles( automaticStyles.toElement() );
00181
00182 QDomNode body = KoDom::namedItemNS( content, ooNS::office, "body" );
00183 if ( body.isNull() )
00184 return;
00185
00186 QDomElement customSlideShow = doc.createElement( "CUSTOMSLIDESHOWCONFIG" );
00187
00188
00189 QDomElement settings = KoDom::namedItemNS( body, ooNS::presentation, "settings");
00190 if (!settings.isNull())
00191 {
00192 if (settings.attributeNS( ooNS::presentation, "endless", QString::null)=="true")
00193 {
00194 QDomElement infElem = doc.createElement("INFINITLOOP");
00195 infElem.setAttribute("value", 1);
00196 docElement.appendChild(infElem);
00197 }
00198
00199 if (settings.attributeNS( ooNS::presentation, "force-manual", QString::null)=="true")
00200 {
00201 QDomElement manualElem = doc.createElement("MANUALSWITCH");
00202 manualElem.setAttribute("value", 1);
00203 docElement.appendChild(manualElem);
00204 }
00205 if ( settings.hasAttributeNS( ooNS::presentation, "show") )
00206 {
00207 QDomElement defaultPage = doc.createElement("DEFAULTCUSTOMSLIDESHOWNAME");
00208 defaultPage.setAttribute("name", settings.attributeNS( ooNS::presentation, "show", QString::null) );
00209 docElement.appendChild(defaultPage);
00210 }
00211 }
00212
00213 QDomElement presentationShow;
00214 forEachElement( presentationShow, settings )
00215 {
00216 if ( presentationShow.localName()=="show" && presentationShow.namespaceURI() == ooNS::presentation )
00217 {
00218 if ( presentationShow.hasAttributeNS( ooNS::presentation, "pages") &&
00219 presentationShow.hasAttributeNS( ooNS::presentation, "name"))
00220 {
00221 QDomElement slide=doc.createElement("CUSTOMSLIDESHOW");
00222 slide.setAttribute( "pages", presentationShow.attributeNS( ooNS::presentation, "pages", QString::null ));
00223 slide.setAttribute( "name", presentationShow.attributeNS( ooNS::presentation, "name", QString::null ));
00224 customSlideShow.appendChild( slide );
00225 }
00226 }
00227 }
00228
00229
00230 QDomElement drawPage = KoDom::namedItemNS( body, ooNS::draw, "page" );
00231 if ( drawPage.isNull() )
00232 return;
00233
00234 QDomElement objectElement = doc.createElement( "OBJECTS" );
00235 QDomElement pictureElement = doc.createElement( "PICTURES" );
00236 QDomElement pageTitleElement = doc.createElement( "PAGETITLES" );
00237 QDomElement pageNoteElement = doc.createElement( "PAGENOTES" );
00238 QDomElement backgroundElement = doc.createElement( "BACKGROUND" );
00239 QDomElement soundElement = doc.createElement( "SOUNDS" );
00240 QDomElement selSlideElement = doc.createElement( "SELSLIDES" );
00241 QDomElement helpLineElement = doc.createElement( "HELPLINES" );
00242 QDomElement attributeElement = doc.createElement( "ATTRIBUTES" );
00243 QDomElement *master = m_styles[drawPage.attributeNS( ooNS::draw, "master-page-name", QString::null )];
00244
00245 appendObject(*master, doc, soundElement,pictureElement,pageNoteElement,objectElement, 0, true);
00246
00247 QDomElement *style = m_styles[master->attributeNS( ooNS::style, "page-master-name", QString::null )];
00248 QDomElement properties = KoDom::namedItemNS( *style, ooNS::style, "properties" );
00249
00250 QDomElement *backgroundStyle = m_stylesPresentation[ master->attributeNS( ooNS::draw, "style-name", QString::null ).isEmpty() ? "Standard-background" : master->attributeNS( ooNS::draw, "style-name", QString::null ) ];
00251
00252
00253 double pageHeight;
00254 QDomElement paperElement = doc.createElement( "PAPER" );
00255 if ( properties.isNull() )
00256 {
00257 paperElement.setAttribute( "ptWidth", CM_TO_POINT(28) );
00258 paperElement.setAttribute( "ptHeight", CM_TO_POINT(21) );
00259 paperElement.setAttribute( "unit", 0 );
00260 paperElement.setAttribute( "format", 5 );
00261 paperElement.setAttribute( "tabStopValue", 42.5198 );
00262 paperElement.setAttribute( "orientation", 0 );
00263 pageHeight = 21;
00264
00265 QDomElement paperBorderElement = doc.createElement( "PAPERBORDERS" );
00266 paperBorderElement.setAttribute( "ptRight", 0 );
00267 paperBorderElement.setAttribute( "ptBottom", 0 );
00268 paperBorderElement.setAttribute( "ptLeft", 0 );
00269 paperBorderElement.setAttribute( "ptTop", 0 );
00270 paperElement.appendChild( paperBorderElement );
00271 }
00272 else
00273 {
00274 paperElement.setAttribute( "ptWidth", KoUnit::parseValue(properties.attributeNS( ooNS::fo, "page-width", QString::null ) ) );
00275 paperElement.setAttribute( "ptHeight", KoUnit::parseValue(properties.attributeNS( ooNS::fo, "page-height", QString::null ) ) );
00276
00277
00278
00279
00280
00281
00282
00283 if (properties.attributeNS( ooNS::style, "print-orientation", QString::null)=="portrait")
00284 paperElement.setAttribute("orientation", 0);
00285 else if (properties.attributeNS( ooNS::style, "print-orientation", QString::null)=="landscape")
00286 paperElement.setAttribute("orientation", 1);
00287
00288
00289
00290 pageHeight = properties.attributeNS( ooNS::fo, "page-height", QString::null ).remove( "cm" ).toDouble();
00291
00292 QDomElement paperBorderElement = doc.createElement( "PAPERBORDERS" );
00293 paperBorderElement.setAttribute( "ptRight", KoUnit::parseValue( properties.attributeNS( ooNS::fo, "margin-right", QString::null ) ) );
00294 paperBorderElement.setAttribute( "ptBottom", KoUnit::parseValue( properties.attributeNS( ooNS::fo, "margin-bottom", QString::null ) ) );
00295 paperBorderElement.setAttribute( "ptLeft", KoUnit::parseValue( properties.attributeNS( ooNS::fo, "margin-left", QString::null ) ) );
00296 paperBorderElement.setAttribute( "ptTop", KoUnit::parseValue( properties.attributeNS( ooNS::fo, "margin-top", QString::null ) ) );
00297 paperElement.appendChild( paperBorderElement );
00298 }
00299
00300
00301
00302 forEachElement( drawPage, body )
00303 {
00304 if ( drawPage.localName()=="page" && drawPage.namespaceURI() == ooNS::draw && drawPage.hasAttributeNS( ooNS::draw, "id" ))
00305 {
00306 m_styleStack.clear();
00307 fillStyleStack( drawPage );
00308 m_styleStack.save();
00309 int pagePos = drawPage.attributeNS( ooNS::draw, "id", QString::null ).toInt() - 1;
00310
00311 if ( m_styleStack.hasAttributeNS( ooNS::draw, "fill" )
00312 || m_styleStack.hasAttributeNS( ooNS::presentation, "transition-style" ))
00313 {
00314 appendBackgroundPage( doc, backgroundElement,pictureElement, soundElement );
00315 }
00316 else if ( !m_styleStack.hasAttributeNS( ooNS::draw, "fill" ) && backgroundStyle)
00317 {
00318 m_styleStack.save();
00319 m_styleStack.push( *backgroundStyle );
00320 appendBackgroundPage( doc, backgroundElement,pictureElement, soundElement );
00321 m_styleStack.restore();
00322 kdDebug(30518)<<" load standard bacground \n";
00323 }
00324 if ( m_styleStack.hasAttributeNS( ooNS::presentation, "visibility" ) )
00325 {
00326 QString str = m_styleStack.attributeNS( ooNS::presentation, "visibility" );
00327 QDomElement slide = doc.createElement("SLIDE");
00328 slide.setAttribute( "nr", pagePos );
00329 slide.setAttribute( "show", ( ( str=="hidden" ) ? "0" : "1" ));
00330 selSlideElement.appendChild( slide );
00331
00332
00333 kdDebug(30518)<<"m_styleStack.hasAttribute( presentation:visibility ) :"<<str<<" position page "<<pagePos<<endl;
00334 }
00335
00336 QDomElement titleElement = doc.createElement( "Title" );
00337 titleElement.setAttribute( "title", drawPage.attributeNS( ooNS::draw, "name", QString::null ) );
00338 pageTitleElement.appendChild( titleElement );
00339
00340
00341
00342 double offset = CM_TO_POINT( ( drawPage.attributeNS( ooNS::draw, "id", QString::null ).toInt() - 1 ) * pageHeight ) + 1;
00343
00344
00345 createPresentationAnimation(KoDom::namedItemNS( drawPage, ooNS::presentation, "animations") );
00346
00347
00348 appendObject(drawPage, doc, soundElement,pictureElement,pageNoteElement,objectElement, offset);
00349
00350
00351 m_styleStack.restore();
00352 }
00353 }
00354
00355 docElement.appendChild( paperElement );
00356 docElement.appendChild( backgroundElement );
00357 if ( parseSettings( doc, helpLineElement, attributeElement ) )
00358 docElement.appendChild( helpLineElement );
00359 docElement.appendChild( attributeElement );
00360 docElement.appendChild( pageTitleElement );
00361 docElement.appendChild( pageNoteElement );
00362 docElement.appendChild( objectElement );
00363 docElement.appendChild( selSlideElement );
00364 docElement.appendChild( customSlideShow );
00365 docElement.appendChild( soundElement );
00366 docElement.appendChild( pictureElement );
00367
00368 doccontent.appendChild( doc );
00369 }
00370
00371 bool OoImpressImport::parseSettings( QDomDocument &doc, QDomElement &helpLineElement, QDomElement &attributeElement )
00372 {
00373 bool foundElement = false;
00374 KoOasisSettings settings( m_settings, ooNS::office, ooNS::config );
00375 KoOasisSettings::Items viewSettings = settings.itemSet( "view-settings" );
00376
00377 KoOasisSettings::IndexedMap viewMap = viewSettings.indexedMap( "Views" );
00378 KoOasisSettings::Items firstView = viewMap.entry( 0 );
00379
00380
00381
00382 if ( !firstView.isNull() )
00383 {
00384 QString str = firstView.parseConfigItemString( "SnapLinesDrawing" );
00385 if ( !str.isEmpty() )
00386 {
00387 parseHelpLine( doc, helpLineElement, str );
00388
00389 helpLineElement.setAttribute( "show", true );
00390 foundElement = true;
00391 }
00392
00393 int gridX = firstView.parseConfigItemInt( "GridFineWidth" );
00394 int gridY = firstView.parseConfigItemInt( "GridFineHeight" );
00395 bool snapToGrid = firstView.parseConfigItemBool( "IsSnapToGrid" );
00396 int selectedPage = firstView.parseConfigItemInt( "SelectedPage" );
00397
00398 attributeElement.setAttribute( "activePage", selectedPage );
00399 attributeElement.setAttribute( "gridx", MM_TO_POINT( gridX / 100.0 ) );
00400 attributeElement.setAttribute( "gridy", MM_TO_POINT( gridY / 100.0 ) );
00401 attributeElement.setAttribute( "snaptogrid", (int)snapToGrid );
00402
00403 }
00404
00405
00406 return foundElement;
00407 }
00408
00409 void OoImpressImport::parseHelpLine( QDomDocument &doc,QDomElement &helpLineElement, const QString &text )
00410 {
00411 QString str;
00412 int newPos = text.length()-1;
00413 for ( int pos = text.length()-1; pos >=0;--pos )
00414 {
00415 if ( text[pos]=='P' )
00416 {
00417
00418
00419 str = text.mid( pos+1, ( newPos-pos ) );
00420 QDomElement point=doc.createElement("HelpPoint");
00421
00422
00423 QStringList listVal = QStringList::split( ",", str );
00424 int posX = ( listVal[0].toInt()/100 );
00425 int posY = ( listVal[1].toInt()/100 );
00426 point.setAttribute("posX", MM_TO_POINT( posX ));
00427 point.setAttribute("posY", MM_TO_POINT( posY ));
00428
00429 helpLineElement.appendChild( point );
00430 newPos = pos-1;
00431 }
00432 else if ( text[pos]=='V' )
00433 {
00434 QDomElement lines=doc.createElement("Vertical");
00435
00436 str = text.mid( pos+1, ( newPos-pos ) );
00437
00438 int posX = ( str.toInt()/100 );
00439 lines.setAttribute( "value", MM_TO_POINT( posX ) );
00440 helpLineElement.appendChild( lines );
00441
00442 newPos = ( pos-1 );
00443
00444 }
00445 else if ( text[pos]=='H' )
00446 {
00447
00448 QDomElement lines=doc.createElement("Horizontal");
00449 str = text.mid( pos+1, ( newPos-pos ) );
00450
00451 int posY = ( str.toInt()/100 );
00452 lines.setAttribute( "value", MM_TO_POINT( posY ) );
00453 helpLineElement.appendChild( lines );
00454 newPos = pos-1;
00455 }
00456 }
00457 }
00458
00459 void OoImpressImport::appendObject(QDomNode & drawPage, QDomDocument & doc, QDomElement & soundElement, QDomElement & pictureElement, QDomElement & pageNoteElement, QDomElement &objectElement, double offset, bool sticky)
00460 {
00461 QDomElement o;
00462 forEachElement( o, drawPage )
00463 {
00464 const QString localName = o.localName();
00465 const QString ns = o.namespaceURI();
00466 const QString drawID = o.attributeNS( ooNS::draw, "id", QString::null);
00467 m_styleStack.save();
00468
00469 QDomElement e;
00470 if ( localName == "text-box" && ns == ooNS::draw )
00471 {
00472 fillStyleStack( o, sticky );
00473 e = doc.createElement( "OBJECT" );
00474 e.setAttribute( "type", 4 );
00475 if ( sticky )
00476 e.setAttribute( "sticky", "1" );
00477 append2DGeometry( doc, e, o, (int)offset );
00478 appendName(doc, e, o);
00479 appendPen( doc, e );
00480 appendBrush( doc, e );
00481 appendRounding( doc, e, o );
00482 appendShadow( doc, e );
00483 appendObjectEffect(doc, e, o, soundElement);
00484 e.appendChild( parseTextBox( doc, o ) );
00485 }
00486 else if ( localName == "rect" && ns == ooNS::draw )
00487 {
00488 fillStyleStack( o, sticky );
00489 e = doc.createElement( "OBJECT" );
00490 e.setAttribute( "type", 2 );
00491 if ( sticky )
00492 e.setAttribute( "sticky", "1" );
00493 append2DGeometry( doc, e, o, (int)offset );
00494 appendName(doc, e, o);
00495 appendPen( doc, e );
00496 appendBrush( doc, e );
00497 appendRounding( doc, e, o );
00498 appendShadow( doc, e );
00499
00500 appendObjectEffect(doc, e, o, soundElement);
00501 }
00502 else if ( ( localName == "circle" || localName == "ellipse" ) && ns == ooNS::draw )
00503 {
00504 fillStyleStack( o, sticky );
00505 e = doc.createElement( "OBJECT" );
00506 if ( sticky )
00507 e.setAttribute( "sticky", "1" );
00508 append2DGeometry( doc, e, o, (int)offset );
00509 appendName(doc, e, o);
00510 appendPen( doc, e );
00511 appendShadow( doc, e );
00512 appendLineEnds( doc, e );
00513 appendObjectEffect(doc, e, o, soundElement);
00514
00515 if ( o.hasAttributeNS( ooNS::draw, "kind" ) )
00516 {
00517 e.setAttribute( "type", 8 );
00518 appendPie( doc, e, o );
00519 QDomElement type = doc.createElement( "PIETYPE" );
00520
00521 QString kind = o.attributeNS( ooNS::draw, "kind", QString::null );
00522 if ( kind == "section" )
00523 {
00524 appendBrush( doc, e );
00525 type.setAttribute( "value", 0 );
00526 }
00527 else if ( kind == "cut" )
00528 {
00529 appendBrush( doc, e );
00530 type.setAttribute( "value", 2 );
00531 }
00532 else if ( kind == "arc" )
00533 {
00534
00535 type.setAttribute( "value", 1 );
00536 }
00537 e.appendChild( type );
00538 }
00539 else
00540 {
00541 e.setAttribute( "type", 3 );
00542 appendBrush( doc, e );
00543 }
00544 }
00545 else if ( localName == "line" && ns == ooNS::draw )
00546 {
00547 fillStyleStack( o, sticky );
00548 e = doc.createElement( "OBJECT" );
00549 e.setAttribute( "type", 1 );
00550 if ( sticky )
00551 e.setAttribute( "sticky", "1" );
00552 bool orderEndStartLine = appendLineGeometry( doc, e, o, (int)offset );
00553 appendName(doc, e, o);
00554 appendPen( doc, e );
00555 appendBrush( doc, e );
00556 appendShadow( doc, e );
00557 appendLineEnds( doc, e, orderEndStartLine );
00558 appendObjectEffect(doc, e, o, soundElement);
00559 }
00560 else if ( localName=="polyline" && ns == ooNS::draw ) {
00561 fillStyleStack(o, sticky);
00562 e = doc.createElement("OBJECT");
00563 e.setAttribute("type", 12);
00564 if ( sticky )
00565 e.setAttribute( "sticky", "1" );
00566 append2DGeometry(doc, e, o, (int)offset);
00567 appendName(doc, e, o);
00568 appendPoints(doc, e, o);
00569 appendPen(doc, e);
00570 appendBrush(doc, e);
00571 appendLineEnds(doc, e);
00572
00573 appendObjectEffect(doc, e, o, soundElement);
00574 }
00575 else if ( localName=="polygon" && ns == ooNS::draw ) {
00576 fillStyleStack(o, sticky);
00577 e = doc.createElement("OBJECT");
00578 e.setAttribute("type", 16);
00579 if ( sticky )
00580 e.setAttribute( "sticky", "1" );
00581 append2DGeometry(doc, e, o, (int)offset);
00582 appendName(doc, e, o);
00583 appendPoints(doc, e, o);
00584 appendPen(doc, e);
00585 appendBrush(doc, e);
00586
00587
00588 appendObjectEffect(doc, e, o, soundElement);
00589 }
00590 else if ( localName == "image" && ns == ooNS::draw )
00591 {
00592 fillStyleStack( o, sticky );
00593 e = doc.createElement( "OBJECT" );
00594 e.setAttribute( "type", 0 );
00595 if ( sticky )
00596 e.setAttribute( "sticky", "1" );
00597 append2DGeometry( doc, e, o, (int)offset );
00598 appendName(doc, e, o);
00599 appendImage( doc, e, pictureElement, o );
00600 appendObjectEffect(doc, e, o, soundElement);
00601 }
00602 else if ( localName == "object" && ns == ooNS::draw )
00603 {
00604
00605 }
00606 else if ( localName == "g" && ns == ooNS::draw )
00607 {
00608
00609 }
00610 else if ( localName == "path" && ns == ooNS::draw )
00611 {
00612
00613 }
00614 else if ( localName == "notes" && ns == ooNS::presentation )
00615 {
00616 QDomNode textBox = KoDom::namedItemNS( o, ooNS::draw, "text-box" );
00617 if ( !textBox.isNull() )
00618 {
00619 QString note;
00620 QDomElement t;
00621 forEachElement( t, textBox )
00622 {
00623
00624
00625 note += t.text() + "\n";
00626 }
00627 QDomElement notesElement = doc.createElement( "Note" );
00628 notesElement.setAttribute( "note", note );
00629 pageNoteElement.appendChild( notesElement );
00630 }
00631 }
00632 else
00633 {
00634 kdDebug(30518) << "Unsupported object '" << localName << "'" << endl;
00635 m_styleStack.restore();
00636 continue;
00637 }
00638
00639 objectElement.appendChild( e );
00640 m_styleStack.restore();
00641 }
00642 }
00643
00644 void OoImpressImport::appendBackgroundPage( QDomDocument &doc, QDomElement &backgroundElement, QDomElement & pictureElement, QDomElement &soundElement)
00645 {
00646 QDomElement bgPage = doc.createElement( "PAGE" );
00647
00648
00649 if ( m_styleStack.hasAttributeNS( ooNS::draw, "fill" ) )
00650 {
00651 const QString fill = m_styleStack.attributeNS( ooNS::draw, "fill" );
00652 if ( fill == "solid" )
00653 {
00654 QDomElement backColor1 = doc.createElement( "BACKCOLOR1" );
00655 backColor1.setAttribute( "color", m_styleStack.attributeNS( ooNS::draw, "fill-color" ) );
00656 bgPage.appendChild( backColor1 );
00657
00658 QDomElement bcType = doc.createElement( "BCTYPE" );
00659 bcType.setAttribute( "value", 0 );
00660 bgPage.appendChild( bcType );
00661
00662 QDomElement backType = doc.createElement( "BACKTYPE" );
00663 backType.setAttribute( "value", 0 );
00664 bgPage.appendChild( backType );
00665 }
00666 else if ( fill == "gradient" )
00667 {
00668 QString style = m_styleStack.attributeNS( ooNS::draw, "fill-gradient-name" );
00669 QDomElement* draw = m_draws[style];
00670 appendBackgroundGradient( doc, bgPage, *draw );
00671 }
00672 else if ( fill == "bitmap" )
00673 {
00674 QString style = m_styleStack.attributeNS( ooNS::draw, "fill-image-name" );
00675 QDomElement* draw = m_draws[style];
00676 appendBackgroundImage( doc, bgPage, pictureElement, *draw );
00677
00678 QDomElement backView = doc.createElement( "BACKVIEW" );
00679 if ( m_styleStack.hasAttributeNS( ooNS::style, "repeat" ) )
00680 {
00681 QString repeat = m_styleStack.attributeNS( ooNS::style, "repeat" );
00682 if ( repeat == "stretch" )
00683 backView.setAttribute( "value", 0 );
00684 else if ( repeat == "no-repeat" )
00685 backView.setAttribute( "value", 1 );
00686 else
00687 backView.setAttribute( "value", 2 );
00688 }
00689 else
00690 backView.setAttribute( "value", 2 );
00691 bgPage.appendChild( backView );
00692
00693 QDomElement backType = doc.createElement( "BACKTYPE" );
00694 backType.setAttribute( "value", 1 );
00695 bgPage.appendChild( backType );
00696 }
00697 }
00698
00699 if ( m_styleStack.hasAttributeNS( ooNS::presentation, "duration" ) )
00700 {
00701 QString str = m_styleStack.attributeNS( ooNS::presentation, "duration");
00702 kdDebug(30518)<<"styleStack.hasAttribute(presentation:duration ) :"<<str<<endl;
00703
00704 int hour( str.mid( 2, 2 ).toInt() );
00705 int minute( str.mid( 5, 2 ).toInt() );
00706 int second( str.mid( 8, 2 ).toInt() );
00707 int pageTimer = second + minute*60 + hour*60*60;
00708 QDomElement pgEffect = doc.createElement("PGTIMER");
00709 pgEffect.setAttribute( "timer", pageTimer );
00710 bgPage.appendChild(pgEffect);
00711 }
00712
00713 if (m_styleStack.hasAttributeNS( ooNS::presentation, "transition-style"))
00714 {
00715 QDomElement pgEffect = doc.createElement("PGEFFECT");
00716
00717 const QString effect = m_styleStack.attributeNS( ooNS::presentation, "transition-style");
00718
00719 int pef;
00720
00721 if (effect=="vertical-stripes" || effect=="vertical-lines")
00722 pef=14;
00723 else if (effect=="horizontal-stripes" || effect=="horizontal-lines")
00724 pef=13;
00725 else if (effect=="spiralin-left" || effect=="spiralin-right"
00726 || effect== "spiralout-left" || effect=="spiralout-right")
00727 pef=11;
00728 else if (effect=="fade-from-upperleft")
00729 pef=39;
00730 else if (effect=="fade-from-upperright")
00731 pef=37;
00732 else if (effect=="fade-from-lowerleft")
00733 pef=38;
00734 else if (effect=="fade-from-lowerright")
00735 pef=36;
00736 else if (effect=="fade-from-top")
00737 pef=19;
00738 else if (effect=="fade-from-bottom")
00739 pef=21;
00740 else if (effect=="fade-from-left")
00741 pef=25;
00742 else if (effect=="fade-from-right")
00743 pef=23;
00744 else if (effect=="fade-to-center")
00745 pef=3;
00746 else if (effect=="fade-from-center")
00747 pef=6;
00748 else if (effect=="open-vertical")
00749 pef=4;
00750 else if (effect=="open-horizontal")
00751 pef=5;
00752 else if (effect=="close-vertical")
00753 pef=1;
00754 else if (effect=="close-horizontal")
00755 pef=2;
00756 else if (effect=="dissolve")
00757 pef=35;
00758 else if (effect=="horizontal-checkerboard")
00759 pef=17;
00760 else if (effect=="vertical-checkerboard")
00761 pef=18;
00762 else if (effect=="roll-from-left")
00763 pef=26;
00764 else if (effect=="roll-from-right")
00765 pef=24;
00766 else if (effect=="roll-from-bottom")
00767 pef=22;
00768 else if (effect=="roll-from-top")
00769 pef=20;
00770 else if (effect=="random")
00771 pef=-1;
00772 else
00773 pef=-1;
00774
00775 pgEffect.setAttribute("value", pef);
00776 bgPage.appendChild(pgEffect);
00777 }
00778
00779
00780 if (m_styleStack.hasChildNodeNS( ooNS::presentation, "sound"))
00781 {
00782 QString soundUrl = storeSound(m_styleStack.childNodeNS( ooNS::presentation, "sound"),
00783 soundElement, doc);
00784
00785 if (!soundUrl.isNull())
00786 {
00787 QDomElement pseElem = doc.createElement("PGSOUNDEFFECT");
00788 pseElem.setAttribute("soundEffect", 1);
00789 pseElem.setAttribute("soundFileName", soundUrl);
00790
00791 bgPage.appendChild(pseElem);
00792 }
00793 }
00794
00795 backgroundElement.appendChild(bgPage);
00796 }
00797
00798 void OoImpressImport::appendName(QDomDocument& doc, QDomElement& e, const QDomElement& object)
00799 {
00800 if( object.hasAttributeNS( ooNS::draw, "name" ))
00801 {
00802 QDomElement name = doc.createElement( "OBJECTNAME" );
00803 name.setAttribute( "objectName", object.attributeNS( ooNS::draw, "name", QString::null ));
00804 e.appendChild( name );
00805 }
00806 }
00807
00808 void OoImpressImport::append2DGeometry( QDomDocument& doc, QDomElement& e, const QDomElement& object, int offset )
00809 {
00810 QDomElement orig = doc.createElement( "ORIG" );
00811 orig.setAttribute( "x", KoUnit::parseValue( object.attributeNS( ooNS::svg, "x", QString::null ) ) );
00812 orig.setAttribute( "y", KoUnit::parseValue( object.attributeNS( ooNS::svg, "y", QString::null ) ) + offset );
00813 e.appendChild( orig );
00814
00815 QDomElement size = doc.createElement( "SIZE" );
00816 size.setAttribute( "width", KoUnit::parseValue( object.attributeNS( ooNS::svg, "width", QString::null ) ) );
00817 size.setAttribute( "height", KoUnit::parseValue( object.attributeNS( ooNS::svg, "height", QString::null ) ) );
00818 e.appendChild( size );
00819 if( object.hasAttributeNS( ooNS::draw, "transform" ))
00820 {
00821 kdDebug(30518)<<" object transform \n";
00822
00823 QString transform = object.attributeNS( ooNS::draw, "transform", QString::null );
00824 if( transform.contains("rotate ("))
00825 {
00826
00827 transform = transform.remove("rotate (" );
00828 transform = transform.left(transform.find(")"));
00829
00830 bool ok;
00831 double radian = transform.toDouble(&ok);
00832 if( ok )
00833 {
00834 QDomElement angle = doc.createElement( "ANGLE" );
00835
00836 angle.setAttribute("value", (-1 * ((radian*180)/M_PI)));
00837
00838 e.appendChild( angle );
00839 }
00840 }
00841 }
00842 }
00843
00844
00845 bool OoImpressImport::appendLineGeometry( QDomDocument& doc, QDomElement& e, const QDomElement& object, int offset )
00846 {
00847 double x1 = KoUnit::parseValue( object.attributeNS( ooNS::svg, "x1", QString::null ) );
00848 double y1 = KoUnit::parseValue( object.attributeNS( ooNS::svg, "y1", QString::null ) );
00849 double x2 = KoUnit::parseValue( object.attributeNS( ooNS::svg, "x2", QString::null ) );
00850 double y2 = KoUnit::parseValue( object.attributeNS( ooNS::svg, "y2", QString::null ) );
00851
00852 double x = QMIN( x1, x2 );
00853 double y = QMIN( y1, y2 );
00854
00855 QDomElement orig = doc.createElement( "ORIG" );
00856 orig.setAttribute( "x", x );
00857 orig.setAttribute( "y", y + offset );
00858 e.appendChild( orig );
00859
00860 QDomElement size = doc.createElement( "SIZE" );
00861 size.setAttribute( "width", fabs( x1 - x2 ) );
00862 size.setAttribute( "height", fabs( y1 - y2 ) );
00863 e.appendChild( size );
00864
00865 QDomElement linetype = doc.createElement( "LINETYPE" );
00866 if ( ( x1 < x2 && y1 < y2 ) || ( x1 > x2 && y1 > y2 ) )
00867 linetype.setAttribute( "value", 2 );
00868 else
00869 linetype.setAttribute( "value", 3 );
00870
00871 e.appendChild( linetype );
00872 return (x1 < x2);
00873 }
00874
00875 void OoImpressImport::appendPen( QDomDocument& doc, QDomElement& e )
00876 {
00877 if ( m_styleStack.hasAttributeNS( ooNS::draw, "stroke" ))
00878 {
00879 QDomElement pen = doc.createElement( "PEN" );
00880 if ( m_styleStack.attributeNS( ooNS::draw, "stroke" ) == "none" )
00881 pen.setAttribute( "style", 0 );
00882 else if ( m_styleStack.attributeNS( ooNS::draw, "stroke" ) == "solid" )
00883 pen.setAttribute( "style", 1 );
00884 else if ( m_styleStack.attributeNS( ooNS::draw, "stroke" ) == "dash" )
00885 {
00886 QString style = m_styleStack.attributeNS( ooNS::draw, "stroke-dash" );
00887 if ( style == "Ultrafine Dashed" || style == "Fine Dashed" ||
00888 style == "Fine Dashed (var)" || style == "Dashed (var)" )
00889 pen.setAttribute( "style", 2 );
00890 else if ( style == "Fine Dotted" || style == "Ultrafine Dotted (var)" ||
00891 style == "Line with Fine Dots" )
00892 pen.setAttribute( "style", 3 );
00893 else if ( style == "3 Dashes 3 Dots (var)" || style == "Ultrafine 2 Dots 3 Dashes" )
00894 pen.setAttribute( "style", 4 );
00895 else if ( style == "2 Dots 1 Dash" )
00896 pen.setAttribute( "style", 5 );
00897 }
00898
00899 if ( m_styleStack.hasAttributeNS( ooNS::svg, "stroke-width" ) )
00900 pen.setAttribute( "width", (int) KoUnit::parseValue( m_styleStack.attributeNS( ooNS::svg, "stroke-width" ) ) );
00901 if ( m_styleStack.hasAttributeNS( ooNS::svg, "stroke-color" ) )
00902 pen.setAttribute( "color", m_styleStack.attributeNS( ooNS::svg, "stroke-color" ) );
00903 e.appendChild( pen );
00904 }
00905 }
00906
00907 void OoImpressImport::appendBrush( QDomDocument& doc, QDomElement& e )
00908 {
00909 if ( m_styleStack.hasAttributeNS( ooNS::draw, "fill" ) )
00910 {
00911 const QString fill = m_styleStack.attributeNS( ooNS::draw, "fill" );
00912
00913 if ( fill == "solid" )
00914 {
00915 QDomElement brush = doc.createElement( "BRUSH" );
00916 if ( m_styleStack.hasAttributeNS( ooNS::draw, "transparency" ) )
00917 {
00918 QString transparency = m_styleStack.attributeNS( ooNS::draw, "transparency" );
00919 transparency = transparency.remove( '%' );
00920 int value = transparency.toInt();
00921 if ( value >= 94 && value <= 99 )
00922 {
00923 brush.setAttribute( "style", 2 );
00924 }
00925 else if ( value>=64 && value <= 93 )
00926 {
00927 brush.setAttribute( "style", 3 );
00928 }
00929 else if ( value>=51 && value <= 63 )
00930 {
00931 brush.setAttribute( "style", 4 );
00932 }
00933 else if ( value>=38 && value <= 50 )
00934 {
00935 brush.setAttribute( "style", 5 );
00936 }
00937 else if ( value>=13 && value <= 37 )
00938 {
00939 brush.setAttribute( "style", 6 );
00940 }
00941 else if ( value>=7 && value <= 12 )
00942 {
00943 brush.setAttribute( "style", 7 );
00944 }
00945 else if ( value>=1 && value <= 6 )
00946 {
00947 brush.setAttribute( "style", 8 );
00948 }
00949 }
00950 else
00951 brush.setAttribute( "style", 1 );
00952 if ( m_styleStack.hasAttributeNS( ooNS::draw, "fill-color" ) )
00953 brush.setAttribute( "color", m_styleStack.attributeNS( ooNS::draw, "fill-color" ) );
00954 e.appendChild( brush );
00955 }
00956 else if ( fill == "hatch" )
00957 {
00958 QDomElement brush = doc.createElement( "BRUSH" );
00959 QString style = m_styleStack.attributeNS( ooNS::draw, "fill-hatch-name" );
00960 QDomElement* draw = m_draws[style];
00961 if ( draw )
00962 {
00963 if( draw->hasAttributeNS( ooNS::draw, "color" ) )
00964 brush.setAttribute( "color", draw->attributeNS( ooNS::draw, "color", QString::null ) );
00965 int angle = 0;
00966 if( draw->hasAttributeNS( ooNS::draw, "rotation" ))
00967 {
00968 angle = (draw->attributeNS( ooNS::draw, "rotation", QString::null ).toInt())/10;
00969 kdDebug(30518)<<"angle :"<<angle<<endl;
00970 }
00971 if( draw->hasAttributeNS( ooNS::draw, "style" ))
00972 {
00973 QString styleHash = draw->attributeNS( ooNS::draw, "style", QString::null );
00974 if( styleHash == "single")
00975 {
00976 switch( angle )
00977 {
00978 case 0:
00979 case 180:
00980 brush.setAttribute( "style", 9 );
00981 break;
00982 case 45:
00983 case 225:
00984 brush.setAttribute( "style", 12 );
00985 break;
00986 case 90:
00987 case 270:
00988 brush.setAttribute( "style", 10 );
00989 break;
00990 case 135:
00991 case 315:
00992 brush.setAttribute( "style", 13 );
00993 break;
00994 default:
00995
00996 kdDebug(30518)<<" draw:rotation 'angle' : "<<angle<<endl;
00997 break;
00998 }
00999 }
01000 else if( styleHash == "double")
01001 {
01002 switch( angle )
01003 {
01004 case 0:
01005 case 180:
01006 case 90:
01007 case 270:
01008 brush.setAttribute("style", 11 );
01009 break;
01010 case 45:
01011 case 135:
01012 case 225:
01013 case 315:
01014 brush.setAttribute("style",14 );
01015 break;
01016 default:
01017
01018 kdDebug(30518)<<" draw:rotation 'angle' : "<<angle<<endl;
01019 break;
01020 }
01021
01022 }
01023 else if( styleHash == "triple")
01024 {
01025 kdDebug(30518)<<" it is not implemented :( \n";
01026 }
01027
01028 }
01029 }
01030 e.appendChild( brush );
01031 }
01032 else if ( fill == "gradient" )
01033 {
01034
01035
01036
01037 QDomElement brush = doc.createElement( "BRUSH" );
01038 brush.setAttribute( "style", 1 );
01039 e.appendChild( brush );
01040
01041 QDomElement gradient = doc.createElement( "GRADIENT" );
01042 QString style = m_styleStack.attributeNS( ooNS::draw, "fill-gradient-name" );
01043
01044 QDomElement* draw = m_draws[style];
01045 if ( draw )
01046 {
01047 gradient.setAttribute( "color1", draw->attributeNS( ooNS::draw, "start-color", QString::null ) );
01048 gradient.setAttribute( "color2", draw->attributeNS( ooNS::draw, "end-color", QString::null ) );
01049
01050 QString type = draw->attributeNS( ooNS::draw, "style", QString::null );
01051
01052 if ( type == "linear" )
01053 {
01054 int angle = draw->attributeNS( ooNS::draw, "angle", QString::null ).toInt() / 10;
01055
01056
01057 angle = abs( angle );
01058 angle -= ( (int) ( angle / 360 ) ) * 360;
01059
01060
01061
01062 int lower, upper, nearAngle = 0;
01063 for ( lower = 0, upper = 45; upper < 360; lower += 45, upper += 45 )
01064 {
01065 if ( upper >= angle )
01066 {
01067 int distanceToUpper = abs( angle - upper );
01068 int distanceToLower = abs( angle - lower );
01069 nearAngle = distanceToUpper > distanceToLower ? lower : upper;
01070 break;
01071 }
01072 }
01073 kdDebug(30518)<<"nearAngle :"<<nearAngle<<endl;
01074
01075 if ( nearAngle == 0 || nearAngle == 180 )
01076 gradient.setAttribute( "type", 1 );
01077 else if ( nearAngle == 90 || nearAngle == 270 )
01078 gradient.setAttribute( "type", 2 );
01079 else if ( nearAngle == 45 || nearAngle == 225 )
01080 gradient.setAttribute( "type", 3 );
01081 else if ( nearAngle == 135 || nearAngle == 315 )
01082 gradient.setAttribute( "type", 4 );
01083 }
01084 else if ( type == "radial" || type == "ellipsoid" )
01085 gradient.setAttribute( "type", 5 );
01086 else if ( type == "square" || type == "rectangular" )
01087 gradient.setAttribute( "type", 6 );
01088 else if ( type == "axial" )
01089 gradient.setAttribute( "type", 7 );
01090
01091
01092
01093 int x, y;
01094 if ( draw->hasAttributeNS( ooNS::draw, "cx" ) )
01095 x = draw->attributeNS( ooNS::draw, "cx", QString::null ).remove( '%' ).toInt();
01096 else
01097 x = 50;
01098
01099 if ( draw->hasAttributeNS( ooNS::draw, "cy" ) )
01100 y = draw->attributeNS( ooNS::draw, "cy", QString::null ).remove( '%' ).toInt();
01101 else
01102 y = 50;
01103
01104 if ( x == 50 && y == 50 )
01105 {
01106 gradient.setAttribute( "unbalanced", 0 );
01107 gradient.setAttribute( "xfactor", 100 );
01108 gradient.setAttribute( "yfactor", 100 );
01109 }
01110 else
01111 {
01112 gradient.setAttribute( "unbalanced", 1 );
01113
01114 gradient.setAttribute( "xfactor", 4 * x - 200 );
01115 gradient.setAttribute( "yfactor", 4 * y - 200 );
01116 }
01117 }
01118 e.appendChild( gradient );
01119
01120 QDomElement fillType = doc.createElement( "FILLTYPE" );
01121 fillType.setAttribute( "value", 1 );
01122 e.appendChild( fillType );
01123 }
01124 }
01125 }
01126
01127 void OoImpressImport::appendPie( QDomDocument& doc, QDomElement& e, const QDomElement& object )
01128 {
01129 QDomElement angle = doc.createElement( "PIEANGLE" );
01130 int start = (int) ( object.attributeNS( ooNS::draw, "start-angle", QString::null ).toDouble() );
01131 angle.setAttribute( "value", start * 16 );
01132 e.appendChild( angle );
01133
01134 QDomElement length = doc.createElement( "PIELENGTH" );
01135 int end = (int) ( object.attributeNS( ooNS::draw, "end-angle", QString::null ).toDouble() );
01136 if ( end < start )
01137 length.setAttribute( "value", ( 360 - start + end ) * 16 );
01138 else
01139 length.setAttribute( "value", ( end - start ) * 16 );
01140 e.appendChild( length );
01141 }
01142
01143 void OoImpressImport::appendImage( QDomDocument& doc, QDomElement& e, QDomElement& p,
01144 const QDomElement& object )
01145 {
01146 QString fileName = storeImage( object );
01147
01148
01149 QTime time = QTime::currentTime();
01150 QDate date = QDate::currentDate();
01151
01152 QDomElement image = doc.createElement( "KEY" );
01153 image.setAttribute( "msec", time.msec() );
01154 image.setAttribute( "second", time.second() );
01155 image.setAttribute( "minute", time.minute() );
01156 image.setAttribute( "hour", time.hour() );
01157 image.setAttribute( "day", date.day() );
01158 image.setAttribute( "month", date.month() );
01159 image.setAttribute( "year", date.year() );
01160 image.setAttribute( "filename", fileName );
01161 e.appendChild( image );
01162
01163 QDomElement settings = doc.createElement( "PICTURESETTINGS" );
01164 if ( m_styleStack.hasAttributeNS( ooNS::draw, "color-mode" ) && ( m_styleStack.attributeNS( ooNS::draw, "color-mode" )=="greyscale" ) )
01165 settings.setAttribute( "grayscal", 1 );
01166 else
01167 settings.setAttribute( "grayscal", 0 );
01168
01169 if ( m_styleStack.hasAttributeNS( ooNS::draw, "luminance" ) )
01170 {
01171 QString str( m_styleStack.attributeNS( ooNS::draw, "luminance" ) );
01172 str = str.remove( '%' );
01173 settings.setAttribute( "bright", str );
01174 }
01175 else
01176 settings.setAttribute( "bright", 0 );
01177
01178 settings.setAttribute( "mirrorType", 0 );
01179 settings.setAttribute( "swapRGB", 0 );
01180 settings.setAttribute( "depth", 0 );
01181 e.appendChild( settings );
01182
01183 QDomElement effects = doc.createElement( "EFFECTS" );
01184 bool hasEffect = false;
01185 if ( m_styleStack.hasAttributeNS( ooNS::draw, "contrast" ) )
01186 {
01187 QString str( m_styleStack.attributeNS( ooNS::draw, "contrast" ) );
01188 str = str.remove( '%' );
01189 int val = str.toInt();
01190 val = ( int )( 255.0 *val/100.0 );
01191 effects.setAttribute( "type", "5" );
01192 effects.setAttribute( "param1", QString::number( val ) );
01193 hasEffect = true;
01194 }
01195 if ( hasEffect )
01196 e.appendChild( effects );
01197
01198 QDomElement key = image.cloneNode().toElement();
01199 key.setAttribute( "name", "pictures/" + fileName );
01200 p.appendChild( key );
01201 }
01202
01203 void OoImpressImport::appendBackgroundImage( QDomDocument& doc, QDomElement& e,
01204 QDomElement& p, const QDomElement& object )
01205 {
01206 QString fileName = storeImage( object );
01207
01208
01209 QTime time = QTime::currentTime();
01210 QDate date = QDate::currentDate();
01211
01212 QDomElement image = doc.createElement( "BACKPICTUREKEY" );
01213 image.setAttribute( "msec", time.msec() );
01214 image.setAttribute( "second", time.second() );
01215 image.setAttribute( "minute", time.minute() );
01216 image.setAttribute( "hour", time.hour() );
01217 image.setAttribute( "day", date.day() );
01218 image.setAttribute( "month", date.month() );
01219 image.setAttribute( "year", date.year() );
01220 image.setAttribute( "filename", fileName );
01221 e.appendChild( image );
01222
01223 QDomElement key = image.cloneNode().toElement();
01224 key.setTagName( "KEY" );
01225 key.setAttribute( "name", "pictures/" + fileName );
01226 p.appendChild( key );
01227 }
01228
01229 void OoImpressImport::appendBackgroundGradient( QDomDocument& doc, QDomElement& e,
01230 const QDomElement& object )
01231 {
01232 QDomElement backColor1 = doc.createElement( "BACKCOLOR1" );
01233 backColor1.setAttribute( "color", object.attributeNS( ooNS::draw, "start-color", QString::null ) );
01234 e.appendChild( backColor1 );
01235
01236 QDomElement backColor2 = doc.createElement( "BACKCOLOR2" );
01237 backColor2.setAttribute( "color", object.attributeNS( ooNS::draw, "end-color", QString::null ) );
01238 e.appendChild( backColor2 );
01239
01240 QDomElement backType = doc.createElement( "BACKTYPE" );
01241 backType.setAttribute( "value", 0 );
01242 e.appendChild( backType );
01243
01244 QDomElement bcType = doc.createElement( "BCTYPE" );
01245 QString type = object.attributeNS( ooNS::draw, "style", QString::null );
01246 if ( type == "linear" )
01247 {
01248 int angle = object.attributeNS( ooNS::draw, "angle", QString::null ).toInt() / 10;
01249
01250
01251 angle = abs( angle );
01252 angle -= ( (int) ( angle / 360 ) ) * 360;
01253
01254
01255
01256 int lower, upper, nearAngle = 0;
01257 for ( lower = 0, upper = 45; upper < 360; lower += 45, upper += 45 )
01258 {
01259 if ( upper >= angle )
01260 {
01261 int distanceToUpper = abs( angle - upper );
01262 int distanceToLower = abs( angle - lower );
01263 nearAngle = distanceToUpper > distanceToLower ? lower : upper;
01264 break;
01265 }
01266 }
01267
01268
01269 if ( nearAngle == 0 || nearAngle == 180 )
01270 bcType.setAttribute( "value", 1 );
01271 else if ( nearAngle == 90 || nearAngle == 270 )
01272 bcType.setAttribute( "value", 2 );
01273 else if ( nearAngle == 45 || nearAngle == 225 )
01274 bcType.setAttribute( "value", 3 );
01275 else if ( nearAngle == 135 || nearAngle == 315 )
01276 bcType.setAttribute( "value", 4 );
01277 }
01278 else if ( type == "radial" || type == "ellipsoid" )
01279 bcType.setAttribute( "value", 5 );
01280 else if ( type == "square" || type == "rectangular" )
01281 bcType.setAttribute( "value", 6 );
01282 else if ( type == "axial" )
01283 bcType.setAttribute( "value", 7 );
01284
01285 e.appendChild( bcType );
01286
01287 QDomElement bGradient = doc.createElement( "BGRADIENT" );
01288
01289
01290
01291 int x, y;
01292 if ( object.hasAttributeNS( ooNS::draw, "cx" ) )
01293 x = object.attributeNS( ooNS::draw, "cx", QString::null ).remove( '%' ).toInt();
01294 else
01295 x = 50;
01296
01297 if ( object.hasAttributeNS( ooNS::draw, "cy" ) )
01298 y = object.attributeNS( ooNS::draw, "cy", QString::null ).remove( '%' ).toInt();
01299 else
01300 y = 50;
01301
01302 if ( x == 50 && y == 50 )
01303 {
01304 bGradient.setAttribute( "unbalanced", 0 );
01305 bGradient.setAttribute( "xfactor", 100 );
01306 bGradient.setAttribute( "yfactor", 100 );
01307 }
01308 else
01309 {
01310 bGradient.setAttribute( "unbalanced", 1 );
01311
01312 bGradient.setAttribute( "xfactor", 4 * x - 200 );
01313 bGradient.setAttribute( "yfactor", 4 * y - 200 );
01314 }
01315
01316 e.appendChild( bGradient );
01317 }
01318
01319 void OoImpressImport::appendRounding( QDomDocument& doc, QDomElement& e, const QDomElement& object )
01320 {
01321 if ( object.hasAttributeNS( ooNS::draw, "corner-radius" ) )
01322 {
01323
01324 QDomElement rounding = doc.createElement( "RNDS" );
01325 int corner = static_cast<int>(KoUnit::parseValue(object.attributeNS( ooNS::draw, "corner-radius", QString::null)));
01326 rounding.setAttribute( "x", corner );
01327 rounding.setAttribute( "y", corner );
01328 e.appendChild( rounding );
01329 }
01330 }
01331
01332 void OoImpressImport::appendShadow( QDomDocument& doc, QDomElement& e )
01333 {
01334
01335
01336
01337
01338
01339
01340 if ( !e.hasAttribute( "type" ) ||
01341 ( e.hasAttribute( "type" ) && e.attribute( "type" ) == "4" ) )
01342 {
01343 if ( m_styleStack.hasAttributeNS( ooNS::fo, "text-shadow" ) &&
01344 m_styleStack.attributeNS( ooNS::fo, "text-shadow" ) != "none" )
01345 {
01346
01347 QDomElement shadow = doc.createElement( "SHADOW" );
01348 QString distance = m_styleStack.attributeNS( ooNS::fo, "text-shadow" );
01349 distance.truncate( distance.find( ' ' ) );
01350 shadow.setAttribute( "distance", KoUnit::parseValue( distance ) );
01351 shadow.setAttribute( "direction", 5 );
01352 shadow.setAttribute( "color", "#a0a0a0" );
01353 e.appendChild( shadow );
01354 }
01355 }
01356 else if ( m_styleStack.hasAttributeNS( ooNS::draw, "shadow" ) &&
01357 m_styleStack.attributeNS( ooNS::draw, "shadow" ) == "visible" )
01358 {
01359
01360 QDomElement shadow = doc.createElement( "SHADOW" );
01361 double x = KoUnit::parseValue( m_styleStack.attributeNS( ooNS::draw, "shadow-offset-x" ) );
01362 double y = KoUnit::parseValue( m_styleStack.attributeNS( ooNS::draw, "shadow-offset-y" ) );
01363
01364 if ( x < 0 && y < 0 )
01365 {
01366 shadow.setAttribute( "direction", 1 );
01367 shadow.setAttribute( "distance", (int) fabs ( x ) );
01368 }
01369 else if ( x == 0 && y < 0 )
01370 {
01371 shadow.setAttribute( "direction", 2 );
01372 shadow.setAttribute( "distance", (int) fabs ( y ) );
01373 }
01374 else if ( x > 0 && y < 0 )
01375 {
01376 shadow.setAttribute( "direction", 3 );
01377 shadow.setAttribute( "distance", (int) fabs ( x ) );
01378 }
01379 else if ( x > 0 && y == 0 )
01380 {
01381 shadow.setAttribute( "direction", 4 );
01382 shadow.setAttribute( "distance", (int) fabs ( x ) );
01383 }
01384 else if ( x > 0 && y > 0 )
01385 {
01386 shadow.setAttribute( "direction", 5 );
01387 shadow.setAttribute( "distance", (int) fabs ( x ) );
01388 }
01389 else if ( x == 0 && y > 0 )
01390 {
01391 shadow.setAttribute( "direction", 6 );
01392 shadow.setAttribute( "distance", (int) fabs ( y ) );
01393 }
01394 else if ( x < 0 && y > 0 )
01395 {
01396 shadow.setAttribute( "direction", 7 );
01397 shadow.setAttribute( "distance", (int) fabs ( x ) );
01398 }
01399 else if ( x < 0 && y == 0 )
01400 {
01401 shadow.setAttribute( "direction", 8 );
01402 shadow.setAttribute( "distance", (int) fabs ( x ) );
01403 }
01404
01405 if ( m_styleStack.hasAttributeNS( ooNS::draw, "shadow-color" ) )
01406 shadow.setAttribute( "color", m_styleStack.attributeNS( ooNS::draw, "shadow-color" ) );
01407
01408 e.appendChild( shadow );
01409 }
01410 if ( m_styleStack.hasAttributeNS( ooNS::draw, "size-protect" ) || m_styleStack.hasAttributeNS( ooNS::draw, "move-protect" ) )
01411 {
01412 bool b = ( m_styleStack.attributeNS( ooNS::draw, "size-protect" ) == "true" ) || ( m_styleStack.attributeNS( ooNS::draw, "move-protect" ) == "true" );
01413 if ( b )
01414 {
01415 QDomElement protect = doc.createElement( "PROTECT" );
01416 protect.setAttribute("state" , b);
01417 e.appendChild(protect);
01418 }
01419 }
01420 }
01421
01422 void OoImpressImport::appendLineEnds( QDomDocument& doc, QDomElement& e, bool orderEndStartLine)
01423 {
01424 const char* attr = orderEndStartLine ? "marker-start" : "marker-end";
01425 if ( m_styleStack.hasAttributeNS( ooNS::draw, attr ) )
01426 {
01427 QDomElement lineBegin = doc.createElement( "LINEBEGIN" );
01428 QString type = m_styleStack.attributeNS( ooNS::draw, attr );
01429 if ( type == "Arrow" || type == "Small Arrow" || type == "Rounded short Arrow" ||
01430 type == "Symmetric Arrow" || type == "Rounded large Arrow" || type == "Arrow concave" )
01431 lineBegin.setAttribute( "value", 1 );
01432 else if ( type == "Square" )
01433 lineBegin.setAttribute( "value", 2 );
01434 else if ( type == "Circle" || type == "Square 45" )
01435 lineBegin.setAttribute( "value", 3 );
01436 else if ( type == "Line Arrow" )
01437 lineBegin.setAttribute( "value", 4 );
01438 else if ( type == "Dimension Lines" )
01439 lineBegin.setAttribute( "value", 5 );
01440 else if ( type == "Double Arrow" )
01441 lineBegin.setAttribute( "value", 6 );
01442 e.appendChild( lineBegin );
01443 }
01444 attr = orderEndStartLine ? "marker-end" : "marker-start";
01445 if ( m_styleStack.hasAttributeNS( ooNS::draw, attr ) )
01446 {
01447 QDomElement lineEnd = doc.createElement( "LINEEND" );
01448 QString type = m_styleStack.attributeNS( ooNS::draw, attr );
01449 if ( type == "Arrow" || type == "Small Arrow" || type == "Rounded short Arrow" ||
01450 type == "Symmetric Arrow" || type == "Rounded large Arrow" || type == "Arrow concave" )
01451 lineEnd.setAttribute( "value", 1 );
01452 else if ( type == "Square" )
01453 lineEnd.setAttribute( "value", 2 );
01454 else if ( type == "Circle" || type == "Square 45" )
01455 lineEnd.setAttribute( "value", 3 );
01456 else if ( type == "Line Arrow" )
01457 lineEnd.setAttribute( "value", 4 );
01458 else if ( type == "Dimension Lines" )
01459 lineEnd.setAttribute( "value", 5 );
01460 else if ( type == "Double Arrow" )
01461 lineEnd.setAttribute( "value", 6 );
01462 e.appendChild( lineEnd );
01463 }
01464 }
01465
01466 void OoImpressImport::appendTextObjectMargin( QDomDocument& , QDomElement& e )
01467 {
01468 if ( m_styleStack.hasAttributeNS( ooNS::fo, "padding" ) )
01469 {
01470 double tmpValue = KoUnit::parseValue(m_styleStack.attributeNS( ooNS::fo, "padding" ) );
01471 e.setAttribute( "btoppt", tmpValue );
01472 e.setAttribute( "bbottompt", tmpValue );
01473 e.setAttribute( "bleftpt", tmpValue );
01474 e.setAttribute( "brightpt", tmpValue );
01475 }
01476 else
01477 {
01478 if( m_styleStack.hasAttributeNS( ooNS::fo, "padding-top" ) )
01479 e.setAttribute( "btoppt", KoUnit::parseValue( m_styleStack.attributeNS( ooNS::fo, "padding-top" ) ) );
01480 if( m_styleStack.hasAttributeNS( ooNS::fo, "padding-bottom" ) )
01481 e.setAttribute( "bbottompt", KoUnit::parseValue( m_styleStack.attributeNS( ooNS::fo, "padding-bottom" ) ) );
01482 if( m_styleStack.hasAttributeNS( ooNS::fo, "padding-left" ) )
01483 e.setAttribute( "bleftpt", KoUnit::parseValue( m_styleStack.attributeNS( ooNS::fo, "padding-left" ) ) );
01484 if( m_styleStack.hasAttributeNS( ooNS::fo, "padding-right" ) )
01485 e.setAttribute( "brightpt", KoUnit::parseValue( m_styleStack.attributeNS( ooNS::fo, "padding-right" ) ) );
01486 }
01487 }
01488
01489 QDomElement OoImpressImport::parseTextBox( QDomDocument& doc, const QDomElement& textBox )
01490 {
01491 QDomElement textObjectElement = doc.createElement( "TEXTOBJ" );
01492 appendTextObjectMargin( doc, textObjectElement );
01493
01494
01495 if ( m_styleStack.hasAttributeNS( ooNS::draw, "textarea-vertical-align" ) )
01496 {
01497 QString alignment = m_styleStack.attributeNS( ooNS::draw, "textarea-vertical-align" );
01498 if ( alignment == "top" )
01499 textObjectElement.setAttribute( "verticalAlign", "top" );
01500 else if ( alignment == "middle" )
01501 textObjectElement.setAttribute( "verticalAlign", "center" );
01502 else if ( alignment == "bottom" )
01503 textObjectElement.setAttribute( "verticalAlign", "bottom" );
01504
01505 textObjectElement.setAttribute("verticalValue", 0.0);
01506 }
01507
01508 parseParagraphs( doc, textObjectElement, textBox );
01509
01510 return textObjectElement;
01511 }
01512
01513 void OoImpressImport::parseParagraphs( QDomDocument& doc, QDomElement& textObjectElement, const QDomElement& parent )
01514 {
01515 QDomElement t;
01516 forEachElement( t, parent )
01517 {
01518 m_styleStack.save();
01519 const QString localName = t.localName();
01520 const QString ns = t.namespaceURI();
01521 const bool isTextNS = ns == ooNS::text;
01522
01523 QDomElement e;
01524 if ( isTextNS && localName == "p" )
01525 e = parseParagraph( doc, t );
01526 else if ( isTextNS && localName == "h" )
01527 {
01528 e = parseParagraph( doc, t );
01529 }
01530 else if ( isTextNS && ( localName == "unordered-list" || localName == "ordered-list" ) )
01531 {
01532 parseList( doc, textObjectElement, t );
01533 m_styleStack.restore();
01534 continue;
01535 }
01536
01537 else
01538 {
01539 kdDebug(30518) << "Unsupported texttype '" << localName << "'" << endl;
01540 }
01541
01542 if ( !e.isNull() )
01543 textObjectElement.appendChild( e );
01544 m_styleStack.restore();
01545 }
01546 }
01547
01548 void OoImpressImport::applyListStyle( QDomElement& paragraph )
01549 {
01550
01551 if ( m_listStyleStack.hasListStyle() && m_nextItemIsListItem ) {
01552
01553
01554 m_nextItemIsListItem = false;
01555
01556
01557
01558 QDomElement counter = paragraph.ownerDocument().createElement( "COUNTER" );
01559 counter.setAttribute( "numberingtype", 0 );
01560 counter.setAttribute( "depth", 0 );
01561
01562 if ( m_insideOrderedList )
01563 counter.setAttribute( "type", 1 );
01564 else
01565 counter.setAttribute( "type", 10 );
01566 paragraph.appendChild( counter );
01567 }
01568 }
01569
01570 static QDomElement findListLevelStyle( QDomElement& fullListStyle, int level )
01571 {
01572 QDomElement listLevelItem;
01573 forEachElement( listLevelItem, fullListStyle )
01574 {
01575 if ( listLevelItem.attributeNS( ooNS::text, "level", QString::null ).toInt() == level )
01576 return listLevelItem;
01577 }
01578 return QDomElement();
01579 }
01580
01581 bool OoImpressImport::pushListLevelStyle( const QString& listStyleName, int level )
01582 {
01583 QDomElement* fullListStyle = m_listStyles[listStyleName];
01584 if ( !fullListStyle ) {
01585 kdWarning(30518) << "List style " << listStyleName << " not found!" << endl;
01586 return false;
01587 }
01588 else
01589 return pushListLevelStyle( listStyleName, *fullListStyle, level );
01590 }
01591
01592 bool OoImpressImport::pushListLevelStyle( const QString& listStyleName,
01593 QDomElement& fullListStyle, int level )
01594 {
01595
01596 int i = level;
01597 QDomElement listLevelStyle;
01598 while ( i > 0 && listLevelStyle.isNull() ) {
01599 listLevelStyle = findListLevelStyle( fullListStyle, i );
01600 --i;
01601 }
01602 if ( listLevelStyle.isNull() ) {
01603 kdWarning(30518) << "List level style for level " << level << " in list style " << listStyleName << " not found!" << endl;
01604 return false;
01605 }
01606 kdDebug(30518) << "Pushing list-level-style from list-style " << listStyleName << " level " << level << endl;
01607 m_listStyleStack.push( listLevelStyle );
01608 return true;
01609 }
01610
01611 void OoImpressImport::parseList( QDomDocument& doc, QDomElement& textObjectElement, const QDomElement& list )
01612 {
01613
01614
01615 m_insideOrderedList = ( list.localName() == "ordered-list" );
01616 QString oldListStyleName = m_currentListStyleName;
01617 if ( list.hasAttributeNS( ooNS::text, "style-name" ) )
01618 m_currentListStyleName = list.attributeNS( ooNS::text, "style-name", QString::null );
01619 bool listOK = !m_currentListStyleName.isEmpty();
01620 const int level = m_listStyleStack.level() + 1;
01621
01622 if ( listOK )
01623 listOK = pushListLevelStyle( m_currentListStyleName, level );
01624
01625
01626 QDomElement listItem;
01627 forEachElement( listItem, list )
01628 {
01629
01630 m_nextItemIsListItem = ( listItem.localName() != "list-header" );
01631 m_restartNumbering = -1;
01632 if ( listItem.hasAttributeNS( ooNS::text, "start-value" ) )
01633 m_restartNumbering = listItem.attributeNS( ooNS::text, "start-value", QString::null ).toInt();
01634
01635 parseParagraphs( doc, textObjectElement, listItem );
01636 m_restartNumbering = -1;
01637 }
01638 if ( listOK )
01639 m_listStyleStack.pop();
01640 m_currentListStyleName = oldListStyleName;
01641 }
01642
01643 QDomElement OoImpressImport::parseParagraph( QDomDocument& doc, const QDomElement& paragraph )
01644 {
01645 QDomElement p = doc.createElement( "P" );
01646
01647
01648 fillStyleStack( paragraph );
01649
01650
01651 QString styleName = m_styleStack.userStyleName("paragraph");
01652 if ( !styleName.isEmpty() )
01653 {
01654 QDomElement nameElem = doc.createElement("NAME");
01655 nameElem.setAttribute("value", styleName);
01656 p.appendChild(nameElem);
01657 }
01658
01659
01660 if ( m_styleStack.hasAttributeNS( ooNS::fo, "text-align" ) )
01661 {
01662 QString align = m_styleStack.attributeNS( ooNS::fo, "text-align" );
01663 if ( align == "center" )
01664 p.setAttribute( "align", 4 );
01665 else if ( align == "justify" )
01666 p.setAttribute( "align", 8 );
01667 else if ( align == "start" )
01668 p.setAttribute( "align", 0 );
01669 else if ( align == "end" )
01670 p.setAttribute( "align", 2 );
01671 }
01672 else
01673 p.setAttribute( "align", 0 );
01674
01675
01676
01677 OoUtils::importTopBottomMargin( p, m_styleStack );
01678
01679
01680 OoUtils::importIndents( p, m_styleStack );
01681
01682
01683 OoUtils::importLineSpacing( p, m_styleStack );
01684
01685
01686 OoUtils::importTabulators( p, m_styleStack );
01687
01688
01689 OoUtils::importBorders( p, m_styleStack );
01690
01691 applyListStyle( p );
01692
01693 uint pos = 0;
01694
01695 m_styleStack.save();
01696
01697 parseSpanOrSimilar( doc, paragraph, p, pos);
01698 m_styleStack.restore();
01699
01700 return p;
01701 }
01702
01703 void OoImpressImport::parseSpanOrSimilar( QDomDocument& doc, const QDomElement& parent,
01704 QDomElement& outputParagraph, uint& pos)
01705 {
01706
01707
01708 for( QDomNode node = parent.firstChild(); !node.isNull(); node = node.nextSibling() )
01709 {
01710 QDomElement ts = node.toElement();
01711 QString textData;
01712 const QString localName( ts.localName() );
01713 const QString ns = ts.namespaceURI();
01714 const bool isTextNS = ns == ooNS::text;
01715 QDomText t = node.toText();
01716
01717
01718 if ( isTextNS && localName == "span" )
01719 {
01720 m_styleStack.save();
01721 fillStyleStack( ts );
01722 parseSpanOrSimilar( doc, ts, outputParagraph, pos);
01723 m_styleStack.restore();
01724 }
01725 else if ( isTextNS && localName == "s" )
01726 {
01727 textData = OoUtils::expandWhitespace(ts);
01728 }
01729 else if ( isTextNS && localName == "tab-stop" )
01730 {
01731
01732
01733
01734 textData = '\t';
01735 }
01736 else if ( isTextNS && localName == "line-break" )
01737 {
01738 textData = '\n';
01739 }
01740 else if ( localName == "image" && ns == ooNS::draw )
01741 {
01742 textData = '#';
01743
01744 }
01745 else if ( isTextNS && localName == "a" )
01746 {
01747 m_styleStack.save();
01748 QString href( ts.attributeNS( ooNS::xlink, "href", QString::null) );
01749 if ( href.startsWith("#") )
01750 {
01751
01752
01753 parseSpanOrSimilar( doc, ts, outputParagraph, pos);
01754 }
01755 else
01756 {
01757 #if 0 // TODO
01758
01759
01760 QDomElement fakeParagraph, fakeFormats;
01761 uint fakePos=0;
01762 QString text;
01763 parseSpanOrSimilar( doc, ts, fakeParagraph, fakeFormats, text, fakePos);
01764 textData = '#';
01765 QDomElement linkElement (doc.createElement("LINK"));
01766 linkElement.setAttribute("hrefName",ts.attributeNS( ooNS::xlink, "href", QString::null));
01767 linkElement.setAttribute("linkName",text);
01768 appendVariable(doc, ts, pos, "STRING", 9, text, linkElement);
01769 #endif
01770 }
01771 m_styleStack.restore();
01772 }
01773 else if ( isTextNS &&
01774 (localName == "date"
01775 || localName == "time"
01776 || localName == "page-number"
01777 || localName == "file-name"
01778 || localName == "author-name"
01779 || localName == "author-initials" ) )
01780 {
01781 textData = "#";
01782 appendField(doc, outputParagraph, ts, pos);
01783 }
01784 else if ( t.isNull() )
01785 {
01786 kdWarning(30518) << "Ignoring tag " << ts.tagName() << endl;
01787 continue;
01788 }
01789 else
01790 textData = t.data();
01791
01792 pos += textData.length();
01793
01794 QDomElement text = saveHelper(textData, doc);
01795
01796 kdDebug(30518) << k_funcinfo << "Para text is: " << textData << endl;
01797
01798 if (m_styleStack.hasAttributeNS( ooNS::fo, "language" )) {
01799 QString lang = m_styleStack.attributeNS( ooNS::fo, "language" );
01800 if (lang=="en")
01801 text.setAttribute("language", "en_US");
01802 else
01803 text.setAttribute("language", lang);
01804 }
01805
01806
01807 if ( m_styleStack.hasAttributeNS( ooNS::fo, "color" ) ) {
01808 kdDebug(30518) << "color=" << m_styleStack.attributeNS( ooNS::fo, "color" ) << endl;
01809 text.setAttribute( "color", m_styleStack.attributeNS( ooNS::fo, "color" ) );
01810 }
01811 if ( m_styleStack.hasAttributeNS( ooNS::fo, "font-family" )
01812 || m_styleStack.hasAttributeNS( ooNS::style, "font-name") )
01813 {
01814
01815
01816 if ( m_styleStack.attributeNS( ooNS::fo, "font-family" ) == "Thorndale" )
01817 text.setAttribute( "family", "Times New Roman" );
01818 else if ( m_styleStack.attributeNS( ooNS::fo, "font-family" ) == "Albany" )
01819 text.setAttribute( "family", "Arial" );
01820 else
01821 text.setAttribute( "family", m_styleStack.attributeNS( ooNS::fo, "font-family" ).remove( "'" ) );
01822 }
01823 if ( m_styleStack.hasAttributeNS( ooNS::fo, "font-size" ) )
01824 {
01825 double pointSize = m_styleStack.fontSize();
01826 text.setAttribute( "pointSize", qRound(pointSize) );
01827 }
01828 if ( m_styleStack.hasAttributeNS( ooNS::fo, "font-weight" ) )
01829 if ( m_styleStack.attributeNS( ooNS::fo, "font-weight" ) == "bold" )
01830 text.setAttribute( "bold", 1 );
01831 if ( m_styleStack.hasAttributeNS( ooNS::fo, "font-style" ) )
01832 if ( m_styleStack.attributeNS( ooNS::fo, "font-style" ) == "italic" )
01833 text.setAttribute( "italic", 1 );
01834
01835 if ( m_styleStack.hasAttributeNS( ooNS::style, "text-position" ) )
01836 {
01837 QString text_position = m_styleStack.attributeNS( ooNS::style, "text-position");
01838 QString value;
01839 QString relativetextsize;
01840 OoUtils::importTextPosition( text_position, value, relativetextsize );
01841 text.setAttribute( "VERTALIGN", value );
01842 if ( !relativetextsize.isEmpty() )
01843 text.setAttribute( "relativetextsize", relativetextsize );
01844 }
01845
01846 bool wordByWord = (m_styleStack.hasAttributeNS( ooNS::fo, "score-spaces"))
01847 && (m_styleStack.attributeNS( ooNS::fo, "score-spaces") == "false");
01848
01849
01850 if ( m_styleStack.hasAttributeNS( ooNS::style, "text-crossing-out")
01851 && m_styleStack.attributeNS( ooNS::style, "text-crossing-out") != "none")
01852 {
01853 QString strikeOutType = m_styleStack.attributeNS( ooNS::style, "text-crossing-out" );
01854 if ( strikeOutType =="double-line" )
01855 {
01856 text.setAttribute( "strikeOut", "double" );
01857 text.setAttribute( "strikeoutstyleline", "solid" );
01858 }
01859 else if ( strikeOutType =="thick-line" )
01860 {
01861 text.setAttribute( "strikeOut", "single-bold" );
01862 text.setAttribute( "strikeoutstyleline", "solid" );
01863 }
01864 else
01865 {
01866 text.setAttribute( "strikeOut", "single" );
01867 text.setAttribute( "strikeoutstyleline", "solid" );
01868 }
01869
01870 if (wordByWord)
01871 text.setAttribute("wordbyword", 1);
01872 }
01873
01874
01875 if ( m_styleStack.hasAttributeNS( ooNS::style, "text-underline" ) )
01876 {
01877 QString underline;
01878 QString styleline;
01879 OoUtils::importUnderline( m_styleStack.attributeNS( ooNS::style, "text-underline" ),
01880 underline, styleline );
01881 QString underLineColor = m_styleStack.attributeNS( ooNS::style, "text-underline-color" );
01882
01883 text.setAttribute( "value", underline );
01884 text.setAttribute( "styleline", styleline );
01885
01886 if ( !underLineColor.isEmpty() && underLineColor != "font-color" )
01887 text.setAttribute("underlinecolor", underLineColor);
01888 if ( wordByWord )
01889 text.setAttribute("wordbyword", 1);
01890 }
01891 #if 0 // strange ooimpress doesn't implement it
01892
01893 if ( m_styleStack.hasAttributeNS( ooNS::fo, "font-variant" )
01894 || m_styleStack.hasAttributeNS( ooNS::fo, "text-transform" ) )
01895 {
01896 QDomElement fontAttrib( doc.createElement( "FONTATTRIBUTE" ) );
01897 bool smallCaps = m_styleStack.attributeNS( ooNS::fo, "font-variant" ) == "small-caps";
01898 if ( smallCaps )
01899 {
01900 text.setAttribute( "fontattribute", "smallcaps" );
01901 } else
01902 {
01903
01904
01905 text.setAttribute( "fontattribute", m_styleStack.attributeNS( ooNS::fo, "text-transform" ) );
01906 }
01907 }
01908 #endif
01909
01910 if (m_styleStack.hasAttributeNS( ooNS::fo, "background-color" ))
01911 {
01912 QString bgColor = m_styleStack.attributeNS( ooNS::fo, "background-color");
01913 if (bgColor != "transparent")
01914 text.setAttribute("textbackcolor", bgColor);
01915 }
01916
01917 appendShadow( doc, outputParagraph );
01918 outputParagraph.appendChild( text );
01919 }
01920 }
01921
01922 void OoImpressImport::createStyleMap( QDomDocument &docstyles )
01923 {
01924 QDomElement styles = docstyles.documentElement();
01925 if ( styles.isNull() )
01926 return;
01927
01928 QDomNode fixedStyles = KoDom::namedItemNS( styles, ooNS::office, "styles" );
01929 if ( !fixedStyles.isNull() )
01930 {
01931 insertDraws( fixedStyles.toElement() );
01932 insertStyles( fixedStyles.toElement() );
01933 insertStylesPresentation( fixedStyles.toElement() );
01934 }
01935
01936 QDomNode automaticStyles = KoDom::namedItemNS( styles, ooNS::office, "automatic-styles" );
01937 if ( !automaticStyles.isNull() )
01938 {
01939 insertStyles( automaticStyles.toElement() );
01940 insertStylesPresentation( automaticStyles.toElement() );
01941 }
01942 QDomNode masterStyles = KoDom::namedItemNS( styles, ooNS::office, "master-styles" );
01943 if ( !masterStyles.isNull() )
01944 insertStyles( masterStyles.toElement() );
01945 }
01946
01947 void OoImpressImport::insertDraws( const QDomElement& styles )
01948 {
01949 QDomElement e;
01950 forEachElement( e, styles )
01951 {
01952 if ( !e.hasAttributeNS( ooNS::draw, "name" ) )
01953 continue;
01954
01955 QString name = e.attributeNS( ooNS::draw, "name", QString::null );
01956 m_draws.insert( name, new QDomElement( e ) );
01957 }
01958 }
01959
01960 void OoImpressImport::insertStyles( const QDomElement& styles )
01961 {
01962 QDomElement e;
01963 forEachElement( e, styles )
01964 {
01965 const QString localName = e.localName();
01966 const QString ns = e.namespaceURI();
01967 if ( !e.hasAttributeNS( ooNS::style, "name" ) )
01968 continue;
01969
01970 const QString name = e.attributeNS( ooNS::style, "name", QString::null );
01971 if ( localName == "list-style" && ns == ooNS::text ) {
01972 QDomElement* ep = new QDomElement( e );
01973 m_listStyles.insert( name, ep );
01974 kdDebug(30518) << "List style: '" << name << "' loaded " << endl;
01975 }
01976 else
01977 {
01978 m_styles.insert( name, new QDomElement( e ) );
01979 kdDebug(30518) << "Style: '" << name << "' loaded " << endl;
01980 }
01981 }
01982 }
01983
01984 void OoImpressImport::insertStylesPresentation( const QDomElement& styles )
01985 {
01986 QDomElement e;
01987 forEachElement( e, styles )
01988 {
01989 if ( !e.hasAttributeNS( ooNS::style, "name" ) )
01990 continue;
01991
01992 QString name = e.attributeNS( ooNS::style, "name", QString::null );
01993 m_stylesPresentation.insert( name, new QDomElement( e ) );
01994
01995 }
01996 }
01997
01998 void OoImpressImport::fillStyleStack( const QDomElement& object, bool sticky )
01999 {
02000
02001 if ( object.hasAttributeNS( ooNS::presentation, "style-name" ) )
02002 {
02003 kdDebug(30518)<<" presentation:style-name **************************** :"<<object.attributeNS( ooNS::presentation, "style-name", QString::null )<<endl;
02004 if ( sticky )
02005 addStyles( m_stylesPresentation[object.attributeNS( ooNS::presentation, "style-name", QString::null )] );
02006 else
02007 addStyles( m_styles[object.attributeNS( ooNS::presentation, "style-name", QString::null )] );
02008 }
02009 if ( object.hasAttributeNS( ooNS::draw, "style-name" ) )
02010 addStyles( m_styles[object.attributeNS( ooNS::draw, "style-name", QString::null )] );
02011
02012 if ( object.hasAttributeNS( ooNS::draw, "text-style-name" ) )
02013 addStyles( m_styles[object.attributeNS( ooNS::draw, "text-style-name", QString::null )] );
02014
02015 if ( object.hasAttributeNS( ooNS::text, "style-name" ) ) {
02016 QString styleName = object.attributeNS( ooNS::text, "style-name", QString::null );
02017
02018 addStyles( m_styles[styleName] );
02019 }
02020 }
02021
02022 void OoImpressImport::addStyles( const QDomElement* style )
02023 {
02024 kdDebug(30518)<<" addStyle :" << style->attributeNS( ooNS::style, "name", QString::null ) <<endl;
02025
02026 if ( style->hasAttributeNS( ooNS::style, "parent-style-name" ) )
02027 {
02028
02029 addStyles( m_styles[style->attributeNS( ooNS::style, "parent-style-name", QString::null )] );
02030 }
02031
02032 m_styleStack.push( *style );
02033 }
02034
02035 QString OoImpressImport::storeImage( const QDomElement& object )
02036 {
02037
02038 QString url = object.attributeNS( ooNS::xlink, "href", QString::null ).remove( '#' );
02039 KArchiveFile* file = (KArchiveFile*) m_zip->directory()->entry( url );
02040
02041 QString extension = url.mid( url.find( '.' ) );
02042 QString fileName = QString( "picture%1" ).arg( m_numPicture++ ) + extension;
02043 KoStoreDevice* out = m_chain->storageFile( "pictures/" + fileName, KoStore::Write );
02044
02045 if ( file && out )
02046 {
02047 QByteArray buffer = file->data();
02048 out->writeBlock( buffer.data(), buffer.size() );
02049 }
02050
02051 return fileName;
02052 }
02053
02054 QString OoImpressImport::storeSound(const QDomElement & object, QDomElement & p, QDomDocument & doc)
02055 {
02056 QFileInfo fi(m_chain->inputFile());
02057 QDir::setCurrent(fi.dirPath(true));
02058 fi.setFile(object.attributeNS( ooNS::xlink, "href", QString::null));
02059 QString url = fi.absFilePath();
02060
02061
02062
02063 QFile file(url);
02064 if (!file.exists())
02065 return QString::null;
02066
02067 QString extension = url.mid( url.find( '.' ) );
02068 QString fileName = QString( "sound%1" ).arg( m_numSound++ ) + extension;
02069 fileName = "sounds/" + fileName;
02070 KoStoreDevice* out = m_chain->storageFile( fileName, KoStore::Write );
02071
02072 if (out)
02073 {
02074 if (!file.open(IO_ReadOnly))
02075 return QString::null;
02076
02077 QByteArray data(8*1024);
02078
02079 uint total = 0;
02080 for ( int block = 0; ( block = file.readBlock(data.data(), data.size()) ) > 0;
02081 total += block )
02082 out->writeBlock(data.data(), data.size());
02083
02084 Q_ASSERT(total == fi.size());
02085
02086 file.close();
02087 }
02088 else
02089 return QString::null;
02090
02091 QDomElement key = doc.createElement("FILE");
02092 key.setAttribute("name", fileName);
02093 key.setAttribute("filename", url);
02094 p.appendChild(key);
02095
02096 return url;
02097 }
02098
02099 QDomElement OoImpressImport::saveHelper(const QString &tmpText, QDomDocument &doc)
02100 {
02101 QDomElement element=doc.createElement("TEXT");
02102
02103 if(tmpText.stripWhiteSpace().isEmpty())
02104
02105 element.setAttribute("whitespace", tmpText.length());
02106
02107 element.appendChild(doc.createTextNode(tmpText));
02108 return element;
02109 }
02110
02111 void OoImpressImport::appendPoints(QDomDocument& doc, QDomElement& e, const QDomElement& object)
02112 {
02113 QDomElement ptsElem = doc.createElement("POINTS");
02114
02115 QStringList ptList = QStringList::split(' ', object.attributeNS( ooNS::draw, "points", QString::null));
02116
02117 QString pt_x, pt_y;
02118 double tmp_x, tmp_y;
02119 for (QStringList::Iterator it = ptList.begin(); it != ptList.end(); ++it)
02120 {
02121 QDomElement point = doc.createElement("Point");
02122
02123 tmp_x = (*it).section(',',0,0).toInt() / 100;
02124 tmp_y = (*it).section(',',1,1).toInt() / 100;
02125
02126 pt_x.setNum(tmp_x);
02127 pt_x+="mm";
02128
02129 pt_y.setNum(tmp_y);
02130 pt_y+="mm";
02131
02132 point.setAttribute("point_x", KoUnit::parseValue(pt_x));
02133 point.setAttribute("point_y", KoUnit::parseValue(pt_y));
02134 ptsElem.appendChild(point);
02135 }
02136
02137 e.appendChild(ptsElem);
02138 }
02139
02140 void OoImpressImport::appendField(QDomDocument& doc, QDomElement& e, const QDomElement& object, uint pos)
02141 {
02142 const QString tag = object.localName();
02143 const QString ns = object.namespaceURI();
02144 const bool isTextNS = ns == ooNS::text;
02145
02146 QDomElement custom = doc.createElement("CUSTOM");
02147 custom.setAttribute("pos", pos);
02148 QDomElement variable = doc.createElement("VARIABLE");
02149
02150 if (isTextNS && tag == "date")
02151 {
02152 QDateTime dt(QDate::fromString(object.attributeNS( ooNS::text, "date-value", QString::null), Qt::ISODate));
02153
02154 bool fixed = (object.hasAttributeNS( ooNS::text, "fixed") && object.attributeNS( ooNS::text, "fixed", QString::null)=="true");
02155
02156 if (!dt.isValid()) {
02157 dt = QDateTime::currentDateTime();
02158 fixed = false;
02159 }
02160
02161 QDomElement typeElem = doc.createElement("TYPE");
02162 typeElem.setAttribute("key", "DATE0locale");
02163 typeElem.setAttribute("type", 0);
02164 typeElem.setAttribute("text", object.text());
02165
02166 variable.appendChild(typeElem);
02167
02168 const QDate date(dt.date());
02169 const QTime time(dt.time());
02170 QDomElement dateElement = doc.createElement("DATE");
02171 dateElement.setAttribute("subtype", fixed ? 0 : 1);
02172 dateElement.setAttribute("fix", fixed ? 1 : 0);
02173 dateElement.setAttribute("day", date.day());
02174 dateElement.setAttribute("month", date.month());
02175 dateElement.setAttribute("year", date.year());
02176 dateElement.setAttribute("hour", time.hour());
02177 dateElement.setAttribute("minute", time.minute());
02178 dateElement.setAttribute("second", time.second());
02179 if (object.hasAttributeNS( ooNS::text, "date-adjust"))
02180 dateElement.setAttribute("correct", object.attributeNS( ooNS::text, "date-adjust", QString::null));
02181
02182 variable.appendChild(dateElement);
02183 }
02184 else if (isTextNS && tag == "time")
02185 {
02186
02187 QDateTime dt(QDateTime::fromString(object.attributeNS( ooNS::text, "time-value", QString::null), Qt::ISODate));
02188
02189 bool fixed = (object.hasAttributeNS( ooNS::text, "fixed") && object.attributeNS( ooNS::text, "fixed", QString::null)=="true");
02190
02191 if (!dt.isValid()) {
02192 dt = QDateTime::currentDateTime();
02193 fixed = false;
02194 }
02195
02196 QDomElement typeElem = doc.createElement("TYPE");
02197 typeElem.setAttribute("key", "TIMElocale");
02198 typeElem.setAttribute("type", 2);
02199 typeElem.setAttribute("text", object.text());
02200
02201 variable.appendChild(typeElem);
02202
02203 const QTime time(dt.time());
02204 QDomElement timeElement = doc.createElement("TIME");
02205 timeElement.setAttribute("subtype", fixed ? 0 : 1);
02206 timeElement.setAttribute("fix", fixed ? 1 : 0);
02207 timeElement.setAttribute("hour", time.hour());
02208 timeElement.setAttribute("minute", time.minute());
02209 timeElement.setAttribute("second", time.second());
02210
02211
02212
02213 variable.appendChild(timeElement);
02214 }
02215 else if (isTextNS && tag == "page-number")
02216 {
02217 QDomElement typeElem = doc.createElement("TYPE");
02218 typeElem.setAttribute("key", "NUMBER");
02219 typeElem.setAttribute("type", 4);
02220 typeElem.setAttribute("text", object.text());
02221
02222 variable.appendChild(typeElem);
02223
02224 QDomElement pgNumElem = doc.createElement("PGNUM");
02225
02226 int subtype = 0;
02227
02228 if (object.hasAttributeNS( ooNS::text, "select-page"))
02229 {
02230 const QString select = object.attributeNS( ooNS::text, "select-page", QString::null);
02231
02232 if (select == "previous")
02233 subtype = 3;
02234 else if (select == "next")
02235 subtype = 4;
02236 else
02237 subtype = 0;
02238 }
02239
02240 pgNumElem.setAttribute("subtype", subtype);
02241 pgNumElem.setAttribute("value", object.text());
02242
02243 variable.appendChild(pgNumElem);
02244 }
02245 else if (isTextNS && tag == "file-name")
02246 {
02247 QDomElement typeElem = doc.createElement("TYPE");
02248 typeElem.setAttribute("key", "STRING");
02249 typeElem.setAttribute("type", 8);
02250 typeElem.setAttribute("text", object.text());
02251
02252 variable.appendChild(typeElem);
02253
02254 int subtype = 5;
02255
02256 if (object.hasAttributeNS( ooNS::text, "display"))
02257 {
02258 const QString display = object.attributeNS( ooNS::text, "display", QString::null);
02259
02260 if (display == "path")
02261 subtype = 1;
02262 else if (display == "name")
02263 subtype = 6;
02264 else if (display == "name-and-extension")
02265 subtype = 0;
02266 else
02267 subtype = 5;
02268 }
02269
02270 QDomElement fileNameElem = doc.createElement("FIELD");
02271 fileNameElem.setAttribute("subtype", subtype);
02272 fileNameElem.setAttribute("value", object.text());
02273
02274 variable.appendChild(fileNameElem);
02275 }
02276 else if (isTextNS && tag == "author-name"
02277 || isTextNS && tag == "author-initials")
02278 {
02279 QDomElement typeElem = doc.createElement("TYPE");
02280 typeElem.setAttribute("key", "STRING");
02281 typeElem.setAttribute("type", 8);
02282 typeElem.setAttribute("text", object.text());
02283
02284 variable.appendChild(typeElem);
02285
02286 int subtype = 2;
02287
02288 if (isTextNS && tag == "author-initials")
02289 subtype = 16;
02290
02291 QDomElement authorElem = doc.createElement("FIELD");
02292 authorElem.setAttribute("subtype", subtype);
02293 authorElem.setAttribute("value", object.text());
02294
02295 variable.appendChild(authorElem);
02296 }
02297
02298 custom.appendChild(variable);
02299 e.appendChild(custom);
02300 }
02301
02302 void OoImpressImport::createPresentationAnimation(const QDomElement& element)
02303 {
02304 int order = 0;
02305 QDomElement e;
02306 forEachElement( e, element )
02307 {
02308 const QString localName = e.localName();
02309 const QString ns = e.namespaceURI();
02310 if ( ns == ooNS::presentation && localName == "show-shape" && e.hasAttributeNS( ooNS::draw, "shape-id" ) )
02311 {
02312 QString name = e.attributeNS( ooNS::draw, "shape-id", QString::null );
02313
02314 animationList *lst = new animationList;
02315 QDomElement* ep = new QDomElement( e );
02316 lst->element = ep;
02317 lst->order = order;
02318 m_animations.insert( name, lst );
02319 ++order;
02320 }
02321 }
02322 }
02323
02324 QDomElement OoImpressImport::findAnimationByObjectID(const QString & id, int & order)
02325 {
02326 kdDebug(30518)<<"QDomElement OoImpressImport::findAnimationByObjectID(const QString & id) :"<<id<<endl;
02327 if (m_animations.isEmpty() )
02328 return QDomElement();
02329
02330 animationList *animation = m_animations[id];
02331
02332 if ( !animation )
02333 return QDomElement();
02334 for (QDomNode node = *( animation->element ); !node.isNull(); node = node.nextSibling())
02335 {
02336 QDomElement e = node.toElement();
02337 order = animation->order;
02338 kdDebug(30518)<<"e.tagName() :"<<e.tagName()<<" e.attribute(draw:shape-id) :"<<e.attributeNS( ooNS::draw, "shape-id", QString::null)<<endl;
02339 if (e.tagName()=="presentation:show-shape" && e.attributeNS( ooNS::draw, "shape-id", QString::null)==id)
02340 return e;
02341 }
02342
02343 return QDomElement();
02344 }
02345
02346
02347 void OoImpressImport::appendObjectEffect(QDomDocument& doc, QDomElement& e, const QDomElement& object,
02348 QDomElement& sound)
02349 {
02350 int order = 0;
02351 QDomElement origEffect = findAnimationByObjectID(object.attributeNS( ooNS::draw, "id", QString::null), order).toElement();
02352
02353 if (origEffect.isNull())
02354 return;
02355
02356 QString effect = origEffect.attributeNS( ooNS::presentation, "effect", QString::null);
02357 QString dir = origEffect.attributeNS( ooNS::presentation, "direction", QString::null);
02358 QString speed = origEffect.attributeNS( ooNS::presentation, "speed", QString::null);
02359 kdDebug(30518)<<"speed :"<<speed<<endl;
02360
02361
02362 int effVal=0;
02363
02364 if (effect=="fade")
02365 {
02366 if (dir=="from-right")
02367 effVal=10;
02368 else if (dir=="from-left")
02369 effVal=9;
02370 else if (dir=="from-top")
02371 effVal=11;
02372 else if (dir=="from-bottom")
02373 effVal=12;
02374 else
02375 return;
02376 }
02377 else if (effect=="move")
02378 {
02379 if (dir=="from-right")
02380 effVal=1;
02381 else if (dir=="from-left")
02382 effVal=2;
02383 else if (dir=="from-top")
02384 effVal=3;
02385 else if (dir=="from-bottom")
02386 effVal=4;
02387 else if (dir=="from-upper-right")
02388 effVal=5;
02389 else if (dir=="from-lower-right")
02390 effVal=6;
02391 else if (dir=="from-upper-left")
02392 effVal=7;
02393 else if (dir=="from-lower-left")
02394 effVal=8;
02395 else
02396 return;
02397 }
02398 else
02399 return;
02400
02401 QDomElement effElem = doc.createElement("EFFECTS");
02402 effElem.setAttribute("effect", effVal);
02403 e.appendChild(effElem);
02404
02405 QDomElement presNum = doc.createElement( "PRESNUM" );
02406 presNum.setAttribute("value", order);
02407 e.appendChild( presNum );
02408
02409
02410 QDomElement origSoundEff = KoDom::namedItemNS( origEffect, ooNS::presentation, "sound");
02411 if (!origSoundEff.isNull())
02412 {
02413 QString soundUrl = storeSound(origSoundEff, sound, doc);
02414
02415 if (!soundUrl.isNull())
02416 {
02417 QDomElement pseElem = doc.createElement("APPEARSOUNDEFFECT");
02418 pseElem.setAttribute("appearSoundEffect", 1);
02419 pseElem.setAttribute("appearSoundFileName", soundUrl);
02420
02421 e.appendChild(pseElem);
02422 }
02423 }
02424 }
02425
02426 #include "ooimpressimport.moc"