filters

rtfimport_dom.cpp

00001 /*
00002    This file is part of the KDE project
00003    Copyright (C) 2001 Ewald Snel <ewald@rambo.its.tudelft.nl>
00004    Copyright (C) 2001 Tomasz Grobelny <grotk@poczta.onet.pl>
00005 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License, or (at your option) any later version.
00010 */
00011 
00012 #include <stdio.h>
00013 
00014 #include <qdatetime.h>
00015 #include <qtextcodec.h>
00016 #include <qcolor.h>
00017 
00018 #include <kdebug.h>
00019 
00020 #include "rtfimport_dom.h"
00021 
00025 QString CheckAndEscapeXmlText(const QString& strText)
00026 {
00027     QString strReturn(strText);
00028     QChar ch;
00029 
00030     for (uint i=0; i<strReturn.length(); i++)
00031     {
00032         ch = strReturn[i];
00033         const int test = ch.unicode();
00034 
00035         // The i+= is for the additional characters
00036         if (test == 38) { strReturn.replace(i, 1, "&amp;"); i+=4; } // &
00037         else if (test == 60) { strReturn.replace(i, 1, "&lt;"); i+=3; } // <
00038         else if (test == 62) { strReturn.replace(i, 1, "&gt;"); i+=3; } // >
00039         else if (test == 34) { strReturn.replace(i, 1, "&quot;"); i+=5; } // "
00040         else if (test == 39) { strReturn.replace(i, 1, "&apos;"); i+=5; } // '
00041         else if (test >= 32) continue; // Normal character (from space on)
00042         else if ((test == 9) || (test == 10) || (test == 13) ) continue; // Allowed control characters: TAB, LF, CR
00043         else
00044         {
00045             // An unallowed control character:
00046             // - could be a bug in the RTF file
00047             // - could be not supported encoding.
00048             // In any case, we must replace this character.
00049             kdDebug(30515) << "Control character in XML stream: " << test << endl;
00050             strReturn.replace(i, 1, '?'); // Replacement character
00051         }
00052     }
00053 
00054     return strReturn;
00055 }
00056 
00057 
00058 DomNode::DomNode()
00059 {
00060     clear(0);
00061 }
00062 
00067 DomNode::DomNode( const char *doctype )
00068 {
00069     documentLevel   = 1;
00070     hasChildren     = false;
00071     hasAttributes   = false;
00072     str += "<?xml version = '1.0' encoding = 'UTF-8'?><!DOCTYPE " ;
00073     str += doctype;
00074     str += " >\n<";
00075     str += doctype;
00076 }
00077 
00082 void DomNode::clear( int level )
00083 {
00084     str = QString::null;
00085     documentLevel   = level;
00086     hasChildren     = true;
00087     hasAttributes   = false;
00088 }
00089 
00094 void DomNode::addNode( const char *name )
00095 {
00096     closeTag( true );
00097     str += " <";
00098     str += name;
00099     hasChildren = false;
00100     ++documentLevel;
00101 }
00102 
00107 void DomNode::addTextNode( const char *text, QTextCodec* codec )
00108 {
00109     closeTag( false );
00110 
00111     if (!codec)
00112     {
00113         kdError(30515) << "No QTextCodec available!" << endl;
00114         return;
00115     }
00116 
00117     str += CheckAndEscapeXmlText(codec->toUnicode(text));
00118 
00119 }
00120 
00124 void DomNode::addBorder( int id, const QColor &color, int style, double width )
00125 {
00126     char attr[16];
00127     sprintf( attr, "%cRed", id );
00128     setAttribute( attr, color.red() );
00129     sprintf( attr, "%cGreen", id );
00130     setAttribute( attr, color.green() );
00131     sprintf( attr, "%cBlue", id );
00132     setAttribute( attr, color.blue() );
00133     sprintf( attr, "%cStyle", id );
00134     setAttribute( attr, style );
00135     sprintf( attr, "%cWidth", id );
00136     setAttribute( attr, width );
00137 }
00138 
00143 void DomNode::addColor( const QColor &color )
00144 {
00145     setAttribute( "red", color.red() );
00146     setAttribute( "green", color.green() );
00147     setAttribute( "blue", color.blue() );
00148 }
00149 
00153 void DomNode::addRect( int left, int top, int right, int bottom )
00154 {
00155     setAttribute( "left", .05*left );
00156     setAttribute( "top", .05*top );
00157     setAttribute( "right", .05*right );
00158     setAttribute( "bottom", .05*bottom );
00159 }
00160 
00167 void DomNode::addKey( const QDateTime& dt, const QString& filename, const QString& name )
00168 {
00169     const QDate date ( dt.date() );
00170     const QTime time ( dt.time() );
00171 
00172     addNode( "KEY" );
00173     setAttribute( "filename", CheckAndEscapeXmlText(filename) );
00174     setAttribute( "year", date.year() );
00175     setAttribute( "month", date.month() );
00176     setAttribute( "day", date.day() );
00177     setAttribute( "hour", time.hour() );
00178     setAttribute( "minute", time.minute() );
00179     setAttribute( "second", time.second() );
00180     setAttribute( "msec", time.msec() );
00181 
00182     if (!name.isEmpty())
00183     {
00184         setAttribute( "name", CheckAndEscapeXmlText(name) );
00185     }
00186     closeNode( "KEY" );
00187 }
00188 
00192 void DomNode::addFrameSet( const char *name, int frameType, int frameInfo )
00193 {
00194     addNode( "FRAMESET" );
00195     setAttribute( "name", name );
00196     setAttribute( "frameType", frameType );
00197     setAttribute( "frameInfo", frameInfo );
00198     setAttribute( "removable", 0 );
00199     setAttribute( "visible", 1 );
00200 }
00201 
00205 void DomNode::addFrame( int left, int top, int right, int bottom,
00206             int autoCreateNewFrame, int newFrameBehaviour,
00207             int sheetSide )
00208 {
00209     addNode( "FRAME" );
00210     addRect( left, top, right, bottom );
00211     setAttribute( "runaround", 1 );
00212     setAttribute( "runaroundGap", 2 );
00213     setAttribute( "autoCreateNewFrame", autoCreateNewFrame );
00214     setAttribute( "newFrameBehaviour", newFrameBehaviour );
00215     setAttribute( "sheetSide", sheetSide );
00216 }
00217 
00221 void DomNode::setAttribute( const QString& attribute, const QString& value )
00222 {
00223     str += ' ';
00224     str += attribute;
00225     str += '=';
00226     str += '"';
00227     str += CheckAndEscapeXmlText( value );
00228     str += '"';
00229     hasAttributes = true;
00230 }
00231 
00235 void DomNode::setAttribute( const char *attribute, int value )
00236 {
00237     char strvalue[32];
00238     sprintf( strvalue, "%d", value );
00239     setAttribute( attribute, (const char *)strvalue );
00240 }
00241 
00245 void DomNode::setAttribute( const char *attribute, double value )
00246 {
00247     char strvalue[32];
00248     sprintf( strvalue, "%f", value );
00249     setAttribute( attribute, (const char *)strvalue );
00250 }
00251 
00256 void DomNode::closeNode( const char *name )
00257 {
00258     if (!hasChildren)
00259     {
00260         str += '/';
00261     }
00262     else
00263     {
00264         str += "</";
00265         str += name;
00266     }
00267     str += ">\n";
00268 
00269     --documentLevel;
00270     for (int i=documentLevel-1; i>0; i--)
00271     {
00272         str += ' ';
00273     }
00274     hasChildren = true;
00275 }
00276 
00281 void DomNode::closeTag( bool nl )
00282 {
00283     if (!hasChildren)
00284     {
00285         str += '>';
00286 
00287         if (nl)
00288         {
00289             str += '\n';
00290 
00291             for (int i=documentLevel-1; i>0; i--)
00292             {
00293                 str += ' ';
00294             }
00295         }
00296         hasChildren = true;
00297     }
00298     hasAttributes = false;
00299 }
00300 
00305 void DomNode::appendNode( const DomNode &child )
00306 {
00307     const QString childStr ( child.toString() );
00308     closeTag( (childStr.length() >= 2 && (childStr[0] == '<' || childStr[1] == '<')) );
00309     str += childStr;
00310 }
00311 
00315 void DomNode::append( const QString& _str)
00316 {
00317     str += _str;
00318 }
00319 
00320 void DomNode::append( const QCString& cstr)
00321 {
00322     str += QString::fromUtf8(cstr);
00323 }
00324 
00325 void DomNode::append( const char ch)
00326 {
00327     str += ch;
00328 }
00329 
00333 bool DomNode::isEmpty( void ) const
00334 {
00335     return str.isEmpty();
00336 }
00337 
00341 QString DomNode::toString( void ) const
00342 {
00343     return str;
00344 }
KDE Home | KDE Accessibility Home | Description of Access Keys