Subversion Repositories Scribus

Rev

Rev 18084 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4430 cbradney 1
/*
2
For general Scribus (>=1.3.2) copyright and licensing information please refer
3
to the COPYING file provided with the program. Following this notice may exist
4
a copyright and/or license notice that predates the release of Scribus 1.3.2
5
for which a new license (GPL+exception) is in place.
6
*/
1579 tsoots 7
/***************************************************************************
8
 *   Copyright (C) 2004 by Riku Leino                                      *
9
 *   tsoots@gmail.com                                                      *
10
 *                                                                         *
11
 *   This program is free software; you can redistribute it and/or modify  *
12
 *   it under the terms of the GNU General Public License as published by  *
13
 *   the Free Software Foundation; either version 2 of the License, or     *
14
 *   (at your option) any later version.                                   *
15
 *                                                                         *
16
 *   This program is distributed in the hope that it will be useful,       *
17
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
18
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
19
 *   GNU General Public License for more details.                          *
20
 *                                                                         *
21
 *   You should have received a copy of the GNU General Public License     *
22
 *   along with this program; if not, write to the                         *
23
 *   Free Software Foundation, Inc.,                                       *
18122 mrdocs 24
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.             *
1579 tsoots 25
 ***************************************************************************/
26
 
10223 cbradney 27
#include <QGlobalStatic>
9535 fschmid 28
#include <QByteArray>
1579 tsoots 29
#include "contentreader.h"
7277 jghali 30
#include "scribusstructs.h"
13805 jghali 31
#include "gtwriter.h"
32
#include "gtstyle.h"
33
#include "gtparagraphstyle.h"
34
#include "stylereader.h"
1579 tsoots 35
 
36
ContentReader* ContentReader::creader = NULL;
37
 
38
extern xmlSAXHandlerPtr cSAXHandler;
39
 
40
ContentReader::ContentReader(QString documentName, StyleReader *s, gtWriter *w, bool textOnly)
41
{
42
        creader = this;
43
        docname = documentName;
44
        sreader = s;
45
        writer  = w;
46
        importTextOnly = textOnly;
47
        defaultStyle = NULL;
48
        currentStyle = NULL;
49
        inList = false;
13814 jghali 50
        inAnnotation = false;
1579 tsoots 51
        inSpan = false;
12143 jghali 52
        append = 0;
1579 tsoots 53
        listIndex = 0;
54
        listLevel = 0;
55
        currentList = "";
2212 tsoots 56
        currentListStyle = 0;
1579 tsoots 57
        inT = false;
58
        tName = "";
59
}
60
 
