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 "contentreader.h"
00028 
00029 #ifdef HAVE_XML
00030 
00031 #include <scribusstructs.h>
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        isOrdered = false;
00049        inSpan = false;
00050        listIndex = 0;
00051        listLevel = 0;
00052        currentList = "";
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:unordered-list") || (name == "text:ordered-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               styleNames.clear();
00117               styleNames.push_back(QString(currentList + "_%1").arg(listLevel));
00118               if (name == "text:ordered-list")
00119               {
00120                      isOrdered = true;
00121                      isOrdered2.push_back(true);
00122               }
00123               else
00124               {
00125                      isOrdered = false;
00126                      isOrdered2.push_back(false);
00127               }
00128        }
00129        else if (name == "text:list-item")
00130        {
00131               if (isOrdered2[listLevel - 1])
00132               {
00133                      ++listIndex;
00134                      ++listIndex2[listLevel - 1];
00135                      if (listLevel == 1)
00136                             write(QString("%1. ").arg(listIndex2[listLevel - 1]));
00137                      else
00138                             write(QString("%1. ").arg(listIndex2[listLevel - 1]));
00139               }
00140               else
00141                      write("- ");
00142        }
00143        else if (name == "style:style")
00144        {
00145               QString sname = "";
00146               bool isTextStyle = false;
00147               for (int i = 0; i < attrs.count(); ++i)
00148               {
00149                      if (attrs.localName(i) == "style:name")
00150                             sname = attrs.value(i);
00151                      else if ((attrs.localName(i) == "style:family") && (attrs.value(i) == "text"))
00152                             isTextStyle = true;
00153               }
00154               if (isTextStyle)
00155               {
00156                      tName = sname;
00157                      inT = true;
00158               }
00159        }
00160        else if ((name == "style:properties") && (inT))
00161        {
00162               Properties p;
00163               for (int i = 0; i < attrs.count(); ++i)
00164               {
00165                      std::pair<QString, QString> pair(attrs.localName(i), attrs.value(i));
00166                      p.push_back(pair);
00167               }
00168               tmap[tName] = p;
00169        }
00170        else if (name == "text:s")
00171        {
00172               int count = 1;
00173               for (int i = 0; i < attrs.count(); ++i)
00174               {
00175                      if (attrs.localName(i) == "text:c")
00176                      {
00177                             bool ok = false;
00178                             int tmpcount = (attrs.value(i)).toInt(&ok);
00179                             if (ok)
00180                                    count = tmpcount;
00181                      }
00182               }
00183               for (int i = 0; i < count; ++i)
00184                      write(" ");
00185        }
00186        return true;
00187 }
00188 
00189 bool ContentReader::characters(const QString &ch) 
00190 {
00191        QString tmp = ch;
00192        tmp = tmp.remove("\n");
00193        tmp = tmp.remove(""); // Remove all OO.o hyphenation chars
00194        tmp = tmp.replace(QChar(160), QChar(29)); // replace OO.o nbsp with Scribus nbsp
00195        if (append)
00196               write(tmp);
00197        return true;
00198 }
00199 
00200 bool ContentReader::endElement(const QString&, const QString&, const QString &name)
00201 {
00202        if ((name == "text:p") || (name == "text:h"))
00203        {
00204               write("\n");
00205               append = false;
00206               if (inList)
00207               {
00208                      if (styleNames.size() != 0)
00209                             styleNames.pop_back();
00210               }
00211               else
00212                      styleNames.clear();
00213        }
00214        else if (name == "text:span")
00215        {
00216               inSpan = false;
00217               currentStyle = pstyle;
00218               if (styleNames.size() != 0)
00219                      styleNames.pop_back();      
00220               currentStyle = sreader->getStyle(getName());
00221        }
00222        else if (name == "text:line-break")
00223               write(QChar(28));
00224        else if (name == "text:tab-stop")
00225               write("\t");
00226        else if ((name == "text:unordered-list") || (name == "text:ordered-list"))
00227        {
00228               --listLevel;
00229               styleNames.clear();
00230               if (listLevel == 0)
00231               {
00232                      inList = false;
00233                      listIndex2.clear();
00234               }
00235               else
00236               {
00237                      currentStyle = sreader->getStyle(QString(currentList + "_%1").arg(listLevel));
00238                      styleNames.push_back(QString(currentList + "_%1").arg(listLevel));
00239               }
00240        }
00241        else if ((name == "style:style") && (inT))
00242        {
00243               inT = false;
00244               tName = "";
00245        }
00246        return true;
00247 }
00248 
00249 void ContentReader::write(const QString& text)
00250 {
00251        if (importTextOnly)
00252               writer->append(text);
00253        else if (inSpan)
00254               writer->append(text, currentStyle, false);
00255        else
00256               writer->append(text, currentStyle);
00257        lastStyle = currentStyle;
00258 }
00259 
00260 void ContentReader::parse(QString fileName)
00261 {
00262        sreader->parse(fileName);
00263 #if defined(_WIN32)
00264        QString fname = QDir::convertSeparators(fileName);
00265        QCString fn = (qWinVersion() & Qt::WV_NT_based) ? fname.utf8() : fname.local8Bit();
00266 #else
00267        QCString fn(fileName.local8Bit());
00268 #endif
00269        xmlSAXParseFile(cSAXHandler, fn.data(), 1);
00270 }
00271 
00272 xmlSAXHandler cSAXHandlerStruct = {
00273        NULL, // internalSubset,
00274        NULL, // isStandalone,
00275        NULL, // hasInternalSubset,
00276        NULL, // hasExternalSubset,
00277        NULL, // resolveEntity,
00278        NULL, // getEntity,
00279        NULL, // entityDecl,
00280        NULL, // notationDecl,
00281        NULL, // attributeDecl,
00282        NULL, // elementDecl,
00283        NULL, // unparsedEntityDecl,
00284        NULL, // setDocumentLocator,
00285        NULL, // startDocument,
00286        NULL, // endDocument,
00287        ContentReader::startElement,
00288        ContentReader::endElement,
00289        NULL, // reference,
00290        ContentReader::characters,
00291        NULL, // ignorableWhitespace,
00292        NULL, // processingInstruction,
00293        NULL, // comment,
00294        NULL, // warning,
00295        NULL, // error,
00296        NULL, // fatalError,
00297        NULL, // getParameterEntity,
00298        NULL, // cdata,
00299        NULL,
00300        1
00301 #ifdef HAVE_XML26
00302        ,
00303        NULL,
00304        NULL,
00305        NULL,
00306        NULL
00307 #endif
00308 };
00309 
00310 xmlSAXHandlerPtr cSAXHandler = &cSAXHandlerStruct;
00311 
00312 void ContentReader::startElement(void*, const xmlChar *fullname, const xmlChar ** atts)
00313 {
00314        QString* name = new QString((const char*) fullname);
00315        name = new QString(name->lower());
00316        QXmlAttributes* attrs = new QXmlAttributes();
00317        if (atts)
00318        {
00319               for(const xmlChar** cur = atts; cur && *cur; cur += 2)
00320                      attrs->append(QString((char*)*cur), NULL, QString((char*)*cur), QString((char*)*(cur + 1)));
00321        }
00322        creader->startElement(NULL, NULL, *name, *attrs);
00323 }
00324 
00325 void ContentReader::characters(void*, const xmlChar *ch, int len)
00326 {
00327        QString chars = QString::fromUtf8((const char*) ch, len);
00328        creader->characters(chars);
00329 }
00330 
00331 void ContentReader::endElement(void*, const xmlChar *name)
00332 {
00333        QString *nname = new QString((const char*) name);
00334        nname = new QString(nname->lower());
00335        creader->endElement(NULL, NULL, *nname);
00336 }
00337 
00338 QString ContentReader::getName()
00339 {
00340        QString s = "";
00341        for (uint i = 0; i < styleNames.size(); ++i)
00342               s += styleNames[i];
00343        return s;
00344 }
00345 
00346 void ContentReader::getStyle()
00347 {
00348        gtParagraphStyle* par = NULL;
00349        if (styleNames.size() == 0)
00350               par = dynamic_cast<gtParagraphStyle*>(sreader->getStyle("default-style"));
00351        else
00352               par = dynamic_cast<gtParagraphStyle*>(sreader->getStyle(styleNames[0]));
00353        gtParagraphStyle* tmp = new gtParagraphStyle(*par);
00354        for (uint i = 1; i < styleNames.size(); ++i)
00355        {
00356               Properties& p = tmap[styleNames[i]];
00357               for (uint j = 0; j < p.size(); ++j)
00358                      sreader->updateStyle(tmp, sreader->getStyle(styleNames[i - 1]), p[j].first, p[j].second);
00359        }
00360 
00361        currentStyle = tmp;
00362        sreader->setStyle(getName(), tmp);
00363 }
00364 
00365 ContentReader::~ContentReader()
00366 {
00367        creader = NULL;
00368        delete defaultStyle;
00369 }
00370 
00371 #endif // HAVE_XML