Rev 25137 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
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 <QStack>
#include <QDebug>
#include <cstdlib>
#include "importcvg.h"
#include "commonstrings.h"
#include "loadsaveplugin.h"
#include "prefsmanager.h"
#include "scconfig.h"
#include "scmimedata.h"
#include "scribusXml.h"
#include "scribuscore.h"
#include "scribusdoc.h"
#include "scribusview.h"
#include "selection.h"
#include "ui/multiprogressdialog.h"
#include "undomanager.h"
#include "util_math.h"
CvgPlug::CvgPlug(ScribusDoc* doc, int flags)
{
tmpSel=new Selection(this, false);
m_Doc=doc;
importerFlags = flags;
interactive = (flags & LoadSavePlugin::lfInteractive);
progressDialog = nullptr;
}
QImage CvgPlug::readThumbnail(const QString& fName)
{
QFileInfo fi = QFileInfo(fName);
baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/"));
double b, h;
parseHeader(fName, 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;
progressDialog = nullptr;
m_Doc = new ScribusDoc();
m_Doc->setup(0, 1, 1, 1, 1, "Custom", "Custom");
m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
m_Doc->addPage(0);
m_Doc->setGUI(false, ScCore->primaryMainWindow(), nullptr);
baseX = m_Doc->currentPage()->xOffset();
baseY = m_Doc->currentPage()->yOffset();
Elements.clear();
m_Doc->setLoading(true);
m_Doc->DoDrawing = false;
m_Doc->scMW()->setScriptRunning(true);
QString CurDirP = QDir::currentPath();
QDir::setCurrent(fi.path());
if (convert(fName))
{
tmpSel->clear();
QDir::setCurrent(CurDirP);
if (Elements.count() > 1)
m_Doc->groupObjectsList(Elements);
m_Doc->DoDrawing = true;
m_Doc->m_Selection->delaySignalsOn();
QImage tmpImage;
if (Elements.count() > 0)
{
for (int dre=0; dre<Elements.count(); ++dre)
{
tmpSel->addItem(Elements.at(dre), true);
}
tmpSel->setGroupRect();
double xs = tmpSel->width();
double ys = tmpSel->height();
tmpImage = Elements.at(0)->DrawObj_toImage(500);
tmpImage.setText("XSize", QString("%1").arg(xs));
tmpImage.setText("YSize", QString("%1").arg(ys));
}
m_Doc->scMW()->setScriptRunning(false);
m_Doc->setLoading(false);
m_Doc->m_Selection->delaySignalsOff();
delete m_Doc;
return tmpImage;
}
QDir::setCurrent(CurDirP);
m_Doc->DoDrawing = true;
m_Doc->scMW()->setScriptRunning(false);
delete m_Doc;
return QImage();
}
bool CvgPlug::import(const QString& fNameIn, const TransactionSettings& trSettings, int flags, bool showProgress)
{
bool success = false;
interactive = (flags & LoadSavePlugin::lfInteractive);
importerFlags = flags;
cancel = false;
double b, h;
bool ret = false;
CustColors.clear();
QFileInfo fi = QFileInfo(fNameIn);
if ( !ScCore->usingGUI() )
{
interactive = false;
showProgress = false;
}
baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/"));
if ( showProgress )
{
ScribusMainWindow* mw=(m_Doc==nullptr) ? 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 = nullptr;
/* Set default Page to size defined in Preferences */
b = 0.0;
h = 0.0;
if (progressDialog)
{
progressDialog->setOverallProgress(1);
qApp->processEvents();
}
parseHeader(fNameIn, 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 = 0;
baseY = 0;
}
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 = 0;
baseY = 0;
baseX = m_Doc->currentPage()->xOffset();
baseY = m_Doc->currentPage()->yOffset();
}
}
if ((!ret) && (interactive))
{
baseX = m_Doc->currentPage()->xOffset();
baseY = m_Doc->currentPage()->yOffset();
}
if ((ret) || (!interactive))
{
if (docWidth > docHeight)
m_Doc->setPageOrientation(1);
else
m_Doc->setPageOrientation(0);
m_Doc->setPageSize("Custom");
}
if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr))
m_Doc->view()->deselectItems();
Elements.clear();
m_Doc->setLoading(true);
m_Doc->DoDrawing = false;
if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr))
m_Doc->view()->updatesOn(false);
m_Doc->scMW()->setScriptRunning(true);
qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
QString CurDirP = QDir::currentPath();
QDir::setCurrent(fi.path());
if (convert(fNameIn))
{
tmpSel->clear();
QDir::setCurrent(CurDirP);
if ((Elements.count() > 1) && (!(importerFlags & LoadSavePlugin::lfCreateDoc)))
m_Doc->groupObjectsList(Elements);
m_Doc->DoDrawing = true;
m_Doc->scMW()->setScriptRunning(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);
if (!(flags & LoadSavePlugin::lfLoadAsPattern))
{
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();
if (m_Doc->view() != nullptr)
m_Doc->view()->updatesOn(true);
}
}
else
{
m_Doc->DragP = true;
m_Doc->DraggedElem = nullptr;
m_Doc->DragElements.clear();
m_Doc->m_Selection->delaySignalsOn();
for (int dre=0; dre<Elements.count(); ++dre)
{
tmpSel->addItem(Elements.at(dre), true);
}
tmpSel->setGroupRect();
ScElemMimeData* md = ScriXmlDoc::writeToMimeData(m_Doc, tmpSel);
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 = nullptr;
m_Doc->DragElements.clear();
}
}
else
{
m_Doc->changed();
m_Doc->reformPages();
if (!(flags & LoadSavePlugin::lfLoadAsPattern))
m_Doc->view()->updatesOn(true);
}
success = true;
}
else
{
QDir::setCurrent(CurDirP);
m_Doc->DoDrawing = true;
m_Doc->scMW()->setScriptRunning(false);
if (!(flags & LoadSavePlugin::lfLoadAsPattern))
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 (!(flags & LoadSavePlugin::lfLoadAsPattern))
{
if ((showProgress) && (!interactive))
m_Doc->view()->DrawNew();
}
qApp->restoreOverrideCursor();
return success;
}
CvgPlug::~CvgPlug()
{
delete progressDialog;
delete tmpSel;
}
void CvgPlug::parseHeader(const QString& fName, double &b, double &h)
{
QFile f(fName);
if (f.open(QIODevice::ReadOnly))
{
QDataStream ts(&f);
ts.device()->seek(16);
quint16 pgY, pgW, pgH;
ts >> pgY >> pgW >> pgH;
b = pgW / 72.0;
h = pgH / 72.0;
scPg = h / b;
b = pgY / 72.0;
h = pgY / 72.0 * scPg;
f.close();
}
}
bool CvgPlug::convert(const QString& fn)
{
CurrColorFill = "Black";
CurrFillShade = 100.0;
CurrColorStroke = "Black";
CurrStrokeShade = 100.0;
Coords.resize(0);
Coords.svgInit();
importedColors.clear();
QList<PageItem*> gElements;
groupStack.push(gElements);
currentItemNr = 0;
if (progressDialog)
{
progressDialog->setOverallProgress(2);
progressDialog->setLabel("GI", tr("Generating Items"));
qApp->processEvents();
}
QFile f(fn);
if (f.open(QIODevice::ReadOnly))
{
int fSize = (int) f.size();
if (progressDialog)
{
progressDialog->setTotalSteps("GI", fSize);
qApp->processEvents();
}
QDataStream ts(&f);
ts.device()->seek(10);
quint16 pgX, pgY, pgW, pgH, colorF, dummy;
bool colorFlag = false;
ts >> colorF >> dummy;
if (colorF == 0x044c)
colorFlag = true;
ts >> pgX >> pgY >> pgW >> pgH;
quint32 currentFilePos = 14;
while (!ts.atEnd())
{
quint16 data;
quint32 lenData;
ts >> data;
ts >> lenData;
currentFilePos = ts.device()->pos();
if (data == 0x0020)
qDebug() << "Group" << "Len" << lenData;
if (data == 0x0004)
{
getObjects(ts, colorFlag, lenData - 26);
}
ts.device()->seek(currentFilePos + lenData - 6);
if (progressDialog)
{
progressDialog->setProgress("GI", ts.device()->pos());
qApp->processEvents();
}
}
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 CvgPlug::getObjects(QDataStream &ts, bool color, quint32 lenData)
{
quint16 obX, obY, obW, obH, fillFlag, lineWidth;
quint32 counter = 0;
quint32 colorFill, colorLine;
int z;
PageItem *ite;
Coords.resize(0);
Coords.svgInit();
ts >> obX >> obY >> obW >> obH;
ts >> colorFill >> colorLine;
ts >> fillFlag >> lineWidth;
fillFlag = fillFlag & 0x0FFF;
qreal scX = obW / 16384.0;
qreal scY = obH / 16384.0;
parseColor(colorFill, colorLine, color, fillFlag);
while (counter < lenData)
{
quint16 opCode, x1, y1, cx1, cy1, cx2, cy2;
ts >> opCode;
counter += 2;
if (opCode == 0x0000) // moveTo
{
ts >> x1 >> y1;
counter += 4;
Coords.svgMoveTo(x1 / 72.0 * scX, y1 / 72.0 * scY * scPg);
}
else if (opCode == 0x0001) // lineTo
{
ts >> x1 >> y1;
counter += 4;
Coords.svgLineTo(x1 / 72.0 * scX, y1 / 72.0 * scY * scPg);
}
else if (opCode == 0x0002) // curveTo
{
ts >> cx1 >> cy1 >> cx2 >> cy2 >> x1 >> y1;
counter += 12;
Coords.svgCurveToCubic(cx1 / 72.0 * scX, cy1 / 72.0 * scY * scPg, cx2 / 72.0 * scX, cy2 / 72.0 * scY * scPg, x1 / 72.0 * scX, y1 / 72.0 * scY * scPg);
}
else if (opCode == 0x000f)
break;
}
if (Coords.empty())
return;
Coords.svgClosePath();
z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX + obX / 72.0, baseY + obY / 72.0 * scPg, 10, 10, lineWidth / 72.0, CurrColorFill, CurrColorStroke);
ite = m_Doc->Items->at(z);
ite->PoLine = Coords.copy();
ite->PoLine.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
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);
if (groupStack.count() != 0)
groupStack.top().append(ite);
}
void CvgPlug::parseColor(quint32 dataF, quint32 dataS, bool color, quint16 flag)
{
ScColor tmp;
CurrColorFill = CommonStrings::None;
CurrFillShade = 100.0;
CurrColorStroke = CommonStrings::None;
CurrStrokeShade = 100.0;
QColor c;
if (color)
{
if ((flag == 0x0080) || (flag == 0x0200))
{
c.setRgb(dataF);
tmp.fromQColor(c);
tmp.setSpotColor(false);
tmp.setRegistrationColor(false);
QString newColorName = "FromCVG"+c.name();
QString fNam = m_Doc->PageColors.tryAddColor(newColorName, tmp);
if (fNam == newColorName)
importedColors.append(fNam);
CurrColorFill = fNam;
}
if ((flag == 0x0080) || (flag == 0x0100))
{
c.setRgb(dataS);
tmp.fromQColor(c);
tmp.setSpotColor(false);
tmp.setRegistrationColor(false);
QString newColorName = "FromCVG"+c.name();
QString fNam = m_Doc->PageColors.tryAddColor(newColorName, tmp);
if (fNam == newColorName)
importedColors.append(fNam);
CurrColorStroke = fNam;
}
}
else
{
if (flag == 0x0080)
{
CurrColorFill = "Black";
CurrFillShade = dataF & 0x000000FF;
CurrColorStroke = "Black";
CurrStrokeShade = dataS & 0x000000FF;
}
else if (flag == 0x0100)
{
CurrColorFill = CommonStrings::None;
CurrFillShade = dataF & 0x000000FF;
CurrColorStroke = "Black";
CurrStrokeShade = dataS & 0x000000FF;
}
else
{
CurrColorFill = "Black";
CurrFillShade = dataF & 0x000000FF;
CurrColorStroke = CommonStrings::None;
CurrStrokeShade = dataS & 0x000000FF;
}
}
}