Subversion Repositories Scribus

Rev

Rev 17444 | Rev 17498 | 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>
17448 fschmid 19
#include <poppler-config.h>
16729 fschmid 20
 
21
#include "importpdf.h"
22
 
23
#include <cstdlib>
24
 
25
#include "commonstrings.h"
26
#include "loadsaveplugin.h"
27
#include "pagesize.h"
28
#include "prefscontext.h"
29
#include "prefsfile.h"
30
#include "prefsmanager.h"
31
#include "prefstable.h"
32
#include "rawimage.h"
33
#include "scclocale.h"
34
#include "sccolorengine.h"
35
#include "scconfig.h"
36
#include "scmimedata.h"
37
#include "scpaths.h"
38
#include "scribus.h"
39
#include "scribusXml.h"
40
#include "scribuscore.h"
41
#include "sctextstream.h"
42
#include "selection.h"
43
#include "undomanager.h"
44
#include "util.h"
45
#include "util_formats.h"
46
#include "util_ghostscript.h"
47
#include "util_icon.h"
48
#include "util_math.h"
49
 
17031 jghali 50
#include "ui/customfdialog.h"
51
#include "ui/missing.h"
52
#include "ui/multiprogressdialog.h"
53
#include "ui/propertiespalette.h"
16729 fschmid 54
 
55
PdfPlug::PdfPlug(ScribusDoc* doc, int flags)
56
{
57
        tmpSele = new Selection(this, false);
58
        m_Doc = doc;
59
        importerFlags = flags;
60
        interactive = (flags & LoadSavePlugin::lfInteractive);
16773 fschmid 61
        progressDialog = NULL;
16729 fschmid 62
}
63
 
64
QImage PdfPlug::readThumbnail(QString fName)
65
{
66
        QString tmp, cmd1, cmd2;
67
        QString pdfFile = QDir::toNativeSeparators(fName);
68
        QString tmpFile = QDir::toNativeSeparators(ScPaths::getTempFileDir() + "sc.png");
69
        int ret = -1;
70
        tmp.setNum(1);
71
        QStringList args;
72
        args.append("-r72");
73
        args.append("-sOutputFile="+tmpFile);
74
        args.append("-dFirstPage="+tmp);
75
        args.append("-dLastPage="+tmp);
76
        args.append(pdfFile);
77
        ret = callGS(args);
78
        if (ret == 0)
79
        {
80
                QImage image;
81
                image.load(tmpFile);
82
                QFile::remove(tmpFile);
83
                image.setText("XSize", QString("%1").arg(image.width()));
84
                image.setText("YSize", QString("%1").arg(image.height()));
85
                return image;
86
        }
87
        return QImage();
88
}
89
 
90
bool PdfPlug::import(QString fNameIn, const TransactionSettings& trSettings, int flags, bool showProgress)
91
{
92
        QString fName = fNameIn;
93
        bool success = false;
94
        interactive = (flags & LoadSavePlugin::lfInteractive);
95
        importerFlags = flags;
96
        cancel = false;
97
        double x, y, b, h;
98
        bool ret = false;
99
        QFileInfo fi = QFileInfo(fName);
100
        if ( !ScCore->usingGUI() )
101
        {
102
                interactive = false;
103
                showProgress = false;
104
        }
105
        baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/"));
106
        if ( showProgress )
107
        {
108
                ScribusMainWindow* mw=(m_Doc==0) ? ScCore->primaryMainWindow() : m_Doc->scMW();
109
                progressDialog = new MultiProgressDialog( tr("Importing: %1").arg(fi.fileName()), CommonStrings::tr_Cancel, mw );
110
                QStringList barNames, barTexts;
111
                barNames << "GI";
112
                barTexts << tr("Analyzing File:");
113
                QList<bool> barsNumeric;
114
                barsNumeric << false;
115
                progressDialog->addExtraProgressBars(barNames, barTexts, barsNumeric);
116
                progressDialog->setOverallTotalSteps(3);
117
                progressDialog->setOverallProgress(0);
118
                progressDialog->setProgress("GI", 0);
119
                progressDialog->show();
120
                connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelRequested()));
121
                qApp->processEvents();
122
        }
123
        else
124
                progressDialog = NULL;
125
/* Set default Page to size defined in Preferences */
126
        x = 0.0;
127
        y = 0.0;
128
        b = 0.0;
129
        h = 0.0;
130
        if (progressDialog)
131
        {
132
                progressDialog->setOverallProgress(1);
133
                qApp->processEvents();
134
        }
135
        if (b == 0.0)
