Subversion Repositories Scribus

Rev

Rev 439 | Rev 940 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
411 Franz 1
/***************************************************************************
2
 *   Copyright (C) 2004 by Riku Leino                                      *
898 tsoots 3
 *   riku.leino@gmail.com                                                      *
411 Franz 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
        if ((name == "text:p") || (name == "text:h"))
52
        {
53
                append = true;
439 tsoots 54
                QString name = "";
55
                for (int i = 0; i < attrs.count(); ++i)
411 Franz 56
                {
439 tsoots 57
                        if (attrs.localName(i) == "text:style-name")
411 Franz 58
                        {
439 tsoots 59
                                name = attrs.value(i);
60
                                styleNames.push_back(attrs.value(i));
411 Franz 61
                        }
62
                }
439 tsoots 63
                if (!inList)
64
                {
65
                        pstyle = sreader->getStyle(name);
66
                        currentStyle = pstyle;
67
                }
68
                else
69
                {
70
                        gtStyle *tmp = sreader->getStyle(getName());
71
                        if ((tmp->getName()).find("default-style") != -1)
72
                                getStyle();
73
                        else
74
                                currentStyle = tmp;
75
                }
411 Franz 76
        }
77
        else if (name == "text:span")
78
        {
79
                inSpan = true;
80
                QString styleName = "";
81
                for (int i = 0; i < attrs.count(); ++i)
82
                {
83
                        if (attrs.localName(i) == "text:style-name")
84
                        {
85
                                currentStyle = sreader->getStyle(attrs.value(i));
86
                                styleName = attrs.value(i);
87
                                styleNames.push_back(styleName);
88
                        }
89
                }
90
                gtStyle *tmp = sreader->getStyle(getName());
91
                if ((tmp->getName()).find("default-style") != -1)
92
                        getStyle();
93
                else
94
                        currentStyle = tmp;
95
        }
96
        else if ((name == "text:unordered-list") || (name == "text:ordered-list"))
97
        {
98
                inList = true;
99
                ++listLevel;
100
                if (static_cast<int>(listIndex2.size()) < listLevel)
101
                        listIndex2.push_back(0);
102
                for (int i = 0; i < attrs.count(); ++i)
103
                {
104
                        if (attrs.localName(i) == "text:style-name")
105
                                currentList = attrs.value(i);
106
                }
107
                currentStyle = sreader->getStyle(QString(currentList + "_%1").arg(listLevel));
439 tsoots 108
                styleNames.clear();
109
                styleNames.push_back(QString(currentList + "_%1").arg(listLevel));
411 Franz 110
                if (name == "text:ordered-list")
111
                {
112
                        isOrdered = true;
113
                        isOrdered2.push_back(true);
114
                }
115
                else
116
                {
117
                        isOrdered = false;
118
                        isOrdered2.push_back(false);
119
                }
120
        }
121
        else if (name == "text:list-item")
122
        {
123
                if (isOrdered2[listLevel - 1])
124
                {
125
                        ++listIndex;
126
                        ++listIndex2[listLevel - 1];
127
                        if (listLevel == 1)
128
                                write(QString("%1. ").arg(listIndex2[listLevel - 1]));
129
                        else
130
                                write(QString("%1. ").arg(listIndex2[listLevel - 1]));
131
                }
132
                else
133
                        write("- ");
134
        }
135
        else if (name == "style:style")
136
        {
137
                QString sname = "";
138
                bool isTextStyle = false;
139
                for (int i = 0; i < attrs.count(); ++i)
140
                {
141
                        if (attrs.localName(i) == "style:name")
142
                                sname = attrs.value(i);
143
                        else if ((attrs.localName(i) == "style:family") && (attrs.value(i) == "text"));
144
                                isTextStyle = true;
145
                }
146
                if (isTextStyle)
147
                {
148
                        tName = sname;
149
                        inT = true;
150
                }
151
        }
152
        else if ((name == "style:properties") && (inT))
153
        {
154
                Properties p;
155
                for (int i = 0; i < attrs.count(); ++i)
156
                {
157
                        std::pair<QString, QString> pair(attrs.localName(i), attrs.value(i));
158
                        p.push_back(pair);
159
                }
160
                tmap[tName] = p;
161
        }
420 Franz 162
        else if (name == "text:s")
163
        {
164
                int count = 1;
165
                for (int i = 0; i < attrs.count(); ++i)
166
                {
167
                        if (attrs.localName(i) == "text:c")
168
                        {
169
                                bool ok = false;
170
                                int tmpcount = (attrs.value(i)).toInt(&ok);
171
                                if (ok)
172
                                        count = tmpcount;
173
                        }
174
                }
175
                for (int i = 0; i < count; ++i)
176
                        write(" ");
177
        }
411 Franz 178
        return true;
179
}
180
 
181
bool ContentReader::characters(const QString &ch)
182
{
183
        QString tmp = ch;
184
        tmp = tmp.remove("\n");
185
        tmp = tmp.remove(""); // Remove all OO.o hyphenation chars
186
        if (append)
187
                write(tmp);
188
        return true;
189
}
190
 
191
bool ContentReader::endElement(const QString&, const QString&, const QString &name)
192
{
193
        if ((name == "text:p") || (name == "text:h"))
194
        {
195
                write("\n");
196
                append = false;
439 tsoots 197
                if (inList)
411 Franz 198
                        styleNames.pop_back();
439 tsoots 199
                else
200
                        styleNames.clear();
411 Franz 201
        }
202
        else if (name == "text:span")
203
        {
204
                inSpan = false;
205
                currentStyle = pstyle;
206
                if (styleNames.size() != 0)
439 tsoots 207
                        styleNames.pop_back(); 
411 Franz 208
                currentStyle = sreader->getStyle(getName());
209
        }
210
        else if (name == "text:line-break")
211
                write(QChar(28));
212
        else if (name == "text:tab-stop")
213
                write("\t");
214
        else if ((name == "text:unordered-list") || (name == "text:ordered-list"))
215
        {
216
                --listLevel;
439 tsoots 217
                styleNames.clear();
411 Franz 218
                if (listLevel == 0)
219
                {
220
                        inList = false;
221
                        listIndex2.clear();
222
                }
223
                else
439 tsoots 224
                {
411 Franz 225
                        currentStyle = sreader->getStyle(QString(currentList + "_%1").arg(listLevel));
439 tsoots 226
                        styleNames.push_back(QString(currentList + "_%1").arg(listLevel));
227
                }
411 Franz 228
        }
229
        else if ((name == "style:style") && (inT))
230
        {
231
                inT = false;
232
                tName = "";
233
        }
234
        return true;
235
}
236
 
237
void ContentReader::write(const QString& text)
238
{
239
        if (importTextOnly)
240
                writer->append(text);
241
        else if (inSpan)
242
                writer->append(text, currentStyle, false);
243
        else
244
                writer->append(text, currentStyle);
245
        lastStyle = currentStyle;
246
}
247
 
248
void ContentReader::parse(QString fileName)
249
{
250
        sreader->parse(fileName);
251
        xmlSAXParseFile(cSAXHandler, fileName.ascii(), XML_PARSE_RECOVER);
252
}
253
 
254
xmlSAXHandler cSAXHandlerStruct = {
255
        NULL, // internalSubset,
256
        NULL, // isStandalone,
257
        NULL, // hasInternalSubset,
258
        NULL, // hasExternalSubset,
259
        NULL, // resolveEntity,
260
        NULL, // getEntity,
261
        NULL, // entityDecl,
262
        NULL, // notationDecl,
263
        NULL, // attributeDecl,
264
        NULL, // elementDecl,
265
        NULL, // unparsedEntityDecl,
266
        NULL, // setDocumentLocator,
267
        NULL, // startDocument,
268
        NULL, // endDocument,
269
        ContentReader::startElement,
270
        ContentReader::endElement,
271
        NULL, // reference,
272
        ContentReader::characters,
273
        NULL, // ignorableWhitespace,
274
        NULL, // processingInstruction,
275
        NULL, // comment,
276
        NULL, // warning,
277
        NULL, // error,
278
        NULL, // fatalError,
279
        NULL, // getParameterEntity,
280
        NULL, // cdata,
281
        NULL,
282
        1
283
#ifdef HAVE_XML26
284
        ,
285
        NULL,
286
        NULL,
287
        NULL,
288
        NULL
289
#endif
290
};
291
 
292
xmlSAXHandlerPtr cSAXHandler = &cSAXHandlerStruct;
293
 
294
void ContentReader::startElement(void *user_data, const xmlChar *fullname, const xmlChar ** atts)
295
{
296
        QString* name = new QString((const char*) fullname);
297
        name = new QString(name->lower());
298
        QXmlAttributes* attrs = new QXmlAttributes();
299
        if (atts)
300
        {
301
                for(const xmlChar** cur = atts; cur && *cur; cur += 2)
302
                        attrs->append(QString((char*)*cur), NULL, QString((char*)*cur), QString((char*)*(cur + 1)));
303
        }
304
        creader->startElement(NULL, NULL, *name, *attrs);
305
}
306
 
307
void ContentReader::characters(void *user_data, const xmlChar *ch, int len)
308
{
309
        QString chars = QString::fromUtf8((const char*) ch, len);
310
        creader->characters(chars);
311
}
312
 
313
void ContentReader::endElement(void *user_data, const xmlChar *name)
314
{
315
        QString *nname = new QString((const char*) name);
316
        nname = new QString(nname->lower());
317
        creader->endElement(NULL, NULL, *nname);
318
}
319
 
320
QString ContentReader::getName()
321
{
322
        QString s = "";
323
        for (uint i = 0; i < styleNames.size(); ++i)
324
                s += styleNames[i];
325
        return s;
326
}
327
 
328
void ContentReader::getStyle()
329
{
439 tsoots 330
        gtParagraphStyle* par = NULL;
331
        if (styleNames.size() == 0)
332
                par = dynamic_cast<gtParagraphStyle*>(sreader->getStyle("default-style"));
333
        else
334
                par = dynamic_cast<gtParagraphStyle*>(sreader->getStyle(styleNames[0]));
411 Franz 335
        gtParagraphStyle* tmp = new gtParagraphStyle(*par);
336
        for (uint i = 1; i < styleNames.size(); ++i)
337
        {
338
                Properties& p = tmap[styleNames[i]];
339
                for (uint j = 0; j < p.size(); ++j)
340
                        sreader->updateStyle(tmp, sreader->getStyle(styleNames[i - 1]), p[j].first, p[j].second);
341
        }
342
 
343
        currentStyle = tmp;
344
        sreader->setStyle(getName(), tmp);
345
}
346
 
347
ContentReader::~ContentReader()
348
{
349
        creader = NULL;
350
        delete defaultStyle;
351
}
352
 
353
#endif // HAVE_XML