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 "importpm.h"
21 #include "../revenge/rawpainter.h"
22 #include <libpagemaker/libpagemaker.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
PmPlug(ScribusDoc * doc,int flags)54 PmPlug::PmPlug(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 PmPlug::readThumbnail(const QString& fName)
68 {
69 QFileInfo fi = QFileInfo(fName);
70 docWidth = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
71 docHeight = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
72 progressDialog = nullptr;
73 m_Doc = new ScribusDoc();
74 m_Doc->setup(0, 1, 1, 1, 1, "Custom", "Custom");
75 m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
76 m_Doc->addPage(0);
77 m_Doc->setGUI(false, ScCore->primaryMainWindow(), nullptr);
78 baseX = m_Doc->currentPage()->xOffset();
79 baseY = m_Doc->currentPage()->yOffset();
80 Elements.clear();
81 m_Doc->setLoading(true);
82 m_Doc->DoDrawing = false;
83 m_Doc->scMW()->setScriptRunning(true);
84 QString CurDirP = QDir::currentPath();
85 QDir::setCurrent(fi.path());
86 if (convert(fName))
87 {
88 tmpSel->clear();
89 QDir::setCurrent(CurDirP);
90 if (Elements.count() > 1)
91 m_Doc->groupObjectsList(Elements);
92 m_Doc->DoDrawing = true;
93 m_Doc->m_Selection->delaySignalsOn();
94 QImage tmpImage;
95 if (Elements.count() > 0)
96 {
97 for (int dre=0; dre<Elements.count(); ++dre)
98 {
99 tmpSel->addItem(Elements.at(dre), true);
100 }
101 tmpSel->setGroupRect();
102 double xs = tmpSel->width();
103 double ys = tmpSel->height();
104 tmpImage = Elements.at(0)->DrawObj_toImage(500);
105 tmpImage.setText("XSize", QString("%1").arg(xs));
106 tmpImage.setText("YSize", QString("%1").arg(ys));
107 }
108 m_Doc->scMW()->setScriptRunning(false);
109 m_Doc->setLoading(false);
110 m_Doc->m_Selection->delaySignalsOff();
111 delete m_Doc;
112 return tmpImage;
113 }
114 QDir::setCurrent(CurDirP);
115 m_Doc->DoDrawing = true;
116 m_Doc->scMW()->setScriptRunning(false);
117 delete m_Doc;
118 return QImage();
119 }
120
import(const QString & fNameIn,const TransactionSettings & trSettings,int flags,bool showProgress)121 bool PmPlug::import(const QString& fNameIn, const TransactionSettings& trSettings, int flags, bool showProgress)
122 {
123 bool success = false;
124 interactive = (flags & LoadSavePlugin::lfInteractive);
125 importerFlags = flags;
126 cancel = false;
127 bool ret = false;
128 QFileInfo fi = QFileInfo(fNameIn);
129 if ( !ScCore->usingGUI() )
130 {
131 interactive = false;
132 showProgress = false;
133 }
134 if ( showProgress )
135 {
136 ScribusMainWindow* mw=(m_Doc==nullptr) ? ScCore->primaryMainWindow() : m_Doc->scMW();
137 progressDialog = new MultiProgressDialog( tr("Importing: %1").arg(fi.fileName()), CommonStrings::tr_Cancel, mw );
138 QStringList barNames, barTexts;
139 barNames << "GI";
140 barTexts << tr("Analyzing File:");
141 QList<bool> barsNumeric;
142 barsNumeric << false;
143 progressDialog->addExtraProgressBars(barNames, barTexts, barsNumeric);
144 progressDialog->setOverallTotalSteps(3);
145 progressDialog->setOverallProgress(0);
146 progressDialog->setProgress("GI", 0);
147 progressDialog->show();
148 connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelRequested()));
149 qApp->processEvents();
150 }
151 else
152 progressDialog = nullptr;
153 /* Set default Page to size defined in Preferences */
154 double w = 0.0;
155 double h = 0.0;
156 if (progressDialog)
157 {
158 progressDialog->setOverallProgress(1);
159 qApp->processEvents();
160 }
161 if (w == 0.0)
162 w = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
163 if (h == 0.0)
164 h = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
165 docWidth = w;
166 docHeight = h;
167 baseX = 0;
168 baseY = 0;
169 if (!interactive || (flags & LoadSavePlugin::lfInsertPage))
170 {
171 m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
172 m_Doc->addPage(0);
173 m_Doc->view()->addPage(0, true);
174 baseX = 0;
175 baseY = 0;
176 }
177 else
178 {
179 if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc))
180 {
181 m_Doc=ScCore->primaryMainWindow()->doFileNew(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom", true);
182 ScCore->primaryMainWindow()->HaveNewDoc();
183 ret = true;
184 baseX = 0;
185 baseY = 0;
186 baseX = m_Doc->currentPage()->xOffset();
187 baseY = m_Doc->currentPage()->yOffset();
188 }
189 }
190 if ((!ret) && (interactive))
191 {
192 baseX = m_Doc->currentPage()->xOffset();
193 baseY = m_Doc->currentPage()->yOffset();
194 }
195 if ((ret) || (!interactive))
196 {
197 if (docWidth > docHeight)
198 m_Doc->setPageOrientation(1);
199 else
200 m_Doc->setPageOrientation(0);
201 m_Doc->setPageSize("Custom");
202 }
203 if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr))
204 m_Doc->view()->deselectItems();
205 Elements.clear();
206 m_Doc->setLoading(true);
207 m_Doc->DoDrawing = false;
208 if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr))
209 m_Doc->view()->updatesOn(false);
210 m_Doc->scMW()->setScriptRunning(true);
211 qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
212 QString CurDirP = QDir::currentPath();
213 QDir::setCurrent(fi.path());
214 if (convert(fNameIn))
215 {
216 tmpSel->clear();
217 QDir::setCurrent(CurDirP);
218 if ((Elements.count() > 1) && (!(importerFlags & LoadSavePlugin::lfCreateDoc)))
219 m_Doc->groupObjectsList(Elements);
220 m_Doc->DoDrawing = true;
221 m_Doc->scMW()->setScriptRunning(false);
222 m_Doc->setLoading(false);
223 qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
224 if ((Elements.count() > 0) && (!ret) && (interactive))
225 {
226 if (flags & LoadSavePlugin::lfScripted)
227 {
228 bool loadF = m_Doc->isLoading();
229 m_Doc->setLoading(false);
230 m_Doc->changed();
231 m_Doc->setLoading(loadF);
232 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
233 {
234 m_Doc->m_Selection->delaySignalsOn();
235 for (int dre=0; dre<Elements.count(); ++dre)
236 {
237 m_Doc->m_Selection->addItem(Elements.at(dre), true);
238 }
239 m_Doc->m_Selection->delaySignalsOff();
240 m_Doc->m_Selection->setGroupRect();
241 if (m_Doc->view() != nullptr)
242 m_Doc->view()->updatesOn(true);
243 }
244 }
245 else
246 {
247 m_Doc->DragP = true;
248 m_Doc->DraggedElem = nullptr;
249 m_Doc->DragElements.clear();
250 m_Doc->m_Selection->delaySignalsOn();
251 for (int i=0; i<Elements.count(); ++i)
252 {
253 tmpSel->addItem(Elements.at(i), true);
254 }
255 tmpSel->setGroupRect();
256 ScElemMimeData* md = ScriXmlDoc::writeToMimeData(m_Doc, tmpSel);
257 m_Doc->itemSelection_DeleteItem(tmpSel);
258 m_Doc->view()->updatesOn(true);
259 if (importedPatterns.count() != 0)
260 {
261 for (int i = 0; i < importedPatterns.count(); i++)
262 {
263 m_Doc->docPatterns.remove(importedPatterns[i]);
264 }
265 }
266 if (importedColors.count() != 0)
267 {
268 for (int i = 0; i < importedColors.count(); i++)
269 {
270 m_Doc->PageColors.remove(importedColors[i]);
271 }
272 }
273 m_Doc->m_Selection->delaySignalsOff();
274 // We must copy the TransationSettings object as it is owned
275 // by handleObjectImport method afterwards
276 TransactionSettings* transacSettings = new TransactionSettings(trSettings);
277 m_Doc->view()->handleObjectImport(md, transacSettings);
278 m_Doc->DragP = false;
279 m_Doc->DraggedElem = nullptr;
280 m_Doc->DragElements.clear();
281 }
282 }
283 else
284 {
285 m_Doc->changed();
286 m_Doc->reformPages();
287 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
288 m_Doc->view()->updatesOn(true);
289 }
290 success = true;
291 }
292 else
293 {
294 QDir::setCurrent(CurDirP);
295 m_Doc->DoDrawing = true;
296 m_Doc->scMW()->setScriptRunning(false);
297 m_Doc->view()->updatesOn(true);
298 qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
299 }
300 if (interactive)
301 m_Doc->setLoading(false);
302 //CB If we have a gui we must refresh it if we have used the progressbar
303 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
304 {
305 if ((showProgress) && (!interactive))
306 m_Doc->view()->DrawNew();
307 }
308 qApp->restoreOverrideCursor();
309 return success;
310 }
311
~PmPlug()312 PmPlug::~PmPlug()
313 {
314 delete progressDialog;
315 delete tmpSel;
316 }
317
convert(const QString & fn)318 bool PmPlug::convert(const QString& fn)
319 {
320 importedColors.clear();
321 importedPatterns.clear();
322
323 QFile file(fn);
324 if (!file.exists())
325 {
326 qDebug() << "File " << QFile::encodeName(fn).data() << " does not exist";
327 return false;
328 }
329
330 librevenge::RVNGFileStream input(QFile::encodeName(fn).data());
331 if (!libpagemaker::PMDocument::isSupported(&input))
332 {
333 qDebug() << "ERROR: Unsupported file format!";
334 return false;
335 }
336 RawPainter painter(m_Doc, baseX, baseY, docWidth, docHeight, importerFlags, &Elements, &importedColors, &importedPatterns, tmpSel, "pmd");
337 if (!libpagemaker::PMDocument::parse(&input, &painter))
338 {
339 qDebug() << "ERROR: Import failed!";
340 if (progressDialog)
341 progressDialog->close();
342 if (importerFlags & LoadSavePlugin::lfCreateDoc)
343 {
344 ScribusMainWindow* mw=(m_Doc==nullptr) ? ScCore->primaryMainWindow() : m_Doc->scMW();
345 qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
346 ScMessageBox::warning(mw, CommonStrings::trWarning, tr("Parsing failed!\n\nPlease submit your file (if possible) to the\nDocument Liberation Project http://www.documentliberation.org"));
347 qApp->changeOverrideCursor(QCursor(Qt::WaitCursor));
348 }
349 return false;
350 }
351 if (Elements.count() == 0)
352 {
353 if (importedColors.count() != 0)
354 {
355 for (int i = 0; i < importedColors.count(); i++)
356 {
357 m_Doc->PageColors.remove(importedColors[i]);
358 }
359 }
360 if (importedPatterns.count() != 0)
361 {
362 for (int i = 0; i < importedPatterns.count(); i++)
363 {
364 m_Doc->docPatterns.remove(importedPatterns[i]);
365 }
366 }
367 }
368 if (progressDialog)
369 progressDialog->close();
370 return true;
371 }
372