00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <QGlobalStatic>
00028 #include <QByteArray>
00029 #include "contentreader.h"
00030 #include "scribusstructs.h"
00031
00032 ContentReader* ContentReader::creader = NULL;
00033
00034 extern xmlSAXHandlerPtr cSAXHandler;
00035
00036 ContentReader::ContentReader(QString documentName, StyleReader *s, gtWriter *w, bool textOnly)
00037 {
00038 creader = this;
00039 docname = documentName;
00040 sreader = s;
00041 writer = w;
00042 importTextOnly = textOnly;
00043 defaultStyle = NULL;
00044 currentStyle = NULL;
00045 append = false;
00046 inList = false;
00047 inNote = false;
00048 inNoteBody = false;
00049 inSpan = false;
00050 listIndex = 0;
00051 listLevel = 0;
00052 currentList = "";
00053 currentListStyle = 0;
00054 inT = false;
00055 tName = "";
00056 }
00057
00058 bool ContentReader::startElement(const QString&, const QString&, const QString &name, const QXmlAttributes &attrs)
00059 {
00060 if ((name == "text:p") || (name == "text:h"))
00061 {
00062 append = true;
00063 QString name = "";
00064 for (int i = 0; i < attrs.count(); ++i)
00065 {
00066 if (attrs.localName(i) == "text:style-name")
00067 {
00068 name = attrs.value(i);
00069 styleNames.push_back(attrs.value(i));
00070 }
00071 }
00072 if (!inList)
00073 {
00074 pstyle = sreader->getStyle(name);
00075 currentStyle = pstyle;
00076 }
00077 else
00078 {
00079 gtStyle *tmp = sreader->getStyle(getName());
00080 if ((tmp->getName()).indexOf("default-style") != -1)
00081 getStyle();
00082 else
00083 currentStyle = tmp;
00084 }
00085 }
00086 else if (name == "text:span")
00087 {
00088 inSpan = true;
00089 QString styleName = "";
00090 for (int i = 0; i < attrs.count(); ++i)
00091 {
00092 if (attrs.localName(i) == "text:style-name")
00093 {
00094 currentStyle = sreader->getStyle(attrs.value(i));
00095 styleName = attrs.value(i);
00096 styleNames.push_back(styleName);
00097 }
00098 }
00099 gtStyle *tmp = sreader->getStyle(getName());
00100 if ((tmp->getName()).indexOf("default-style") != -1)
00101 getStyle();
00102 else
00103 currentStyle = tmp;
00104 }
00105 else if (name == "text:list")
00106 {
00107 inList = true;
00108 ++listLevel;
00109 if (static_cast<int>(listIndex2.size()) < listLevel)
00110 listIndex2.push_back(0);
00111 for (int i = 0; i < attrs.count(); ++i)
00112 {
00113 if (attrs.localName(i) == "text:style-name")
00114 currentList = attrs.value(i);
00115 }
00116 currentStyle = sreader->getStyle(QString(currentList + "_%1").arg(listLevel));
00117 currentListStyle = sreader->getList(currentList);
00118 currentListStyle->setLevel(listLevel);
00119 styleNames.clear();
00120 styleNames.push_back(QString(currentList + "_%1").arg(listLevel));
00121 }
00122 else if (name == "text:list-item")
00123 {
00124 currentListStyle->advance();
00125 write(currentListStyle->bullet());
00126 }
00127 else if (name == "text:note")
00128 inNote = true;
00129 else if (name == "text:note-body")
00130 inNoteBody = true;
00131 else if (name == "style:style")
00132 {
00133 QString sname = "";
00134 bool isTextStyle = false;
00135 for (int i = 0; i < attrs.count(); ++i)
00136 {
00137 if (attrs.localName(i) == "style:name")
00138 sname = attrs.value(i);
00139 else if ((attrs.localName(i) == "style:family") && (attrs.value(i) == "text"))
00140 isTextStyle = true;
00141 }
00142 if (isTextStyle)
00143 {
00144 tName = sname;
00145 inT = true;
00146 }
00147 }
00148 else if ((name == "style:paragraph-properties" ||
00149 name == "style:text-properties" ||
00150 name == "style:list-level-properties") && (inT))
00151 {
00152 Properties p;
00153 for (int i = 0; i < attrs.count(); ++i)
00154 {
00155 std::pair<QString, QString> pair(attrs.localName(i), attrs.value(i));
00156 p.push_back(pair);
00157 }
00158 tmap[tName] = p;
00159 }
00160 else if (name == "text:s")
00161 {
00162 int count = 1;
00163 for (int i = 0; i < attrs.count(); ++i)
00164 {
00165 if (attrs.localName(i) == "text:c")
00166 {
00167 bool ok = false;
00168 int tmpcount = (attrs.value(i)).toInt(&ok);
00169 if (ok)
00170 count = tmpcount;
00171 }
00172 }
00173 for (int i = 0; i < count; ++i)
00174 write(" ");
00175 }
00176 return true;
00177 }
00178
00179 bool ContentReader::characters(const QString &ch)
00180 {
00181 QString tmp = ch;
00182 tmp = tmp.remove("\n");
00183 tmp = tmp.remove("");
00184 tmp = tmp.replace(QChar(160), SpecialChars::NBSPACE);
00185 if (append)
00186 write(tmp);
00187 return true;
00188 }
00189
00190 bool ContentReader::endElement(const QString&, const QString&, const QString &name)
00191 {
00192 if ((name == "text:p") || (name == "text:h"))
00193 {
00194 write("\n");
00195 append = false;
00196 if (inList || inNote || inNoteBody)
00197 styleNames.pop_back();
00198 else
00199 styleNames.clear();
00200 }
00201 else if (name == "text:span")
00202 {
00203 inSpan = false;
00204 currentStyle = pstyle;
00205 if (styleNames.size() != 0)
00206 styleNames.pop_back();
00207 currentStyle = sreader->getStyle(getName());
00208 }
00209 else if (name == "text:note")
00210 inNote = false;
00211 else if (name == "text:note-body")
00212 inNoteBody = false;
00213 else if (name == "text:line-break")
00214 write(SpecialChars::LINEBREAK);
00215 else if (name == "text:tab")
00216 write("\t");
00217 else if (name == "text:list")
00218 {
00219 --listLevel;
00220 styleNames.clear();
00221 if (listLevel == 0)
00222 {
00223 inList = false;
00224 listIndex2.clear();
00225 currentListStyle = 0;
00226 }
00227 else
00228 {
00229 currentStyle = sreader->getStyle(QString(currentList + "_%1").arg(listLevel));
00230 styleNames.push_back(QString(currentList + "_%1").arg(listLevel));
00231 currentListStyle->resetLevel();
00232 currentListStyle = sreader->getList(currentList);
00233 currentListStyle->setLevel(listLevel);
00234 }
00235 }
00236 else if ((name == "style:style") && (inT))
00237 {
00238 inT = false;
00239 tName = "";
00240 }
00241 return true;
00242 }
00243
00244 void ContentReader::write(const QString& text)
00245 {
00246 if (!inNote && !inNoteBody)
00247 {
00248 if (importTextOnly)
00249 writer->append(text);
00250 else if (inSpan)
00251 writer->append(text, currentStyle, false);
00252 else
00253 writer->append(text, currentStyle);
00254 }
00255 lastStyle = currentStyle;
00256 }
00257
00258 void ContentReader::parse(QString fileName)
00259 {
00260 sreader->parse(fileName);
00261 #if defined(_WIN32)
00262 QString fname = QDir::convertSeparators(fileName);
00263 QByteArray fn = (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based) ? fname.toUtf8() : fname.toLocal8Bit();
00264 #else
00265 QByteArray fn(fileName.toLocal8Bit());
00266 #endif
00267 xmlSAXParseFile(cSAXHandler, fn.data(), 1);
00268 }
00269
00270 xmlSAXHandler cSAXHandlerStruct = {
00271 NULL,
00272 NULL,
00273 NULL,
00274 NULL,
00275 NULL,
00276 NULL,
00277 NULL,
00278 NULL,
00279 NULL,
00280 NULL,
00281 NULL,
00282 NULL,
00283 NULL,
00284 NULL,
00285 ContentReader::startElement,
00286 ContentReader::endElement,
00287 NULL,
00288 ContentReader::characters,
00289 NULL,
00290 NULL,
00291 NULL,
00292 NULL,
00293 NULL,
00294 NULL,
00295 NULL,
00296 NULL,
00297 NULL,
00298 1
00299 #ifdef HAVE_XML26
00300 ,
00301 NULL,
00302 NULL,
00303 NULL,
00304 NULL
00305 #endif
00306 };
00307
00308 xmlSAXHandlerPtr cSAXHandler = &cSAXHandlerStruct;
00309
00310 void ContentReader::startElement(void*, const xmlChar *fullname, const xmlChar ** atts)
00311 {
00312 QString* name = new QString((const char*) fullname);
00313 name = new QString(name->toLower());
00314 QXmlAttributes* attrs = new QXmlAttributes();
00315 if (atts)
00316 {
00317 for(const xmlChar** cur = atts; cur && *cur; cur += 2)
00318 attrs->append(QString((char*)*cur), NULL, QString((char*)*cur), QString((char*)*(cur + 1)));
00319 }
00320 creader->startElement(NULL, NULL, *name, *attrs);
00321 }
00322
00323 void ContentReader::characters(void*, const xmlChar *ch, int len)
00324 {
00325 QString chars = QString::fromUtf8((const char*) ch, len);
00326 creader->characters(chars);
00327 }
00328
00329 void ContentReader::endElement(void*, const xmlChar *name)
00330 {
00331 QString *nname = new QString((const char*) name);
00332 nname = new QString(nname->toLower());
00333 creader->endElement(NULL, NULL, *nname);
00334 }
00335
00336 QString ContentReader::getName()
00337 {
00338 QString s = "";
00339 for (uint i = 0; i < styleNames.size(); ++i)
00340 s += styleNames[i];
00341 return s;
00342 }
00343
00344 void ContentReader::getStyle()
00345 {
00346 gtParagraphStyle* par = NULL;
00347 if (styleNames.size() == 0)
00348 par = dynamic_cast<gtParagraphStyle*>(sreader->getStyle("default-style"));
00349 else
00350 par = dynamic_cast<gtParagraphStyle*>(sreader->getStyle(styleNames[0]));
00351 assert(par != NULL);
00352 gtParagraphStyle* tmp = new gtParagraphStyle(*par);
00353 for (uint i = 1; i < styleNames.size(); ++i)
00354 {
00355 Properties& p = tmap[styleNames[i]];
00356 for (uint j = 0; j < p.size(); ++j)
00357 sreader->updateStyle(tmp, sreader->getStyle(styleNames[i - 1]), p[j].first, p[j].second);
00358 }
00359
00360 currentStyle = tmp;
00361 sreader->setStyle(getName(), tmp);
00362 }
00363
00364 ContentReader::~ContentReader()
00365 {
00366 creader = NULL;
00367 delete defaultStyle;
00368 }