You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koffice/filters/kpresenter/ooimpress/ooimpressexport.cc

1161 lines
44 KiB

/* This file is part of the KDE project
Copyright (C) 2003 Percy Leonhardt
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 "ooimpressexport.h"
#include <tqdom.h>
#include <tqfile.h>
#include <tqdatetime.h>
#include <kdebug.h>
#include <kgenericfactory.h>
#include <KoFilterChain.h>
#include <KoGlobal.h>
#include <KoUnit.h>
typedef KGenericFactory<OoImpressExport, KoFilter> OoImpressExportFactory;
K_EXPORT_COMPONENT_FACTORY( libooimpressexport, OoImpressExportFactory( "kofficefilters" ) )
OoImpressExport::OoImpressExport( KoFilter *, const char *, const TQStringList & )
: KoFilter()
, m_currentPage( 0 )
, m_objectIndex( 0 )
, m_pageHeight( 0 )
, m_activePage( 0 )
, m_gridX( -1.0 )
, m_gridY( -1.0 )
, m_snapToGrid( false )
, m_pictureIndex( 0 )
, m_storeinp( 0L )
, m_storeout( 0L )
{
}
OoImpressExport::~OoImpressExport()
{
delete m_storeout;
delete m_storeinp;
}
KoFilter::ConversionStatus OoImpressExport::convert( const TQCString & from,
const TQCString & to )
{
kdDebug(30518) << "Entering Ooimpress Export filter: " << from << " - " << to << endl;
if ( ( to != "application/vnd.sun.xml.impress") || (from != "application/x-kpresenter" ) )
{
kdWarning(30518) << "Invalid mimetypes " << to << " " << from << endl;
return KoFilter::NotImplemented;
}
// read in the KPresenter file
KoFilter::ConversionStatus preStatus = openFile();
if ( preStatus != KoFilter::OK )
return preStatus;
TQDomImplementation impl;
TQDomDocument meta( impl.createDocumentType( "office:document-meta",
"-//OpenOffice.org//DTD OfficeDocument 1.0//EN",
"office.dtd" ) );
createDocumentMeta( meta );
// store document meta
m_storeout = KoStore::createStore( m_chain->outputFile(), KoStore::Write, "", KoStore::Zip );
if ( !m_storeout )
{
kdWarning(30518) << "Couldn't open the requested file." << endl;
return KoFilter::FileNotFound;
}
if ( !m_storeout->open( "meta.xml" ) )
{
kdWarning(30518) << "Couldn't open the file 'meta.xml'." << endl;
return KoFilter::CreationError;
}
TQCString metaString = meta.toCString();
//kdDebug(30518) << "meta :" << metaString << endl;
m_storeout->write( metaString , metaString.length() );
m_storeout->close();
TQDomDocument content( impl.createDocumentType( "office:document-content",
"-//OpenOffice.org//DTD OfficeDocument 1.0//EN",
"office.dtd" ) );
createDocumentContent( content );
// add the automatic styles
m_styleFactory.addAutomaticStyles( content, m_styles );
// store document content
if ( !m_storeout->open( "content.xml" ) )
{
kdWarning(30518) << "Couldn't open the file 'content.xml'." << endl;
return KoFilter::CreationError;
}
TQCString contentString = content.toCString();
//kdDebug(30518) << "content :" << contentString << endl;
m_storeout->write( contentString , contentString.length() );
m_storeout->close();
TQDomDocument settings( impl.createDocumentType( "office:document-content",
"-//OpenOffice.org//DTD OfficeDocument 1.0//EN",
"office.dtd" ) );
createDocumentSettings( settings );
// store document content
if ( !m_storeout->open( "settings.xml" ) )
{
kdWarning(30518) << "Couldn't open the file 'settings.xml'." << endl;
return KoFilter::CreationError;
}
TQCString settingsString = settings.toCString();
//kdDebug(30518) << "content :" << settingsString << endl;
m_storeout->write( settingsString , settingsString.length() );
m_storeout->close();
TQDomDocument styles( impl.createDocumentType( "office:document-styles",
"-//OpenOffice.org//DTD OfficeDocument 1.0//EN",
"office.dtd" ) );
createDocumentStyles( styles );
// store document styles
if ( !m_storeout->open( "styles.xml" ) )
{
kdWarning(30518) << "Couldn't open the file 'styles.xml'." << endl;
return KoFilter::CreationError;
}
TQCString stylesString = styles.toCString();
//kdDebug(30518) << "styles :" << stylesString << endl;
m_storeout->write( stylesString , stylesString.length() );
m_storeout->close();
TQDomDocument manifest( impl.createDocumentType( "manifest:manifest",
"-//OpenOffice.org//DTD Manifest 1.0//EN",
"Manifest.dtd" ) );
createDocumentManifest( manifest );
// store document manifest
m_storeout->enterDirectory( "META-INF" );
if ( !m_storeout->open( "manifest.xml" ) )
{
kdWarning(30518) << "Couldn't open the file 'META-INF/manifest.xml'." << endl;
return KoFilter::CreationError;
}
TQCString manifestString = manifest.toCString();
//kdDebug(30518) << "manifest :" << manifestString << endl;
m_storeout->write( manifestString , manifestString.length() );
m_storeout->close();
return KoFilter::OK;
}
KoFilter::ConversionStatus OoImpressExport::openFile()
{
m_storeinp = KoStore::createStore( m_chain->inputFile(), KoStore::Read );
if ( !m_storeinp )
{
kdWarning(30518) << "Couldn't open the requested file." << endl;
return KoFilter::FileNotFound;
}
if ( !m_storeinp->open( "maindoc.xml" ) )
{
kdWarning(30518) << "This file doesn't seem to be a valid KPresenter file" << endl;
return KoFilter::WrongFormat;
}
m_maindoc.setContent( m_storeinp->device() );
m_storeinp->close();
if ( m_storeinp->open( "documentinfo.xml" ) )
{
m_documentinfo.setContent( m_storeinp->device() );
m_storeinp->close();
}
else
kdWarning(30518) << "Documentinfo do not exist!" << endl;
emit sigProgress( 10 );
return KoFilter::OK;
}
void OoImpressExport::createDocumentMeta( TQDomDocument & docmeta )
{
docmeta.appendChild( docmeta.createProcessingInstruction( "xml","version=\"1.0\" encoding=\"UTF-8\"" ) );
TQDomElement content = docmeta.createElement( "office:document-meta" );
content.setAttribute( "xmlns:office", "http://openoffice.org/2000/office" );
content.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" );
content.setAttribute( "xmlns:dc", "http://purl.org/dc/elements/1.1/" );
content.setAttribute( "xmlns:meta", "http://openoffice.org/2000/meta" );
content.setAttribute( "office:version", "1.0" );
TQDomNode meta = docmeta.createElement( "office:meta" );
TQDomElement generator = docmeta.createElement( "meta:generator" );
generator.appendChild( docmeta.createTextNode( "KPresenter 1.5" ) );
meta.appendChild( generator );
TQDomNode i = m_documentinfo.namedItem( "document-info" );
if ( !i.isNull() )
{
TQDomNode n = i.namedItem( "author" ).namedItem( "full-name" );
if ( !n.isNull() )
{
TQDomElement fullName = n.toElement();
TQDomElement creator = docmeta.createElement( "meta:initial-creator" );
creator.appendChild( docmeta.createTextNode( fullName.text() ) );
meta.appendChild( creator );
creator = docmeta.createElement( "meta:creator" );
creator.appendChild( docmeta.createTextNode( fullName.text() ) );
meta.appendChild( creator );
}
n = i.namedItem( "about" ).namedItem( "abstract" );
if ( !n.isNull() )
{
TQDomElement user = docmeta.createElement( "dc:description" );
user.appendChild( n.firstChild() );
meta.appendChild( user );
}
n = i.namedItem( "about" ).namedItem( "keyword" );
if ( !n.isNull() )
{
TQDomElement text = n.toElement();
TQDomElement key = docmeta.createElement( "meta:keywords" );
TQDomElement keyword = docmeta.createElement( "meta:keyword" );
key.appendChild( keyword );
keyword.appendChild( docmeta.createTextNode( text.text() ) );
meta.appendChild( key );
}
n = i.namedItem( "about" ).namedItem( "subject" );
if ( !n.isNull() )
{
TQDomElement text = n.toElement();
TQDomElement subjet = docmeta.createElement( "dc:subject" );
subjet.appendChild( docmeta.createTextNode( text.text() ) );
meta.appendChild( subjet );
}
n = i.namedItem( "about" ).namedItem( "title" );
if ( !n.isNull() )
{
TQDomElement text = n.toElement();
TQDomElement title = docmeta.createElement( "dc:title" );
title.appendChild( docmeta.createTextNode( text.text() ) );
meta.appendChild( title );
}
}
// TQDomElement statistic = docmeta.createElement( "meta:document-statistic" );
// statistic.setAttribute( "meta:object-count", 0 );
// meta.appendChild( data );
content.appendChild( meta );
docmeta.appendChild( content );
}
void OoImpressExport::createDocumentStyles( TQDomDocument & docstyles )
{
docstyles.appendChild( docstyles.createProcessingInstruction( "xml","version=\"1.0\" encoding=\"UTF-8\"" ) );
TQDomElement content = docstyles.createElement( "office:document-content" );
content.setAttribute( "xmlns:office", "http://openoffice.org/2000/office" );
content.setAttribute( "xmlns:style", "http://openoffice.org/2000/style" );
content.setAttribute( "xmlns:text", "http://openoffice.org/2000/text" );
content.setAttribute( "xmlns:table", "http://openoffice.org/2000/table" );
content.setAttribute( "xmlns:draw", "http://openoffice.org/2000/drawing" );
content.setAttribute( "xmlns:fo", "http://www.w3.org/1999/XSL/Format" );
content.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" );
content.setAttribute( "xmlns:number", "http://openoffice.org/2000/datastyle" );
content.setAttribute( "xmlns:svg", "http://www.w3.org/2000/svg" );
content.setAttribute( "xmlns:chart", "http://openoffice.org/2000/chart" );
content.setAttribute( "xmlns:dr3d", "http://openoffice.org/2000/dr3d" );
content.setAttribute( "xmlns:math", "http://www.w3.org/1998/Math/MathML" );
content.setAttribute( "xmlns:form", "http://openoffice.org/2000/form" );
content.setAttribute( "xmlns:script", "http://openoffice.org/2000/script" );
content.setAttribute( "office:version", "1.0" );
// order important here!
TQDomElement styles = docstyles.createElement( "office:styles" );
m_styleFactory.addOfficeStyles( docstyles, styles );
content.appendChild( styles );
TQDomElement automatic = docstyles.createElement( "office:automatic-styles" );
m_styleFactory.addOfficeAutomatic( docstyles, automatic );
content.appendChild( automatic );
TQDomElement master = docstyles.createElement( "office:master-styles" );
m_styleFactory.addOfficeMaster( docstyles, master );
content.appendChild( master );
docstyles.appendChild( content );
}
void OoImpressExport::createDocumentSettings( TQDomDocument & docsetting )
{
docsetting.appendChild( docsetting.createProcessingInstruction( "xml","version=\"1.0\" encoding=\"UTF-8\"" ) );
TQDomElement setting = docsetting.createElement( "office:document-settings" );
setting.setAttribute( "xmlns:office", "http://openoffice.org/2000/office");
setting.setAttribute( "xmlns:config", "http://openoffice.org/2001/config" );
setting.setAttribute( "office:class", "presentation" );
setting.setAttribute( "office:version", "1.0" );
TQDomElement begin = docsetting.createElement( "office:settings" );
TQDomElement configItem = docsetting.createElement("config:config-item-set" );
configItem.setAttribute( "config:name", "view-settings" );
TQDomElement mapIndexed = docsetting.createElement( "config:config-item-map-indexed" );
mapIndexed.setAttribute("config:name", "Views" );
configItem.appendChild( mapIndexed );
//<config:config-item-map-indexed config:name="Views">
TQDomElement mapItem = docsetting.createElement("config:config-item-map-entry" );
TQDomElement attribute = docsetting.createElement("config:config-item" );
attribute.setAttribute( "config:name", "SnapLinesDrawing" );
attribute.setAttribute( "config:type", "string" );
attribute.appendChild( docsetting.createTextNode( m_helpLine ) );
mapItem.appendChild( attribute );
//<config:config-item config:name="SnapLinesDrawing" config:type="string">H5983V700V10777H4518V27601P50000,9000P8021,2890</config:config-item>
attribute = docsetting.createElement("config:config-item" );
attribute.setAttribute( "config:name", "IsSnapToGrid" );
attribute.setAttribute( "config:type", "boolean" );
attribute.appendChild( docsetting.createTextNode( m_snapToGrid ? "true" : "false" ) );
mapItem.appendChild( attribute );
if ( m_gridX >=0 )
{
attribute = docsetting.createElement("config:config-item" );
attribute.setAttribute( "config:name", "GridFineWidth" );
attribute.setAttribute( "config:type", "int" );
attribute.appendChild( docsetting.createTextNode( TQString::number( ( int ) ( KoUnit::toMM( ( m_gridX ) )*100 ) ) ) );
mapItem.appendChild( attribute );
}
if ( m_gridY >=0 )
{
attribute = docsetting.createElement("config:config-item" );
attribute.setAttribute( "config:name", "GridFineHeight" );
attribute.setAttribute( "config:type", "int" );
attribute.appendChild( docsetting.createTextNode( TQString::number( ( int ) ( KoUnit::toMM( ( m_gridY ) )*100 ) ) ) );
mapItem.appendChild( attribute );
}
attribute = docsetting.createElement("config:config-item" );
attribute.setAttribute( "config:name", "SelectedPage" );
attribute.setAttribute( "config:type", "short" );
attribute.appendChild( docsetting.createTextNode( TQString::number( m_activePage ) ) );
mapItem.appendChild( attribute );
mapIndexed.appendChild( mapItem );
begin.appendChild( configItem );
setting.appendChild( begin );
docsetting.appendChild( setting );
}
void OoImpressExport::createDocumentContent( TQDomDocument & doccontent )
{
doccontent.appendChild( doccontent.createProcessingInstruction( "xml","version=\"1.0\" encoding=\"UTF-8\"" ) );
TQDomElement content = doccontent.createElement( "office:document-content" );
content.setAttribute( "xmlns:office", "http://openoffice.org/2000/office");
content.setAttribute( "xmlns:style", "http://openoffice.org/2000/style" );
content.setAttribute( "xmlns:text", "http://openoffice.org/2000/text" );
content.setAttribute( "xmlns:table", "http://openoffice.org/2000/table" );
content.setAttribute( "xmlns:draw", "http://openoffice.org/2000/drawing" );
content.setAttribute( "xmlns:fo", "http://www.w3.org/1999/XSL/Format" );
content.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" );
content.setAttribute( "xmlns:number", "http://openoffice.org/2000/datastyle" );
content.setAttribute( "xmlns:svg", "http://www.w3.org/2000/svg" );
content.setAttribute( "xmlns:chart", "http://openoffice.org/2000/chart" );
content.setAttribute( "xmlns:dr3d", "http://openoffice.org/2000/dr3d" );
content.setAttribute( "xmlns:math", "http://www.w3.org/1998/Math/MathML" );
content.setAttribute( "xmlns:form", "http://openoffice.org/2000/form" );
content.setAttribute( "xmlns:script", "http://openoffice.org/2000/script" );
content.setAttribute( "xmlns:presentation", "http://openoffice.org/2000/presentation" );
content.setAttribute( "office:class", "presentation" );
content.setAttribute( "office:version", "1.0" );
TQDomElement script = doccontent.createElement( "office:script" );
content.appendChild( script );
m_styles = doccontent.createElement( "office:automatic-styles" );
content.appendChild( m_styles );
TQDomElement body = doccontent.createElement( "office:body" );
exportBody( doccontent, body );
content.appendChild( body );
doccontent.appendChild( content );
}
void OoImpressExport::createDocumentManifest( TQDomDocument & docmanifest )
{
docmanifest.appendChild( docmanifest.createProcessingInstruction( "xml","version=\"1.0\" encoding=\"UTF-8\"" ) );
TQDomElement manifest = docmanifest.createElement( "manifest:manifest" );
manifest.setAttribute( "xmlns:manifest", "http://openoffice.org/2001/manifest" );
TQDomElement entry = docmanifest.createElement( "manifest:file-entry" );
entry.setAttribute( "manifest:media-type", "application/vnd.sun.xml.impress" );
entry.setAttribute( "manifest:full-path", "/" );
manifest.appendChild( entry );
TQMap<TQString, TQString>::Iterator it;
for ( it = m_pictureLst.begin(); it != m_pictureLst.end(); ++it )
{
entry = docmanifest.createElement( "manifest:file-entry" );
entry.setAttribute( "manifest:media-type", it.data() );
entry.setAttribute( "manifest:full-path", it.key() );
manifest.appendChild( entry );
}
entry = docmanifest.createElement( "manifest:file-entry" );
entry.setAttribute( "manifest:media-type", "text/xml" );
entry.setAttribute( "manifest:full-path", "content.xml" );
manifest.appendChild( entry );
entry = docmanifest.createElement( "manifest:file-entry" );
entry.setAttribute( "manifest:media-type", "text/xml" );
entry.setAttribute( "manifest:full-path", "styles.xml" );
manifest.appendChild( entry );
entry = docmanifest.createElement( "manifest:file-entry" );
entry.setAttribute( "manifest:media-type", "text/xml" );
entry.setAttribute( "manifest:full-path", "meta.xml" );
manifest.appendChild( entry );
entry = docmanifest.createElement( "manifest:file-entry" );
entry.setAttribute( "manifest:media-type", "text/xml" );
entry.setAttribute( "manifest:full-path", "settings.xml" );
manifest.appendChild( entry );
docmanifest.appendChild( manifest );
}
TQString OoImpressExport::pictureKey( TQDomElement &elem )
{
// Default date/time is the *nix epoch: 1970-01-01 00:00:00,000
int year=1970, month=1, day=1;
int hour=0, minute=0, second=0, msec=0; // We must initialize to zero, as not all compilers are C99-compliant
if ( elem.tagName() == "KEY" )
{
if( elem.hasAttribute( "year" ) )
year=elem.attribute( "year" ).toInt();
if( elem.hasAttribute( "month" ) )
month=elem.attribute( "month" ).toInt();
if( elem.hasAttribute( "day" ) )
day=elem.attribute( "day" ).toInt();
if( elem.hasAttribute( "hour" ) )
hour=elem.attribute( "hour" ).toInt();
if( elem.hasAttribute( "minute" ) )
minute=elem.attribute( "minute" ).toInt();
if( elem.hasAttribute( "second" ) )
second=elem.attribute( "second" ).toInt();
if( elem.hasAttribute( "msec" ) )
msec=elem.attribute( "msec" ).toInt();
}
TQDateTime key;
key.setDate( TQDate( year, month, day ) );
key.setTime( TQTime( hour, minute, second, msec ) );
return key.toString();
}
void OoImpressExport::createPictureList( TQDomNode &pictures )
{
pictures = pictures.firstChild();
for( ; !pictures.isNull(); pictures = pictures.nextSibling() )
{
if ( pictures.isElement() )
{
TQDomElement element = pictures.toElement();
if ( element.tagName() == "KEY" )
{
//kdDebug(30518)<<"element.attribute( name ) :"<<element.attribute( "name" )<<endl;
m_kpresenterPictureLst.insert( pictureKey( element ), element.attribute( "name" ) );
}
else
kdDebug(30518)<<" Tag not recognize :"<<element.tagName()<<endl;
}
}
}
void OoImpressExport::createAttribute( TQDomNode &attributeValue )
{
TQDomElement elem = attributeValue.toElement();
if(elem.hasAttribute("activePage"))
m_activePage=elem.attribute("activePage").toInt();
if(elem.hasAttribute("gridx"))
m_gridX = elem.attribute("gridx").toDouble();
if(elem.hasAttribute("gridy"))
m_gridY = elem.attribute("gridy").toDouble();
if(elem.hasAttribute("snaptogrid"))
m_snapToGrid = (bool)elem.attribute("snaptogrid").toInt();
}
void OoImpressExport::createHelpLine( TQDomNode &helpline )
{
helpline = helpline.firstChild();
TQDomElement helplines;
for( ; !helpline.isNull(); helpline = helpline.nextSibling() )
{
if ( helpline.isElement() )
{
helplines = helpline.toElement();
if ( helplines.tagName()=="Vertical" )
{
int tmpX = ( int ) ( KoUnit::toMM( helplines.attribute("value").toDouble() )*100 );
m_helpLine+="V"+TQString::number( tmpX );
}
else if ( helplines.tagName()=="Horizontal" )
{
int tmpY = ( int ) ( KoUnit::toMM( helplines.attribute("value").toDouble() )*100 );
m_helpLine+="H"+TQString::number( tmpY );
}
else if ( helplines.tagName()=="HelpPoint" )
{
TQString str( "P%1,%2" );
int tmpX = ( int ) ( KoUnit::toMM( helplines.attribute("posX").toDouble() )*100 );
int tmpY = ( int ) ( KoUnit::toMM( helplines.attribute("posY").toDouble() )*100 );
m_helpLine+=str.arg( TQString::number( tmpX ) ).arg( TQString::number( tmpY ) );
}
}
}
//kdDebug(30518)<<"m_helpLine :"<<m_helpLine<<endl;
}
void OoImpressExport::exportBody( TQDomDocument & doccontent, TQDomElement & body )
{
TQDomNode doc = m_maindoc.namedItem( "DOC" );
TQDomNode paper = doc.namedItem( "PAPER" );
TQDomNode background = doc.namedItem( "BACKGROUND" );
TQDomNode header = doc.namedItem( "HEADER" );
TQDomNode footer = doc.namedItem( "FOOTER" );
TQDomNode titles = doc.namedItem( "PAGETITLES" );
TQDomNode notes = doc.namedItem( "PAGENOTES" );
TQDomNode objects = doc.namedItem( "OBJECTS" );
TQDomNode pictures = doc.namedItem( "PICTURES" );
TQDomNode sounds = doc.namedItem( "SOUNDS" );
TQDomNode helpline = doc.namedItem( "HELPLINES" );
TQDomNode attributeValue = doc.namedItem( "ATTRIBUTES" );
TQDomNode infiniLoop = doc.namedItem( "INFINITLOOP" );
TQDomNode manualSwitch = doc.namedItem( "MANUALSWITCH" );
TQDomNode customSlideShow = doc.namedItem( "CUSTOMSLIDESHOWCONFIG" );
TQDomNode customSlideShowDefault = doc.namedItem( "DEFAULTCUSTOMSLIDESHOWNAME" );
TQDomNode bgpage = background.firstChild();
createPictureList( pictures );
createHelpLine( helpline );
createAttribute( attributeValue );
// store the paper settings
TQDomElement p = paper.toElement();
m_masterPageStyle = m_styleFactory.createPageMasterStyle( p );
m_pageHeight = p.attribute( "ptHeight" ).toFloat();
m_currentPage = 1;
// parse all pages
TQDomNode note = notes.firstChild();
for ( TQDomNode title = titles.firstChild(); !title.isNull() && !note.isNull();
title = title.nextSibling(), note = note.nextSibling() )
{
// create the page style and ignore the fact that there may
// be less backgrounds than pages
TQDomElement bg = bgpage.toElement();
TQString ps = m_styleFactory.createPageStyle( bg );
bgpage = bgpage.nextSibling();
TQDomElement t = title.toElement();
TQDomElement drawPage = doccontent.createElement( "draw:page" );
drawPage.setAttribute( "draw:name", t.attribute( "title" ) );
drawPage.setAttribute( "draw:style-name", ps );
drawPage.setAttribute( "draw:id", m_currentPage );
drawPage.setAttribute( "draw:master-page-name", m_masterPageStyle );
appendObjects( doccontent, objects, drawPage );
TQDomElement noteElement = note.toElement();
appendNote( doccontent, noteElement, drawPage );
body.appendChild( drawPage );
m_currentPage++;
}
int infiniLoopValue = -1;
int manualSwitchValue = -1;
if ( !infiniLoop.isNull() && infiniLoop.toElement().hasAttribute( "value" ))
{
bool ok;
int val = infiniLoop.toElement().attribute( "value" ).toInt( &ok );
if ( ok )
infiniLoopValue = val;
}
if ( !manualSwitch.isNull() && manualSwitch.toElement().hasAttribute( "value" ))
{
bool ok;
int val = manualSwitch.toElement().attribute( "value" ).toInt( &ok );
if ( ok )
manualSwitchValue = val;
}
if ( infiniLoopValue != -1 || manualSwitchValue != -1 || !customSlideShowDefault.isNull())
{
TQDomElement settings = doccontent.createElement( "presentation:settings" );
if ( infiniLoopValue !=-1 )
settings.setAttribute( "presentation:force-manual", ( manualSwitchValue==1 ) ? "true" : "false" );
if ( manualSwitchValue != -1 )
settings.setAttribute( "presentation:endless", ( infiniLoopValue==1 ) ? "true": "false" );
if ( !customSlideShowDefault.isNull() )
settings.setAttribute( "presentation:show", customSlideShowDefault.toElement().attribute( "name" ) );
if ( !customSlideShow.isNull() )
{
for ( TQDomNode customPage = customSlideShow.firstChild(); !customPage.isNull();
customPage = customPage.nextSibling() )
{
TQDomElement show = customPage.toElement();
if ( !show.isNull() && show.tagName()=="CUSTOMSLIDESHOW" )
{
TQDomElement showElement = doccontent.createElement( "presentation:show" );
showElement.setAttribute( "presentation:name",show.attribute( "name" ) );
showElement.setAttribute( "presentation:pages",show.attribute( "pages" ) );
settings.appendChild( showElement );
}
}
}
body.appendChild( settings );
}
}
void OoImpressExport::appendObjects(TQDomDocument & doccontent, TQDomNode &objects, TQDomElement &drawPage)
{
// I am not sure if objects are always stored sorted so I parse all
// of them to find the ones belonging to a certain page.
for ( TQDomNode object = objects.firstChild(); !object.isNull();
object = object.nextSibling() )
{
TQDomElement o = object.toElement();
TQDomElement orig = o.namedItem( "ORIG" ).toElement();
float y = orig.attribute( "y" ).toFloat();
if ( y < m_pageHeight * ( m_currentPage - 1 ) ||
y >= m_pageHeight * m_currentPage )
continue; // object not on current page
switch( o.attribute( "type" ).toInt() )
{
case 0: // image
appendPicture( doccontent, o, drawPage );
break;
case 1: // line
appendLine( doccontent, o, drawPage );
break;
case 2: // rectangle
appendRectangle( doccontent, o, drawPage );
break;
case 3: // circle, ellipse
appendEllipse( doccontent, o, drawPage );
break;
case 4: // textbox
appendTextbox( doccontent, o, drawPage );
break;
case 5:
kdDebug(30518)<<" autoform not implemented\n";
break;
case 6:
kdDebug(30518)<<" clipart not implemented\n";
break;
case 8: // pie, chord, arc
appendEllipse( doccontent, o, drawPage, true );
break;
case 9: //part
kdDebug(30518)<<" part object not implemented \n";
break;
case 10:
appendGroupObject( doccontent, o, drawPage );
break;
case 11:
kdDebug(30518)<<" free hand not implemented\n";
break;
case 12: // polyline
appendPolyline( doccontent, o, drawPage );
break;
case 13: //OT_QUADRICBEZIERCURVE = 13
case 14: //OT_CUBICBEZIERCURVE = 14
//todo
// "draw:path"
break;
case 15: // polygon
case 16: // close polygone
appendPolyline( doccontent, o, drawPage, true /*polygon*/ );
break;
}
++m_objectIndex;
}
}
void OoImpressExport::appendGroupObject( TQDomDocument & doc, TQDomElement & source, TQDomElement & target )
{
TQDomElement groupElement = doc.createElement( "draw:g" );
TQDomNode objects = source.namedItem( "OBJECTS" );
appendObjects( doc, objects, groupElement);
target.appendChild( groupElement );
}
void OoImpressExport::appendNote( TQDomDocument & doc, TQDomElement & source, TQDomElement & target )
{
TQString noteText = source.attribute("note");
//kdDebug(30518)<<"noteText :"<<noteText<<endl;
if ( noteText.isEmpty() )
return;
TQDomElement noteElement = doc.createElement( "presentation:notes" );
TQDomElement noteTextBox = doc.createElement( "draw:text-box" );
//TODO : add draw:text-box size :
//<draw:text-box draw:style-name="gr2" draw:text-style-name="P2" draw:layer="layout" svg:width="13.336cm" svg:height="56.288cm" svg:x="-0.54cm" svg:y="-14.846cm">
TQStringList text = TQStringList::split( "\n", noteText );
for ( TQStringList::Iterator it = text.begin(); it != text.end(); ++it ) {
TQDomElement tmp = doc.createElement( "text:p" );
tmp.appendChild( doc.createTextNode( *it ) );
noteTextBox.appendChild( tmp );
}
noteElement.appendChild( noteTextBox );
target.appendChild( noteElement );
}
void OoImpressExport::appendTextbox( TQDomDocument & doc, TQDomElement & source, TQDomElement & target )
{
TQDomElement textbox = doc.createElement( "draw:text-box" );
TQDomNode textobject = source.namedItem( "TEXTOBJ" );
// create the graphic style
TQString gs = m_styleFactory.createGraphicStyle( source );
textbox.setAttribute( "draw:style-name", gs );
// set the geometry
set2DGeometry( source, textbox );
// parse every paragraph
for ( TQDomNode paragraph = textobject.firstChild(); !paragraph.isNull();
paragraph = paragraph.nextSibling() )
{
TQDomElement p = paragraph.toElement();
appendParagraph( doc, p, textbox );
}
target.appendChild( textbox );
}
void OoImpressExport::appendParagraph( TQDomDocument & doc, TQDomElement & source, TQDomElement & target )
{
TQDomElement paragraph = doc.createElement( "text:p" );
// create the paragraph style
TQString ps = m_styleFactory.createParagraphStyle( source );
paragraph.setAttribute( "text:style-name", ps );
// parse every text element
for ( TQDomNode text = source.firstChild(); !text.isNull();
text = text.nextSibling() )
{
if ( text.nodeName() == "TEXT" )
{
TQDomElement t = text.toElement();
appendText( doc, t, paragraph );
}
}
// take care of lists
TQDomNode counter = source.namedItem( "COUNTER" );
if ( !counter.isNull() )
{
TQDomElement c = counter.toElement();
int type = c.attribute( "type" ).toInt();
int level = 1;
if ( c.hasAttribute( "depth" ) )
level = c.attribute( "depth" ).toInt() + 1;
TQDomElement endOfList = target;
for ( int l = 0; l < level; l++ )
{
TQDomElement list;
if ( type == 1 )
{
list = doc.createElement( "text:ordered-list" );
list.setAttribute( "text:continue-numbering", "true" );
}
else
list = doc.createElement( "text:unordered-list" );
if ( l == 0 )
{
// create the list style
TQString ls = m_styleFactory.createListStyle( c );
list.setAttribute( "text:style-name", ls );
}
TQDomElement item = doc.createElement( "text:list-item" );
list.appendChild( item );
endOfList.appendChild( list );
endOfList = item;
}
endOfList.appendChild( paragraph );
}
else
target.appendChild( paragraph );
}
void OoImpressExport::appendText( TQDomDocument & doc, TQDomElement & source, TQDomElement & target )
{
TQDomElement textspan = doc.createElement( "text:span" );
// create the text style
TQString ts = m_styleFactory.createTextStyle( source );
textspan.setAttribute( "text:style-name", ts );
textspan.appendChild( doc.createTextNode( source.text() ) );
target.appendChild( textspan );
}
void OoImpressExport::appendPicture( TQDomDocument & doc, TQDomElement & source, TQDomElement & target )
{
TQDomElement image = doc.createElement( "draw:image" );
// create the graphic style
TQString gs = m_styleFactory.createGraphicStyle( source );
image.setAttribute( "draw:style-name", gs );
TQDomElement key = source.namedItem( "KEY" ).toElement();
TQString pictureName = TQString( "Picture/Picture%1" ).arg( m_pictureIndex );
image.setAttribute( "xlink:type", "simple" );
image.setAttribute( "xlink:show", "embed" );
image.setAttribute( "xlink:actuate", "onLoad");
if ( !key.isNull() )
{
TQString str = pictureKey( key );
TQString returnstr = m_kpresenterPictureLst[str];
const int pos=returnstr.findRev('.');
if (pos!=-1)
{
const TQString extension( returnstr.mid(pos+1) );
pictureName +="."+extension;
}
if ( m_storeinp->open( returnstr ) )
{
if ( m_storeout->open( pictureName ) )
{
TQByteArray data(8*1024);
uint total = 0;
for ( int block = 0; ( block = m_storeinp->read(data.data(), data.size()) ) > 0;
total += block )
m_storeout->write(data.data(), data.size());
m_storeout->close();
m_storeinp->close();
}
}
}
image.setAttribute( "xlink:href", "#" + pictureName );
// set the geometry
set2DGeometry( source, image );
target.appendChild( image );
m_pictureLst.insert( pictureName , "image/png" );
++m_pictureIndex;
}
void OoImpressExport::appendLine( TQDomDocument & doc, TQDomElement & source, TQDomElement & target )
{
TQDomElement line = doc.createElement( "draw:line" );
// create the graphic style
TQString gs = m_styleFactory.createGraphicStyle( source );
line.setAttribute( "draw:style-name", gs );
// set the geometry
setLineGeometry( source, line );
target.appendChild( line );
}
void OoImpressExport::appendRectangle( TQDomDocument & doc, TQDomElement & source, TQDomElement & target )
{
TQDomElement rectangle = doc.createElement( "draw:rect" );
// create the graphic style
TQString gs = m_styleFactory.createGraphicStyle( source );
rectangle.setAttribute( "draw:style-name", gs );
// set the geometry
set2DGeometry( source, rectangle );
target.appendChild( rectangle );
}
void OoImpressExport::appendPolyline( TQDomDocument & doc, TQDomElement & source, TQDomElement & target, bool _poly)
{
TQDomElement polyline = doc.createElement( _poly ? "draw:polygon" : "draw:polyline" );
// create the graphic style
TQString gs = m_styleFactory.createGraphicStyle( source );
polyline.setAttribute( "draw:style-name", gs );
// set the geometry
set2DGeometry( source, polyline, false, true /*multipoint*/ );
target.appendChild( polyline );
}
void OoImpressExport::appendEllipse( TQDomDocument & doc, TQDomElement & source, TQDomElement & target, bool pieObject )
{
TQDomElement size = source.namedItem( "SIZE" ).toElement();
double width = size.attribute( "width" ).toDouble();
double height = size.attribute( "height" ).toDouble();
TQDomElement ellipse = doc.createElement( (width == height) ? "draw:circle" : "draw:ellipse" );
// create the graphic style
TQString gs = m_styleFactory.createGraphicStyle( source );
ellipse.setAttribute( "draw:style-name", gs );
// set the geometry
set2DGeometry( source, ellipse, pieObject );
target.appendChild( ellipse );
}
void OoImpressExport::set2DGeometry( TQDomElement & source, TQDomElement & target, bool pieObject, bool multiPoint )
{
TQDomElement orig = source.namedItem( "ORIG" ).toElement();
TQDomElement size = source.namedItem( "SIZE" ).toElement();
TQDomElement name = source.namedItem( "OBJECTNAME").toElement();
float y = orig.attribute( "y" ).toFloat();
y -= m_pageHeight * ( m_currentPage - 1 );
TQDomElement angle = source.namedItem( "ANGLE").toElement();
if ( !angle.isNull() )
{
TQString returnAngle = rotateValue( angle.attribute( "value" ).toDouble() );
if ( !returnAngle.isEmpty() )
target.setAttribute("draw:transform",returnAngle );
}
target.setAttribute( "draw:id", TQString::number( m_objectIndex ) );
target.setAttribute( "svg:x", StyleFactory::toCM( orig.attribute( "x" ) ) );
target.setAttribute( "svg:y", TQString( "%1cm" ).arg( KoUnit::toCM( y ) ) );
target.setAttribute( "svg:width", StyleFactory::toCM( size.attribute( "width" ) ) );
target.setAttribute( "svg:height", StyleFactory::toCM( size.attribute( "height" ) ) );
TQString nameStr = name.attribute("objectName");
if( !nameStr.isEmpty() )
target.setAttribute( "draw:name", nameStr );
if ( pieObject )
{
TQDomElement pie = source.namedItem( "PIETYPE").toElement();
if( !pie.isNull() )
{
int typePie = pie.attribute("value").toInt();
switch( typePie )
{
case 0:
target.setAttribute( "draw:kind", "section");
break;
case 1:
target.setAttribute( "draw:kind", "arc");
break;
case 2:
target.setAttribute( "draw:kind", "cut");
break;
default:
kdDebug(30518)<<" type unknown : "<<typePie<<endl;
break;
}
}
else
target.setAttribute( "draw:kind", "section");//by default
TQDomElement pieAngle = source.namedItem( "PIEANGLE").toElement();
int startangle = 45;
if( !pieAngle.isNull() )
{
startangle = (pieAngle.attribute("value").toInt())/16;
target.setAttribute( "draw:start-angle", startangle);
}
else
{
//default value take it into kppieobject
target.setAttribute( "draw:start-angle", 45 );
}
TQDomElement pieLength = source.namedItem( "PIELENGTH").toElement();
if( !pieLength.isNull() )
{
int value = pieLength.attribute("value").toInt();
value = value /16;
value = value + startangle;
target.setAttribute( "draw:end-angle", value );
}
else
{
//default value take it into kppieobject
//default is 90<39> into kpresenter
target.setAttribute( "draw:end-angle", (90+startangle) );
}
}
if ( multiPoint )
{
//loadPoint
TQDomElement point = source.namedItem( "POINTS" ).toElement();
if ( !point.isNull() ) {
TQDomElement elemPoint = point.firstChild().toElement();
TQString listOfPoint;
int maxX=0;
int maxY=0;
while ( !elemPoint.isNull() ) {
if ( elemPoint.tagName() == "Point" ) {
int tmpX = 0;
int tmpY = 0;
if( elemPoint.hasAttribute( "point_x" ) )
tmpX = ( int ) ( KoUnit::toMM( elemPoint.attribute( "point_x" ).toDouble() )*100 );
if( elemPoint.hasAttribute( "point_y" ) )
tmpY = ( int ) ( KoUnit::toMM(elemPoint.attribute( "point_y" ).toDouble() )*100 );
if ( !listOfPoint.isEmpty() )
listOfPoint += TQString( " %1,%2" ).arg( tmpX ).arg( tmpY );
else
listOfPoint = TQString( "%1,%2" ).arg( tmpX ).arg( tmpY );
maxX = TQMAX( maxX, tmpX );
maxY = TQMAX( maxY, tmpY );
}
elemPoint = elemPoint.nextSibling().toElement();
}
target.setAttribute( "draw:points", listOfPoint );
target.setAttribute( "svg:viewBox", TQString( "0 0 %1 %2" ).arg( maxX ).arg( maxY ) );
}
}
}
TQString OoImpressExport::rotateValue( double val )
{
TQString str;
if ( val!=0.0 )
{
double value = -1 * ( ( double )val* M_PI )/180.0;
str=TQString( "rotate (%1)" ).arg( value );
}
return str;
}
void OoImpressExport::setLineGeometry( TQDomElement & source, TQDomElement & target )
{
TQDomElement orig = source.namedItem( "ORIG" ).toElement();
TQDomElement size = source.namedItem( "SIZE" ).toElement();
TQDomElement linetype = source.namedItem( "LINETYPE" ).toElement();
TQDomElement name = source.namedItem( "OBJECTNAME").toElement();
TQDomElement angle = source.namedItem( "ANGLE").toElement();
if ( !angle.isNull() )
{
TQString returnAngle = rotateValue( angle.attribute( "value" ).toDouble() );
if ( !returnAngle.isEmpty() )
target.setAttribute("draw:transform",returnAngle );
}
float x1 = orig.attribute( "x" ).toFloat();
float y1 = orig.attribute( "y" ).toFloat();
float x2 = size.attribute( "width" ).toFloat();
float y2 = size.attribute( "height" ).toFloat();
int type = 0;
if ( !linetype.isNull() )
type = linetype.attribute( "value" ).toInt();
y1 -= m_pageHeight * ( m_currentPage - 1 );
x2 += x1;
y2 += y1;
target.setAttribute( "draw:id", TQString::number( m_objectIndex ) );
TQString xpos1 = StyleFactory::toCM( orig.attribute( "x" ) );
TQString xpos2 = TQString( "%1cm" ).arg( KoUnit::toCM( x2 ) );
if ( type == 0 )
{
target.setAttribute( "svg:y1", TQString( "%1cm" ).arg( KoUnit::toCM( y2/2.0 ) ) );
target.setAttribute( "svg:y2", TQString( "%1cm" ).arg( KoUnit::toCM( y2/2.0 ) ) );
}
else if ( type == 1 )
{
target.setAttribute( "svg:y1", TQString( "%1cm" ).arg( KoUnit::toCM( y1 ) ) );
target.setAttribute( "svg:y2", TQString( "%1cm" ).arg( KoUnit::toCM( y2 ) ) );
xpos1 = TQString( "%1cm" ).arg( KoUnit::toCM( x1/2.0 ) );
xpos2 = xpos1;
}
else if ( type == 3 ) // from left bottom to right top
{
target.setAttribute( "svg:y1", TQString( "%1cm" ).arg( KoUnit::toCM( y2 ) ) );
target.setAttribute( "svg:y2", TQString( "%1cm" ).arg( KoUnit::toCM( y1 ) ) );
}
else // from left top to right bottom
{
target.setAttribute( "svg:y1", TQString( "%1cm" ).arg( KoUnit::toCM( y1 ) ) );
target.setAttribute( "svg:y2", TQString( "%1cm" ).arg( KoUnit::toCM( y2 ) ) );
}
target.setAttribute( "svg:x1", xpos1 );
target.setAttribute( "svg:x2", xpos2 );
TQString nameStr = name.attribute("objectName");
if( !nameStr.isEmpty() )
target.setAttribute( "draw:name", nameStr );
}
#include "ooimpressexport.moc"