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