Subversion Repositories Scribus

Rev

Rev 1598 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1593 tsoots 1
/***************************************************************************
2
 *   Copyright (C) 2004 by Riku Leino                                      *
3
 *   tsoots@gmail.com                                                      *
4
 *                                                                         *
5
 *   This program is free software; you can redistribute it and/or modify  *
6
 *   it under the terms of the GNU General Public License as published by  *
7
 *   the Free Software Foundation; either version 2 of the License, or     *
8
 *   (at your option) any later version.                                   *
9
 *                                                                         *
10
 *   This program is distributed in the hope that it will be useful,       *
11
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13
 *   GNU General Public License for more details.                          *
14
 *                                                                         *
15
 *   You should have received a copy of the GNU General Public License     *
16
 *   along with this program; if not, write to the                         *
17
 *   Free Software Foundation, Inc.,                                       *
18
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19
 ***************************************************************************/
20
 
21
#include "contentreader.h"
22
 
23
#ifdef HAVE_XML
24
 
25
ContentReader* ContentReader::creader = NULL;
26
 
27
extern xmlSAXHandlerPtr cSAXHandler;
28
 
29
ContentReader::ContentReader(QString documentName, StyleReader *s, gtWriter *w, bool textOnly)
30
{
31
        creader = this;
32
        docname = documentName;
33
        sreader = s;
34
        writer  = w;
35
        importTextOnly = textOnly;
36
        defaultStyle = NULL;
37
        currentStyle = NULL;
38
        append = false;
39
        inList = false;
40
        isOrdered = false;
41
        inSpan = false;
42
        listIndex = 0;
43
        listLevel = 0;
44
        currentList = "";
45
        inT = false;
46
        tName = "";
47
}
48
 
49
bool ContentReader::startElement(const QString&, const QString&, const QString &name, const QXmlAttributes &attrs)
50
{
51
        qDebug("Start element: " + name);
52
        if ((name == "text:p") || (name == "text:h"))
53
        {
54
                append = true;
55
                QString name = "";
56
                for (int i = 0; i < attrs.count(); ++i)
57
                {
58
                        if (attrs.localName(i) == "text:style-name")
59
                        {
60
                                name = attrs.value(i);
61
                                styleNames.push_back(attrs.value(i));
62
                        }
63
                }
64
                if (!inList)
65
                {
66
                        pstyle = sreader->getStyle(name);
67
                        currentStyle = pstyle;
68
                }
69
                else
70
                {
71
                        gtStyle *tmp = sreader->getStyle(getName());
72
                        if ((tmp->getName()).find("default-style") != -1)
73
                                getStyle();
74
                        else
75
                                currentStyle = tmp;
76
                }
77
        }
78
        else if (name == "text:span")
79
        {
80
                inSpan = true;
81
                QString styleName = "";
82
                for (int i = 0; i < attrs.count(); ++i)
83
                {
84
                        if (attrs.localName(i) == "text:style-name")
85
                        {
86
                                currentStyle = sreader->getStyle(attrs.value(i));
87
                                styleName = attrs.value(i);
88
                                styleNames.push_back(styleName);
89
                        }
90
                }
91
                gtStyle *tmp = sreader->getStyle(getName());
92
                if ((tmp->getName()).find("default-style") != -1)
93
                        getStyle();
94
                else
95
                        currentStyle = tmp;
96
        }
97
        else if ((name == "text:unordered-list") ||
98
                 (name == "text:ordered-list") ||
99
                 (name == "text:list"))
100
        {
101
                inList = true;
102
                ++listLevel;
103
                if (static_cast<int>(listIndex2.size()) < listLevel)
104
                        listIndex2.push_back(0);
105
                for (int i = 0; i < attrs.count(); ++i)
106
                {
107
                        if (attrs.localName(i) == "text:style-name")
108
                                currentList = attrs.value(i);
109
                }
110
                currentStyle = sreader->getStyle(QString(currentList + "_%1").arg(listLevel));
111
                styleNames.clear();
112
                styleNames.push_back(QString(currentList + "_%1").arg(listLevel));
113
                if (name == "text:ordered-list")
114
                {
115
                        isOrdered = true;
116
                        isOrdered2.push_back(true);
117
                        qDebug("isOrdered2.push_back(true);");
118
                }
119
                else
120
                {
121
                        isOrdered = false;
122
                        isOrdered2.push_back(false);
123
                        qDebug("isOrdered2.push_back(false);");
124
                }
125
        }
126
        else if (name == "text:list-item")
127
        {
128
                qDebug(QString("isOrdered2.size() == %1").arg(isOrdered2.size()));
129
                if (isOrdered2[listLevel - 1])
130
                {
131
                        ++listIndex;
132
                        ++listIndex2[listLevel - 1];
133
                        if (listLevel == 1)
134
                                write(QString("%1. ").arg(listIndex2[listLevel - 1]));
135
                        else
136
                                write(QString("%1. ").arg(listIndex2[listLevel - 1]));
137
                }
138
                else
139
                        write("- ");
140
        }
141
        else if (name == "style:style")
142
        {
143
                QString sname = "";
144
                bool isTextStyle = false;
145
                for (int i = 0; i < attrs.count(); ++i)
146
                {
147
                        if (attrs.localName(i) == "style:name")
148
                                sname = attrs.value(i);
149
                        else if ((attrs.localName(i) == "style:family") && (attrs.value(i) == "text"));
150
                                isTextStyle = true;
151
                }
152
                if (isTextStyle)
153
                {
154
                        tName = sname;
155
                        inT = true;
156
                }
157
        }
158
        else if ((name == "style:paragraph-properties" ||
159
                  name == "style:text-properties" ||
160
                  name == "style:list-level-properties") && (inT))
161
        {
162
                Properties p;
163
                for (int i = 0; i < attrs.count(); ++i)
164
                {
165
                        std::pair<QString, QString> pair(attrs.localName(i), attrs.value(i));
166
                        p.push_back(pair);
167
                }
168
                tmap[tName] = p;
169
        }
170
        else if (name == "text:s")
171
        {
172
                int count = 1;
173
                for (int i = 0; i < attrs.count(); ++i)
174
                {
175
                        if (attrs.localName(i) == "text:c")
176
                        {
177
                                bool ok = false;
178
                                int tmpcount = (attrs.value(i)).toInt(&ok);
179
                                if (ok)
180
                                        count = tmpcount;
181
                        }
182
                }
183
                for (int i = 0; i < count; ++i)
184
                        write(" ");
185
        }
186
        return true;
187
}
188
 
