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 "commonstrings.h"
8 
9 #include "importai.h"
10 #include "importaiplugin.h"
11 
12 #include "prefscontext.h"
13 #include "prefsfile.h"
14 #include "prefsmanager.h"
15 #include "scconfig.h"
16 #include "scpage.h"
17 #include "scraction.h"
18 #include "scribuscore.h"
19 #include "undomanager.h"
20 #include "util_formats.h"
21 
22 #include "ui/customfdialog.h"
23 #include "ui/scmessagebox.h"
24 #include "ui/scmwmenumanager.h"
25 
26 #include <QApplication>
27 #include <QMessageBox>
28 
importai_getPluginAPIVersion()29 int importai_getPluginAPIVersion()
30 {
31 	return PLUGIN_API_VERSION;
32 }
33 
importai_getPlugin()34 ScPlugin* importai_getPlugin()
35 {
36 	ImportAIPlugin* plug = new ImportAIPlugin();
37 	Q_CHECK_PTR(plug);
38 	return plug;
39 }
40 
importai_freePlugin(ScPlugin * plugin)41 void importai_freePlugin(ScPlugin* plugin)
42 {
43 	ImportAIPlugin* plug = qobject_cast<ImportAIPlugin*>(plugin);
44 	Q_ASSERT(plug);
45 	delete plug;
46 }
47 
ImportAIPlugin()48 ImportAIPlugin::ImportAIPlugin() :
49 	importAction(new ScrAction(ScrAction::DLL, "", 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 ImportAIPlugin::languageChange()
58 {
59 	importAction->setText( tr("Import AI..."));
60 	FileFormat* fmt = getFormatByExt("ai");
61 	fmt->trName = FormatsManager::instance()->nameOfFormat(FormatsManager::AI); // Human readable name
62 	fmt->filter = FormatsManager::instance()->extensionsForFormat(FormatsManager::AI); // QFileDialog filter
63 }
64 
~ImportAIPlugin()65 ImportAIPlugin::~ImportAIPlugin()
66 {
67 	unregisterAll();
68 }
69 
fullTrName() const70 QString ImportAIPlugin::fullTrName() const
71 {
72 	return QObject::tr("Adobe Illustrator Importer");
73 }
74 
75 
getAboutData() const76 const ScActionPlugin::AboutData* ImportAIPlugin::getAboutData() const
77 {
78 	AboutData* about = new AboutData;
79 	about->authors = "Franz Schmid <franz@scribus.info>";
80 	about->shortDescription = tr("Imports Illustrator Files");
81 	about->description = tr("Imports most Illustrator files into the current document, converting their vector data into Scribus objects.");
82 	about->license = "GPL";
83 	Q_CHECK_PTR(about);
84 	return about;
85 }
86 
deleteAboutData(const AboutData * about) const87 void ImportAIPlugin::deleteAboutData(const AboutData* about) const
88 {
89 	Q_ASSERT(about);
90 	delete about;
91 }
92 
registerFormats()93 void ImportAIPlugin::registerFormats()
94 {
95 	FileFormat fmt(this);
96 	fmt.trName = FormatsManager::instance()->nameOfFormat(FormatsManager::AI); // Human readable name
97 	fmt.formatId = 0;
98 	fmt.filter = FormatsManager::instance()->extensionsForFormat(FormatsManager::AI); // QFileDialog filter
99 	fmt.fileExtensions = QStringList() << "ai";
100 	fmt.load = true;
101 	fmt.save = false;
102 	fmt.thumb = true;
103 	fmt.colorReading = true;
104 	fmt.mimeTypes = FormatsManager::instance()->mimetypeOfFormat(FormatsManager::AI); // MIME types
105 	fmt.priority = 64; // Priority
106 	registerFormat(fmt);
107 }
108 
fileSupported(QIODevice *,const QString & fileName) const109 bool ImportAIPlugin::fileSupported(QIODevice* /* file */, const QString & fileName) const
110 {
111 	// TODO: check for %!PS-Adobe
112 	return true;
113 }
114 
loadFile(const QString & fileName,const FileFormat &,int flags,int)115 bool ImportAIPlugin::loadFile(const QString & fileName, const FileFormat & /*fmt*/, int flags, int /*index*/)
116 {
117 	// There's only one format to handle, so we just call import(...)
118 	return import(fileName, flags);
119 }
120 
import(QString fileName,int flags)121 bool ImportAIPlugin::import(QString fileName, int flags)
122 {
123 	if (!checkFlags(flags))
124 		return false;
125 	if (fileName.isEmpty())
126 	{
127 		flags |= lfInteractive;
128 		PrefsContext* prefs = PrefsManager::instance().prefsFile->getPluginContext("importai");
129 		QString wdir = prefs->get("wdir", ".");
130 		CustomFDialog diaf(ScCore->primaryMainWindow(), wdir, QObject::tr("Open"), FormatsManager::instance()->fileDialogFormatList(FormatsManager::AI));
131 		if (diaf.exec())
132 		{
133 			fileName = diaf.selectedFile();
134 			prefs->set("wdir", fileName.left(fileName.lastIndexOf("/")));
135 		}
136 		else
137 			return true;
138 	}
139 	m_Doc=ScCore->primaryMainWindow()->doc;
140 	UndoTransaction activeTransaction;
141 	bool emptyDoc = (m_Doc == nullptr);
142 	bool hasCurrentPage = (m_Doc && m_Doc->currentPage());
143 	TransactionSettings trSettings;
144 	trSettings.targetName   = hasCurrentPage ? m_Doc->currentPage()->getUName() : "";
145 	trSettings.targetPixmap = Um::IImageFrame;
146 	trSettings.actionName   = Um::ImportAI;
147 	trSettings.description  = fileName;
148 	trSettings.actionPixmap = Um::IAI;
149 	if (emptyDoc || !(flags & lfInteractive) || !(flags & lfScripted))
150 		UndoManager::instance()->setUndoEnabled(false);
151 	if (UndoManager::undoEnabled())
152 		activeTransaction = UndoManager::instance()->beginTransaction(trSettings);
153 #ifdef HAVE_POPPLER
154 	if (!(flags & LoadSavePlugin::lfLoadAsPattern))
155 	{
156 /* Check if the file is an old style AI or one of the newer PDF wrapped ones */
157 		QFile fT(fileName);
158 		if (fT.open(QIODevice::ReadOnly))
159 		{
160 			QByteArray tempBuf(25, ' ');
161 			fT.read(tempBuf.data(), 24);
162 			fT.close();
163 			if (tempBuf.startsWith("%PDF"))
164 			{
165 				qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
166 				ScMessageBox msgBox(ScCore->primaryMainWindow());
167 				msgBox.setText( tr("This file contains 2 versions of the data."));
168 				msgBox.setInformativeText( tr("Choose which one should be imported"));
169 				msgBox.setIcon(QMessageBox::Question);
170 				QPushButton *pdfButton = msgBox.addButton( tr("Use the PDF part"), QMessageBox::ActionRole);
171 				msgBox.addButton( tr("Use the AI part"), QMessageBox::ActionRole);
172 				msgBox.setDefaultButton(pdfButton);
173 				msgBox.exec();
174 				if ((QPushButton *)msgBox.clickedButton() == pdfButton)
175 				{
176 					//Import PDF
177 					const FileFormat *fmt = LoadSavePlugin::getFormatByExt("pdf");
178 					if (!fmt)
179 					{
180 						ScMessageBox::warning(ScCore->primaryMainWindow(), CommonStrings::trWarning, tr("The PDF Import plugin could not be found"));
181 						return false;
182 					}
183 					qApp->changeOverrideCursor(QCursor(Qt::WaitCursor));
184 					bool success = fmt->loadFile(fileName, flags);
185 					if (activeTransaction)
186 						activeTransaction.commit();
187 					if (emptyDoc || !(flags & lfInteractive) || !(flags & lfScripted))
188 						UndoManager::instance()->setUndoEnabled(true);
189 					if (!success)
190 						ScMessageBox::warning(ScCore->primaryMainWindow(), CommonStrings::trWarning, tr("The file could not be imported"));
191 					return success;
192 				}
193 				qApp->changeOverrideCursor(QCursor(Qt::WaitCursor));
194 			}
195 			else if (tempBuf.startsWith("%!PS-Adobe-3.0 EPSF-3.0"))
196 			{
197 				//Import EPS
198 				const FileFormat *fmt = LoadSavePlugin::getFormatByExt("eps");
199 				if (!fmt)
200 				{
201 					ScMessageBox::warning(ScCore->primaryMainWindow(), CommonStrings::trWarning, tr("The EPS Import plugin could not be found"));
202 					return false;
203 				}
204 				qApp->changeOverrideCursor(QCursor(Qt::WaitCursor));
205 				bool success = fmt->loadFile(fileName, flags);
206 				if (activeTransaction)
207 					activeTransaction.commit();
208 				if (emptyDoc || !(flags & lfInteractive) || !(flags & lfScripted))
209 					UndoManager::instance()->setUndoEnabled(true);
210 				if (!success)
211 					ScMessageBox::warning(ScCore->primaryMainWindow(), CommonStrings::trWarning, tr("The file could not be imported"));
212 				return success;
213 			}
214 		}
215 	}
216 #endif
217 	AIPlug *dia = new AIPlug(m_Doc, flags);
218 	Q_CHECK_PTR(dia);
219 	bool success = dia->import(fileName, trSettings, flags, !(flags & lfScripted));
220 	if (activeTransaction)
221 		activeTransaction.commit();
222 	if (emptyDoc || !(flags & lfInteractive) || !(flags & lfScripted))
223 		UndoManager::instance()->setUndoEnabled(true);
224 	if (!success)
225 		ScMessageBox::warning(ScCore->primaryMainWindow(), CommonStrings::trWarning, tr("The file could not be imported"));
226 	delete dia;
227 	return success;
228 }
229 
readThumbnail(const QString & fileName)230 QImage ImportAIPlugin::readThumbnail(const QString& fileName)
231 {
232 	if (fileName.isEmpty())
233 		return QImage();
234 	UndoManager::instance()->setUndoEnabled(false);
235 	m_Doc = nullptr;
236 	AIPlug *dia = new AIPlug(m_Doc, lfCreateThumbnail);
237 	Q_CHECK_PTR(dia);
238 	QImage ret = dia->readThumbnail(fileName);
239 	UndoManager::instance()->setUndoEnabled(true);
240 	delete dia;
241 	return ret;
242 }
243 
readColors(const QString & fileName,ColorList & colors)244 bool ImportAIPlugin::readColors(const QString& fileName, ColorList &colors)
245 {
246 	if (fileName.isEmpty())
247 		return false;
248 	UndoManager::instance()->setUndoEnabled(false);
249 	m_Doc = nullptr;
250 	AIPlug *dia = new AIPlug(m_Doc, lfCreateThumbnail);
251 	Q_CHECK_PTR(dia);
252 	bool ret = dia->readColors(fileName, colors);
253 	UndoManager::instance()->setUndoEnabled(true);
254 	delete dia;
255 	return ret;
256 }
257