Subversion Repositories Scribus

Rev

Rev 2211 | Details | Compare with Previous | 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
        inSpan = false;
41
        listIndex = 0;
42
        listLevel = 0;
43
        currentList = "";
2211 tsoots 44
        currentListStyle = 0;
1593 tsoots 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;
54
                QString name = "";
55
                for (int i = 0; i < attrs.count(); ++i)
56
                {
57
                        if (attrs.localName(i) == "text:style-name")
58
                        {
59
                                name = attrs.value(i);
60
                                styleNames.push_back(attrs.value(i));
61
                        }
62
                }
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
                }
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
        }
2211 tsoots 96
        else if (name == "text:list")
1593 tsoots 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));
2211 tsoots 108
                currentListStyle = sreader->getList(currentList);
109
                currentListStyle->setLevel(listLevel);
1593 tsoots 110
                styleNames.clear();
111
                styleNames.push_back(QString(currentList + "_%1").arg(listLevel));
112
        }
113
        else if (name == "text:list-item")
114
        {
2211 tsoots 115
                currentListStyle->advance();
116
                write(currentListStyle->bullet());
1593 tsoots 117
        }
118
        else if (name == "style:style")
119
        {
120
                QString sname = "";
121
                bool isTextStyle = false;
122
                for (int i = 0; i < attrs.count(); ++i)
123
                {
124
                        if (attrs.localName(i) == "style:name")
125
                                sname = attrs.value(i);
3259 cbradney 126
                        else if ((attrs.localName(i) == "style:family") && (attrs.value(i) == "text"))
1593 tsoots 127
                                isTextStyle = true;
128
                }
129
                if (isTextStyle)
130
                {
131
                        tName = sname;
132
                        inT = true;
133
                }
134
        }
135
        else if ((name == "style:paragraph-properties" ||
136
                  name == "style:text-properties" ||
137
                  name == "style:list-level-properties") && (inT))
138
        {
139
                Properties p;
140
                for (int i = 0; i < attrs.count(); ++i)
141
                {
142
                        std::pair<QString, QString> pair(attrs.localName(i), attrs.value(i));
143
                        p.push_back(pair);
144
                }
145
                tmap[tName] = p;
146
        }
147
        else if (name == "text:s")
148
        {
149
                int count = 1;
150
                for (int i = 0; i < attrs.count(); ++i)
151
                {
152
                        if (attrs.localName(i) == "text:c")
153
                        {
154
                                bool ok = false;
155
                                int tmpcount = (attrs.value(i)).toInt(&ok);
156
                                if (ok)
157
                                        count = tmpcount;
158
                        }
159
                }
160
                for (int i = 0; i < count; ++i)
161
                        write(" ");
162
        }
163
        return true;
164
}
165
 
166
bool ContentReader::characters(const QString &ch)
167
{
168
        QString tmp = ch;
169
        tmp = tmp.remove("\n");
170
        tmp = tmp.remove(""); // Remove all OO.o hyphenation chars
171
        tmp = tmp.replace(QChar(160), QChar(29)); // replace OO.o nbsp with Scribus nbsp
172
        if (append)
173
                write(tmp);
174
        return true;
175
}
176
 
177
bool ContentReader::endElement(const QString&, const QString&, const QString &name)
178
{
179
        if ((name == "text:p") || (name == "text:h"))
180
        {
181
                write("\n");
182
                append = false;
183
                if (inList)
184
                        styleNames.pop_back();
185
                else
186
                        styleNames.clear();
187
        }
188
        else if (name == "text:span")
189
        {
190
                inSpan = false;
191
                currentStyle = pstyle;
192
                if (styleNames.size() != 0)
193
                        styleNames.pop_back(); 
194
                currentStyle = sreader->getStyle(getName());
195
        }
196
        else if (name == "text:line-break")
197
                write(QChar(28));
198
        else if (name == "text:tab")
199
                write("\t");
2211 tsoots 200
        else if (name == "text:list")
1593 tsoots 201
        {
202
                --listLevel;
203
                styleNames.clear();
204
                if (listLevel == 0)
205
                {
206
                        inList = false;
207
                        listIndex2.clear();
2211 tsoots 208
                        currentListStyle = 0;
1593 tsoots 209
                }
210
                else
211
                {
212
                        currentStyle = sreader->getStyle(QString(currentList + "_%1").arg(listLevel));
213
                        styleNames.push_back(QString(currentList + "_%1").arg(listLevel));
2211 tsoots 214
                        currentListStyle->resetLevel();
215
                        currentListStyle = sreader->getList(currentList);
216
                        currentListStyle->setLevel(listLevel);
1593 tsoots 217
                }
218
        }
219
        else if ((name == "style:style") && (inT))
220
        {
221
                inT = false;
222
                tName = "";
223
        }
224
        return true;
225
}
226
 