189
bool ContentReader::characters(const QString &ch)
190
{
191
        QString tmp = ch;
192
        tmp = tmp.remove("\n");
193
        tmp = tmp.remove(""); // Remove all OO.o hyphenation chars
194
        tmp = tmp.replace(QChar(160), QChar(29)); // replace OO.o nbsp with Scribus nbsp
195
        if (append)
196
                write(tmp);
197
        return true;
198
}
199
 
200
bool ContentReader::endElement(const QString&, const QString&, const QString &name)
201
{
202
        if ((name == "text:p") || (name == "text:h"))
203
        {
204
                write("\n");
205
                append = false;
206
                if (inList)
207
                        styleNames.pop_back();
208
                else
209
                        styleNames.clear();
210
        }
211
        else if (name == "text:span")
212
        {
213
                inSpan = false;
214
                currentStyle = pstyle;
215
                if (styleNames.size() != 0)
216
                        styleNames.pop_back(); 
217
                currentStyle = sreader->getStyle(getName());
218
        }
219
        else if (name == "text:line-break")
220
                write(QChar(28));
221
        else if (name == "text:tab")
222
                write("\t");
223
        else if ((name == "text:unordered-list") ||
224
                 (name == "text:ordered-list") ||
225
                 (name == "text:list"))
226
        {
227
                --listLevel;
228
                styleNames.clear();
229
                if (listLevel == 0)
230
                {
231
                        inList = false;
232
                        listIndex2.clear();
233
                }
234
                else
235
                {
236
                        currentStyle = sreader->getStyle(QString(currentList + "_%1").arg(listLevel));
237
                        styleNames.push_back(QString(currentList + "_%1").arg(listLevel));
238
                }
239
        }
240
        else if ((name == "style:style") && (inT))
241
        {
242
                inT = false;
243
                tName = "";
244
        }
245
        return true;
246
}
247
 
