r14261 by fschmid - Initial bits of a Xara importer, currently only colors are imported.

scribus-commit scribus-commit at lists.scribus.net
Wed Nov 4 14:25:26 CET 2009


Revision: 14261
Author: fschmid
Date: 2009-11-04T08:10:10.108973Z
Commit message: Initial bits of a Xara importer, currently only colors are imported.

Changeset: 
M  /trunk/Scribus/scribus/util_formats.cpp
A  /trunk/Scribus/scribus/plugins/xarimplugin/importxarplugin.h
A  /trunk/Scribus/scribus/plugins/xarimplugin/qtiocompressor.cpp
A  /trunk/Scribus/scribus/plugins/xarimplugin/importxar.h
A  /trunk/Scribus/scribus/plugins/xarimplugin/CMakeLists.txt
M  /trunk/Scribus/scribus/plugins/CMakeLists.txt
M  /trunk/Scribus/scribus/util_formats.h
A  /trunk/Scribus/scribus/plugins/xarimplugin/qtiocompressor.h
A  /trunk/Scribus/scribus/plugins/xarimplugin
A  /trunk/Scribus/scribus/plugins/xarimplugin/importxarplugin.cpp
A  /trunk/Scribus/scribus/plugins/xarimplugin/importxar.cpp
M  /trunk/Scribus/scribus/plugins/formatidlist.h

Diffs:
Index: scribus/util_formats.cpp
===================================================================
--- scribus/util_formats.cpp	(revision 14260)
+++ scribus/util_formats.cpp	(revision 14261)
@@ -37,6 +37,8 @@
 #endif
 	m_fmts.insert(FormatsManager::UNICONV, QStringList() << "cdr" << "cdt" << "ccx" << "cmx" << "cgm" << "aff" << "sk" << "sk1");
 	m_fmts.insert(FormatsManager::PCT,  QStringList() << "pct" << "pic" << "pict");
+	m_fmts.insert(FormatsManager::XAR,  QStringList() << "xar");
+	m_fmts.insert(FormatsManager::CGM,  QStringList() << "cgm");
 	
 	m_fmtNames[FormatsManager::EPS]  = QObject::tr("Encapsulated PostScript \"*.eps\"");
 	m_fmtNames[FormatsManager::GIF]  = QObject::tr("GIF");
@@ -59,6 +61,8 @@
 #endif
 	m_fmtNames[FormatsManager::UNICONV] = QObject::tr("UniConvertor File");
 	m_fmtNames[FormatsManager::PCT]  = QObject::tr("Macinthosh Pict File");
+	m_fmtNames[FormatsManager::XAR]  = QObject::tr("XARA \"*.xar\" File");
+	m_fmtNames[FormatsManager::CGM]  = QObject::tr("CGM File");
 	
 	m_fmtMimeTypes.insert(FormatsManager::EPS,  QStringList() << "application/postscript");
 	m_fmtMimeTypes.insert(FormatsManager::GIF,  QStringList() << "image/gif");
@@ -77,6 +81,8 @@
 	m_fmtMimeTypes.insert(FormatsManager::CVG,  QStringList() << "");
 	m_fmtMimeTypes.insert(FormatsManager::WPG,  QStringList() << "");
 	m_fmtMimeTypes.insert(FormatsManager::PCT,  QStringList() << "");
+	m_fmtMimeTypes.insert(FormatsManager::XAR,  QStringList() << "");
+	m_fmtMimeTypes.insert(FormatsManager::CGM,  QStringList() << "");
 			
 	QMapIterator<int, QStringList> i(m_fmts);
 	while (i.hasNext()) 
Index: scribus/util_formats.h
===================================================================
--- scribus/util_formats.h	(revision 14260)
+++ scribus/util_formats.h	(revision 14261)
@@ -65,7 +65,9 @@
 			GMAGICK			= 65536,  // GraphicsMagick
 #endif
 			UNICONV			= 131072, // UniConvertor
