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