136
                b = PrefsManager::instance()->appPrefs.docSetupPrefs.pageWidth;
137
        if (h == 0.0)
138
                h = PrefsManager::instance()->appPrefs.docSetupPrefs.pageHeight;
139
        docWidth = b;
140
        docHeight = h;
141
        baseX = 0;
142
        baseY = 0;
143
        if (!interactive || (flags & LoadSavePlugin::lfInsertPage))
144
        {
145
                m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
146
                m_Doc->addPage(0);
147
                m_Doc->view()->addPage(0, true);
148
                baseX = 0;
149
                baseY = 0;
150
        }
151
        else
152
        {
153
                if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc))
154
                {
17078 fschmid 155
                        m_Doc=ScCore->primaryMainWindow()->doFileNew(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, 0, 0, 0, 0, 1, "Custom", true);
16729 fschmid 156
                        ScCore->primaryMainWindow()->HaveNewDoc();
157
                        ret = true;
158
                        baseX = 0;
159
                        baseY = 0;
160
                        baseX = m_Doc->currentPage()->xOffset();
161
                        baseY = m_Doc->currentPage()->yOffset();
162
                }
163
        }
164
        if ((!ret) && (interactive))
165
        {
166
                baseX = m_Doc->currentPage()->xOffset();
167
                baseY = m_Doc->currentPage()->yOffset();
168
        }
169
        if ((ret) || (!interactive))
170
        {
171
                if (docWidth > docHeight)
172
                        m_Doc->setPageOrientation(1);
173
                else
174
                        m_Doc->setPageOrientation(0);
175
                m_Doc->setPageSize("Custom");
176
        }
177
        Elements.clear();
178
        m_Doc->setLoading(true);
179
        m_Doc->DoDrawing = false;
180
        if (!(flags & LoadSavePlugin::lfLoadAsPattern))
181
                m_Doc->view()->updatesOn(false);
182
        m_Doc->scMW()->setScriptRunning(true);
183
        qApp->changeOverrideCursor(QCursor(Qt::WaitCursor));
184
        QString CurDirP = QDir::currentPath();
185
        QDir::setCurrent(fi.path());
186
        if (convert(fName))
187
        {
188
                tmpSele->clear();
189
                QDir::setCurrent(CurDirP);
190
                if ((Elements.count() > 1) && (!(importerFlags & LoadSavePlugin::lfCreateDoc)))
191
                        m_Doc->groupObjectsList(Elements);
192
                m_Doc->DoDrawing = true;
193
                m_Doc->scMW()->setScriptRunning(false);
194
                m_Doc->setLoading(false);
195
                qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
196
                if ((Elements.count() > 0) && (!ret) && (interactive))
197
                {
198
                        if (flags & LoadSavePlugin::lfScripted)
199
                        {
200
                                bool loadF = m_Doc->isLoading();
201
                                m_Doc->setLoading(false);
202
                                m_Doc->changed();
203
                                m_Doc->setLoading(loadF);
204
                                if (!(flags & LoadSavePlugin::lfLoadAsPattern))
205
                                {
206
                                        m_Doc->m_Selection->delaySignalsOn();
207
                                        for (int dre=0; dre<Elements.count(); ++dre)
208
                                        {
209
                                                m_Doc->m_Selection->addItem(Elements.at(dre), true);
210
                                        }
211
                                        m_Doc->m_Selection->delaySignalsOff();
212
                                        m_Doc->m_Selection->setGroupRect();
213
                                        m_Doc->view()->updatesOn(true);
214
                                }
215
                        }
216
                        else
217
                        {
218
                                m_Doc->DragP = true;
219
                                m_Doc->DraggedElem = 0;
220
                                m_Doc->DragElements.clear();
221
                                m_Doc->m_Selection->delaySignalsOn();
222
                                for (int dre=0; dre<Elements.count(); ++dre)
223
                                {
224
                                        tmpSele->addItem(Elements.at(dre), true);
225
                                }
226
                                tmpSele->setGroupRect();
227
                                ScriXmlDoc *ss = new ScriXmlDoc();
228
                                ScElemMimeData* md = new ScElemMimeData();
229
                                md->setScribusElem(ss->WriteElem(m_Doc, tmpSele));
230
                                delete ss;
231
                                m_Doc->itemSelection_DeleteItem(tmpSele);
232
                                m_Doc->view()->updatesOn(true);
233
                                m_Doc->m_Selection->delaySignalsOff();
234
                                // We must copy the TransationSettings object as it is owned
235
                                // by handleObjectImport method afterwards
236
                                TransactionSettings* transacSettings = new TransactionSettings(trSettings);
237
                                m_Doc->view()->handleObjectImport(md, transacSettings);
238
                                m_Doc->DragP = false;
239
                                m_Doc->DraggedElem = 0;
240
                                m_Doc->DragElements.clear();
241
                        }
242
                }
243
                else
244
                {
245
                        m_Doc->changed();
246
                        m_Doc->reformPages();
247
                        if (!(flags & LoadSavePlugin::lfLoadAsPattern))
248
                                m_Doc->view()->updatesOn(true);
249
                }
250
                success = true;
251
        }