-			PCT				= 262144  // Mac Pict
+			PCT				= 262144,  // Mac Pict
+			XAR				= 524288,  // Xara
+			CGM				= 1048576 // CGM
 		};
 	
 /*
Index: scribus/plugins/formatidlist.h
===================================================================
--- scribus/plugins/formatidlist.h	(revision 14260)
+++ scribus/plugins/formatidlist.h	(revision 14261)
@@ -28,6 +28,8 @@
 #define FORMATID_PCTIMPORT 110
 #define FORMATID_PSIMPORT  111
 #define FORMATID_PDFIMPORT 112
+#define FORMATID_XARIMPORT 113
+#define FORMATID_CGMIMPORT 114
 
 // EXPORT
 
Index: scribus/plugins/xarimplugin/qtiocompressor.h
===================================================================
--- scribus/plugins/xarimplugin/qtiocompressor.h	(revision 0)
+++ scribus/plugins/xarimplugin/qtiocompressor.h	(revision 14261)
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** This file is part of a Qt Solutions component.
+** 
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** 
+** Contact:  Qt Software Information (qt-info at nokia.com)
+** 
+** Commercial Usage  
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Solutions Commercial License Agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and Nokia.
+** 
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** 
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+** 
+** GNU General Public License Usage 
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+** 
+** Please note Third Party Software included with Qt Solutions may impose
+** additional restrictions and it is the user's responsibility to ensure
+** that they have met the licensing requirements of the GPL, LGPL, or Qt
+** Solutions Commercial license and the relevant license of the Third
+** Party Software they are using.
+** 
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales at nokia.com.
+** 
+****************************************************************************/
+
+#ifndef QTIOCOMPRESSOR_H
+#define QTIOCOMPRESSOR_H
+
+#include <QtCore/QIODevice>
+
+class QtIOCompressorPrivate;
+class QtIOCompressor : public QIODevice
+{
+Q_OBJECT
+public:
+enum StreamFormat { ZlibFormat, GzipFormat, RawZipFormat };
+    QtIOCompressor(QIODevice *device, int compressionLevel = 6, int bufferSize = 65500);
+    ~QtIOCompressor();
+    void setStreamFormat(StreamFormat format);
+    StreamFormat streamFormat() const;
+    static bool isGzipSupported();
+    bool isSequential() const;
+    bool open(OpenMode mode);
+    void close();
+    void flush();
+    qint64 bytesAvailable() const;
+protected:
+    qint64 readData(char * data, qint64 maxSize);
+    qint64 writeData(const char * data, qint64 maxSize);
+private:
+    static bool checkGzipSupport(const char * const versionString);
+    QtIOCompressorPrivate *d_ptr;
+    Q_DECLARE_PRIVATE(QtIOCompressor)
+    Q_DISABLE_COPY(QtIOCompressor)
+};
+
+#endif
Index: scribus/plugins/xarimplugin/importxarplugin.cpp
===================================================================
--- scribus/plugins/xarimplugin/importxarplugin.cpp	(revision 0)
+++ scribus/plugins/xarimplugin/importxarplugin.cpp	(revision 14261)
@@ -0,0 +1,155 @@
+/*
+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 "commonstrings.h"
+#include "ui/customfdialog.h"
+#include "importxar.h"
+#include "importxarplugin.h"
+#include "menumanager.h"
+#include "page.h"
+#include "prefscontext.h"
+#include "prefsfile.h"
+#include "prefsmanager.h"
+#include "scraction.h"
+#include "scribuscore.h"
+#include "undomanager.h"
+#include "util_formats.h"
+
+
+int importxar_getPluginAPIVersion()
+{
+	return PLUGIN_API_VERSION;
+}
+
+ScPlugin* importxar_getPlugin()
+{
+	ImportXarPlugin* plug = new ImportXarPlugin();
+	Q_CHECK_PTR(plug);
+	return plug;
+}
+
+void importxar_freePlugin(ScPlugin* plugin)
+{
+	ImportXarPlugin* plug = dynamic_cast<ImportXarPlugin*>(plugin);
+	Q_ASSERT(plug);
+	delete plug;
+}
+
+ImportXarPlugin::ImportXarPlugin() : 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 format support.
+	languageChange();
+}
+
+void ImportXarPlugin::languageChange()
+{
+	importAction->setText( tr("Import Pict..."));
+	// (Re)register file format support
+	unregisterAll();
+	registerFormats();
+}
+
+ImportXarPlugin::~ImportXarPlugin()
+{
+	unregisterAll();
+};
+
+const QString ImportXarPlugin::fullTrName() const
+{
+	return QObject::tr("Xara Importer");
+}
+
+
+const ScActionPlugin::AboutData* ImportXarPlugin::getAboutData() const
+{
+	AboutData* about = new AboutData;
+	about->authors = "Franz Schmid <franz at scribus.info>";
+	about->shortDescription = tr("Imports Xara Files");
+	about->description = tr("Imports most Xara files into the current document,\nconverting their vector data into Scribus objects.");
+	about->license = "GPL";
+	Q_CHECK_PTR(about);
+	return about;
+}
+
+void ImportXarPlugin::deleteAboutData(const AboutData* about) const
+{
+	Q_ASSERT(about);
+	delete about;
+}
+
+void ImportXarPlugin::registerFormats()
+{
+	FileFormat fmt(this);
+	fmt.trName = FormatsManager::instance()->nameOfFormat(FormatsManager::XAR); // Human readable name
+	fmt.formatId = FORMATID_XARIMPORT;
+	fmt.filter = FormatsManager::instance()->extensionsForFormat(FormatsManager::XAR); // QFileDialog filter
+	fmt.nameMatch = QRegExp("\\."+FormatsManager::instance()->extensionListForFormat(FormatsManager::XAR, 1)+"$", Qt::CaseInsensitive);
+	fmt.load = true;
+	fmt.save = false;
+	fmt.mimeTypes = FormatsManager::instance()->mimetypeOfFormat(FormatsManager::XAR); // MIME types
+	fmt.priority = 64; // Priority
+	registerFormat(fmt);
+}
+
+bool ImportXarPlugin::fileSupported(QIODevice* /* file */, const QString & fileName) const
+{
+	return true;
+}
+
+bool ImportXarPlugin::loadFile(const QString & fileName, const FileFormat &, int flags, int /*index*/)
+{
+	// There's only one format to handle, so we just call import(...)
+	return import(fileName, flags);
+}
+
+bool ImportXarPlugin::import(QString fileName, int flags)
+{
+	if (!checkFlags(flags))
+		return false;
+	if( fileName.isEmpty() )
+	{
+		flags |= lfInteractive;
+		PrefsContext* prefs = PrefsManager::instance()->prefsFile->getPluginContext("importpct");
+		QString wdir = prefs->get("wdir", ".");
+		CustomFDialog diaf(ScCore->primaryMainWindow(), wdir, QObject::tr("Open"), tr("All Supported Formats")+" (*.xar *.XAR);;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::ImportXfig;
+	trSettings.description  = fileName;
+	trSettings.actionPixmap = Um::IXFIG;
+	if (emptyDoc || !(flags & lfInteractive) || !(flags & lfScripted))
+		UndoManager::instance()->setUndoEnabled(false);
+	if (UndoManager::undoEnabled())
+		activeTransaction = new UndoTransaction(UndoManager::instance()->beginTransaction(trSettings));
+	XarPlug *dia = new XarPlug(m_Doc, flags);
+	Q_CHECK_PTR(dia);
+	dia->import(fileName, trSettings, flags);
+	if (activeTransaction)
+	{
+		activeTransaction->commit();
+		delete activeTransaction;
+		activeTransaction = NULL;
+	}
+	if (emptyDoc || !(flags & lfInteractive) || !(flags & lfScripted))
+		UndoManager::instance()->setUndoEnabled(true);
+	delete dia;
+	return true;
+}
Index: scribus/plugins/xarimplugin/importxar.cpp
===================================================================
--- scribus/plugins/xarimplugin/importxar.cpp	(revision 0)
+++ scribus/plugins/xarimplugin/importxar.cpp	(revision 14261)
@@ -0,0 +1,724 @@
+/*
+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 <QByteArray>
+#include <QCursor>
+#include <QDrag>
+#include <QFile>
+#include <QList>
+#include <QMimeData>
+#include <QRegExp>
+#include <QTextCodec>
+#include <QStack>
+#include <QDebug>
+#include "qtiocompressor.h"
+
+#include <cstdlib>
+
+#include "commonstrings.h"
+#include "ui/customfdialog.h"
+#include "importxar.h"
+#include "loadsaveplugin.h"
+#include "ui/missing.h"
+#include "ui/multiprogressdialog.h"
+#include "pageitem_imageframe.h"
+#include "pagesize.h"
+#include "prefscontext.h"
+#include "prefsfile.h"
+#include "prefsmanager.h"
+#include "prefstable.h"
+#include "ui/propertiespalette.h"
+#include "rawimage.h"
+#include "scclocale.h"
+#include "sccolorengine.h"
+#include "scconfig.h"
+#include "scmimedata.h"
+#include "scpaths.h"
+#include "scpattern.h"
+#include "scribus.h"
+#include "scribusXml.h"
+#include "scribuscore.h"
+#include "sctextstream.h"
+#include "selection.h"
+#include "undomanager.h"
+#include "util.h"
+#include "util_formats.h"
+#include "util_icon.h"
+#include "util_math.h"
+
+extern SCRIBUS_API ScribusQApp * ScQApp;
+
+XarPlug::XarPlug(ScribusDoc* doc, int flags)
+{
+	tmpSel=new Selection(this, false);
+	m_Doc=doc;
+	interactive = (flags & LoadSavePlugin::lfInteractive);
+}
+
+bool XarPlug::import(QString fNameIn, const TransactionSettings& trSettings, int flags, bool showProgress)
+{
+	QString fName = fNameIn;
+	bool success = false;
+	interactive = (flags & LoadSavePlugin::lfInteractive);
+	importerFlags = flags;
+	cancel = false;
+	double x, y, b, h;
+	bool ret = false;
+	QFileInfo fi = QFileInfo(fName);
+	if ( !ScCore->usingGUI() )
+	{
+		interactive = false;
+		showProgress = false;
+	}
+	baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/"));
+	if ( showProgress )
+	{
+		ScribusMainWindow* mw=(m_Doc==0) ? ScCore->primaryMainWindow() : m_Doc->scMW();
+		progressDialog = new MultiProgressDialog( tr("Importing: %1").arg(fi.fileName()), CommonStrings::tr_Cancel, mw );
+		QStringList barNames, barTexts;
+		barNames << "GI";
+		barTexts << tr("Analyzing File:");
+		QList<bool> barsNumeric;
+		barsNumeric << false;
+		progressDialog->addExtraProgressBars(barNames, barTexts, barsNumeric);
+		progressDialog->setOverallTotalSteps(3);
+		progressDialog->setOverallProgress(0);
+		progressDialog->setProgress("GI", 0);
+		progressDialog->show();
+		connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelRequested()));
+		qApp->processEvents();
+	}
+	else
+		progressDialog = NULL;
+/* Set default Page to size defined in Preferences */
+	x = 0.0;
+	y = 0.0;
+	b = 0.0;
+	h = 0.0;
+	if (progressDialog)
+	{
+		progressDialog->setOverallProgress(1);
+		qApp->processEvents();
+	}
+//	parseHeader(fName, x, y, b, h);
+	if (b == 0.0)
+		b = PrefsManager::instance()->appPrefs.docSetupPrefs.pageWidth;
+	if (h == 0.0)
+		h = PrefsManager::instance()->appPrefs.docSetupPrefs.pageHeight;
+	docWidth = b;
+	docHeight = h;
+	baseX = 0;
+	baseY = 0;
+	if (!interactive || (flags & LoadSavePlugin::lfInsertPage))
+	{
+		m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
+		m_Doc->addPage(0);
+		m_Doc->view()->addPage(0, true);
+		baseX = -x;
+		baseY = -y;
+	}
+	else
+	{
+		if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc))
+		{
+			m_Doc=ScCore->primaryMainWindow()->doFileNew(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom", true);
+			ScCore->primaryMainWindow()->HaveNewDoc();
+			ret = true;
+			baseX = m_Doc->currentPage()->xOffset() - x;
+			baseY = m_Doc->currentPage()->yOffset() - y;
+		}
+	}
+	if ((!ret) && (interactive))
+	{
+		baseX = m_Doc->currentPage()->xOffset() - x;
+		baseY = m_Doc->currentPage()->yOffset() - y;
+	}
+	if ((ret) || (!interactive))
+	{
+		if (docWidth > docHeight)
+			m_Doc->PageOri = 1;
+		else
+			m_Doc->PageOri = 0;
+		m_Doc->m_pageSize = "Custom";
+	}
+	Elements.clear();
+	FPoint minSize = m_Doc->minCanvasCoordinate;
+	FPoint maxSize = m_Doc->maxCanvasCoordinate;
+	FPoint cOrigin = m_Doc->view()->canvasOrigin();
+	m_Doc->setLoading(true);
+	m_Doc->DoDrawing = false;
+	m_Doc->view()->updatesOn(false);
+	m_Doc->scMW()->ScriptRunning = true;
+	qApp->changeOverrideCursor(QCursor(Qt::WaitCursor));
+	QString CurDirP = QDir::currentPath();
+	QDir::setCurrent(fi.path());
+	if (convert(fName))
+	{
+		tmpSel->clear();
+		QDir::setCurrent(CurDirP);
+		if ((Elements.count() > 1) && (!(importerFlags & LoadSavePlugin::lfCreateDoc)))
+		{
+			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;
+		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);
+			}
+			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);
+				}
+				tmpSel->setGroupRect();
+				ScriXmlDoc *ss = new ScriXmlDoc();
+				ScElemMimeData* md = new ScElemMimeData();
+				md->setScribusElem(ss->WriteElem(m_Doc, m_Doc->view(), tmpSel));
+				delete ss;
+				m_Doc->itemSelection_DeleteItem(tmpSel);
+				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
+		{
+			m_Doc->changed();
+			m_Doc->reformPages();
+			m_Doc->view()->updatesOn(true);
+		}
+		success = true;
+	}
+	else
+	{
+		QDir::setCurrent(CurDirP);
+		m_Doc->DoDrawing = true;
+		m_Doc->scMW()->ScriptRunning = false;
+		m_Doc->view()->updatesOn(true);
+		qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
+	}
+	if (interactive)
+		m_Doc->setLoading(false);
+	//CB If we have a gui we must refresh it if we have used the progressbar
+	if ((showProgress) && (!interactive))
+		m_Doc->view()->DrawNew();
+	return success;
+}
+
+XarPlug::~XarPlug()
+{
+	if (progressDialog)
+		delete progressDialog;
+	delete tmpSel;
+}
+
+void XarPlug::parseHeader(QString fName, double &x, double &y, double &b, double &h)
+{
+	QFile f(fName);
+	if (f.open(QIODevice::ReadOnly))
+	{
+		QDataStream ts(&f);
+		ts.device()->seek(512);
+		qint16 pgX, pgY, pgW, pgH, dummy;
+		ts >> dummy >> pgX >> pgY >> pgW >> pgH;
+		h = pgW - pgX;
+		b = pgH - pgY;
+		x = pgY;
+		y = pgX;
+		f.close();
+//		qDebug() << "W" << b << "H" << h;
+	}
+}
+
+bool XarPlug::convert(QString fn)
+{
+	QString tmp;
+	CurrColorFill = "White";
+	CurrFillShade = 100.0;
+	CurrColorStroke = "Black";
+	CurrStrokeShade = 100.0;
+	patternMode = false;
+	patternData.resize(0);
+	backColor = Qt::white;
+	foreColor = Qt::black;
+	Coords.resize(0);
+	Coords.svgInit();
+	LineW = 1.0;
+	currentPoint = QPoint(0, 0);
+	currentPointT = QPoint(0, 0);
+	ovalSize = QPoint(0, 0);
+	fontMap.clear();
+	currentTextSize = 12;
+	currentFontID = 0;
+	currentFontStyle = 0;
+	imageData.resize(0);
+	lineMode = false;
+	skipOpcode = false;
+	postscriptMode = false;
+	textIsPostScript = false;
+	importedColors.clear();
+	QList<PageItem*> gElements;
+	groupStack.push(gElements);
+	if(progressDialog)
+	{
+		progressDialog->setOverallProgress(2);
+		progressDialog->setLabel("GI", tr("Generating Items"));
+		qApp->processEvents();
+	}
+	QFile f(fn);
+	if (f.open(QIODevice::ReadOnly))
+	{
+		oldDocItemCount = m_Doc->Items->count();
+		int fSize = (int) f.size();
+		if (progressDialog)
+		{
+			progressDialog->setTotalSteps("GI", fSize);
+			qApp->processEvents();
+		}
+		QDataStream ts(&f);
+		ts.setByteOrder(QDataStream::LittleEndian);
+		parseXar(ts);
+		if (Elements.count() == 0)
+		{
+			if (importedColors.count() != 0)
+			{
+				for (int cd = 0; cd < importedColors.count(); cd++)
+				{
+					m_Doc->PageColors.remove(importedColors[cd]);
+				}
+			}
+		}
+		f.close();
+	}
+	if (progressDialog)
+		progressDialog->close();
+	return true;
+}
+
+void XarPlug::parseXar(QDataStream &ts)
+{
+	XarStyle *gc = new XarStyle;
+	m_gc.push( gc );
+	quint32 id;
+	ts >> id;
+	if (id != 0x41524158)
+		return;
+	ts >> id;
+	if (id != 0x0A0DA3A3)
+		return;
+	recordCounter = 0;
+	while (!ts.atEnd())
+	{
+		quint32 opCode, dataLen;
+		ts >> opCode;
+		ts >> dataLen;
+		recordCounter++;
+		if (opCode == 30)
+		{
+			ts.skipRawData(dataLen);
+			quint64 pos = ts.device()->pos();
+			QtIOCompressor compressor(ts.device(), 6, 1);
+			compressor.setStreamFormat(QtIOCompressor::RawZipFormat);
+			compressor.open(QIODevice::ReadOnly);
+			QDataStream tsc(&compressor);
+			tsc.setByteOrder(QDataStream::LittleEndian);
+			tsc.device()->seek(pos);
+			while (!tsc.atEnd())
+			{
+				tsc >> opCode;
+				tsc >> dataLen;
+				recordCounter++;
+				if (opCode == 31)
+				{
+					tsc.skipRawData(dataLen);
+					break;
+				}
+				handleTags(opCode, dataLen, tsc);
+			}
+			ts.skipRawData(dataLen+1);
+		}
+		else
+			handleTags(opCode, dataLen, ts);
+		if (progressDialog)
+		{
+			progressDialog->setProgress("GI", ts.device()->pos());
+			qApp->processEvents();
+		}
+	}
+}
+
+void XarPlug::handleTags(quint32 tag, quint32 dataLen, QDataStream &ts)
+{
+	qDebug() << QString("OpCode: %1 at %2 Data Len %3").arg(tag).arg(ts.device()->pos()-8, 8, 16, QLatin1Char('0')).arg(dataLen, 8, 16, QLatin1Char('0'));
+	if (tag == 0)
+		delete( m_gc.pop() );
+	else if (tag == 1)
+		addGraphicContext();
+	else if (tag == 10)
+		addToAtomic(dataLen, ts);
+	else if (tag == 50)
+		handleColorRGB(ts);
+	else if (tag == 51)
+		handleComplexColor(ts);
+	else if ((tag == 61) || (tag == 62) || (tag == 63))
+	{
+		QImage image;
+		QByteArray data;
+		data.resize(dataLen);
+		ts.readRawData(data.data(), dataLen);
+		image.loadFromData(data);
+		int z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, baseX, baseY, image.width(), image.height(), 0, m_Doc->itemToolPrefs.imageFillColor, CommonStrings::None, true);
+		PageItem *ite = m_Doc->Items->at(z);
+		ite->tempImageFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_xar_XXXXXX.png");
+		ite->tempImageFile->open();
+		QString fileName = getLongPathName(ite->tempImageFile->fileName());
+		ite->tempImageFile->close();
+		ite->isInlineImage = true;
+		image.save(fileName, "PNG");
+		ite->moveBy(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
+		m_Doc->LoadPict(fileName, z);
+		ite->setImageScalingMode(false, false);
+		ite->ClipEdited = true;
+		ite->FrameType = 3;
+		ite->setFillShade(CurrFillShade);
+		ite->setLineShade(CurrStrokeShade);
+		FPoint wh = getMaxClipF(&ite->PoLine);
+		ite->setWidthHeight(wh.x(),wh.y());
+		ite->setTextFlowMode(PageItem::TextFlowDisabled);
+		m_Doc->AdjustItemSize(ite);
+		ite->OldB2 = ite->width();
+		ite->OldH2 = ite->height();
+		ite->updateClip();
+		Elements.append(ite);
+	}
+	else
+		ts.skipRawData(dataLen);
+}
+
+void XarPlug::handleComplexColor(QDataStream &ts)
+{
+	QString tmpName = CommonStrings::None;
+	ScColor tmp;
+	ColorList::Iterator it;
+	quint8 Rc, Gc, Bc, colorModel, colorType;
+	quint16 charC = 0;
+	quint32 EntryIndex, component1, component2, component3, component4;
+	qint32 colorRef;
+	int hR, hG, hB;
+	ts >> Rc >> Gc >> Bc >> colorModel >> colorType;
+	ts >> EntryIndex;
+	ts >> colorRef;
+	ts >> component1 >> component2 >> component3 >> component4;
+	ts >> charC;
+	QString XarName = "";
+	while (charC != 0)
+	{
+		XarName += QChar(charC);
+		ts >> charC;
+	}
+/*	QString colM = "";
+	switch (colorModel)
+	{
+		case 2:
+			colM = "RGB";
+			break;
+		case 3:
+			colM = "CMYK";
+			break;
+		case 4:
+			colM = "HSV";
+			break;
+		case 5:
+			colM = "Gray";
+			break;
+	}
+	QString colT = "";
+	switch (colorType)
+	{
+		case 0:
+			colT = "Normal";
+			break;
+		case 1:
+			colT = "Spot";
+			break;
+		case 2:
+			colT = "Tint";
+			break;
+		case 3:
+			colT = "Linked";
+			break;
+		case 4:
+			colT = "Shade";
+			break;
+	} */
+	double c1 = decodeColorComponent(component1);
+	double c2 = decodeColorComponent(component2);
+	double c3 = decodeColorComponent(component3);
+	double c4 = decodeColorComponent(component4);
+//	qDebug() << "Record" << recordCounter << "Complex Color" << XarName << colM << colT << colorRef;
+//	qDebug() << "\t\tComponents" << c1 << c2 << c3 << c4;
+	XarColor color;
+	color.colorType = colorType;
+	color.colorModel = colorModel;
+	color.colorRef = colorRef;
+	color.component1 = c1;
+	color.component2 = c2;
+	color.component3 = c3;
+	color.component1 = c4;
+	XarColorMap.insert(recordCounter, color);
+	bool found = false;
+	QColor c = QColor(Rc, Gc, Bc);
+	if ((colorType == 0) || (colorType == 1))
+	{
+		if (colorModel == 3)
+		{
+			int Cc = qRound(c1 * 255);
+			int Mc = qRound(c2 * 255);
+			int Yc = qRound(c3 * 255);
+			int Kc = qRound(c4 * 255);
+			int hC, hM, hY, hK;
+			tmp.setColor(Cc, Mc, Yc, Kc);
+			for (it = m_Doc->PageColors.begin(); it != m_Doc->PageColors.end(); ++it)
+			{
+				if (it.value().getColorModel() == colorModelCMYK)
+				{
+					it.value().getCMYK(&hC, &hM, &hY, &hK);
+					if ((Cc == hC) && (Mc == hM) && (Yc == hY) && (Kc == hK))
+					{
+						tmpName = it.key();
+						found = true;
+						break;
+					}
+				}
+			}
+			if (!found)
+			{
+				if (colorType == 1)
+					tmp.setSpotColor(true);
+				else
+					tmp.setSpotColor(false);
+				tmp.setRegistrationColor(false);
+				if (XarName.isEmpty())
+					tmpName = "FromXara"+c.name();
+				else
+					tmpName = XarName;
+				m_Doc->PageColors.insert(tmpName, tmp);
+				importedColors.append(tmpName);
+			}
+		}
+		else
+		{
+			for (it = m_Doc->PageColors.begin(); it != m_Doc->PageColors.end(); ++it)
+			{
+				if (it.value().getColorModel() == colorModelRGB)
+				{
+					it.value().getRGB(&hR, &hG, &hB);
+					if ((Rc == hR) && (Gc == hG) && (Bc == hB))
+					{
+						tmpName = it.key();
+						found = true;
+						break;
+					}
+				}
+			}
+			if (!found)
+			{
+				tmp.setColorRGB(Rc, Gc, Bc);
+				tmp.setSpotColor(false);
+				tmp.setRegistrationColor(false);
+				if (XarName.isEmpty())
+					tmpName = "FromXara"+c.name();
+				else
+					tmpName = XarName;
+				m_Doc->PageColors.insert(tmpName, tmp);
+				importedColors.append(tmpName);
+			}
+		}
+	}
+	else
+	{
+		for (it = m_Doc->PageColors.begin(); it != m_Doc->PageColors.end(); ++it)
+		{
+			if (it.value().getColorModel() == colorModelRGB)
+			{
+				it.value().getRGB(&hR, &hG, &hB);
+				if ((Rc == hR) && (Gc == hG) && (Bc == hB))
+				{
+					tmpName = it.key();
+					found = true;
+					break;
+				}
+			}
+		}
+		if (!found)
+		{
+			tmp.setColorRGB(Rc, Gc, Bc);
+			tmp.setSpotColor(false);
+			tmp.setRegistrationColor(false);
+			if (XarName.isEmpty())
+				tmpName = "FromXara"+c.name();
+			else
+				tmpName = XarName;
+			m_Doc->PageColors.insert(tmpName, tmp);
+			importedColors.append(tmpName);
+		}
+	}
+}
+
+void XarPlug::handleColorRGB(QDataStream &ts)
+{
+	QString tmpName = CommonStrings::None;
+	ScColor tmp;
+	ColorList::Iterator it;
+	quint8 Rc, Gc, Bc;
+	int hR, hG, hB;
+	ts >> Rc >> Gc >> Bc;
+	bool found = false;
+	QColor c = QColor(Rc, Gc, Bc);
+	for (it = m_Doc->PageColors.begin(); it != m_Doc->PageColors.end(); ++it)
+	{
+		if (it.value().getColorModel() == colorModelRGB)
+		{
+			it.value().getRGB(&hR, &hG, &hB);
+			if ((Rc == hR) && (Gc == hG) && (Bc == hB))
+			{
+				tmpName = it.key();
+				found = true;
+				break;
+			}
+		}
+	}
+	if (!found)
+	{
+		tmp.setColorRGB(Rc, Gc, Bc);
+		tmp.setSpotColor(false);
+		tmp.setRegistrationColor(false);
+		tmpName = "FromXara"+c.name();
+		m_Doc->PageColors.insert(tmpName, tmp);
+		importedColors.append(tmpName);
+	}
+}
+
+double XarPlug::decodeColorComponent(quint32 data)
+{
+	double ret = 0.0;
+	char man = (data & 0xFF000000) >> 24;
+	if (man >= 0)
+	{
+		ret = (data & 0x00FFFFFF) / 16777215.0;
+		ret = (ret + man);
+	}
+	else
+	{
+		ret = (~data & 0x00FFFFFF) / 16777215.0;
+		ret = (ret + ~man) * -1;
+	}
+	return ret;
+}
+
+void XarPlug::addToAtomic(quint32 dataLen, QDataStream &ts)
+{
+	quint32 l = dataLen / 4;
+	quint32 val;
+	for (quint32 a = 0; a < l; a++)
+	{
+		ts >> val;
+		atomicTags.append(val);
+	}
+}
+
+void XarPlug::addGraphicContext()
+{
+	XarStyle *gc = new XarStyle;
+	if ( m_gc.top() )
+		*gc = *( m_gc.top() );
+	m_gc.push( gc );
+}
Index: scribus/plugins/xarimplugin/importxarplugin.h
===================================================================
--- scribus/plugins/xarimplugin/importxarplugin.h	(revision 0)
+++ scribus/plugins/xarimplugin/importxarplugin.h	(revision 14261)
@@ -0,0 +1,57 @@
+/*
+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 IMPORTXARLUGIN_H
+#define IMPORTXARPLUGIN_H
+
+#include "pluginapi.h"
+#include "loadsaveplugin.h"
+#include "../formatidlist.h"
+
+class ScrAction;
+
+class PLUGIN_API ImportXarPlugin : public LoadSavePlugin
+{
+	Q_OBJECT
+
+	public:
+		// Standard plugin implementation
+		ImportXarPlugin();
+		virtual ~ImportXarPlugin();
+		/*!
+		\author Franz Schmid
+		\date
+		\brief Returns name of plugin
+		\retval QString containing name of plugin: Import EPS/PDF/PS...
+		*/
+		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 *) {};
+
+	public slots:
+		/*!
+		\author Franz Schmid
+		\date
+		\brief Run the EPS import
+		\param fileName input filename, or QString::null to prompt.
+		\retval bool always true
+		 */
+		virtual bool import(QString fileName = QString::null, int flags = lfUseCurrentPage|lfInteractive);
+
+	private:
+		void registerFormats();
+		ScrAction* importAction;
+};
+
+extern "C" PLUGIN_API int importxar_getPluginAPIVersion();
+extern "C" PLUGIN_API ScPlugin* importxar_getPlugin();
+extern "C" PLUGIN_API void importxar_freePlugin(ScPlugin* plugin);
+
+#endif
Index: scribus/plugins/xarimplugin/qtiocompressor.cpp
===================================================================
--- scribus/plugins/xarimplugin/qtiocompressor.cpp	(revision 0)
+++ scribus/plugins/xarimplugin/qtiocompressor.cpp	(revision 14261)
@@ -0,0 +1,624 @@
+/****************************************************************************
+**
+** This file is part of a Qt Solutions component.
+** 
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** 
+** Contact:  Qt Software Information (qt-info at nokia.com)
+** 
+** Commercial Usage  
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Solutions Commercial License Agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and Nokia.
+** 
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** 
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+** 
+** GNU General Public License Usage 
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+** 
+** Please note Third Party Software included with Qt Solutions may impose
+** additional restrictions and it is the user's responsibility to ensure
+** that they have met the licensing requirements of the GPL, LGPL, or Qt
+** Solutions Commercial license and the relevant license of the Third
+** Party Software they are using.
+** 
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales at nokia.com.
+** 
+****************************************************************************/
+
+#include "qtiocompressor.h"
+#include <zlib.h>
+#include <QtCore/QDebug>
+
+typedef Bytef ZlibByte;
+typedef uInt ZlibSize;
+
+class QtIOCompressorPrivate {
+    QtIOCompressor *q_ptr;
+    Q_DECLARE_PUBLIC(QtIOCompressor)
+public:
+    enum State {
+        // Read state
+        NotReadFirstByte,
+        InStream,
+        EndOfStream,
+        // Write state
+        NoBytesWritten,
+        BytesWritten,
+        // Common
+        Closed,
+        Error
+    };
+
+    QtIOCompressorPrivate(QtIOCompressor *q_ptr, QIODevice *device, int compressionLevel, int bufferSize);
+    ~QtIOCompressorPrivate();
+    void flushZlib(int flushMode);
+    bool writeBytes(ZlibByte *buffer, ZlibSize outputSize);
+    void setZlibError(const QString &erroMessage, int zlibErrorCode);
+
+    QIODevice *device;
+    bool manageDevice;
+    z_stream zlibStream;
+    const int compressionLevel;
+    const ZlibSize bufferSize;
+    ZlibByte *buffer;
+    State state;
+    QtIOCompressor::StreamFormat streamFormat;
+};
+
+/*!
+    \internal
+*/
+QtIOCompressorPrivate::QtIOCompressorPrivate(QtIOCompressor *q_ptr, QIODevice *device, int compressionLevel, int bufferSize)
+:q_ptr(q_ptr)
+,device(device)
+,compressionLevel(compressionLevel)
+,bufferSize(bufferSize)
+,buffer(new ZlibByte[bufferSize])
+,state(Closed)
+,streamFormat(QtIOCompressor::ZlibFormat)
+{
+    // Use default zlib memory management.
+    zlibStream.zalloc = Z_NULL;
+    zlibStream.zfree = Z_NULL;
+    zlibStream.opaque = Z_NULL;
+}
+
+/*!
+    \internal
+*/
+QtIOCompressorPrivate::~QtIOCompressorPrivate()
+{
+    delete[] buffer;
+}
+
+/*!
+    \internal
+    Flushes the zlib stream.
+*/
+void QtIOCompressorPrivate::flushZlib(int flushMode)
+{
+    // No input.
+    zlibStream.next_in = 0;
+    zlibStream.avail_in = 0;
+    int status;
+    do {
+        zlibStream.next_out = buffer;
+        zlibStream.avail_out = bufferSize;
+        status = deflate(&zlibStream, flushMode);
+        if (status != Z_OK && status != Z_STREAM_END) {
+            state = QtIOCompressorPrivate::Error;
+            setZlibError(QT_TRANSLATE_NOOP("QtIOCompressor", "Internal zlib error when compressing: "), status);
+            return;
+        }
+
+        ZlibSize outputSize = bufferSize - zlibStream.avail_out;
+
+        // Try to write data from the buffer to to the underlying device, return on failure.
+        if (!writeBytes(buffer, outputSize))
+            return;
+
+    // If the mode is Z_FNISH we must loop until we get Z_STREAM_END,
+    // else we loop as long as zlib is able to fill the output buffer.
+    } while ((flushMode == Z_FINISH && status != Z_STREAM_END) || (flushMode != Z_FINISH && zlibStream.avail_out == 0));
+
+    if (flushMode == Z_FINISH)
+        Q_ASSERT(status == Z_STREAM_END);
+    else
+        Q_ASSERT(status == Z_OK);
+}
+
+/*!
+    \internal
+    Writes outputSize bytes from buffer to the inderlying device.
+*/
+bool QtIOCompressorPrivate::writeBytes(ZlibByte *buffer, ZlibSize outputSize)
+{
+    Q_Q(QtIOCompressor);
+    ZlibSize totalBytesWritten = 0;
+    // Loop until all bytes are written to the underlying device.
+    do {
+        const qint64 bytesWritten = device->write(reinterpret_cast<char *>(buffer), outputSize);
+        if (bytesWritten == -1) {
+            q->setErrorString(QT_TRANSLATE_NOOP("QtIOCompressor", "Error writing to underlying device: ") + device->errorString());
+            return false;
+        }
+        totalBytesWritten += bytesWritten;
+    } while (totalBytesWritten != outputSize);
+
+    // put up a flag so that the device will be flushed on close.
+    state = BytesWritten;
+    return true;
+}
+
+/*!
+    \internal
+    Sets the error string to errorMessage + zlib error string for zlibErrorCode
+*/
+void QtIOCompressorPrivate::setZlibError(const QString &errorMessage, int zlibErrorCode)
+{
+    Q_Q(QtIOCompressor);
+    // Watch out, zlibErrorString may be null.
+    const char * const zlibErrorString = zError(zlibErrorCode);
+    QString errorString;
+    if (zlibErrorString)
+        errorString = errorMessage + zlibErrorString;
+    else
+        errorString = errorMessage  + " Unknown error, code " + QString::number(zlibErrorCode);
+
+    q->setErrorString(errorString);
+}
+
+/*! \class QtIOCompressor
+    \brief The QtIOCompressor class is a QIODevice that compresses data streams.
+
+    A QtIOCompressor object is constructed with a pointer to an
+    underlying QIODevice.  Data written to the QtIOCompressor object
+    will be compressed before it is written to the underlying
+    QIODevice. Similary, if you read from the QtIOCompressor object,
+    the data will be read from the underlying device and then
+    decompressed.
+
+    QtIOCompressor is a sequential device, which means that it does
+    not support seeks or random access. Internally, QtIOCompressor
+    uses the zlib library to compress and uncompress data.
+
+    Usage examples:
+    Writing compressed data to a file:
+    \code
+        QFile file("foo");
+        QtIOCompressor compressor(&file);
+        compressor.open(QIODevice::WriteOnly);
+        compressor.write(QByteArray() << "The quick brown fox");
+        compressor.close();
+    \endcode
+
+    Reading compressed data from a file:
+    \code
+        QFile file("foo");
+        QtIOCompressor compressor(&file);
+        compressor.open(QIODevice::ReadOnly);
+        const QByteArray text = compressor.readAll();
+        compressor.close();
+    \endcode
+
+    QtIOCompressor can also read and write compressed data in
+    different compressed formats, ref. StreamFormat. Use
+    setStreamFormat() before open() to select format.
+*/
+
+/*!
+    \enum QtIOCompressor::StreamFormat
+    This enum specifies which stream format to use.
+
+    \value ZlibFormat: This is the default and has the smallest overhead.
+
+    \value GzipFormat: This format is compatible with the gzip file
+    format, but has more overhead than ZlibFormat. Note: requires zlib
+    version 1.2.x or higher at runtime.
+
+    \value RawZipFormat: This is compatible with the most common
+    compression method of the data blocks contained in ZIP
+    archives. Note: ZIP file headers are not read or generated, so
+    setting this format, by itself, does not let QtIOCompressor read
+    or write ZIP files. Ref. the ziplist example program.
+
+    \sa setStreamFormat()
+*/
+
+/*!
+    Constructs a QtIOCompressor using the given \a device as the underlying device.
+
+    The allowed value range for \a compressionLevel is 0 to 9, where 0 means no compression
+    and 9 means maximum compression. The default value is 6.
+
+    \a bufferSize specifies the size of the internal buffer used when reading from and writing to the
+    underlying device. The default value is 65KB. Using a larger value allows for faster compression and
+    deompression at the expense of memory usage.
+*/
+QtIOCompressor::QtIOCompressor(QIODevice *device, int compressionLevel, int bufferSize)
+:d_ptr(new QtIOCompressorPrivate(this, device, compressionLevel, bufferSize))
+{}
+
+/*!
+    Destroys the QtIOCompressor, closing it if neccesary.
+*/
+QtIOCompressor::~QtIOCompressor()
+{
+    Q_D(QtIOCompressor);
+    close();
+    delete d;
+}
+
+/*!
+    Sets the format on the compressed stream to \a format.
+
+    \sa QtIOCompressor::StreamFormat
+*/
+void QtIOCompressor::setStreamFormat(StreamFormat format)
+{
+    Q_D(QtIOCompressor);
+
+    // Print a waning if the compile-time version of zlib does not support gzip.
+    if (format == GzipFormat && checkGzipSupport(ZLIB_VERSION) == false)
+        qWarning("QtIOCompressor::setStreamFormat: zlib 1.2.x or higher is "
+                 "required to use the gzip format. Current version is: %s",
+                 ZLIB_VERSION);
+
+    d->streamFormat = format;
+}
+
+/*!
+    Returns the format set on the compressed stream.
+    \sa QtIOCompressor::StreamFormat
+*/
+QtIOCompressor::StreamFormat QtIOCompressor::streamFormat() const
+{
+    Q_D(const QtIOCompressor);
+    return d->streamFormat;
+}
+
+/*!
+    Returns true if the zlib library in use supports the gzip format, false otherwise.
+*/
+bool QtIOCompressor::isGzipSupported()
+{
+    return checkGzipSupport(zlibVersion());
+}
+
+/*!
+    \reimp
+*/
+bool QtIOCompressor::isSequential() const
+{
+    return true;
+}
+
+/*!
+    Opens the QtIOCompressor in \a mode. Only ReadOnly and WriteOnly is supported.
+    This functon will return false if you try to open in other modes.
+
+    If the underlying device is not opened, this function will open it in a suitable mode. If this happens
+    the device will also be closed when close() is called.
+
+    If the underlying device is already opened, its openmode must be compatable with \a mode.
+
+    Returns true on success, false on error.
+
+    \sa close()
+*/
+bool QtIOCompressor::open(OpenMode mode)
+{
+    Q_D(QtIOCompressor);
+    if (isOpen()) {
+        qWarning("QtIOCompressor::open: device already open");
+        return false;
+    }
+
+    // Check for correct mode: ReadOnly xor WriteOnly
+    const bool read = (bool)(mode & ReadOnly);
+    const bool write = (bool)(mode & WriteOnly);
+    const bool both = (read && write);
+    const bool neither = !(read || write);
+    if (both || neither) {
+        qWarning("QtIOCompressor::open: QtIOCompressor can only be opened in the ReadOnly or WriteOnly modes");
+        return false;
+    }
+
+    // If the underlying device is open, check that is it opened in a compatible mode.
+    if (d->device->isOpen()) {
+        d->manageDevice = false;
+        const OpenMode deviceMode = d->device->openMode();
+        if (read && !(deviceMode & ReadOnly)) {
+            qWarning("QtIOCompressor::open: underlying device must be open in one of the ReadOnly or WriteOnly modes");
+            return false;
+        } else if (write && !(deviceMode & WriteOnly)) {
+            qWarning("QtIOCompressor::open: underlying device must be open in one of the ReadOnly or WriteOnly modes");
+            return false;
+        }
+
+    // If the underlying device is closed, open it.
+    } else {
+        d->manageDevice = true;
+        if (d->device->open(mode) == false) {
+            setErrorString(QT_TRANSLATE_NOOP("QtIOCompressor", "Error opening underlying device: ") + d->device->errorString());
+            return false;
+        }
+    }
+
+    // Initialize zlib for deflating or inflating.
+
+    // The second argument to inflate/deflateInit2 is the windowBits parameter,
+    // which also controls what kind of compression stream headers to use.
+    // The default value for this is 15. Passing a value greater than 15
+    // enables gzip headers and then subtracts 16 form the windowBits value.
+    // (So passing 31 gives gzip headers and 15 windowBits). Passing a negative
+    // value selects no headers hand then negates the windowBits argument.
+    int windowBits;
+    switch (d->streamFormat) {
+    case QtIOCompressor::GzipFormat:
+        windowBits = 31;
+        break;
+    case QtIOCompressor::RawZipFormat:
+        windowBits = -15;
+        break;
+    default:
+        windowBits = 15;
+    }
+
+    int status;
+    if (read) {
+        d->state = QtIOCompressorPrivate::NotReadFirstByte;
+        d->zlibStream.avail_in = 0;
+        d->zlibStream.next_in = 0;
+        if (d->streamFormat == QtIOCompressor::ZlibFormat) {
+            status = inflateInit(&d->zlibStream);
+        } else {
+            if (checkGzipSupport(zlibVersion()) == false) {
+                setErrorString(QT_TRANSLATE_NOOP("QtIOCompressor::open", "The gzip format not supported in this version of zlib."));
+                return false;
+            }
+
+            status = inflateInit2(&d->zlibStream, windowBits);
+        }
+    } else {
+        d->state = QtIOCompressorPrivate::NoBytesWritten;
+        if (d->streamFormat == QtIOCompressor::ZlibFormat)
+            status = deflateInit(&d->zlibStream, d->compressionLevel);
+        else
+            status = deflateInit2(&d->zlibStream, d->compressionLevel, Z_DEFLATED, windowBits, 8, Z_DEFAULT_STRATEGY);
+    }
+
+    // Handle error.
+    if (status != Z_OK) {
+        d->setZlibError(QT_TRANSLATE_NOOP("QtIOCompressor::open", "Internal zlib error: "), status);
+        return false;
+    }
+    return QIODevice::open(mode);
+}
+
+/*!
+     Closes the QtIOCompressor, and also the underlying device if it was opened by QtIOCompressor.
+    \sa open()
+*/
+void QtIOCompressor::close()
+{
+    Q_D(QtIOCompressor);
+    if (isOpen() == false)
+        return;
+
+    // Flush and close the zlib stream.
+    if (openMode() & ReadOnly) {
+        d->state = QtIOCompressorPrivate::NotReadFirstByte;
+        inflateEnd(&d->zlibStream);
+    } else {
+        if (d->state == QtIOCompressorPrivate::BytesWritten) { // Only flush if we have written anything.
+            d->state = QtIOCompressorPrivate::NoBytesWritten;
+            d->flushZlib(Z_FINISH);
+        }
+        deflateEnd(&d->zlibStream);
+    }
+
+    // Close the underlying device if we are managing it.
+    if (d->manageDevice)
+        d->device->close();
+
+    QIODevice::close();
+}
+
+/*!
+    Flushes the internal buffer.
+
+    Each time you call flush, all data written to the QtIOCompressor is compressed and written to the
+    underlying device. Calling this function can reduce the compression ratio. The underlying device
+    is not flushed.
+
+    Calling this function when QtIOCompressor is in ReadOnly mode has no effect.
+*/
+void QtIOCompressor::flush()
+{
+    Q_D(QtIOCompressor);
+    if (isOpen() == false || openMode() & ReadOnly)
+        return;
+
+    d->flushZlib(Z_SYNC_FLUSH);
+}
+
+/*!
+    Returns 1 if there might be data available for reading, or 0 if there is no data available.
+
+    There is unfortunately no way of knowing how much data there is available when dealing with compressed streams.
+
+    Also, since the remaining compressed data might be a part of the meta-data that ends the compressed stream (and
+    therefore will yield no uncompressed data), you cannot assume that a read after getting a 1 from this function will return data.
+*/
+qint64 QtIOCompressor::bytesAvailable() const
+{
+    Q_D(const QtIOCompressor);
+    if ((openMode() & ReadOnly) == false)
+        return 0;
+
+    int numBytes = 0;
+
+    switch (d->state) {
+        case QtIOCompressorPrivate::NotReadFirstByte:
+            numBytes = d->device->bytesAvailable();
+        break;
+        case QtIOCompressorPrivate::InStream:
+            numBytes = 1;
+        break;
+        case QtIOCompressorPrivate::EndOfStream:
+        case QtIOCompressorPrivate::Error:
+        default:
+            numBytes = 0;
+        break;
+    };
+
+    numBytes += QIODevice::bytesAvailable();
+
+    if (numBytes > 0)
+        return 1;
+    else
+        return 0;
+}
+
+/*!
+    \internal
+    Reads and decompresses data from the underlying device.
+*/
+qint64 QtIOCompressor::readData(char *data, qint64 maxSize)
+{
+    Q_D(QtIOCompressor);
+
+    if (d->state == QtIOCompressorPrivate::EndOfStream)
+        return 0;
+
+    if (d->state == QtIOCompressorPrivate::Error)
+        return -1;
+
+    // We are ging to try to fill the data buffer
+    d->zlibStream.next_out = reinterpret_cast<ZlibByte *>(data);
+    d->zlibStream.avail_out = maxSize;
+
+    int status;
+    do {
+        // Read data if if the input buffer is empty. There could be data in the buffer
+        // from a previous readData call.
+        if (d->zlibStream.avail_in == 0) {
+            qint64 bytesAvalible = d->device->read(reinterpret_cast<char *>(d->buffer), d->bufferSize);
+            d->zlibStream.next_in = d->buffer;
+            d->zlibStream.avail_in = bytesAvalible;
+
+            if (bytesAvalible == -1) {
+                d->state = QtIOCompressorPrivate::Error;
+                setErrorString(QT_TRANSLATE_NOOP("QtIOCompressor", "Error reading data from underlying device: ") + d->device->errorString());
+                return -1;
+            }
+
+            if (d->state != QtIOCompressorPrivate::InStream) {
+                // If we are not in a stream and get 0 bytes, we are probably trying to read from an empty device.
+                if(bytesAvalible == 0)
+                    return 0;
+                else if (bytesAvalible > 0)
+                    d->state = QtIOCompressorPrivate::InStream;
+            }
+        }
+
+        // Decompress.
+        status = inflate(&d->zlibStream, Z_SYNC_FLUSH);
+        switch (status) {
+            case Z_NEED_DICT:
+            case Z_DATA_ERROR:
+            case Z_MEM_ERROR:
+                d->state = QtIOCompressorPrivate::Error;
+                d->setZlibError(QT_TRANSLATE_NOOP("QtIOCompressor", "Internal zlib error when decompressing: "), status);
+                return -1;
+            case Z_BUF_ERROR: // No more input and zlib can not privide more output - Not an error, we can try to read again when we have more input.
+                return 0;
+            break;
+        }
+    // Loop util data buffer is full or we reach the end of the input stream.
+    } while (d->zlibStream.avail_out != 0 && status != Z_STREAM_END);
+
+    if (status == Z_STREAM_END) {
+        d->state = QtIOCompressorPrivate::EndOfStream;
+
+        // Unget any data left in the read buffer.
+        for (int i = d->zlibStream.avail_in;  i >= 0; --i)
+            d->device->ungetChar(*reinterpret_cast<char *>(d->zlibStream.next_in + i));
+    }
+
+    const ZlibSize outputSize = maxSize - d->zlibStream.avail_out;
+    return outputSize;
+}
+
+
+/*!
+    \internal
+    Compresses and writes data to the underlying device.
+*/
+qint64 QtIOCompressor::writeData(const char *data, qint64 maxSize)
+{
+    if (maxSize < 1)
+        return 0;
+    Q_D(QtIOCompressor);
+    d->zlibStream.next_in = reinterpret_cast<ZlibByte *>(const_cast<char *>(data));
+    d->zlibStream.avail_in = maxSize;
+
+    if (d->state == QtIOCompressorPrivate::Error)
+        return -1;
+
+    do {
+        d->zlibStream.next_out = d->buffer;
+        d->zlibStream.avail_out = d->bufferSize;
+        const int status = deflate(&d->zlibStream, Z_NO_FLUSH);
+        if (status != Z_OK) {
+            d->state = QtIOCompressorPrivate::Error;
+            d->setZlibError(QT_TRANSLATE_NOOP("QtIOCompressor", "Internal zlib error when compressing: "), status);
+            return -1;
+        }
+
+        ZlibSize outputSize = d->bufferSize - d->zlibStream.avail_out;
+
+        // Try to write data from the buffer to to the underlying device, return -1 on failure.
+        if (d->writeBytes(d->buffer, outputSize) == false)
+            return -1;
+
+    } while (d->zlibStream.avail_out == 0); // run until output is not full.
+    Q_ASSERT(d->zlibStream.avail_in == 0);
+
+    return maxSize;
+}
+
+/*
+    \internal
+    Checks if the run-time zlib version is 1.2.x or higher.
+*/
+bool QtIOCompressor::checkGzipSupport(const char * const versionString)
+{
+    if (strlen(versionString) < 3)
+        return false;
+
+    if (versionString[0] == '0' || (versionString[0] == '1' && (versionString[2] == '0' || versionString[2]  == '1' )))
+        return false;
+
+    return true;
+}
Index: scribus/plugins/xarimplugin/importxar.h
===================================================================
--- scribus/plugins/xarimplugin/importxar.h	(revision 0)
+++ scribus/plugins/xarimplugin/importxar.h	(revision 14261)
@@ -0,0 +1,199 @@
+/*
+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 IMPORTXAR_H
+#define IMPORTXAR_H
+
+
+#include "pluginapi.h"
+#include "pageitem.h"
+#include "sccolor.h"
+#include "fpointarray.h"
+#include <QList>
+#include <QTransform>
+#include <QMultiMap>
+#include <QtGlobal>
+#include <QObject>
+#include <QString>
+#include <QRect>
+#include <QStack>
+
+class MultiProgressDialog;
+class ScribusDoc;
+class Selection;
+class TransactionSettings;
+
+class XarStyle
+{
+public:
+	XarStyle() :
+		dashOffset(0),
+		FontFamily(""),
+		FontStyle("normal"),
+		FontWeight("normal"),
+		FontStretch("normal"),
+		FontSize(12),
+		FillCol("Black"),
+		fillRule("nonzero"),
+		FillGradient(VGradient::linear),
+		StrokeGradient(VGradient::linear),
+		FillGradientType(0),
+		StrokeGradientType(0),
+		GradFillX1(0),
+		GradFillX2(0),
+		GradFillY1(0),
+		GradFillY2(0),
+		GradStrokeX1(0),
+		GradStrokeX2(0),
+		GradStrokeY1(0),
+		GradStrokeY2(0),
+		LWidth(1.0),
+		PLineArt(Qt::SolidLine),
+		PLineEnd(Qt::FlatCap),
+		PLineJoin(Qt::MiterJoin),
+		StrokeCol("None"),
+		FillOpacity(1.0),
+		StrokeOpacity(1.0),
+		clipPath()
+		{
+		}
+	QVector<double> dashArray;
+	double dashOffset;
+	QString FontFamily;
+	QString FontStyle;
+	QString FontWeight;
+	QString FontStretch;
+	int FontSize;
+	QString FillCol;
+	QString fillRule;
+	VGradient FillGradient;
+	VGradient StrokeGradient;
+	int    FillGradientType;
+	int    StrokeGradientType;
+	double GradFillX1;
+	double GradFillX2;
+	double GradFillY1;
+	double GradFillY2;
+	double GradStrokeX1;
+	double GradStrokeX2;
+	double GradStrokeY1;
+	double GradStrokeY2;
+	double LWidth;
+	Qt::PenStyle PLineArt;
+	Qt::PenCapStyle PLineEnd;
+	Qt::PenJoinStyle PLineJoin;
+	QString StrokeCol;
+	double FillOpacity;
+	double StrokeOpacity;
+	FPointArray clipPath;
+};
+
+//! \brief Xar (Xara) importer plugin
+class XarPlug : public QObject
+{
+	Q_OBJECT
+
+public:
+	/*!
+	\author Franz Schmid
+	\date
+	\brief Create the Xar importer window.
+	\param fName QString
+	\param flags combination of loadFlags
+	\param showProgress if progress must be displayed
+	\retval EPSPlug plugin
+	*/
+	XarPlug( ScribusDoc* doc, int flags );
+	~XarPlug();
+
+	/*!
+	\author Franz Schmid
+	\date
+	\brief Perform import.
+	\param fn QString
+	\param trSettings undo transaction settings
+	\param flags combination of loadFlags
+	\param showProgress if progress must be displayed
+	\retval bool true if import was ok
+	 */
+	bool import(QString fn, const TransactionSettings& trSettings, int flags, bool showProgress = true);
+
+private:
+	void parseHeader(QString fName, double &x, double &y, double &b, double &h);
+	bool convert(QString fn);
+	void parseXar(QDataStream &ts);
+	void handleTags(quint32 tag, quint32 dataLen, QDataStream &ts);
+	void handleComplexColor(QDataStream &ts);
+	void handleColorRGB(QDataStream &ts);
+	double decodeColorComponent(quint32 data);
+	void addToAtomic(quint32 dataLen, QDataStream &ts);
+	void addGraphicContext();
+	
+	struct XarColor
+	{
+		quint32 colorType;
+		quint32 colorModel;
+		quint32 colorRef;
+		double component1;
+		double component2;
+		double component3;
+		double component4;
+	};
+	QMap<quint32, XarColor> XarColorMap;
+	QList<PageItem*> Elements;
+	int recordCounter;
+	QList<quint32> atomicTags;
+	QStack<QList<PageItem*> > groupStack;
+	QStack<XarStyle*>	m_gc;
+	double baseX, baseY;
+	double docWidth;
+	double docHeight;
+
+	double LineW;
+	QString CurrColorFill;
+	QColor backColor;
+	QString CurrColorStroke;
+	QColor foreColor;
+	double CurrStrokeShade;
+	double CurrFillShade;
+	bool patternMode;
+	QByteArray patternData;
+	QMap<QString, QString> patternMap;
+	QRect currRect;
+	int currRectItemNr;
+	int currRectType;
+	QRect lastImageRect;
+	QStringList importedColors;
+	QPoint ovalSize;
+	QMap<int, QString> fontMap;
+	int currentTextSize;
+	int currentFontID;
+	int currentFontStyle;
+	FPointArray lastCoords;
+	QByteArray imageData;
+
+	FPointArray Coords;
+	QPoint currentPoint;
+	QPoint currentPointT;
+	bool lineMode;
+	bool postscriptMode;
+	bool textIsPostScript;
+	bool interactive;
+	MultiProgressDialog * progressDialog;
+	bool cancel;
+	ScribusDoc* m_Doc;
+	Selection* tmpSel;
+	int importerFlags;
+	int oldDocItemCount;
+	QString baseFile;
+	int pctVersion;
+	bool skipOpcode;
+
+public slots:
+	void cancelRequested() { cancel = true; }
+};
+
+#endif
Index: scribus/plugins/xarimplugin/CMakeLists.txt
===================================================================
--- scribus/plugins/xarimplugin/CMakeLists.txt	(revision 0)
+++ scribus/plugins/xarimplugin/CMakeLists.txt	(revision 14261)
@@ -0,0 +1,32 @@
+INCLUDE_DIRECTORIES(
+${CMAKE_SOURCE_DIR}
+${CMAKE_SOURCE_DIR}/scribus
+)
+
+SET(IMPORTXAR_PLUGIN_MOC_CLASSES
+  qtiocompressor.h
+  importxar.h
+  importxarplugin.h
+)
+
+SET(IMPORTXAR_PLUGIN_SOURCES
+  qtiocompressor.cpp
+  importxar.cpp
+  importxarplugin.cpp
+)
+
+SET(SCRIBUS_IMPORTXAR_PLUGIN "importxar")
+
+QT4_WRAP_CPP(IMPORTXAR_PLUGIN_MOC_SOURCES ${IMPORTXAR_PLUGIN_MOC_CLASSES})
+
+ADD_LIBRARY(${SCRIBUS_IMPORTXAR_PLUGIN} MODULE ${IMPORTXAR_PLUGIN_SOURCES} ${IMPORTXAR_PLUGIN_MOC_SOURCES})
+
+TARGET_LINK_LIBRARIES(${SCRIBUS_IMPORTXAR_PLUGIN} ${PLUGIN_LIBRARIES})
+
+INSTALL(TARGETS ${SCRIBUS_IMPORTXAR_PLUGIN}
+  LIBRARY
+  DESTINATION ${PLUGINDIR}
+  PERMISSIONS ${PLUGIN_PERMISSIONS}
+)
+
+ADD_DEPENDENCIES(${SCRIBUS_IMPORTXAR_PLUGIN} ${EXE_NAME})
Index: scribus/plugins/CMakeLists.txt
===================================================================
--- scribus/plugins/CMakeLists.txt	(revision 14260)
+++ scribus/plugins/CMakeLists.txt	(revision 14261)
@@ -20,6 +20,7 @@
 ADD_SUBDIRECTORY(cvgimplugin)
 ADD_SUBDIRECTORY(wpgimplugin)
 ADD_SUBDIRECTORY(pctimplugin)
+ADD_SUBDIRECTORY(xarimplugin)
 ADD_SUBDIRECTORY(tools)
 ADD_SUBDIRECTORY(picbrowser)
 




More information about the scribus-commit mailing list