diff options
Diffstat (limited to 'filters/kpresenter/kword/kprkword.cpp')
-rw-r--r-- | filters/kpresenter/kword/kprkword.cpp | 466 |
1 files changed, 466 insertions, 0 deletions
diff --git a/filters/kpresenter/kword/kprkword.cpp b/filters/kpresenter/kword/kprkword.cpp new file mode 100644 index 000000000..fc0f50cd0 --- /dev/null +++ b/filters/kpresenter/kword/kprkword.cpp @@ -0,0 +1,466 @@ +/* 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 <tdelocale.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> |