~ubuntu-branches/ubuntu/breezy/koffice/breezy

« back to all changes in this revision

Viewing changes to filters/kword/rtf/import/rtfimport_dom.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Ben Burton
  • Date: 2004-05-09 11:33:00 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040509113300-vfrdadqsvjfuhn3b
Tags: 1:1.3.1-1
* New upstream bugfix release.
* Built against newer imagemagick (closes: #246623).
* Made koffice-libs/kformula recommend/depend on latex-xft-fonts, which
  provides mathematical fonts that the formula editor can use.  Also
  patched the kformula part to make these fonts the default.
* Changed kword menu hint from "WordProcessors" to "Word processors"
  (closes: #246209).
* Spellchecker configuration is now fixed (closes: #221256, #227568).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 <qdatetime.h>
 
15
#include <qtextcodec.h>
 
16
#include <qcolor.h>
 
17
 
 
18
#include <kdebug.h>
 
19
 
 
20
#include "rtfimport_dom.h"
 
21
 
 
22
/**
 
23
 * Escape the special XML characters and be careful to catch any unallowed control character
 
24
 */
 
25
QString CheckAndEscapeXmlText(const QString& strText)
 
26
{
 
27
    QString strReturn(strText);
 
28
    QChar 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
 
 
58
DomNode::DomNode()
 
59
{
 
60
    clear(0);
 
61
}
 
62
 
 
63
/**
 
64
 * Creates a new document.
 
65
 * @param doctype the document type (tag)
 
66
 */
 
67
DomNode::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
 
 
78
/**
 
79
 * Creates a new document node (no memory allocation).
 
80
 * @param level the document depth of the node
 
81
 */
 
82
void DomNode::clear( int level )
 
83
{
 
84
    str = QString::null;
 
85
    documentLevel       = level;
 
86
    hasChildren         = true;
 
87
    hasAttributes       = false;
 
88
}
 
89
 
 
90
/**
 
91
 * Adds a new node.
 
92
 * @param name the name of the new node (tag)
 
93
 */
 
94
void DomNode::addNode( const char *name )
 
95
{
 
96
    closeTag( true );
 
97
    str += " <";
 
98
    str += name;
 
99
    hasChildren = false;
 
100
    ++documentLevel;
 
101
}
 
102
 
 
103
/**
 
104
 * Adds a text node.
 
105
 * @param text the text to write into the document node
 
106
 */
 
107
void DomNode::addTextNode( const char *text, QTextCodec* codec )
 
108
{
 
109
    closeTag( false );
 
110
 
 
111
    if (!codec)
 
112
    {
 
113
        kdError(30515) << "No QTextCodec available!" << endl;
 
114
        return;
 
115
    }
 
116
 
 
117
    str += CheckAndEscapeXmlText(codec->toUnicode(text));
 
118
 
 
119
}
 
120
 
 
121
/**
 
122
 * Add border to existing frameset (see KWord DTD).
 
123
 */
 
124
void DomNode::addBorder( int id, const QColor &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
 
 
139
/**
 
140
 * Add color attributes to document node.
 
141
 * @param color the color
 
142
 */
 
143
void DomNode::addColor( const QColor &color )
 
144
{
 
145
    setAttribute( "red", color.red() );
 
146
    setAttribute( "green", color.green() );
 
147
    setAttribute( "blue", color.blue() );
 
148
}
 
149
 
 
150
/**
 
151
 * Add rectangle attributes to document node.
 
152
 */
 
153
void 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
 
 
161
/**
 
162
 * Add pixmap or clipart key.
 
163
 * @param dt date/time
 
164
 * @param filename the filename of the image
 
165
 * @param name the relative path to the image in the store (optional)
 
166
 */
 
167
void DomNode::addKey( const QDateTime& dt, const QString& filename, const QString& name )
 
168
{
 
169
    const QDate date ( dt.date() );
 
170
    const QTime 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
 
 
189
/**
 
190
 * Add frameset to document (see KWord DTD).
 
191
 */
 
192
void 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
 
 
202
/**
 
203
 * Add frame to existing frameset (see KWord DTD).
 
204
 */
 
205
void 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
 
 
218
/**
 
219
 * Sets a new attribute to a string value.
 
220
 */
 
221
void DomNode::setAttribute( const QString& attribute, const QString& value )
 
222
{
 
223
    str += ' ';
 
224
    str += attribute;
 
225
    str += '=';
 
226
    str += '"';
 
227
    str += value;
 
228
    str += '"';
 
229
    hasAttributes = true;
 
230
}
 
231
 
 
232
/**
 
233
 * Sets a new attribute to an integer value.
 
234
 */
 
235
void 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
 
 
242
/**
 
243
 * Sets a new attribute to a double value.
 
244
 */
 
245
void 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
 
 
252
/**
 
253
 * Closes a document node.
 
254
 * @param name the node (tag) to close
 
255
 */
 
256
void 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
 
 
277
/**
 
278
 * Closes the current XML tag (if open).
 
279
 * @param nl add a newline
 
280
 */
 
281
void 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
 
 
301
/**
 
302
 * Appends a child node.
 
303
 * @param child the node to append to this document node
 
304
 */
 
305
void DomNode::appendNode( const DomNode &child )
 
306
{
 
307
    const QString childStr ( child.toString() );
 
308
    closeTag( (childStr.length() >= 2 && (childStr[0] == '<' || childStr[1] == '<')) );
 
309
    str += childStr;
 
310
}
 
311
 
 
312
/**
 
313
 * Appends XML text to node
 
314
 */
 
315
void DomNode::append( const QString& _str)
 
316
{
 
317
    str += _str;
 
318
}
 
319
 
 
320
void DomNode::append( const QCString& cstr)
 
321
{
 
322
    str += QString::fromUtf8(cstr);
 
323
}
 
324
 
 
325
void DomNode::append( const char ch)
 
326
{
 
327
    str += ch;
 
328
}
 
329
 
 
330
/**
 
331
 * Returns true if node is empty.
 
332
 */
 
333
bool DomNode::isEmpty( void ) const
 
334
{
 
335
    return str.isEmpty();
 
336
}
 
337
 
 
338
/**
 
339
 * Returns the data of the document node.
 
340
 */
 
341
QString DomNode::toString( void ) const
 
342
{
 
343
    return str;
 
344
}