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