Back to index

scribus-ng  1.3.4.dfsg+svn20071115
contentreader.cpp
Go to the documentation of this file.
00001 /*
00002 For general Scribus (>=1.3.2) copyright and licensing information please refer
00003 to the COPYING file provided with the program. Following this notice may exist
00004 a copyright and/or license notice that predates the release of Scribus 1.3.2
00005 for which a new license (GPL+exception) is in place.
00006 */
00007 /***************************************************************************
00008  *   Copyright (C) 2004 by Riku Leino                                      *
00009  *   tsoots@gmail.com                                                      *
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  *   This program is distributed in the hope that it will be useful,       *
00017  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00018  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00019  *   GNU General Public License for more details.                          *
00020  *                                                                         *
00021  *   You should have received a copy of the GNU General Public License     *
00022  *   along with this program; if not, write to the                         *
00023  *   Free Software Foundation, Inc.,                                       *
00024  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00025  ***************************************************************************/
00026 
00027 #include <qglobal.h>
00028 #include "contentreader.h"
00029 #include "scribusstructs.h"
00030 
00031 #ifdef HAVE_XML
00032 
00033 ContentReader* ContentReader::creader = NULL;
00034 
00035 extern xmlSAXHandlerPtr cSAXHandler;
00036 
00037 ContentReader::ContentReader(QString documentName, StyleReader *s, gtWriter *w, bool textOnly)
00038 {
00039        creader = this;
00040        docname = documentName;
00041        sreader = s;
00042        writer  = w;
00043        importTextOnly = textOnly;
00044        defaultStyle = NULL;
00045        currentStyle = NULL;
00046        append = false;
00047        inList = false;
00048        inSpan = false;
00049        listIndex = 0;
00050        listLevel = 0;
00051        currentList = "";
00052        currentListStyle = 0;
00053        inT = false;
00054        tName = "";
00055 }
00056 
00057 bool ContentReader::startElement(const QString&, const QString&, const QString &name, const QXmlAttributes &attrs) 
00058 {
00059        if ((name == "text:p") || (name == "text:h"))
00060        {
00061               append = true;
00062               QString name = "";
00063               for (int i = 0; i < attrs.count(); ++i)
00064               {
00065                      if (attrs.localName(i) == "text:style-name")
00066                      {
00067                             name = attrs.value(i);
00068                             styleNames.push_back(attrs.value(i));
00069                      }
00070               }
00071               if (!inList)
00072               {
00073                      pstyle = sreader->getStyle(name);
00074                      currentStyle = pstyle;
00075               }
00076               else
00077               {
00078                      gtStyle *tmp = sreader->getStyle(getName());
00079                      if ((tmp->getName()).find("default-style") != -1)
00080                             getStyle();
00081                      else
00082                             currentStyle = tmp;
00083               }
00084        }
00085        else if (name == "text:span")
00086        {
00087               inSpan = true;
00088               QString styleName = "";
00089               for (int i = 0; i < attrs.count(); ++i)
00090               {
00091                      if (attrs.localName(i) == "text:style-name")
00092                      {
00093                             currentStyle = sreader->getStyle(attrs.value(i));
00094                             styleName = attrs.value(i);
00095                             styleNames.push_back(styleName);
00096                      }
00097               }
00098               gtStyle *tmp = sreader->getStyle(getName());
00099               if ((tmp->getName()).find("default-style") != -1)
00100                      getStyle();
00101               else
00102                      currentStyle = tmp;
00103        }
00104        else if (name == "text:list")
00105        {
00106               inList = true;
00107               ++listLevel;
00108               if (static_cast<int>(listIndex2.size()) < listLevel)
00109                      listIndex2.push_back(0);
00110               for (int i = 0; i < attrs.count(); ++i)
00111               {
00112                      if (attrs.localName(i) == "text:style-name")
00113                             currentList = attrs.value(i);
00114               }
00115               currentStyle = sreader->getStyle(QString(currentList + "_%1").arg(listLevel));
00116               currentListStyle = sreader->getList(currentList);
00117               currentListStyle->setLevel(listLevel);
00118               styleNames.clear();
00119               styleNames.push_back(QString(currentList + "_%1").arg(listLevel));
00120        }
00121        else if (name == "text:list-item")
00122        {
00123               currentListStyle->advance();
00124               write(currentListStyle->bullet());
00125        }
00126        else if (name == "style:style")
00127        {
00128               QString sname = "";
00129               bool isTextStyle = false;
00130               for (int i = 0; i < attrs.count(); ++i)
00131               {
00132                      if (attrs.localName(i) == "style:name")
00133                             sname = attrs.value(i);
00134                      else if ((attrs.localName(i) == "style:family") && (attrs.value(i) == "text"))
00135                             isTextStyle = true;
00136               }
00137               if (isTextStyle)
00138               {
00139                      tName = sname;
00140                      inT = true;
00141               }
00142        }
00143        else if ((name == "style:paragraph-properties" ||
00144                  name == "style:text-properties" ||
00145                  name == "style:list-level-properties") && (inT))
00146        {
00147               Properties p;
00148               for (int i = 0; i < attrs.count(); ++i)
00149               {
00150                      std::pair<QString, QString> pair(attrs.localName(i), attrs.value(i));
00151                      p.push_back(pair);
00152               }
00153               tmap[tName] = p;
00154        }
00155        else if (name == "text:s")
00156        {
00157               int count = 1;
00158               for (int i = 0; i < attrs.count(); ++i)
00159               {
00160                      if (attrs.localName(i) == "text:c")
00161                      {
00162                             bool ok = false;
00163                             int tmpcount = (attrs.value(i)).toInt(&ok);
00164                             if (ok)
00165                                    count = tmpcount;
00166                      }
00167               }
00168               for (int i = 0; i < count; ++i)
00169                      write(" ");
00170        }
00171        return true;
00172 }
00173 
00174 bool ContentReader::characters(const QString &ch) 
00175 {
00176        QString tmp = ch;
00177        tmp = tmp.remove("\n");
00178        tmp = tmp.remove(""); // Remove all OO.o hyphenation chars
00179        tmp = tmp.replace(QChar(160), QChar(29)); // replace OO.o nbsp with Scribus nbsp
00180        if (append)
00181               write(tmp);
00182        return true;
00183 }
00184 
00185 bool ContentReader::endElement(const QString&, const QString&, const QString &name)
00186 {
00187        if ((name == "text:p") || (name == "text:h"))
00188        {
00189               write("\n");
00190               append = false;
00191               if (inList)
00192                      styleNames.pop_back();
00193               else
00194                      styleNames.clear();
00195        }
00196        else if (name == "text:span")
00197        {
00198               inSpan = false;
00199               currentStyle = pstyle;
00200               if (styleNames.size() != 0)
00201                      styleNames.pop_back();      
00202               currentStyle = sreader->getStyle(getName());
00203        }
00204        else if (name == "text:line-break")
00205               write(QChar(28));
00206        else if (name == "text:tab")
00207               write("\t");
00208        else if (name == "text:list")
00209        {
00210               --listLevel;
00211               styleNames.clear();
00212               if (listLevel == 0)
00213               {
00214                      inList = false;
00215                      listIndex2.clear();
00216                      currentListStyle = 0;
00217               }
00218               else
00219               {
00220                      currentStyle = sreader->getStyle(QString(currentList + "_%1").arg(listLevel));
00221                      styleNames.push_back(QString(currentList + "_%1").arg(listLevel));
00222                      currentListStyle->resetLevel();
00223                      currentListStyle = sreader->getList(currentList);
00224                      currentListStyle->setLevel(listLevel);
00225               }
00226        }
00227        else if ((name == "style:style") && (inT))
00228        {
00229               inT = false;
00230               tName = "";
00231        }
00232        return true;
00233 }
00234 
00235 void ContentReader::write(const QString& text)
00236 {
00237        if (importTextOnly)
00238               writer->append(text);
00239        else if (inSpan)
00240               writer->append(text, currentStyle, false);
00241        else
00242               writer->append(text, currentStyle);
00243        lastStyle = currentStyle;
00244 }
00245 
00246 void ContentReader::parse(QString fileName)
00247 {
00248        sreader->parse(fileName);
00249 #if defined(_WIN32)
00250        QString fname = QDir::convertSeparators(fileName);
00251        QCString fn = (qWinVersion() & Qt::WV_NT_based) ? fname.utf8() : fname.local8Bit();
00252 #else
00253        QCString fn(fileName.local8Bit());
00254 #endif
00255        xmlSAXParseFile(cSAXHandler, fn.data(), 1);
00256 }
00257 
00258 xmlSAXHandler cSAXHandlerStruct = {
00259        NULL, // internalSubset,
00260        NULL, // isStandalone,
00261        NULL, // hasInternalSubset,
00262        NULL, // hasExternalSubset,
00263        NULL, // resolveEntity,
00264        NULL, // getEntity,
00265        NULL, // entityDecl,
00266        NULL, // notationDecl,
00267        NULL, // attributeDecl,
00268        NULL, // elementDecl,
00269        NULL, // unparsedEntityDecl,
00270        NULL, // setDocumentLocator,
00271        NULL, // startDocument,
00272        NULL, // endDocument,
00273        ContentReader::startElement,
00274        ContentReader::endElement,
00275        NULL, // reference,
00276        ContentReader::characters,
00277        NULL, // ignorableWhitespace,
00278        NULL, // processingInstruction,
00279        NULL, // comment,
00280        NULL, // warning,
00281        NULL, // error,
00282        NULL, // fatalError,
00283        NULL, // getParameterEntity,
00284        NULL, // cdata,
00285        NULL,
00286        1
00287 #ifdef HAVE_XML26
00288        ,
00289        NULL,
00290        NULL,
00291        NULL,
00292        NULL
00293 #endif
00294 };
00295 
00296 xmlSAXHandlerPtr cSAXHandler = &cSAXHandlerStruct;
00297 
00298 void ContentReader::startElement(void*, const xmlChar *fullname, const xmlChar ** atts)
00299 {
00300        QString* name = new QString((const char*) fullname);
00301        name = new QString(name->lower());
00302        QXmlAttributes* attrs = new QXmlAttributes();
00303        if (atts)
00304        {
00305               for(const xmlChar** cur = atts; cur && *cur; cur += 2)
00306                      attrs->append(QString((char*)*cur), NULL, QString((char*)*cur), QString((char*)*(cur + 1)));
00307        }
00308        creader->startElement(NULL, NULL, *name, *attrs);
00309 }
00310 
00311 void ContentReader::characters(void*, const xmlChar *ch, int len)
00312 {
00313        QString chars = QString::fromUtf8((const char*) ch, len);
00314        creader->characters(chars);
00315 }
00316 
00317 void ContentReader::endElement(void*, const xmlChar *name)
00318 {
00319        QString *nname = new QString((const char*) name);
00320        nname = new QString(nname->lower());
00321        creader->endElement(NULL, NULL, *nname);
00322 }
00323 
00324 QString ContentReader::getName()
00325 {
00326        QString s = "";
00327        for (uint i = 0; i < styleNames.size(); ++i)
00328               s += styleNames[i];
00329        return s;
00330 }
00331 
00332 void ContentReader::getStyle()
00333 {
00334        gtParagraphStyle* par = NULL;
00335        if (styleNames.size() == 0)
00336               par = dynamic_cast<gtParagraphStyle*>(sreader->getStyle("default-style"));
00337        else
00338               par = dynamic_cast<gtParagraphStyle*>(sreader->getStyle(styleNames[0]));
00339        gtParagraphStyle* tmp = new gtParagraphStyle(*par);
00340        for (uint i = 1; i < styleNames.size(); ++i)
00341        {
00342               Properties& p = tmap[styleNames[i]];
00343               for (uint j = 0; j < p.size(); ++j)
00344                      sreader->updateStyle(tmp, sreader->getStyle(styleNames[i - 1]), p[j].first, p[j].second);
00345        }
00346 
00347        currentStyle = tmp;
00348        sreader->setStyle(getName(), tmp);
00349 }
00350 
00351 ContentReader::~ContentReader()
00352 {
00353        creader = NULL;
00354        delete defaultStyle;
00355 }
00356 
00357 #endif // HAVE_XML