252
        else
253
        {
254
                QDir::setCurrent(CurDirP);
255
                m_Doc->DoDrawing = true;
256
                m_Doc->scMW()->setScriptRunning(false);
257
                if (!(flags & LoadSavePlugin::lfLoadAsPattern))
258
                        m_Doc->view()->updatesOn(true);
259
                qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
260
        }
261
        if (interactive)
262
                m_Doc->setLoading(false);
263
        //CB If we have a gui we must refresh it if we have used the progressbar
264
        if (!(flags & LoadSavePlugin::lfLoadAsPattern))
265
        {
266
                if ((showProgress) && (!interactive))
267
                        m_Doc->view()->DrawNew();
268
        }
269
        return success;
270
}
271
 
272
PdfPlug::~PdfPlug()
273
{
274
        if (progressDialog)
275
                delete progressDialog;
276
        delete tmpSele;
277
}
278
 
279
bool PdfPlug::convert(QString fn)
280
{
17448 fschmid 281
        bool firstLayer = true;
282
        bool firstPg = true;
283
        int currentLayer = m_Doc->activeLayer();
16729 fschmid 284
        importedColors.clear();
285
        if(progressDialog)
286
        {
287
                progressDialog->setOverallProgress(2);
288
                progressDialog->setLabel("GI", tr("Generating Items"));
289
                qApp->processEvents();
290
        }
291
        QFile f(fn);
292
        oldDocItemCount = m_Doc->Items->count();
293
        if (progressDialog)
294
        {
295
                progressDialog->setBusyIndicator("GI");
296
                qApp->processEvents();
297
        }
298
 
299
        globalParams = new GlobalParams();
300
        if (globalParams)
301
        {
302
                GooString *fname = new GooString(QFile::encodeName(fn).data());
303
                globalParams->setErrQuiet(gTrue);
17448 fschmid 304
                GBool hasOcg = gFalse;
305
                QList<OptionalContentGroup*> ocgGroups;
16729 fschmid 306
//              globalParams->setPrintCommands(gTrue);
307
                PDFDoc *pdfDoc = new PDFDoc(fname, 0, 0, 0);
308
                if (pdfDoc)
309
                {
310
                        if (pdfDoc->isOk())
311
                        {
312
                                double hDPI = 72.0;
313
                                double vDPI = 72.0;
314
                                int firstPage = 1;
315
                                int lastPage = pdfDoc->getNumPages();
17448 fschmid 316
                                SlaOutputDev *dev = new SlaOutputDev(m_Doc, &Elements, &importedColors, importerFlags);
317
                                if (dev->isOk())
17444 fschmid 318
                                {
17448 fschmid 319
                                        OCGs* ocg = pdfDoc->getOptContentConfig();
320
                                        if (ocg)
17444 fschmid 321
                                        {
17448 fschmid 322
                                                hasOcg = ocg->hasOCGs();
323
                                                if (hasOcg)
17444 fschmid 324
                                                {
17448 fschmid 325
                                                        Array *order = ocg->getOrderArray();
326
                                                        if (order)
17444 fschmid 327
                                                        {
17448 fschmid 328
                                                                for (int i = 0; i < order->getLength (); ++i)
17444 fschmid 329
                                                                {
17448 fschmid 330
                                                                        Object orderItem;
331
                                                                        order->get(i, &orderItem);
332
                                                                        if (orderItem.isDict())
17444 fschmid 333
                                                                        {
17448 fschmid 334
                                                                                Object ref;
335
                                                                                order->getNF(i, &ref);
336
                                                                                if (ref.isRef())
337
                                                                                {
338
                                                                                        OptionalContentGroup *oc = ocg->findOcgByRef(ref.getRef());
339
                                                                                        ocgGroups.prepend(oc);
340
                                                                                }
341
                                                                                ref.free();
17444 fschmid 342
                                                                        }
343
                                                                }
344
                                                        }
17448 fschmid 345
                                                        else
17444 fschmid 346
                                                        {
17448 fschmid 347
                                                                GooList *ocgs;
348
                                                                int i;
349
                                                                ocgs = ocg->getOCGs ();
350
                                                                for (i = 0; i < ocgs->getLength (); ++i)
351
                                                                {
352
                                                                        OptionalContentGroup *oc = (OptionalContentGroup *)ocgs->get(i);
353
                                                                        ocgGroups.prepend(oc);
354
                                                                }
17444 fschmid 355
                                                        }
356
                                                }
357
                                        }
16729 fschmid 358
                                        GBool useMediaBox = gTrue;
359
                                        GBool crop = gFalse;
360
                                        GBool printing = gFalse;
17419 fschmid 361
                                        dev->startDoc(pdfDoc, pdfDoc->getXRef(), pdfDoc->getCatalog());
16729 fschmid 362
                                        int rotate = pdfDoc->getPageRotate(firstPage);
363
                                        if (importerFlags & LoadSavePlugin::lfCreateDoc)
364
                                        {
17448 fschmid 365
                                                if (hasOcg)
366
                                                {
367
                                                        for (int a = 0; a < ocgGroups.count(); a++)
368
                                                        {
369
                                                                OptionalContentGroup *oc = ocgGroups[a];
370
                                                                if (firstLayer)
371
                                                                {
372
                                                                        m_Doc->changeLayerName(m_Doc->activeLayer(), UnicodeParsedString(oc->getName()));
373
                                                                        currentLayer = m_Doc->activeLayer();
374
                                                                        firstLayer = false;
375
                                                                }
376
                                                                else
377
                                                                        currentLayer = m_Doc->addLayer(UnicodeParsedString(oc->getName()), false);
378
// POPPLER_VERSION appeared in 0.19.0 first
379
#ifdef POPPLER_VERSION
380
                                                                if ((oc->getViewState() == OptionalContentGroup::ocUsageOn) || (oc->getViewState() == OptionalContentGroup::ocUsageUnset))
381
                                                                        m_Doc->setLayerVisible(currentLayer, true);
382
                                                                else
383
                                                                        m_Doc->setLayerVisible(currentLayer, false);
384
                                                                if ((oc->getPrintState() == OptionalContentGroup::ocUsageOn) || (oc->getPrintState() == OptionalContentGroup::ocUsageUnset))
385
                                                                        m_Doc->setLayerPrintable(currentLayer, true);
386
                                                                else
387
                                                                        m_Doc->setLayerPrintable(currentLayer, false);
388
#else
389
                                                                if (oc->getState() == OptionalContentGroup::On)
390
                                                                {
391
                                                                        m_Doc->setLayerVisible(currentLayer, true);
392
                                                                        m_Doc->setLayerPrintable(currentLayer, true);
393
                                                                }
394
                                                                else
395
                                                                {
396
                                                                        m_Doc->setLayerVisible(currentLayer, false);
397
                                                                        m_Doc->setLayerPrintable(currentLayer, false);
398
                                                                }
399
#endif
400
                                                                oc->setState(OptionalContentGroup::Off);
401
                                                        }
402
                                                        dev->layersSetByOCG = true;
403
                                                }
16729 fschmid 404
                                                Object info;
405
                                                pdfDoc->getDocInfo(&info);
406
                                                if (info.isDict())
407
                                                {
408
                                                        Object obj;
409
                                                        GooString *s1;
410
                                                        Dict *infoDict = info.getDict();
16732 fschmid 411
                                                        if (infoDict->lookup((char*)"Title", &obj )->isString())
16729 fschmid 412
                                                        {
413
                                                                s1 = obj.getString();
414
                                                                m_Doc->documentInfo().setTitle(UnicodeParsedString(obj.getString()));
415
                                                                obj.free();
416
                                                        }
16732 fschmid 417
                                                        if (infoDict->lookup((char*)"Author", &obj )->isString())
16729 fschmid 418
                                                        {
419
                                                                s1 = obj.getString();
420
                                                                m_Doc->documentInfo().setAuthor(UnicodeParsedString(obj.getString()));
421
                                                                obj.free();
422
                                                        }
16732 fschmid 423
                                                        if (infoDict->lookup((char*)"Subject", &obj )->isString())
16729 fschmid 424
                                                        {
425
                                                                s1 = obj.getString();
426
                                                                m_Doc->documentInfo().setSubject(UnicodeParsedString(obj.getString()));
427
                                                                obj.free();
428
                                                        }
16732 fschmid 429
                                                        if (infoDict->lookup((char*)"Keywords", &obj )->isString())
16729 fschmid 430
                                                        {
431
                                                                s1 = obj.getString();
432
                                                                m_Doc->documentInfo().setKeywords(UnicodeParsedString(obj.getString()));
433
                                                                obj.free();
434
                                                        }
435
                                                }
436
                                                info.free();
17448 fschmid 437
                                                for (int pp = 0; pp < lastPage; pp++)
438
                                                {
439
                                                        if (firstPg)
440
                                                                firstPg = false;
441
                                                        else
442
                                                                m_Doc->addPage(pp);
443
                                                        m_Doc->currentPage()->setInitialHeight(pdfDoc->getPageMediaHeight(pp + 1));
444
                                                        m_Doc->currentPage()->setInitialWidth(pdfDoc->getPageMediaWidth(pp + 1));
445
                                                        m_Doc->currentPage()->setHeight(pdfDoc->getPageMediaHeight(pp + 1));
446
                                                        m_Doc->currentPage()->setWidth(pdfDoc->getPageMediaWidth(pp + 1));
447
                                                        m_Doc->currentPage()->MPageNam = CommonStrings::trMasterPageNormal;
448
                                                        m_Doc->currentPage()->m_pageSize = "Custom";
449
                                                        m_Doc->setPageSize("Custom");
450
                                                        m_Doc->reformPages(true);
451
                                                        if (hasOcg)
452
                                                        {
453
                                                                for (int a = 0; a < ocgGroups.count(); a++)
454
                                                                {
455
                                                                        OptionalContentGroup *oc = ocgGroups[a];
456
                                                                        m_Doc->setActiveLayer(UnicodeParsedString(oc->getName()));
457
                                                                        currentLayer = m_Doc->activeLayer();
458
                                                                        oc->setState(OptionalContentGroup::On);
459
                                                                        pdfDoc->displayPage(dev, pp + 1, hDPI, vDPI, rotate, useMediaBox, crop, printing);
460
                                                                        oc->setState(OptionalContentGroup::Off);
461
                                                                }
462
                                                        }
463
                                                        else
464
                                                                pdfDoc->displayPage(dev, pp + 1, hDPI, vDPI, rotate, useMediaBox, crop, printing);
465
                                                }
16729 fschmid 466
                                        }
467
                                        else
17448 fschmid 468
                                        {
469
                                                if (hasOcg)
470
                                                {
471
                                                        for (int a = 0; a < ocgGroups.count(); a++)
472
                                                        {
473
                                                                ocgGroups[a]->setState(OptionalContentGroup::On);
474
                                                        }
475
                                                }
16729 fschmid 476
                                                pdfDoc->displayPage(dev, firstPage, hDPI, vDPI, rotate, useMediaBox, crop, printing);
17448 fschmid 477
                                        }
16729 fschmid 478
                                }
479
                                delete dev;
480
                        }
481
                }
482
                delete pdfDoc;
483
        }
484
        delete globalParams;
485
        globalParams = 0;
486
 
487
//      qDebug() << "converting finished";
488
//      qDebug() << "Imported" << Elements.count() << "Elements";
489
 
490
        if (Elements.count() == 0)
491
        {
492
                if (importedColors.count() != 0)
493
                {
494
                        for (int cd = 0; cd < importedColors.count(); cd++)
495
                        {
496
                                m_Doc->PageColors.remove(importedColors[cd]);
497
                        }
498
                }
499
        }
500
 
501
        if (progressDialog)
502
                progressDialog->close();
503
        return true;
504
}
505
 
506
QString PdfPlug::UnicodeParsedString(GooString *s1)
507
{
508
        if ( !s1 || s1->getLength() == 0 )
509
                return QString();
510
        GBool isUnicode;
511
        int i;
512
        Unicode u;
513
        QString result;
514
        if ((s1->getChar(0) & 0xff) == 0xfe && (s1->getLength() > 1 && (s1->getChar(1) & 0xff) == 0xff))
515
        {
516
                isUnicode = gTrue;
517
                i = 2;
518
                result.reserve((s1->getLength() - 2) / 2);
519
        }
520
        else
521
        {
522
                isUnicode = gFalse;
523
                i = 0;
524
                result.reserve(s1->getLength());
525
        }
526
        while (i < s1->getLength())
527
        {
528
                if (isUnicode)
529
                {
530
                        u = ((s1->getChar(i) & 0xff) << 8) | (s1->getChar(i+1) & 0xff);
531
                        i += 2;
532
                }
533
                else
534
                {
535
                        u = s1->getChar(i) & 0xff;
536
                        ++i;
537
                }
538
                result += QChar( u );
539
        }
540
        return result;
541
}