r14707 by fschmid - Moved the oodraw importer plugin to the import subdirectory.
scribus-commit
scribus-commit at lists.scribus.net
Sat Feb 13 12:10:25 CET 2010
Revision: 14707
Author: fschmid
Date: 2010-02-13T11:07:54.727563Z
Commit message: Moved the oodraw importer plugin to the import subdirectory.
Changeset:
A /trunk/Scribus/scribus/plugins/import/oodraw
M /trunk/Scribus/scribus/plugins/import/CMakeLists.txt
Diffs:
Index: scribus/plugins/import/oodraw/oodrawimp.cpp
===================================================================
--- scribus/plugins/import/oodraw/oodrawimp.cpp (revision 0)
+++ scribus/plugins/import/oodraw/oodrawimp.cpp (revision 14707)
@@ -0,0 +1,2016 @@
+/*
+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.
+*/
+#include <QWidget>
+#include <QFile>
+#include <QRegExp>
+#include <QCursor>
+#include <QDir>
+#include <QString>
+#include <QDomElement>
+#include <QDrag>
+#include <QMimeData>
+
+#include "oodrawimp.h"
+
+#include "scconfig.h"
+
+#include "color.h"
+#include "commonstrings.h"
+#include "fileunzip.h"
+#include "fpointarray.h"
+#include "ui/scmwmenumanager.h"
+#include "pageitem.h"
+#include "pluginmanager.h"
+#include "prefscontext.h"
+#include "prefsfile.h"
+#include "prefsmanager.h"
+#include "prefstable.h"
+#include "scclocale.h"
+#include "sccolorengine.h"
+#include "scmimedata.h"
+#include "scraction.h"
+#include "scribusXml.h"
+#include "scribuscore.h"
+#include "scribusdoc.h"
+#include "selection.h"
+#include "serializer.h"
+#include "stylestack.h"
+#include "ui/customfdialog.h"
+#include "ui/propertiespalette.h"
+#include "undomanager.h"
+#include "util.h"
+#include "util_icon.h"
+#include "util_math.h"
+
+
+using namespace std;
+
+int oodrawimp_getPluginAPIVersion()
+{
+ return PLUGIN_API_VERSION;
+}
+
+ScPlugin* oodrawimp_getPlugin()
+{
+ OODrawImportPlugin* plug = new OODrawImportPlugin();
+ Q_CHECK_PTR(plug);
+ return plug;
+}
+
+void oodrawimp_freePlugin(ScPlugin* plugin)
+{
+ OODrawImportPlugin* plug = dynamic_cast<OODrawImportPlugin*>(plugin);
+ Q_ASSERT(plug);
+ delete plug;
+}
+
+OODrawImportPlugin::OODrawImportPlugin() :
+ LoadSavePlugin(),
+ importAction(new ScrAction(ScrAction::DLL, QPixmap(), QPixmap(), "", QKeySequence(), this))
+{
+ // Set action info in languageChange, so we only have to do
+ // it in one place. This includes registering file formats.
+ languageChange();
+}
+/*
+void OODrawImportPlugin::addToMainWindowMenu(ScribusMainWindow *mw)
+{
+ // Then hook up the action
+ importAction->setEnabled(true);
+ connect( importAction, SIGNAL(triggered()), SLOT(import()) );
+ mw->scrMenuMgr->addMenuItem(importAction, "FileImport");
+}
+*/
+OODrawImportPlugin::~OODrawImportPlugin()
+{
+ unregisterAll();
+ // note: importAction is automatically deleted by Qt
+};
+
+void OODrawImportPlugin::languageChange()
+{
+ importAction->setText( tr("Import &OpenOffice.org Draw..."));
+ // (Re)register file formats
+ unregisterAll();
+ registerFormats();
+}
+
+const QString OODrawImportPlugin::fullTrName() const
+{
+ return QObject::tr("OpenOffice.org Draw Importer");
+}
+
+const ScActionPlugin::AboutData* OODrawImportPlugin::getAboutData() const
+{
+ AboutData* about = new AboutData;
+ about->authors = "Franz Schmid <franz at scribus.info>";
+ about->shortDescription = tr("Imports OpenOffice.org Draw Files");
+ about->description = tr("Imports most OpenOffice.org Draw files into the current document, converting their vector data into Scribus objects.");
+ about->license = "GPL";
+ Q_CHECK_PTR(about);
+ return about;
+}
+
+void OODrawImportPlugin::deleteAboutData(const AboutData* about) const
+{
+ Q_ASSERT(about);
+ delete about;
+}
+
+void OODrawImportPlugin::registerFormats()
+{
+ QString odtName = tr("OpenDocument 1.0 Draw", "Import/export format name");
+ FileFormat odtformat(this);
+ odtformat.trName = odtName; // Human readable name
+ odtformat.formatId = FORMATID_ODGIMPORT;
+ odtformat.filter = odtName + " (*.odg *.ODG)"; // QFileDialog filter
+ odtformat.nameMatch = QRegExp("\\.odg$", Qt::CaseInsensitive);
+ odtformat.fileExtensions = QStringList() << "odg";
+ odtformat.load = true;
+ odtformat.save = false;
+ odtformat.mimeTypes = QStringList("application/vnd.oasis.opendocument.graphics"); // MIME types
+ odtformat.priority = 64; // Priority
+ registerFormat(odtformat);
+
+ QString sxdName = tr("OpenOffice.org 1.x Draw", "Import/export format name");
+ FileFormat sxdformat(this);
+ sxdformat.trName = sxdName; // Human readable name
+ sxdformat.formatId = FORMATID_SXDIMPORT;
+ sxdformat.filter = sxdName + " (*.sxd *.SXD)"; // QFileDialog filter
+ sxdformat.nameMatch = QRegExp("\\.sxd$", Qt::CaseInsensitive);
+ sxdformat.fileExtensions = QStringList() << "sxd";
+ sxdformat.load = true;
+ sxdformat.save = false;
+ sxdformat.mimeTypes = QStringList("application/vnd.sun.xml.draw"); // MIME types
+ sxdformat.priority = 64; // Priority
+ registerFormat(sxdformat);
+}
+
+bool OODrawImportPlugin::fileSupported(QIODevice* /* file */, const QString & fileName) const
+{
+ // TODO: try to identify .sxd / .odt files
+ return true;
+}
+
+bool OODrawImportPlugin::loadFile(const QString & fileName, const FileFormat &, int flags, int /*index*/)
+{
+ // For this plugin, right now "load" and "import" are the same thing
+ return import(fileName, flags);
+}
+
+bool OODrawImportPlugin::import(QString fileName, int flags)
+{
+ if (!checkFlags(flags))
+ return false;
+ if (fileName.isEmpty())
+ {
+ flags |= lfInteractive;
+ PrefsContext* prefs = PrefsManager::instance()->prefsFile->getPluginContext("OODrawImport");
+ QString wdir = prefs->get("wdir", ".");
+ CustomFDialog diaf(ScCore->primaryMainWindow(), wdir, QObject::tr("Open"), QObject::tr("OpenOffice.org Draw (*.sxd *.odg);;All Files (*)"));
+ if (diaf.exec())
+ {
+ fileName = diaf.selectedFile();
+ prefs->set("wdir", fileName.left(fileName.lastIndexOf("/")));
+ }
+ else
+ return true;
+ }
+ m_Doc=ScCore->primaryMainWindow()->doc;
+ UndoTransaction* activeTransaction = NULL;
+ bool emptyDoc = (m_Doc == NULL);
+ bool hasCurrentPage = (m_Doc && m_Doc->currentPage());
+ TransactionSettings trSettings;
+ trSettings.targetName = hasCurrentPage ? m_Doc->currentPage()->getUName() : "";
+ trSettings.targetPixmap = Um::IImageFrame;
+ trSettings.actionName = Um::ImportOOoDraw;
+ trSettings.description = fileName;
+ trSettings.actionPixmap = Um::IImportOOoDraw;
+ OODPlug dia(m_Doc);
+ if (emptyDoc || !(flags & lfInteractive) || !(flags & lfScripted))
+ UndoManager::instance()->setUndoEnabled(false);
+ if (UndoManager::undoEnabled())
+ activeTransaction = new UndoTransaction(UndoManager::instance()->beginTransaction(trSettings));
+ bool importDone = dia.import(fileName, trSettings, flags);
+ if (activeTransaction)
+ {
+ activeTransaction->commit();
+ delete activeTransaction;
+ activeTransaction = NULL;
+ }
+ if (emptyDoc || !(flags & lfInteractive) || !(flags & lfScripted))
+ UndoManager::instance()->setUndoEnabled(true);
+ if (dia.importCanceled)
+ {
+ if ((!importDone) || (dia.importFailed))
+ QMessageBox::warning(ScCore->primaryMainWindow(), CommonStrings::trWarning, tr("The file could not be imported"), 1, 0, 0);
+ else if (dia.unsupported)
+ QMessageBox::warning(ScCore->primaryMainWindow(), CommonStrings::trWarning, tr("This file contains some unsupported features"), 1, 0, 0);
+ }
+ return importDone;
+}
+
+OODPlug::OODPlug(ScribusDoc* doc)
+{
+ m_Doc=doc;
+ unsupported = false;
+ interactive = false;
+ importFailed = false;
+ importCanceled = true;
+ importedColors.clear();
+ tmpSel=new Selection(this, false);
+}
+
+bool OODPlug::import(QString fileName, const TransactionSettings& trSettings, int flags )
+{
+ bool importDone = false;
+ interactive = (flags & LoadSavePlugin::lfInteractive);
+ QByteArray f, f2, f3;
+ if ( !QFile::exists(fileName) )
+ return false;
+// m_styles.setAutoDelete( true );
+ FileUnzip* fun = new FileUnzip(fileName);
+ stylePath = fun->getFile("styles.xml");
+ contentPath = fun->getFile("content.xml");
+ metaPath = fun->getFile("meta.xml");
+ delete fun;
+ // Qt4 NULL -> isNull()
+ if ((!stylePath.isNull()) && (!contentPath.isNull()))
+ {
+ HaveMeta = false;
+ QString docname = fileName.right(fileName.length() - fileName.lastIndexOf("/") - 1);
+ docname = docname.left(docname.lastIndexOf("."));
+ loadRawText(stylePath, f);
+ if(!inpStyles.setContent(f))
+ return false;
+ loadRawText(contentPath, f2);
+ if(!inpContents.setContent(f2))
+ return false;
+ QFile::remove(stylePath);
+ QFile::remove(contentPath);
+ HaveMeta = false;
+ if (!metaPath.isEmpty())
+ {
+ loadRawText(metaPath, f3);
+ HaveMeta = inpMeta.setContent(f3);
+ QFile::remove(f3);
+ }
+ }
+ else if ((stylePath.isNull()) && (!contentPath.isNull()))
+ {
+ QFile f2(contentPath);
+ f2.remove();
+ }
+ else if ((!stylePath.isNull()) && (contentPath.isNull()))
+ {
+ QFile f1(stylePath);
+ f1.remove();
+ }
+ QString CurDirP = QDir::currentPath();
+ QFileInfo efp(fileName);
+ QDir::setCurrent(efp.path());
+ importDone = convert(trSettings, flags);
+ QDir::setCurrent(CurDirP);
+ return importDone;
+}
+
+bool OODPlug::convert(const TransactionSettings& trSettings, int flags)
+{
+ bool ret = false;
+ bool isOODraw2 = false;
+ QDomNode drawPagePNode;
+ int PageCounter = 0;
+ QList<PageItem*> Elements;
+ createStyleMap( inpStyles );
+ QDomElement docElem = inpContents.documentElement();
+ QDomNode automaticStyles = docElem.namedItem( "office:automatic-styles" );
+ if( !automaticStyles.isNull() )
+ insertStyles( automaticStyles.toElement() );
+ QDomNode body = docElem.namedItem( "office:body" );
+ QDomNode drawPage = body.namedItem( "draw:page" );
+ if ( drawPage.isNull() )
+ {
+ QDomNode offDraw = body.namedItem( "office:drawing" );
+ drawPage = offDraw.namedItem( "draw:page" );
+ if (drawPage.isNull())
+ {
+ QMessageBox::warning( m_Doc->scMW(), CommonStrings::trWarning, tr("This document does not seem to be an OpenOffice Draw file.") );
+ return false;
+ }
+ else
+ {
+ isOODraw2 = true;
+ drawPagePNode = body.namedItem( "office:drawing" );
+ }
+ }
+ else
+ drawPagePNode = body;
+ StyleStack::Mode mode = isOODraw2 ? StyleStack::OODraw2x : StyleStack::OODraw1x;
+ m_styleStack.setMode( mode );
+ QDomElement dp = drawPage.toElement();
+ QDomElement *master = m_styles[dp.attribute( "draw:master-page-name" )];
+ QDomElement *style = NULL;
+ QDomElement properties;
+ if (isOODraw2)
+ {
+ style = m_styles.value(master->attribute( "style:page-layout-name" ), NULL);
+ if (style)
+ properties = style->namedItem("style:page-layout-properties" ).toElement();
+ }
+ else
+ {
+ style = m_styles.value(master->attribute( "style:page-master-name" ), NULL);
+ if (style)
+ properties = style->namedItem( "style:properties" ).toElement();
+ }
+ double width = !properties.attribute( "fo:page-width" ).isEmpty() ? parseUnit(properties.attribute( "fo:page-width" ) ) : 550.0;
+ double height = !properties.attribute( "fo:page-height" ).isEmpty() ? parseUnit(properties.attribute( "fo:page-height" ) ) : 841.0;
+ if (!interactive || (flags & LoadSavePlugin::lfInsertPage))
+ m_Doc->setPage(width, height, 0, 0, 0, 0, 0, 0, false, false);
+ else
+ {
+ if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc))
+ {
+ m_Doc=ScCore->primaryMainWindow()->doFileNew(width, height, 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom", true);
+ ScCore->primaryMainWindow()->HaveNewDoc();
+ ret = true;
+ }
+ }
+ if ((ret) || (!interactive))
+ {
+ if (width > height)
+ m_Doc->PageOri = 1;
+ else
+ m_Doc->PageOri = 0;
+ m_Doc->m_pageSize = "Custom";
+ QDomNode mpg;
+ QDomElement metaElem = inpMeta.documentElement();
+ QDomElement mp = metaElem.namedItem( "office:meta" ).toElement();
+ mpg = mp.namedItem( "dc:title" );
+ if (!mpg.isNull())
+ m_Doc->documentInfo.setTitle(mpg.toElement().text());
+ mpg = mp.namedItem( "meta:initial-creator" );
+ if (!mpg.isNull())
+ m_Doc->documentInfo.setAuthor(mpg.toElement().text());
+ mpg = mp.namedItem( "dc:description" );
+ if (!mpg.isNull())
+ m_Doc->documentInfo.setComments(mpg.toElement().text());
+ mpg = mp.namedItem( "dc:language" );
+ if (!mpg.isNull())
+ m_Doc->documentInfo.setLangInfo(mpg.toElement().text());
+ mpg = mp.namedItem( "meta:creation-date" );
+ if (!mpg.isNull())
+ m_Doc->documentInfo.setDate(mpg.toElement().text());
+ mpg = mp.namedItem( "dc:creator" );
+ if (!mpg.isNull())
+ m_Doc->documentInfo.setContrib(mpg.toElement().text());
+ mpg = mp.namedItem( "meta:keywords" );
+ if (!mpg.isNull())
+ {
+ QString Keys = "";
+ for( QDomNode n = mpg.firstChild(); !n.isNull(); n = n.nextSibling() )
+ {
+ Keys += n.toElement().text()+", ";
+ }
+ if (Keys.length() > 2)
+ m_Doc->documentInfo.setKeywords(Keys.left(Keys.length()-2));
+ }
+ }
+ FPoint minSize = m_Doc->minCanvasCoordinate;
+ FPoint maxSize = m_Doc->maxCanvasCoordinate;
+ FPoint cOrigin = m_Doc->view()->canvasOrigin();
+ m_Doc->view()->Deselect();
+ Elements.clear();
+ m_Doc->setLoading(true);
+ m_Doc->DoDrawing = false;
+ m_Doc->view()->updatesOn(false);
+ m_Doc->scMW()->ScriptRunning = true;
+ qApp->changeOverrideCursor(QCursor(Qt::WaitCursor));
+ if (!m_Doc->PageColors.contains("Black"))
+ m_Doc->PageColors.insert("Black", ScColor(0, 0, 0, 255));
+ for( QDomNode drawPag = drawPagePNode.firstChild(); !drawPag.isNull(); drawPag = drawPag.nextSibling() )
+ {
+ QDomElement dpg = drawPag.toElement();
+ if (!interactive)
+ {
+ m_Doc->addPage(PageCounter);
+ m_Doc->view()->addPage(PageCounter);
+ }
+ PageCounter++;
+ m_styleStack.clear();
+ fillStyleStack( dpg );
+ QList<PageItem*> el = parseGroup( dpg );
+ for (int ec = 0; ec < el.count(); ++ec)
+ Elements.append(el.at(ec));
+ if ((interactive) && (PageCounter == 1))
+ break;
+ }
+ tmpSel->clear();
+// if ((Elements.count() > 1) && (interactive))
+ if (Elements.count() == 0)
+ {
+ importFailed = true;
+ if (importedColors.count() != 0)
+ {
+ for (int cd = 0; cd < importedColors.count(); cd++)
+ {
+ m_Doc->PageColors.remove(importedColors[cd]);
+ }
+ }
+ }
+ if (Elements.count() > 1)
+ {
+ bool isGroup = true;
+ int firstElem = -1;
+ if (Elements.at(0)->Groups.count() != 0)
+ firstElem = Elements.at(0)->Groups.top();
+ for (int bx = 0; bx < Elements.count(); ++bx)
+ {
+ PageItem* bxi = Elements.at(bx);
+ if (bxi->Groups.count() != 0)
+ {
+ if (bxi->Groups.top() != firstElem)
+ isGroup = false;
+ }
+ else
+ isGroup = false;
+ }
+ if (!isGroup)
+ {
+ double minx = 99999.9;
+ double miny = 99999.9;
+ double maxx = -99999.9;
+ double maxy = -99999.9;
+ uint lowestItem = 999999;
+ uint highestItem = 0;
+ for (int a = 0; a < Elements.count(); ++a)
+ {
+ Elements.at(a)->Groups.push(m_Doc->GroupCounter);
+ PageItem* currItem = Elements.at(a);
+ lowestItem = qMin(lowestItem, currItem->ItemNr);
+ highestItem = qMax(highestItem, currItem->ItemNr);
+ double x1, x2, y1, y2;
+ currItem->getVisualBoundingRect(&x1, &y1, &x2, &y2);
+ minx = qMin(minx, x1);
+ miny = qMin(miny, y1);
+ maxx = qMax(maxx, x2);
+ maxy = qMax(maxy, y2);
+ }
+ double gx = minx;
+ double gy = miny;
+ double gw = maxx - minx;
+ double gh = maxy - miny;
+ PageItem *high = m_Doc->Items->at(highestItem);
+ int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, gx, gy, gw, gh, 0, m_Doc->itemToolPrefs.shapeFillColor, m_Doc->itemToolPrefs.shapeLineColor, true);
+ PageItem *neu = m_Doc->Items->takeAt(z);
+ m_Doc->Items->insert(lowestItem, neu);
+ neu->Groups.push(m_Doc->GroupCounter);
+ neu->setItemName( tr("Group%1").arg(neu->Groups.top()));
+ neu->AutoName = false;
+ neu->isGroupControl = true;
+ neu->groupsLastItem = high;
+ neu->setTextFlowMode(PageItem::TextFlowDisabled);
+ for (int a = 0; a < m_Doc->Items->count(); ++a)
+ {
+ m_Doc->Items->at(a)->ItemNr = a;
+ }
+ Elements.prepend(neu);
+ m_Doc->GroupCounter++;
+ }
+ }
+ m_Doc->DoDrawing = true;
+ m_Doc->scMW()->ScriptRunning = false;
+ if (interactive)
+ m_Doc->setLoading(false);
+ qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
+ if ((Elements.count() > 0) && (!ret) && (interactive))
+ {
+ if (flags & LoadSavePlugin::lfScripted)
+ {
+ bool loadF = m_Doc->isLoading();
+ m_Doc->setLoading(false);
+ m_Doc->changed();
+ m_Doc->setLoading(loadF);
+ m_Doc->m_Selection->delaySignalsOn();
+ for (int dre=0; dre<Elements.count(); ++dre)
+ {
+ m_Doc->m_Selection->addItem(Elements.at(dre), true);
+ }
+ m_Doc->m_Selection->delaySignalsOff();
+ m_Doc->m_Selection->setGroupRect();
+ m_Doc->view()->updatesOn(true);
+ importCanceled = false;
+ }
+ else
+ {
+ m_Doc->DragP = true;
+ m_Doc->DraggedElem = 0;
+ m_Doc->DragElements.clear();
+ m_Doc->m_Selection->delaySignalsOn();
+ for (int dre=0; dre<Elements.count(); ++dre)
+ {
+ m_Doc->DragElements.append(Elements.at(dre)->ItemNr);
+ tmpSel->addItem(Elements.at(dre), true);
+ }
+ ScriXmlDoc *ss = new ScriXmlDoc();
+ tmpSel->setGroupRect();
+ //CB keep for reference conversion for now
+ //Q3DragObject *dr = new Q3TextDrag(ss->WriteElem(m_Doc, m_Doc->view(), tmpSel), m_Doc->view()->viewport());
+ ScElemMimeData* md = new ScElemMimeData();
+ md->setScribusElem(ss->WriteElem(m_Doc, m_Doc->view(), tmpSel));
+ delete ss;
+/*#ifndef Q_WS_MAC*/
+// see #2196, #2526
+ m_Doc->itemSelection_DeleteItem(tmpSel);
+/*#endif*/
+ m_Doc->view()->updatesOn(true);
+ m_Doc->m_Selection->delaySignalsOff();
+ // We must copy the TransationSettings object as it is owned
+ // by handleObjectImport method afterwards
+ TransactionSettings* transacSettings = new TransactionSettings(trSettings);
+ m_Doc->view()->handleObjectImport(md, transacSettings);
+ m_Doc->DragP = false;
+ m_Doc->DraggedElem = 0;
+ m_Doc->DragElements.clear();
+ }
+ }
+ else
+ {
+ bool loadF = m_Doc->isLoading();
+ m_Doc->setLoading(false);
+ m_Doc->changed();
+ m_Doc->reformPages();
+ m_Doc->view()->updatesOn(true);
+ m_Doc->setLoading(loadF);
+ }
+ return true;
+}
+
+QList<PageItem*> OODPlug::parseGroup(const QDomElement &e)
+{
+ OODrawStyle oostyle;
+ FPointArray ImgClip;
+ QList<PageItem*> elements, cElements;
+ double BaseX = m_Doc->currentPage()->xOffset();
+ double BaseY = m_Doc->currentPage()->yOffset();
+ storeObjectStyles(e);
+ parseStyle(oostyle, e);
+ QString drawID = e.attribute("draw:name");
+ int zn = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, BaseX, BaseY, 1, 1, 0, CommonStrings::None, CommonStrings::None, true);
+ PageItem *neu = m_Doc->Items->at(zn);
+ for (QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling())
+ {
+ QDomElement b = n.toElement();
+ if( b.isNull() )
+ continue;
+ QList<PageItem*> el = parseElement(b);
+ for (int ec = 0; ec < el.count(); ++ec)
+ cElements.append(el.at(ec));
+ }
+ if (cElements.count() < 2)
+ {
+ m_Doc->Items->takeAt(zn);
+ delete neu;
+ for (int a = 0; a < m_Doc->Items->count(); ++a)
+ {
+ m_Doc->Items->at(a)->ItemNr = a;
+ }
+ for (int gr = 0; gr < cElements.count(); ++gr)
+ {
+ elements.append(cElements.at(gr));
+ }
+ }
+ else
+ {
+ double minx = 99999.9;
+ double miny = 99999.9;
+ double maxx = -99999.9;
+ double maxy = -99999.9;
+ elements.append(neu);
+ for (int gr = 0; gr < cElements.count(); ++gr)
+ {
+ PageItem* currItem = cElements.at(gr);
+ double x1, x2, y1, y2;
+ currItem->getVisualBoundingRect(&x1, &y1, &x2, &y2);
+ minx = qMin(minx, x1);
+ miny = qMin(miny, y1);
+ maxx = qMax(maxx, x2);
+ maxy = qMax(maxy, y2);
+ }
+ double gx = minx;
+ double gy = miny;
+ double gw = maxx - minx;
+ double gh = maxy - miny;
+ neu->setXYPos(gx, gy);
+ neu->setWidthHeight(gw, gh);
+ if (ImgClip.size() != 0)
+ neu->PoLine = ImgClip.copy();
+ else
+ neu->SetRectFrame();
+ ImgClip.resize(0);
+ neu->Clip = FlattenPath(neu->PoLine, neu->Segments);
+ neu->Groups.push(m_Doc->GroupCounter);
+ neu->isGroupControl = true;
+ neu->groupsLastItem = cElements.at(cElements.count()-1);
+ if( !e.attribute("id").isEmpty() )
+ neu->setItemName(e.attribute("id"));
+ else
+ neu->setItemName( tr("Group%1").arg(neu->Groups.top()));
+ neu->AutoName = false;
+// neu->setFillTransparency(1 - gc->Opacity);
+ for (int gr = 0; gr < cElements.count(); ++gr)
+ {
+ cElements.at(gr)->Groups.push(m_Doc->GroupCounter);
+ elements.append(cElements.at(gr));
+ }
+ neu->setTextFlowMode(PageItem::TextFlowDisabled);
+ m_Doc->GroupCounter++;
+ }
+ return elements;
+}
+
+QList<PageItem*> OODPlug::parseElement(const QDomElement &e)
+{
+ QList<PageItem*> GElements;
+ QString STag = e.tagName();
+ if ( STag == "draw:g" )
+ {
+ GElements = parseGroup(e);
+ return GElements;
+ }
+ if ( STag == "draw:rect" )
+ GElements = parseRect(e);
+ else if ( STag == "draw:circle" || STag == "draw:ellipse" )
+ GElements = parseEllipse(e);
+ else if ( STag == "draw:line" )
+ GElements = parseLine(e);
+ else if ( STag == "draw:polygon" )
+ GElements = parsePolygon(e);
+ else if ( STag == "draw:polyline" )
+ GElements = parsePolyline(e);
+ else if( STag == "draw:path" )
+ GElements = parsePath(e);
+ else if ( STag == "draw:text-box" )
+ GElements = parseTextBox(e);
+ else if ( STag == "draw:frame" )
+ GElements = parseFrame(e);
+ else if ( STag == "draw:connector" )
+ GElements = parseConnector(e);
+ else
+ {
+ // warn if unsupported feature are encountered
+ unsupported = true;
+ qDebug("Not supported yet: %s", STag.toLocal8Bit().data());
+ }
+ return GElements;
+}
+
+QList<PageItem*> OODPlug::parseRect(const QDomElement &e)
+{
+ OODrawStyle style;
+ QList<PageItem*> elements;
+ double BaseX = m_Doc->currentPage()->xOffset();
+ double BaseY = m_Doc->currentPage()->yOffset();
+ double x = parseUnit(e.attribute("svg:x"));
+ double y = parseUnit(e.attribute("svg:y")) ;
+ double w = parseUnit(e.attribute("svg:width"));
+ double h = parseUnit(e.attribute("svg:height"));
+ double corner = parseUnit(e.attribute("draw:corner-radius"));
+ storeObjectStyles(e);
+ parseStyle(style, e);
+ int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, BaseX+x, BaseY+y, w, h, style.strokeWidth, style.fillColor, style.strokeColor, true);
+ PageItem* ite = m_Doc->Items->at(z);
+ if (corner != 0)
+ {
+ ite->setCornerRadius(corner);
+ ite->SetFrameRound();
+ m_Doc->setRedrawBounding(ite);
+ }
+ ite = finishNodeParsing(e, ite, style);
+ elements.append(ite);
+ return elements;
+}
+
+QList<PageItem*> OODPlug::parseEllipse(const QDomElement &e)
+{
+ OODrawStyle style;
+ QList<PageItem*> elements;
+ double BaseX = m_Doc->currentPage()->xOffset();
+ double BaseY = m_Doc->currentPage()->yOffset();
+ double x = parseUnit(e.attribute("svg:x"));
+ double y = parseUnit(e.attribute("svg:y")) ;
+ double w = parseUnit(e.attribute("svg:width"));
+ double h = parseUnit(e.attribute("svg:height"));
+ storeObjectStyles(e);
+ parseStyle(style, e);
+ int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, BaseX+x, BaseY+y, w, h, style.strokeWidth, style.fillColor, style.strokeColor, true);
+ PageItem* ite = m_Doc->Items->at(z);
+ ite = finishNodeParsing(e, ite, style);
+ elements.append(ite);
+ return elements;
+}
+
+QList<PageItem*> OODPlug::parseLine(const QDomElement &e)
+{
+ OODrawStyle style;
+ QList<PageItem*> elements;
+ double BaseX = m_Doc->currentPage()->xOffset();
+ double BaseY = m_Doc->currentPage()->yOffset();
+ double x1 = e.attribute( "svg:x1" ).isEmpty() ? 0.0 : parseUnit( e.attribute( "svg:x1" ) );
+ double y1 = e.attribute( "svg:y1" ).isEmpty() ? 0.0 : parseUnit( e.attribute( "svg:y1" ) );
+ double x2 = e.attribute( "svg:x2" ).isEmpty() ? 0.0 : parseUnit( e.attribute( "svg:x2" ) );
+ double y2 = e.attribute( "svg:y2" ).isEmpty() ? 0.0 : parseUnit( e.attribute( "svg:y2" ) );
+ storeObjectStyles(e);
+ parseStyle(style, e);
+ int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, BaseX, BaseY, 10, 10, style.strokeWidth, CommonStrings::None, style.strokeColor, true);
+ PageItem* ite = m_Doc->Items->at(z);
+ ite->PoLine.resize(4);
+ ite->PoLine.setPoint(0, FPoint(x1, y1));
+ ite->PoLine.setPoint(1, FPoint(x1, y1));
+ ite->PoLine.setPoint(2, FPoint(x2, y2));
+ ite->PoLine.setPoint(3, FPoint(x2, y2));
+ FPoint wh = getMaxClipF(&ite->PoLine);
+ ite->setWidthHeight(wh.x(), wh.y());
+ ite->ClipEdited = true;
+ ite->FrameType = 3;
+ if (!e.hasAttribute("draw:transform"))
+ {
+ ite->Clip = FlattenPath(ite->PoLine, ite->Segments);
+ m_Doc->AdjustItemSize(ite);
+ }
+ ite = finishNodeParsing(e, ite, style);
+ elements.append(ite);
+ return elements;
+}
+
+QList<PageItem*> OODPlug::parsePolygon(const QDomElement &e)
+{
+ OODrawStyle style;
+ QList<PageItem*> elements;
+ double BaseX = m_Doc->currentPage()->xOffset();
+ double BaseY = m_Doc->currentPage()->yOffset();
+ storeObjectStyles(e);
+ parseStyle(style, e);
+ int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, BaseX, BaseY, 10, 10, style.strokeWidth, style.fillColor, style.strokeColor, true);
+ PageItem* ite = m_Doc->Items->at(z);
+ ite->PoLine.resize(0);
+ appendPoints(&ite->PoLine, e, true);
+ FPoint wh = getMaxClipF(&ite->PoLine);
+ ite->setWidthHeight(wh.x(), wh.y());
+ ite->ClipEdited = true;
+ ite->FrameType = 3;
+ if (!e.hasAttribute("draw:transform"))
+ {
+ ite->Clip = FlattenPath(ite->PoLine, ite->Segments);
+ m_Doc->AdjustItemSize(ite);
+ }
+ ite = finishNodeParsing(e, ite, style);
+ elements.append(ite);
+ return elements;
+}
+
+QList<PageItem*> OODPlug::parsePolyline(const QDomElement &e)
+{
+ OODrawStyle style;
+ QList<PageItem*> elements;
+ double BaseX = m_Doc->currentPage()->xOffset();
+ double BaseY = m_Doc->currentPage()->yOffset();
+ storeObjectStyles(e);
+ parseStyle(style, e);
+ int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, BaseX, BaseY, 10, 10, style.strokeWidth, CommonStrings::None, style.strokeColor, true);
+ PageItem* ite = m_Doc->Items->at(z);
+ ite->PoLine.resize(0);
+ appendPoints(&ite->PoLine, e, false);
+ FPoint wh = getMaxClipF(&ite->PoLine);
+ ite->setWidthHeight(wh.x(), wh.y());
+ ite->ClipEdited = true;
+ ite->FrameType = 3;
+ if (!e.hasAttribute("draw:transform"))
+ {
+ ite->Clip = FlattenPath(ite->PoLine, ite->Segments);
+ m_Doc->AdjustItemSize(ite);
+ }
+ ite = finishNodeParsing(e, ite, style);
+ elements.append(ite);
+ return elements;
+}
+
+QList<PageItem*> OODPlug::parsePath(const QDomElement &e)
+{
+ OODrawStyle style;
+ FPointArray pArray;
+ QList<PageItem*> elements;
+ double BaseX = m_Doc->currentPage()->xOffset();
+ double BaseY = m_Doc->currentPage()->yOffset();
+ storeObjectStyles(e);
+ parseStyle(style, e);
+ PageItem::ItemType itype = parseSVG(e.attribute("svg:d"), &pArray) ? PageItem::PolyLine : PageItem::Polygon;
+ int z = m_Doc->itemAdd(itype, PageItem::Unspecified, BaseX, BaseY, 10, 10, style.strokeWidth, style.fillColor, style.strokeColor, true);
+ PageItem* ite = m_Doc->Items->at(z);
+ ite->PoLine.resize(0);
+ ite->PoLine = pArray;
+ if (ite->PoLine.size() < 4)
+ {
+// m_Doc->m_Selection->addItem(ite);
+ tmpSel->addItem(ite);
+// m_Doc->itemSelection_DeleteItem();
+ m_Doc->itemSelection_DeleteItem(tmpSel);
+ }
+ else
+ {
+ QTransform mat;
+ double x = parseUnit(e.attribute("svg:x"));
+ double y = parseUnit(e.attribute("svg:y")) ;
+ double w = parseUnit(e.attribute("svg:width"));
+ double h = parseUnit(e.attribute("svg:height"));
+ double vx = 0;
+ double vy = 0;
+ double vw = 1;
+ double vh = 1;
+ parseViewBox(e, &vx, &vy, &vw, &vh);
+ double sx = (vw != 0.0) ? (w / vw) : w;
+ double sy = (vh != 0.0) ? (h / vh) : h;
+ mat.translate(x, y);
+ mat.scale(sx, sy);
+ ite->PoLine.map(mat);
+ FPoint wh = getMaxClipF(&ite->PoLine);
+ ite->setWidthHeight(wh.x(), wh.y());
+ ite->ClipEdited = true;
+ ite->FrameType = 3;
+ if (!e.hasAttribute("draw:transform"))
+ {
+ ite->Clip = FlattenPath(ite->PoLine, ite->Segments);
+ m_Doc->AdjustItemSize(ite);
+ }
+ ite = finishNodeParsing(e, ite, style);
+ elements.append(ite);
+ }
+ return elements;
+}
+
+QList<PageItem*> OODPlug::parseTextBox(const QDomElement &e)
+{
+ OODrawStyle style;
+ QList<PageItem*> elements;
+ double BaseX = m_Doc->currentPage()->xOffset();
+ double BaseY = m_Doc->currentPage()->yOffset();
+ double x = parseUnit(e.attribute("svg:x"));
+ double y = parseUnit(e.attribute("svg:y")) ;
+ double w = parseUnit(e.attribute("svg:width"));
+ double h = parseUnit(e.attribute("svg:height"));
+ storeObjectStyles(e);
+ parseStyle(style, e);
+ int z = m_Doc->itemAdd(PageItem::TextFrame, PageItem::Unspecified, BaseX+x, BaseY+y, w, h+(h*0.1), style.strokeWidth, CommonStrings::None, style.strokeColor, true);
+ PageItem* ite = m_Doc->Items->at(z);
+ ite->setFillColor(style.fillColor);
+ ite->setLineColor(style.strokeColor);
+ ite = finishNodeParsing(e, ite, style);
+ elements.append(ite);
+ return elements;
+}
+
+QList<PageItem*> OODPlug::parseFrame(const QDomElement &e)
+{
+ OODrawStyle oostyle;
+ QList<PageItem*> elements;
+ QString drawID = e.attribute("draw:name");
+ double BaseX = m_Doc->currentPage()->xOffset();
+ double BaseY = m_Doc->currentPage()->yOffset();
+ double x = parseUnit(e.attribute("svg:x"));
+ double y = parseUnit(e.attribute("svg:y")) ;
+ double w = parseUnit(e.attribute("svg:width"));
+ double h = parseUnit(e.attribute("svg:height"));
+ storeObjectStyles(e);
+ parseStyle(oostyle, e);
+ QDomNode n = e.firstChild();
+ QString STag2 = n.toElement().tagName();
+ if ( STag2 == "draw:text-box" )
+ {
+ int z = m_Doc->itemAdd(PageItem::TextFrame, PageItem::Unspecified, BaseX+x, BaseY+y, w, h+(h*0.1), oostyle.strokeWidth, CommonStrings::None, oostyle.strokeColor, true);
+ PageItem* ite = m_Doc->Items->at(z);
+ ite->setTextToFrameDist(0.0, 0.0, 0.0, 0.0);
+ ite->setFillTransparency(oostyle.fillTrans);
+ ite->setLineTransparency(oostyle.strokeTrans);
+ ite->setTextFlowMode(PageItem::TextFlowDisabled);
+ if (!drawID.isEmpty())
+ {
+ ite->setItemName(drawID);
+ ite->AutoName = false;
+ }
+ ite = parseTextP(n.toElement(), ite);
+ elements.append(ite);
+ }
+ return elements;
+}
+
+QList<PageItem*> OODPlug::parseConnector(const QDomElement &e)
+{
+ QList<PageItem*> elements;
+ if (e.hasAttribute("svg:x1") && e.hasAttribute("svg:x2") && e.hasAttribute("svg:y1") && e.hasAttribute("svg:y2"))
+ {
+ elements = parseLine(e);
+ }
+ else
+ {
+ unsupported = true;
+ qDebug("an unsupported form of connector was found");
+ }
+ return elements;
+}
+
+void OODPlug::parseStyle(OODrawStyle& oostyle, const QDomElement &e)
+{
+ oostyle.haveGradient = false;
+ oostyle.gradient.clearStops();
+ if( m_styleStack.hasAttribute("draw:stroke") )
+ {
+ if( m_styleStack.attribute( "draw:stroke" ) == "none" )
+ oostyle.strokeWidth = 0.0;
+ else
+ {
+ if( m_styleStack.hasAttribute("svg:stroke-width"))
+ {
+ oostyle.strokeWidth = parseUnit(m_styleStack.attribute("svg:stroke-width"));
+ if (oostyle.strokeWidth == 0)
+ oostyle.strokeWidth = 1;
+ }
+ if( m_styleStack.hasAttribute("svg:stroke-color"))
+ oostyle.strokeColor = parseColor(m_styleStack.attribute("svg:stroke-color"));
+ if( m_styleStack.hasAttribute( "svg:stroke-opacity" ) )
+ oostyle.strokeTrans = ScCLocale::toDoubleC(m_styleStack.attribute( "svg:stroke-opacity" ).remove( '%' )) / 100.0;
+ if( m_styleStack.attribute( "draw:stroke" ) == "dash" )
+ {
+ QString style = m_styleStack.attribute( "draw:stroke-dash" );
+ if( style == "Ultrafine Dashed")
+ oostyle.dashes << 1.4 << 1.4;
+ else if( style == "Fine Dashed" )
+ oostyle.dashes << 14.4 << 14.4;
+ else if( style == "Fine Dotted")
+ oostyle.dashes << 13 << 13;
+ else if( style == "Ultrafine 2 Dots 3 Dashes")
+ oostyle.dashes << 1.45 << 3.6 << 1.45 << 3.6 << 7.2 << 3.6 << 7.2 << 3.6 << 7.2 << 3.6;
+ else if( style == "Line with Fine Dots")
+ {
+ oostyle.dashes << 56.9 << 4.31;
+ for (int dd = 0; dd < 10; ++ dd)
+ {
+ oostyle.dashes << 8.6 << 4.31;
+ }
+ }
+ else if( style == "2 Dots 1 Dash" )
+ oostyle.dashes << 2.8 << 5.75 << 2.8 << 5.75 << 5.75 << 5.75;
+ }
+ }
+ }
+ if( m_styleStack.hasAttribute( "draw:fill" ) )
+ {
+ QString fill = m_styleStack.attribute( "draw:fill" );
+ if( fill == "solid" )
+ {
+ if( m_styleStack.hasAttribute( "draw:fill-color" ) )
+ oostyle.fillColor = parseColor( m_styleStack.attribute("draw:fill-color"));
+ if( m_styleStack.hasAttribute( "draw:transparency" ) )
+ oostyle.fillTrans = ScCLocale::toDoubleC(m_styleStack.attribute( "draw:transparency" ).remove( '%' )) / 100.0;
+ }
+ else if( fill == "gradient" )
+ {
+ oostyle.haveGradient = true;
+ oostyle.gradientAngle = 0;
+ oostyle.gradient.clearStops();
+ oostyle.gradient.setRepeatMethod( VGradient::none );
+ QString style = m_styleStack.attribute( "draw:fill-gradient-name" );
+ QDomElement* draw = m_draws[style];
+ if( draw )
+ {
+ double border = 0.0;
+ int shadeS = 100;
+ int shadeE = 100;
+ if( draw->hasAttribute( "draw:border" ) )
+ border += ScCLocale::toDoubleC(draw->attribute( "draw:border" ).remove( '%' )) / 100.0;
+ if( draw->hasAttribute( "draw:start-intensity" ) )
+ shadeS = draw->attribute( "draw:start-intensity" ).remove( '%' ).toInt();
+ if( draw->hasAttribute( "draw:end-intensity" ) )
+ shadeE = draw->attribute( "draw:end-intensity" ).remove( '%' ).toInt();
+ QString type = draw->attribute( "draw:style" );
+ if( type == "linear" || type == "axial" )
+ {
+ oostyle.gradient.setType( VGradient::linear );
+ oostyle.gradientAngle = ScCLocale::toDoubleC(draw->attribute( "draw:angle" )) / 10;
+ oostyle.gradientType = 1;
+ }
+ else if( type == "radial" || type == "ellipsoid" )
+ {
+ if( draw->hasAttribute( "draw:cx" ) )
+ oostyle.gradientPointX = ScCLocale::toDoubleC(draw->attribute( "draw:cx" ).remove( '%' )) / 100.0;
+ else
+ oostyle.gradientPointX = 0.5;
+ if( draw->hasAttribute( "draw:cy" ) )
+ oostyle.gradientPointY = ScCLocale::toDoubleC(draw->attribute( "draw:cy" ).remove( '%' )) / 100.0;
+ else
+ oostyle.gradientPointY = 0.5;
+ oostyle.gradientType = 2;
+ }
+ QString c, c2;
+ c = parseColor( draw->attribute( "draw:start-color" ) );
+ c2 = parseColor( draw->attribute( "draw:end-color" ) );
+ const ScColor& col1 = m_Doc->PageColors[c];
+ const ScColor& col2 = m_Doc->PageColors[c2];
+ if (((oostyle.gradientAngle > 90) && (oostyle.gradientAngle < 271)) || (oostyle.gradientType == 2))
+ {
+ const ScColor& col1 = m_Doc->PageColors[c];
+ const ScColor& col2 = m_Doc->PageColors[c2];
+ oostyle.gradient.addStop( ScColorEngine::getRGBColor(col2, m_Doc), 0.0, 0.5, 1, c2, shadeE );
+ oostyle.gradient.addStop( ScColorEngine::getRGBColor(col1, m_Doc), 1.0 - border, 0.5, 1, c, shadeS );
+ }
+ else
+ {
+ oostyle.gradient.addStop( ScColorEngine::getRGBColor(col1, m_Doc), border, 0.5, 1, c, shadeS );
+ oostyle.gradient.addStop( ScColorEngine::getRGBColor(col2, m_Doc), 1.0, 0.5, 1, c2, shadeE );
+ }
+ }
+ }
+ }
+}
+
+void OODPlug::parseCharStyle(CharStyle& style, const QDomElement &e)
+{
+ if ( m_styleStack.hasAttribute("fo:font-size") )
+ {
+ QString fs = m_styleStack.attribute("fo:font-size").remove( "pt" );
+ int FontSize = (int) (ScCLocale::toFloatC(fs) * 10.0);
+ style.setFontSize(FontSize);
+ }
+}
+
+void OODPlug::parseParagraphStyle(ParagraphStyle& style, const QDomElement &e)
+{
+ if ( m_styleStack.hasAttribute("fo:text-align") )
+ {
+ QString attValue = m_styleStack.attribute("fo:text-align");
+ if (attValue == "left")
+ style.setAlignment(ParagraphStyle::Leftaligned);
+ if (attValue == "center")
+ style.setAlignment(ParagraphStyle::Centered);
+ if (attValue == "right")
+ style.setAlignment(ParagraphStyle::Rightaligned);
+ }
+ if ( m_styleStack.hasAttribute("fo:font-size") )
+ {
+ QString fs = m_styleStack.attribute("fo:font-size").remove( "pt" );
+ int FontSize = (int) (ScCLocale::toFloatC(fs) * 10.0);
+ style.charStyle().setFontSize(FontSize);
+ style.setLineSpacing((FontSize + FontSize * 0.2) / 10.0);
+ }
+}
+
+PageItem* OODPlug::parseTextP (const QDomElement& elm, PageItem* item)
+{
+ for ( QDomNode n = elm.firstChild(); !n.isNull(); n = n.nextSibling() )
+ {
+ if ( !n.hasAttributes() && !n.hasChildNodes() )
+ continue;
+ QDomElement e = n.toElement();
+ if ( e.text().isEmpty() )
+ continue;
+ storeObjectStyles(e);
+ item->itemText.insertChars(-1, SpecialChars::PARSEP);
+ item = parseTextSpans(e, item);
+ }
+ return item;
+}
+
+PageItem* OODPlug::parseTextSpans(const QDomElement& elm, PageItem* item)
+{
+ bool firstSpan = true;
+ for ( QDomNode n = elm.firstChild(); !n.isNull(); n = n.nextSibling() )
+ {
+ QString chars;
+ QDomElement e = n.toElement();
+ if (n.isElement() && (e.tagName() == "text:span"))
+ {
+ chars = e.text().simplified();
+ storeObjectStyles(e);
+ }
+ if (n.isText())
+ {
+ QDomText t = n.toText();
+ chars = t.data().simplified();
+ }
+ if (chars.isEmpty())
+ continue;
+ int pos = item->itemText.length();
+ if ( firstSpan && (m_styleStack.hasAttribute("fo:text-align") || m_styleStack.hasAttribute("fo:font-size")) )
+ {
+ ParagraphStyle newStyle;
+ parseParagraphStyle(newStyle, n.isElement() ? e : elm);
+ item->itemText.applyStyle(-1, newStyle);
+ }
+ item->itemText.insertChars( -2, chars);
+ if ( !firstSpan && m_styleStack.hasAttribute("fo:font-size") )
+ {
+ CharStyle newStyle;
+ parseCharStyle(newStyle, n.isElement() ? e : elm);
+ item->itemText.applyCharStyle(pos, chars.length(), newStyle);
+ }
+ if (!item->asPolyLine() && !item->asTextFrame())
+ item = m_Doc->convertItemTo(item, PageItem::TextFrame);
+ firstSpan = false;
+ }
+ return item;
+}
+
+PageItem* OODPlug::finishNodeParsing(const QDomElement &elm, PageItem* item, OODrawStyle& oostyle)
+{
+ item->setTextToFrameDist(0.0, 0.0, 0.0, 0.0);
+// bool firstPa = false;
+ QString drawID = elm.attribute("draw:name");
+ item = parseTextP(elm, item);
+ item->setFillTransparency(oostyle.fillTrans);
+ item->setLineTransparency(oostyle.strokeTrans);
+ if (oostyle.dashes.count() != 0)
+ item->DashValues = oostyle.dashes;
+ if (!drawID.isEmpty())
+ {
+ item->setItemName(drawID);
+ item->AutoName = false;
+ }
+ if (elm.hasAttribute("draw:transform"))
+ {
+ parseTransform(&item->PoLine, elm.attribute("draw:transform"));
+ item->ClipEdited = true;
+ item->FrameType = 3;
+ FPoint wh = getMaxClipF(&item->PoLine);
+ item->setWidthHeight(wh.x(), wh.y());
+ item->Clip = FlattenPath(item->PoLine, item->Segments);
+ m_Doc->AdjustItemSize(item);
+ }
+ item->OwnPage = m_Doc->OnPage(item);
+ //ite->setTextFlowMode(PageItem::TextFlowUsesFrameShape);
+ item->setTextFlowMode(PageItem::TextFlowDisabled);
+ if (oostyle.haveGradient)
+ {
+ item->GrType = 0;
+ if (oostyle.gradient.Stops() > 1)
+ {
+ item->fill_gradient = oostyle.gradient;
+ if (oostyle.gradientType == 1)
+ {
+ bool flipped = false;
+ double gradientAngle(oostyle.gradientAngle);
+ if ((gradientAngle == 0) || (gradientAngle == 180) || (gradientAngle == 90) || (gradientAngle == 270))
+ {
+ if ((gradientAngle == 0) || (gradientAngle == 180))
+ {
+ item->GrType = 6;
+ item->GrStartX = item->width() / 2.0;
+ item->GrStartY = 0;
+ item->GrEndX = item->width() / 2.0;
+ item->GrEndY = item->height();
+ }
+ else if ((gradientAngle == 90) || (gradientAngle == 270))
+ {
+ item->GrType = 6;
+ item->GrStartX = 0;
+ item->GrStartY = item->height() / 2.0;
+ item->GrEndX = item->width();
+ item->GrEndY = item->height() / 2.0;
+ }
+ }
+ else
+ {
+ if ((gradientAngle > 90) && (gradientAngle < 270))
+ gradientAngle -= 180;
+ else if ((gradientAngle > 270) && (gradientAngle < 360))
+ {
+ gradientAngle = 360 - gradientAngle;
+ flipped = true;
+ }
+ double xpos;
+ xpos = (item->width() / 2) * tan(gradientAngle* M_PI / 180.0) * (item->height() / item->width()) + (item->width() / 2);
+ if ((xpos < 0) || (xpos > item->width()))
+ {
+ xpos = (item->height() / 2)- (item->height() / 2) * tan(gradientAngle* M_PI / 180.0) * (item->height() / item->width());
+ if (flipped)
+ {
+ item->GrEndX = item->width();
+ item->GrEndY = item->height() - xpos;
+ item->GrStartX = 0;
+ item->GrStartY = xpos;
+ }
+ else
+ {
+ item->GrEndY = xpos;
+ item->GrEndX = item->width();
+ item->GrStartX = 0;
+ item->GrStartY = item->height() - xpos;
+ }
+ }
+ else
+ {
+ item->GrEndX = xpos;
+ item->GrEndY = item->height();
+ item->GrStartX = item->width() - xpos;
+ item->GrStartY = 0;
+ }
+ if (flipped)
+ {
+ item->GrEndX = item->width() - xpos;
+ item->GrEndY = item->height();
+ item->GrStartX = xpos;
+ item->GrStartY = 0;
+ }
+ item->GrType = 6;
+ }
+ }
+ if (oostyle.gradientType == 2)
+ {
+ item->GrType = 7;
+ item->GrStartX = item->width() * oostyle.gradientPointX;
+ item->GrStartY = item->height()* oostyle.gradientPointY;
+ if (item->width() >= item->height())
+ {
+ item->GrEndX = item->width();
+ item->GrEndY = item->height() / 2.0;
+ }
+ else
+ {
+ item->GrEndX = item->width() / 2.0;
+ item->GrEndY = item->height();
+ }
+ //m_Doc->view()->updateGradientVectors(ite);
+ item->updateGradientVectors();
+ }
+ }
+ else
+ {
+ QList<VColorStop*> cstops = oostyle.gradient.colorStops();
+ item->setFillColor(cstops.at(0)->name);
+ item->setFillShade(cstops.at(0)->shade);
+ }
+ }
+ return item;
+}
+
+void OODPlug::createStyleMap( QDomDocument &docstyles )
+{
+ QDomElement styles = docstyles.documentElement();
+ if( styles.isNull() )
+ return;
+
+ QDomNode fixedStyles = styles.namedItem( "office:styles" );
+ if( !fixedStyles.isNull() )
+ {
+ insertDraws( fixedStyles.toElement() );
+ insertStyles( fixedStyles.toElement() );
+ }
+ QDomNode automaticStyles = styles.namedItem( "office:automatic-styles" );
+ if( !automaticStyles.isNull() )
+ insertStyles( automaticStyles.toElement() );
+
+ QDomNode masterStyles = styles.namedItem( "office:master-styles" );
+ if( !masterStyles.isNull() )
+ insertStyles( masterStyles.toElement() );
+}
+
+void OODPlug::insertDraws( const QDomElement& styles )
+{
+ for( QDomNode n = styles.firstChild(); !n.isNull(); n = n.nextSibling() )
+ {
+ QDomElement e = n.toElement();
+ if( !e.hasAttribute( "draw:name" ) )
+ continue;
+ QString name = e.attribute( "draw:name" );
+ m_draws.insert( name, new QDomElement( e ) );
+ }
+}
+
+void OODPlug::insertStyles( const QDomElement& styles )
+{
+ for ( QDomNode n = styles.firstChild(); !n.isNull(); n = n.nextSibling() )
+ {
+ QDomElement e = n.toElement();
+ if( !e.hasAttribute( "style:name" ) )
+ continue;
+ QString name = e.attribute( "style:name" );
+ m_styles.insert( name, new QDomElement( e ) );
+ }
+}
+
+void OODPlug::fillStyleStack( const QDomElement& object )
+{
+ if( object.hasAttribute( "presentation:style-name" ) )
+ addStyles( m_styles.value(object.attribute( "presentation:style-name" ), NULL) );
+ if( object.hasAttribute( "draw:style-name" ) )
+ addStyles( m_styles.value(object.attribute( "draw:style-name" ), NULL) );
+ if( object.hasAttribute( "draw:text-style-name" ) )
+ addStyles( m_styles.value(object.attribute( "draw:text-style-name" ), NULL) );
+ if( object.hasAttribute( "text:style-name" ) )
+ addStyles( m_styles.value(object.attribute( "text:style-name" ), NULL) );
+}
+
+void OODPlug::addStyles( const QDomElement* style )
+{
+ if (style)
+ {
+ if( style->hasAttribute( "style:parent-style-name" ) )
+ addStyles( m_styles.value(style->attribute( "style:parent-style-name" ), NULL) );
+ m_styleStack.push( *style );
+ }
+}
+
+void OODPlug::storeObjectStyles( const QDomElement& object )
+{
+ fillStyleStack( object );
+}
+
+double OODPlug::parseUnit(const QString &unit)
+{
+ QString unitval=unit;
+ if (unit.isEmpty())
+ return 0.0;
+ if( unit.right( 2 ) == "pt" )
+ unitval.replace( "pt", "" );
+ else if( unit.right( 2 ) == "cm" )
+ unitval.replace( "cm", "" );
+ else if( unit.right( 2 ) == "mm" )
+ unitval.replace( "mm" , "" );
+ else if( unit.right( 2 ) == "in" )
+ unitval.replace( "in", "" );
+ else if( unit.right( 2 ) == "px" )
+ unitval.replace( "px", "" );
+ double value = ScCLocale::toDoubleC(unitval);
+ if( unit.right( 2 ) == "pt" )
+ value = value;
+ else if( unit.right( 2 ) == "cm" )
+ value = ( value / 2.54 ) * 72;
+ else if( unit.right( 2 ) == "mm" )
+ value = ( value / 25.4 ) * 72;
+ else if( unit.right( 2 ) == "in" )
+ value = value * 72;
+ else if( unit.right( 2 ) == "px" )
+ value = value;
+ return value;
+}
+
+QColor OODPlug::parseColorN( const QString &rgbColor )
+{
+ int r, g, b;
+ keywordToRGB( rgbColor, r, g, b );
+ return QColor( r, g, b );
+}
+
+QString OODPlug::parseColor( const QString &s )
+{
+ QColor c;
+ QString ret = CommonStrings::None;
+ if( s.startsWith( "rgb(" ) )
+ {
+ QString parse = s.trimmed();
+ QStringList colors = parse.split( ',', QString::SkipEmptyParts );
+ QString r = colors[0].right( ( colors[0].length() - 4 ) );
+ QString g = colors[1];
+ QString b = colors[2].left( ( colors[2].length() - 1 ) );
+ if( r.contains( "%" ) )
+ {
+ r = r.left( r.length() - 1 );
+ r = QString::number( static_cast<int>( ( static_cast<double>( 255 * ScCLocale::toDoubleC(r) ) / 100.0 ) ) );
+ }
+ if( g.contains( "%" ) )
+ {
+ g = g.left( g.length() - 1 );
+ g = QString::number( static_cast<int>( ( static_cast<double>( 255 * ScCLocale::toDoubleC(g) ) / 100.0 ) ) );
+ }
+ if( b.contains( "%" ) )
+ {
+ b = b.left( b.length() - 1 );
+ b = QString::number( static_cast<int>( ( static_cast<double>( 255 * ScCLocale::toDoubleC(b) ) / 100.0 ) ) );
+ }
+ c = QColor(r.toInt(), g.toInt(), b.toInt());
+ }
+ else
+ {
+ QString rgbColor = s.trimmed();
+ if( rgbColor.startsWith( "#" ) )
+ c.setNamedColor( rgbColor );
+ else
+ c = parseColorN( rgbColor );
+ }
+ ColorList::Iterator it;
+ bool found = false;
+ int r, g, b;
+ QColor tmpR;
+ for (it = m_Doc->PageColors.begin(); it != m_Doc->PageColors.end(); ++it)
+ {
+ if (it.value().getColorModel() == colorModelRGB)
+ {
+ it.value().getRGB(&r, &g, &b);
+ tmpR.setRgb(r, g, b);
+ if (c == tmpR)
+ {
+ ret = it.key();
+ found = true;
+ }
+ }
+ }
+ if (!found)
+ {
+ ScColor tmp;
+ tmp.fromQColor(c);
+ tmp.setSpotColor(false);
+ tmp.setRegistrationColor(false);
+ m_Doc->PageColors.insert("FromOODraw"+c.name(), tmp);
+ importedColors.append("FromOODraw"+c.name());
+ ret = "FromOODraw"+c.name();
+ }
+ return ret;
+}
+
+void OODPlug::parseTransform(FPointArray *composite, const QString &transform)
+{
+ double dx, dy;
+ QTransform result;
+ QStringList subtransforms = transform.split(')', QString::SkipEmptyParts);
+ QStringList::ConstIterator it = subtransforms.begin();
+ QStringList::ConstIterator end = subtransforms.end();
+ for (; it != end; ++it)
+ {
+ QStringList subtransform = (*it).split('(', QString::SkipEmptyParts);
+ subtransform[0] = subtransform[0].trimmed().toLower();
+ subtransform[1] = subtransform[1].simplified();
+ QRegExp reg("[,( ]");
+ QStringList params = subtransform[1].split(reg, QString::SkipEmptyParts);
+ if(subtransform[0].startsWith(";") || subtransform[0].startsWith(","))
+ subtransform[0] = subtransform[0].right(subtransform[0].length() - 1);
+ if(subtransform[0] == "rotate")
+ {
+ result = QTransform();
+ result.rotate(-parseUnit(params[0]) * 180 / M_PI);
+ composite->map(result);
+ }
+ else if(subtransform[0] == "translate")
+ {
+ if(params.count() == 2)
+ {
+ dx = parseUnit(params[0]);
+ dy = parseUnit(params[1]);
+ }
+ else
+ {
+ dx = parseUnit(params[0]);
+ dy =0.0;
+ }
+ result = QTransform();
+ result.translate(dx, dy);
+ composite->map(result);
+ }
+ else if(subtransform[0] == "skewx")
+ {
+ result = QTransform();
+ result.shear(-tan(ScCLocale::toDoubleC(params[0])), 0.0);
+ composite->map(result);
+ }
+ else if(subtransform[0] == "skewy")
+ {
+ result = QTransform();
+ result.shear(0.0, -tan(ScCLocale::toDoubleC(params[0])));
+ composite->map(result);
+ }
+ }
+}
+
+void OODPlug::parseViewBox( const QDomElement& object, double *x, double *y, double *w, double *h )
+{
+ if( !object.attribute( "svg:viewBox" ).isEmpty() )
+ {
+ QString viewbox( object.attribute( "svg:viewBox" ) );
+ QStringList points = viewbox.replace( QRegExp(","), " ").simplified().split( ' ', QString::SkipEmptyParts );
+ *x = ScCLocale::toDoubleC(points[0]);
+ *y = ScCLocale::toDoubleC(points[1]);
+ *w = ScCLocale::toDoubleC(points[2]);
+ *h = ScCLocale::toDoubleC(points[3]);
+ }
+}
+
+void OODPlug::appendPoints(FPointArray *composite, const QDomElement& object, bool closePath)
+{
+ double x = parseUnit(object.attribute("svg:x"));
+ double y = parseUnit(object.attribute("svg:y")) ;
+ double w = parseUnit(object.attribute("svg:width"));
+ double h = parseUnit(object.attribute("svg:height"));
+ double vx = 0;
+ double vy = 0;
+ double vw = 1;
+ double vh = 1;
+ parseViewBox(object, &vx, &vy, &vw, &vh);
+ double sx = (vw != 0.0) ? (w / vw) : w;
+ double sy = (vh != 0.0) ? (h / vh) : h;
+ QStringList ptList = object.attribute( "draw:points" ).split( ' ', QString::SkipEmptyParts );
+ FPoint point, firstP;
+ bool bFirst = true;
+ for( QStringList::Iterator it = ptList.begin(); it != ptList.end(); ++it )
+ {
+ point = FPoint(ScCLocale::toDoubleC((*it).section( ',', 0, 0 )), ScCLocale::toDoubleC((*it).section( ',', 1, 1 )));
+ if (bFirst)
+ {
+ composite->addPoint(point);
+ composite->addPoint(point);
+ firstP = point;
+ bFirst = false;
+ }
+ else
+ {
+ composite->addPoint(point);
+ composite->addPoint(point);
+ composite->addPoint(point);
+ composite->addPoint(point);
+ }
+ }
+ if (closePath)
+ {
+ composite->addPoint(firstP);
+ composite->addPoint(firstP);
+ }
+ QTransform mat;
+ mat.translate(x, y);
+ mat.scale(sx, sy);
+ composite->map(mat);
+}
+
+const char * OODPlug::getCoord( const char *ptr, double &number )
+{
+ int integer, exponent;
+ double decimal, frac;
+ int sign, expsign;
+
+ exponent = 0;
+ integer = 0;
+ frac = 1.0;
+ decimal = 0;
+ sign = 1;
+ expsign = 1;
+
+ // read the sign
+ if(*ptr == '+')
+ ptr++;
+ else if(*ptr == '-')
+ {
+ ptr++;
+ sign = -1;
+ }
+
+ // read the integer part
+ while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9')
+ integer = (integer * 10) + *(ptr++) - '0';
+ if(*ptr == '.') // read the decimals
+ {
+ ptr++;
+ while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9')
+ decimal += (*(ptr++) - '0') * (frac *= 0.1);
+ }
+
+ if(*ptr == 'e' || *ptr == 'E') // read the exponent part
+ {
+ ptr++;
+
+ // read the sign of the exponent
+ if(*ptr == '+')
+ ptr++;
+ else if(*ptr == '-')
+ {
+ ptr++;
+ expsign = -1;
+ }
+
+ exponent = 0;
+ while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9')
+ {
+ exponent *= 10;
+ exponent += *ptr - '0';
+ ptr++;
+ }
+ }
+ number = integer + decimal;
+ number *= sign * pow( static_cast<double>(10), static_cast<double>( expsign * exponent ) );
+
+ // skip the following space
+ if(*ptr == ' ')
+ ptr++;
+
+ return ptr;
+}
+
+bool OODPlug::parseSVG( const QString &s, FPointArray *ite )
+{
+ QString d = s;
+ d = d.replace( QRegExp( "," ), " ");
+ bool ret = false;
+ if( !d.isEmpty() )
+ {
+ d = d.simplified();
+ QByteArray data = d.toLatin1();
+ const char *ptr = data.constData();
+ const char *end = data.constData() + data.length() + 1;
+ double contrlx, contrly, curx, cury, subpathx, subpathy, tox, toy, x1, y1, x2, y2, xc, yc;
+ double px1, py1, px2, py2, px3, py3;
+ bool relative;
+ FirstM = true;
+ char command = *(ptr++), lastCommand = ' ';
+ subpathx = subpathy = curx = cury = contrlx = contrly = 0.0;
+ while( ptr < end )
+ {
+ if( *ptr == ' ' )
+ ptr++;
+ relative = false;
+ switch( command )
+ {
+ case 'm':
+ relative = true;
+ case 'M':
+ {
+ ptr = getCoord( ptr, tox );
+ ptr = getCoord( ptr, toy );
+ WasM = true;
+ subpathx = curx = relative ? curx + tox : tox;
+ subpathy = cury = relative ? cury + toy : toy;
+ svgMoveTo(curx, cury );
+ break;
+ }
+ case 'l':
+ relative = true;
+ case 'L':
+ {
+ ptr = getCoord( ptr, tox );
+ ptr = getCoord( ptr, toy );
+ curx = relative ? curx + tox : tox;
+ cury = relative ? cury + toy : toy;
+ svgLineTo(ite, curx, cury );
+ break;
+ }
+ case 'h':
+ {
+ ptr = getCoord( ptr, tox );
+ curx = curx + tox;
+ svgLineTo(ite, curx, cury );
+ break;
+ }
+ case 'H':
+ {
+ ptr = getCoord( ptr, tox );
+ curx = tox;
+ svgLineTo(ite, curx, cury );
+ break;
+ }
+ case 'v':
+ {
+ ptr = getCoord( ptr, toy );
+ cury = cury + toy;
+ svgLineTo(ite, curx, cury );
+ break;
+ }
+ case 'V':
+ {
+ ptr = getCoord( ptr, toy );
+ cury = toy;
+ svgLineTo(ite, curx, cury );
+ break;
+ }
+ case 'z':
+ case 'Z':
+ {
+// curx = subpathx;
+// cury = subpathy;
+ svgClosePath(ite);
+ break;
+ }
+ case 'c':
+ relative = true;
+ case 'C':
+ {
+ ptr = getCoord( ptr, x1 );
+ ptr = getCoord( ptr, y1 );
+ ptr = getCoord( ptr, x2 );
+ ptr = getCoord( ptr, y2 );
+ ptr = getCoord( ptr, tox );
+ ptr = getCoord( ptr, toy );
+ px1 = relative ? curx + x1 : x1;
+ py1 = relative ? cury + y1 : y1;
+ px2 = relative ? curx + x2 : x2;
+ py2 = relative ? cury + y2 : y2;
+ px3 = relative ? curx + tox : tox;
+ py3 = relative ? cury + toy : toy;
+ svgCurveToCubic(ite, px1, py1, px2, py2, px3, py3 );
+ contrlx = relative ? curx + x2 : x2;
+ contrly = relative ? cury + y2 : y2;
+ curx = relative ? curx + tox : tox;
+ cury = relative ? cury + toy : toy;
+ break;
+ }
+ case 's':
+ relative = true;
+ case 'S':
+ {
+ ptr = getCoord( ptr, x2 );
+ ptr = getCoord( ptr, y2 );
+ ptr = getCoord( ptr, tox );
+ ptr = getCoord( ptr, toy );
+ px1 = 2 * curx - contrlx;
+ py1 = 2 * cury - contrly;
+ px2 = relative ? curx + x2 : x2;
+ py2 = relative ? cury + y2 : y2;
+ px3 = relative ? curx + tox : tox;
+ py3 = relative ? cury + toy : toy;
+ svgCurveToCubic(ite, px1, py1, px2, py2, px3, py3 );
+ contrlx = relative ? curx + x2 : x2;
+ contrly = relative ? cury + y2 : y2;
+ curx = relative ? curx + tox : tox;
+ cury = relative ? cury + toy : toy;
+ break;
+ }
+ case 'q':
+ relative = true;
+ case 'Q':
+ {
+ ptr = getCoord( ptr, x1 );
+ ptr = getCoord( ptr, y1 );
+ ptr = getCoord( ptr, tox );
+ ptr = getCoord( ptr, toy );
+ px1 = relative ? (curx + 2 * (x1 + curx)) * (1.0 / 3.0) : (curx + 2 * x1) * (1.0 / 3.0);
+ py1 = relative ? (cury + 2 * (y1 + cury)) * (1.0 / 3.0) : (cury + 2 * y1) * (1.0 / 3.0);
+ px2 = relative ? ((curx + tox) + 2 * (x1 + curx)) * (1.0 / 3.0) : (tox + 2 * x1) * (1.0 / 3.0);
+ py2 = relative ? ((cury + toy) + 2 * (y1 + cury)) * (1.0 / 3.0) : (toy + 2 * y1) * (1.0 / 3.0);
+ px3 = relative ? curx + tox : tox;
+ py3 = relative ? cury + toy : toy;
+ svgCurveToCubic(ite, px1, py1, px2, py2, px3, py3 );
+ contrlx = relative ? curx + x1 : (tox + 2 * x1) * (1.0 / 3.0);
+ contrly = relative ? cury + y1 : (toy + 2 * y1) * (1.0 / 3.0);
+ curx = relative ? curx + tox : tox;
+ cury = relative ? cury + toy : toy;
+ break;
+ }
+ case 't':
+ relative = true;
+ case 'T':
+ {
+ ptr = getCoord(ptr, tox);
+ ptr = getCoord(ptr, toy);
+ xc = 2 * curx - contrlx;
+ yc = 2 * cury - contrly;
+ px1 = relative ? (curx + 2 * xc) * (1.0 / 3.0) : (curx + 2 * xc) * (1.0 / 3.0);
+ py1 = relative ? (cury + 2 * yc) * (1.0 / 3.0) : (cury + 2 * yc) * (1.0 / 3.0);
+ px2 = relative ? ((curx + tox) + 2 * xc) * (1.0 / 3.0) : (tox + 2 * xc) * (1.0 / 3.0);
+ py2 = relative ? ((cury + toy) + 2 * yc) * (1.0 / 3.0) : (toy + 2 * yc) * (1.0 / 3.0);
+ px3 = relative ? curx + tox : tox;
+ py3 = relative ? cury + toy : toy;
+ svgCurveToCubic(ite, px1, py1, px2, py2, px3, py3 );
+ contrlx = xc;
+ contrly = yc;
+ curx = relative ? curx + tox : tox;
+ cury = relative ? cury + toy : toy;
+ break;
+ }
+ case 'a':
+ relative = true;
+ case 'A':
+ {
+ bool largeArc, sweep;
+ double angle, rx, ry;
+ ptr = getCoord( ptr, rx );
+ ptr = getCoord( ptr, ry );
+ ptr = getCoord( ptr, angle );
+ ptr = getCoord( ptr, tox );
+ largeArc = tox == 1;
+ ptr = getCoord( ptr, tox );
+ sweep = tox == 1;
+ ptr = getCoord( ptr, tox );
+ ptr = getCoord( ptr, toy );
+ calculateArc(ite, relative, curx, cury, angle, tox, toy, rx, ry, largeArc, sweep );
+ }
+ }
+ lastCommand = command;
+ if(*ptr == '+' || *ptr == '-' || (*ptr >= '0' && *ptr <= '9'))
+ {
+ // there are still coords in this command
+ if(command == 'M')
+ command = 'L';
+ else if(command == 'm')
+ command = 'l';
+ }
+ else
+ command = *(ptr++);
+
+ if( lastCommand != 'C' && lastCommand != 'c' &&
+ lastCommand != 'S' && lastCommand != 's' &&
+ lastCommand != 'Q' && lastCommand != 'q' &&
+ lastCommand != 'T' && lastCommand != 't')
+ {
+ contrlx = curx;
+ contrly = cury;
+ }
+ }
+ if ((lastCommand != 'z') && (lastCommand != 'Z'))
+ ret = true;
+ if (ite->size() > 2)
+ {
+ if ((ite->point(0).x() == ite->point(ite->size()-2).x()) && (ite->point(0).y() == ite->point(ite->size()-2).y()))
+ ret = false;
+ }
+ }
+ return ret;
+}
+
+void OODPlug::calculateArc(FPointArray *ite, bool relative, double &curx, double &cury, double angle, double x, double y, double r1, double r2, bool largeArcFlag, bool sweepFlag)
+{
+ double sin_th, cos_th;
+ double a00, a01, a10, a11;
+ double x0, y0, x1, y1, xc, yc;
+ double d, sfactor, sfactor_sq;
+ double th0, th1, th_arc;
+ int i, n_segs;
+ sin_th = sin(angle * (M_PI / 180.0));
+ cos_th = cos(angle * (M_PI / 180.0));
+ double dx;
+ if(!relative)
+ dx = (curx - x) / 2.0;
+ else
+ dx = -x / 2.0;
+ double dy;
+ if(!relative)
+ dy = (cury - y) / 2.0;
+ else
+ dy = -y / 2.0;
+ double _x1 = cos_th * dx + sin_th * dy;
+ double _y1 = -sin_th * dx + cos_th * dy;
+ double Pr1 = r1 * r1;
+ double Pr2 = r2 * r2;
+ double Px = _x1 * _x1;
+ double Py = _y1 * _y1;
+ double check = Px / Pr1 + Py / Pr2;
+ if(check > 1)
+ {
+ r1 = r1 * sqrt(check);
+ r2 = r2 * sqrt(check);
+ }
+ a00 = cos_th / r1;
+ a01 = sin_th / r1;
+ a10 = -sin_th / r2;
+ a11 = cos_th / r2;
+ x0 = a00 * curx + a01 * cury;
+ y0 = a10 * curx + a11 * cury;
+ if(!relative)
+ x1 = a00 * x + a01 * y;
+ else
+ x1 = a00 * (curx + x) + a01 * (cury + y);
+ if(!relative)
+ y1 = a10 * x + a11 * y;
+ else
+ y1 = a10 * (curx + x) + a11 * (cury + y);
+ d = (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0);
+ sfactor_sq = 1.0 / d - 0.25;
+ if(sfactor_sq < 0)
+ sfactor_sq = 0;
+ sfactor = sqrt(sfactor_sq);
+ if(sweepFlag == largeArcFlag)
+ sfactor = -sfactor;
+ xc = 0.5 * (x0 + x1) - sfactor * (y1 - y0);
+ yc = 0.5 * (y0 + y1) + sfactor * (x1 - x0);
+
+ th0 = atan2(y0 - yc, x0 - xc);
+ th1 = atan2(y1 - yc, x1 - xc);
+ th_arc = th1 - th0;
+ if(th_arc < 0 && sweepFlag)
+ th_arc += 2 * M_PI;
+ else if(th_arc > 0 && !sweepFlag)
+ th_arc -= 2 * M_PI;
+ n_segs = static_cast<int>(ceil(fabs(th_arc / (M_PI * 0.5 + 0.001))));
+ for(i = 0; i < n_segs; i++)
+ {
+ {
+ double sin_th, cos_th;
+ double a00, a01, a10, a11;
+ double x1, y1, x2, y2, x3, y3;
+ double t;
+ double th_half;
+ double _th0 = th0 + i * th_arc / n_segs;
+ double _th1 = th0 + (i + 1) * th_arc / n_segs;
+ sin_th = sin(angle * (M_PI / 180.0));
+ cos_th = cos(angle * (M_PI / 180.0));
+ a00 = cos_th * r1;
+ a01 = -sin_th * r2;
+ a10 = sin_th * r1;
+ a11 = cos_th * r2;
+ th_half = 0.5 * (_th1 - _th0);
+ t = (8.0 / 3.0) * sin(th_half * 0.5) * sin(th_half * 0.5) / sin(th_half);
+ x1 = xc + cos(_th0) - t * sin(_th0);
+ y1 = yc + sin(_th0) + t * cos(_th0);
+ x3 = xc + cos(_th1);
+ y3 = yc + sin(_th1);
+ x2 = x3 + t * sin(_th1);
+ y2 = y3 - t * cos(_th1);
+ svgCurveToCubic(ite, a00 * x1 + a01 * y1, a10 * x1 + a11 * y1, a00 * x2 + a01 * y2, a10 * x2 + a11 * y2, a00 * x3 + a01 * y3, a10 * x3 + a11 * y3 );
+ }
+ }
+ if(!relative)
+ curx = x;
+ else
+ curx += x;
+ if(!relative)
+ cury = y;
+ else
+ cury += y;
+}
+
+void OODPlug::svgMoveTo(double x1, double y1)
+{
+ CurrX = x1;
+ CurrY = y1;
+ StartX = x1;
+ StartY = y1;
+ PathLen = 0;
+}
+
+void OODPlug::svgLineTo(FPointArray *i, double x1, double y1)
+{
+ if ((!FirstM) && (WasM))
+ {
+ i->setMarker();
+ PathLen += 4;
+ }
+ FirstM = false;
+ WasM = false;
+ if (i->size() > 3)
+ {
+ FPoint b1 = i->point(i->size()-4);
+ FPoint b2 = i->point(i->size()-3);
+ FPoint b3 = i->point(i->size()-2);
+ FPoint b4 = i->point(i->size()-1);
+ FPoint n1 = FPoint(CurrX, CurrY);
+ FPoint n2 = FPoint(x1, y1);
+ if ((b1 == n1) && (b2 == n1) && (b3 == n2) && (b4 == n2))
+ return;
+ }
+ i->addPoint(FPoint(CurrX, CurrY));
+ i->addPoint(FPoint(CurrX, CurrY));
+ i->addPoint(FPoint(x1, y1));
+ i->addPoint(FPoint(x1, y1));
+ CurrX = x1;
+ CurrY = y1;
+ PathLen += 4;
+}
+
+void OODPlug::svgCurveToCubic(FPointArray *i, double x1, double y1, double x2, double y2, double x3, double y3)
+{
+ if ((!FirstM) && (WasM))
+ {
+ i->setMarker();
+ PathLen += 4;
+ }
+ FirstM = false;
+ WasM = false;
+ if (PathLen > 3)
+ {
+ FPoint b1 = i->point(i->size()-4);
+ FPoint b2 = i->point(i->size()-3);
+ FPoint b3 = i->point(i->size()-2);
+ FPoint b4 = i->point(i->size()-1);
+ FPoint n1 = FPoint(CurrX, CurrY);
+ FPoint n2 = FPoint(x1, y1);
+ FPoint n3 = FPoint(x3, y3);
+ FPoint n4 = FPoint(x2, y2);
+ if ((b1 == n1) && (b2 == n2) && (b3 == n3) && (b4 == n4))
+ return;
+ }
+ i->addPoint(FPoint(CurrX, CurrY));
+ i->addPoint(FPoint(x1, y1));
+ i->addPoint(FPoint(x3, y3));
+ i->addPoint(FPoint(x2, y2));
+ CurrX = x3;
+ CurrY = y3;
+ PathLen += 4;
+}
+
+void OODPlug::svgClosePath(FPointArray *i)
+{
+ if (PathLen > 2)
+ {
+ if ((PathLen == 4) || (i->point(i->size()-2).x() != StartX) || (i->point(i->size()-2).y() != StartY))
+ {
+ i->addPoint(i->point(i->size()-2));
+ i->addPoint(i->point(i->size()-3));
+ i->addPoint(FPoint(StartX, StartY));
+ i->addPoint(FPoint(StartX, StartY));
+ }
+ }
+}
+
+OODPlug::~OODPlug()
+{
+ delete tmpSel;
+ // it's probably needed as QHash() dos not support autocleaning
+ m_styles.clear();
+ m_draws.clear();
+}
+
Property changes on: scribus/plugins/import/oodraw/oodrawimp.cpp
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision
Added: svn:eol-style
+ native
Index: scribus/plugins/import/oodraw/oodrawimp.h
===================================================================
--- scribus/plugins/import/oodraw/oodrawimp.h (revision 0)
+++ scribus/plugins/import/oodraw/oodrawimp.h (revision 14707)
@@ -0,0 +1,160 @@
+/*
+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.
+*/
+#ifndef OODPLUG_H
+#define OODPLUG_H
+
+#include "pluginapi.h"
+#include "loadsaveplugin.h"
+#include "../../formatidlist.h"
+#include "stylestack.h"
+#include "scribusstructs.h"
+
+class PageItem;
+class ScrAction;
+class ScribusDoc;
+class Selection;
+class TransactionSettings;
+
+class PLUGIN_API OODrawImportPlugin : public LoadSavePlugin
+{
+ Q_OBJECT
+
+ public:
+ // Standard plugin implementation
+ OODrawImportPlugin();
+ virtual ~OODrawImportPlugin();
+ virtual const QString fullTrName() const;
+ virtual const AboutData* getAboutData() const;
+ virtual void deleteAboutData(const AboutData* about) const;
+ virtual void languageChange();
+ virtual bool fileSupported(QIODevice* file, const QString & fileName=QString::null) const;
+ virtual bool loadFile(const QString & fileName, const FileFormat & fmt, int flags, int index = 0);
+ virtual void addToMainWindowMenu(ScribusMainWindow *) {};
+
+ // Special features - File->Import slot
+ public slots:
+ virtual bool import(QString target = QString::null, int flags = lfUseCurrentPage|lfInteractive);
+
+ private:
+ void registerFormats();
+ ScrAction* importAction;
+};
+
+extern "C" PLUGIN_API int oodrawimp_getPluginAPIVersion();
+extern "C" PLUGIN_API ScPlugin* oodrawimp_getPlugin();
+extern "C" PLUGIN_API void oodrawimp_freePlugin(ScPlugin* plugin);
+
+class QWidget;
+class ScribusMainWindow;
+class ScribusDoc;
+class FPointArray;
+class QDomDocument;
+class QDomElement;
+
+class OODrawStyle
+{
+public:
+ OODrawStyle() :
+ fillColor("None"),
+ strokeColor("None"),
+ fillTrans(0.0),
+ strokeTrans(0.0),
+ strokeWidth(0.0),
+ haveGradient(false),
+ gradientType(0),
+ gradientAngle(0.0),
+ gradientPointX(0.0),
+ gradientPointY(0.0)
+ {}
+ QString fillColor;
+ QString strokeColor;
+ double fillTrans;
+ double strokeTrans;
+ double strokeWidth;
+ QVector<double> dashes;
+ bool haveGradient;
+ int gradientType;
+ VGradient gradient;
+ double gradientAngle;
+ double gradientPointX;
+ double gradientPointY;
+};
+
+class OODPlug : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ OODPlug(ScribusDoc* doc);
+ ~OODPlug();
+
+ //! \brief Indicator if there is any unsupported feature in imported svg.
+ bool unsupported;
+ bool importFailed;
+ bool importCanceled;
+ bool import(QString fName, const TransactionSettings& trSettings, int flags);
+ static double parseUnit(const QString &unit);
+
+protected:
+
+ bool convert(const TransactionSettings& trSettings, int flags);
+ QList<PageItem*> parseGroup(const QDomElement &e);
+ QList<PageItem*> parseElement(const QDomElement &e);
+ QList<PageItem*> parseRect(const QDomElement &e);
+ QList<PageItem*> parseEllipse(const QDomElement &e);
+ QList<PageItem*> parseLine(const QDomElement &e);
+ QList<PageItem*> parsePolygon(const QDomElement &e);
+ QList<PageItem*> parsePolyline(const QDomElement &e);
+ QList<PageItem*> parsePath(const QDomElement &e);
+ QList<PageItem*> parseTextBox(const QDomElement &e);
+ QList<PageItem*> parseFrame(const QDomElement &e);
+ QList<PageItem*> parseConnector(const QDomElement &e);
+ void parseStyle(OODrawStyle& style, const QDomElement &e);
+ void parseCharStyle(CharStyle& style, const QDomElement &e);
+ void parseParagraphStyle(ParagraphStyle& style, const QDomElement &e);
+ PageItem* parseTextP(const QDomElement& e, PageItem* item);
+ PageItem* parseTextSpans(const QDomElement& elm, PageItem* item);
+ PageItem* finishNodeParsing(const QDomElement &elm, PageItem* item, OODrawStyle& oostyle);
+ void createStyleMap( QDomDocument &docstyles );
+ void insertDraws( const QDomElement& styles );
+ void insertStyles( const QDomElement& styles );
+ void fillStyleStack( const QDomElement& object );
+ void addStyles( const QDomElement* style );
+ void storeObjectStyles( const QDomElement& object );
+ QColor parseColorN( const QString &rgbColor );
+ QString parseColor( const QString &s );
+ void parseTransform(FPointArray *composite, const QString &transform);
+ void parseViewBox( const QDomElement& object, double *x, double *y, double *w, double *h );
+ void appendPoints(FPointArray *composite, const QDomElement& object, bool closePath);
+ const char * getCoord( const char *ptr, double &number );
+ bool parseSVG( const QString &s, FPointArray *ite );
+ void calculateArc(FPointArray *ite, bool relative, double &curx, double &cury, double angle, double x, double y, double r1, double r2, bool largeArcFlag, bool sweepFlag);
+ void svgClosePath(FPointArray *i);
+ void svgMoveTo(double x1, double y1);
+ void svgLineTo(FPointArray *i, double x1, double y1);
+ void svgCurveToCubic(FPointArray *i, double x1, double y1, double x2, double y2, double x3, double y3);
+
+ QDomDocument inpContents;
+ QDomDocument inpStyles;
+ QDomDocument inpMeta;
+ QHash<QString,QDomElement*> m_styles, m_draws;
+ StyleStack m_styleStack;
+ QString stylePath;
+ QString contentPath;
+ QString metaPath;
+ double CurrX, CurrY, StartX, StartY;
+ int PathLen;
+ bool FirstM, WasM, PathClosed, HaveMeta;
+
+ bool interactive;
+ ScribusDoc* m_Doc;
+ Selection* tmpSel;
+ QStringList importedColors;
+};
+
+#endif
Property changes on: scribus/plugins/import/oodraw/oodrawimp.h
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision
Added: svn:eol-style
+ native
Index: scribus/plugins/import/oodraw/stylestack.cpp
===================================================================
--- scribus/plugins/import/oodraw/stylestack.cpp (revision 0)
+++ scribus/plugins/import/oodraw/stylestack.cpp (revision 14707)
@@ -0,0 +1,268 @@
+/*
+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.
+*/
+/* This file is part of the KDE project
+ Copyright (c) 2003 Lukas Tinkl <lukas at kde.org>
+ Copyright (c) 2003 David Faure <faure at kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "stylestack.h"
+#include "oodrawimp.h"
+#include "scclocale.h"
+#include <QList>
+
+StyleStack::StyleStack()
+{
+ clear();
+ fillNodeNameList(m_nodeNames, StyleStack::OODraw1x);
+}
+
+StyleStack::~StyleStack()
+{
+}
+
+void StyleStack::setMode( const StyleStack::Mode mode )
+{
+ m_nodeNames.clear();
+ fillNodeNameList(m_nodeNames, mode);
+}
+
+void StyleStack::clear()
+{
+ m_stack.clear();
+}
+
+void StyleStack::save()
+{
+ m_marks.push( m_stack.count() );
+}
+
+void StyleStack::restore()
+{
+ Q_ASSERT( !m_marks.isEmpty() );
+ int toIndex = m_marks.pop();
+ Q_ASSERT( toIndex > -1 );
+ Q_ASSERT( toIndex <= (int)m_stack.count() ); // If equal, nothing to remove. If greater, bug.
+ for ( int index = (int)m_stack.count() - 1; index >= toIndex; --index )
+ m_stack.pop_back();
+}
+
+void StyleStack::pop()
+{
+ m_stack.pop_back();
+}
+
+void StyleStack::push( const QDomElement& style )
+{
+ m_stack.append( style );
+}
+
+bool StyleStack::hasAttribute( const QString& name ) const
+{
+ // TODO: has to be fixed for complex styles like list-styles
+ QList<QDomElement>::ConstIterator it = m_stack.end();
+ while ( it != m_stack.begin() )
+ {
+ --it;
+ QDomElement properties = searchAttribute( *it, m_nodeNames, name );
+ if ( properties.hasAttribute( name ) )
+ return true;
+ }
+
+ return false;
+}
+
+QString StyleStack::attribute( const QString& name ) const
+{
+ // TODO: has to be fixed for complex styles like list-styles
+ QList<QDomElement>::ConstIterator it = m_stack.end();
+ while ( it != m_stack.begin() )
+ {
+ --it;
+ QDomElement properties = searchAttribute( *it, m_nodeNames, name );
+ if ( properties.hasAttribute( name ) )
+ return properties.attribute( name );
+ }
+
+ return QString::null;
+}
+
+bool StyleStack::hasAttribute( const QString& name, const QString& detail ) const
+{
+ QString fullName( name );
+ fullName += '-';
+ fullName += detail;
+ QList<QDomElement>::ConstIterator it = m_stack.end();
+ while ( it != m_stack.begin() )
+ {
+ --it;
+ QDomElement properties = searchAttribute( *it, m_nodeNames, name, fullName );
+ if ( properties.hasAttribute( name ) || properties.hasAttribute( fullName ) )
+ return true;
+ }
+
+ return false;
+}
+
+QString StyleStack::attribute( const QString& name, const QString& detail ) const
+{
+ QString fullName( name );
+ fullName += '-';
+ fullName += detail;
+ QList<QDomElement>::ConstIterator it = m_stack.end();
+ while ( it != m_stack.begin() )
+ {
+ --it;
+ QDomElement properties = searchAttribute( *it, m_nodeNames, name, fullName );
+ if ( properties.hasAttribute( fullName ) )
+ return properties.attribute( fullName );
+ if ( properties.hasAttribute( name ) )
+ return properties.attribute( name );
+ }
+
+ return QString::null;
+}
+
+// Font size is a bit special. "115%" applies to "the fontsize of the parent style".
+// This can be generalized though (hasAttributeThatCanBePercentOfParent() ? :)
+// Although, if we also add support for fo:font-size-rel here then it's not general anymore.
+double StyleStack::fontSize() const
+{
+ QString name = "fo:font-size";
+ double percent = 1;
+ QList<QDomElement>::ConstIterator it = m_stack.end();
+ while ( it != m_stack.begin() )
+ {
+ --it;
+ QDomElement properties = searchAttribute( *it, m_nodeNames, name );
+ if ( properties.hasAttribute( name ) ) {
+ QString value = properties.attribute( name );
+ if ( value.endsWith( "%" ) )
+ percent *= ScCLocale::toDoubleC(value) / 100.0;
+ else
+ return percent * OODPlug::parseUnit( value ); // e.g. 12pt
+ }
+ }
+ return 0;
+}
+
+bool StyleStack::hasChildNode(const QString & name) const
+{
+ QList<QDomElement>::ConstIterator it = m_stack.end();
+ while ( it != m_stack.begin() )
+ {
+ --it;
+ QDomElement properties = searchAttribute( *it, m_nodeNames, name );
+ if ( !properties.namedItem( name ).isNull() )
+ return true;
+ }
+
+ return false;
+}
+
+QDomNode StyleStack::childNode(const QString & name) const
+{
+ QList<QDomElement>::ConstIterator it = m_stack.end();
+ while ( it != m_stack.begin() )
+ {
+ --it;
+ QDomElement properties = searchAttribute( *it, m_nodeNames, name );
+ if ( !properties.namedItem( name ).isNull() )
+ return properties.namedItem( name );
+ }
+
+ return QDomNode(); // a null node
+}
+
+static bool isUserStyle( const QDomElement& e )
+{
+ QDomElement parent = e.parentNode().toElement();
+ return parent.tagName() == "office:styles";
+}
+
+QString StyleStack::userStyleName() const
+{
+ QList<QDomElement>::ConstIterator it = m_stack.end();
+ while ( it != m_stack.begin() )
+ {
+ --it;
+ if ( isUserStyle( *it ) )
+ return (*it).attribute("style:name");
+ }
+ // Can this ever happen?
+ return "Standard";
+}
+
+void StyleStack::fillNodeNameList( QStringList& names, const StyleStack::Mode mode )
+{
+ if ( mode == StyleStack::OODraw2x )
+ {
+ names.append("style:graphic-properties");
+ names.append("style:paragraph-properties");
+ names.append("style:page-layout-properties");
+ names.append("style:drawing-page-properties");
+ names.append("style:text-properties");
+ }
+ else
+ names.append("style:properties");
+}
+
+QDomElement StyleStack::searchAttribute( const QDomElement& element, const QStringList& names,const QString& name ) const
+{
+ QDomElement node;
+ QDomNodeList childNodes;
+ childNodes = element.childNodes();
+ for ( int i = 0; i < childNodes.count(); i++ )
+ {
+ QDomNode n = childNodes.item(i);
+ if ( n.isElement() )
+ {
+ QDomElement* e = (QDomElement*) (&n);
+ if ( (names.indexOf(e->nodeName()) >= 0) && e->hasAttribute(name) )
+ {
+ node = *e;
+ break;
+ }
+ }
+ }
+ return node;
+}
+
+QDomElement StyleStack::searchAttribute( const QDomElement& element, const QStringList& names, const QString& name, const QString& fullName ) const
+{
+ QDomElement node;
+ QDomNodeList childNodes;
+ childNodes = element.childNodes();
+ for ( int i = 0; i < childNodes.count(); i++ )
+ {
+ QDomNode n = childNodes.item(i);
+ if ( n.isElement() )
+ {
+ QDomElement* e = (QDomElement*) (&n);
+ if ( (names.indexOf(e->nodeName()) >= 0) && (e->hasAttribute(name) || e->hasAttribute(fullName)) )
+ {
+ node = *e;
+ break;
+ }
+ }
+ }
+ return node;
+}
Property changes on: scribus/plugins/import/oodraw/stylestack.cpp
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision
Added: svn:eol-style
+ native
Index: scribus/plugins/import/oodraw/stylestack.h
===================================================================
--- scribus/plugins/import/oodraw/stylestack.h (revision 0)
+++ scribus/plugins/import/oodraw/stylestack.h (revision 14707)
@@ -0,0 +1,170 @@
+/*
+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.
+*/
+/* This file is part of the KDE project
+ Copyright (c) 2003 Lukas Tinkl <lukas at kde.org>
+ Copyright (c) 2003 David Faure <faure at kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef STYLESTACK_H
+#define STYLESTACK_H
+
+#include <QDomElement>
+#include <QStringList>
+#include <QList>
+#include <QStack>
+
+
+/**
+ * This class implements a stack for the different styles of an object.
+ *
+ * There can be several styles that are valid for one object. For example
+ * a textobject on a page has styles 'pr3' and 'P7' and a paragraph in
+ * that textobject has styles 'P1' and 'T3'. And some styles even have
+ * parent-styles...
+ *
+ * If you want to know if there is, for example, the attribute 'fo:font-family'
+ * for this paragraph, you have to look into style 'T3', 'P1', 'P7' and 'pr3'.
+ * When you find this attribute in one style you have to stop processing the list
+ * and take the found attribute for this object.
+ *
+ * This is what this class does. You can push styles on the stack while walking
+ * through the xml-tree to your object and then ask the stack if any of the styles
+ * provides a certain attribute. The stack will search from top to bottom, i.e.
+ * in our example from 'T3' to 'pr3' and return the first occurrence of the wanted
+ * attribute.
+ *
+ * So this is some sort of inheritance where the styles on top of the stack overwrite
+ * the same attribute of a lower style on the stack.
+ */
+class StyleStack
+{
+public:
+ StyleStack();
+ virtual ~StyleStack();
+
+ enum Mode
+ {
+ OODraw1x = 1,
+ OODraw2x = 2
+ };
+
+ /**
+ * Set attribute analysis mode.
+ */
+ void setMode( const StyleStack::Mode mode );
+
+ /**
+ * Clears the complete stack.
+ */
+ void clear();
+
+ /**
+ * Save the current state of the stack. Any items added between
+ * this call and its corresponding restore() will be removed when calling restore().
+ */
+ void save();
+
+ /**
+ * Restore the stack to the state it was at the corresponding save() call.
+ */
+ void restore();
+
+ /**
+ * Removes the style on top of the stack.
+ */
+ void pop();
+
+ /**
+ * Pushes the new style onto the stack.
+ */
+ void push( const QDomElement& style );
+
+ /**
+ * Check if any of the styles on the stack has an attribute called 'name'.
+ */
+ bool hasAttribute( const QString& name ) const;
+
+ /**
+ * Search for the attribute called 'name', starting on top of the stack,
+ * and return it.
+ */
+ QString attribute( const QString& name ) const;
+
+ /**
+ * Check if any of the styles on the stack has an attribute called 'name'-'detail'
+ * where detail is e.g. left, right, top or bottom.
+ * This allows to also find 'name' alone (e.g. padding implies padding-left, padding-right etc.)
+ */
+ bool hasAttribute( const QString& name, const QString& detail ) const;
+
+ /**
+ * Search for the attribute called 'name', starting on top of the stack,
+ * and return it.
+ */
+ QString attribute( const QString& name, const QString& detail ) const;
+
+ /**
+ * Check if any of the styles on the stack has a child node called 'name'.
+ */
+ bool hasChildNode(const QString & name) const;
+
+ /**
+ * Search for a child node called 'name', starting on top of the stack,
+ * and return it.
+ */
+ QDomNode childNode(const QString & name) const;
+
+ /**
+ * Special case for the current font size, due to special handling of fo:font-size="115%".
+ */
+ double fontSize() const;
+
+ /**
+ * Return the name of the style specified by the user,
+ * i.e. not an auto style
+ */
+ QString userStyleName() const;
+
+private:
+
+ // Node names to look for style properties
+ QStringList m_nodeNames;
+
+ // For save/restore: stack of "marks". Each mark is an index in m_stack.
+ QStack<int> m_marks;
+
+ // We use QValueList instead of QValueStack because we need access to all styles
+ // not only the top one.
+ QList<QDomElement> m_stack;
+
+ // Get node name to look for according to property type
+ void fillNodeNameList( QStringList& names, const StyleStack::Mode mode );
+
+ // Search a specific attribute amongst childs of an element
+ QDomElement searchAttribute( const QDomElement& element, const QStringList& names,const QString& name ) const;
+
+ // Search a specific attribute amongst childs of an element
+ QDomElement searchAttribute( const QDomElement& element, const QStringList& names, const QString& name, const QString& fullName ) const;
+};
+
+
+#endif /* STYLESTACK_H */
Property changes on: scribus/plugins/import/oodraw/stylestack.h
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision
Added: svn:eol-style
+ native
Index: scribus/plugins/import/oodraw/CMakeLists.txt
===================================================================
--- scribus/plugins/import/oodraw/CMakeLists.txt (revision 0)
+++ scribus/plugins/import/oodraw/CMakeLists.txt (revision 14707)
@@ -0,0 +1,29 @@
+INCLUDE_DIRECTORIES(
+${CMAKE_SOURCE_DIR}
+${CMAKE_SOURCE_DIR}/scribus
+)
+
+SET(OODRAW_FL_PLUGIN_MOC_CLASSES
+oodrawimp.h
+)
+
+SET(OODRAW_FL_PLUGIN_SOURCES
+oodrawimp.cpp
+stylestack.cpp
+)
+
+SET(SCRIBUS_OODRAW_FL_PLUGIN "oodrawimp")
+
+QT4_WRAP_CPP(OODRAW_FL_PLUGIN_MOC_SOURCES ${OODRAW_FL_PLUGIN_MOC_CLASSES})
+
+ADD_LIBRARY(${SCRIBUS_OODRAW_FL_PLUGIN} MODULE ${OODRAW_FL_PLUGIN_SOURCES} ${OODRAW_FL_PLUGIN_MOC_SOURCES})
+
+TARGET_LINK_LIBRARIES(${SCRIBUS_OODRAW_FL_PLUGIN} ${PLUGIN_LIBRARIES})
+
+INSTALL(TARGETS ${SCRIBUS_OODRAW_FL_PLUGIN}
+ LIBRARY
+ DESTINATION ${PLUGINDIR}
+ PERMISSIONS ${PLUGIN_PERMISSIONS}
+)
+
+# SET_TARGET_PROPERTIES(${SCRIBUS_FONTPREVIEW_PLUGIN} PROPERTIES VERSION "0.0.0")
Property changes on: scribus/plugins/import/oodraw/CMakeLists.txt
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision
Added: svn:eol-style
+ native
Property changes on: scribus/plugins/import/oodraw
___________________________________________________________________
Added: svn:mergeinfo
Added: svn:ignore
+ Makefile
Makefile.in
*.la
*.lo
*.moc.cpp
*.moc
*.o
.deps
.libs
CVS
CMakeFiles
cmake_install.cmake
Index: scribus/plugins/import/CMakeLists.txt
===================================================================
--- scribus/plugins/import/CMakeLists.txt (revision 14706)
+++ scribus/plugins/import/CMakeLists.txt (revision 14707)
@@ -3,6 +3,7 @@
ADD_SUBDIRECTORY(cvg)
ADD_SUBDIRECTORY(drw)
ADD_SUBDIRECTORY(idml)
+ADD_SUBDIRECTORY(oodraw)
ADD_SUBDIRECTORY(pct)
ADD_SUBDIRECTORY(ps)
ADD_SUBDIRECTORY(svg)
More information about the scribus-commit
mailing list