248
void ContentReader::write(const QString& text)
249
{
250
        if (importTextOnly)
251
                writer->append(text);
252
        else if (inSpan)
253
                writer->append(text, currentStyle, false);
254
        else
255
                writer->append(text, currentStyle);
256
        lastStyle = currentStyle;
257
}
258
 
259
void ContentReader::parse(QString fileName)
260
{
261
        sreader->parse(fileName);
262
        xmlSAXParseFile(cSAXHandler, fileName.ascii(), 1);
263
}
264
 
265
xmlSAXHandler cSAXHandlerStruct = {
266
        NULL, // internalSubset,
267
        NULL, // isStandalone,
268
        NULL, // hasInternalSubset,
269
        NULL, // hasExternalSubset,
270
        NULL, // resolveEntity,
271
        NULL, // getEntity,
272
        NULL, // entityDecl,
273
        NULL, // notationDecl,
274
        NULL, // attributeDecl,
275
        NULL, // elementDecl,
276
        NULL, // unparsedEntityDecl,
277
        NULL, // setDocumentLocator,
278
        NULL, // startDocument,
279
        NULL, // endDocument,
280
        ContentReader::startElement,
281
        ContentReader::endElement,
282
        NULL, // reference,
283
        ContentReader::characters,
284
        NULL, // ignorableWhitespace,
285
        NULL, // processingInstruction,
286
        NULL, // comment,
287
        NULL, // warning,
288
        NULL, // error,
289
        NULL, // fatalError,
290
        NULL, // getParameterEntity,
291
        NULL, // cdata,
292
        NULL,
293
        1
294
#ifdef HAVE_XML26
295
        ,
296
        NULL,
297
        NULL,
298
        NULL,
299
        NULL
300
#endif
301
};
302
 
303
xmlSAXHandlerPtr cSAXHandler = &cSAXHandlerStruct;
304
 
305
void ContentReader::startElement(void*, const xmlChar *fullname, const xmlChar ** atts)
306
{
307
        QString* name = new QString((const char*) fullname);
308
        name = new QString(name->lower());
309
        QXmlAttributes* attrs = new QXmlAttributes();
310
        if (atts)
311
        {
312
                for(const xmlChar** cur = atts; cur && *cur; cur += 2)
313
                        attrs->append(QString((char*)*cur), NULL, QString((char*)*cur), QString((char*)*(cur + 1)));
314
        }
315
        creader->startElement(NULL, NULL, *name, *attrs);
316
}
317
 
318
void ContentReader::characters(void*, const xmlChar *ch, int len)
319
{
320
        QString chars = QString::fromUtf8((const char*) ch, len);
321
        creader->characters(chars);
322
}
323
 
324
void ContentReader::endElement(void*, const xmlChar *name)
325
{
326
        QString *nname = new QString((const char*) name);
327
        nname = new QString(nname->lower());
328
        creader->endElement(NULL, NULL, *nname);
329
}
330
 
331
QString ContentReader::getName()
332
{
333
        QString s = "";
334
        for (uint i = 0; i < styleNames.size(); ++i)
335
                s += styleNames[i];
336
        return s;
337
}
338
 
339
void ContentReader::getStyle()
340
{
341
        gtParagraphStyle* par = NULL;
342
        if (styleNames.size() == 0)
343
                par = dynamic_cast<gtParagraphStyle*>(sreader->getStyle("default-style"));
344
        else
345
                par = dynamic_cast<gtParagraphStyle*>(sreader->getStyle(styleNames[0]));
346
        gtParagraphStyle* tmp = new gtParagraphStyle(*par);
347
        for (uint i = 1; i < styleNames.size(); ++i)
348
        {
349
                Properties& p = tmap[styleNames[i]];
350
                for (uint j = 0; j < p.size(); ++j)
351
                        sreader->updateStyle(tmp, sreader->getStyle(styleNames[i - 1]), p[j].first, p[j].second);
352
        }
353
 
354
        currentStyle = tmp;
355
        sreader->setStyle(getName(), tmp);
356
}
357
 
358
ContentReader::~ContentReader()
359
{
360
        creader = NULL;
361
        delete defaultStyle;
362
}
363
 
364
#endif // HAVE_XML