Scribus Developer Documentation - API
logo-pen

Scribus Developer Documentation - API

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