61
bool ContentReader::startElement(const QString&, const QString&, const QString &name, const QXmlAttributes &attrs)
62
{
63
        if ((name == "text:p") || (name == "text:h"))
64
        {
12143 jghali 65
                ++append;
1579 tsoots 66
                QString name = "";
67
                for (int i = 0; i < attrs.count(); ++i)
68
                {
69
                        if (attrs.localName(i) == "text:style-name")
70
                        {
71
                                name = attrs.value(i);
72
                                styleNames.push_back(attrs.value(i));
73
                        }
74
                }
75
                if (!inList)
76
                {
77
                        pstyle = sreader->getStyle(name);
78
                        currentStyle = pstyle;
79
                }
80
                else
81
                {
82
                        gtStyle *tmp = sreader->getStyle(getName());
10430 cbradney 83
                        if ((tmp->getName()).indexOf("default-style") != -1)
1579 tsoots 84
                                getStyle();
85
                        else
86
                                currentStyle = tmp;
87
                }
88
        }
89
        else if (name == "text:span")
90
        {
91
                inSpan = true;
92
                QString styleName = "";
93
                for (int i = 0; i < attrs.count(); ++i)
94
                {
95
                        if (attrs.localName(i) == "text:style-name")
96
                        {
97
                                currentStyle = sreader->getStyle(attrs.value(i));
98
                                styleName = attrs.value(i);
99
                                styleNames.push_back(styleName);
100
                        }
101
                }
102
                gtStyle *tmp = sreader->getStyle(getName());
10430 cbradney 103
                if ((tmp->getName()).indexOf("default-style") != -1)
1579 tsoots 104
                        getStyle();
105
                else
106
                        currentStyle = tmp;
107
        }
2212 tsoots 108
        else if (name == "text:list")
1579 tsoots 109
        {
110
                inList = true;
111
                ++listLevel;
112
                if (static_cast<int>(listIndex2.size()) < listLevel)
113
                        listIndex2.push_back(0);
114
                for (int i = 0; i < attrs.count(); ++i)
115
                {
116
                        if (attrs.localName(i) == "text:style-name")
18084 jghali 117
                        {
1579 tsoots 118
                                currentList = attrs.value(i);
18084 jghali 119
                        }
1579 tsoots 120
                }
121
                currentStyle = sreader->getStyle(QString(currentList + "_%1").arg(listLevel));
2212 tsoots 122
                currentListStyle = sreader->getList(currentList);
13008 jghali 123
                if (currentListStyle)
124
                        currentListStyle->setLevel(listLevel);
1579 tsoots 125
                styleNames.clear();
126
                styleNames.push_back(QString(currentList + "_%1").arg(listLevel));
127
        }
128
        else if (name == "text:list-item")
129
        {
13008 jghali 130
                if (currentListStyle)
131
                {
132
                        currentListStyle->advance();
18047 craig 133
                        //write(currentListStyle->bullet());
13008 jghali 134
                }
1579 tsoots 135
        }
13814 jghali 136
        else if (name == "office:annotation")
137
                inAnnotation = true;
10574 jghali 138
        else if (name == "text:note")
18084 jghali 139
                writer->inNote = true;
10574 jghali 140
        else if (name == "text:note-body")
18084 jghali 141
                writer->inNoteBody = true;
1579 tsoots 142
        else if (name == "style:style")
143
        {
144
                QString sname = "";
145
                bool isTextStyle = false;
146
                for (int i = 0; i < attrs.count(); ++i)
147
                {
148
                        if (attrs.localName(i) == "style:name")
149
                                sname = attrs.value(i);
3258 cbradney 150
                        else if ((attrs.localName(i) == "style:family") && (attrs.value(i) == "text"))
1579 tsoots 151
                                isTextStyle = true;
152
                }
153
                if (isTextStyle)
154
                {
155
                        tName = sname;
156
                        inT = true;
157
                }
158
        }
159
        else if ((name == "style:paragraph-properties" ||
160
                  name == "style:text-properties" ||
161
                  name == "style:list-level-properties") && (inT))
162
        {
163
                Properties p;
164
                for (int i = 0; i < attrs.count(); ++i)
165
                {
166
                        std::pair<QString, QString> pair(attrs.localName(i), attrs.value(i));
167
                        p.push_back(pair);
168
                }
169
                tmap[tName] = p;
170
        }
171
        else if (name == "text:s")
172
        {
173
                int count = 1;
174
                for (int i = 0; i < attrs.count(); ++i)
175
                {
176
                        if (attrs.localName(i) == "text:c")
177
                        {
178
                                bool ok = false;
179
                                int tmpcount = (attrs.value(i)).toInt(&ok);
180
                                if (ok)
181
                                        count = tmpcount;
182
                        }
183
                }
184
                for (int i = 0; i < count; ++i)
185
                        write(" ");
186
        }
187
        return true;
188
}
189
 
190
bool ContentReader::characters(const QString &ch)
191
{
192
        QString tmp = ch;
193
        tmp = tmp.remove("\n");
194
        tmp = tmp.remove(""); // Remove all OO.o hyphenation chars
12874 jghali 195
        // Unneeded as scribus now also use standard unicode non-breakable space
196
        // tmp = tmp.replace(QChar(160), SpecialChars::NBSPACE); // replace OO.o nbsp with Scribus nbsp
12143 jghali 197
        if (append > 0)
1579 tsoots 198
                write(tmp);
199
        return true;
200
}
201
 
