Subversion Repositories Scribus

Rev

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