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 #include <QApplication>
8 #include <QMessageBox>
9
10 #include "commonstrings.h"
11
12 #include "importpdf.h"
13 #include "importpdfplugin.h"
14 #include "prefscontext.h"
15 #include "prefsfile.h"
16 #include "prefsmanager.h"
17 #include "scpage.h"
18 #include "scpaths.h"
19 #include "scraction.h"
20 #include "scribuscore.h"
21 #include "undomanager.h"
22 #include "util_formats.h"
23 #include "util.h"
24
25 #include "ui/customfdialog.h"
26 #include "ui/scmessagebox.h"
27 #include "ui/scmwmenumanager.h"
28
importpdf_getPluginAPIVersion()29 int importpdf_getPluginAPIVersion()
30 {
31 return PLUGIN_API_VERSION;
32 }
33
importpdf_getPlugin()34 ScPlugin* importpdf_getPlugin()
35 {
36 ImportPdfPlugin* plug = new ImportPdfPlugin();
37 Q_CHECK_PTR(plug);
38 return plug;
39 }
40
importpdf_freePlugin(ScPlugin * plugin)41 void importpdf_freePlugin(ScPlugin* plugin)
42 {
43 ImportPdfPlugin* plug = qobject_cast<ImportPdfPlugin*>(plugin);
44 Q_ASSERT(plug);
45 delete plug;
46 }
47
ImportPdfPlugin()48 ImportPdfPlugin::ImportPdfPlugin() :
49 importAction(new ScrAction(ScrAction::DLL, QPixmap(), QPixmap(), "", QKeySequence(), this))
50 {
51 // Set action info in languageChange, so we only have to do it in one
52 // place. This includes registering file format support.
53 registerFormats();
54 languageChange();
55 }
56
languageChange()57 void ImportPdfPlugin::languageChange()
58 {
59 importAction->setText( tr("Import PDF..."));
60 FileFormat* fmt = getFormatByExt("pdf");
61 fmt->trName = FormatsManager::instance()->nameOfFormat(FormatsManager::PDF); // Human readable name
62 fmt->filter = FormatsManager::instance()->extensionsForFormat(FormatsManager::PDF); // QFileDialog filter
63 if (ScCore->haveGS())
64 {
65 FileFormat* fmt2 = getFormatByExt("eps");
66 fmt2->trName = FormatsManager::instance()->nameOfFormat(FormatsManager::EPS);
67 fmt2->filter = FormatsManager::instance()->extensionsForFormat(FormatsManager::EPS);
68 FileFormat* fmt3 = getFormatByExt("ps");
69 fmt3->trName = FormatsManager::instance()->nameOfFormat(FormatsManager::PS);
70 fmt3->filter = FormatsManager::instance()->extensionsForFormat(FormatsManager::PS);
71 }
72 }
73
~ImportPdfPlugin()74 ImportPdfPlugin::~ImportPdfPlugin()
75 {
76 unregisterAll();
77 }
78
fullTrName() const79 QString ImportPdfPlugin::fullTrName() const
80 {
81 return QObject::tr("PDF Importer");
82 }
83
84
getAboutData() const85 const ScActionPlugin::AboutData* ImportPdfPlugin::getAboutData() const
86 {
87 AboutData* about = new AboutData;
88 about->authors = "Franz Schmid <franz@scribus.info>";
89 about->shortDescription = tr("Imports PDF Files");
90 about->description = tr("Imports most PDF files into the current document, converting their vector data into Scribus objects.");
91 about->license = "GPL";
92 Q_CHECK_PTR(about);
93 return about;
94 }
95
deleteAboutData(const AboutData * about) const96 void ImportPdfPlugin::deleteAboutData(const AboutData* about) const
97 {
98 Q_ASSERT(about);
99 delete about;
100 }
101
registerFormats()102 void ImportPdfPlugin::registerFormats()
103 {
104 FileFormat fmt(this);
105 fmt.trName = FormatsManager::instance()->nameOfFormat(FormatsManager::PDF); // Human readable name
106 fmt.formatId = 0;
107 fmt.filter = FormatsManager::instance()->extensionsForFormat(FormatsManager::PDF); // QFileDialog filter
108 fmt.fileExtensions = QStringList() << "pdf";
109 fmt.load = true;
110 fmt.save = false;
111 fmt.thumb = true;
112 fmt.mimeTypes = FormatsManager::instance()->mimetypeOfFormat(FormatsManager::PDF); // MIME types
113 fmt.priority = 64; // Priority
114 registerFormat(fmt);
115
116 if (ScCore->haveGS())
117 {
118 FileFormat fmt2(this);
119 fmt2.trName = FormatsManager::instance()->nameOfFormat(FormatsManager::EPS); // Human readable name
120 fmt2.formatId = 0;
121 fmt2.filter = FormatsManager::instance()->extensionsForFormat(FormatsManager::EPS);// QFileDialog filter
122 fmt2.fileExtensions = QStringList() << "eps" << "epsf" << "epsi" << "eps2" << "eps3" << "epi" << "ept";
123 fmt2.load = true;
124 fmt2.save = false;
125 fmt2.mimeTypes = FormatsManager::instance()->mimetypeOfFormat(FormatsManager::EPS); // MIME types
126 fmt2.priority = 64; // Priority
127 registerFormat(fmt2);
128
129 FileFormat fmt3(this);
130 fmt3.trName = FormatsManager::instance()->nameOfFormat(FormatsManager::PS); // Human readable name
131 fmt3.formatId = 0;
132 fmt3.filter = FormatsManager::instance()->extensionsForFormat(FormatsManager::PS);// QFileDialog filter
133 fmt3.fileExtensions = QStringList() << "ps";
134 fmt3.load = true;
135 fmt3.save = false;
136 fmt3.mimeTypes = FormatsManager::instance()->mimetypeOfFormat(FormatsManager::PS); // MIME types
137 fmt3.priority = 64; // Priority
138 registerFormat(fmt3);
139 }
140 }
141
fileSupported(QIODevice *,const QString & fileName) const142 bool ImportPdfPlugin::fileSupported(QIODevice* /* file */, const QString & fileName) const
143 {
144 return true;
145 }
146
loadFile(const QString & fileName,const FileFormat &,int flags,int)147 bool ImportPdfPlugin::loadFile(const QString & fileName, const FileFormat &, int flags, int /*index*/)
148 {
149 // There's only one format to handle, so we just call import(...)
150 return import(fileName, flags);
151 }
152
import(QString fileName,int flags)153 bool ImportPdfPlugin::import(QString fileName, int flags)
154 {
155 if (!checkFlags(flags))
156 return false;
157 if (fileName.isEmpty())
158 {
159 flags |= lfInteractive;
160 PrefsContext* prefs = PrefsManager::instance().prefsFile->getPluginContext("importpdf");
161 QString wdir = prefs->get("wdir", ".");
162 CustomFDialog diaf(ScCore->primaryMainWindow(), wdir, QObject::tr("Open"), tr("All Supported Formats")+" (*.pdf *.PDF);;All Files (*)");
163 if (diaf.exec() != QDialog::Accepted)
164 return false;
165 fileName = diaf.selectedFile();
166 prefs->set("wdir", fileName.left(fileName.lastIndexOf("/")));
167 }
168 m_Doc = ScCore->primaryMainWindow()->doc;
169 bool emptyDoc = (m_Doc == nullptr);
170 bool hasCurrentPage = (m_Doc && m_Doc->currentPage());
171
172 QFileInfo fi(fileName);
173 QStringList exts = QStringList() << "eps" << "epsf" << "epsi" << "eps2" << "eps3" << "epi" << "ept" << "ps" << "ai";
174 QString lowerExt = fi.suffix().toLower();
175
176 QString undoActionName = Um::ImportPDF;
177 if (lowerExt == QLatin1String("ai"))
178 undoActionName = Um::ImportAI;
179 else if (exts.contains(fi.suffix().toLower()))
180 undoActionName = Um::ImportEPS;
181
182 TransactionSettings trSettings;
183 trSettings.targetName = hasCurrentPage ? m_Doc->currentPage()->getUName() : "";
184 trSettings.targetPixmap = Um::IImageFrame;
185 trSettings.actionName = undoActionName;
186 trSettings.description = fileName;
187 trSettings.actionPixmap = Um::IXFIG;
188
189 UndoTransaction activeTransaction;
190 if (emptyDoc || !(flags & lfInteractive) || !(flags & lfScripted))
191 UndoManager::instance()->setUndoEnabled(false);
192 if (UndoManager::undoEnabled())
193 activeTransaction = UndoManager::instance()->beginTransaction(trSettings);
194
195 bool isCleanedFile = false;
196 QString cleanFile = "";
197 if (exts.contains(fi.suffix().toLower()))
198 {
199 if (!ScCore->haveGS())
200 {
201 qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
202 ScMessageBox::warning(ScCore->primaryMainWindow(), CommonStrings::trWarning, tr("The Import plugin cannot handle Postscript files"));
203 qApp->changeOverrideCursor(QCursor(Qt::WaitCursor));
204 return false;
205 }
206
207 // Destill the eps/ps with ghostscript to get a clean pdf file
208 bool cancel = false;
209 QString errFile = getShortPathName(ScPaths::tempFileDir())+ "/ps.err";
210 cleanFile = getShortPathName(ScPaths::tempFileDir()) + "/" + fi.baseName() + ".pdf";
211 QStringList args;
212 args.append( "-q" );
213 args.append( "-dNOPAUSE" );
214 args.append( "-sDEVICE=pdfwrite" );
215 args.append( "-dBATCH" );
216 args.append( "-dSAFER" );
217 if (extensionIndicatesEPS(fi.suffix().toLower()))
218 args.append("-dEPSCrop");
219 args.append("-dCompatibilityLevel=1.4");
220 args.append( QString("-sOutputFile=%1").arg(QDir::toNativeSeparators(cleanFile)) );
221 args.append( QDir::toNativeSeparators(fileName) );
222 System(getShortPathName(PrefsManager::instance().ghostscriptExecutable()), args, errFile, errFile, &cancel);
223 args.clear();
224 isCleanedFile = true;
225 }
226 bool ret = false;
227 PdfPlug *dia = new PdfPlug(m_Doc, flags);
228 Q_CHECK_PTR(dia);
229 if (isCleanedFile)
230 ret = dia->import(cleanFile, trSettings, flags, !(flags & lfScripted));
231 else
232 ret = dia->import(fileName, trSettings, flags, !(flags & lfScripted));
233 if (activeTransaction)
234 activeTransaction.commit();
235 if (emptyDoc || !(flags & lfInteractive) || !(flags & lfScripted))
236 UndoManager::instance()->setUndoEnabled(true);
237 delete dia;
238 if (isCleanedFile)
239 QFile::remove(cleanFile);
240 return ret;
241 }
242
readThumbnail(const QString & fileName)243 QImage ImportPdfPlugin::readThumbnail(const QString& fileName)
244 {
245 if (fileName.isEmpty())
246 return QImage();
247 UndoManager::instance()->setUndoEnabled(false);
248 m_Doc = nullptr;
249 PdfPlug *dia = new PdfPlug(m_Doc, lfCreateThumbnail);
250 Q_CHECK_PTR(dia);
251 QImage ret = dia->readThumbnail(fileName);
252 UndoManager::instance()->setUndoEnabled(true);
253 delete dia;
254 return ret;
255 }
256