202
bool ContentReader::endElement(const QString&, const QString&, const QString &name)
203
{
204
        if ((name == "text:p") || (name == "text:h"))
205
        {
12620 pierre 206
//              qDebug("TPTH");
1579 tsoots 207
                write("\n");
12143 jghali 208
                --append;
18084 jghali 209
                if (inList || inAnnotation)
12620 pierre 210
                {
211
                        if(static_cast<int>(styleNames.size()) > 0)
212
                                styleNames.pop_back();
213
                }
1579 tsoots 214
                else
215
                        styleNames.clear();
216
        }
217
        else if (name == "text:span")
218
        {
12620 pierre 219
//              qDebug("TS");
1579 tsoots 220
                inSpan = false;
221
                currentStyle = pstyle;
222
                if (styleNames.size() != 0)
223
                        styleNames.pop_back(); 
224
                currentStyle = sreader->getStyle(getName());
225
        }
13814 jghali 226
        else if (name == "office:annotation")
227
        {
228
                inAnnotation = false;
229
        }
10574 jghali 230
        else if (name == "text:note")
12620 pierre 231
        {
232
//              qDebug("TN");
18084 jghali 233
                writer->inNote = false;
12620 pierre 234
        }
10574 jghali 235
        else if (name == "text:note-body")
12620 pierre 236
        {
237
//              qDebug("TNB");
18084 jghali 238
                write(SpecialChars::OBJECT);
239
                writer->inNoteBody = false;
12620 pierre 240
        }
1579 tsoots 241
        else if (name == "text:line-break")
12620 pierre 242
        {
243
//              qDebug("TLB");
10796 avox 244
                write(SpecialChars::LINEBREAK);
12620 pierre 245
        }
1579 tsoots 246
        else if (name == "text:tab")
12620 pierre 247
        {
248
//              qDebug("TT");
1579 tsoots 249
                write("\t");
12620 pierre 250
        }
2212 tsoots 251
        else if (name == "text:list")
1579 tsoots 252
        {
12620 pierre 253
//              qDebug("TL");
1579 tsoots 254
                --listLevel;
255
                styleNames.clear();
256
                if (listLevel == 0)
257
                {
258
                        inList = false;
259
                        listIndex2.clear();
2212 tsoots 260
                        currentListStyle = 0;
1579 tsoots 261
                }
262
                else
263
                {
264
                        currentStyle = sreader->getStyle(QString(currentList + "_%1").arg(listLevel));
265
                        styleNames.push_back(QString(currentList + "_%1").arg(listLevel));
13008 jghali 266
                        if (currentListStyle)
267
                                currentListStyle->resetLevel();
2212 tsoots 268
                        currentListStyle = sreader->getList(currentList);
13008 jghali 269
                        if (currentListStyle)
270
                                currentListStyle->setLevel(listLevel);
1579 tsoots 271
                }
272
        }
273
        else if ((name == "style:style") && (inT))
274
        {
12620 pierre 275
//              qDebug("SS");
1579 tsoots 276
                inT = false;
277
                tName = "";
278
        }
279
        return true;
280
}
281
 
282
void ContentReader::write(const QString& text)
283
{
18084 jghali 284
        if (!inAnnotation)
10574 jghali 285
        {
286
                if (importTextOnly)
12895 jghali 287
                        writer->appendUnstyled(text);
10574 jghali 288
                else if (inSpan)
289
                        writer->append(text, currentStyle, false);
290
                else
291
                        writer->append(text, currentStyle);
292
        }
1579 tsoots 293
        lastStyle = currentStyle;
294
}
295
 
296
void ContentReader::parse(QString fileName)
297
{
298
        sreader->parse(fileName);
7277 jghali 299
#if defined(_WIN32)
16577 craig 300
        QString fname = QDir::toNativeSeparators(fileName);
10723 jghali 301
        QByteArray fn = (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based) ? fname.toUtf8() : fname.toLocal8Bit();
7277 jghali 302
#else
10493 fschmid 303
        QByteArray fn(fileName.toLocal8Bit());
7277 jghali 304
#endif
305
        xmlSAXParseFile(cSAXHandler, fn.data(), 1);
1579 tsoots 306
}
307
 
