summaryrefslogtreecommitdiffstats
path: root/filters/kpresenter/ooimpress/ooimpressimport.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'filters/kpresenter/ooimpress/ooimpressimport.cpp')
-rw-r--r--filters/kpresenter/ooimpress/ooimpressimport.cpp2432
1 files changed, 2432 insertions, 0 deletions
diff --git a/filters/kpresenter/ooimpress/ooimpressimport.cpp b/filters/kpresenter/ooimpress/ooimpressimport.cpp
new file mode 100644
index 000000000..5d6c9da4a
--- /dev/null
+++ b/filters/kpresenter/ooimpress/ooimpressimport.cpp
@@ -0,0 +1,2432 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002 Laurent Montel <lmontel@mandrakesoft.com>
+ Copyright (c) 2003 Lukas Tinkl <lukas@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "ooimpressimport.h"
+
+#include <math.h>
+
+#include <tqregexp.h>
+#include <tqdatetime.h>
+#include <tqfileinfo.h>
+#include <tqdir.h>
+
+#include <kzip.h>
+#include <karchive.h>
+#include <kdebug.h>
+#include <KoUnit.h>
+#include <KoDocumentInfo.h>
+#include <KoDocument.h>
+
+#include <kgenericfactory.h>
+#include <KoFilterChain.h>
+#include <KoGlobal.h>
+#include <ooutils.h>
+#include <KoDom.h>
+#include <KoOasisSettings.h>
+
+typedef KGenericFactory<OoImpressImport, KoFilter> OoImpressImportFactory;
+K_EXPORT_COMPONENT_FACTORY( libooimpressimport, OoImpressImportFactory( "kofficefilters" ) )
+
+
+OoImpressImport::OoImpressImport( KoFilter *, const char *, const TQStringList & )
+ : KoFilter(),
+ m_numPicture( 1 ),
+ m_numSound(1),
+ m_styles( 23, true ),
+ m_styleStack( ooNS::style, ooNS::fo )
+{
+ m_styles.setAutoDelete( true );
+ m_listStyles.setAutoDelete( true );
+}
+
+OoImpressImport::~OoImpressImport()
+{
+ TQDictIterator<animationList> it( m_animations ); // See TQDictIterator
+ for( ; it.current(); ++it )
+ {
+ delete it.current()->element;
+ }
+ m_animations.clear();
+}
+
+KoFilter::ConversionStatus OoImpressImport::convert( TQCString const & from, TQCString const & to )
+{
+ kdDebug(30518) << "Entering Ooimpress Import filter: " << from << " - " << to << endl;
+
+ if ( (from != "application/vnd.sun.xml.impress" && from != "application/vnd.sun.xml.impress.template" )
+ || to != "application/x-kpresenter" )
+ {
+ kdWarning(30518) << "Invalid mimetypes " << from << " " << to << endl;
+ return KoFilter::NotImplemented;
+ }
+
+ m_zip = new KZip( m_chain->inputFile() );
+
+ if ( !m_zip->open( IO_ReadOnly ) )
+ {
+ kdError(30518) << "Couldn't open the requested file "<< m_chain->inputFile() << endl;
+ delete m_zip;
+ return KoFilter::FileNotFound;
+ }
+
+ KoFilter::ConversionStatus preStatus = openFile();
+
+ if ( preStatus != KoFilter::OK )
+ {
+ m_zip->close();
+ delete m_zip;
+ return preStatus;
+ }
+
+ TQDomDocument docinfo;
+ createDocumentInfo( docinfo );
+
+ // store document info
+ KoStoreDevice* out = m_chain->storageFile( "documentinfo.xml", KoStore::Write );
+ if( out )
+ {
+ TQCString info = docinfo.toCString();
+ //kdDebug(30518) << " info :" << info << endl;
+ // WARNING: we cannot use KoStore::write(const TQByteArray&) because it gives an extra NULL character at the end.
+ out->writeBlock( info , info.length() );
+ }
+
+ TQDomDocument doccontent;
+ createDocumentContent( doccontent );
+
+ // store document content
+ out = m_chain->storageFile( "maindoc.xml", KoStore::Write );
+ if( out )
+ {
+ TQCString content = doccontent.toCString();
+ kdDebug(30518) << " content :" << content << endl;
+ out->writeBlock( content , content.length() );
+ }
+
+ m_zip->close();
+ delete m_zip;
+
+ kdDebug(30518) << "######################## OoImpressImport::convert done ####################" << endl;
+ return KoFilter::OK;
+}
+
+// Very related to OoWriterImport::openFile()
+KoFilter::ConversionStatus OoImpressImport::openFile()
+{
+ KoFilter::ConversionStatus status = loadAndParse( "content.xml", m_content );
+ if ( status != KoFilter::OK )
+ {
+ kdError(30518) << "Content.xml could not be parsed correctly! Aborting!" << endl;
+ return status;
+ }
+
+ // We do not stop if the following calls fail.
+ TQDomDocument styles;
+ loadAndParse( "styles.xml", styles );
+ loadAndParse( "meta.xml", m_meta );
+ loadAndParse( "settings.xml", m_settings );
+
+ emit sigProgress( 10 );
+ createStyleMap( styles );
+
+ return KoFilter::OK;
+}
+
+KoFilter::ConversionStatus OoImpressImport::loadAndParse(const TQString& filename, TQDomDocument& doc)
+{
+ return OoUtils::loadAndParse( filename, doc, m_zip);
+}
+
+// Very related to OoWriterImport::createDocumentInfo
+void OoImpressImport::createDocumentInfo( TQDomDocument &docinfo )
+{
+ docinfo = KoDocument::createDomDocument( "document-info" /*DTD name*/, "document-info" /*tag name*/, "1.1" );
+
+ OoUtils::createDocumentInfo(m_meta, docinfo);
+ //kdDebug(30518) << " meta-info :" << m_meta.toCString() << endl;
+}
+
+void OoImpressImport::createDocumentContent( TQDomDocument &doccontent )
+{
+ TQDomDocument doc = KoDocument::createDomDocument( "kpresenter", "DOC", "1.2" );
+ TQDomElement docElement = doc.documentElement();
+ docElement.setAttribute( "editor", "KPresenter" );
+ docElement.setAttribute( "mime", "application/x-kpresenter" );
+ docElement.setAttribute( "syntaxVersion", "2" );
+
+ TQDomElement content = m_content.documentElement();
+
+ // content.xml contains some automatic-styles that we need to store
+ TQDomNode automaticStyles = KoDom::namedItemNS( content, ooNS::office, "automatic-styles" );
+ if ( !automaticStyles.isNull() )
+ insertStyles( automaticStyles.toElement() );
+
+ TQDomNode body = KoDom::namedItemNS( content, ooNS::office, "body" );
+ if ( body.isNull() )
+ return;
+
+ TQDomElement customSlideShow = doc.createElement( "CUSTOMSLIDESHOWCONFIG" );
+
+ // presentation settings
+ TQDomElement settings = KoDom::namedItemNS( body, ooNS::presentation, "settings");
+ if (!settings.isNull())
+ {
+ if (settings.attributeNS( ooNS::presentation, "endless", TQString())=="true")
+ {
+ TQDomElement infElem = doc.createElement("INFINITLOOP");
+ infElem.setAttribute("value", 1);
+ docElement.appendChild(infElem);
+ }
+
+ if (settings.attributeNS( ooNS::presentation, "show-end-of-presentation-slide", TQString())=="true")
+ {
+ TQDomElement infElem = doc.createElement("SHOWENDOFPRESENTATIONSLIDE");
+ infElem.setAttribute("value", 1);
+ docElement.appendChild(infElem);
+ }
+
+ if (settings.attributeNS( ooNS::presentation, "force-manual", TQString())=="true")
+ {
+ TQDomElement manualElem = doc.createElement("MANUALSWITCH");
+ manualElem.setAttribute("value", 1);
+ docElement.appendChild(manualElem);
+ }
+ if ( settings.hasAttributeNS( ooNS::presentation, "show") )
+ {
+ TQDomElement defaultPage = doc.createElement("DEFAULTCUSTOMSLIDESHOWNAME");
+ defaultPage.setAttribute("name", settings.attributeNS( ooNS::presentation, "show", TQString()) );
+ docElement.appendChild(defaultPage);
+ }
+ }
+
+ TQDomElement presentationShow;
+ forEachElement( presentationShow, settings )
+ {
+ if ( presentationShow.localName()=="show" && presentationShow.namespaceURI() == ooNS::presentation )
+ {
+ if ( presentationShow.hasAttributeNS( ooNS::presentation, "pages") &&
+ presentationShow.hasAttributeNS( ooNS::presentation, "name"))
+ {
+ TQDomElement slide=doc.createElement("CUSTOMSLIDESHOW");
+ slide.setAttribute( "pages", presentationShow.attributeNS( ooNS::presentation, "pages", TQString() ));
+ slide.setAttribute( "name", presentationShow.attributeNS( ooNS::presentation, "name", TQString() ));
+ customSlideShow.appendChild( slide );
+ }
+ }
+ }
+ // it seems that ooimpress has different paper-settings for every slide.
+ // we take the settings of the first slide for the whole document.
+ TQDomElement drawPage = KoDom::namedItemNS( body, ooNS::draw, "page" );
+ if ( drawPage.isNull() ) // no slides? give up.
+ return;
+
+ TQDomElement objectElement = doc.createElement( "OBJECTS" );
+ TQDomElement pictureElement = doc.createElement( "PICTURES" );
+ TQDomElement pageTitleElement = doc.createElement( "PAGETITLES" );
+ TQDomElement pageNoteElement = doc.createElement( "PAGENOTES" );
+ TQDomElement backgroundElement = doc.createElement( "BACKGROUND" );
+ TQDomElement soundElement = doc.createElement( "SOUNDS" );
+ TQDomElement selSlideElement = doc.createElement( "SELSLIDES" );
+ TQDomElement helpLineElement = doc.createElement( "HELPLINES" );
+ TQDomElement attributeElement = doc.createElement( "ATTRIBUTES" );
+ TQDomElement *master = m_styles[drawPage.attributeNS( ooNS::draw, "master-page-name", TQString() )];
+
+ appendObject(*master, doc, soundElement,pictureElement,pageNoteElement,objectElement, 0, true);
+
+ TQDomElement *style = m_styles[master->attributeNS( ooNS::style, "page-master-name", TQString() )];
+ TQDomElement properties = KoDom::namedItemNS( *style, ooNS::style, "properties" );
+ //kdDebug(30518)<<" master->attribute( draw:style-name ) :"<<master->attributeNS( ooNS::draw, "style-name", TQString() )<<endl;
+ TQDomElement *backgroundStyle = m_stylesPresentation[ master->attributeNS( ooNS::draw, "style-name", TQString() ).isEmpty() ? "Standard-background" : master->attributeNS( ooNS::draw, "style-name", TQString() ) ];
+
+ //kdDebug(30518)<<" backgroundStyle :"<<backgroundStyle<<endl;
+ double pageHeight;
+ TQDomElement paperElement = doc.createElement( "PAPER" );
+ if ( properties.isNull() )
+ {
+ paperElement.setAttribute( "ptWidth", CM_TO_POINT(28) );
+ paperElement.setAttribute( "ptHeight", CM_TO_POINT(21) );
+ paperElement.setAttribute( "unit", 0 );
+ paperElement.setAttribute( "format", 5 );
+ paperElement.setAttribute( "tabStopValue", 42.5198 );
+ paperElement.setAttribute( "orientation", 0 );
+ pageHeight = 21;
+
+ TQDomElement paperBorderElement = doc.createElement( "PAPERBORDERS" );
+ paperBorderElement.setAttribute( "ptRight", 0 );
+ paperBorderElement.setAttribute( "ptBottom", 0 );
+ paperBorderElement.setAttribute( "ptLeft", 0 );
+ paperBorderElement.setAttribute( "ptTop", 0 );
+ paperElement.appendChild( paperBorderElement );
+ }
+ else
+ {
+ paperElement.setAttribute( "ptWidth", KoUnit::parseValue(properties.attributeNS( ooNS::fo, "page-width", TQString() ) ) );
+ paperElement.setAttribute( "ptHeight", KoUnit::parseValue(properties.attributeNS( ooNS::fo, "page-height", TQString() ) ) );
+// paperElement.setAttribute( "unit", 0 );
+// paperElement.setAttribute( "format", 5 );
+// paperElement.setAttribute( "tabStopValue", 42.5198 );
+// paperElement.setAttribute( "orientation", 0 );
+ // Keep pageHeight in cm to avoid rounding-errors that would
+ // get multiplied with every new slide.
+
+ if (properties.attributeNS( ooNS::style, "print-orientation", TQString())=="portrait")
+ paperElement.setAttribute("orientation", 0);
+ else if (properties.attributeNS( ooNS::style, "print-orientation", TQString())=="landscape")
+ paperElement.setAttribute("orientation", 1);
+
+
+
+ pageHeight = properties.attributeNS( ooNS::fo, "page-height", TQString() ).remove( "cm" ).toDouble();
+
+ TQDomElement paperBorderElement = doc.createElement( "PAPERBORDERS" );
+ paperBorderElement.setAttribute( "ptRight", KoUnit::parseValue( properties.attributeNS( ooNS::fo, "margin-right", TQString() ) ) );
+ paperBorderElement.setAttribute( "ptBottom", KoUnit::parseValue( properties.attributeNS( ooNS::fo, "margin-bottom", TQString() ) ) );
+ paperBorderElement.setAttribute( "ptLeft", KoUnit::parseValue( properties.attributeNS( ooNS::fo, "margin-left", TQString() ) ) );
+ paperBorderElement.setAttribute( "ptTop", KoUnit::parseValue( properties.attributeNS( ooNS::fo, "margin-top", TQString() ) ) );
+ paperElement.appendChild( paperBorderElement );
+ }
+
+
+ // parse all pages
+ forEachElement( drawPage, body )
+ {
+ if ( drawPage.localName()=="page" && drawPage.namespaceURI() == ooNS::draw && drawPage.hasAttributeNS( ooNS::draw, "id" ))
+ {
+ m_styleStack.clear(); // remove all styles
+ fillStyleStack( drawPage );
+ m_styleStack.save();
+ int pagePos = drawPage.attributeNS( ooNS::draw, "id", TQString() ).toInt() - 1;
+ // take care of a possible page background or slide transition or sound
+ if ( m_styleStack.hasAttributeNS( ooNS::draw, "fill" )
+ || m_styleStack.hasAttributeNS( ooNS::presentation, "transition-style" ))
+ {
+ appendBackgroundPage( doc, backgroundElement,pictureElement, soundElement );
+ }
+ else if ( !m_styleStack.hasAttributeNS( ooNS::draw, "fill" ) && backgroundStyle)
+ {
+ m_styleStack.save();
+ m_styleStack.push( *backgroundStyle );
+ appendBackgroundPage( doc, backgroundElement,pictureElement, soundElement );
+ m_styleStack.restore();
+ kdDebug(30518)<<" load standard bacground \n";
+ }
+ if ( m_styleStack.hasAttributeNS( ooNS::presentation, "visibility" ) )
+ {
+ TQString str = m_styleStack.attributeNS( ooNS::presentation, "visibility" );
+ TQDomElement slide = doc.createElement("SLIDE");
+ slide.setAttribute( "nr", pagePos );
+ slide.setAttribute( "show", ( ( str=="hidden" ) ? "0" : "1" ));
+ selSlideElement.appendChild( slide );
+
+ //todo add support
+ kdDebug(30518)<<"m_styleStack.hasAttribute( presentation:visibility ) :"<<str<<" position page "<<pagePos<<endl;
+ }
+ // set the pagetitle
+ TQDomElement titleElement = doc.createElement( "Title" );
+ titleElement.setAttribute( "title", drawPage.attributeNS( ooNS::draw, "name", TQString() ) );
+ pageTitleElement.appendChild( titleElement );
+
+ // The '+1' is necessary to avoid that objects that start on the first line
+ // of a slide will show up on the last line of the previous slide.
+ double offset = CM_TO_POINT( ( drawPage.attributeNS( ooNS::draw, "id", TQString() ).toInt() - 1 ) * pageHeight ) + 1;
+
+ // animations (object effects)
+ createPresentationAnimation(KoDom::namedItemNS( drawPage, ooNS::presentation, "animations") );
+
+ // parse all objects
+ appendObject(drawPage, doc, soundElement,pictureElement,pageNoteElement,objectElement, offset);
+
+ //m_animations.clear();
+ m_styleStack.restore();
+ }
+ }
+
+ docElement.appendChild( paperElement );
+ docElement.appendChild( backgroundElement );
+ if ( parseSettings( doc, helpLineElement, attributeElement ) )
+ docElement.appendChild( helpLineElement );
+ docElement.appendChild( attributeElement );
+ docElement.appendChild( pageTitleElement );
+ docElement.appendChild( pageNoteElement );
+ docElement.appendChild( objectElement );
+ docElement.appendChild( selSlideElement );
+ docElement.appendChild( customSlideShow );
+ docElement.appendChild( soundElement );
+ docElement.appendChild( pictureElement );
+
+ doccontent.appendChild( doc );
+}
+
+bool OoImpressImport::parseSettings( TQDomDocument &doc, TQDomElement &helpLineElement, TQDomElement &attributeElement )
+{
+ bool foundElement = false;
+ KoOasisSettings settings( m_settings, ooNS::office, ooNS::config );
+ KoOasisSettings::Items viewSettings = settings.itemSet( "view-settings" );
+ //setUnit(KoUnit::unit(viewSettings.parseConfigItemString("unit")));
+ KoOasisSettings::IndexedMap viewMap = viewSettings.indexedMap( "Views" );
+ KoOasisSettings::Items firstView = viewMap.entry( 0 );
+ //<config:config-item config:name="SnapLinesDrawing" config:type="string">V7939H1139</config:config-item>
+ //by default show line
+
+ if ( !firstView.isNull() )
+ {
+ TQString str = firstView.parseConfigItemString( "SnapLinesDrawing" );
+ if ( !str.isEmpty() )
+ {
+ parseHelpLine( doc, helpLineElement, str );
+ //display it by default
+ helpLineElement.setAttribute( "show", true );
+ foundElement = true;
+ }
+
+ int gridX = firstView.parseConfigItemInt( "GridFineWidth" );
+ int gridY = firstView.parseConfigItemInt( "GridFineHeight" );
+ bool snapToGrid = firstView.parseConfigItemBool( "IsSnapToGrid" );
+ int selectedPage = firstView.parseConfigItemInt( "SelectedPage" );
+
+ attributeElement.setAttribute( "activePage", selectedPage );
+ attributeElement.setAttribute( "gridx", MM_TO_POINT( gridX / 100.0 ) );
+ attributeElement.setAttribute( "gridy", MM_TO_POINT( gridY / 100.0 ) );
+ attributeElement.setAttribute( "snaptogrid", (int)snapToGrid );
+
+ }
+
+ //kdDebug(30518)<<" gridX :"<<gridX<<" gridY :"<<gridY<<" snapToGrid :"<<snapToGrid<<" selectedPage :"<<selectedPage<<endl;
+ return foundElement;
+}
+
+void OoImpressImport::parseHelpLine( TQDomDocument &doc,TQDomElement &helpLineElement, const TQString &text )
+{
+ TQString str;
+ int newPos = text.length()-1; //start to element = 1
+ for ( int pos = text.length()-1; pos >=0;--pos )
+ {
+ if ( text[pos]=='P' )
+ {
+
+ //point
+ str = text.mid( pos+1, ( newPos-pos ) );
+ TQDomElement point=doc.createElement("HelpPoint");
+
+ //kdDebug(30518)<<" point element :"<< str <<endl;
+ TQStringList listVal = TQStringList::split( ",", str );
+ int posX = ( listVal[0].toInt()/100 );
+ int posY = ( listVal[1].toInt()/100 );
+ point.setAttribute("posX", MM_TO_POINT( posX ));
+ point.setAttribute("posY", MM_TO_POINT( posY ));
+
+ helpLineElement.appendChild( point );
+ newPos = pos-1;
+ }
+ else if ( text[pos]=='V' )
+ {
+ TQDomElement lines=doc.createElement("Vertical");
+ //vertical element
+ str = text.mid( pos+1, ( newPos-pos ) );
+ //kdDebug(30518)<<" vertical :"<< str <<endl;
+ int posX = ( str.toInt()/100 );
+ lines.setAttribute( "value", MM_TO_POINT( posX ) );
+ helpLineElement.appendChild( lines );
+
+ newPos = ( pos-1 );
+
+ }
+ else if ( text[pos]=='H' )
+ {
+ //horizontal element
+ TQDomElement lines=doc.createElement("Horizontal");
+ str = text.mid( pos+1, ( newPos-pos ) );
+ //kdDebug(30518)<<" horizontal :"<< str <<endl;
+ int posY = ( str.toInt()/100 );
+ lines.setAttribute( "value", MM_TO_POINT( posY ) );
+ helpLineElement.appendChild( lines );
+ newPos = pos-1;
+ }
+ }
+}
+
+void OoImpressImport::appendObject(TQDomNode & drawPage, TQDomDocument & doc, TQDomElement & soundElement, TQDomElement & pictureElement, TQDomElement & pageNoteElement, TQDomElement &objectElement, double offset, bool sticky)
+{
+ TQDomElement o;
+ forEachElement( o, drawPage )
+ {
+ const TQString localName = o.localName();
+ const TQString ns = o.namespaceURI();
+ const TQString drawID = o.attributeNS( ooNS::draw, "id", TQString());
+ m_styleStack.save();
+
+ TQDomElement e;
+ if ( localName == "text-box" && ns == ooNS::draw ) // textbox
+ {
+ fillStyleStack( o, sticky );
+ e = doc.createElement( "OBJECT" );
+ e.setAttribute( "type", 4 );
+ if ( sticky )
+ e.setAttribute( "sticky", "1" );
+ append2DGeometry( doc, e, o, (int)offset );
+ appendName(doc, e, o);
+ appendPen( doc, e );
+ appendBrush( doc, e );
+ appendRounding( doc, e, o );
+ appendShadow( doc, e );
+ appendObjectEffect(doc, e, o, soundElement);
+ e.appendChild( parseTextBox( doc, o ) );
+ }
+ else if ( localName == "rect" && ns == ooNS::draw ) // rectangle
+ {
+ fillStyleStack( o, sticky );
+ e = doc.createElement( "OBJECT" );
+ e.setAttribute( "type", 2 );
+ if ( sticky )
+ e.setAttribute( "sticky", "1" );
+ append2DGeometry( doc, e, o, (int)offset );
+ appendName(doc, e, o);
+ appendPen( doc, e );
+ appendBrush( doc, e );
+ appendRounding( doc, e, o );
+ appendShadow( doc, e );
+
+ appendObjectEffect(doc, e, o, soundElement);
+ }
+ else if ( ( localName == "circle" || localName == "ellipse" ) && ns == ooNS::draw )
+ {
+ fillStyleStack( o, sticky );
+ e = doc.createElement( "OBJECT" );
+ if ( sticky )
+ e.setAttribute( "sticky", "1" );
+ append2DGeometry( doc, e, o, (int)offset );
+ appendName(doc, e, o);
+ appendPen( doc, e );
+ appendShadow( doc, e );
+ appendLineEnds( doc, e );
+ appendObjectEffect(doc, e, o, soundElement);
+
+ if ( o.hasAttributeNS( ooNS::draw, "kind" ) ) // pie, chord or arc
+ {
+ e.setAttribute( "type", 8 );
+ appendPie( doc, e, o );
+ TQDomElement type = doc.createElement( "PIETYPE" );
+
+ TQString kind = o.attributeNS( ooNS::draw, "kind", TQString() );
+ if ( kind == "section" )
+ {
+ appendBrush( doc, e );
+ type.setAttribute( "value", 0 );
+ }
+ else if ( kind == "cut" )
+ {
+ appendBrush( doc, e );
+ type.setAttribute( "value", 2 );
+ }
+ else if ( kind == "arc" )
+ {
+ // arc has no brush
+ type.setAttribute( "value", 1 );
+ }
+ e.appendChild( type );
+ }
+ else // circle or ellipse
+ {
+ e.setAttribute( "type", 3 );
+ appendBrush( doc, e );
+ }
+ }
+ else if ( localName == "line" && ns == ooNS::draw ) // line
+ {
+ fillStyleStack( o, sticky );
+ e = doc.createElement( "OBJECT" );
+ e.setAttribute( "type", 1 );
+ if ( sticky )
+ e.setAttribute( "sticky", "1" );
+ bool orderEndStartLine = appendLineGeometry( doc, e, o, (int)offset );
+ appendName(doc, e, o);
+ appendPen( doc, e );
+ appendBrush( doc, e );
+ appendShadow( doc, e );
+ appendLineEnds( doc, e, orderEndStartLine );
+ appendObjectEffect(doc, e, o, soundElement);
+ }
+ else if ( localName=="polyline" && ns == ooNS::draw ) { // polyline
+ fillStyleStack(o, sticky);
+ e = doc.createElement("OBJECT");
+ e.setAttribute("type", 12);
+ if ( sticky )
+ e.setAttribute( "sticky", "1" );
+ append2DGeometry(doc, e, o, (int)offset);
+ appendName(doc, e, o);
+ appendPoints(doc, e, o);
+ appendPen(doc, e);
+ appendBrush(doc, e);
+ appendLineEnds(doc, e);
+ //appendShadow(doc, e);
+ appendObjectEffect(doc, e, o, soundElement);
+ }
+ else if ( localName=="polygon" && ns == ooNS::draw ) { // polygon
+ fillStyleStack(o, sticky);
+ e = doc.createElement("OBJECT");
+ e.setAttribute("type", 16);
+ if ( sticky )
+ e.setAttribute( "sticky", "1" );
+ append2DGeometry(doc, e, o, (int)offset);
+ appendName(doc, e, o);
+ appendPoints(doc, e, o);
+ appendPen(doc, e);
+ appendBrush(doc, e);
+ //appendLineEnds(doc, e);
+ //appendShadow(doc, e);
+ appendObjectEffect(doc, e, o, soundElement);
+ }
+ else if ( localName == "image" && ns == ooNS::draw ) // image
+ {
+ fillStyleStack( o, sticky );
+ e = doc.createElement( "OBJECT" );
+ e.setAttribute( "type", 0 );
+ if ( sticky )
+ e.setAttribute( "sticky", "1" );
+ append2DGeometry( doc, e, o, (int)offset );
+ appendName(doc, e, o);
+ appendImage( doc, e, pictureElement, o );
+ appendObjectEffect(doc, e, o, soundElement);
+ }
+ else if ( localName == "object" && ns == ooNS::draw )
+ {
+ //todo add part object
+ }
+ else if ( localName == "g" && ns == ooNS::draw )
+ {
+ //todo add group object
+ }
+ else if ( localName == "path" && ns == ooNS::draw )
+ {
+ //todo add path object (freehand/cubic/quadricbeziercurve
+ }
+ else if ( localName == "notes" && ns == ooNS::presentation ) // notes
+ {
+ TQDomNode textBox = KoDom::namedItemNS( o, ooNS::draw, "text-box" );
+ if ( !textBox.isNull() )
+ {
+ TQString note;
+ TQDomElement t;
+ forEachElement( t, textBox )
+ {
+ // We don't care about styles as they are not supported in kpresenter.
+ // Only add a linebreak for every child.
+ note += t.text() + "\n";
+ }
+ TQDomElement notesElement = doc.createElement( "Note" );
+ notesElement.setAttribute( "note", note );
+ pageNoteElement.appendChild( notesElement );
+ }
+ }
+ else
+ {
+ kdDebug(30518) << "Unsupported object '" << localName << "'" << endl;
+ m_styleStack.restore();
+ continue;
+ }
+
+ objectElement.appendChild( e );
+ m_styleStack.restore();
+ }
+}
+
+void OoImpressImport::appendBackgroundPage( TQDomDocument &doc, TQDomElement &backgroundElement, TQDomElement & pictureElement, TQDomElement &soundElement)
+{
+ TQDomElement bgPage = doc.createElement( "PAGE" );
+
+ // background
+ if ( m_styleStack.hasAttributeNS( ooNS::draw, "fill" ) )
+ {
+ const TQString fill = m_styleStack.attributeNS( ooNS::draw, "fill" );
+ if ( fill == "solid" )
+ {
+ TQDomElement backColor1 = doc.createElement( "BACKCOLOR1" );
+ backColor1.setAttribute( "color", m_styleStack.attributeNS( ooNS::draw, "fill-color" ) );
+ bgPage.appendChild( backColor1 );
+
+ TQDomElement bcType = doc.createElement( "BCTYPE" );
+ bcType.setAttribute( "value", 0 ); // plain
+ bgPage.appendChild( bcType );
+
+ TQDomElement backType = doc.createElement( "BACKTYPE" );
+ backType.setAttribute( "value", 0 ); // color/gradient
+ bgPage.appendChild( backType );
+ }
+ else if ( fill == "gradient" )
+ {
+ TQString style = m_styleStack.attributeNS( ooNS::draw, "fill-gradient-name" );
+ TQDomElement* draw = m_draws[style];
+ appendBackgroundGradient( doc, bgPage, *draw );
+ }
+ else if ( fill == "bitmap" )
+ {
+ TQString style = m_styleStack.attributeNS( ooNS::draw, "fill-image-name" );
+ TQDomElement* draw = m_draws[style];
+ appendBackgroundImage( doc, bgPage, pictureElement, *draw );
+
+ TQDomElement backView = doc.createElement( "BACKVIEW" );
+ if ( m_styleStack.hasAttributeNS( ooNS::style, "repeat" ) )
+ {
+ TQString repeat = m_styleStack.attributeNS( ooNS::style, "repeat" );
+ if ( repeat == "stretch" )
+ backView.setAttribute( "value", 0 ); // zoomed
+ else if ( repeat == "no-repeat" )
+ backView.setAttribute( "value", 1 ); // centered
+ else
+ backView.setAttribute( "value", 2 ); // use tiled as default
+ }
+ else
+ backView.setAttribute( "value", 2 ); // use tiled as default
+ bgPage.appendChild( backView );
+
+ TQDomElement backType = doc.createElement( "BACKTYPE" );
+ backType.setAttribute( "value", 1 ); // image
+ bgPage.appendChild( backType );
+ }
+ }
+
+ if ( m_styleStack.hasAttributeNS( ooNS::presentation, "duration" ) )
+ {
+ TQString str = m_styleStack.attributeNS( ooNS::presentation, "duration");
+ kdDebug(30518)<<"styleStack.hasAttribute(presentation:duration ) :"<<str<<endl;
+ //convert date duration
+ int hour( str.mid( 2, 2 ).toInt() );
+ int minute( str.mid( 5, 2 ).toInt() );
+ int second( str.mid( 8, 2 ).toInt() );
+ int pageTimer = second + minute*60 + hour*60*60;
+ TQDomElement pgEffect = doc.createElement("PGTIMER");
+ pgEffect.setAttribute( "timer", pageTimer );
+ bgPage.appendChild(pgEffect);
+ }
+ // slide transition
+ if (m_styleStack.hasAttributeNS( ooNS::presentation, "transition-style"))
+ {
+ TQDomElement pgEffect = doc.createElement("PGEFFECT");
+
+ const TQString effect = m_styleStack.attributeNS( ooNS::presentation, "transition-style");
+ //kdDebug(30518) << "Transition name: " << effect << endl;
+ int pef;
+
+ if (effect=="vertical-stripes" || effect=="vertical-lines") // PEF_BLINDS_VER
+ pef=14;
+ else if (effect=="horizontal-stripes" || effect=="horizontal-lines") // PEF_BLINDS_HOR
+ pef=13;
+ else if (effect=="spiralin-left" || effect=="spiralin-right"
+ || effect== "spiralout-left" || effect=="spiralout-right") // PEF_SURROUND1
+ pef=11;
+ else if (effect=="fade-from-upperleft") // PEF_STRIPS_RIGHT_DOWN
+ pef=39;
+ else if (effect=="fade-from-upperright") // PEF_STRIPS_LEFT_DOWN
+ pef=37;
+ else if (effect=="fade-from-lowerleft") // PEF_STRIPS_RIGHT_UP
+ pef=38;
+ else if (effect=="fade-from-lowerright") // PEF_STRIPS_LEFT_UP
+ pef=36;
+ else if (effect=="fade-from-top") // PEF_COVER_DOWN
+ pef=19;
+ else if (effect=="fade-from-bottom") // PEF_COVER_UP
+ pef=21;
+ else if (effect=="fade-from-left") // PEF_COVER_RIGHT
+ pef=25;
+ else if (effect=="fade-from-right") // PEF_COVER_LEFT
+ pef=23;
+ else if (effect=="fade-to-center") // PEF_CLOSE_ALL
+ pef=3;
+ else if (effect=="fade-from-center") // PEF_OPEN_ALL
+ pef=6;
+ else if (effect=="open-vertical") // PEF_OPEN_HORZ; really, no kidding ;)
+ pef=4;
+ else if (effect=="open-horizontal") // PEF_OPEN_VERT
+ pef=5;
+ else if (effect=="close-vertical") // PEF_CLOSE_HORZ
+ pef=1;
+ else if (effect=="close-horizontal") // PEF_CLOSE_VERT
+ pef=2;
+ else if (effect=="dissolve") // PEF_DISSOLVE; perfect hit ;)
+ pef=35;
+ else if (effect=="horizontal-checkerboard") // PEF_CHECKBOARD_ACROSS
+ pef=17;
+ else if (effect=="vertical-checkerboard") // PEF_CHECKBOARD_DOWN
+ pef=18;
+ else if (effect=="roll-from-left") // PEF_UNCOVER_RIGHT
+ pef=26;
+ else if (effect=="roll-from-right") // PEF_UNCOVER_LEFT
+ pef=24;
+ else if (effect=="roll-from-bottom") // PEF_UNCOVER_UP
+ pef=22;
+ else if (effect=="roll-from-top") // PEF_UNCOVER_DOWN
+ pef=20;
+ else if (effect=="random") // PEF_RANDOM
+ pef=-1;
+ else // we choose a random transition instead of the unsupported ones ;)
+ pef=-1;
+
+ pgEffect.setAttribute("value", pef);
+ bgPage.appendChild(pgEffect);
+ }
+
+ // slide transition sound
+ if (m_styleStack.hasChildNodeNS( ooNS::presentation, "sound"))
+ {
+ TQString soundUrl = storeSound(m_styleStack.childNodeNS( ooNS::presentation, "sound"),
+ soundElement, doc);
+
+ if (!soundUrl.isNull())
+ {
+ TQDomElement pseElem = doc.createElement("PGSOUNDEFFECT");
+ pseElem.setAttribute("soundEffect", 1);
+ pseElem.setAttribute("soundFileName", soundUrl);
+
+ bgPage.appendChild(pseElem);
+ }
+ }
+
+ backgroundElement.appendChild(bgPage);
+}
+
+void OoImpressImport::appendName(TQDomDocument& doc, TQDomElement& e, const TQDomElement& object)
+{
+ if( object.hasAttributeNS( ooNS::draw, "name" ))
+ {
+ TQDomElement name = doc.createElement( "OBJECTNAME" );
+ name.setAttribute( "objectName", object.attributeNS( ooNS::draw, "name", TQString() ));
+ e.appendChild( name );
+ }
+}
+
+void OoImpressImport::append2DGeometry( TQDomDocument& doc, TQDomElement& e, const TQDomElement& object, int offset )
+{
+ TQDomElement orig = doc.createElement( "ORIG" );
+ orig.setAttribute( "x", KoUnit::parseValue( object.attributeNS( ooNS::svg, "x", TQString() ) ) );
+ orig.setAttribute( "y", KoUnit::parseValue( object.attributeNS( ooNS::svg, "y", TQString() ) ) + offset );
+ e.appendChild( orig );
+
+ TQDomElement size = doc.createElement( "SIZE" );
+ size.setAttribute( "width", KoUnit::parseValue( object.attributeNS( ooNS::svg, "width", TQString() ) ) );
+ size.setAttribute( "height", KoUnit::parseValue( object.attributeNS( ooNS::svg, "height", TQString() ) ) );
+ e.appendChild( size );
+ if( object.hasAttributeNS( ooNS::draw, "transform" ))
+ {
+ kdDebug(30518)<<" object transform \n";
+ //todo parse it
+ TQString transform = object.attributeNS( ooNS::draw, "transform", TQString() );
+ if( transform.contains("rotate ("))
+ {
+ //kdDebug(30518)<<" rotate object \n";
+ transform = transform.remove("rotate (" );
+ transform = transform.left(transform.find(")"));
+ //kdDebug(30518)<<" transform :"<<transform<<endl;
+ bool ok;
+ double radian = transform.toDouble(&ok);
+ if( ok )
+ {
+ TQDomElement angle = doc.createElement( "ANGLE" );
+ //angle is defined as a radian in oo but degree into kpresenter.
+ angle.setAttribute("value", (-1 * ((radian*180)/M_PI)));
+
+ e.appendChild( angle );
+ }
+ }
+ }
+}
+
+//return true if (x1 < x2) necessary to load correctly start-line and end-line
+bool OoImpressImport::appendLineGeometry( TQDomDocument& doc, TQDomElement& e, const TQDomElement& object, int offset )
+{
+ double x1 = KoUnit::parseValue( object.attributeNS( ooNS::svg, "x1", TQString() ) );
+ double y1 = KoUnit::parseValue( object.attributeNS( ooNS::svg, "y1", TQString() ) );
+ double x2 = KoUnit::parseValue( object.attributeNS( ooNS::svg, "x2", TQString() ) );
+ double y2 = KoUnit::parseValue( object.attributeNS( ooNS::svg, "y2", TQString() ) );
+
+ double x = TQMIN( x1, x2 );
+ double y = TQMIN( y1, y2 );
+
+ TQDomElement orig = doc.createElement( "ORIG" );
+ orig.setAttribute( "x", x );
+ orig.setAttribute( "y", y + offset );
+ e.appendChild( orig );
+
+ TQDomElement size = doc.createElement( "SIZE" );
+ size.setAttribute( "width", fabs( x1 - x2 ) );
+ size.setAttribute( "height", fabs( y1 - y2 ) );
+ e.appendChild( size );
+
+ TQDomElement linetype = doc.createElement( "LINETYPE" );
+ if ( ( x1 < x2 && y1 < y2 ) || ( x1 > x2 && y1 > y2 ) )
+ linetype.setAttribute( "value", 2 );
+ else
+ linetype.setAttribute( "value", 3 );
+
+ e.appendChild( linetype );
+ return (x1 < x2);
+}
+
+void OoImpressImport::appendPen( TQDomDocument& doc, TQDomElement& e )
+{
+ if ( m_styleStack.hasAttributeNS( ooNS::draw, "stroke" ))
+ {
+ TQDomElement pen = doc.createElement( "PEN" );
+ if ( m_styleStack.attributeNS( ooNS::draw, "stroke" ) == "none" )
+ pen.setAttribute( "style", 0 );
+ else if ( m_styleStack.attributeNS( ooNS::draw, "stroke" ) == "solid" )
+ pen.setAttribute( "style", 1 );
+ else if ( m_styleStack.attributeNS( ooNS::draw, "stroke" ) == "dash" )
+ {
+ TQString style = m_styleStack.attributeNS( ooNS::draw, "stroke-dash" );
+ if ( style == "Ultrafine Dashed" || style == "Fine Dashed" ||
+ style == "Fine Dashed (var)" || style == "Dashed (var)" )
+ pen.setAttribute( "style", 2 );
+ else if ( style == "Fine Dotted" || style == "Ultrafine Dotted (var)" ||
+ style == "Line with Fine Dots" )
+ pen.setAttribute( "style", 3 );
+ else if ( style == "3 Dashes 3 Dots (var)" || style == "Ultrafine 2 Dots 3 Dashes" )
+ pen.setAttribute( "style", 4 );
+ else if ( style == "2 Dots 1 Dash" )
+ pen.setAttribute( "style", 5 );
+ }
+
+ if ( m_styleStack.hasAttributeNS( ooNS::svg, "stroke-width" ) )
+ pen.setAttribute( "width", (int) KoUnit::parseValue( m_styleStack.attributeNS( ooNS::svg, "stroke-width" ) ) );
+ if ( m_styleStack.hasAttributeNS( ooNS::svg, "stroke-color" ) )
+ pen.setAttribute( "color", m_styleStack.attributeNS( ooNS::svg, "stroke-color" ) );
+ e.appendChild( pen );
+ }
+}
+
+void OoImpressImport::appendBrush( TQDomDocument& doc, TQDomElement& e )
+{
+ if ( m_styleStack.hasAttributeNS( ooNS::draw, "fill" ) )
+ {
+ const TQString fill = m_styleStack.attributeNS( ooNS::draw, "fill" );
+ //kdDebug(30518)<<"void OoImpressImport::appendBrush( TQDomDocument& doc, TQDomElement& e ) :"<<fill<<endl;
+ if ( fill == "solid" )
+ {
+ TQDomElement brush = doc.createElement( "BRUSH" );
+ if ( m_styleStack.hasAttributeNS( ooNS::draw, "transparency" ) )
+ {
+ TQString transparency = m_styleStack.attributeNS( ooNS::draw, "transparency" );
+ transparency = transparency.remove( '%' );
+ int value = transparency.toInt();
+ if ( value >= 94 && value <= 99 )
+ {
+ brush.setAttribute( "style", 2 );
+ }
+ else if ( value>=64 && value <= 93 )
+ {
+ brush.setAttribute( "style", 3 );
+ }
+ else if ( value>=51 && value <= 63 )
+ {
+ brush.setAttribute( "style", 4 );
+ }
+ else if ( value>=38 && value <= 50 )
+ {
+ brush.setAttribute( "style", 5 );
+ }
+ else if ( value>=13 && value <= 37 )
+ {
+ brush.setAttribute( "style", 6 );
+ }
+ else if ( value>=7 && value <= 12 )
+ {
+ brush.setAttribute( "style", 7 );
+ }
+ else if ( value>=1 && value <= 6 )
+ {
+ brush.setAttribute( "style", 8 );
+ }
+ }
+ else
+ brush.setAttribute( "style", 1 );
+ if ( m_styleStack.hasAttributeNS( ooNS::draw, "fill-color" ) )
+ brush.setAttribute( "color", m_styleStack.attributeNS( ooNS::draw, "fill-color" ) );
+ e.appendChild( brush );
+ }
+ else if ( fill == "hatch" )
+ {
+ TQDomElement brush = doc.createElement( "BRUSH" );
+ TQString style = m_styleStack.attributeNS( ooNS::draw, "fill-hatch-name" );
+ TQDomElement* draw = m_draws[style];
+ if ( draw )
+ {
+ if( draw->hasAttributeNS( ooNS::draw, "color" ) )
+ brush.setAttribute( "color", draw->attributeNS( ooNS::draw, "color", TQString() ) );
+ int angle = 0;
+ if( draw->hasAttributeNS( ooNS::draw, "rotation" ))
+ {
+ angle = (draw->attributeNS( ooNS::draw, "rotation", TQString() ).toInt())/10;
+ kdDebug(30518)<<"angle :"<<angle<<endl;
+ }
+ if( draw->hasAttributeNS( ooNS::draw, "style" ))
+ {
+ TQString styleHash = draw->attributeNS( ooNS::draw, "style", TQString() );
+ if( styleHash == "single")
+ {
+ switch( angle )
+ {
+ case 0:
+ case 180:
+ brush.setAttribute( "style", 9 );
+ break;
+ case 45:
+ case 225:
+ brush.setAttribute( "style", 12 );
+ break;
+ case 90:
+ case 270:
+ brush.setAttribute( "style", 10 );
+ break;
+ case 135:
+ case 315:
+ brush.setAttribute( "style", 13 );
+ break;
+ default:
+ //todo fixme when we will have a kopaint
+ kdDebug(30518)<<" draw:rotation 'angle' : "<<angle<<endl;
+ break;
+ }
+ }
+ else if( styleHash == "double")
+ {
+ switch( angle )
+ {
+ case 0:
+ case 180:
+ case 90:
+ case 270:
+ brush.setAttribute("style", 11 );
+ break;
+ case 45:
+ case 135:
+ case 225:
+ case 315:
+ brush.setAttribute("style",14 );
+ break;
+ default:
+ //todo fixme when we will have a kopaint
+ kdDebug(30518)<<" draw:rotation 'angle' : "<<angle<<endl;
+ break;
+ }
+
+ }
+ else if( styleHash == "triple")
+ {
+ kdDebug(30518)<<" it is not implemented :( \n";
+ }
+
+ }
+ }
+ e.appendChild( brush );
+ }
+ else if ( fill == "gradient" )
+ {
+ // We have to set a brush with brushstyle != no background fill
+ // otherwise the properties dialog for the object won't
+ // display the preview for the gradient.
+ TQDomElement brush = doc.createElement( "BRUSH" );
+ brush.setAttribute( "style", 1 );
+ e.appendChild( brush );
+
+ TQDomElement gradient = doc.createElement( "GRADIENT" );
+ TQString style = m_styleStack.attributeNS( ooNS::draw, "fill-gradient-name" );
+
+ TQDomElement* draw = m_draws[style];
+ if ( draw )
+ {
+ gradient.setAttribute( "color1", draw->attributeNS( ooNS::draw, "start-color", TQString() ) );
+ gradient.setAttribute( "color2", draw->attributeNS( ooNS::draw, "end-color", TQString() ) );
+
+ TQString type = draw->attributeNS( ooNS::draw, "style", TQString() );
+ //kdDebug(30518)<<" type !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! :"<<type<<endl;
+ if ( type == "linear" )
+ {
+ int angle = draw->attributeNS( ooNS::draw, "angle", TQString() ).toInt() / 10;
+
+ // make sure the angle is between 0 and 359
+ angle = abs( angle );
+ angle -= ( (int) ( angle / 360 ) ) * 360;
+
+ // What we are trying to do here is to find out if the given
+ // angle belongs to a horizontal, vertical or diagonal gradient.
+ int lower, upper, nearAngle = 0;
+ for ( lower = 0, upper = 45; upper < 360; lower += 45, upper += 45 )
+ {
+ if ( upper >= angle )
+ {
+ int distanceToUpper = abs( angle - upper );
+ int distanceToLower = abs( angle - lower );
+ nearAngle = distanceToUpper > distanceToLower ? lower : upper;
+ break;
+ }
+ }
+ kdDebug(30518)<<"nearAngle :"<<nearAngle<<endl;
+ // nearAngle should now be one of: 0, 45, 90, 135, 180...
+ if ( nearAngle == 0 || nearAngle == 180 )
+ gradient.setAttribute( "type", 1 ); // horizontal
+ else if ( nearAngle == 90 || nearAngle == 270 )
+ gradient.setAttribute( "type", 2 ); // vertical
+ else if ( nearAngle == 45 || nearAngle == 225 )
+ gradient.setAttribute( "type", 3 ); // diagonal 1
+ else if ( nearAngle == 135 || nearAngle == 315 )
+ gradient.setAttribute( "type", 4 ); // diagonal 2
+ }
+ else if ( type == "radial" || type == "ellipsoid" )
+ gradient.setAttribute( "type", 5 ); // circle
+ else if ( type == "square" || type == "rectangular" )
+ gradient.setAttribute( "type", 6 ); // rectangle
+ else if ( type == "axial" )
+ gradient.setAttribute( "type", 7 ); // pipecross
+
+ // Hard to map between x- and y-center settings of ooimpress
+ // and (un-)balanced settings of kpresenter. Let's try it.
+ int x, y;
+ if ( draw->hasAttributeNS( ooNS::draw, "cx" ) )
+ x = draw->attributeNS( ooNS::draw, "cx", TQString() ).remove( '%' ).toInt();
+ else
+ x = 50;
+
+ if ( draw->hasAttributeNS( ooNS::draw, "cy" ) )
+ y = draw->attributeNS( ooNS::draw, "cy", TQString() ).remove( '%' ).toInt();
+ else
+ y = 50;
+
+ if ( x == 50 && y == 50 )
+ {
+ gradient.setAttribute( "unbalanced", 0 );
+ gradient.setAttribute( "xfactor", 100 );
+ gradient.setAttribute( "yfactor", 100 );
+ }
+ else
+ {
+ gradient.setAttribute( "unbalanced", 1 );
+ // map 0 - 100% to -200 - 200
+ gradient.setAttribute( "xfactor", 4 * x - 200 );
+ gradient.setAttribute( "yfactor", 4 * y - 200 );
+ }
+ }
+ e.appendChild( gradient );
+
+ TQDomElement fillType = doc.createElement( "FILLTYPE" );
+ fillType.setAttribute( "value", 1 );
+ e.appendChild( fillType );
+ }
+ }
+}
+
+void OoImpressImport::appendPie( TQDomDocument& doc, TQDomElement& e, const TQDomElement& object )
+{
+ TQDomElement angle = doc.createElement( "PIEANGLE" );
+ int start = (int) ( object.attributeNS( ooNS::draw, "start-angle", TQString() ).toDouble() );
+ angle.setAttribute( "value", start * 16 );
+ e.appendChild( angle );
+
+ TQDomElement length = doc.createElement( "PIELENGTH" );
+ int end = (int) ( object.attributeNS( ooNS::draw, "end-angle", TQString() ).toDouble() );
+ if ( end < start )
+ length.setAttribute( "value", ( 360 - start + end ) * 16 );
+ else
+ length.setAttribute( "value", ( end - start ) * 16 );
+ e.appendChild( length );
+}
+
+void OoImpressImport::appendImage( TQDomDocument& doc, TQDomElement& e, TQDomElement& p,
+ const TQDomElement& object )
+{
+ TQString fileName = storeImage( object );
+
+ // create a key for the picture
+ TQTime time = TQTime::currentTime();
+ TQDate date = TQDate::currentDate();
+
+ TQDomElement image = doc.createElement( "KEY" );
+ image.setAttribute( "msec", time.msec() );
+ image.setAttribute( "second", time.second() );
+ image.setAttribute( "minute", time.minute() );
+ image.setAttribute( "hour", time.hour() );
+ image.setAttribute( "day", date.day() );
+ image.setAttribute( "month", date.month() );
+ image.setAttribute( "year", date.year() );
+ image.setAttribute( "filename", fileName );
+ e.appendChild( image );
+
+ TQDomElement settings = doc.createElement( "PICTURESETTINGS" );
+ if ( m_styleStack.hasAttributeNS( ooNS::draw, "color-mode" ) && ( m_styleStack.attributeNS( ooNS::draw, "color-mode" )=="greyscale" ) )
+ settings.setAttribute( "grayscal", 1 );
+ else
+ settings.setAttribute( "grayscal", 0 );
+
+ if ( m_styleStack.hasAttributeNS( ooNS::draw, "luminance" ) )
+ {
+ TQString str( m_styleStack.attributeNS( ooNS::draw, "luminance" ) );
+ str = str.remove( '%' );
+ settings.setAttribute( "bright", str );
+ }
+ else
+ settings.setAttribute( "bright", 0 );
+
+ settings.setAttribute( "mirrorType", 0 );
+ settings.setAttribute( "swapRGB", 0 );
+ settings.setAttribute( "depth", 0 );
+ e.appendChild( settings );
+
+ TQDomElement effects = doc.createElement( "EFFECTS" );
+ bool hasEffect = false;
+ if ( m_styleStack.hasAttributeNS( ooNS::draw, "contrast" ) )
+ {
+ TQString str( m_styleStack.attributeNS( ooNS::draw, "contrast" ) );
+ str = str.remove( '%' );
+ int val = str.toInt();
+ val = ( int )( 255.0 *val/100.0 );
+ effects.setAttribute( "type", "5" );
+ effects.setAttribute( "param1", TQString::number( val ) );
+ hasEffect = true;
+ }
+ if ( hasEffect )
+ e.appendChild( effects );
+
+ TQDomElement key = image.cloneNode().toElement();
+ key.setAttribute( "name", "pictures/" + fileName );
+ p.appendChild( key );
+}
+
+void OoImpressImport::appendBackgroundImage( TQDomDocument& doc, TQDomElement& e,
+ TQDomElement& p, const TQDomElement& object )
+{
+ TQString fileName = storeImage( object );
+
+ // create a key for the picture
+ TQTime time = TQTime::currentTime();
+ TQDate date = TQDate::currentDate();
+
+ TQDomElement image = doc.createElement( "BACKPICTUREKEY" );
+ image.setAttribute( "msec", time.msec() );
+ image.setAttribute( "second", time.second() );
+ image.setAttribute( "minute", time.minute() );
+ image.setAttribute( "hour", time.hour() );
+ image.setAttribute( "day", date.day() );
+ image.setAttribute( "month", date.month() );
+ image.setAttribute( "year", date.year() );
+ image.setAttribute( "filename", fileName );
+ e.appendChild( image );
+
+ TQDomElement key = image.cloneNode().toElement();
+ key.setTagName( "KEY" );
+ key.setAttribute( "name", "pictures/" + fileName );
+ p.appendChild( key );
+}
+
+void OoImpressImport::appendBackgroundGradient( TQDomDocument& doc, TQDomElement& e,
+ const TQDomElement& object )
+{
+ TQDomElement backColor1 = doc.createElement( "BACKCOLOR1" );
+ backColor1.setAttribute( "color", object.attributeNS( ooNS::draw, "start-color", TQString() ) );
+ e.appendChild( backColor1 );
+
+ TQDomElement backColor2 = doc.createElement( "BACKCOLOR2" );
+ backColor2.setAttribute( "color", object.attributeNS( ooNS::draw, "end-color", TQString() ) );
+ e.appendChild( backColor2 );
+
+ TQDomElement backType = doc.createElement( "BACKTYPE" );
+ backType.setAttribute( "value", 0 ); // color/gradient
+ e.appendChild( backType );
+
+ TQDomElement bcType = doc.createElement( "BCTYPE" );
+ TQString type = object.attributeNS( ooNS::draw, "style", TQString() );
+ if ( type == "linear" )
+ {
+ int angle = object.attributeNS( ooNS::draw, "angle", TQString() ).toInt() / 10;
+
+ // make sure the angle is between 0 and 359
+ angle = abs( angle );
+ angle -= ( (int) ( angle / 360 ) ) * 360;
+
+ // What we are trying to do here is to find out if the given
+ // angle belongs to a horizontal, vertical or diagonal gradient.
+ int lower, upper, nearAngle = 0;
+ for ( lower = 0, upper = 45; upper < 360; lower += 45, upper += 45 )
+ {
+ if ( upper >= angle )
+ {
+ int distanceToUpper = abs( angle - upper );
+ int distanceToLower = abs( angle - lower );
+ nearAngle = distanceToUpper > distanceToLower ? lower : upper;
+ break;
+ }
+ }
+
+ // nearAngle should now be one of: 0, 45, 90, 135, 180...
+ if ( nearAngle == 0 || nearAngle == 180 )
+ bcType.setAttribute( "value", 1 ); // horizontal
+ else if ( nearAngle == 90 || nearAngle == 270 )
+ bcType.setAttribute( "value", 2 ); // vertical
+ else if ( nearAngle == 45 || nearAngle == 225 )
+ bcType.setAttribute( "value", 3 ); // diagonal 1
+ else if ( nearAngle == 135 || nearAngle == 315 )
+ bcType.setAttribute( "value", 4 ); // diagonal 2
+ }
+ else if ( type == "radial" || type == "ellipsoid" )
+ bcType.setAttribute( "value", 5 ); // circle
+ else if ( type == "square" || type == "rectangular" )
+ bcType.setAttribute( "value", 6 ); // rectangle
+ else if ( type == "axial" )
+ bcType.setAttribute( "value", 7 ); // pipecross
+
+ e.appendChild( bcType );
+
+ TQDomElement bGradient = doc.createElement( "BGRADIENT" );
+
+ // Hard to map between x- and y-center settings of ooimpress
+ // and (un-)balanced settings of kpresenter. Let's try it.
+ int x, y;
+ if ( object.hasAttributeNS( ooNS::draw, "cx" ) )
+ x = object.attributeNS( ooNS::draw, "cx", TQString() ).remove( '%' ).toInt();
+ else
+ x = 50;
+
+ if ( object.hasAttributeNS( ooNS::draw, "cy" ) )
+ y = object.attributeNS( ooNS::draw, "cy", TQString() ).remove( '%' ).toInt();
+ else
+ y = 50;
+
+ if ( x == 50 && y == 50 )
+ {
+ bGradient.setAttribute( "unbalanced", 0 );
+ bGradient.setAttribute( "xfactor", 100 );
+ bGradient.setAttribute( "yfactor", 100 );
+ }
+ else
+ {
+ bGradient.setAttribute( "unbalanced", 1 );
+ // map 0 - 100% to -200 - 200
+ bGradient.setAttribute( "xfactor", 4 * x - 200 );
+ bGradient.setAttribute( "yfactor", 4 * y - 200 );
+ }
+
+ e.appendChild( bGradient );
+}
+
+void OoImpressImport::appendRounding( TQDomDocument& doc, TQDomElement& e, const TQDomElement& object )
+{
+ if ( object.hasAttributeNS( ooNS::draw, "corner-radius" ) )
+ {
+ // kpresenter uses percent, ooimpress uses cm ... hmm?
+ TQDomElement rounding = doc.createElement( "RNDS" );
+ int corner = static_cast<int>(KoUnit::parseValue(object.attributeNS( ooNS::draw, "corner-radius", TQString())));
+ rounding.setAttribute( "x", corner );
+ rounding.setAttribute( "y", corner );
+ e.appendChild( rounding );
+ }
+}
+
+void OoImpressImport::appendShadow( TQDomDocument& doc, TQDomElement& e )
+{
+ // Note that ooimpress makes a difference between shadowed text and
+ // a shadowed object while kpresenter only knows the attribute 'shadow'.
+ // This means that a shadowed textobject in kpresenter will always show
+ // a shadowed text but no shadow for the object itself.
+
+ // make sure this is a textobject or textspan
+ if ( !e.hasAttribute( "type" ) ||
+ ( e.hasAttribute( "type" ) && e.attribute( "type" ) == "4" ) )
+ {
+ if ( m_styleStack.hasAttributeNS( ooNS::fo, "text-shadow" ) &&
+ m_styleStack.attributeNS( ooNS::fo, "text-shadow" ) != "none" )
+ {
+ // use the shadow attribute to indicate a text-shadow
+ TQDomElement shadow = doc.createElement( "SHADOW" );
+ TQString distance = m_styleStack.attributeNS( ooNS::fo, "text-shadow" );
+ distance.truncate( distance.find( ' ' ) );
+ shadow.setAttribute( "distance", KoUnit::parseValue( distance ) );
+ shadow.setAttribute( "direction", 5 );
+ shadow.setAttribute( "color", "#a0a0a0" );
+ e.appendChild( shadow );
+ }
+ }
+ else if ( m_styleStack.hasAttributeNS( ooNS::draw, "shadow" ) &&
+ m_styleStack.attributeNS( ooNS::draw, "shadow" ) == "visible" )
+ {
+ // use the shadow attribute to indicate an object-shadow
+ TQDomElement shadow = doc.createElement( "SHADOW" );
+ double x = KoUnit::parseValue( m_styleStack.attributeNS( ooNS::draw, "shadow-offset-x" ) );
+ double y = KoUnit::parseValue( m_styleStack.attributeNS( ooNS::draw, "shadow-offset-y" ) );
+
+ if ( x < 0 && y < 0 )
+ {
+ shadow.setAttribute( "direction", 1 );
+ shadow.setAttribute( "distance", (int) fabs ( x ) );
+ }
+ else if ( x == 0 && y < 0 )
+ {
+ shadow.setAttribute( "direction", 2 );
+ shadow.setAttribute( "distance", (int) fabs ( y ) );
+ }
+ else if ( x > 0 && y < 0 )
+ {
+ shadow.setAttribute( "direction", 3 );
+ shadow.setAttribute( "distance", (int) fabs ( x ) );
+ }
+ else if ( x > 0 && y == 0 )
+ {
+ shadow.setAttribute( "direction", 4 );
+ shadow.setAttribute( "distance", (int) fabs ( x ) );
+ }
+ else if ( x > 0 && y > 0 )
+ {
+ shadow.setAttribute( "direction", 5 );
+ shadow.setAttribute( "distance", (int) fabs ( x ) );
+ }
+ else if ( x == 0 && y > 0 )
+ {
+ shadow.setAttribute( "direction", 6 );
+ shadow.setAttribute( "distance", (int) fabs ( y ) );
+ }
+ else if ( x < 0 && y > 0 )
+ {
+ shadow.setAttribute( "direction", 7 );
+ shadow.setAttribute( "distance", (int) fabs ( x ) );
+ }
+ else if ( x < 0 && y == 0 )
+ {
+ shadow.setAttribute( "direction", 8 );
+ shadow.setAttribute( "distance", (int) fabs ( x ) );
+ }
+
+ if ( m_styleStack.hasAttributeNS( ooNS::draw, "shadow-color" ) )
+ shadow.setAttribute( "color", m_styleStack.attributeNS( ooNS::draw, "shadow-color" ) );
+
+ e.appendChild( shadow );
+ }
+ if ( m_styleStack.hasAttributeNS( ooNS::draw, "size-protect" ) || m_styleStack.hasAttributeNS( ooNS::draw, "move-protect" ) )
+ {
+ bool b = ( m_styleStack.attributeNS( ooNS::draw, "size-protect" ) == "true" ) || ( m_styleStack.attributeNS( ooNS::draw, "move-protect" ) == "true" );
+ if ( b )
+ {
+ TQDomElement protect = doc.createElement( "PROTECT" );
+ protect.setAttribute("state" , b);
+ e.appendChild(protect);
+ }
+ }
+}
+
+void OoImpressImport::appendLineEnds( TQDomDocument& doc, TQDomElement& e, bool orderEndStartLine)
+{
+ const char* attr = orderEndStartLine ? "marker-start" : "marker-end";
+ if ( m_styleStack.hasAttributeNS( ooNS::draw, attr ) )
+ {
+ TQDomElement lineBegin = doc.createElement( "LINEBEGIN" );
+ TQString type = m_styleStack.attributeNS( ooNS::draw, attr );
+ if ( type == "Arrow" || type == "Small Arrow" || type == "Rounded short Arrow" ||
+ type == "Symmetric Arrow" || type == "Rounded large Arrow" || type == "Arrow concave" )
+ lineBegin.setAttribute( "value", 1 );
+ else if ( type == "Square" )
+ lineBegin.setAttribute( "value", 2 );
+ else if ( type == "Circle" || type == "Square 45" )
+ lineBegin.setAttribute( "value", 3 );
+ else if ( type == "Line Arrow" )
+ lineBegin.setAttribute( "value", 4 );
+ else if ( type == "Dimension Lines" )
+ lineBegin.setAttribute( "value", 5 );
+ else if ( type == "Double Arrow" )
+ lineBegin.setAttribute( "value", 6 );
+ e.appendChild( lineBegin );
+ }
+ attr = orderEndStartLine ? "marker-end" : "marker-start";
+ if ( m_styleStack.hasAttributeNS( ooNS::draw, attr ) )
+ {
+ TQDomElement lineEnd = doc.createElement( "LINEEND" );
+ TQString type = m_styleStack.attributeNS( ooNS::draw, attr );
+ if ( type == "Arrow" || type == "Small Arrow" || type == "Rounded short Arrow" ||
+ type == "Symmetric Arrow" || type == "Rounded large Arrow" || type == "Arrow concave" )
+ lineEnd.setAttribute( "value", 1 );
+ else if ( type == "Square" )
+ lineEnd.setAttribute( "value", 2 );
+ else if ( type == "Circle" || type == "Square 45" )
+ lineEnd.setAttribute( "value", 3 );
+ else if ( type == "Line Arrow" )
+ lineEnd.setAttribute( "value", 4 );
+ else if ( type == "Dimension Lines" )
+ lineEnd.setAttribute( "value", 5 );
+ else if ( type == "Double Arrow" )
+ lineEnd.setAttribute( "value", 6 );
+ e.appendChild( lineEnd );
+ }
+}
+
+void OoImpressImport::appendTextObjectMargin( TQDomDocument& /*doc*/, TQDomElement& e )
+{
+ if ( m_styleStack.hasAttributeNS( ooNS::fo, "padding" ) )
+ {
+ double tmpValue = KoUnit::parseValue(m_styleStack.attributeNS( ooNS::fo, "padding" ) );
+ e.setAttribute( "btoppt", tmpValue );
+ e.setAttribute( "bbottompt", tmpValue );
+ e.setAttribute( "bleftpt", tmpValue );
+ e.setAttribute( "brightpt", tmpValue );
+ }
+ else
+ {
+ if( m_styleStack.hasAttributeNS( ooNS::fo, "padding-top" ) )
+ e.setAttribute( "btoppt", KoUnit::parseValue( m_styleStack.attributeNS( ooNS::fo, "padding-top" ) ) );
+ if( m_styleStack.hasAttributeNS( ooNS::fo, "padding-bottom" ) )
+ e.setAttribute( "bbottompt", KoUnit::parseValue( m_styleStack.attributeNS( ooNS::fo, "padding-bottom" ) ) );
+ if( m_styleStack.hasAttributeNS( ooNS::fo, "padding-left" ) )
+ e.setAttribute( "bleftpt", KoUnit::parseValue( m_styleStack.attributeNS( ooNS::fo, "padding-left" ) ) );
+ if( m_styleStack.hasAttributeNS( ooNS::fo, "padding-right" ) )
+ e.setAttribute( "brightpt", KoUnit::parseValue( m_styleStack.attributeNS( ooNS::fo, "padding-right" ) ) );
+ }
+}
+
+TQDomElement OoImpressImport::parseTextBox( TQDomDocument& doc, const TQDomElement& textBox )
+{
+ TQDomElement textObjectElement = doc.createElement( "TEXTOBJ" );
+ appendTextObjectMargin( doc, textObjectElement );
+
+ // vertical alignment
+ if ( m_styleStack.hasAttributeNS( ooNS::draw, "textarea-vertical-align" ) )
+ {
+ TQString alignment = m_styleStack.attributeNS( ooNS::draw, "textarea-vertical-align" );
+ if ( alignment == "top" )
+ textObjectElement.setAttribute( "verticalAlign", "top" );
+ else if ( alignment == "middle" )
+ textObjectElement.setAttribute( "verticalAlign", "center" );
+ else if ( alignment == "bottom" )
+ textObjectElement.setAttribute( "verticalAlign", "bottom" );
+
+ textObjectElement.setAttribute("verticalValue", 0.0);
+ }
+
+ parseParagraphs( doc, textObjectElement, textBox );
+
+ return textObjectElement;
+}
+
+void OoImpressImport::parseParagraphs( TQDomDocument& doc, TQDomElement& textObjectElement, const TQDomElement& parent )
+{
+ TQDomElement t;
+ forEachElement( t, parent )
+ {
+ m_styleStack.save();
+ const TQString localName = t.localName();
+ const TQString ns = t.namespaceURI();
+ const bool isTextNS = ns == ooNS::text;
+
+ TQDomElement e;
+ if ( isTextNS && localName == "p" ) // text paragraph
+ e = parseParagraph( doc, t );
+ else if ( isTextNS && localName == "h" ) // heading - can this happen in ooimpress?
+ {
+ e = parseParagraph( doc, t );
+ }
+ else if ( isTextNS && ( localName == "unordered-list" || localName == "ordered-list" ) )
+ {
+ parseList( doc, textObjectElement, t );
+ m_styleStack.restore();
+ continue;
+ }
+ // TODO text:sequence-decls
+ else
+ {
+ kdDebug(30518) << "Unsupported texttype '" << localName << "'" << endl;
+ }
+
+ if ( !e.isNull() )
+ textObjectElement.appendChild( e );
+ m_styleStack.restore(); // remove the styles added by the paragraph or list
+ }
+}
+
+void OoImpressImport::applyListStyle( TQDomElement& paragraph )
+{
+ // Spec: see 3.3.5 p137
+ if ( m_listStyleStack.hasListStyle() && m_nextItemIsListItem ) {
+ //const TQDomElement listStyle = m_listStyleStack.currentListStyle();
+ //bool heading = paragraph.localName() == "h";
+ m_nextItemIsListItem = false;
+ /*int level = heading ? paragraph.attributeNS( ooNS::text, "level", TQString() ).toInt()
+ : m_listStyleStack.level();*/
+
+ TQDomElement counter = paragraph.ownerDocument().createElement( "COUNTER" );
+ counter.setAttribute( "numberingtype", 0 );
+ counter.setAttribute( "depth", 0 );
+
+ if ( m_insideOrderedList )
+ counter.setAttribute( "type", 1 );
+ else
+ counter.setAttribute( "type", 10 ); // a disc bullet
+ paragraph.appendChild( counter );
+ }
+}
+
+static TQDomElement findListLevelStyle( TQDomElement& fullListStyle, int level )
+{
+ TQDomElement listLevelItem;
+ forEachElement( listLevelItem, fullListStyle )
+ {
+ if ( listLevelItem.attributeNS( ooNS::text, "level", TQString() ).toInt() == level )
+ return listLevelItem;
+ }
+ return TQDomElement();
+}
+
+bool OoImpressImport::pushListLevelStyle( const TQString& listStyleName, int level )
+{
+ TQDomElement* fullListStyle = m_listStyles[listStyleName];
+ if ( !fullListStyle ) {
+ kdWarning(30518) << "List style " << listStyleName << " not found!" << endl;
+ return false;
+ }
+ else
+ return pushListLevelStyle( listStyleName, *fullListStyle, level );
+}
+
+bool OoImpressImport::pushListLevelStyle( const TQString& listStyleName, // for debug only
+ TQDomElement& fullListStyle, int level )
+{
+ // Find applicable list-level-style for level
+ int i = level;
+ TQDomElement listLevelStyle;
+ while ( i > 0 && listLevelStyle.isNull() ) {
+ listLevelStyle = findListLevelStyle( fullListStyle, i );
+ --i;
+ }
+ if ( listLevelStyle.isNull() ) {
+ kdWarning(30518) << "List level style for level " << level << " in list style " << listStyleName << " not found!" << endl;
+ return false;
+ }
+ kdDebug(30518) << "Pushing list-level-style from list-style " << listStyleName << " level " << level << endl;
+ m_listStyleStack.push( listLevelStyle );
+ return true;
+}
+
+void OoImpressImport::parseList( TQDomDocument& doc, TQDomElement& textObjectElement, const TQDomElement& list )
+{
+ //kdDebug(30518) << k_funcinfo << "parseList"<< endl;
+
+ m_insideOrderedList = ( list.localName() == "ordered-list" );
+ TQString oldListStyleName = m_currentListStyleName;
+ if ( list.hasAttributeNS( ooNS::text, "style-name" ) )
+ m_currentListStyleName = list.attributeNS( ooNS::text, "style-name", TQString() );
+ bool listOK = !m_currentListStyleName.isEmpty();
+ const int level = m_listStyleStack.level() + 1;
+ //kdDebug(30518) << k_funcinfo << " listOK=" << listOK << " level=" << level << endl;
+ if ( listOK )
+ listOK = pushListLevelStyle( m_currentListStyleName, level );
+
+ // Iterate over list items
+ TQDomElement listItem;
+ forEachElement( listItem, list )
+ {
+ // It's either list-header (normal text on top of list) or list-item
+ m_nextItemIsListItem = ( listItem.localName() != "list-header" );
+ m_restartNumbering = -1;
+ if ( listItem.hasAttributeNS( ooNS::text, "start-value" ) )
+ m_restartNumbering = listItem.attributeNS( ooNS::text, "start-value", TQString() ).toInt();
+ // ### Oasis: can be p h or list only.
+ parseParagraphs( doc, textObjectElement, listItem );
+ m_restartNumbering = -1;
+ }
+ if ( listOK )
+ m_listStyleStack.pop();
+ m_currentListStyleName = oldListStyleName;
+}
+
+TQDomElement OoImpressImport::parseParagraph( TQDomDocument& doc, const TQDomElement& paragraph )
+{
+ TQDomElement p = doc.createElement( "P" );
+
+ // parse the paragraph-properties
+ fillStyleStack( paragraph );
+
+ // Style name
+ TQString styleName = m_styleStack.userStyleName("paragraph");
+ if ( !styleName.isEmpty() )
+ {
+ TQDomElement nameElem = doc.createElement("NAME");
+ nameElem.setAttribute("value", styleName);
+ p.appendChild(nameElem);
+ }
+
+ // Paragraph alignment
+ if ( m_styleStack.hasAttributeNS( ooNS::fo, "text-align" ) )
+ {
+ TQString align = m_styleStack.attributeNS( ooNS::fo, "text-align" );
+ if ( align == "center" )
+ p.setAttribute( "align", 4 );
+ else if ( align == "justify" )
+ p.setAttribute( "align", 8 );
+ else if ( align == "start" )
+ p.setAttribute( "align", 0 );
+ else if ( align == "end" )
+ p.setAttribute( "align", 2 );
+ }
+ else
+ p.setAttribute( "align", 0 ); // use left aligned as default
+
+
+ // Offset before and after paragraph
+ OoUtils::importTopBottomMargin( p, m_styleStack );
+
+ // Indentation (margins)
+ OoUtils::importIndents( p, m_styleStack );
+
+ // Line spacing
+ OoUtils::importLineSpacing( p, m_styleStack );
+
+ // Tabulators
+ OoUtils::importTabulators( p, m_styleStack );
+
+ // Borders
+ OoUtils::importBorders( p, m_styleStack );
+
+ applyListStyle( p );
+
+ uint pos = 0;
+
+ m_styleStack.save();
+ // parse every childnode of the paragraph
+ parseSpanOrSimilar( doc, paragraph, p, pos);
+ m_styleStack.restore(); // remove possible garbage (should not be needed)
+
+ return p;
+}
+
+void OoImpressImport::parseSpanOrSimilar( TQDomDocument& doc, const TQDomElement& parent,
+ TQDomElement& outputParagraph, uint& pos)
+{
+ // Parse every child node of the parent
+ // Can't use forEachElement here since we also care about text nodes
+ for( TQDomNode node = parent.firstChild(); !node.isNull(); node = node.nextSibling() )
+ {
+ TQDomElement ts = node.toElement();
+ TQString textData;
+ const TQString localName( ts.localName() );
+ const TQString ns = ts.namespaceURI();
+ const bool isTextNS = ns == ooNS::text;
+ TQDomText t = node.toText();
+
+ // Try to keep the order of the tag names by probability of happening
+ if ( isTextNS && localName == "span" ) // text:span
+ {
+ m_styleStack.save();
+ fillStyleStack( ts );
+ parseSpanOrSimilar( doc, ts, outputParagraph, pos);
+ m_styleStack.restore();
+ }
+ else if ( isTextNS && localName == "s" ) // text:s
+ {
+ textData = OoUtils::expandWhitespace(ts);
+ }
+ else if ( isTextNS && localName == "tab-stop" ) // text:tab-stop
+ {
+ // KPresenter currently uses \t.
+ // Known bug: a line with only \t\t\t\t isn't loaded - XML (TQDom) strips out whitespace.
+ // One more good reason to switch to <text:tab-stop> instead...
+ textData = '\t';
+ }
+ else if ( isTextNS && localName == "line-break" )
+ {
+ textData = '\n';
+ }
+ else if ( localName == "image" && ns == ooNS::draw )
+ {
+ textData = '#'; // anchor placeholder
+ // TODO
+ }
+ else if ( isTextNS && localName == "a" )
+ {
+ m_styleStack.save();
+ TQString href( ts.attributeNS( ooNS::xlink, "href", TQString()) );
+ if ( href.startsWith("#") )
+ {
+ // We have a reference to a bookmark (### TODO)
+ // As we do not support it now, treat it as a <text:span> without formatting
+ parseSpanOrSimilar( doc, ts, outputParagraph, pos);
+ }
+ else
+ {
+#if 0 // TODO
+ // The problem is that KPresenter's hyperlink text is not inside the normal text, but for OOWriter it is nearly a <text:span>
+ // So we have to fake.
+ TQDomElement fakeParagraph, fakeFormats;
+ uint fakePos=0;
+ TQString text;
+ parseSpanOrSimilar( doc, ts, fakeParagraph, fakeFormats, text, fakePos);
+ textData = '#'; // hyperlink placeholder
+ TQDomElement linkElement (doc.createElement("LINK"));
+ linkElement.setAttribute("hrefName",ts.attributeNS( ooNS::xlink, "href", TQString()));
+ linkElement.setAttribute("linkName",text);
+ appendVariable(doc, ts, pos, "STRING", 9, text, linkElement);
+#endif
+ }
+ m_styleStack.restore();
+ }
+ else if ( isTextNS &&
+ (localName == "date" // fields
+ || localName == "time"
+ || localName == "page-number"
+ || localName == "file-name"
+ || localName == "author-name"
+ || localName == "author-initials" ) )
+ {
+ textData = "#"; // field placeholder
+ appendField(doc, outputParagraph, ts, pos);
+ }
+ else if ( t.isNull() ) // no textnode, we must ignore
+ {
+ kdWarning(30518) << "Ignoring tag " << ts.tagName() << endl;
+ continue;
+ }
+ else
+ textData = t.data();
+
+ pos += textData.length();
+
+ TQDomElement text = saveHelper(textData, doc);
+
+ kdDebug(30518) << k_funcinfo << "Para text is: " << textData << endl;
+
+ if (m_styleStack.hasAttributeNS( ooNS::fo, "language" )) {
+ TQString lang = m_styleStack.attributeNS( ooNS::fo, "language" );
+ if (lang=="en")
+ text.setAttribute("language", "en_US");
+ else
+ text.setAttribute("language", lang);
+ }
+
+ // parse the text-properties
+ if ( m_styleStack.hasAttributeNS( ooNS::fo, "color" ) ) {
+ kdDebug(30518) << "color=" << m_styleStack.attributeNS( ooNS::fo, "color" ) << endl;
+ text.setAttribute( "color", m_styleStack.attributeNS( ooNS::fo, "color" ) );
+ }
+ if ( m_styleStack.hasAttributeNS( ooNS::fo, "font-family" ) // 3.10.9
+ || m_styleStack.hasAttributeNS( ooNS::style, "font-name") )//3.10.8
+ {
+ // 'Thorndale/Albany' are not known outside OpenOffice so we substitute them
+ // with 'Times New Roman/Arial' that look nearly the same.
+ if ( m_styleStack.attributeNS( ooNS::fo, "font-family" ) == "Thorndale" )
+ text.setAttribute( "family", "Times New Roman" );
+ else if ( m_styleStack.attributeNS( ooNS::fo, "font-family" ) == "Albany" )
+ text.setAttribute( "family", "Arial" );
+ else
+ text.setAttribute( "family", m_styleStack.attributeNS( ooNS::fo, "font-family" ).remove( "'" ) );
+ }
+ if ( m_styleStack.hasAttributeNS( ooNS::fo, "font-size" ) )
+ {
+ double pointSize = m_styleStack.fontSize();
+ text.setAttribute( "pointSize", tqRound(pointSize) ); // KPresenter uses toInt()!
+ }
+ if ( m_styleStack.hasAttributeNS( ooNS::fo, "font-weight" ) ) // 3.10.24
+ if ( m_styleStack.attributeNS( ooNS::fo, "font-weight" ) == "bold" )
+ text.setAttribute( "bold", 1 );
+ if ( m_styleStack.hasAttributeNS( ooNS::fo, "font-style" ) )
+ if ( m_styleStack.attributeNS( ooNS::fo, "font-style" ) == "italic" )
+ text.setAttribute( "italic", 1 );
+
+ if ( m_styleStack.hasAttributeNS( ooNS::style, "text-position" ) ) // 3.10.17
+ {
+ TQString text_position = m_styleStack.attributeNS( ooNS::style, "text-position");
+ TQString value;
+ TQString relativetextsize;
+ OoUtils::importTextPosition( text_position, value, relativetextsize );
+ text.setAttribute( "VERTALIGN", value );
+ if ( !relativetextsize.isEmpty() )
+ text.setAttribute( "relativetextsize", relativetextsize );
+ }
+
+ bool wordByWord = (m_styleStack.hasAttributeNS( ooNS::fo, "score-spaces"))// 3.10.25
+ && (m_styleStack.attributeNS( ooNS::fo, "score-spaces") == "false");
+
+ // strikeout
+ if ( m_styleStack.hasAttributeNS( ooNS::style, "text-crossing-out")// 3.10.6
+ && m_styleStack.attributeNS( ooNS::style, "text-crossing-out") != "none")
+ {
+ TQString strikeOutType = m_styleStack.attributeNS( ooNS::style, "text-crossing-out" );
+ if ( strikeOutType =="double-line" )
+ {
+ text.setAttribute( "strikeOut", "double" );
+ text.setAttribute( "strikeoutstyleline", "solid" );
+ }
+ else if ( strikeOutType =="thick-line" )
+ {
+ text.setAttribute( "strikeOut", "single-bold" );
+ text.setAttribute( "strikeoutstyleline", "solid" );
+ }
+ else //if ( strikeOutType == "single-line" ) //fall back to the default strikeout
+ {
+ text.setAttribute( "strikeOut", "single" );
+ text.setAttribute( "strikeoutstyleline", "solid" );
+ }
+
+ if (wordByWord)
+ text.setAttribute("wordbyword", 1);
+ }
+
+ // underlining
+ if ( m_styleStack.hasAttributeNS( ooNS::style, "text-underline" ) ) // 3.10.22
+ {
+ TQString underline;
+ TQString styleline;
+ OoUtils::importUnderline( m_styleStack.attributeNS( ooNS::style, "text-underline" ),
+ underline, styleline );
+ TQString underLineColor = m_styleStack.attributeNS( ooNS::style, "text-underline-color" );// 3.10.23
+
+ text.setAttribute( "value", underline );
+ text.setAttribute( "styleline", styleline );
+
+ if ( !underLineColor.isEmpty() && underLineColor != "font-color" )
+ text.setAttribute("underlinecolor", underLineColor);
+ if ( wordByWord )
+ text.setAttribute("wordbyword", 1);
+ }
+#if 0 // strange ooimpress doesn't implement it
+ // Small caps, lowercase, uppercase
+ if ( m_styleStack.hasAttributeNS( ooNS::fo, "font-variant" ) // 3.10.1
+ || m_styleStack.hasAttributeNS( ooNS::fo, "text-transform" ) ) // 3.10.2
+ {
+ TQDomElement fontAttrib( doc.createElement( "FONTATTRIBUTE" ) );
+ bool smallCaps = m_styleStack.attributeNS( ooNS::fo, "font-variant" ) == "small-caps";
+ if ( smallCaps )
+ {
+ text.setAttribute( "fontattribute", "smallcaps" );
+ } else
+ {
+ // Both KWord/KPresenter and OO use "uppercase" and "lowercase".
+ // TODO in KWord: "capitalize".
+ text.setAttribute( "fontattribute", m_styleStack.attributeNS( ooNS::fo, "text-transform" ) );
+ }
+ }
+#endif
+ // background color (property of the paragraph in OOo, of the text in kword/kpresenter)
+ if (m_styleStack.hasAttributeNS( ooNS::fo, "background-color" ))
+ {
+ TQString bgColor = m_styleStack.attributeNS( ooNS::fo, "background-color");
+ if (bgColor != "transparent")
+ text.setAttribute("textbackcolor", bgColor);
+ }
+
+ appendShadow( doc, outputParagraph ); // this is necessary to take care of shadowed paragraphs
+ outputParagraph.appendChild( text );
+ } // for each text span
+}
+
+void OoImpressImport::createStyleMap( TQDomDocument &docstyles )
+{
+ TQDomElement styles = docstyles.documentElement();
+ if ( styles.isNull() )
+ return;
+
+ TQDomNode fixedStyles = KoDom::namedItemNS( styles, ooNS::office, "styles" );
+ if ( !fixedStyles.isNull() )
+ {
+ insertDraws( fixedStyles.toElement() );
+ insertStyles( fixedStyles.toElement() );
+ insertStylesPresentation( fixedStyles.toElement() );
+ }
+
+ TQDomNode automaticStyles = KoDom::namedItemNS( styles, ooNS::office, "automatic-styles" );
+ if ( !automaticStyles.isNull() )
+ {
+ insertStyles( automaticStyles.toElement() );
+ insertStylesPresentation( automaticStyles.toElement() );
+ }
+ TQDomNode masterStyles = KoDom::namedItemNS( styles, ooNS::office, "master-styles" );
+ if ( !masterStyles.isNull() )
+ insertStyles( masterStyles.toElement() );
+}
+
+void OoImpressImport::insertDraws( const TQDomElement& styles )
+{
+ TQDomElement e;
+ forEachElement( e, styles )
+ {
+ if ( !e.hasAttributeNS( ooNS::draw, "name" ) )
+ continue;
+
+ TQString name = e.attributeNS( ooNS::draw, "name", TQString() );
+ m_draws.insert( name, new TQDomElement( e ) );
+ }
+}
+
+void OoImpressImport::insertStyles( const TQDomElement& styles )
+{
+ TQDomElement e;
+ forEachElement( e, styles )
+ {
+ const TQString localName = e.localName();
+ const TQString ns = e.namespaceURI();
+ if ( !e.hasAttributeNS( ooNS::style, "name" ) )
+ continue;
+
+ const TQString name = e.attributeNS( ooNS::style, "name", TQString() );
+ if ( localName == "list-style" && ns == ooNS::text ) {
+ TQDomElement* ep = new TQDomElement( e );
+ m_listStyles.insert( name, ep );
+ kdDebug(30518) << "List style: '" << name << "' loaded " << endl;
+ }
+ else
+ {
+ m_styles.insert( name, new TQDomElement( e ) );
+ kdDebug(30518) << "Style: '" << name << "' loaded " << endl;
+ }
+ }
+}
+
+void OoImpressImport::insertStylesPresentation( const TQDomElement& styles )
+{
+ TQDomElement e;
+ forEachElement( e, styles )
+ {
+ if ( !e.hasAttributeNS( ooNS::style, "name" ) )
+ continue;
+
+ TQString name = e.attributeNS( ooNS::style, "name", TQString() );
+ m_stylesPresentation.insert( name, new TQDomElement( e ) );
+ //kdDebug(30518) << "Style: '" << name << "' loaded " << endl;
+ }
+}
+
+void OoImpressImport::fillStyleStack( const TQDomElement& object, bool sticky )
+{
+ // find all styles associated with an object and push them on the stack
+ if ( object.hasAttributeNS( ooNS::presentation, "style-name" ) )
+ {
+ kdDebug(30518)<<" presentation:style-name **************************** :"<<object.attributeNS( ooNS::presentation, "style-name", TQString() )<<endl;
+ if ( sticky )
+ addStyles( m_stylesPresentation[object.attributeNS( ooNS::presentation, "style-name", TQString() )] );
+ else
+ addStyles( m_styles[object.attributeNS( ooNS::presentation, "style-name", TQString() )] );
+ }
+ if ( object.hasAttributeNS( ooNS::draw, "style-name" ) )
+ addStyles( m_styles[object.attributeNS( ooNS::draw, "style-name", TQString() )] );
+
+ if ( object.hasAttributeNS( ooNS::draw, "text-style-name" ) )
+ addStyles( m_styles[object.attributeNS( ooNS::draw, "text-style-name", TQString() )] );
+
+ if ( object.hasAttributeNS( ooNS::text, "style-name" ) ) {
+ TQString styleName = object.attributeNS( ooNS::text, "style-name", TQString() );
+ //kdDebug(30518) << "adding style " << styleName << endl;
+ addStyles( m_styles[styleName] );
+ }
+}
+
+void OoImpressImport::addStyles( const TQDomElement* style )
+{
+ kdDebug(30518)<<" addStyle :" << style->attributeNS( ooNS::style, "name", TQString() ) <<endl;
+ // this function is necessary as parent styles can have parents themself
+ if ( style->hasAttributeNS( ooNS::style, "parent-style-name" ) )
+ {
+ //kdDebug(30518)<<"m_styles[style->attribute( style:parent-style-name )] :"<<m_styles[style->attributeNS( ooNS::style, "parent-style-name", TQString() )]<<endl;
+ addStyles( m_styles[style->attributeNS( ooNS::style, "parent-style-name", TQString() )] );
+ }
+ //kdDebug(30518)<<" void OoImpressImport::addStyles( const TQDomElement* style ) :"<<style<<endl;
+ m_styleStack.push( *style );
+}
+
+TQString OoImpressImport::storeImage( const TQDomElement& object )
+{
+ // store the picture
+ TQString url = object.attributeNS( ooNS::xlink, "href", TQString() ).remove( '#' );
+ KArchiveFile* file = (KArchiveFile*) m_zip->directory()->entry( url );
+
+ TQString extension = url.mid( url.find( '.' ) );
+ TQString fileName = TQString( "picture%1" ).arg( m_numPicture++ ) + extension;
+ KoStoreDevice* out = m_chain->storageFile( "pictures/" + fileName, KoStore::Write );
+
+ if ( file && out )
+ {
+ TQByteArray buffer = file->data();
+ out->writeBlock( buffer.data(), buffer.size() );
+ }
+
+ return fileName;
+}
+
+TQString OoImpressImport::storeSound(const TQDomElement & object, TQDomElement & p, TQDomDocument & doc)
+{
+ TQFileInfo fi(m_chain->inputFile()); // handle relative URLs
+ TQDir::setCurrent(fi.dirPath(true));
+ fi.setFile(object.attributeNS( ooNS::xlink, "href", TQString()));
+ TQString url = fi.absFilePath();
+
+ //kdDebug(30518) << "Sound URL: " << url << endl;
+
+ TQFile file(url);
+ if (!file.exists())
+ return TQString();
+
+ TQString extension = url.mid( url.find( '.' ) );
+ TQString fileName = TQString( "sound%1" ).arg( m_numSound++ ) + extension;
+ fileName = "sounds/" + fileName;
+ KoStoreDevice* out = m_chain->storageFile( fileName, KoStore::Write );
+
+ if (out)
+ {
+ if (!file.open(IO_ReadOnly))
+ return TQString();
+
+ TQByteArray data(8*1024);
+
+ uint total = 0;
+ for ( int block = 0; ( block = file.readBlock(data.data(), data.size()) ) > 0;
+ total += block )
+ out->writeBlock(data.data(), data.size());
+
+ Q_ASSERT(total == fi.size());
+
+ file.close();
+ }
+ else
+ return TQString();
+
+ TQDomElement key = doc.createElement("FILE");
+ key.setAttribute("name", fileName);
+ key.setAttribute("filename", url);
+ p.appendChild(key);
+
+ return url;
+}
+
+TQDomElement OoImpressImport::saveHelper(const TQString &tmpText, TQDomDocument &doc)
+{
+ TQDomElement element=doc.createElement("TEXT");
+
+ if(tmpText.stripWhiteSpace().isEmpty()) // ### careful, this also strips \t and \n ....
+ // working around a bug in TQDom
+ element.setAttribute("whitespace", tmpText.length());
+
+ element.appendChild(doc.createTextNode(tmpText));
+ return element;
+}
+
+void OoImpressImport::appendPoints(TQDomDocument& doc, TQDomElement& e, const TQDomElement& object)
+{
+ TQDomElement ptsElem = doc.createElement("POINTS");
+
+ TQStringList ptList = TQStringList::split(' ', object.attributeNS( ooNS::draw, "points", TQString()));
+
+ TQString pt_x, pt_y;
+ double tmp_x, tmp_y;
+ for (TQStringList::Iterator it = ptList.begin(); it != ptList.end(); ++it)
+ {
+ TQDomElement point = doc.createElement("Point");
+
+ tmp_x = (*it).section(',',0,0).toInt() / 100;
+ tmp_y = (*it).section(',',1,1).toInt() / 100;
+
+ pt_x.setNum(tmp_x);
+ pt_x+="mm";
+
+ pt_y.setNum(tmp_y);
+ pt_y+="mm";
+
+ point.setAttribute("point_x", KoUnit::parseValue(pt_x));
+ point.setAttribute("point_y", KoUnit::parseValue(pt_y));
+ ptsElem.appendChild(point);
+ }
+
+ e.appendChild(ptsElem);
+}
+
+void OoImpressImport::appendField(TQDomDocument& doc, TQDomElement& e, const TQDomElement& object, uint pos)
+{
+ const TQString tag = object.localName();
+ const TQString ns = object.namespaceURI();
+ const bool isTextNS = ns == ooNS::text;
+
+ TQDomElement custom = doc.createElement("CUSTOM");
+ custom.setAttribute("pos", pos);
+ TQDomElement variable = doc.createElement("VARIABLE");
+
+ if (isTextNS && tag == "date")
+ {
+ TQDateTime dt(TQDate::fromString(object.attributeNS( ooNS::text, "date-value", TQString()), Qt::ISODate));
+
+ bool fixed = (object.hasAttributeNS( ooNS::text, "fixed") && object.attributeNS( ooNS::text, "fixed", TQString())=="true");
+
+ if (!dt.isValid()) {
+ dt = TQDateTime::currentDateTime(); // OOo docs say so :)
+ fixed = false;
+ }
+
+ TQDomElement typeElem = doc.createElement("TYPE");
+ typeElem.setAttribute("key", "DATE0locale"); // ### find out the correlation between KOffice and OOo date/time types
+ typeElem.setAttribute("type", 0); // VT_DATE
+ typeElem.setAttribute("text", object.text());
+
+ variable.appendChild(typeElem);
+
+ const TQDate date(dt.date());
+ const TQTime time(dt.time());
+ TQDomElement dateElement = doc.createElement("DATE");
+ dateElement.setAttribute("subtype", fixed ? 0 : 1); // VST_DATE_FIX, VST_DATE_CURRENT
+ dateElement.setAttribute("fix", fixed ? 1 : 0);
+ dateElement.setAttribute("day", date.day());
+ dateElement.setAttribute("month", date.month());
+ dateElement.setAttribute("year", date.year());
+ dateElement.setAttribute("hour", time.hour());
+ dateElement.setAttribute("minute", time.minute());
+ dateElement.setAttribute("second", time.second());
+ if (object.hasAttributeNS( ooNS::text, "date-adjust"))
+ dateElement.setAttribute("correct", object.attributeNS( ooNS::text, "date-adjust", TQString()));
+
+ variable.appendChild(dateElement);
+ }
+ else if (isTextNS && tag == "time")
+ {
+ // Use TQDateTime to work around a possible problem of TQTime::FromString in TQt 3.2.2
+ TQDateTime dt(TQDateTime::fromString(object.attributeNS( ooNS::text, "time-value", TQString()), Qt::ISODate));
+
+ bool fixed = (object.hasAttributeNS( ooNS::text, "fixed") && object.attributeNS( ooNS::text, "fixed", TQString())=="true");
+
+ if (!dt.isValid()) {
+ dt = TQDateTime::currentDateTime(); // OOo docs say so :)
+ fixed = false;
+ }
+
+ TQDomElement typeElem = doc.createElement("TYPE");
+ typeElem.setAttribute("key", "TIMElocale"); // ### find out the correlation between KOffice and OOo date/time types
+ typeElem.setAttribute("type", 2); // VT_TIME
+ typeElem.setAttribute("text", object.text());
+
+ variable.appendChild(typeElem);
+
+ const TQTime time(dt.time());
+ TQDomElement timeElement = doc.createElement("TIME");
+ timeElement.setAttribute("subtype", fixed ? 0 : 1); // VST_TIME_FIX, VST_TIME_CURRENT
+ timeElement.setAttribute("fix", fixed ? 1 : 0);
+ timeElement.setAttribute("hour", time.hour());
+ timeElement.setAttribute("minute", time.minute());
+ timeElement.setAttribute("second", time.second());
+ /*if (object.hasAttributeNS( ooNS::text, "time-adjust"))
+ timeElem.setAttribute("correct", object.attributeNS( ooNS::text, "time-adjust", TQString()));*/ // ### TODO
+
+ variable.appendChild(timeElement);
+ }
+ else if (isTextNS && tag == "page-number")
+ {
+ TQDomElement typeElem = doc.createElement("TYPE");
+ typeElem.setAttribute("key", "NUMBER");
+ typeElem.setAttribute("type", 4); // VT_PGNUM
+ typeElem.setAttribute("text", object.text());
+
+ variable.appendChild(typeElem);
+
+ TQDomElement pgNumElem = doc.createElement("PGNUM");
+
+ int subtype = 0; // VST_PGNUM_CURRENT
+
+ if (object.hasAttributeNS( ooNS::text, "select-page"))
+ {
+ const TQString select = object.attributeNS( ooNS::text, "select-page", TQString());
+
+ if (select == "previous")
+ subtype = 3; // VST_PGNUM_PREVIOUS
+ else if (select == "next")
+ subtype = 4; // VST_PGNUM_NEXT
+ else
+ subtype = 0; // VST_PGNUM_CURRENT
+ }
+
+ pgNumElem.setAttribute("subtype", subtype);
+ pgNumElem.setAttribute("value", object.text());
+
+ variable.appendChild(pgNumElem);
+ }
+ else if (isTextNS && tag == "file-name")
+ {
+ TQDomElement typeElem = doc.createElement("TYPE");
+ typeElem.setAttribute("key", "STRING");
+ typeElem.setAttribute("type", 8); // VT_FIELD
+ typeElem.setAttribute("text", object.text());
+
+ variable.appendChild(typeElem);
+
+ int subtype = 5;
+
+ if (object.hasAttributeNS( ooNS::text, "display"))
+ {
+ const TQString display = object.attributeNS( ooNS::text, "display", TQString());
+
+ if (display == "path")
+ subtype = 1; // VST_DIRECTORYNAME
+ else if (display == "name")
+ subtype = 6; // VST_FILENAMEWITHOUTEXTENSION
+ else if (display == "name-and-extension")
+ subtype = 0; // VST_FILENAME
+ else
+ subtype = 5; // VST_PATHFILENAME
+ }
+
+ TQDomElement fileNameElem = doc.createElement("FIELD");
+ fileNameElem.setAttribute("subtype", subtype);
+ fileNameElem.setAttribute("value", object.text());
+
+ variable.appendChild(fileNameElem);
+ }
+ else if (isTextNS && tag == "author-name"
+ || isTextNS && tag == "author-initials")
+ {
+ TQDomElement typeElem = doc.createElement("TYPE");
+ typeElem.setAttribute("key", "STRING");
+ typeElem.setAttribute("type", 8); // VT_FIELD
+ typeElem.setAttribute("text", object.text());
+
+ variable.appendChild(typeElem);
+
+ int subtype = 2; // VST_AUTHORNAME
+
+ if (isTextNS && tag == "author-initials")
+ subtype = 16; // VST_INITIAL
+
+ TQDomElement authorElem = doc.createElement("FIELD");
+ authorElem.setAttribute("subtype", subtype);
+ authorElem.setAttribute("value", object.text());
+
+ variable.appendChild(authorElem);
+ }
+
+ custom.appendChild(variable);
+ e.appendChild(custom);
+}
+
+void OoImpressImport::createPresentationAnimation(const TQDomElement& element)
+{
+ int order = 0;
+ TQDomElement e;
+ forEachElement( e, element )
+ {
+ const TQString localName = e.localName();
+ const TQString ns = e.namespaceURI();
+ if ( ns == ooNS::presentation && localName == "show-shape" && e.hasAttributeNS( ooNS::draw, "shape-id" ) )
+ {
+ TQString name = e.attributeNS( ooNS::draw, "shape-id", TQString() );
+ //kdDebug(30518)<<" insert animation style : name :"<<name<<endl;
+ animationList *lst = new animationList;
+ TQDomElement* ep = new TQDomElement( e );
+ lst->element = ep;
+ lst->order = order;
+ m_animations.insert( name, lst );
+ ++order;
+ }
+ }
+}
+
+TQDomElement OoImpressImport::findAnimationByObjectID(const TQString & id, int & order)
+{
+ kdDebug(30518)<<"TQDomElement OoImpressImport::findAnimationByObjectID(const TQString & id) :"<<id<<endl;
+ if (m_animations.isEmpty() )
+ return TQDomElement();
+
+ animationList *animation = m_animations[id];
+ //kdDebug(30518)<<"TQDomElement *animation = m_animations[id]; :"<<animation<<endl;
+ if ( !animation )
+ return TQDomElement();
+ for (TQDomNode node = *( animation->element ); !node.isNull(); node = node.nextSibling())
+ {
+ TQDomElement e = node.toElement();
+ order = animation->order;
+ kdDebug(30518)<<"e.tagName() :"<<e.tagName()<<" e.attribute(draw:shape-id) :"<<e.attributeNS( ooNS::draw, "shape-id", TQString())<<endl;
+ if (e.tagName()=="presentation:show-shape" && e.attributeNS( ooNS::draw, "shape-id", TQString())==id)
+ return e;
+ }
+
+ return TQDomElement();
+}
+
+
+void OoImpressImport::appendObjectEffect(TQDomDocument& doc, TQDomElement& e, const TQDomElement& object,
+ TQDomElement& sound)
+{
+ int order = 0;
+ TQDomElement origEffect = findAnimationByObjectID(object.attributeNS( ooNS::draw, "id", TQString()), order).toElement();
+
+ if (origEffect.isNull())
+ return;
+
+ TQString effect = origEffect.attributeNS( ooNS::presentation, "effect", TQString());
+ TQString dir = origEffect.attributeNS( ooNS::presentation, "direction", TQString());
+ TQString speed = origEffect.attributeNS( ooNS::presentation, "speed", TQString());
+ kdDebug(30518)<<"speed :"<<speed<<endl;
+ //todo implement speed value.
+
+ int effVal=0;
+ //kdDebug(30518)<<" effect :"<<effect<<" dir :"<<dir<<endl;
+ if (effect=="fade")
+ {
+ if (dir=="from-right")
+ effVal=10; // EF_WIPE_RIGHT
+ else if (dir=="from-left")
+ effVal=9; // EF_WIPE_LEFT
+ else if (dir=="from-top")
+ effVal=11; // EF_WIPE_TOP
+ else if (dir=="from-bottom")
+ effVal=12; // EF_WIPE_BOTTOM
+ else
+ return;
+ }
+ else if (effect=="move")
+ {
+ if (dir=="from-right")
+ effVal=1; // EF_COME_RIGHT
+ else if (dir=="from-left")
+ effVal=2; // EF_COME_LEFT
+ else if (dir=="from-top")
+ effVal=3; // EF_COME_TOP
+ else if (dir=="from-bottom")
+ effVal=4; // EF_COME_BOTTOM
+ else if (dir=="from-upper-right")
+ effVal=5; // EF_COME_RIGHT_TOP
+ else if (dir=="from-lower-right")
+ effVal=6; // EF_COME_RIGHT_BOTTOM
+ else if (dir=="from-upper-left")
+ effVal=7; // EF_COME_LEFT_TOP
+ else if (dir=="from-lower-left")
+ effVal=8; // EF_COME_LEFT_BOTTOM
+ else
+ return;
+ }
+ else
+ return; // sorry, no more supported effects :(
+
+ TQDomElement effElem = doc.createElement("EFFECTS");
+ effElem.setAttribute("effect", effVal);
+ e.appendChild(effElem);
+
+ TQDomElement presNum = doc.createElement( "PRESNUM" );
+ presNum.setAttribute("value", order);
+ e.appendChild( presNum );
+
+ // sound effect
+ TQDomElement origSoundEff = KoDom::namedItemNS( origEffect, ooNS::presentation, "sound");
+ if (!origSoundEff.isNull())
+ {
+ TQString soundUrl = storeSound(origSoundEff, sound, doc);
+
+ if (!soundUrl.isNull())
+ {
+ TQDomElement pseElem = doc.createElement("APPEARSOUNDEFFECT");
+ pseElem.setAttribute("appearSoundEffect", 1);
+ pseElem.setAttribute("appearSoundFileName", soundUrl);
+
+ e.appendChild(pseElem);
+ }
+ }
+}
+
+#include "ooimpressimport.moc"