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.
467 lines
18 KiB
467 lines
18 KiB
/* This file is part of the KDE project
|
|
Copyright (C) 2001 David Faure <faure@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 <config.h>
|
|
|
|
#include <kgenericfactory.h>
|
|
#include <KoStoreDevice.h>
|
|
#include <KoFilterChain.h>
|
|
#include <KoGlobal.h>
|
|
#include <kprkword.h>
|
|
#include <klocale.h>
|
|
#include <kdebug.h>
|
|
#include <tqsortedlist.h>
|
|
#include <tqcolor.h>
|
|
|
|
typedef KGenericFactory<KprKword, KoFilter> KprKwordFactory;
|
|
K_EXPORT_COMPONENT_FACTORY( libkprkword, KprKwordFactory( "kofficefilters" ) )
|
|
|
|
KprKword::KprKword(KoFilter *, const char *, const TQStringList&) :
|
|
KoFilter(),
|
|
outdoc( "DOC" )
|
|
{
|
|
}
|
|
|
|
// This filter can act as an import filter for KWord and as an export
|
|
// filter for KPresenter (isn't our architecture really nice ? :)
|
|
// This is why we use the file-to-file method, not a TQDomDoc one.
|
|
KoFilter::ConversionStatus KprKword::convert( const TQCString& from, const TQCString& to )
|
|
{
|
|
if(to!="application/x-kword" || from!="application/x-kpresenter")
|
|
return KoFilter::NotImplemented;
|
|
|
|
KoStoreDevice* inpdev = m_chain->storageFile( "root", KoStore::Read );
|
|
if ( !inpdev )
|
|
{
|
|
kdError(30502) << "Unable to open input stream" << endl;
|
|
return KoFilter::StorageCreationError;
|
|
}
|
|
|
|
inpdoc.setContent( inpdev );
|
|
|
|
|
|
outdoc.appendChild( outdoc.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) );
|
|
TQDomElement kwdoc = outdoc.createElement( "DOC" );
|
|
kwdoc.setAttribute( "editor", "KprKword converter" );
|
|
kwdoc.setAttribute( "mime", "application/x-kword" );
|
|
kwdoc.setAttribute( "syntaxVersion", 1 );
|
|
outdoc.appendChild( kwdoc );
|
|
|
|
TQDomElement paper = outdoc.createElement( "PAPER" );
|
|
kwdoc.appendChild( paper );
|
|
paper.setAttribute( "format", 1 ); // A4. How on earth could I know what the user really wants ? :)
|
|
paper.setAttribute( "width", 595 );
|
|
paper.setAttribute( "height", 841 );
|
|
TQDomElement borders = outdoc.createElement( "PAPERBORDERS" );
|
|
paper.appendChild( borders );
|
|
borders.setAttribute( "left", 28 );
|
|
borders.setAttribute( "top", 42 );
|
|
borders.setAttribute( "right", 28 );
|
|
borders.setAttribute( "bottom", 42 );
|
|
|
|
TQDomElement framesets = outdoc.createElement( "FRAMESETS" );
|
|
kwdoc.appendChild( framesets );
|
|
|
|
frameset = outdoc.createElement( "FRAMESET" );
|
|
framesets.appendChild( frameset );
|
|
frameset.setAttribute( "frameType", 1 ); // text
|
|
frameset.setAttribute( "frameInfo", 0 ); // body
|
|
TQDomElement frame = outdoc.createElement( "FRAME" );
|
|
frameset.appendChild( frame );
|
|
frame.setAttribute( "left", 28 );
|
|
frame.setAttribute( "top", 42 );
|
|
frame.setAttribute( "right", 566 );
|
|
frame.setAttribute( "bottom", 798 );
|
|
frame.setAttribute( "autoCreateNewFrame", 1 );
|
|
frame.setAttribute( "newFrameBehaviour", 0 );
|
|
|
|
titleStyleName = i18n("Slide Title");
|
|
|
|
// Convert !
|
|
|
|
convert();
|
|
|
|
// Create a style for the slide titles
|
|
|
|
TQDomElement styles = outdoc.createElement( "STYLES" );
|
|
kwdoc.appendChild( styles );
|
|
|
|
TQDomElement style = outdoc.createElement( "STYLE" );
|
|
styles.appendChild( style );
|
|
TQDomElement elem = outdoc.createElement( "NAME" );
|
|
style.appendChild( elem );
|
|
elem.setAttribute( "value", titleStyleName );
|
|
elem = outdoc.createElement( "FOLLOWING" );
|
|
style.appendChild( elem );
|
|
elem.setAttribute( "name", "Standard" ); // no i18n here!
|
|
|
|
TQDomElement counter = outdoc.createElement( "COUNTER" );
|
|
style.appendChild( counter );
|
|
counter.setAttribute( "type", 1 ); // numbered
|
|
counter.setAttribute( "depth", 0 );
|
|
counter.setAttribute( "start", 1 );
|
|
counter.setAttribute( "numberingtype", 1 ); // chapter
|
|
counter.setAttribute( "righttext", "." );
|
|
|
|
TQDomElement format = outdoc.createElement( "FORMAT" );
|
|
style.appendChild( format );
|
|
TQDomElement font = outdoc.createElement( "FONT" );
|
|
format.appendChild( font );
|
|
font.setAttribute( "name", titleFont ); // found when reading the first title
|
|
TQDomElement size = outdoc.createElement( "SIZE" );
|
|
format.appendChild( size );
|
|
size.setAttribute( "value", 24 );
|
|
TQDomElement bold = outdoc.createElement( "WEIGHT" );
|
|
format.appendChild( bold );
|
|
bold.setAttribute( "value", 75 );
|
|
|
|
// Create the standard style
|
|
style = outdoc.createElement( "STYLE" );
|
|
styles.appendChild( style );
|
|
elem = outdoc.createElement( "NAME" );
|
|
style.appendChild( elem );
|
|
elem.setAttribute( "value", "Standard" ); // no i18n here!
|
|
format = outdoc.createElement( "FORMAT" );
|
|
style.appendChild( format ); // empty format == use defaults
|
|
|
|
// Write output file
|
|
|
|
KoStoreDevice* out = m_chain->storageFile( "root", KoStore::Write );
|
|
if(!out) {
|
|
kdError(30502) << "Unable to open output file!" << endl;
|
|
return KoFilter::StorageCreationError;
|
|
}
|
|
TQCString cstring = outdoc.toCString(); // utf-8 already
|
|
out->writeBlock( cstring.data(), cstring.length() );
|
|
return KoFilter::OK;
|
|
}
|
|
|
|
// This class is used to sort the objects by y position
|
|
class KprObject {
|
|
public:
|
|
double y;
|
|
TQDomElement elem;
|
|
bool operator < ( const KprObject & c ) const
|
|
{
|
|
return y < c.y;
|
|
}
|
|
bool operator == ( const KprObject & c ) const
|
|
{
|
|
return y == c.y;
|
|
}
|
|
};
|
|
|
|
void KprKword::convert()
|
|
{
|
|
TQDomElement docElem = inpdoc.documentElement();
|
|
TQDomElement paper = docElem.namedItem( "PAPER" ).toElement();
|
|
int ptPageHeight = paper.attribute( "ptHeight" ).toInt();
|
|
|
|
TQDomElement objects = docElem.namedItem( "OBJECTS" ).toElement();
|
|
if ( objects.isNull() )
|
|
return;
|
|
|
|
TQSortedList< KprObject > objList;
|
|
objList.setAutoDelete( true );
|
|
|
|
TQDomNodeList lst = objects.elementsByTagName( "OBJECT" );
|
|
uint lstcount = lst.count();
|
|
for ( uint item = 0 ; item < lstcount ; ++item )
|
|
{
|
|
TQDomElement object = lst.item( item ).toElement();
|
|
if ( object.attribute( "type" ).toInt() == 4 ) // we only care about text objs
|
|
{
|
|
TQDomElement orig = object.namedItem( "ORIG" ).toElement();
|
|
if ( !orig.isNull() )
|
|
{
|
|
KprObject * obj = new KprObject;
|
|
obj->y = orig.attribute( "y" ).toDouble();
|
|
obj->elem = object;
|
|
objList.inSort( obj );
|
|
}
|
|
}
|
|
}
|
|
|
|
int curPage = -1;
|
|
//kdDebug() << "found " << objList.count() << " objects" << endl;
|
|
|
|
for ( TQPtrListIterator<KprObject> it(objList); it.current(); ++it )
|
|
{
|
|
TQDomElement elem = it.current()->elem;
|
|
// Detect the first object of each page
|
|
int page = int( it.current()->y / ptPageHeight );
|
|
bool isTitle = ( page > curPage );
|
|
//kdDebug() << "KprKword::convert y=" << it.current()->y << " ptPageHeight=" << ptPageHeight
|
|
// << " isTitle=" << isTitle << endl;
|
|
curPage = page;
|
|
|
|
TQDomElement textObj = elem.namedItem( "TEXTOBJ" ).toElement();
|
|
if (textObj.isNull())
|
|
continue;
|
|
// For each paragraph in this text object...
|
|
TQDomNodeList lst = textObj.elementsByTagName( "P" );
|
|
uint lstcount = lst.count();
|
|
for ( uint item = 0; item < lstcount ; ++item )
|
|
{
|
|
TQDomElement p = lst.item( item ).toElement();
|
|
|
|
// Create paragraph in KWord doc
|
|
TQDomElement parag = outdoc.createElement( "PARAGRAPH" );
|
|
frameset.appendChild( parag );
|
|
|
|
TQDomElement outFormatsElem = outdoc.createElement( "FORMATS" );
|
|
|
|
TQString text;
|
|
// For each text element in the paragraph...
|
|
TQDomElement textElem = p.firstChild().toElement();
|
|
|
|
TQDomElement counter = p.namedItem( "COUNTER" ).toElement();
|
|
TQDomElement indent=p.namedItem("INDENTS").toElement();
|
|
TQDomElement lineSpacing=p.namedItem( "LINESPACING" ).toElement();
|
|
TQDomElement offset=p.namedItem("OFFSETS").toElement();
|
|
TQDomElement leftBorder = p.namedItem( "LEFTBORDER" ).toElement();
|
|
TQDomElement rightBorder = p.namedItem( "RIGHTBORDER" ).toElement();
|
|
TQDomElement topBorder = p.namedItem( "TOPBORDER" ).toElement();
|
|
TQDomElement bottomBorder = p.namedItem( "BOTTOMBORDER" ).toElement();
|
|
|
|
TQDomElement shadow=p.namedItem("SHADOW").toElement();
|
|
|
|
for ( ; !textElem.isNull() ; textElem = textElem.nextSibling().toElement() )
|
|
{
|
|
int oldLen = text.length();
|
|
text += textElem.text();
|
|
//kdDebug() << "KprKword::convert text now " << text << endl;
|
|
TQDomElement outFormatElem = outdoc.createElement( "FORMAT" );
|
|
|
|
if ( textElem.attribute( "italic" ).toInt() )
|
|
{
|
|
TQDomElement e = outdoc.createElement("ITALIC");
|
|
e.setAttribute( "value", 1 );
|
|
outFormatElem.appendChild( e );
|
|
}
|
|
TQColor underlineColor;
|
|
if ( textElem.hasAttribute("underlinecolor" ))
|
|
{
|
|
underlineColor =TQColor(textElem.attribute("underlinecolor" ));
|
|
}
|
|
TQString underlineStyleLine;
|
|
if ( textElem.hasAttribute("underlinestyleline"))
|
|
{
|
|
underlineStyleLine = textElem.attribute("underlinestyleline");
|
|
}
|
|
if ( textElem.hasAttribute("underline" ))
|
|
{
|
|
TQDomElement e = outdoc.createElement("UNDERLINE");
|
|
TQString value = textElem.attribute( "underline" );
|
|
if ( value == "double" )
|
|
{
|
|
e.setAttribute( "value", "double" );
|
|
}
|
|
else if ( value == "single" )
|
|
{
|
|
e.setAttribute( "value", "double" );
|
|
}
|
|
else
|
|
{
|
|
e.setAttribute( "value", (bool)value.toInt() ? "1" :"0" );
|
|
}
|
|
if ( underlineColor.isValid())
|
|
{
|
|
e.setAttribute("underlinecolor", underlineColor.name());
|
|
}
|
|
if ( !underlineStyleLine.isEmpty() )
|
|
e.setAttribute("styleline", underlineStyleLine);
|
|
outFormatElem.appendChild( e );
|
|
|
|
}
|
|
|
|
TQString strikeOutStyleLine;
|
|
if ( textElem.hasAttribute("strikeoutstyleline"))
|
|
{
|
|
strikeOutStyleLine = textElem.attribute("strikeoutstyleline");
|
|
}
|
|
TQString strikeOutValue;
|
|
if ( textElem.hasAttribute("strikeOut"))
|
|
{
|
|
strikeOutValue = textElem.attribute("strikeOut");
|
|
}
|
|
|
|
if( !strikeOutValue.isEmpty())
|
|
{
|
|
TQDomElement e = outdoc.createElement("STRIKEOUT");
|
|
e.setAttribute( "value", strikeOutValue );
|
|
if ( !strikeOutStyleLine.isEmpty())
|
|
e.setAttribute("styleline", strikeOutStyleLine);
|
|
outFormatElem.appendChild( e );
|
|
}
|
|
/*if ( textElem.attribute( "bold" ).toInt() )
|
|
{
|
|
TQDomElement e = outdoc.createElement("WEIGHT");
|
|
e.setAttribute( "value", 75 );
|
|
outFormatElem.appendChild( e );
|
|
}*/ // doesn't look good
|
|
if ( titleFont.isEmpty() && isTitle )
|
|
titleFont = textElem.attribute( "family" );
|
|
|
|
// Family and point size are voluntarily NOT passed over.
|
|
if ( !textElem.attribute( "color" ).isEmpty())
|
|
{
|
|
TQColor col;
|
|
col.setNamedColor(textElem.attribute( "color" ));
|
|
TQDomElement e = outdoc.createElement("COLOR");
|
|
e.setAttribute( "red", col.red() );
|
|
e.setAttribute( "green", col.green() );
|
|
e.setAttribute( "blue", col.blue() );
|
|
outFormatElem.appendChild( e );
|
|
}
|
|
if ( !textElem.attribute("textbackcolor").isEmpty())
|
|
{
|
|
TQColor col;
|
|
col.setNamedColor(textElem.attribute( "textbackcolor" ));
|
|
TQDomElement e = outdoc.createElement("TEXTBACKGROUNDCOLOR");
|
|
e.setAttribute( "red", col.red() );
|
|
e.setAttribute( "green", col.green() );
|
|
e.setAttribute( "blue", col.blue() );
|
|
outFormatElem.appendChild( e );
|
|
}
|
|
|
|
//before VERTICAL align
|
|
double relative = 0;
|
|
if( textElem.attribute("relativetextsize").toDouble())
|
|
{
|
|
relative = textElem.attribute("relativetextsize").toDouble();
|
|
}
|
|
|
|
|
|
if( textElem.attribute("VERTALIGN").toInt())
|
|
{
|
|
TQDomElement e = outdoc.createElement("VERTALIGN");
|
|
e.setAttribute( "value", textElem.attribute("VERTALIGN").toInt() );
|
|
if ( relative != 0)
|
|
e.setAttribute( "relativetextsize", relative );
|
|
outFormatElem.appendChild( e );
|
|
}
|
|
|
|
if( textElem.hasAttribute("shadowtext"))
|
|
{
|
|
TQDomElement e = outdoc.createElement("SHADOWTEXT");
|
|
e.setAttribute( "value", textElem.attribute("shadowtext").toInt() );
|
|
outFormatElem.appendChild( e );
|
|
}
|
|
|
|
if( textElem.hasAttribute("offsetfrombaseline"))
|
|
{
|
|
TQDomElement e = outdoc.createElement("OFFSETFROMBASELINE");
|
|
e.setAttribute( "value", textElem.attribute("offsetfrombaseline").toInt() );
|
|
outFormatElem.appendChild( e );
|
|
}
|
|
|
|
if( textElem.hasAttribute("wordbyword"))
|
|
{
|
|
TQDomElement e = outdoc.createElement("WORDBYWORD");
|
|
e.setAttribute( "value", textElem.attribute("wordbyword").toInt() );
|
|
outFormatElem.appendChild( e );
|
|
}
|
|
|
|
if( textElem.hasAttribute("fontattribute"))
|
|
{
|
|
TQDomElement e = outdoc.createElement("FONTATTRIBUTE");
|
|
e.setAttribute( "value", textElem.attribute("fontattribute") );
|
|
outFormatElem.appendChild( e );
|
|
}
|
|
if( textElem.hasAttribute("language"))
|
|
{
|
|
TQDomElement e = outdoc.createElement("LANGUAGE");
|
|
e.setAttribute( "value", textElem.attribute("language") );
|
|
outFormatElem.appendChild( e );
|
|
}
|
|
if ( !outFormatElem.firstChild().isNull() )
|
|
{
|
|
outFormatElem.setAttribute( "id", 1 ); // normal exte
|
|
outFormatElem.setAttribute( "pos", oldLen );
|
|
outFormatElem.setAttribute( "len", text.length() - oldLen );
|
|
outFormatsElem.appendChild( outFormatElem );
|
|
}
|
|
|
|
} // end "for each text element"
|
|
|
|
// KPresenter seems to save a trailing space (bug!)
|
|
int len = text.length();
|
|
if ( len > 0 && text[ len - 1 ] == ' ' )
|
|
text.truncate( len - 1 );
|
|
|
|
TQDomElement outTextElem = outdoc.createElement( "TEXT" );
|
|
parag.appendChild( outTextElem );
|
|
outTextElem.appendChild( outdoc.createTextNode( text ) );
|
|
|
|
if ( !outFormatsElem.firstChild().isNull() ) // Do we have formats to save ?
|
|
parag.appendChild( outFormatsElem );
|
|
|
|
TQDomElement layoutElem = outdoc.createElement( "LAYOUT" );
|
|
parag.appendChild( layoutElem );
|
|
TQDomElement nameElem = outdoc.createElement( "NAME" );
|
|
layoutElem.appendChild( nameElem );
|
|
nameElem.setAttribute( "value", isTitle ? titleStyleName : TQString("Standard") );
|
|
TQDomElement align=outdoc.createElement("FLOW");
|
|
if(p.hasAttribute("align"))
|
|
{
|
|
switch(p.attribute( "align" ).toInt())
|
|
{
|
|
case 1:
|
|
align.setAttribute( "align","left");
|
|
break;
|
|
case 2:
|
|
align.setAttribute( "align","right");
|
|
break;
|
|
case 4:
|
|
align.setAttribute( "align","center");
|
|
break;
|
|
case 8:
|
|
align.setAttribute( "align","justify");
|
|
break;
|
|
}
|
|
}
|
|
if(!counter.isNull() )
|
|
layoutElem.appendChild( counter );
|
|
if(!indent.isNull())
|
|
layoutElem.appendChild( indent );
|
|
if(!lineSpacing.isNull())
|
|
layoutElem.appendChild( lineSpacing );
|
|
if(!offset.isNull())
|
|
layoutElem.appendChild( offset);
|
|
if(!leftBorder.isNull())
|
|
layoutElem.appendChild(leftBorder);
|
|
if(!rightBorder.isNull())
|
|
layoutElem.appendChild(rightBorder);
|
|
if(!topBorder.isNull())
|
|
layoutElem.appendChild(topBorder);
|
|
if(!bottomBorder.isNull())
|
|
layoutElem.appendChild(bottomBorder);
|
|
if(!align.isNull())
|
|
layoutElem.appendChild(align);
|
|
if(!shadow.isNull())
|
|
layoutElem.appendChild(shadow);
|
|
// Only the first parag of the top text object is set to the 'title' style
|
|
isTitle = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
#include <kprkword.moc>
|