308
xmlSAXHandler cSAXHandlerStruct = {
309
        NULL, // internalSubset,
310
        NULL, // isStandalone,
311
        NULL, // hasInternalSubset,
312
        NULL, // hasExternalSubset,
313
        NULL, // resolveEntity,
314
        NULL, // getEntity,
315
        NULL, // entityDecl,
316
        NULL, // notationDecl,
317
        NULL, // attributeDecl,
318
        NULL, // elementDecl,
319
        NULL, // unparsedEntityDecl,
320
        NULL, // setDocumentLocator,
321
        NULL, // startDocument,
322
        NULL, // endDocument,
323
        ContentReader::startElement,
324
        ContentReader::endElement,
325
        NULL, // reference,
326
        ContentReader::characters,
327
        NULL, // ignorableWhitespace,
328
        NULL, // processingInstruction,
329
        NULL, // comment,
330
        NULL, // warning,
331
        NULL, // error,
332
        NULL, // fatalError,
333
        NULL, // getParameterEntity,
334
        NULL, // cdata,
335
        NULL,
336
        1
337
#ifdef HAVE_XML26
338
        ,
339
        NULL,
340
        NULL,
341
        NULL,
342
        NULL
343
#endif
344
};
345
 
346
xmlSAXHandlerPtr cSAXHandler = &cSAXHandlerStruct;
347
 
348
void ContentReader::startElement(void*, const xmlChar *fullname, const xmlChar ** atts)
349
{
12147 jghali 350
        QString name(QString((const char*) fullname).toLower());
351
        QXmlAttributes attrs;
1579 tsoots 352
        if (atts)
353
        {
354
                for(const xmlChar** cur = atts; cur && *cur; cur += 2)
12147 jghali 355
                        attrs.append(QString((char*)*cur), NULL, QString((char*)*cur), QString((char*)*(cur + 1)));
1579 tsoots 356
        }
12147 jghali 357
        creader->startElement(NULL, NULL, name, attrs);
1579 tsoots 358
}
359
 
360
void ContentReader::characters(void*, const xmlChar *ch, int len)
361
{
362
        QString chars = QString::fromUtf8((const char*) ch, len);
363
        creader->characters(chars);
364
}
365
 
366
void ContentReader::endElement(void*, const xmlChar *name)
367
{
12147 jghali 368
        QString nname(QString((const char*) name).toLower());
369
        creader->endElement(NULL, NULL, nname);
1579 tsoots 370
}
371
 
372
QString ContentReader::getName()
373
{
374
        QString s = "";
375
        for (uint i = 0; i < styleNames.size(); ++i)
376
                s += styleNames[i];
377
        return s;
378
}
379
 
380
void ContentReader::getStyle()
381
{
11935 jghali 382
        gtStyle *style = NULL, *tmp = NULL;
1579 tsoots 383
        if (styleNames.size() == 0)
11935 jghali 384
                style = sreader->getStyle("default-style");
1579 tsoots 385
        else
11935 jghali 386
                style = sreader->getStyle(styleNames[0]);
387
        assert (style != NULL);
388
        gtParagraphStyle* par = dynamic_cast<gtParagraphStyle*>(style);
389
        if (par)
390
                tmp = new gtParagraphStyle(*par);
391
        else
392
                tmp = new gtStyle(*style);
1579 tsoots 393
        for (uint i = 1; i < styleNames.size(); ++i)
394
        {
395
                Properties& p = tmap[styleNames[i]];
396
                for (uint j = 0; j < p.size(); ++j)
397
                        sreader->updateStyle(tmp, sreader->getStyle(styleNames[i - 1]), p[j].first, p[j].second);
398
        }
399
        currentStyle = tmp;
400
        sreader->setStyle(getName(), tmp);
401
}
402
 
403
ContentReader::~ContentReader()
404
{
405
        creader = NULL;
406
        delete defaultStyle;
407
}