1 /*
2 For general Scribus (>=1.3.2) copyright and licensing information please refer
3 to the COPYING file provided with the program. Following this notice may exist
4 a copyright and/or license notice that predates the release of Scribus 1.3.2
5 for which a new license (GPL+exception) is in place.
6 */
7
8 #include <QByteArray>
9 #include <QCursor>
10 #include <QDrag>
11 #include <QFile>
12 #include <QList>
13 #include <QMessageBox>
14 #include <QMimeData>
15 #include <QRegExp>
16 #include <QStack>
17 #include <QDebug>
18
19 #include <cstdlib>
20 #include "importcdr.h"
21 #include "../revenge/rawpainter.h"
22 #include <libcdr/libcdr.h>
23
24 #include "commonstrings.h"
25 #include "ui/customfdialog.h"
26 #include "fileloader.h"
27 #include "loadsaveplugin.h"
28 #include "ui/missing.h"
29 #include "ui/multiprogressdialog.h"
30 #include "pagesize.h"
31 #include "prefscontext.h"
32 #include "prefsfile.h"
33 #include "prefsmanager.h"
34 #include "prefstable.h"
35 #include "ui/propertiespalette.h"
36 #include "rawimage.h"
37 #include "scclocale.h"
38 #include "sccolorengine.h"
39 #include "scconfig.h"
40 #include "scmimedata.h"
41 #include "scpaths.h"
42 #include "scpattern.h"
43 #include "scribus.h"
44 #include "scribusXml.h"
45 #include "scribuscore.h"
46 #include "scribusview.h"
47 #include "sctextstream.h"
48 #include "selection.h"
49 #include "undomanager.h"
50 #include "util.h"
51 #include "util_formats.h"
52 #include "util_math.h"
53
CdrPlug(ScribusDoc * doc,int flags)54 CdrPlug::CdrPlug(ScribusDoc* doc, int flags)
55 {
56 baseX = baseY = 0;
57 docWidth = docHeight = 1;
58
59 tmpSel = new Selection(this, false);
60 m_Doc = doc;
61 importerFlags = flags;
62 interactive = (flags & LoadSavePlugin::lfInteractive);
63 progressDialog = nullptr;
64 cancel = false;
65 }
66
readThumbnail(const QString & fName)67 QImage CdrPlug::readThumbnail(const QString& fName)
68 {
69 QFileInfo fi = QFileInfo(fName);
70 double b, h;
71 b = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
72 h = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
73 docWidth = b;
74 docHeight = h;
75 progressDialog = nullptr;
76 m_Doc = new ScribusDoc();
77 m_Doc->setup(0, 1, 1, 1, 1, "Custom", "Custom");
78 m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
79 m_Doc->addPage(0);
80 m_Doc->setGUI(false, ScCore->primaryMainWindow(), nullptr);
81 baseX = m_Doc->currentPage()->xOffset();
82 baseY = m_Doc->currentPage()->yOffset();
83 Elements.clear();
84 m_Doc->setLoading(true);
85 m_Doc->DoDrawing = false;
86 m_Doc->scMW()->setScriptRunning(true);
87 QString CurDirP = QDir::currentPath();
88 QDir::setCurrent(fi.path());
89 if (convert(fName))
90 {
91 tmpSel->clear();
92 QDir::setCurrent(CurDirP);
93 if (Elements.count() > 1)
94 m_Doc->groupObjectsList(Elements);
95 m_Doc->DoDrawing = true;
96 m_Doc->m_Selection->delaySignalsOn();
97 QImage tmpImage;
98 if (Elements.count() > 0)
99 {
100 for (int dre=0; dre<Elements.count(); ++dre)
101 {
102 tmpSel->addItem(Elements.at(dre), true);
103 }
104 tmpSel->setGroupRect();
105 double xs = tmpSel->width();
106 double ys = tmpSel->height();
107 tmpImage = Elements.at(0)->DrawObj_toImage(500);
108 tmpImage.setText("XSize", QString("%1").arg(xs));
109 tmpImage.setText("YSize", QString("%1").arg(ys));
110 }
111 m_Doc->scMW()->setScriptRunning(false);
112 m_Doc->setLoading(false);
113 m_Doc->m_Selection->delaySignalsOff();
114 delete m_Doc;
115 return tmpImage;
116 }
117 QDir::setCurrent(CurDirP);
118 m_Doc->DoDrawing = true;
119 m_Doc->scMW()->setScriptRunning(false);
120 delete m_Doc;
121 return QImage();
122 }
123
import(const QString & fNameIn,const TransactionSettings & trSettings,int flags,bool showProgress)124 bool CdrPlug::import(const QString& fNameIn, const TransactionSettings& trSettings, int flags, bool showProgress)
125 {
126 bool success = false;
127 interactive = (flags & LoadSavePlugin::lfInteractive);
128 importerFlags = flags;
129 cancel = false;
130 double b, h;
131 bool ret = false;
132 QFileInfo fi = QFileInfo(fNameIn);
133 if ( !ScCore->usingGUI() )
134 {
135 interactive = false;
136 showProgress = false;
137 }
138 if ( showProgress )
139 {
140 ScribusMainWindow* mw=(m_Doc==nullptr) ? ScCore->primaryMainWindow() : m_Doc->scMW();
141 progressDialog = new MultiProgressDialog( tr("Importing: %1").arg(fi.fileName()), CommonStrings::tr_Cancel, mw );
142 QStringList barNames, barTexts;
143 barNames << "GI";
144 barTexts << tr("Analyzing File:");
145 QList<bool> barsNumeric;
146 barsNumeric << false;
147 progressDialog->addExtraProgressBars(barNames, barTexts, barsNumeric);
148 progressDialog->setOverallTotalSteps(3);
149 progressDialog->setOverallProgress(0);
150 progressDialog->setProgress("GI", 0);
151 progressDialog->show();
152 connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelRequested()));
153 qApp->processEvents();
154 }
155 else
156 progressDialog = nullptr;
157 /* Set default Page to size defined in Preferences */
158 b = 0.0;
159 h = 0.0;
160 if (progressDialog)
161 {
162 progressDialog->setOverallProgress(1);
163 qApp->processEvents();
164 }
165 if (b == 0.0)
166 b = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
167 if (h == 0.0)
168 h = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
169 docWidth = b;
170 docHeight = h;
171 baseX = 0;
172 baseY = 0;
173 if (!interactive || (flags & LoadSavePlugin::lfInsertPage))
174 {
175 m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
176 m_Doc->addPage(0);
177 m_Doc->view()->addPage(0, true);
178 baseX = 0;
179 baseY = 0;
180 }
181 else
182 {
183 if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc))
184 {
185 m_Doc=ScCore->primaryMainWindow()->doFileNew(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom", true);
186 ScCore->primaryMainWindow()->HaveNewDoc();
187 ret = true;
188 baseX = 0;
189 baseY = 0;
190 baseX = m_Doc->currentPage()->xOffset();
191 baseY = m_Doc->currentPage()->yOffset();
192 }
193 }
194 if ((!ret) && (interactive))
195 {
196 baseX = m_Doc->currentPage()->xOffset();
197 baseY = m_Doc->currentPage()->yOffset();
198 }
199 if ((ret) || (!interactive))
200 {
201 if (docWidth > docHeight)
202 m_Doc->setPageOrientation(1);
203 else
204 m_Doc->setPageOrientation(0);
205 m_Doc->setPageSize("Custom");
206 }
207 if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr))
208 m_Doc->view()->deselectItems();
209 Elements.clear();
210 m_Doc->setLoading(true);
211 m_Doc->DoDrawing = false;
212 if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr))
213 m_Doc->view()->updatesOn(false);
214 m_Doc->scMW()->setScriptRunning(true);
215 qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
216 QString CurDirP = QDir::currentPath();
217 QDir::setCurrent(fi.path());
218 if (convert(fNameIn))
219 {
220 tmpSel->clear();
221 QDir::setCurrent(CurDirP);
222 if ((Elements.count() > 1) && (!(importerFlags & LoadSavePlugin::lfCreateDoc)))
223 m_Doc->groupObjectsList(Elements);
224 m_Doc->DoDrawing = true;
225 m_Doc->scMW()->setScriptRunning(false);
226 m_Doc->setLoading(false);
227 qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
228 if ((Elements.count() > 0) && (!ret) && (interactive))
229 {
230 if (flags & LoadSavePlugin::lfScripted)
231 {
232 bool loadF = m_Doc->isLoading();
233 m_Doc->setLoading(false);
234 m_Doc->changed();
235 m_Doc->setLoading(loadF);
236 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
237 {
238 m_Doc->m_Selection->delaySignalsOn();
239 for (int dre=0; dre<Elements.count(); ++dre)
240 {
241 m_Doc->m_Selection->addItem(Elements.at(dre), true);
242 }
243 m_Doc->m_Selection->delaySignalsOff();
244 m_Doc->m_Selection->setGroupRect();
245 if (m_Doc->view() != nullptr)
246 m_Doc->view()->updatesOn(true);
247 }
248 }
249 else
250 {
251 m_Doc->DragP = true;
252 m_Doc->DraggedElem = nullptr;
253 m_Doc->DragElements.clear();
254 m_Doc->m_Selection->delaySignalsOn();
255 for (int dre=0; dre<Elements.count(); ++dre)
256 {
257 tmpSel->addItem(Elements.at(dre), true);
258 }
259 tmpSel->setGroupRect();
260 ScElemMimeData* md = ScriXmlDoc::writeToMimeData(m_Doc, tmpSel);
261 m_Doc->itemSelection_DeleteItem(tmpSel);
262 m_Doc->view()->updatesOn(true);
263 if (importedPatterns.count() != 0)
264 {
265 for (int cd = 0; cd < importedPatterns.count(); cd++)
266 {
267 m_Doc->docPatterns.remove(importedPatterns[cd]);
268 }
269 }
270 if (importedColors.count() != 0)
271 {
272 for (int cd = 0; cd < importedColors.count(); cd++)
273 {
274 m_Doc->PageColors.remove(importedColors[cd]);
275 }
276 }
277 m_Doc->m_Selection->delaySignalsOff();
278 // We must copy the TransationSettings object as it is owned
279 // by handleObjectImport method afterwards
280 TransactionSettings* transacSettings = new TransactionSettings(trSettings);
281 m_Doc->view()->handleObjectImport(md, transacSettings);
282 m_Doc->DragP = false;
283 m_Doc->DraggedElem = nullptr;
284 m_Doc->DragElements.clear();
285 }
286 }
287 else
288 {
289 m_Doc->changed();
290 m_Doc->reformPages();
291 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
292 m_Doc->view()->updatesOn(true);
293 }
294 success = true;
295 }
296 else
297 {
298 QDir::setCurrent(CurDirP);
299 m_Doc->DoDrawing = true;
300 m_Doc->scMW()->setScriptRunning(false);
301 m_Doc->view()->updatesOn(true);
302 qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
303 }
304 if (interactive)
305 m_Doc->setLoading(false);
306 //CB If we have a gui we must refresh it if we have used the progressbar
307 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
308 {
309 if ((showProgress) && (!interactive))
310 m_Doc->view()->DrawNew();
311 }
312 qApp->restoreOverrideCursor();
313 return success;
314 }
315
~CdrPlug()316 CdrPlug::~CdrPlug()
317 {
318 delete progressDialog;
319 delete tmpSel;
320 }
321
convert(const QString & fn)322 bool CdrPlug::convert(const QString& fn)
323 {
324 importedColors.clear();
325 importedPatterns.clear();
326
327 QFile file(fn);
328 if (!file.exists())
329 {
330 qDebug() << "File " << QFile::encodeName(fn).data() << " does not exist";
331 return false;
332 }
333 QFileInfo fi = QFileInfo(fn);
334 QString ext = fi.suffix().toLower();
335 #if HAVE_REVENGE
336 librevenge::RVNGFileStream input(QFile::encodeName(fn).data());
337 #else
338 WPXFileStream input(QFile::encodeName(fn).data());
339 #endif
340 bool fail = false;
341 if (ext == "cdr")
342 {
343 if (!libcdr::CDRDocument::isSupported(&input))
344 {
345 qDebug() << "ERROR: Unsupported file format!";
346 fail = true;
347 }
348 if (!fail)
349 {
350 RawPainter painter(m_Doc, baseX, baseY, docWidth, docHeight, importerFlags, &Elements, &importedColors, &importedPatterns, tmpSel, "cdr");
351 if (!libcdr::CDRDocument::parse(&input, &painter))
352 fail = true;
353 }
354 if (fail)
355 {
356 qDebug() << "ERROR: Parsing failed!";
357 if (progressDialog)
358 progressDialog->close();
359 /* if (importerFlags & LoadSavePlugin::lfCreateDoc)
360 {
361 ScribusMainWindow* mw=(m_Doc==0) ? ScCore->primaryMainWindow() : m_Doc->scMW();
362 qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
363 ScMessageBox::warning(mw, CommonStrings::trWarning, tr("Parsing failed!\n\nPlease submit your file (if possible) to the\nDocument Liberation Project http://www.documentliberation.org"));
364 qApp->changeOverrideCursor(QCursor(Qt::WaitCursor));
365 }*/
366 return false;
367 }
368 }
369 else if (ext == "cmx")
370 {
371 if (!libcdr::CMXDocument::isSupported(&input))
372 {
373 qDebug() << "ERROR: Unsupported file format!";
374 return false;
375 }
376 RawPainter painter(m_Doc, baseX, baseY, docWidth, docHeight, importerFlags, &Elements, &importedColors, &importedPatterns, tmpSel, "cmx");
377 if (!libcdr::CMXDocument::parse(&input, &painter))
378 {
379 qDebug() << "ERROR: Parsing failed!";
380 if (progressDialog)
381 progressDialog->close();
382 if (importerFlags & LoadSavePlugin::lfCreateDoc)
383 {
384 ScribusMainWindow* mw=(m_Doc==nullptr) ? ScCore->primaryMainWindow() : m_Doc->scMW();
385 qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
386 ScMessageBox::warning(mw, CommonStrings::trWarning, tr("Parsing failed!\n\nPlease submit your file (if possible) to the\nDocument Liberation Project http://www.documentliberation.org"));
387 qApp->changeOverrideCursor(QCursor(Qt::WaitCursor));
388 }
389 return false;
390 }
391 }
392 else
393 return false;
394 if (Elements.count() == 0)
395 {
396 if (importedColors.count() != 0)
397 {
398 for (int cd = 0; cd < importedColors.count(); cd++)
399 {
400 m_Doc->PageColors.remove(importedColors[cd]);
401 }
402 }
403 if (importedPatterns.count() != 0)
404 {
405 for (int cd = 0; cd < importedPatterns.count(); cd++)
406 {
407 m_Doc->docPatterns.remove(importedPatterns[cd]);
408 }
409 }
410 }
411 if (progressDialog)
412 progressDialog->close();
413 return true;
414 }
415