diff options
| author | craig <craig@11d20701-8431-0410-a711-e3c959e3b870> | 2012-01-01 11:40:09 +0000 |
|---|---|---|
| committer | craig <craig@11d20701-8431-0410-a711-e3c959e3b870> | 2012-01-01 11:40:09 +0000 |
| commit | 7ed83b6c6666eb8b6b104c211ae7e52907350372 (patch) | |
| tree | 4430b556abac0ad660a0aacf1887d77f85d8be02 /scribus/plugins/gettext/odtim | |
| download | scribus-7ed83b6c6666eb8b6b104c211ae7e52907350372.tar.gz scribus-7ed83b6c6666eb8b6b104c211ae7e52907350372.tar.xz scribus-7ed83b6c6666eb8b6b104c211ae7e52907350372.zip | |
Branch 1.3.5 tree to 1.4.x tree, goodbye 1.3.x
git-svn-id: svn://scribus.net/branches/Version14x/Scribus@17163 11d20701-8431-0410-a711-e3c959e3b870
Diffstat (limited to 'scribus/plugins/gettext/odtim')
| -rw-r--r-- | scribus/plugins/gettext/odtim/CMakeLists.txt | 31 | ||||
| -rw-r--r-- | scribus/plugins/gettext/odtim/contentreader.cpp | 402 | ||||
| -rw-r--r-- | scribus/plugins/gettext/odtim/contentreader.h | 90 | ||||
| -rw-r--r-- | scribus/plugins/gettext/odtim/odtdia.cpp | 123 | ||||
| -rw-r--r-- | scribus/plugins/gettext/odtim/odtdia.h | 56 | ||||
| -rw-r--r-- | scribus/plugins/gettext/odtim/odtim.cpp | 129 | ||||
| -rw-r--r-- | scribus/plugins/gettext/odtim/odtim.h | 58 | ||||
| -rw-r--r-- | scribus/plugins/gettext/odtim/stylereader.cpp | 1101 | ||||
| -rw-r--r-- | scribus/plugins/gettext/odtim/stylereader.h | 164 |
9 files changed, 2154 insertions, 0 deletions
diff --git a/scribus/plugins/gettext/odtim/CMakeLists.txt b/scribus/plugins/gettext/odtim/CMakeLists.txt new file mode 100644 index 0000000..5477138 --- /dev/null +++ b/scribus/plugins/gettext/odtim/CMakeLists.txt @@ -0,0 +1,31 @@ +INCLUDE_DIRECTORIES( +${CMAKE_SOURCE_DIR} +${CMAKE_SOURCE_DIR}/scribus +) + +SET(ODT_IM_PLUGIN_MOC_CLASSES +odtdia.h +) + +SET(ODT_IM_PLUGIN_SOURCES +contentreader.cpp +odtdia.cpp +odtim.cpp +stylereader.cpp +) + +SET(SCRIBUS_ODT_IM_PLUGIN "odtimplugin") + +QT4_WRAP_CPP(ODT_IM_PLUGIN_MOC_SOURCES ${ODT_IM_PLUGIN_MOC_CLASSES}) + +ADD_LIBRARY(${SCRIBUS_ODT_IM_PLUGIN} MODULE ${ODT_IM_PLUGIN_SOURCES} ${ODT_IM_PLUGIN_MOC_SOURCES}) + +TARGET_LINK_LIBRARIES(${SCRIBUS_ODT_IM_PLUGIN} ${PLUGIN_LIBRARIES}) + +INSTALL(TARGETS ${SCRIBUS_ODT_IM_PLUGIN} + LIBRARY + DESTINATION ${PLUGINDIR}gettext + PERMISSIONS ${PLUGIN_PERMISSIONS} +) + +# SET_TARGET_PROPERTIES(${SCRIBUS_FONTPREVIEW_PLUGIN} PROPERTIES VERSION "0.0.0") diff --git a/scribus/plugins/gettext/odtim/contentreader.cpp b/scribus/plugins/gettext/odtim/contentreader.cpp new file mode 100644 index 0000000..4de539d --- /dev/null +++ b/scribus/plugins/gettext/odtim/contentreader.cpp @@ -0,0 +1,402 @@ +/* +For general Scribus (>=1.3.2) copyright and licensing information please refer +to the COPYING file provided with the program. Following this notice may exist +a copyright and/or license notice that predates the release of Scribus 1.3.2 +for which a new license (GPL+exception) is in place. +*/ +/*************************************************************************** + * Copyright (C) 2004 by Riku Leino * + * tsoots@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include <QGlobalStatic> +#include <QByteArray> +#include "contentreader.h" +#include "scribusstructs.h" + +ContentReader* ContentReader::creader = NULL; + +extern xmlSAXHandlerPtr cSAXHandler; + +ContentReader::ContentReader(QString documentName, StyleReader *s, gtWriter *w, bool textOnly) +{ + creader = this; + docname = documentName; + sreader = s; + writer = w; + importTextOnly = textOnly; + defaultStyle = NULL; + currentStyle = NULL; + inList = false; + inNote = false; + inAnnotation = false; + inNoteBody = false; + inSpan = false; + append = 0; + listIndex = 0; + listLevel = 0; + currentList = ""; + currentListStyle = 0; + inT = false; + tName = ""; +} + +bool ContentReader::startElement(const QString&, const QString&, const QString &name, const QXmlAttributes &attrs) +{ + if ((name == "text:p") || (name == "text:h")) + { + ++append; + QString name = ""; + for (int i = 0; i < attrs.count(); ++i) + { + if (attrs.localName(i) == "text:style-name") + { + name = attrs.value(i); + styleNames.push_back(attrs.value(i)); + } + } + if (!inList) + { + pstyle = sreader->getStyle(name); + currentStyle = pstyle; + } + else + { + gtStyle *tmp = sreader->getStyle(getName()); + if ((tmp->getName()).indexOf("default-style") != -1) + getStyle(); + else + currentStyle = tmp; + } + } + else if (name == "text:span") + { + inSpan = true; + QString styleName = ""; + for (int i = 0; i < attrs.count(); ++i) + { + if (attrs.localName(i) == "text:style-name") + { + currentStyle = sreader->getStyle(attrs.value(i)); + styleName = attrs.value(i); + styleNames.push_back(styleName); + } + } + gtStyle *tmp = sreader->getStyle(getName()); + if ((tmp->getName()).indexOf("default-style") != -1) + getStyle(); + else + currentStyle = tmp; + } + else if (name == "text:list") + { + inList = true; + ++listLevel; + if (static_cast<int>(listIndex2.size()) < listLevel) + listIndex2.push_back(0); + for (int i = 0; i < attrs.count(); ++i) + { + if (attrs.localName(i) == "text:style-name") + currentList = attrs.value(i); + } + currentStyle = sreader->getStyle(QString(currentList + "_%1").arg(listLevel)); + currentListStyle = sreader->getList(currentList); + if (currentListStyle) + currentListStyle->setLevel(listLevel); + styleNames.clear(); + styleNames.push_back(QString(currentList + "_%1").arg(listLevel)); + } + else if (name == "text:list-item") + { + if (currentListStyle) + { + currentListStyle->advance(); + write(currentListStyle->bullet()); + } + } + else if (name == "office:annotation") + inAnnotation = true; + else if (name == "text:note") + inNote = true; + else if (name == "text:note-body") + inNoteBody = true; + else if (name == "style:style") + { + QString sname = ""; + bool isTextStyle = false; + for (int i = 0; i < attrs.count(); ++i) + { + if (attrs.localName(i) == "style:name") + sname = attrs.value(i); + else if ((attrs.localName(i) == "style:family") && (attrs.value(i) == "text")) + isTextStyle = true; + } + if (isTextStyle) + { + tName = sname; + inT = true; + } + } + else if ((name == "style:paragraph-properties" || + name == "style:text-properties" || + name == "style:list-level-properties") && (inT)) + { + Properties p; + for (int i = 0; i < attrs.count(); ++i) + { + std::pair<QString, QString> pair(attrs.localName(i), attrs.value(i)); + p.push_back(pair); + } + tmap[tName] = p; + } + else if (name == "text:s") + { + int count = 1; + for (int i = 0; i < attrs.count(); ++i) + { + if (attrs.localName(i) == "text:c") + { + bool ok = false; + int tmpcount = (attrs.value(i)).toInt(&ok); + if (ok) + count = tmpcount; + } + } + for (int i = 0; i < count; ++i) + write(" "); + } + return true; +} + +bool ContentReader::characters(const QString &ch) +{ + QString tmp = ch; + tmp = tmp.remove("\n"); + tmp = tmp.remove(""); // Remove all OO.o hyphenation chars + // Unneeded as scribus now also use standard unicode non-breakable space + // tmp = tmp.replace(QChar(160), SpecialChars::NBSPACE); // replace OO.o nbsp with Scribus nbsp + if (append > 0) + write(tmp); + return true; +} + +bool ContentReader::endElement(const QString&, const QString&, const QString &name) +{ + if ((name == "text:p") || (name == "text:h")) + { +// qDebug("TPTH"); + write("\n"); + --append; + if (inList || inAnnotation || inNote || inNoteBody) + { + if(static_cast<int>(styleNames.size()) > 0) + styleNames.pop_back(); + } + else + styleNames.clear(); + } + else if (name == "text:span") + { +// qDebug("TS"); + inSpan = false; + currentStyle = pstyle; + if (styleNames.size() != 0) + styleNames.pop_back(); + currentStyle = sreader->getStyle(getName()); + } + else if (name == "office:annotation") + { + inAnnotation = false; + } + else if (name == "text:note") + { +// qDebug("TN"); + inNote = false; + } + else if (name == "text:note-body") + { +// qDebug("TNB"); + inNoteBody = false; + } + else if (name == "text:line-break") + { +// qDebug("TLB"); + write(SpecialChars::LINEBREAK); + } + else if (name == "text:tab") + { +// qDebug("TT"); + write("\t"); + } + else if (name == "text:list") + { +// qDebug("TL"); + --listLevel; + styleNames.clear(); + if (listLevel == 0) + { + inList = false; + listIndex2.clear(); + currentListStyle = 0; + } + else + { + currentStyle = sreader->getStyle(QString(currentList + "_%1").arg(listLevel)); + styleNames.push_back(QString(currentList + "_%1").arg(listLevel)); + if (currentListStyle) + currentListStyle->resetLevel(); + currentListStyle = sreader->getList(currentList); + if (currentListStyle) + currentListStyle->setLevel(listLevel); + } + } + else if ((name == "style:style") && (inT)) + { +// qDebug("SS"); + inT = false; + tName = ""; + } + return true; +} + +void ContentReader::write(const QString& text) +{ + if (!inNote && !inNoteBody && !inAnnotation) // Disable notes import for now + { + if (importTextOnly) + writer->appendUnstyled(text); + else if (inSpan) + writer->append(text, currentStyle, false); + else + writer->append(text, currentStyle); + } + lastStyle = currentStyle; +} + +void ContentReader::parse(QString fileName) +{ + sreader->parse(fileName); +#if defined(_WIN32) + QString fname = QDir::toNativeSeparators(fileName); + QByteArray fn = (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based) ? fname.toUtf8() : fname.toLocal8Bit(); +#else + QByteArray fn(fileName.toLocal8Bit()); +#endif + xmlSAXParseFile(cSAXHandler, fn.data(), 1); +} + +xmlSAXHandler cSAXHandlerStruct = { + NULL, // internalSubset, + NULL, // isStandalone, + NULL, // hasInternalSubset, + NULL, // hasExternalSubset, + NULL, // resolveEntity, + NULL, // getEntity, + NULL, // entityDecl, + NULL, // notationDecl, + NULL, // attributeDecl, + NULL, // elementDecl, + NULL, // unparsedEntityDecl, + NULL, // setDocumentLocator, + NULL, // startDocument, + NULL, // endDocument, + ContentReader::startElement, + ContentReader::endElement, + NULL, // reference, + ContentReader::characters, + NULL, // ignorableWhitespace, + NULL, // processingInstruction, + NULL, // comment, + NULL, // warning, + NULL, // error, + NULL, // fatalError, + NULL, // getParameterEntity, + NULL, // cdata, + NULL, + 1 +#ifdef HAVE_XML26 + , + NULL, + NULL, + NULL, + NULL +#endif +}; + +xmlSAXHandlerPtr cSAXHandler = &cSAXHandlerStruct; + +void ContentReader::startElement(void*, const xmlChar *fullname, const xmlChar ** atts) +{ + QString name(QString((const char*) fullname).toLower()); + QXmlAttributes attrs; + if (atts) + { + for(const xmlChar** cur = atts; cur && *cur; cur += 2) + attrs.append(QString((char*)*cur), NULL, QString((char*)*cur), QString((char*)*(cur + 1))); + } + creader->startElement(NULL, NULL, name, attrs); +} + +void ContentReader::characters(void*, const xmlChar *ch, int len) +{ + QString chars = QString::fromUtf8((const char*) ch, len); + creader->characters(chars); +} + +void ContentReader::endElement(void*, const xmlChar *name) +{ + QString nname(QString((const char*) name).toLower()); + creader->endElement(NULL, NULL, nname); +} + +QString ContentReader::getName() +{ + QString s = ""; + for (uint i = 0; i < styleNames.size(); ++i) + s += styleNames[i]; + return s; +} + +void ContentReader::getStyle() +{ + gtStyle *style = NULL, *tmp = NULL; + if (styleNames.size() == 0) + style = sreader->getStyle("default-style"); + else + style = sreader->getStyle(styleNames[0]); + assert (style != NULL); + gtParagraphStyle* par = dynamic_cast<gtParagraphStyle*>(style); + if (par) + tmp = new gtParagraphStyle(*par); + else + tmp = new gtStyle(*style); + for (uint i = 1; i < styleNames.size(); ++i) + { + Properties& p = tmap[styleNames[i]]; + for (uint j = 0; j < p.size(); ++j) + sreader->updateStyle(tmp, sreader->getStyle(styleNames[i - 1]), p[j].first, p[j].second); + } + currentStyle = tmp; + sreader->setStyle(getName(), tmp); +} + +ContentReader::~ContentReader() +{ + creader = NULL; + delete defaultStyle; +} diff --git a/scribus/plugins/gettext/odtim/contentreader.h b/scribus/plugins/gettext/odtim/contentreader.h new file mode 100644 index 0000000..8467ef9 --- /dev/null +++ b/scribus/plugins/gettext/odtim/contentreader.h @@ -0,0 +1,90 @@ +/* +For general Scribus (>=1.3.2) copyright and licensing information please refer +to the COPYING file provided with the program. Following this notice may exist +a copyright and/or license notice that predates the release of Scribus 1.3.2 +for which a new license (GPL+exception) is in place. +*/ +/*************************************************************************** + * Copyright (C) 2004 by Riku Leino * + * tsoots@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef CONTENTREADER_H +#define CONTENTREADER_H + +#include "scconfig.h" + +#include <utility> +#include <vector> +#ifdef HAVE_XML26 + #include <libxml/SAX2.h> +#else + #include <libxml/SAX.h> +#endif +#include <QXmlAttributes> +#include <QMap> +#include <gtstyle.h> +#include <gtwriter.h> +#include "stylereader.h" + +typedef std::vector<std::pair<QString, QString> > Properties; +typedef QMap<QString, Properties > TMap; + +class ContentReader +{ +private: + static ContentReader *creader; + TMap tmap; + QString docname; + StyleReader* sreader; + gtWriter *writer; + gtStyle *defaultStyle; + gtStyle *currentStyle; + gtStyle *lastStyle; + gtStyle *pstyle; + bool importTextOnly; + bool inList; + bool inAnnotation; + bool inNote; + bool inNoteBody; + bool inSpan; + int append; + int listLevel; + int listIndex; + ListStyle *currentListStyle; + std::vector<int> listIndex2; + bool inT; + std::vector<QString> styleNames; + QString tName; + QString currentList; + void write(const QString& text); + QString getName(); + void getStyle(); +public: + ContentReader(QString documentName, StyleReader* s, gtWriter *w, bool textOnly); + ~ContentReader(); + static void startElement(void *user_data, const xmlChar *fullname, const xmlChar ** atts); + static void endElement(void *user_data, const xmlChar *name); + static void characters(void *user_data, const xmlChar *ch, int len); + bool startElement(const QString&, const QString&, const QString &name, const QXmlAttributes &attrs); + bool endElement(const QString&, const QString&, const QString &name); + bool characters(const QString &ch); + void parse(QString fileName); +}; + +#endif diff --git a/scribus/plugins/gettext/odtim/odtdia.cpp b/scribus/plugins/gettext/odtim/odtdia.cpp new file mode 100644 index 0000000..b104fde --- /dev/null +++ b/scribus/plugins/gettext/odtim/odtdia.cpp @@ -0,0 +1,123 @@ +/* +For general Scribus (>=1.3.2) copyright and licensing information please refer +to the COPYING file provided with the program. Following this notice may exist +a copyright and/or license notice that predates the release of Scribus 1.3.2 +for which a new license (GPL+exception) is in place. +*/ + /*************************************************************************** + * Copyright (C) 2004 by Riku Leino * + * tsoots@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "odtdia.h" + +#include <QToolTip> +#include <QBoxLayout> +#include <QVBoxLayout> +#include <QPixmap> +#include <QHBoxLayout> +#include <QCheckBox> +#include <QPushButton> +#include "scribusapi.h" +#include "util_icon.h" + +OdtDialog::OdtDialog(bool update, bool prefix, bool pack) : QDialog(0) +{ + setModal(true); + setWindowIcon(QIcon(loadIcon ( "AppIcon.png" ))); + setWindowTitle( tr("OpenDocument Importer Options")); + + QBoxLayout* layout = new QVBoxLayout(this); + layout->setMargin(0); + layout->setSpacing(0); + + QBoxLayout* hlayout = new QHBoxLayout; + hlayout->setMargin(5); + hlayout->setSpacing(5); + updateCheck = new QCheckBox( tr("Overwrite Paragraph Styles"), this); + updateCheck->setChecked(update); + updateCheck->setToolTip( "<qt>" + tr("Enabling this will overwrite existing styles in the current Scribus document") + "</qt>"); + hlayout->addWidget(updateCheck); + layout->addLayout(hlayout); + + QBoxLayout* palayout = new QHBoxLayout; + palayout->setMargin(5); + palayout->setSpacing(5); + packCheck = new QCheckBox( tr("Merge Paragraph Styles"), this); + packCheck->setChecked(pack); + packCheck->setToolTip( "<qt>" + tr("Merge paragraph styles by attributes. This will result in fewer similar paragraph styles, will retain style attributes, even if the original document's styles are named differently.") +"</qt>"); + palayout->addWidget(packCheck); + layout->addLayout(palayout); + + QBoxLayout* playout = new QHBoxLayout; + playout->setMargin(5); + playout->setSpacing(5); + prefixCheck = new QCheckBox( tr("Use document name as a prefix for paragraph styles"), this); + prefixCheck->setChecked(prefix); + prefixCheck->setToolTip( "<qt>" + tr("Prepend the document name to the paragraph style name in Scribus.") +"</qt>"); + playout->addWidget(prefixCheck); + layout->addLayout(playout); + + QBoxLayout* dlayout = new QHBoxLayout; + dlayout->setMargin(5); + dlayout->setSpacing(5); + doNotAskCheck = new QCheckBox( tr("Do not ask again"), this); + doNotAskCheck->setChecked(false); + doNotAskCheck->setToolTip( "<qt>" + tr("Make these settings the default and do not prompt again when importing an OASIS OpenDocument.") +"</qt>"); + //dlayout->addStretch(10); + dlayout->addWidget(doNotAskCheck); + layout->addLayout(dlayout); + + QBoxLayout* blayout = new QHBoxLayout; + blayout->setMargin(5); + blayout->setSpacing(5); + blayout->addStretch(10); + okButton = new QPushButton( tr("OK"), this); + blayout->addWidget(okButton); + cancelButton = new QPushButton( tr("Cancel"), this); + blayout->addWidget(cancelButton); + layout->addLayout(blayout); + + connect(okButton, SIGNAL(clicked()), this, SLOT(accept())); + connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject())); +} + +bool OdtDialog::shouldUpdate() +{ + return updateCheck->isChecked(); +} + +bool OdtDialog::usePrefix() +{ + return prefixCheck->isChecked(); +} + +bool OdtDialog::askAgain() +{ + return !(doNotAskCheck->isChecked()); +} + +bool OdtDialog::packStyles() +{ + return packCheck->isChecked(); +} + +OdtDialog::~OdtDialog() +{ + +} diff --git a/scribus/plugins/gettext/odtim/odtdia.h b/scribus/plugins/gettext/odtim/odtdia.h new file mode 100644 index 0000000..3435d85 --- /dev/null +++ b/scribus/plugins/gettext/odtim/odtdia.h @@ -0,0 +1,56 @@ +/* +For general Scribus (>=1.3.2) copyright and licensing information please refer +to the COPYING file provided with the program. Following this notice may exist +a copyright and/or license notice that predates the release of Scribus 1.3.2 +for which a new license (GPL+exception) is in place. +*/ + /*************************************************************************** + * Copyright (C) 2004 by Riku Leino * + * tsoots@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef ODTDIA_H +#define ODTDIA_H + +#include "scconfig.h" + +#include <QDialog> +class QCheckBox; +class QPushButton; + +class OdtDialog : public QDialog +{ + Q_OBJECT + +public: + OdtDialog(bool update, bool prefix, bool pack); + ~OdtDialog(); + bool shouldUpdate(); + bool usePrefix(); + bool askAgain(); + bool packStyles(); +private: + QCheckBox* updateCheck; + QCheckBox* prefixCheck; + QCheckBox* doNotAskCheck; + QCheckBox* packCheck; + QPushButton* okButton; + QPushButton* cancelButton; +}; + +#endif // ODTDIA_H diff --git a/scribus/plugins/gettext/odtim/odtim.cpp b/scribus/plugins/gettext/odtim/odtim.cpp new file mode 100644 index 0000000..6941a82 --- /dev/null +++ b/scribus/plugins/gettext/odtim/odtim.cpp @@ -0,0 +1,129 @@ +/* +For general Scribus (>=1.3.2) copyright and licensing information please refer +to the COPYING file provided with the program. Following this notice may exist +a copyright and/or license notice that predates the release of Scribus 1.3.2 +for which a new license (GPL+exception) is in place. +*/ +/*************************************************************************** + * Copyright (C) 2004 by Riku Leino * + * tsoots@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "odtim.h" + +#ifndef HAVE_XML +#error The odtim plugin requires libxml to build +#endif + +#include <QStringList> + +#include <scribusstructs.h> +#include "prefsmanager.h" +#include <prefsfile.h> +#include <prefscontext.h> +#include <prefstable.h> +#include "fileunzip.h" +#include "stylereader.h" +#include "contentreader.h" +#include "odtdia.h" + +QString FileFormatName() +{ + return QObject::tr("OpenDocument Text Documents"); +} + +QStringList FileExtensions() +{ + return QStringList("odt"); +} + +void GetText(QString filename, QString encoding, bool textOnly, gtWriter *writer) +{ + OdtIm* sim = new OdtIm(filename, encoding, writer, textOnly); + delete sim; +} + +/********** Class OdtIm ************************************************************/ + +OdtIm::OdtIm(QString fileName, QString enc, gtWriter* w, bool textOnly) +{ + PrefsContext* prefs = PrefsManager::instance()->prefsFile->getPluginContext("OdtIm"); + bool update = prefs->getBool("update", true); + bool prefix = prefs->getBool("prefix", true); + bool ask = prefs->getBool("askAgain", true); + bool pack = prefs->getBool("pack", true); + encoding = enc; + if (!textOnly) + { + if (ask) + { + OdtDialog* sxwdia = new OdtDialog(update, prefix, pack); + if (sxwdia->exec()) { + update = sxwdia->shouldUpdate(); + prefix = sxwdia->usePrefix(); + pack = sxwdia->packStyles(); + prefs->set("update", update); + prefs->set("prefix", sxwdia->usePrefix()); + prefs->set("askAgain", sxwdia->askAgain()); + prefs->set("pack", sxwdia->packStyles()); + delete sxwdia; + } else { + delete sxwdia; + return; + } + } + } + filename = fileName; + writer = w; + writer->setUpdateParagraphStyles(update); + FileUnzip* fun = new FileUnzip(fileName); + stylePath = fun->getFile(STYLE); + contentPath = fun->getFile(CONTENT); + delete fun; + // Qt4 NULL -> isNull() + if ((!stylePath.isNull()) && (!contentPath.isNull())) + { + QString docname = filename.right(filename.length() - filename.lastIndexOf("/") - 1); + docname = docname.left(docname.lastIndexOf(".")); + StyleReader *sreader = new StyleReader(docname, writer, textOnly, prefix, pack); + sreader->parse(stylePath); + ContentReader *creader = new ContentReader(docname, sreader, writer, textOnly); + creader->parse(contentPath); + delete sreader; + delete creader; + QFile f1(stylePath); + f1.remove(); + QFile f2(contentPath); + f2.remove(); + } + else if ((stylePath.isNull()) && (!contentPath.isNull())) + { + QFile f2(contentPath); + f2.remove(); + } + else if ((!stylePath.isNull()) && (contentPath.isNull())) + { + QFile f1(stylePath); + f1.remove(); + } +} + +OdtIm::~OdtIm() +{ + +} diff --git a/scribus/plugins/gettext/odtim/odtim.h b/scribus/plugins/gettext/odtim/odtim.h new file mode 100644 index 0000000..eb32e3e --- /dev/null +++ b/scribus/plugins/gettext/odtim/odtim.h @@ -0,0 +1,58 @@ +/* +For general Scribus (>=1.3.2) copyright and licensing information please refer +to the COPYING file provided with the program. Following this notice may exist +a copyright and/or license notice that predates the release of Scribus 1.3.2 +for which a new license (GPL+exception) is in place. +*/ +/*************************************************************************** + * Copyright (C) 2004 by Riku Leino * + * tsoots@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef SXWIM_H +#define SXWIM_H + +#include <QString> +#include <gtwriter.h> +#include "scconfig.h" +#include "pluginapi.h" + +extern "C" PLUGIN_API void GetText(QString filename, QString encoding, bool textOnly, gtWriter *writer); + +extern "C" PLUGIN_API QString FileFormatName(); + +extern "C" PLUGIN_API QStringList FileExtensions(); + +const QString STYLE = "styles.xml"; +const QString CONTENT = "content.xml"; + +class OdtIm +{ +private: + gtWriter* writer; + QString encoding; + QString filename; + QString stylePath; + QString contentPath; + bool decompress(); +public: + OdtIm(QString fileName, QString encoding, gtWriter* w, bool textOnly); + ~OdtIm(); +}; + +#endif // SXWIM_H diff --git a/scribus/plugins/gettext/odtim/stylereader.cpp b/scribus/plugins/gettext/odtim/stylereader.cpp new file mode 100644 index 0000000..6c2ea96 --- /dev/null +++ b/scribus/plugins/gettext/odtim/stylereader.cpp @@ -0,0 +1,1101 @@ +/* +For general Scribus (>=1.3.2) copyright and licensing information please refer +to the COPYING file provided with the program. Following this notice may exist +a copyright and/or license notice that predates the release of Scribus 1.3.2 +for which a new license (GPL+exception) is in place. +*/ + /*************************************************************************** + * Copyright (C) 2004 by Riku Leino * + * tsoots@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "stylereader.h" + +#include <scribusstructs.h> +#include <gtmeasure.h> +#include <gtparagraphstyle.h> +#include <gtframestyle.h> +#include <gtfont.h> +#include <QByteArray> + +StyleReader* StyleReader::sreader = NULL; + +extern xmlSAXHandlerPtr sSAXHandler; + +StyleReader::StyleReader(QString documentName, gtWriter *w, + bool textOnly, bool prefix, bool combineStyles) +{ + sreader = this; + docname = documentName; + readProperties = false; + writer = w; + importTextOnly = textOnly; + usePrefix = prefix; + packStyles = combineStyles; + currentStyle = 0; + currentListStyle = 0; + parentStyle = 0; + inList = false; + currentList = ""; + defaultStyleCreated = false; +} + + bool StyleReader::startElement(const QString&, const QString&, const QString &name, const QXmlAttributes &attrs) + { + if (name == "style:default-style") + defaultStyle(attrs); + else if (name == "style:paragraph-properties" || + name == "style:text-properties" || + name == "style:list-level-properties") + styleProperties(attrs); + else if (name == "style:style") + styleStyle(attrs); + else if (name == "style:tab-stop") + tabStop(attrs); + else if (name == "text:list-style") + { + for (int i = 0; i < attrs.count(); ++i) + if (attrs.localName(i) == "style:name") + currentList = attrs.value(i); + currentListStyle = new ListStyle(currentList); + inList = true; + } + else if (((name == "text:list-level-style-bullet") || + (name == "text:list-level-style-number") || + (name == "text:list-level-style-image")) && (inList)) + { + BulletType bstyle = Bullet; + QString prefix = ""; + QString suffix = ""; + QString bullet = "-"; + uint ulevel = 0; + uint displayLevels = 1; + uint startAt = 0; + QString level = ""; + for (int i = 0; i < attrs.count(); ++i) + { + if (attrs.localName(i) == "text:level") + { + ulevel = QString(attrs.value(i)).toUInt(); + gtStyle *plist; + if (attrs.value(i) == "1") + { + plist = listParents[currentList]; + } + else + { + int level = (attrs.value(i)).toInt(); + --level; + plist = styles[QString(currentList + "_%1").arg(level)]; + } + gtParagraphStyle *pstyle; + if (plist == NULL) + { + if (styles.contains("default-style")) + plist = new gtStyle(*(styles["default-style"])); + else + { + gtParagraphStyle* pstyle = new gtParagraphStyle(*(writer->getDefaultStyle())); + pstyle->setDefaultStyle(true); + plist = dynamic_cast<gtStyle*>(pstyle); + } + } + + if (plist->target() == "paragraph") + { + pstyle = dynamic_cast<gtParagraphStyle*>(plist); + assert(pstyle != NULL); + gtParagraphStyle* tmp = new gtParagraphStyle(*pstyle); + currentStyle = tmp; + } + else + { + gtParagraphStyle* tmp = new gtParagraphStyle(*plist); + currentStyle = tmp; + } + currentStyle->setName(currentList + "_" + attrs.value(i)); + } + else if (attrs.localName(i) == "style:num-prefix") + prefix = attrs.value(i); + else if (attrs.localName(i) == "style:num-suffix") + suffix = attrs.value(i); + /*else if (attrs.localName(i) == "text:bullet-char") + bullet = attrs.value(i);*/ + else if (attrs.localName(i) == "style:num-format") { + QString tmp = attrs.value(i); + if (tmp == "i") + bstyle = LowerRoman; + else if (tmp == "I") + bstyle = UpperRoman; + else if (tmp == "a") + bstyle = LowerAlpha; + else if (tmp == "A") + bstyle = UpperAlpha; + else if (tmp == "1") + bstyle = Number; + } + else if (attrs.localName(i) == "text:start-value") { + startAt = QString(attrs.value(i)).toUInt(); + if (startAt > 0) + --startAt; + } + else if (attrs.localName(i) == "text:display-levels") { + displayLevels = QString(attrs.value(i)).toUInt(); + if (displayLevels == 0) + displayLevels = 1; + } + } + if (bstyle == Bullet) { + prefix = ""; + suffix = ""; + } + ListLevel *llevel = new ListLevel(ulevel, bstyle, prefix, suffix, bullet, displayLevels, startAt); + currentListStyle->addLevel(ulevel, llevel); + readProperties = true; + } + else if ((name == "style:drop-cap") && (readProperties)) + { + if (currentStyle->target() == "paragraph") + { + for (int i = 0; i < attrs.count(); ++i) + { + if (attrs.localName(i) == "style:lines") + { + bool ok = false; + QString sd = attrs.value(i); + int dh = sd.toInt(&ok); + if (ok) + { + gtParagraphStyle* s = dynamic_cast<gtParagraphStyle*>(currentStyle); + assert(s != NULL); + s->setDropCapHeight(dh); + s->setDropCap(true); + } + } + } + } + } + else if (name == "style:font-face") + { + QString key = ""; + QString family = ""; + QString style = ""; + for (int i = 0; i < attrs.count(); ++i) + { + if (attrs.localName(i) == "style:name") + key = attrs.value(i); + else if (attrs.localName(i) == "svg:font-family") + { + family = attrs.value(i); + family = family.remove("'"); + } + else if (attrs.localName(i) == "style:font-style-name") + style += attrs.value(i) + " "; + } + QString name = family + " " + style; + name = name.simplified(); + fonts[key] = name; + } + return true; + } + + void StyleReader::defaultStyle(const QXmlAttributes& attrs) + { + currentStyle = NULL; + for (int i = 0; i < attrs.count(); ++i) + if (attrs.localName(i) == "style:family") + if (attrs.value(i) == "paragraph") + { + gtParagraphStyle* pstyle = new gtParagraphStyle(*(writer->getDefaultStyle())); + pstyle->setDefaultStyle(true); + currentStyle = dynamic_cast<gtStyle*>(pstyle); + currentStyle->setName("default-style"); + readProperties = true; + defaultStyleCreated = true; + } + } + + void StyleReader::styleProperties(const QXmlAttributes& attrs) + { + if ((currentStyle == NULL) || (!readProperties)) + return; + gtParagraphStyle* pstyle = NULL; + if (currentStyle->target() == "paragraph") + pstyle = dynamic_cast<gtParagraphStyle*>(currentStyle); + else + pstyle = NULL; + QString align = NULL; + QString force = NULL; + bool hasColorTag = false; + for (int i = 0; i < attrs.count(); ++i) + { + if ((attrs.localName(i) == "style:font-name") && (!inList)) + currentStyle->getFont()->setName(getFont(attrs.value(i))); + else if (attrs.localName(i) == "fo:font-size") + { + double size = 0; + double psize = 0; + if (parentStyle != NULL) + psize = static_cast<double>(parentStyle->getFont()->getSize()); + else if (styles.contains("default-style")) + psize = static_cast<double>(styles["default-style"]->getFont()->getSize()); + + psize = psize / 10; + size = getSize(attrs.value(i), psize); + int nsize = static_cast<int>(size * 10); + currentStyle->getFont()->setSize(nsize); + if (pstyle) + pstyle->setLineSpacing(writer->getPreferredLineSpacing(nsize)); + } + else if ((attrs.localName(i) == "fo:line-height") && (parentStyle != NULL)) + { + gtParagraphStyle* ppstyle; + if (parentStyle->target() == "paragraph") + { + ppstyle = dynamic_cast<gtParagraphStyle*>(parentStyle); + assert(ppstyle != NULL); + ppstyle->setLineSpacing(getSize(attrs.value(i), writer->getPreferredLineSpacing(currentStyle->getFont()->getSize()))); + } + } + else if (attrs.localName(i) == "fo:color") + { + currentStyle->getFont()->setColor(attrs.value(i)); + hasColorTag = true; + } + else if ((attrs.localName(i) == "style:use-window-font-color") && (attrs.value(i) == "true")) + { + currentStyle->getFont()->setColor("Black"); + hasColorTag = true; + } + else if ((attrs.localName(i) == "fo:font-weight") && (attrs.value(i) == "bold")) + currentStyle->getFont()->setWeight(BOLD); + else if ((attrs.localName(i) == "fo:font-style") && (attrs.value(i) == "italic")) + currentStyle->getFont()->setSlant(ITALIC); + else if ((attrs.localName(i) == "style:text-underline-style") && (attrs.value(i) != "none")) + currentStyle->getFont()->toggleEffect(UNDERLINE); + else if ((attrs.localName(i) == "style:text-crossing-out") && (attrs.value(i) != "none")) + currentStyle->getFont()->toggleEffect(STRIKETHROUGH); + else if ((attrs.localName(i) == "fo:font-variant") && (attrs.value(i) == "small-caps")) + currentStyle->getFont()->toggleEffect(SMALL_CAPS); + else if ((attrs.localName(i) == "style:text-outline") && (attrs.value(i) == "true")) + { + currentStyle->getFont()->toggleEffect(OUTLINE); + currentStyle->getFont()->setStrokeColor("Black"); + currentStyle->getFont()->setColor("White"); + } + else if (attrs.localName(i) == "fo:letter-spacing") + currentStyle->getFont()->setKerning(static_cast<int>(getSize(attrs.value(i), -1.0))); + else if (attrs.localName(i) == "style:text-scale") + currentStyle->getFont()->setHscale(static_cast<int>(getSize(attrs.value(i), -1.0))); + else if ((attrs.localName(i) == "style:text-position") && + (((attrs.value(i)).indexOf("sub") != -1) || + (((attrs.value(i)).left(1) == "-") && ((attrs.value(i)).left(1) != "0")))) + currentStyle->getFont()->toggleEffect(SUBSCRIPT); + else if ((attrs.localName(i) == "style:text-position") && + (((attrs.value(i)).indexOf("super") != -1) || + (((attrs.value(i)).left(1) != "-") && ((attrs.value(i)).left(1) != "0")))) + currentStyle->getFont()->toggleEffect(SUPERSCRIPT); + else if ((attrs.localName(i) == "fo:margin-top") && (pstyle != NULL)) + pstyle->setSpaceAbove(getSize(attrs.value(i))); + else if ((attrs.localName(i) == "fo:margin-bottom") && (pstyle != NULL)) + pstyle->setSpaceBelow(getSize(attrs.value(i))); + else if ((attrs.localName(i) == "fo:margin-left") && (pstyle != NULL)) + { + if (inList) + pstyle->setIndent(pstyle->getIndent() + getSize(attrs.value(i))); + else + pstyle->setIndent(getSize(attrs.value(i))); + } + else if ((attrs.localName(i) == "text:space-before") && (pstyle != NULL)) + { + /*if (inList) + pstyle->setIndent(pstyle->getIndent() + getSize(attrs.value(i))); + else*/ + pstyle->setIndent(getSize(attrs.value(i))); + } + else if ((attrs.localName(i) == "fo:text-indent") && (pstyle != NULL)) + pstyle->setFirstLineIndent(getSize(attrs.value(i))); + else if ((attrs.localName(i) == "fo:text-align") && (pstyle != NULL)) + align = attrs.value(i); + else if ((attrs.localName(i) == "style:justify-single-word") && (pstyle != NULL)) + force = attrs.value(i); + } + // Qt4 NULL -> isNull() + if (!align.isNull()) + { + if (align == "end") + pstyle->setAlignment(RIGHT); + else if (align == "center") + pstyle->setAlignment(CENTER); + else if (align == "justify") + { + if (force == "false") + pstyle->setAlignment(BLOCK); + else + pstyle->setAlignment(FORCED); + } + } + if (!hasColorTag) + currentStyle->getFont()->setColor("Black"); + } + + void StyleReader::styleStyle(const QXmlAttributes& attrs) + { + QString name = ""; + QString listName = NULL; + bool setDefaultStyle = false; + bool isParaStyle = false; + bool create = true; + + if (!defaultStyleCreated) + { + gtParagraphStyle* pstyle = new gtParagraphStyle(*(writer->getDefaultStyle())); + pstyle->setDefaultStyle(true); + currentStyle = dynamic_cast<gtStyle*>(pstyle); + currentStyle->setName("default-style"); + setDefaultStyle = true; + defaultStyleCreated = true; + parentStyle = currentStyle; + } + + for (int i = 0; i < attrs.count(); ++i) + { + if (attrs.localName(i) == "style:family") + { + if (attrs.value(i) == "paragraph") + { + isParaStyle = true; + readProperties = true; + } + else if (attrs.value(i) == "text") + { + isParaStyle = false; + readProperties = true; + } + else + { + readProperties = false; + return; + } + } + else if (attrs.localName(i) == "style:name") + name = attrs.value(i); + else if (attrs.localName(i) == "style:parent-style-name") + { + if (styles.contains(attrs.value(i))) + parentStyle = styles[attrs.value(i)]; + else + parentStyle = NULL; + } + else if (attrs.localName(i) == "style:list-style-name") + listName = attrs.value(i); + } + if ((parentStyle == NULL) && (styles.contains("default-style"))) + parentStyle = styles["default-style"]; + + if (create) + { + if (parentStyle == NULL) + { + parentStyle = new gtStyle("tmp-parent"); + } + if (isParaStyle) + { + gtParagraphStyle *tmpP; + if (parentStyle->target() == "paragraph") + { + tmpP = dynamic_cast<gtParagraphStyle*>(parentStyle); + assert(tmpP != NULL); + gtParagraphStyle* tmp = new gtParagraphStyle(*tmpP); + // tmp->setAutoLineSpacing(true); + currentStyle = tmp; + } + else + { + gtParagraphStyle* tmp = new gtParagraphStyle(*parentStyle); + // tmp->setAutoLineSpacing(true); + currentStyle = tmp; + } + if (!listName.isNull()) + { + listParents[listName] = currentStyle; + } + } + else + currentStyle = new gtStyle(*parentStyle); + + currentStyle->setName(name); + if (setDefaultStyle) + { + gtParagraphStyle* tmp = dynamic_cast<gtParagraphStyle*>(currentStyle); + if (tmp) + tmp->setDefaultStyle(true); + } + } + else + currentStyle = NULL; + } + + void StyleReader::tabStop(const QXmlAttributes& attrs) + { + if (currentStyle->target() == "paragraph") + { + gtParagraphStyle* pstyle = dynamic_cast<gtParagraphStyle*>(currentStyle); + assert(pstyle != NULL); + QString pos = NULL; + QString type = NULL; + for (int i = 0; i < attrs.count(); ++i) + { + if (attrs.localName(i) == "style:position") + pos = attrs.value(i); + else if (attrs.localName(i) == "style:type") + type = attrs.value(i); + + } + if (!pos.isNull()) + { + if (type.isNull()) + type = "left"; + double posd = getSize(pos); + if (type == "left") + pstyle->setTabValue(posd, LEFT_T); + else if (type == "right") + pstyle->setTabValue(posd, RIGHT_T); + else if (type == "center") + pstyle->setTabValue(posd, CENTER_T); + else + pstyle->setTabValue(posd, CENTER_T); + } + } + } + + bool StyleReader::endElement(const QString&, const QString&, const QString &name) + { + if ((name == "style:default-style") && (currentStyle != NULL) && (readProperties)) + { + setStyle(currentStyle->getName(), currentStyle); + currentStyle = NULL; + parentStyle = NULL; + readProperties = false; + } + else if (((name == "style:style") || + (name == "text:list-level-style-bullet") || + (name == "text:list-level-style-number") || + (name == "text:list-level-style-image")) && (currentStyle != NULL)) + { + setStyle(currentStyle->getName(), currentStyle); + currentStyle = NULL; + parentStyle = NULL; + readProperties = false; + } + else if (name == "text:list-style") + { + if (currentListStyle) { + lists[currentListStyle->name()] = currentListStyle; + currentListStyle = 0; + } + inList = false; + } + + return true; + } + + void StyleReader::parse(QString fileName) + { +#if defined(_WIN32) + QString fname = QDir::toNativeSeparators(fileName); + QByteArray fn = (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based) ? fname.toUtf8() : fname.toLocal8Bit(); +#else + QByteArray fn(fileName.toLocal8Bit()); +#endif + xmlSAXParseFile(sSAXHandler, fn.data(), 1); + } + + gtStyle* StyleReader::getDefaultStyle(void) + { + gtStyle* defStyle = writer->getDefaultStyle(); + StyleMap::Iterator it, itEnd = styles.end(); + for (it = styles.begin(); it != itEnd; ++it) + { + gtParagraphStyle *pStyle = dynamic_cast<gtParagraphStyle*> (it.value()); + if (pStyle && pStyle->isDefaultStyle()) + { + defStyle = pStyle; + break; + } + } + return defStyle; + } + + gtStyle* StyleReader::getStyle(const QString& name) + { + if (styles.contains(name)) + { + gtStyle* tmp = styles[name]; + QString tname = tmp->getName(); + if ((tname.indexOf(docname) == -1) && (usePrefix)) + tmp->setName(docname + "_" + tname); + + return tmp; + } + else + return getDefaultStyle(); + } + + void StyleReader::setStyle(const QString& name, gtStyle* style) + { + gtParagraphStyle *s; + QString tname = style->getName(); + if ((style->target() == "paragraph") && (packStyles)) + { + s = dynamic_cast<gtParagraphStyle*>(style); + assert(s != NULL); + QString nameByAttrs = QString("%1-").arg(s->getSpaceAbove()); + nameByAttrs += QString("%1-").arg(s->getSpaceBelow()); + nameByAttrs += QString("%1-").arg(s->getLineSpacing()); + nameByAttrs += QString("%1-").arg(s->getIndent()); + nameByAttrs += QString("%1-").arg(s->getFirstLineIndent()); + nameByAttrs += QString("%1-").arg(s->getAlignment()); + nameByAttrs += QString("%1-").arg(s->hasDropCap()); + nameByAttrs += QString("%1-").arg(s->getFont()->getColor()); + nameByAttrs += QString("%1-").arg(s->getFont()->getStrokeColor()); +// TODO is this important ?? +/* QValueList<double>* tmp = s->getTabValues(); + for (uint i = 0; i < tmp->count(); ++i) + { + double td = (*tmp)[i]; + nameByAttrs += QString("%1-").arg(td); + } */ + if (attrsStyles.contains(nameByAttrs)) + { + tname = attrsStyles[nameByAttrs]->getName(); + ++pstyleCounts[nameByAttrs]; + style->setName(tname); + } + else + { + attrsStyles[nameByAttrs] = style; + pstyleCounts[nameByAttrs] = 1; + tname = style->getName(); + } + } + else if (!packStyles) + { + attrsStyles[name] = style; + pstyleCounts[name] = 1; + tname = style->getName(); + } + if (!styles.contains(name)) + { + if ((tname.indexOf(docname) == -1) && (usePrefix)) + style->setName(docname + "_" + tname); + styles[name] = style; + } + } + + QString StyleReader::getFont(const QString& key) + { + if (fonts.contains(key)) + return fonts[key]; + else + return key; + } + + void StyleReader::setupFrameStyle() + { + QString fstyleName = ""; + int count = 0; + CounterMap::Iterator it; + for (it = pstyleCounts.begin(); it != pstyleCounts.end(); ++it) + { + if (it.value() > count) + { + count = it.value(); + fstyleName = it.key(); + } + } + gtFrameStyle* fstyle; + gtParagraphStyle* pstyle = dynamic_cast<gtParagraphStyle*>(attrsStyles[fstyleName]); + fstyle = new gtFrameStyle(*pstyle); + + if (!importTextOnly) + writer->setFrameStyle(fstyle); + delete fstyle; + } + +ListStyle* StyleReader::getList(const QString &name) +{ + ListStyle *tmp = 0; + if (lists.contains(name)) + tmp = lists[name]; + return tmp; +} + + bool StyleReader::updateStyle(gtStyle* style, gtStyle* parent2Style, const QString& key, const QString& value) + { + gtParagraphStyle* pstyle = NULL; + if (style->target() == "paragraph") + pstyle = dynamic_cast<gtParagraphStyle*>(style); + else + pstyle = NULL; + QString align = NULL; + QString force = NULL; + + if (key == "style:font-name") + style->getFont()->setName(getFont(value)); + else if (key == "fo:font-size") + { + double size = 0; + double psize = 0; + if (parent2Style != NULL) + psize = static_cast<double>(parent2Style->getFont()->getSize()); + else if (styles.contains("default-style")) + psize = static_cast<double>(styles["default-style"]->getFont()->getSize()); + psize = psize / 10; + size = getSize(value, psize); + int nsize = static_cast<int>(size * 10); + style->getFont()->setSize(nsize); + if (pstyle) + pstyle->setLineSpacing(writer->getPreferredLineSpacing(nsize)); + } + else if ((key == "fo:line-height") && (parent2Style != NULL)) + { + gtParagraphStyle* ppstyle; + if (parent2Style->target() == "paragraph") + { + ppstyle = dynamic_cast<gtParagraphStyle*>(parent2Style); + assert(ppstyle != NULL); + ppstyle->setLineSpacing(getSize(value, writer->getPreferredLineSpacing(style->getFont()->getSize()))); + } + } + else if (key == "fo:color") + style->getFont()->setColor(value); + else if ((key == "style:use-window-font-color") && (value == "true")) + style->getFont()->setColor("Black"); + else if ((key == "fo:font-weight") && (value == "bold")) + style->getFont()->setWeight(BOLD); + else if ((key == "fo:font-style") && (value == "italic")) + style->getFont()->setSlant(ITALIC); + else if ((key == "style:text-underline-style") && (value != "none")) + style->getFont()->toggleEffect(UNDERLINE); + else if ((key == "style:text-crossing-out") && (value != "none")) + style->getFont()->toggleEffect(STRIKETHROUGH); + else if ((key == "fo:font-variant") && (value == "small-caps")) + style->getFont()->toggleEffect(SMALL_CAPS); + else if ((key == "style:text-outline") && (value == "true")) + { + style->getFont()->toggleEffect(OUTLINE); + style->getFont()->setStrokeColor("Black"); + style->getFont()->setColor("White"); + } + else if (key == "fo:letter-spacing") + style->getFont()->setKerning(static_cast<int>(getSize(value, -1.0))); + else if (key == "style:text-scale") + style->getFont()->setHscale(static_cast<int>(getSize(value, -1.0))); + else if ((key == "style:text-position") && + (((value).indexOf("sub") != -1) || + (((value).left(1) == "-") && ((value).left(1) != "0")))) + style->getFont()->toggleEffect(SUBSCRIPT); + else if ((key == "style:text-position") && + (((value).indexOf("super") != -1) || + (((value).left(1) != "-") && ((value).left(1) != "0")))) + style->getFont()->toggleEffect(SUPERSCRIPT); + else if ((key == "fo:margin-top") && (pstyle != NULL)) + pstyle->setSpaceAbove(getSize(value)); + else if ((key == "fo:margin-bottom") && (pstyle != NULL)) + pstyle->setSpaceBelow(getSize(value)); + else if ((key == "fo:margin-left") && (pstyle != NULL)) + { + if (inList) + pstyle->setIndent(pstyle->getIndent() + getSize(value)); + else + pstyle->setIndent(getSize(value)); + } + else if ((key == "text:space-before") && (pstyle != NULL)) + { + if (inList) + pstyle->setIndent(pstyle->getIndent() + getSize(value)); + else + pstyle->setIndent(getSize(value)); + } + else if ((key == "fo:text-indent") && (pstyle != NULL)) + pstyle->setFirstLineIndent(getSize(value)); + else if ((key == "fo:text-align") && (pstyle != NULL)) + align = value; + else if ((key == "style:justify-single-word") && (pstyle != NULL)) + force = value; + + if (!align.isNull()) + { + assert(pstyle); + if (align == "end") + pstyle->setAlignment(RIGHT); + else if (align == "center") + pstyle->setAlignment(CENTER); + else if (align == "justify") + { + if (force != "false") + pstyle->setAlignment(FORCED); + else + pstyle->setAlignment(BLOCK); + } + } + + return true; + } + + double StyleReader::getSize(QString s, double parentSize) + { + QString dbl = "0.0"; + QString lowerValue = s.toLower(); + double ret = 0.0; + if (lowerValue.indexOf("pt") != -1) + { + dbl = lowerValue.remove("pt"); + ret = gtMeasure::d2d(dbl.toDouble(), SC_PT); + } + else if (lowerValue.indexOf("mm") != -1) + { + dbl = lowerValue.remove("mm"); + ret = gtMeasure::d2d(dbl.toDouble(), SC_MM); + } + else if (lowerValue.indexOf("cm") != -1) + { + dbl = lowerValue.remove("cm"); + ret = gtMeasure::d2d(dbl.toDouble() * 10, SC_MM); + } + else if (lowerValue.indexOf("in") != -1) + { + dbl = lowerValue.remove("inch"); + dbl = lowerValue.remove("in"); + ret = gtMeasure::d2d(dbl.toDouble(), SC_IN); + } + else if (lowerValue.indexOf("pi") != -1) + { + dbl = lowerValue.remove("pica"); + dbl = lowerValue.remove("pi"); + ret = gtMeasure::d2d(dbl.toDouble(), SC_P); + } + else if (lowerValue.indexOf("c") != -1) + { + dbl = lowerValue.remove("cicero"); + dbl = lowerValue.remove("c"); + ret = gtMeasure::d2d(dbl.toDouble(), SC_C); + } + else if (lowerValue.indexOf("%") != -1) + { + dbl = lowerValue.remove("%"); + double factor = dbl.toDouble(); + if (parentSize != -1.0) + { + factor = factor / 100; + ret = factor * parentSize; + } + else + ret = factor; + } + return ret; + } + + StyleReader::~StyleReader() + { + sreader = NULL; + StyleMap::Iterator it; + for (it = styles.begin(); it != styles.end(); ++it) + { + if (it.value()) + { + delete it.value(); + it.value() = NULL; + } + } + } + + xmlSAXHandler sSAXHandlerStruct = { + NULL, // internalSubset, + NULL, // isStandalone, + NULL, // hasInternalSubset, + NULL, // hasExternalSubset, + NULL, // resolveEntity, + NULL, // getEntity, + NULL, // entityDecl, + NULL, // notationDecl, + NULL, // attributeDecl, + NULL, // elementDecl, + NULL, // unparsedEntityDecl, + NULL, // setDocumentLocator, + NULL, // startDocument, + NULL, // endDocument, + StyleReader::startElement, + StyleReader::endElement, + NULL, // reference, + NULL, // characters + NULL, // ignorableWhitespace, + NULL, // processingInstruction, + NULL, // comment, + NULL, // warning, + NULL, // error, + NULL, // fatalError, + NULL, // getParameterEntity, + NULL, // cdata, + NULL, + 1 + #ifdef HAVE_XML26 + , + NULL, + NULL, + NULL, + NULL + #endif + }; + + xmlSAXHandlerPtr sSAXHandler = &sSAXHandlerStruct; + + void StyleReader::startElement(void*, const xmlChar * fullname, const xmlChar ** atts) + { + QString* name = new QString((const char*) fullname); + name = new QString(name->toLower()); + QXmlAttributes* attrs = new QXmlAttributes(); + if (atts) + { + for(const xmlChar** cur = atts; cur && *cur; cur += 2) + attrs->append(QString((char*)*cur), NULL, QString((char*)*cur), QString((char*)*(cur + 1))); + } + sreader->startElement(NULL, NULL, *name, *attrs); + } + + void StyleReader::endElement(void*, const xmlChar * name) + { + QString *nname = new QString((const char*) name); + nname = new QString(nname->toLower()); + sreader->endElement(NULL, NULL, *nname); + } + +/*** ListLevel *****************************************************************************************/ + +const QString ListLevel::lowerUnits[10] = {"", "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix"}; +const QString ListLevel::lowerTens[10] = {"", "x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc"}; +const QString ListLevel::lowerHundreds[10] = {"", "c", "cc", "ccc", "cd", "d", "dc", "dcc", "dccc", "cm"}; +const QString ListLevel::lowerThousands[4] = {"", "m", "mm", "mmm"}; +const QString ListLevel::upperUnits[10] = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"}; +const QString ListLevel::upperTens[10] = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"}; +const QString ListLevel::upperHundreds[10] = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCC", "CM"}; +const QString ListLevel::upperThousands[4] = {"", "M", "MM", "MMM"}; +const QString ListLevel::lowerAlphabets[27] = {"", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", + "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"}; +const QString ListLevel::upperAlphabets[27] = {"", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", + "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}; + +ListLevel::ListLevel(uint level, + BulletType btype, + const QString &prefix, + const QString &suffix, + const QString &bullet, + uint displayLevels, + uint startValue) : +m_level(level), +m_btype(btype), +m_prefix(prefix), +m_suffix(suffix), +m_bullet(bullet), +m_displayLevels(displayLevels), +m_next(startValue) +{ + +} + +QString ListLevel::bulletString() +{ + QString tmp; + switch (m_btype) { + case Bullet: + tmp = m_bullet; + break; + case Number: + tmp = QString("%1").arg(m_next); + break; + case LowerRoman: + tmp = lowerRoman(m_next); + break; + case UpperRoman: + tmp = upperRoman(m_next); + break; + case LowerAlpha: + tmp = lowerAlpha(m_next); + break; + case UpperAlpha: + tmp = upperAlpha(m_next); + break; + case Graphic: + tmp = "*"; + break; + default: + tmp = ""; + }; + return tmp; +} + +QString ListLevel::bullet() +{ + + return QString(m_prefix + bulletString() + m_suffix); +} + +QString ListLevel::prefix() +{ + return m_prefix; +} + +QString ListLevel::suffix() +{ + return m_suffix; +} + +void ListLevel::advance() +{ + ++m_next; +} + +uint ListLevel::level() +{ + return m_level; +} + +uint ListLevel::displayLevels() +{ + return m_displayLevels; +} + +void ListLevel::reset() +{ + m_next = 0; +} + +QString ListLevel::lowerRoman(uint n) +{ + return QString(lowerThousands[(n / 1000)] + + lowerHundreds[(n / 100) % 10] + + lowerTens[(n / 10) % 10] + + lowerUnits[(n) % 10]); +} + +QString ListLevel::upperRoman(uint n) +{ + return QString(upperThousands[(n / 1000)] + + upperHundreds[(n / 100) % 10] + + upperTens[(n / 10) % 10] + + upperUnits[(n) % 10]); +} + +QString ListLevel::lowerAlpha(uint n) +{ + QString tmp; + uint rounds = static_cast<uint>(n / 26); + if (rounds > 26) + rounds = 0; + uint leftover = n % 26; + return QString(lowerAlphabets[rounds] + lowerAlphabets[leftover]); +} + +QString ListLevel::upperAlpha(uint n) +{ + QString tmp; + uint rounds = static_cast<uint>(n / 26); + if (rounds > 26) + rounds = 0; + uint leftover = n % 26; + return QString(upperAlphabets[rounds] + upperAlphabets[leftover]); +} + +ListLevel::~ListLevel() +{ + +} + +/*** ListStyle **********************************************************************************/ + +ListStyle::ListStyle(const QString &name, bool consecutiveNumbering, uint currentLevel) : +m_name(name), +m_consecutiveNumbering(consecutiveNumbering), +m_currentLevel(currentLevel), +m_count(0) +{ + for (uint i = 0; i < 11; ++i) + levels[i] = 0; +} + +void ListStyle::addLevel(uint level, ListLevel *llevel) +{ + if (level > 0 && level < 11) + levels[level] = llevel; +} + +QString ListStyle::bullet() +{ + uint displayLevels = levels[m_currentLevel]->displayLevels(); + if (displayLevels == 1) + return QString(levels[m_currentLevel]->bullet() + " "); + + QString prefix = levels[m_currentLevel]->prefix(); + QString suffix = levels[m_currentLevel]->suffix(); + QString bullet = ""; + int start = m_currentLevel - displayLevels + 1; + if (start < 1) + return QString(levels[m_currentLevel]->bullet() + " "); + while (static_cast<uint>(start) <= m_currentLevel) + { + if (static_cast<uint>(start) == m_currentLevel) + bullet += levels[start]->bulletString(); + else + bullet += levels[start]->bulletString() + "."; + ++start; + } + return QString(prefix + bullet + suffix + " "); +} + +void ListStyle::advance() +{ + ++m_count; + if (levels[m_currentLevel]) + levels[m_currentLevel]->advance(); +} + +void ListStyle::setLevel(uint level) +{ + if (level > 0 && level < 11) + m_currentLevel = level; +} + +QString& ListStyle::name() +{ + return m_name; +} + +void ListStyle::resetLevel() +{ + levels[m_currentLevel]->reset(); +} + +ListStyle::~ListStyle() +{ + for (uint i = 0; i < 11; ++i) + { + delete levels[i]; + levels[i] = 0; + } +} diff --git a/scribus/plugins/gettext/odtim/stylereader.h b/scribus/plugins/gettext/odtim/stylereader.h new file mode 100644 index 0000000..c814d3a --- /dev/null +++ b/scribus/plugins/gettext/odtim/stylereader.h @@ -0,0 +1,164 @@ +/* +For general Scribus (>=1.3.2) copyright and licensing information please refer +to the COPYING file provided with the program. Following this notice may exist +a copyright and/or license notice that predates the release of Scribus 1.3.2 +for which a new license (GPL+exception) is in place. +*/ +/*************************************************************************** + * Copyright (C) 2004 by Riku Leino * + * tsoots@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef STYLEREADER_H +#define STYLEREADER_H + +#include "scconfig.h" + +#ifdef HAVE_XML26 + #include <libxml/SAX2.h> +#else + #include <libxml/SAX.h> +#endif +#include <QMap> +#include <QXmlAttributes> +#include <gtstyle.h> +#include <gtwriter.h> + + +enum BulletType { + Bullet, + Number, + LowerRoman, + UpperRoman, + LowerAlpha, + UpperAlpha, + Graphic +}; + +class ListLevel +{ +public: + ListLevel(uint level, + BulletType btype, + const QString &prefix, + const QString &suffix, + const QString &bullet, + uint displayLevels = 1, + uint startValue = 0); + ~ListLevel(); + QString bulletString(); + QString bullet(); + QString prefix(); + QString suffix(); + void advance(); + void reset(); + uint level(); + uint displayLevels(); +private: + uint m_level; + BulletType m_btype; + QString m_prefix; + QString m_suffix; + QString m_bullet; + uint m_displayLevels; + uint m_next; + static const QString lowerUnits[10]; + static const QString lowerTens[10]; + static const QString lowerHundreds[10]; + static const QString lowerThousands[4]; + static const QString upperUnits[10]; + static const QString upperTens[10]; + static const QString upperHundreds[10]; + static const QString upperThousands[4]; + static const QString lowerAlphabets[27]; + static const QString upperAlphabets[27]; + QString lowerRoman(uint n); + QString upperRoman(uint n); + QString lowerAlpha(uint n); + QString upperAlpha(uint n); +}; + +class ListStyle +{ +public: + ListStyle(const QString &name, bool consecutiveNumbering = false, uint currentLevel = 1); + ~ListStyle(); + void addLevel(uint level, ListLevel *llevel); + QString bullet(); + void advance(); + void setLevel(uint level); + void resetLevel(); + QString& name(); +private: + QString m_name; + bool m_consecutiveNumbering; + uint m_currentLevel; + uint m_count; + ListLevel* levels[11]; +}; + +typedef QMap<QString, gtStyle*> StyleMap; +typedef QMap<QString, QString> FontMap; +typedef QMap<QString, int> CounterMap; +typedef QMap<QString, ListStyle*> ListMap; + +class StyleReader +{ +private: + static StyleReader *sreader; + gtWriter *writer; + bool importTextOnly; + bool usePrefix; + bool packStyles; + bool readProperties; + QString docname; + StyleMap styles; + StyleMap listParents; + StyleMap attrsStyles; + CounterMap pstyleCounts; + FontMap fonts; + ListMap lists; + gtStyle* currentStyle; + gtStyle* parentStyle; + bool inList; + QString currentList; + ListStyle *currentListStyle; + bool defaultStyleCreated; + double getSize(QString s, double parentSize = -1); + void styleProperties(const QXmlAttributes& attrs); + void defaultStyle(const QXmlAttributes& attrs); + void styleStyle(const QXmlAttributes& attrs); + void tabStop(const QXmlAttributes& attrs); + void setupFrameStyle(); +public: + StyleReader(QString documentName, gtWriter *wr, bool textOnly, bool prefix, bool combineStyles = true); + ~StyleReader(); + bool updateStyle(gtStyle* style, gtStyle* parent2Style, const QString& key, const QString& value); + static void startElement(void *user_data, const xmlChar * fullname, const xmlChar ** atts); + static void endElement(void *user_data, const xmlChar * name); + bool startElement(const QString&, const QString&, const QString &name, const QXmlAttributes &attrs); + bool endElement(const QString&, const QString&, const QString &name); + void parse(QString fileName); + gtStyle* getDefaultStyle(void); + gtStyle* getStyle(const QString& name); + void setStyle(const QString& name, gtStyle* style); + QString getFont(const QString& key); + ListStyle *getList(const QString &name); +}; + +#endif |
