rtfimport_dom.cpp
1/*
2 This file is part of the KDE project
3 Copyright (C) 2001 Ewald Snel <ewald@rambo.its.tudelft.nl>
4 Copyright (C) 2001 Tomasz Grobelny <grotk@poczta.onet.pl>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10*/
11
12#include <stdio.h>
13
14#include <tqdatetime.h>
15#include <tqtextcodec.h>
16#include <tqcolor.h>
17
18#include <kdebug.h>
19
20#include "rtfimport_dom.h"
21
25TQString CheckAndEscapeXmlText(const TQString& strText)
26{
27 TQString strReturn(strText);
28 TQChar ch;
29
30 for (uint i=0; i<strReturn.length(); i++)
31 {
32 ch = strReturn[i];
33 const int test = ch.unicode();
34
35 // The i+= is for the additional characters
36 if (test == 38) { strReturn.replace(i, 1, "&amp;"); i+=4; } // &
37 else if (test == 60) { strReturn.replace(i, 1, "&lt;"); i+=3; } // <
38 else if (test == 62) { strReturn.replace(i, 1, "&gt;"); i+=3; } // >
39 else if (test == 34) { strReturn.replace(i, 1, "&quot;"); i+=5; } // "
40 else if (test == 39) { strReturn.replace(i, 1, "&apos;"); i+=5; } // '
41 else if (test >= 32) continue; // Normal character (from space on)
42 else if ((test == 9) || (test == 10) || (test == 13) ) continue; // Allowed control characters: TAB, LF, CR
43 else
44 {
45 // An unallowed control character:
46 // - could be a bug in the RTF file
47 // - could be not supported encoding.
48 // In any case, we must replace this character.
49 kdDebug(30515) << "Control character in XML stream: " << test << endl;
50 strReturn.replace(i, 1, '?'); // Replacement character
51 }
52 }
53
54 return strReturn;
55}
56
57
58DomNode::DomNode()
59{
60 clear(0);
61}
62
67DomNode::DomNode( const char *doctype )
68{
69 documentLevel = 1;
70 hasChildren = false;
71 hasAttributes = false;
72 str += "<?xml version = '1.0' encoding = 'UTF-8'?><!DOCTYPE " ;
73 str += doctype;
74 str += " >\n<";
75 str += doctype;
76}
77
82void DomNode::clear( int level )
83{
84 str = TQString();
85 documentLevel = level;
86 hasChildren = true;
87 hasAttributes = false;
88}
89
94void DomNode::addNode( const char *name )
95{
96 closeTag( true );
97 str += " <";
98 str += name;
99 hasChildren = false;
100 ++documentLevel;
101}
102
107void DomNode::addTextNode( const char *text, TQTextCodec* codec )
108{
109 closeTag( false );
110
111 if (!codec)
112 {
113 kdError(30515) << "No TQTextCodec available!" << endl;
114 return;
115 }
116
117 str += CheckAndEscapeXmlText(codec->toUnicode(text));
118
119}
120
124void DomNode::addBorder( int id, const TQColor &color, int style, double width )
125{
126 char attr[16];
127 sprintf( attr, "%cRed", id );
128 setAttribute( attr, color.red() );
129 sprintf( attr, "%cGreen", id );
130 setAttribute( attr, color.green() );
131 sprintf( attr, "%cBlue", id );
132 setAttribute( attr, color.blue() );
133 sprintf( attr, "%cStyle", id );
134 setAttribute( attr, style );
135 sprintf( attr, "%cWidth", id );
136 setAttribute( attr, width );
137}
138
143void DomNode::addColor( const TQColor &color )
144{
145 setAttribute( "red", color.red() );
146 setAttribute( "green", color.green() );
147 setAttribute( "blue", color.blue() );
148}
149
153void DomNode::addRect( int left, int top, int right, int bottom )
154{
155 setAttribute( "left", .05*left );
156 setAttribute( "top", .05*top );
157 setAttribute( "right", .05*right );
158 setAttribute( "bottom", .05*bottom );
159}
160
167void DomNode::addKey( const TQDateTime& dt, const TQString& filename, const TQString& name )
168{
169 const TQDate date ( dt.date() );
170 const TQTime time ( dt.time() );
171
172 addNode( "KEY" );
173 setAttribute( "filename", CheckAndEscapeXmlText(filename) );
174 setAttribute( "year", date.year() );
175 setAttribute( "month", date.month() );
176 setAttribute( "day", date.day() );
177 setAttribute( "hour", time.hour() );
178 setAttribute( "minute", time.minute() );
179 setAttribute( "second", time.second() );
180 setAttribute( "msec", time.msec() );
181
182 if (!name.isEmpty())
183 {
184 setAttribute( "name", CheckAndEscapeXmlText(name) );
185 }
186 closeNode( "KEY" );
187}
188
192void DomNode::addFrameSet( const char *name, int frameType, int frameInfo )
193{
194 addNode( "FRAMESET" );
195 setAttribute( "name", name );
196 setAttribute( "frameType", frameType );
197 setAttribute( "frameInfo", frameInfo );
198 setAttribute( "removable", 0 );
199 setAttribute( "visible", 1 );
200}
201
205void DomNode::addFrame( int left, int top, int right, int bottom,
206 int autoCreateNewFrame, int newFrameBehaviour,
207 int sheetSide )
208{
209 addNode( "FRAME" );
210 addRect( left, top, right, bottom );
211 setAttribute( "runaround", 1 );
212 setAttribute( "runaroundGap", 2 );
213 setAttribute( "autoCreateNewFrame", autoCreateNewFrame );
214 setAttribute( "newFrameBehaviour", newFrameBehaviour );
215 setAttribute( "sheetSide", sheetSide );
216}
217
221void DomNode::setAttribute( const TQString& attribute, const TQString& value )
222{
223 str += ' ';
224 str += attribute;
225 str += '=';
226 str += '"';
227 str += CheckAndEscapeXmlText( value );
228 str += '"';
229 hasAttributes = true;
230}
231
235void DomNode::setAttribute( const char *attribute, int value )
236{
237 char strvalue[32];
238 sprintf( strvalue, "%d", value );
239 setAttribute( attribute, (const char *)strvalue );
240}
241
245void DomNode::setAttribute( const char *attribute, double value )
246{
247 char strvalue[32];
248 sprintf( strvalue, "%f", value );
249 setAttribute( attribute, (const char *)strvalue );
250}
251
256void DomNode::closeNode( const char *name )
257{
258 if (!hasChildren)
259 {
260 str += '/';
261 }
262 else
263 {
264 str += "</";
265 str += name;
266 }
267 str += ">\n";
268
269 --documentLevel;
270 for (int i=documentLevel-1; i>0; i--)
271 {
272 str += ' ';
273 }
274 hasChildren = true;
275}
276
281void DomNode::closeTag( bool nl )
282{
283 if (!hasChildren)
284 {
285 str += '>';
286
287 if (nl)
288 {
289 str += '\n';
290
291 for (int i=documentLevel-1; i>0; i--)
292 {
293 str += ' ';
294 }
295 }
296 hasChildren = true;
297 }
298 hasAttributes = false;
299}
300
305void DomNode::appendNode( const DomNode &child )
306{
307 const TQString childStr ( child.toString() );
308 closeTag( (childStr.length() >= 2 && (childStr[0] == '<' || childStr[1] == '<')) );
309 str += childStr;
310}
311
315void DomNode::append( const TQString& _str)
316{
317 str += _str;
318}
319
320void DomNode::append( const TQCString& cstr)
321{
322 str += TQString::fromUtf8(cstr);
323}
324
325void DomNode::append( const char ch)
326{
327 str += ch;
328}
329
333bool DomNode::isEmpty( void ) const
334{
335 return str.isEmpty();
336}
337
341TQString DomNode::toString( void ) const
342{
343 return str;
344}