227
void ContentReader::write(const QString& text)
228
{
2211 tsoots 229
        qDebug(text);
1593 tsoots 230
        if (importTextOnly)
231
                writer->append(text);
232
        else if (inSpan)
233
                writer->append(text, currentStyle, false);
234
        else
235
                writer->append(text, currentStyle);
236
        lastStyle = currentStyle;
237
}
238
 
239
void ContentReader::parse(QString fileName)
240
{
241
        sreader->parse(fileName);
242
        xmlSAXParseFile(cSAXHandler, fileName.ascii(), 1);
243
}
244
 
245
xmlSAXHandler cSAXHandlerStruct = {
246
        NULL, // internalSubset,
247
        NULL, // isStandalone,
248
        NULL, // hasInternalSubset,
249
        NULL, // hasExternalSubset,
250
        NULL, // resolveEntity,
251
        NULL, // getEntity,
252
        NULL, // entityDecl,
253
        NULL, // notationDecl,
254
        NULL, // attributeDecl,
255
        NULL, // elementDecl,
256
        NULL, // unparsedEntityDecl,
257
        NULL, // setDocumentLocator,
258
        NULL, // startDocument,
259
        NULL, // endDocument,
260
        ContentReader::startElement,
261
        ContentReader::endElement,
262
        NULL, // reference,
263
        ContentReader::characters,
264
        NULL, // ignorableWhitespace,
265
        NULL, // processingInstruction,
266
        NULL, // comment,
267
        NULL, // warning,
268
        NULL, // error,
269
        NULL, // fatalError,
270
        NULL, // getParameterEntity,
271
        NULL, // cdata,
272
        NULL,
273
        1
274
#ifdef HAVE_XML26
275
        ,
276
        NULL,
277
        NULL,
278
        NULL,
279
        NULL
280
#endif
281
};
282
 
283
xmlSAXHandlerPtr cSAXHandler = &cSAXHandlerStruct;
284
 
285
void ContentReader::startElement(void*, const xmlChar *fullname, const xmlChar ** atts)
286
{
287
        QString* name = new QString((const char*) fullname);
288
        name = new QString(name->lower());
289
        QXmlAttributes* attrs = new QXmlAttributes();
290
        if (atts)
291
        {
292
                for(const xmlChar** cur = atts; cur && *cur; cur += 2)
293
                        attrs->append(QString((char*)*cur), NULL, QString((char*)*cur), QString((char*)*(cur + 1)));
294
        }
295
        creader->startElement(NULL, NULL, *name, *attrs);
296
}
297
 
298
void ContentReader::characters(void*, const xmlChar *ch, int len)
299
{
300
        QString chars = QString::fromUtf8((const char*) ch, len);
301
        creader->characters(chars);
302
}
303
 
304
void ContentReader::endElement(void*, const xmlChar *name)
305
{
306
        QString *nname = new QString((const char*) name);
307
        nname = new QString(nname->lower());
308
        creader->endElement(NULL, NULL, *nname);
309
}
310
 
311
QString ContentReader::getName()
312
{
313
        QString s = "";
314
        for (uint i = 0; i < styleNames.size(); ++i)
315
                s += styleNames[i];
316
        return s;
317
}
318
 
319
void ContentReader::getStyle()
320
{
321
        gtParagraphStyle* par = NULL;
322
        if (styleNames.size() == 0)
323
                par = dynamic_cast<gtParagraphStyle*>(sreader->getStyle("default-style"));
324
        else
325
                par = dynamic_cast<gtParagraphStyle*>(sreader->getStyle(styleNames[0]));
326
        gtParagraphStyle* tmp = new gtParagraphStyle(*par);
327
        for (uint i = 1; i < styleNames.size(); ++i)
328
        {
329
                Properties& p = tmap[styleNames[i]];
330
                for (uint j = 0; j < p.size(); ++j)
331
                        sreader->updateStyle(tmp, sreader->getStyle(styleNames[i - 1]), p[j].first, p[j].second);
332
        }
333
 
334
        currentStyle = tmp;
335
        sreader->setStyle(getName(), tmp);
336
}
337
 
338
ContentReader::~ContentReader()
339
{
340
        creader = NULL;
341
        delete defaultStyle;
342
}
343
 
344
#endif // HAVE_XML