Rev 17031 | Rev 17261 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
16729 | fschmid | 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 <QMimeData> |
||
14 | #include <QRegExp> |
||
15 | #include <QStack> |
||
16 | #include <QDebug> |
||
17 | #include "slaoutput.h" |
||
18 | #include <GlobalParams.h> |
||
19 | |||
20 | #include "importpdf.h" |
||
21 | |||
22 | #include <cstdlib> |
||
23 | |||
24 | #include "commonstrings.h" |
||
25 | #include "loadsaveplugin.h" |
||
26 | #include "pagesize.h" |
||
27 | #include "prefscontext.h" |
||
28 | #include "prefsfile.h" |
||
29 | #include "prefsmanager.h" |
||
30 | #include "prefstable.h" |
||
31 | #include "rawimage.h" |
||
32 | #include "scclocale.h" |
||
33 | #include "sccolorengine.h" |
||
34 | #include "scconfig.h" |
||
35 | #include "scmimedata.h" |
||
36 | #include "scpaths.h" |
||
37 | #include "scribus.h" |
||
38 | #include "scribusXml.h" |
||
39 | #include "scribuscore.h" |
||
40 | #include "sctextstream.h" |
||
41 | #include "selection.h" |
||
42 | #include "undomanager.h" |
||
43 | #include "util.h" |
||
44 | #include "util_formats.h" |
||
45 | #include "util_ghostscript.h" |
||
46 | #include "util_icon.h" |
||
47 | #include "util_math.h" |
||
48 | |||
17031 | jghali | 49 | #include "ui/customfdialog.h" |
50 | #include "ui/missing.h" |
||
51 | #include "ui/multiprogressdialog.h" |
||
52 | #include "ui/propertiespalette.h" |
||
16729 | fschmid | 53 | |
54 | PdfPlug::PdfPlug(ScribusDoc* doc, int flags) |
||
55 | { |
||
56 | tmpSele = new Selection(this, false); |
||
57 | m_Doc = doc; |
||
58 | importerFlags = flags; |
||
59 | interactive = (flags & LoadSavePlugin::lfInteractive); |
||
16773 | fschmid | 60 | progressDialog = NULL; |
16729 | fschmid | 61 | } |
62 | |||
63 | QImage PdfPlug::readThumbnail(QString fName) |
||
64 | { |
||
65 | QString tmp, cmd1, cmd2; |
||
66 | QString pdfFile = QDir::toNativeSeparators(fName); |
||
67 | QString tmpFile = QDir::toNativeSeparators(ScPaths::getTempFileDir() + "sc.png"); |
||
68 | int ret = -1; |
||
69 | tmp.setNum(1); |
||
70 | QStringList args; |
||
71 | args.append("-r72"); |
||
72 | args.append("-sOutputFile="+tmpFile); |
||
73 | args.append("-dFirstPage="+tmp); |
||
74 | args.append("-dLastPage="+tmp); |
||
75 | args.append(pdfFile); |
||
76 | ret = callGS(args); |
||
77 | if (ret == 0) |
||
78 | { |
||
79 | QImage image; |
||
80 | image.load(tmpFile); |
||
81 | QFile::remove(tmpFile); |
||
82 | image.setText("XSize", QString("%1").arg(image.width())); |
||
83 | image.setText("YSize", QString("%1").arg(image.height())); |
||
84 | return image; |
||
85 | } |
||
86 | return QImage(); |
||
87 | } |
||
88 | |||
89 | bool PdfPlug::import(QString fNameIn, const TransactionSettings& trSettings, int flags, bool showProgress) |
||
90 | { |
||
91 | QString fName = fNameIn; |
||
92 | bool success = false; |
||
93 | interactive = (flags & LoadSavePlugin::lfInteractive); |
||
94 | importerFlags = flags; |
||
95 | cancel = false; |
||
96 | double x, y, b, h; |
||
97 | bool ret = false; |
||
98 | QFileInfo fi = QFileInfo(fName); |
||
99 | if ( !ScCore->usingGUI() ) |
||
100 | { |
||
101 | interactive = false; |
||
102 | showProgress = false; |
||
103 | } |
||
104 | baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/")); |
||
105 | if ( showProgress ) |
||
106 | { |
||
107 | ScribusMainWindow* mw=(m_Doc==0) ? ScCore->primaryMainWindow() : m_Doc->scMW(); |
||
108 | progressDialog = new MultiProgressDialog( tr("Importing: %1").arg(fi.fileName()), CommonStrings::tr_Cancel, mw ); |
||
109 | QStringList barNames, barTexts; |
||
110 | barNames << "GI"; |
||
111 | barTexts << tr("Analyzing File:"); |
||
112 | QList<bool> barsNumeric; |
||
113 | barsNumeric << false; |
||
114 | progressDialog->addExtraProgressBars(barNames, barTexts, barsNumeric); |
||
115 | progressDialog->setOverallTotalSteps(3); |
||
116 | progressDialog->setOverallProgress(0); |
||
117 | progressDialog->setProgress("GI", 0); |
||
118 | progressDialog->show(); |
||
119 | connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelRequested())); |
||
120 | qApp->processEvents(); |
||
121 | } |
||
122 | else |
||
123 | progressDialog = NULL; |
||
124 | /* Set default Page to size defined in Preferences */ |
||
125 | x = 0.0; |
||
126 | y = 0.0; |
||
127 | b = 0.0; |
||
128 | h = 0.0; |
||
129 | if (progressDialog) |
||
130 | { |
||
131 | progressDialog->setOverallProgress(1); |
||
132 | qApp->processEvents(); |
||
133 | } |
||
134 | if (b == 0.0) |
||
135 | b = PrefsManager::instance()->appPrefs.docSetupPrefs.pageWidth; |
||
136 | if (h == 0.0) |
||
137 | h = PrefsManager::instance()->appPrefs.docSetupPrefs.pageHeight; |
||
138 | docWidth = b; |
||
139 | docHeight = h; |
||
140 | baseX = 0; |
||
141 | baseY = 0; |
||
142 | if (!interactive || (flags & LoadSavePlugin::lfInsertPage)) |
||
143 | { |
||
144 | m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false); |
||
145 | m_Doc->addPage(0); |
||
146 | m_Doc->view()->addPage(0, true); |
||
147 | baseX = 0; |
||
148 | baseY = 0; |
||
149 | } |
||
150 | else |
||
151 | { |
||
152 | if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc)) |
||
153 | { |
||
17078 | fschmid | 154 | m_Doc=ScCore->primaryMainWindow()->doFileNew(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, 0, 0, 0, 0, 1, "Custom", true); |
16729 | fschmid | 155 | ScCore->primaryMainWindow()->HaveNewDoc(); |
156 | ret = true; |
||
157 | baseX = 0; |
||
158 | baseY = 0; |
||
159 | baseX = m_Doc->currentPage()->xOffset(); |
||
160 | baseY = m_Doc->currentPage()->yOffset(); |
||
161 | } |
||
162 | } |
||
163 | if ((!ret) && (interactive)) |
||
164 | { |
||
165 | baseX = m_Doc->currentPage()->xOffset(); |
||
166 | baseY = m_Doc->currentPage()->yOffset(); |
||
167 | } |
||
168 | if ((ret) || (!interactive)) |
||
169 | { |
||
170 | if (docWidth > docHeight) |
||
171 | m_Doc->setPageOrientation(1); |
||
172 | else |
||
173 | m_Doc->setPageOrientation(0); |
||
174 | m_Doc->setPageSize("Custom"); |
||
175 | } |
||
176 | Elements.clear(); |
||
177 | m_Doc->setLoading(true); |
||
178 | m_Doc->DoDrawing = false; |
||
179 | if (!(flags & LoadSavePlugin::lfLoadAsPattern)) |
||
180 | m_Doc->view()->updatesOn(false); |
||
181 | m_Doc->scMW()->setScriptRunning(true); |
||
182 | qApp->changeOverrideCursor(QCursor(Qt::WaitCursor)); |
||
183 | QString CurDirP = QDir::currentPath(); |
||
184 | QDir::setCurrent(fi.path()); |
||
185 | if (convert(fName)) |
||
186 | { |
||
187 | tmpSele->clear(); |
||
188 | QDir::setCurrent(CurDirP); |
||
189 | if ((Elements.count() > 1) && (!(importerFlags & LoadSavePlugin::lfCreateDoc))) |
||
190 | m_Doc->groupObjectsList(Elements); |
||
191 | m_Doc->DoDrawing = true; |
||
192 | m_Doc->scMW()->setScriptRunning(false); |
||
193 | m_Doc->setLoading(false); |
||
194 | qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor)); |
||
195 | if ((Elements.count() > 0) && (!ret) && (interactive)) |
||
196 | { |
||
197 | if (flags & LoadSavePlugin::lfScripted) |
||
198 | { |
||
199 | bool loadF = m_Doc->isLoading(); |
||
200 | m_Doc->setLoading(false); |
||
201 | m_Doc->changed(); |
||
202 | m_Doc->setLoading(loadF); |
||
203 | if (!(flags & LoadSavePlugin::lfLoadAsPattern)) |
||
204 | { |
||
205 | m_Doc->m_Selection->delaySignalsOn(); |
||
206 | for (int dre=0; dre<Elements.count(); ++dre) |
||
207 | { |
||
208 | m_Doc->m_Selection->addItem(Elements.at(dre), true); |
||
209 | } |
||
210 | m_Doc->m_Selection->delaySignalsOff(); |
||
211 | m_Doc->m_Selection->setGroupRect(); |
||
212 | m_Doc->view()->updatesOn(true); |
||
213 | } |
||
214 | } |
||
215 | else |
||
216 | { |
||
217 | m_Doc->DragP = true; |
||
218 | m_Doc->DraggedElem = 0; |
||
219 | m_Doc->DragElements.clear(); |
||
220 | m_Doc->m_Selection->delaySignalsOn(); |
||
221 | for (int dre=0; dre<Elements.count(); ++dre) |
||
222 | { |
||
223 | tmpSele->addItem(Elements.at(dre), true); |
||
224 | } |
||
225 | tmpSele->setGroupRect(); |
||
226 | ScriXmlDoc *ss = new ScriXmlDoc(); |
||
227 | ScElemMimeData* md = new ScElemMimeData(); |
||
228 | md->setScribusElem(ss->WriteElem(m_Doc, tmpSele)); |
||
229 | delete ss; |
||
230 | m_Doc->itemSelection_DeleteItem(tmpSele); |
||
231 | m_Doc->view()->updatesOn(true); |
||
232 | m_Doc->m_Selection->delaySignalsOff(); |
||
233 | // We must copy the TransationSettings object as it is owned |
||
234 | // by handleObjectImport method afterwards |
||
235 | TransactionSettings* transacSettings = new TransactionSettings(trSettings); |
||
236 | m_Doc->view()->handleObjectImport(md, transacSettings); |
||
237 | m_Doc->DragP = false; |
||
238 | m_Doc->DraggedElem = 0; |
||
239 | m_Doc->DragElements.clear(); |
||
240 | } |
||
241 | } |
||
242 | else |
||
243 | { |
||
244 | m_Doc->changed(); |
||
245 | m_Doc->reformPages(); |
||
246 | if (!(flags & LoadSavePlugin::lfLoadAsPattern)) |
||
247 | m_Doc->view()->updatesOn(true); |
||
248 | } |
||
249 | success = true; |
||
250 | } |
||
251 | else |
||
252 | { |
||
253 | QDir::setCurrent(CurDirP); |
||
254 | m_Doc->DoDrawing = true; |
||
255 | m_Doc->scMW()->setScriptRunning(false); |
||
256 | if (!(flags & LoadSavePlugin::lfLoadAsPattern)) |
||
257 | m_Doc->view()->updatesOn(true); |
||
258 | qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor)); |
||
259 | } |
||
260 | if (interactive) |
||
261 | m_Doc->setLoading(false); |
||
262 | //CB If we have a gui we must refresh it if we have used the progressbar |
||
263 | if (!(flags & LoadSavePlugin::lfLoadAsPattern)) |
||
264 | { |
||
265 | if ((showProgress) && (!interactive)) |
||
266 | m_Doc->view()->DrawNew(); |
||
267 | } |
||
268 | return success; |
||
269 | } |
||
270 | |||
271 | PdfPlug::~PdfPlug() |
||
272 | { |
||
273 | if (progressDialog) |
||
274 | delete progressDialog; |
||
275 | delete tmpSele; |
||
276 | } |
||
277 | |||
278 | bool PdfPlug::convert(QString fn) |
||
279 | { |
||
280 | QString tmp; |
||
281 | importedColors.clear(); |
||
282 | if(progressDialog) |
||
283 | { |
||
284 | progressDialog->setOverallProgress(2); |
||
285 | progressDialog->setLabel("GI", tr("Generating Items")); |
||
286 | qApp->processEvents(); |
||
287 | } |
||
288 | QFile f(fn); |
||
289 | oldDocItemCount = m_Doc->Items->count(); |
||
290 | if (progressDialog) |
||
291 | { |
||
292 | progressDialog->setBusyIndicator("GI"); |
||
293 | qApp->processEvents(); |
||
294 | } |
||
295 | |||
296 | globalParams = new GlobalParams(); |
||
297 | if (globalParams) |
||
298 | { |
||
299 | GooString *fname = new GooString(QFile::encodeName(fn).data()); |
||
300 | globalParams->setErrQuiet(gTrue); |
||
301 | // globalParams->setPrintCommands(gTrue); |
||
302 | PDFDoc *pdfDoc = new PDFDoc(fname, 0, 0, 0); |
||
303 | if (pdfDoc) |
||
304 | { |
||
305 | if (pdfDoc->isOk()) |
||
306 | { |
||
307 | double hDPI = 72.0; |
||
308 | double vDPI = 72.0; |
||
309 | int firstPage = 1; |
||
310 | int lastPage = pdfDoc->getNumPages(); |
||
311 | // qDebug() << "converting page" << firstPage; |
||
312 | SlaOutputDev *dev = new SlaOutputDev(m_Doc, &Elements, &importedColors, importerFlags); |
||
313 | if (dev->isOk()) |
||
314 | { |
||
315 | GBool useMediaBox = gTrue; |
||
316 | GBool crop = gFalse; |
||
317 | GBool printing = gFalse; |
||
318 | dev->startDoc(pdfDoc->getXRef(), pdfDoc->getCatalog()); |
||
319 | int rotate = pdfDoc->getPageRotate(firstPage); |
||
16773 | fschmid | 320 | /* PDFRectangle *rect = pdfDoc->getPage(firstPage)->getMediaBox(); |
321 | qDebug() << "Media Box" << rect->x1 << rect->y1 << rect->x2 << rect->y2; |
||
322 | rect = pdfDoc->getPage(firstPage)->getCropBox(); |
||
323 | qDebug() << "Crop Box " << rect->x1 << rect->y1 << rect->x2 << rect->y2; |
||
324 | rect = pdfDoc->getPage(firstPage)->getBleedBox(); |
||
325 | qDebug() << "Bleed Box" << rect->x1 << rect->y1 << rect->x2 << rect->y2; |
||
326 | rect = pdfDoc->getPage(firstPage)->getTrimBox(); |
||
327 | qDebug() << "Trim Box " << rect->x1 << rect->y1 << rect->x2 << rect->y2; |
||
328 | rect = pdfDoc->getPage(firstPage)->getArtBox(); |
||
329 | qDebug() << "Art Box " << rect->x1 << rect->y1 << rect->x2 << rect->y2; */ |
||
16729 | fschmid | 330 | if (importerFlags & LoadSavePlugin::lfCreateDoc) |
331 | { |
||
332 | m_Doc->currentPage()->setInitialHeight(pdfDoc->getPageMediaHeight(firstPage)); |
||
333 | m_Doc->currentPage()->setInitialWidth(pdfDoc->getPageMediaWidth(firstPage)); |
||
334 | m_Doc->currentPage()->setHeight(pdfDoc->getPageMediaHeight(firstPage)); |
||
335 | m_Doc->currentPage()->setWidth(pdfDoc->getPageMediaWidth(firstPage)); |
||
17078 | fschmid | 336 | m_Doc->currentPage()->MPageNam = CommonStrings::trMasterPageNormal; |
16729 | fschmid | 337 | m_Doc->reformPages(true); |
338 | Object info; |
||
339 | pdfDoc->getDocInfo(&info); |
||
340 | if (info.isDict()) |
||
341 | { |
||
342 | Object obj; |
||
343 | GooString *s1; |
||
344 | Dict *infoDict = info.getDict(); |
||
16732 | fschmid | 345 | if (infoDict->lookup((char*)"Title", &obj )->isString()) |
16729 | fschmid | 346 | { |
347 | s1 = obj.getString(); |
||
348 | m_Doc->documentInfo().setTitle(UnicodeParsedString(obj.getString())); |
||
349 | obj.free(); |
||
350 | } |
||
16732 | fschmid | 351 | if (infoDict->lookup((char*)"Author", &obj )->isString()) |
16729 | fschmid | 352 | { |
353 | s1 = obj.getString(); |
||
354 | m_Doc->documentInfo().setAuthor(UnicodeParsedString(obj.getString())); |
||
355 | obj.free(); |
||
356 | } |
||
16732 | fschmid | 357 | if (infoDict->lookup((char*)"Subject", &obj )->isString()) |
16729 | fschmid | 358 | { |
359 | s1 = obj.getString(); |
||
360 | m_Doc->documentInfo().setSubject(UnicodeParsedString(obj.getString())); |
||
361 | obj.free(); |
||
362 | } |
||
16732 | fschmid | 363 | if (infoDict->lookup((char*)"Keywords", &obj )->isString()) |
16729 | fschmid | 364 | { |
365 | s1 = obj.getString(); |
||
366 | m_Doc->documentInfo().setKeywords(UnicodeParsedString(obj.getString())); |
||
367 | obj.free(); |
||
368 | } |
||
369 | } |
||
370 | info.free(); |
||
371 | pdfDoc->displayPages(dev, firstPage, lastPage, hDPI, vDPI, rotate, useMediaBox, crop, printing); |
||
372 | } |
||
373 | else |
||
374 | pdfDoc->displayPage(dev, firstPage, hDPI, vDPI, rotate, useMediaBox, crop, printing); |
||
375 | } |
||
376 | delete dev; |
||
377 | } |
||
378 | } |
||
379 | delete pdfDoc; |
||
380 | } |
||
381 | delete globalParams; |
||
382 | globalParams = 0; |
||
383 | |||
384 | // qDebug() << "converting finished"; |
||
385 | // qDebug() << "Imported" << Elements.count() << "Elements"; |
||
386 | |||
387 | if (Elements.count() == 0) |
||
388 | { |
||
389 | if (importedColors.count() != 0) |
||
390 | { |
||
391 | for (int cd = 0; cd < importedColors.count(); cd++) |
||
392 | { |
||
393 | m_Doc->PageColors.remove(importedColors[cd]); |
||
394 | } |
||
395 | } |
||
396 | } |
||
397 | |||
398 | if (progressDialog) |
||
399 | progressDialog->close(); |
||
400 | return true; |
||
401 | } |
||
402 | |||
403 | QString PdfPlug::UnicodeParsedString(GooString *s1) |
||
404 | { |
||
405 | if ( !s1 || s1->getLength() == 0 ) |
||
406 | return QString(); |
||
407 | GBool isUnicode; |
||
408 | int i; |
||
409 | Unicode u; |
||
410 | QString result; |
||
411 | if ((s1->getChar(0) & 0xff) == 0xfe && (s1->getLength() > 1 && (s1->getChar(1) & 0xff) == 0xff)) |
||
412 | { |
||
413 | isUnicode = gTrue; |
||
414 | i = 2; |
||
415 | result.reserve((s1->getLength() - 2) / 2); |
||
416 | } |
||
417 | else |
||
418 | { |
||
419 | isUnicode = gFalse; |
||
420 | i = 0; |
||
421 | result.reserve(s1->getLength()); |
||
422 | } |
||
423 | while (i < s1->getLength()) |
||
424 | { |
||
425 | if (isUnicode) |
||
426 | { |
||
427 | u = ((s1->getChar(i) & 0xff) << 8) | (s1->getChar(i+1) & 0xff); |
||
428 | i += 2; |
||
429 | } |
||
430 | else |
||
431 | { |
||
432 | u = s1->getChar(i) & 0xff; |
||
433 | ++i; |
||
434 | } |
||
435 | result += QChar( u ); |
||
436 | } |
||
437 | return result; |
||
438 | } |