Back to index

scribus-ng  1.3.4.dfsg+svn20071115
stylereader.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 "stylereader.h"
00028  
00029  #ifdef HAVE_XML
00030  
00031  #include <scribusstructs.h>
00032  #include <gtmeasure.h>
00033  #include <gtparagraphstyle.h>
00034  #include <gtframestyle.h>
00035  #include <gtfont.h>
00036  
00037  StyleReader* StyleReader::sreader = NULL;
00038  
00039  extern xmlSAXHandlerPtr sSAXHandler;
00040  
00041 StyleReader::StyleReader(QString documentName, gtWriter *w,
00042                          bool textOnly, bool prefix, bool combineStyles)
00043 {
00044        sreader      = this;
00045        docname      = documentName;
00046        readProperties = false;
00047        writer       = w;
00048        importTextOnly = textOnly;
00049        usePrefix    = prefix;
00050        packStyles   = combineStyles;
00051        currentStyle = 0;
00052        currentListStyle = 0;
00053        parentStyle  = 0;
00054        inList       = false;
00055        currentList  = "";
00056        defaultStyleCreated = false;
00057 }
00058 
00059  bool StyleReader::startElement(const QString&, const QString&, const QString &name, const QXmlAttributes &attrs) 
00060  {
00061        if (name == "style:default-style")
00062               defaultStyle(attrs);
00063        else if (name == "style:paragraph-properties" ||
00064                 name == "style:text-properties" || 
00065                 name == "style:list-level-properties")
00066               styleProperties(attrs);
00067        else if (name == "style:style")
00068        {
00069               if (!defaultStyleCreated)
00070               {
00071                      currentStyle = new gtParagraphStyle(*(writer->getDefaultStyle()));
00072                      currentStyle->setName("default-style");
00073                      defaultStyleCreated = true;
00074               }
00075               styleStyle(attrs);
00076        }
00077        else if (name == "style:tab-stop")
00078               tabStop(attrs);
00079        else if (name == "text:list-style")
00080        {
00081               for (int i = 0; i < attrs.count(); ++i)
00082                      if (attrs.localName(i) == "style:name")
00083                             currentList = attrs.value(i);
00084               currentListStyle = new ListStyle(currentList);
00085               inList = true;
00086        }
00087        else if (((name == "text:list-level-style-bullet") ||
00088                  (name == "text:list-level-style-number") ||
00089                  (name == "text:list-level-style-image")) && (inList))
00090        {
00091               BulletType bstyle = Bullet;
00092               QString prefix = "";
00093               QString suffix = "";
00094               QString bullet = "-";
00095               uint ulevel = 0;
00096               uint displayLevels = 1;
00097               uint startAt = 0;
00098               QString level = "";
00099               for (int i = 0; i < attrs.count(); ++i)
00100               {
00101                      if (attrs.localName(i) == "text:level")
00102                      {
00103                             ulevel = QString(attrs.value(i)).toUInt();
00104                             gtStyle *plist;
00105                             if (attrs.value(i) == "1")
00106                             {
00107                                    plist = listParents[currentList];
00108                             }
00109                             else
00110                             {
00111                                    int level = (attrs.value(i)).toInt();
00112                                    --level;
00113                                    plist = styles[QString(currentList + "_%1").arg(level)]; 
00114                             }
00115                             gtParagraphStyle *pstyle;
00116                             if (plist == NULL)
00117                                    plist = new gtStyle(*(styles["default-style"]));
00118  
00119                             if (plist->target() == "paragraph")
00120                             {
00121                                    pstyle = dynamic_cast<gtParagraphStyle*>(plist);
00122                                    gtParagraphStyle* tmp = new gtParagraphStyle(*pstyle);
00123                                    currentStyle = tmp;
00124                             }
00125                             else
00126                             {
00127                                    gtParagraphStyle* tmp = new gtParagraphStyle(*plist);
00128                                    currentStyle = tmp;
00129                             }
00130                             currentStyle->setName(currentList + "_" + attrs.value(i));
00131                      }
00132                      else if (attrs.localName(i) == "style:num-prefix")
00133                             prefix = attrs.value(i);
00134                      else if (attrs.localName(i) == "style:num-suffix")
00135                             suffix = attrs.value(i);
00136                      /*else if (attrs.localName(i) == "text:bullet-char")
00137                             bullet = attrs.value(i);*/
00138                      else if (attrs.localName(i) == "style:num-format") {
00139                             QString tmp = attrs.value(i);
00140                             if (tmp == "i")
00141                                    bstyle = LowerRoman;
00142                             else if (tmp == "I")
00143                                    bstyle = UpperRoman;
00144                             else if (tmp == "a")
00145                                    bstyle = LowerAlpha;
00146                             else if (tmp == "A")
00147                                    bstyle = UpperAlpha;
00148                             else if (tmp == "1")
00149                                    bstyle = Number;
00150                      }
00151                      else if (attrs.localName(i) == "text:start-value") {
00152                             startAt = QString(attrs.value(i)).toUInt();
00153                             if (startAt > 0)
00154                                    --startAt;
00155                      }
00156                      else if (attrs.localName(i) == "text:display-levels") {
00157                             displayLevels = QString(attrs.value(i)).toUInt();
00158                             if (displayLevels == 0)
00159                                    displayLevels = 1;
00160                      }
00161               }
00162               if (bstyle == Bullet) {
00163                      prefix = "";
00164                      suffix = "";
00165               }
00166               ListLevel *llevel = new ListLevel(ulevel, bstyle, prefix, suffix, bullet, displayLevels, startAt);
00167               currentListStyle->addLevel(ulevel, llevel);
00168               readProperties = true;
00169        }
00170        else if ((name == "style:drop-cap") && (readProperties))
00171        {
00172               if (currentStyle->target() == "paragraph")
00173               {
00174                      for (int i = 0; i < attrs.count(); ++i)
00175                      {
00176                             if (attrs.localName(i) == "style:lines")
00177                             {
00178                                    bool ok = false;
00179                                    QString sd = attrs.value(i);
00180                                    int dh = sd.toInt(&ok);
00181                                    if (ok)
00182                                    {
00183                                           gtParagraphStyle* s = dynamic_cast<gtParagraphStyle*>(currentStyle);
00184                                           s->setDropCapHeight(dh);
00185                                           s->setDropCap(true);
00186                                    }
00187                             }
00188                      }
00189               }
00190        }
00191        else if (name == "style:font-face")
00192        {
00193               QString key = "";
00194               QString family = "";
00195               QString style = "";
00196               for (int i = 0; i < attrs.count(); ++i)
00197               {
00198                      if (attrs.localName(i) == "style:name")
00199                             key = attrs.value(i);
00200                      else if (attrs.localName(i) == "svg:font-family")
00201                      {
00202                             family = attrs.value(i);
00203                             family = family.remove("'");
00204                      }
00205                      else if (attrs.localName(i) == "style:font-style-name")
00206                             style += attrs.value(i) + " ";
00207               }
00208               QString name = family + " " + style;
00209               name = name.simplifyWhiteSpace();
00210               fonts[key] = name;
00211        }
00212        return true;
00213  }
00214  
00215  void StyleReader::defaultStyle(const QXmlAttributes& attrs)
00216  {
00217        currentStyle = NULL;
00218        for (int i = 0; i < attrs.count(); ++i)
00219               if (attrs.localName(i) == "style:family")
00220                      if (attrs.value(i) == "paragraph")
00221                      {
00222                             currentStyle = new gtParagraphStyle(*(writer->getDefaultStyle()));
00223                             currentStyle->setName("default-style");
00224                             readProperties = true;
00225                             defaultStyleCreated = true;
00226                      }
00227  }
00228  
00229  void StyleReader::styleProperties(const QXmlAttributes& attrs)
00230  {
00231        if ((currentStyle == NULL) || (!readProperties))
00232               return;
00233        gtParagraphStyle* pstyle = NULL;
00234        if (currentStyle->target() == "paragraph")
00235               pstyle = dynamic_cast<gtParagraphStyle*>(currentStyle);
00236        else
00237               pstyle = NULL;
00238        QString align = NULL;
00239        QString force = NULL;
00240        bool hasColorTag = false;
00241        for (int i = 0; i < attrs.count(); ++i)
00242        {
00243               if ((attrs.localName(i) == "style:font-name") && (!inList))
00244                      currentStyle->getFont()->setName(getFont(attrs.value(i)));
00245               else if (attrs.localName(i) == "fo:font-size")
00246               {
00247                      double size = 0;
00248                      double psize = 0;
00249                      if (parentStyle != NULL)
00250                             psize = static_cast<double>(parentStyle->getFont()->getSize());
00251                      else if (styles.contains("default-style"))
00252                             psize = static_cast<double>(styles["default-style"]->getFont()->getSize());
00253  
00254                      psize = psize / 10;
00255                      size = getSize(attrs.value(i), psize);
00256                      int nsize = static_cast<int>(size * 10);
00257                      currentStyle->getFont()->setSize(nsize);
00258                      if (pstyle)
00259                             pstyle->setLineSpacing(writer->getPreferredLineSpacing(nsize));
00260               }
00261               else if ((attrs.localName(i) == "fo:line-height") && (parentStyle != NULL))
00262               {
00263                      gtParagraphStyle* ppstyle;
00264                      if (parentStyle->target() == "paragraph")
00265                      {
00266                             ppstyle = dynamic_cast<gtParagraphStyle*>(parentStyle);
00267                             pstyle->setLineSpacing(getSize(attrs.value(i), writer->getPreferredLineSpacing(currentStyle->getFont()->getSize())));
00268                      }
00269               }
00270               else if (attrs.localName(i) == "fo:color")
00271               {
00272                      currentStyle->getFont()->setColor(attrs.value(i));
00273                      hasColorTag = true;
00274               }
00275               else if ((attrs.localName(i) == "style:use-window-font-color") && (attrs.value(i) == "true"))
00276               {
00277                      currentStyle->getFont()->setColor("Black");
00278                      hasColorTag = true;
00279               }
00280               else if ((attrs.localName(i) == "fo:font-weight") && (attrs.value(i) == "bold"))
00281                      currentStyle->getFont()->setWeight(BOLD);
00282               else if ((attrs.localName(i) == "fo:font-style") && (attrs.value(i) == "italic"))
00283                      currentStyle->getFont()->setSlant(ITALIC);
00284               else if ((attrs.localName(i) == "style:text-underline-style") && (attrs.value(i) != "none"))
00285                      currentStyle->getFont()->toggleEffect(UNDERLINE);
00286               else if ((attrs.localName(i) == "style:text-crossing-out") && (attrs.value(i) != "none"))
00287                      currentStyle->getFont()->toggleEffect(STRIKETHROUGH);
00288               else if ((attrs.localName(i) == "fo:font-variant") && (attrs.value(i) == "small-caps"))
00289                      currentStyle->getFont()->toggleEffect(SMALL_CAPS);
00290               else if ((attrs.localName(i) == "style:text-outline") && (attrs.value(i) == "true"))
00291               {
00292                      currentStyle->getFont()->toggleEffect(OUTLINE);
00293                      currentStyle->getFont()->setStrokeColor("Black");
00294                      currentStyle->getFont()->setColor("White");
00295               }
00296               else if (attrs.localName(i) == "fo:letter-spacing")
00297                      currentStyle->getFont()->setKerning(static_cast<int>(getSize(attrs.value(i), -1.0)));
00298               else if (attrs.localName(i) == "style:text-scale")
00299                      currentStyle->getFont()->setHscale(static_cast<int>(getSize(attrs.value(i), -1.0)));
00300               else if ((attrs.localName(i) == "style:text-position") && 
00301                       (((attrs.value(i)).find("sub") != -1) || 
00302                             (((attrs.value(i)).left(1) == "-") && ((attrs.value(i)).left(1) != "0"))))
00303                      currentStyle->getFont()->toggleEffect(SUBSCRIPT);
00304               else if ((attrs.localName(i) == "style:text-position") && 
00305                       (((attrs.value(i)).find("super") != -1) || 
00306                             (((attrs.value(i)).left(1) != "-") && ((attrs.value(i)).left(1) != "0"))))
00307                      currentStyle->getFont()->toggleEffect(SUPERSCRIPT);
00308               else if ((attrs.localName(i) == "fo:margin-top") && (pstyle != NULL))
00309                      pstyle->setSpaceAbove(getSize(attrs.value(i)));
00310               else if ((attrs.localName(i) == "fo:margin-bottom") && (pstyle != NULL))
00311                      pstyle->setSpaceBelow(getSize(attrs.value(i)));
00312               else if ((attrs.localName(i) == "fo:margin-left") && (pstyle != NULL))
00313               {
00314                      if (inList)
00315                             pstyle->setIndent(pstyle->getIndent() + getSize(attrs.value(i)));
00316                      else
00317                             pstyle->setIndent(getSize(attrs.value(i)));      
00318               }
00319               else if ((attrs.localName(i) == "text:space-before") && (pstyle != NULL))
00320               {
00321                      /*if (inList)
00322                             pstyle->setIndent(pstyle->getIndent() + getSize(attrs.value(i)));
00323                      else*/
00324                             pstyle->setIndent(getSize(attrs.value(i)));
00325               }
00326               else if ((attrs.localName(i) == "fo:text-indent") && (pstyle != NULL))
00327                      pstyle->setFirstLineIndent(getSize(attrs.value(i)));
00328               else if ((attrs.localName(i) == "fo:text-align") && (pstyle != NULL))
00329                      align = attrs.value(i);
00330               else if ((attrs.localName(i) == "style:justify-single-word") && (pstyle != NULL))
00331                      force = attrs.value(i);
00332        }
00333        if (align != NULL)
00334        {
00335               if (align == "end")
00336                      pstyle->setAlignment(RIGHT);
00337               else if (align == "center")
00338                      pstyle->setAlignment(CENTER);
00339               else if (align == "justify")
00340               {
00341                      if (force == "false")
00342                             pstyle->setAlignment(BLOCK);
00343                      else
00344                             pstyle->setAlignment(FORCED);
00345               }
00346        }
00347        if (!hasColorTag)
00348               currentStyle->getFont()->setColor("Black");
00349  }
00350  
00351  void StyleReader::styleStyle(const QXmlAttributes& attrs)
00352  {
00353        QString name = "";
00354        QString listName = NULL;
00355        bool isParaStyle = false;
00356        bool create = true;
00357        for (int i = 0; i < attrs.count(); ++i)
00358        {
00359               if (attrs.localName(i) == "style:family")
00360               {
00361                      if (attrs.value(i) == "paragraph")
00362                      {
00363                             isParaStyle = true;
00364                             readProperties = true;
00365                      }
00366                      else if (attrs.value(i) == "text")
00367                      {
00368                             isParaStyle = false;
00369                             readProperties = true;
00370                      }
00371                      else
00372                      {
00373                             readProperties = false;
00374                             return;
00375                      }
00376               }
00377               else if (attrs.localName(i) == "style:name")
00378                      name = attrs.value(i);
00379               else if (attrs.localName(i) == "style:parent-style-name")
00380               {
00381                      if (styles.contains(attrs.value(i)))
00382                             parentStyle = styles[attrs.value(i)];
00383                      else
00384                             parentStyle = NULL;
00385               }
00386               else if (attrs.localName(i) == "style:list-style-name")
00387                      listName = attrs.value(i);
00388        }
00389        if ((parentStyle == NULL) && (styles.contains("default-style")))
00390               parentStyle = styles["default-style"];
00391  
00392        if (create)
00393        {
00394               if (parentStyle == NULL)
00395               {
00396                      parentStyle = new gtStyle("tmp-parent");
00397               }
00398               if (isParaStyle)
00399               {
00400                      gtParagraphStyle *tmpP;
00401                      if (parentStyle->target() == "paragraph")
00402                      {
00403                             tmpP = dynamic_cast<gtParagraphStyle*>(parentStyle);
00404                             gtParagraphStyle* tmp = new gtParagraphStyle(*tmpP);
00405  //                         tmp->setAutoLineSpacing(true);
00406                             currentStyle = tmp;
00407                      }
00408                      else
00409                      {
00410                             gtParagraphStyle* tmp = new gtParagraphStyle(*parentStyle);
00411  //                         tmp->setAutoLineSpacing(true);
00412                             currentStyle = tmp;
00413                      }
00414                      if (listName != NULL)
00415                      {
00416                             listParents[listName] = currentStyle;
00417                      }
00418               }
00419               else
00420                      currentStyle = new gtStyle(*parentStyle);
00421  
00422               currentStyle->setName(name);
00423        }
00424        else
00425               currentStyle = NULL;
00426  }
00427  
00428  void StyleReader::tabStop(const QXmlAttributes& attrs)
00429  {
00430        if (currentStyle->target() == "paragraph")
00431        {
00432               gtParagraphStyle* pstyle = dynamic_cast<gtParagraphStyle*>(currentStyle);
00433               QString pos = NULL;
00434               QString type = NULL;
00435               for (int i = 0; i < attrs.count(); ++i)
00436               {
00437                      if (attrs.localName(i) == "style:position")
00438                             pos = attrs.value(i);
00439                      else if (attrs.localName(i) == "style:type")
00440                             type = attrs.value(i);
00441                             
00442               }
00443               if (pos != NULL)
00444               {
00445                      if (type == NULL)
00446                             type = "left";
00447                      double posd = getSize(pos);
00448                      if (type == "left")
00449                             pstyle->setTabValue(posd, LEFT_T);
00450                      else if (type == "right")
00451                             pstyle->setTabValue(posd, RIGHT_T);
00452                      else if (type == "center")
00453                             pstyle->setTabValue(posd, CENTER_T);
00454                      else
00455                             pstyle->setTabValue(posd, CENTER_T);
00456               }
00457        }
00458  }
00459  
00460  bool StyleReader::endElement(const QString&, const QString&, const QString &name)
00461  {
00462        if ((name == "style:default-style") && (currentStyle != NULL) && (readProperties))
00463        {
00464               setStyle(currentStyle->getName(), currentStyle);
00465               currentStyle = NULL;
00466               parentStyle = NULL;
00467               readProperties = false;
00468        }
00469        else if (((name == "style:style") || 
00470                  (name == "text:list-level-style-bullet") || 
00471                        (name == "text:list-level-style-number") ||
00472                        (name == "text:list-level-style-image")) && (currentStyle != NULL))
00473        {
00474               setStyle(currentStyle->getName(), currentStyle);
00475               currentStyle = NULL;
00476               parentStyle = NULL;
00477               readProperties = false;
00478        }
00479        else if (name == "text:list-style")
00480        {
00481               if (currentListStyle) {
00482                      lists[currentListStyle->name()] = currentListStyle;
00483                      currentListStyle = 0;
00484               }
00485               inList = false;
00486        }
00487 
00488        return true;
00489  }
00490  
00491  void StyleReader::parse(QString fileName)
00492  {
00493 #if defined(_WIN32)
00494        QString fname = QDir::convertSeparators(fileName);
00495        QCString fn = (qWinVersion() & Qt::WV_NT_based) ? fname.utf8() : fname.local8Bit();
00496 #else
00497        QCString fn(fileName.local8Bit());
00498 #endif
00499        xmlSAXParseFile(sSAXHandler, fn.data(), 1);
00500  }
00501  
00502  gtStyle* StyleReader::getStyle(const QString& name)
00503  {
00504        if (styles.contains(name))
00505        {
00506               gtStyle* tmp = styles[name];
00507               QString tname = tmp->getName();
00508               if ((tname.find(docname) == -1) && (usePrefix))
00509                      tmp->setName(docname + "_" + tname);
00510  
00511               return tmp;
00512        }
00513        else
00514               return styles["default-style"];
00515 
00516  }
00517  
00518  void StyleReader::setStyle(const QString& name, gtStyle* style)
00519  {
00520        gtParagraphStyle *s;
00521        QString tname = style->getName();
00522        if ((style->target() == "paragraph") && (packStyles))
00523        {
00524               s = dynamic_cast<gtParagraphStyle*>(style);
00525               QString nameByAttrs = QString("%1-").arg(s->getSpaceAbove());
00526               nameByAttrs += QString("%1-").arg(s->getSpaceBelow());
00527               nameByAttrs += QString("%1-").arg(s->getLineSpacing());
00528               nameByAttrs += QString("%1-").arg(s->getIndent());
00529               nameByAttrs += QString("%1-").arg(s->getFirstLineIndent());
00530               nameByAttrs += QString("%1-").arg(s->getAlignment());
00531               nameByAttrs += QString("%1-").arg(s->hasDropCap());
00532               nameByAttrs += QString("%1-").arg(s->getFont()->getColor());
00533               nameByAttrs += QString("%1-").arg(s->getFont()->getStrokeColor());
00534 // TODO is this important ??
00535 /*            QValueList<double>* tmp = s->getTabValues();
00536               for (uint i = 0; i < tmp->count(); ++i)
00537               {
00538                      double td = (*tmp)[i];
00539                      nameByAttrs += QString("%1-").arg(td);
00540               } */
00541               if (attrsStyles.contains(nameByAttrs))
00542               {
00543                      tname = attrsStyles[nameByAttrs]->getName();
00544                      ++pstyleCounts[nameByAttrs];
00545                      style->setName(tname);
00546               }
00547               else
00548               {
00549                      attrsStyles[nameByAttrs] = style;
00550                      pstyleCounts[nameByAttrs] = 1;
00551                      tname = style->getName();
00552               }
00553        }
00554        else if (!packStyles)
00555        {
00556               attrsStyles[name] = style;
00557               pstyleCounts[name] = 1;
00558               tname = style->getName();
00559        }
00560        if (!styles.contains(name))
00561        {
00562               if ((tname.find(docname) == -1) && (usePrefix))
00563                      style->setName(docname + "_" + tname);
00564               styles[name] = style;
00565        }
00566  }
00567  
00568  QString StyleReader::getFont(const QString& key)
00569  {
00570        if (fonts.contains(key))
00571               return fonts[key];
00572        else
00573               return key;
00574  }
00575  
00576  void StyleReader::setupFrameStyle()
00577  {
00578        QString fstyleName = "";
00579        int count = 0;
00580        CounterMap::Iterator it;
00581        for (it = pstyleCounts.begin(); it != pstyleCounts.end(); ++it)
00582        {
00583               if (it.data() > count)
00584               {
00585                      count = it.data();
00586                      fstyleName = it.key();
00587               }
00588        }
00589        gtFrameStyle* fstyle;
00590        gtParagraphStyle* pstyle = dynamic_cast<gtParagraphStyle*>(attrsStyles[fstyleName]);
00591        fstyle = new gtFrameStyle(*pstyle);
00592  
00593        if (!importTextOnly)
00594               writer->setFrameStyle(fstyle);
00595        delete fstyle;
00596  }
00597  
00598 ListStyle* StyleReader::getList(const QString &name)
00599 {
00600        ListStyle *tmp = 0;
00601        if (lists.contains(name))
00602               tmp = lists[name];
00603        return tmp;
00604 }
00605 
00606  bool StyleReader::updateStyle(gtStyle* style, gtStyle* parent2Style, const QString& key, const QString& value)
00607  {
00608        gtParagraphStyle* pstyle = NULL;
00609        if (style->target() == "paragraph")
00610               pstyle = dynamic_cast<gtParagraphStyle*>(style);
00611        else
00612               pstyle = NULL;
00613        QString align = NULL;
00614        QString force = NULL;
00615  
00616        if (key == "style:font-name")
00617               style->getFont()->setName(getFont(value));
00618        else if (key == "fo:font-size")
00619        {
00620               double size = 0;
00621               double psize = 0;
00622               if (parent2Style != NULL)
00623                      psize = static_cast<double>(parent2Style->getFont()->getSize());
00624               else if (styles.contains("default-style"))
00625                      psize = static_cast<double>(styles["default-style"]->getFont()->getSize());
00626                      psize = psize / 10;
00627               size = getSize(value, psize);
00628               int nsize = static_cast<int>(size * 10);
00629               style->getFont()->setSize(nsize);
00630               if (pstyle)
00631                      pstyle->setLineSpacing(writer->getPreferredLineSpacing(nsize));
00632        }
00633        else if ((key == "fo:line-height") && (parent2Style != NULL))
00634        {
00635               gtParagraphStyle* ppstyle;
00636               if (parent2Style->target() == "paragraph")
00637               {
00638                      ppstyle = dynamic_cast<gtParagraphStyle*>(parent2Style);
00639                      pstyle->setLineSpacing(getSize(value, writer->getPreferredLineSpacing(style->getFont()->getSize())));
00640               }
00641        }
00642        else if (key == "fo:color")
00643               style->getFont()->setColor(value);
00644        else if ((key == "style:use-window-font-color") && (value == "true"))
00645                      style->getFont()->setColor("Black");
00646        else if ((key == "fo:font-weight") && (value == "bold"))
00647               style->getFont()->setWeight(BOLD);
00648        else if ((key == "fo:font-style") && (value == "italic"))
00649               style->getFont()->setSlant(ITALIC);
00650        else if ((key == "style:text-underline-style") && (value != "none"))
00651               style->getFont()->toggleEffect(UNDERLINE);
00652        else if ((key == "style:text-crossing-out") && (value != "none"))
00653               style->getFont()->toggleEffect(STRIKETHROUGH);
00654        else if ((key == "fo:font-variant") && (value == "small-caps"))
00655               style->getFont()->toggleEffect(SMALL_CAPS);
00656        else if ((key == "style:text-outline") && (value == "true"))
00657        {
00658               style->getFont()->toggleEffect(OUTLINE);
00659               style->getFont()->setStrokeColor("Black");
00660               style->getFont()->setColor("White");
00661        }
00662        else if (key == "fo:letter-spacing")
00663               style->getFont()->setKerning(static_cast<int>(getSize(value, -1.0)));
00664        else if (key == "style:text-scale")
00665               style->getFont()->setHscale(static_cast<int>(getSize(value, -1.0)));
00666        else if ((key == "style:text-position") && 
00667                (((value).find("sub") != -1) || 
00668                      (((value).left(1) == "-") && ((value).left(1) != "0"))))
00669               style->getFont()->toggleEffect(SUBSCRIPT);
00670        else if ((key == "style:text-position") && 
00671                (((value).find("super") != -1) || 
00672                      (((value).left(1) != "-") && ((value).left(1) != "0"))))
00673               style->getFont()->toggleEffect(SUPERSCRIPT);
00674        else if ((key == "fo:margin-top") && (pstyle != NULL))
00675               pstyle->setSpaceAbove(getSize(value));
00676        else if ((key == "fo:margin-bottom") && (pstyle != NULL))
00677               pstyle->setSpaceBelow(getSize(value));
00678        else if ((key == "fo:margin-left") && (pstyle != NULL))
00679        {
00680               if (inList)
00681                      pstyle->setIndent(pstyle->getIndent() + getSize(value));
00682               else
00683                      pstyle->setIndent(getSize(value)); 
00684        }
00685        else if ((key == "text:space-before") && (pstyle != NULL))
00686        {
00687               if (inList)
00688                      pstyle->setIndent(pstyle->getIndent() + getSize(value));
00689               else
00690                      pstyle->setIndent(getSize(value)); 
00691        }
00692        else if ((key == "fo:text-indent") && (pstyle != NULL))
00693               pstyle->setFirstLineIndent(getSize(value));
00694        else if ((key == "fo:text-align") && (pstyle != NULL))
00695               align = value;
00696        else if ((key == "style:justify-single-word") && (pstyle != NULL))
00697               force = value;
00698  
00699        if (align != NULL)
00700        {
00701               if (align == "end")
00702                      pstyle->setAlignment(RIGHT);
00703               else if (align == "center")
00704                      pstyle->setAlignment(CENTER);
00705               else if (align == "justify")
00706               {
00707                      if (force != "false")
00708                             pstyle->setAlignment(FORCED);
00709                      else
00710                             pstyle->setAlignment(BLOCK);
00711               }
00712        }
00713        
00714        return true;
00715  }
00716  
00717  double StyleReader::getSize(QString s, double parentSize)
00718  {
00719        QString dbl = "0.0";
00720        QString lowerValue = s.lower();
00721        double ret = 0.0;
00722        if (lowerValue.find("pt") != -1)
00723        {
00724               dbl = lowerValue.remove("pt");
00725               ret = gtMeasure::d2d(dbl.toDouble(), SC_PT);
00726        }
00727        else if (lowerValue.find("mm") != -1)
00728        {
00729               dbl = lowerValue.remove("mm");
00730               ret = gtMeasure::d2d(dbl.toDouble(), SC_MM);
00731        }
00732        else if (lowerValue.find("cm") != -1)
00733        {
00734               dbl = lowerValue.remove("cm");
00735               ret = gtMeasure::d2d(dbl.toDouble() * 10, SC_MM);
00736        }
00737        else if (lowerValue.find("in") != -1)
00738        {
00739               dbl = lowerValue.remove("inch");
00740               dbl = lowerValue.remove("in");
00741               ret = gtMeasure::d2d(dbl.toDouble(), SC_IN);
00742        }
00743        else if (lowerValue.find("pi") != -1)
00744        {
00745               dbl = lowerValue.remove("pica");
00746               dbl = lowerValue.remove("pi");
00747               ret = gtMeasure::d2d(dbl.toDouble(), SC_P);
00748        }
00749        else if (lowerValue.find("c") != -1)
00750        {
00751               dbl = lowerValue.remove("cicero");
00752               dbl = lowerValue.remove("c");
00753               ret = gtMeasure::d2d(dbl.toDouble(), SC_C);
00754        }
00755        else if (lowerValue.find("%") != -1)
00756        {
00757               dbl = lowerValue.remove("%");
00758               double factor = dbl.toDouble();
00759               if (parentSize != -1.0)
00760               {
00761                      factor = factor / 100;
00762                      ret = factor * parentSize;
00763               }
00764               else
00765                      ret = factor;
00766        }
00767        return ret;
00768  }
00769  
00770  StyleReader::~StyleReader()
00771  {
00772        sreader = NULL;
00773        StyleMap::Iterator it;
00774        for (it = styles.begin(); it != styles.end(); ++it)
00775        {
00776               if (it.data())
00777               {
00778                      delete it.data();
00779                      it.data() = NULL;
00780               }
00781        }
00782  }
00783  
00784  xmlSAXHandler sSAXHandlerStruct = {
00785        NULL, // internalSubset,
00786        NULL, // isStandalone,
00787        NULL, // hasInternalSubset,
00788        NULL, // hasExternalSubset,
00789        NULL, // resolveEntity,
00790        NULL, // getEntity,
00791        NULL, // entityDecl,
00792        NULL, // notationDecl,
00793        NULL, // attributeDecl,
00794        NULL, // elementDecl,
00795        NULL, // unparsedEntityDecl,
00796        NULL, // setDocumentLocator,
00797        NULL, // startDocument,
00798        NULL, // endDocument,
00799        StyleReader::startElement,
00800        StyleReader::endElement,
00801        NULL, // reference,
00802        NULL, // characters
00803        NULL, // ignorableWhitespace,
00804        NULL, // processingInstruction,
00805        NULL, // comment,
00806        NULL, // warning,
00807        NULL, // error,
00808        NULL, // fatalError,
00809        NULL, // getParameterEntity,
00810        NULL, // cdata,
00811        NULL,
00812        1
00813  #ifdef HAVE_XML26
00814        ,
00815        NULL,
00816        NULL,
00817        NULL,
00818        NULL
00819  #endif
00820  };
00821  
00822  xmlSAXHandlerPtr sSAXHandler = &sSAXHandlerStruct;
00823  
00824  void StyleReader::startElement(void*, const xmlChar * fullname, const xmlChar ** atts)
00825  {
00826        QString* name = new QString((const char*) fullname);
00827        name = new QString(name->lower());
00828        QXmlAttributes* attrs = new QXmlAttributes();
00829        if (atts)
00830        {
00831               for(const xmlChar** cur = atts; cur && *cur; cur += 2)
00832                      attrs->append(QString((char*)*cur), NULL, QString((char*)*cur), QString((char*)*(cur + 1)));
00833        }
00834        sreader->startElement(NULL, NULL, *name, *attrs);
00835  }
00836  
00837  void StyleReader::endElement(void*, const xmlChar * name)
00838  {
00839        QString *nname = new QString((const char*) name);
00840        nname = new QString(nname->lower());
00841        sreader->endElement(NULL, NULL, *nname);
00842  }
00843 
00844 /*** ListLevel *****************************************************************************************/
00845 
00846 const QString ListLevel::lowerUnits[10] = {"", "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix"};
00847 const QString ListLevel::lowerTens[10] = {"", "x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc"};
00848 const QString ListLevel::lowerHundreds[10] = {"", "c", "cc", "ccc", "cd", "d", "dc", "dcc", "dccc", "cm"};
00849 const QString ListLevel::lowerThousands[4] = {"", "m", "mm", "mmm"};
00850 const QString ListLevel::upperUnits[10] = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
00851 const QString ListLevel::upperTens[10] = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
00852 const QString ListLevel::upperHundreds[10] = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCC", "CM"};
00853 const QString ListLevel::upperThousands[4] = {"", "M", "MM", "MMM"};
00854 const QString ListLevel::lowerAlphabets[27] = {"", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
00855                                     "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"};
00856 const QString ListLevel::upperAlphabets[27] = {"", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
00857                                     "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
00858 
00859 ListLevel::ListLevel(uint level,
00860                         BulletType btype,
00861                         const QString &prefix,
00862                         const QString &suffix,
00863                         const QString &bullet,
00864                         uint displayLevels,
00865                         uint startValue) :
00866 m_level(level),
00867 m_btype(btype),
00868 m_prefix(prefix),
00869 m_suffix(suffix),
00870 m_bullet(bullet),
00871 m_displayLevels(displayLevels),
00872 m_next(startValue)
00873 {
00874 
00875 }
00876 
00877 QString ListLevel::bulletString()
00878 {
00879        QString tmp;
00880        switch (m_btype) {
00881        case Bullet:
00882               tmp = m_bullet;
00883               break;
00884        case Number:
00885               tmp = QString("%1").arg(m_next);
00886               break;
00887        case LowerRoman:
00888               tmp = lowerRoman(m_next);
00889               break;
00890        case UpperRoman:
00891               tmp = upperRoman(m_next);
00892               break;
00893        case LowerAlpha:
00894               tmp = lowerAlpha(m_next);
00895               break;
00896        case UpperAlpha:
00897               tmp = upperAlpha(m_next);
00898               break;
00899        case Graphic:
00900               tmp = "*";
00901               break;
00902        default:
00903               tmp = "";
00904        };
00905        return tmp;
00906 }
00907 
00908 QString ListLevel::bullet()
00909 {
00910        
00911        return QString(m_prefix + bulletString() + m_suffix);
00912 }
00913 
00914 QString ListLevel::prefix()
00915 {
00916        return m_prefix;
00917 }
00918 
00919 QString ListLevel::suffix()
00920 {
00921        return m_suffix;
00922 }
00923 
00924 void ListLevel::advance()
00925 {
00926        ++m_next;
00927 }
00928 
00929 uint ListLevel::level()
00930 {
00931        return m_level;
00932 }
00933 
00934 uint ListLevel::displayLevels()
00935 {
00936        return m_displayLevels;
00937 }
00938 
00939 void ListLevel::reset()
00940 {
00941        m_next = 0;
00942 }
00943 
00944 QString ListLevel::lowerRoman(uint n)
00945 {
00946        return QString(lowerThousands[(n / 1000)] +
00947                       lowerHundreds[(n / 100) % 10] +
00948                       lowerTens[(n / 10) % 10] +
00949                       lowerUnits[(n) % 10]);
00950 }
00951 
00952 QString ListLevel::upperRoman(uint n)
00953 {
00954        return QString(upperThousands[(n / 1000)] +
00955                       upperHundreds[(n / 100) % 10] +
00956                       upperTens[(n / 10) % 10] +
00957                       upperUnits[(n) % 10]);
00958 }
00959 
00960 QString ListLevel::lowerAlpha(uint n)
00961 {
00962        QString tmp;
00963        uint rounds = static_cast<uint>(n / 26);
00964        if (rounds > 26)
00965               rounds = 0;
00966        uint leftover = n % 26;
00967        return QString(lowerAlphabets[rounds] + lowerAlphabets[leftover]);
00968 }
00969 
00970 QString ListLevel::upperAlpha(uint n)
00971 {
00972        QString tmp;
00973        uint rounds = static_cast<uint>(n / 26);
00974        if (rounds > 26)
00975               rounds = 0;
00976        uint leftover = n % 26;
00977        return QString(upperAlphabets[rounds] + upperAlphabets[leftover]);
00978 }
00979 
00980 ListLevel::~ListLevel()
00981 {
00982 
00983 }
00984 
00985 /*** ListStyle **********************************************************************************/
00986 
00987 ListStyle::ListStyle(const QString &name, bool consecutiveNumbering, uint currentLevel) :
00988 m_name(name),
00989 m_consecutiveNumbering(consecutiveNumbering),
00990 m_currentLevel(currentLevel),
00991 m_count(0)
00992 {
00993        for (uint i = 0; i < 11; ++i)
00994               levels[i] = 0;
00995 }
00996 
00997 void ListStyle::addLevel(uint level, ListLevel *llevel)
00998 {
00999        if (level > 0 && level < 11)
01000               levels[level] = llevel;
01001 }
01002 
01003 QString ListStyle::bullet()
01004 {
01005        uint displayLevels = levels[m_currentLevel]->displayLevels();
01006        if (displayLevels == 1)
01007               return QString(levels[m_currentLevel]->bullet() + " ");
01008 
01009        QString prefix = levels[m_currentLevel]->prefix();
01010        QString suffix = levels[m_currentLevel]->suffix();
01011        QString bullet = "";
01012        int start = m_currentLevel - displayLevels + 1;
01013        if (start < 1)
01014               return QString(levels[m_currentLevel]->bullet() + " ");
01015        while (static_cast<uint>(start) <= m_currentLevel)
01016        {
01017               if (static_cast<uint>(start) == m_currentLevel)
01018                      bullet += levels[start]->bulletString();
01019               else
01020                      bullet += levels[start]->bulletString() + ".";
01021               ++start;
01022        }
01023        return QString(prefix + bullet + suffix + " ");
01024 }
01025 
01026 void ListStyle::advance()
01027 {
01028        ++m_count;
01029        if (levels[m_currentLevel])
01030               levels[m_currentLevel]->advance();
01031 }
01032 
01033 void ListStyle::setLevel(uint level)
01034 {
01035        if (level > 0 && level < 11)
01036               m_currentLevel = level;
01037 }
01038 
01039 QString& ListStyle::name()
01040 {
01041        return m_name;
01042 }
01043 
01044 void ListStyle::resetLevel()
01045 {
01046        levels[m_currentLevel]->reset();
01047 }
01048 
01049 ListStyle::~ListStyle()
01050 {
01051        for (uint i = 0; i < 11; ++i)
01052        {
01053               delete levels[i];
01054               levels[i] = 0;
01055        }
01056 }
01057 
01058 #endif