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 <QFileDialog>
9 #include <QInputDialog>
10 #include <QProcess>
11 #include <QMessageBox>
12 #include "scpaths.h"
13 #include "prefsstructs.h"
14 #include "latexhelpers.h"
15 #include "commonstrings.h"
16 #include "ui/scmessagebox.h"
17 #include "util_file.h"
18 #include "util_ghostscript.h"
19 
20 
21 #include "prefs_externaltools.h"
22 
Prefs_ExternalTools(QWidget * parent,ScribusDoc * doc)23 Prefs_ExternalTools::Prefs_ExternalTools(QWidget* parent, ScribusDoc* doc)
24 	: Prefs_Pane(parent)
25 {
26 	setupUi(this);
27 	languageChange();
28 
29 	m_caption = tr("External Tools");
30 	m_icon = "gear_16.png";
31 
32 	connect(psToolChangeButton, SIGNAL(clicked()), this, SLOT(changePostScriptTool()));
33 	connect(imageToolChangeButton, SIGNAL(clicked()), this, SLOT(changeImageTool()));
34 	connect(webBrowserChangeButton, SIGNAL(clicked()), this, SLOT(changeWebBrowser()));
35 	connect(rescanButton, SIGNAL(clicked()), this, SLOT(rescanForTools()));
36 	connect(uniconvertorChangeButton, SIGNAL(clicked()), this, SLOT(changeUniconvertor()));
37 	connect(pdfViewerChangeButton, SIGNAL(clicked()), this, SLOT(changePDFViewer()));
38 	connect(latexConfigUpButton, SIGNAL(clicked()), this, SLOT(upButtonPressed()));
39 	connect(latexConfigDownButton, SIGNAL(clicked()), this, SLOT(downButtonPressed()));
40 	connect(latexConfigAddButton, SIGNAL(clicked()), this, SLOT(addConfig()));
41 	connect(latexConfigDeleteButton, SIGNAL(clicked()), this, SLOT(deleteConfig()));
42 	connect(latexEditorChangeButton, SIGNAL(clicked()), this, SLOT(changeLatexEditor()));
43 	connect(latexConfigChangeCommandButton, SIGNAL(clicked()), this, SLOT(changeLatexPath()));
44 
45 }
46 
~Prefs_ExternalTools()47 Prefs_ExternalTools::~Prefs_ExternalTools()
48 {
49 }
50 
languageChange()51 void Prefs_ExternalTools::languageChange()
52 {
53 }
54 
restoreDefaults(struct ApplicationPrefs * prefsData)55 void Prefs_ExternalTools::restoreDefaults(struct ApplicationPrefs *prefsData)
56 {
57 	psToolLineEdit->setText(QDir::toNativeSeparators(prefsData->extToolPrefs.gs_exe));
58 	psAntialiasTextCheckBox->setChecked(prefsData->extToolPrefs.gs_AntiAliasText);
59 	psAntialiasGraphicsCheckBox->setChecked(prefsData->extToolPrefs.gs_AntiAliasGraphics);
60 	psResolutionSpinBox->setValue(prefsData->extToolPrefs.gs_Resolution);
61 	imageToolLineEdit->setText(QDir::toNativeSeparators(prefsData->extToolPrefs.imageEditorExecutable));
62 	webBrowserLineEdit->setText(QDir::toNativeSeparators(prefsData->extToolPrefs.extBrowserExecutable));
63 	uniconvertorLineEdit->setText(QDir::toNativeSeparators(prefsData->extToolPrefs.uniconvExecutable));
64 	latexResolutionSpinBox->setValue(prefsData->extToolPrefs.latexResolution);
65 	latexEditorLineEdit->setText(prefsData->extToolPrefs.latexEditorExecutable);
66 	latexForceDPICheckBox->setCheckState(prefsData->extToolPrefs.latexForceDpi?Qt::Checked:Qt::Unchecked);
67 	latexEmptyFrameCheckBox->setCheckState(prefsData->extToolPrefs.latexStartWithEmptyFrames?Qt::Checked:Qt::Unchecked);
68 	latexConfigsListWidget->clear();
69 	const QStringList configs = prefsData->extToolPrefs.latexConfigs;
70 	commands = prefsData->extToolPrefs.latexCommands;
71 	for (const QString& config : configs)
72 		insertConfigItem(config);
73 	latexConfigsListWidget->setCurrentRow(0);
74 	pdfViewerLineEdit->setText(QDir::toNativeSeparators(prefsData->extToolPrefs.pdfViewerExecutable));
75 }
76 
saveGuiToPrefs(struct ApplicationPrefs * prefsData) const77 void Prefs_ExternalTools::saveGuiToPrefs(struct ApplicationPrefs *prefsData) const
78 {
79 	prefsData->extToolPrefs.gs_AntiAliasGraphics = psAntialiasGraphicsCheckBox->isChecked();
80 	prefsData->extToolPrefs.gs_AntiAliasText = psAntialiasTextCheckBox->isChecked();
81 	prefsData->extToolPrefs.gs_exe=QDir::fromNativeSeparators(psToolLineEdit->text());
82 	prefsData->extToolPrefs.gs_Resolution = psResolutionSpinBox->value();
83 
84 	prefsData->extToolPrefs.imageEditorExecutable=QDir::fromNativeSeparators(imageToolLineEdit->text());
85 	prefsData->extToolPrefs.extBrowserExecutable=QDir::fromNativeSeparators(webBrowserLineEdit->text());
86 
87 	prefsData->extToolPrefs.latexResolution = latexResolutionSpinBox->value();
88 	prefsData->extToolPrefs.latexForceDpi = latexForceDPICheckBox->checkState() == Qt::Checked;
89 	prefsData->extToolPrefs.latexStartWithEmptyFrames = latexEmptyFrameCheckBox->checkState() == Qt::Checked;
90 	QStringList configsList;
91 	for (int i=0; i < latexConfigsListWidget->count(); i++)
92 		configsList.append(latexConfigsListWidget->item(i)->data(Qt::UserRole).toString());
93 	prefsData->extToolPrefs.latexConfigs=configsList;
94 	prefsData->extToolPrefs.latexCommands=commands;
95 	prefsData->extToolPrefs.latexEditorExecutable=QDir::fromNativeSeparators(latexEditorLineEdit->text());
96 	prefsData->extToolPrefs.uniconvExecutable=QDir::fromNativeSeparators(uniconvertorLineEdit->text());
97 	prefsData->extToolPrefs.pdfViewerExecutable=QDir::fromNativeSeparators(pdfViewerLineEdit->text());
98 }
99 
changePostScriptTool()100 void Prefs_ExternalTools::changePostScriptTool()
101 {
102 	QFileInfo fi(psToolLineEdit->text());
103 	QString s = QFileDialog::getOpenFileName(this, tr("Locate Ghostscript"), fi.path());
104 	if (!s.isEmpty())
105 		psToolLineEdit->setText( QDir::toNativeSeparators(s) );
106 }
107 
changeImageTool()108 void Prefs_ExternalTools::changeImageTool()
109 {
110 	QFileInfo fi(imageToolLineEdit->text());
111 	QString s = QFileDialog::getOpenFileName(this, tr("Locate your image editor"), fi.path());
112 	if (!s.isEmpty())
113 		imageToolLineEdit->setText( QDir::toNativeSeparators(s) );
114 }
115 
changeWebBrowser()116 void Prefs_ExternalTools::changeWebBrowser()
117 {
118 	QFileInfo fi(webBrowserLineEdit->text());
119 	QString s = QFileDialog::getOpenFileName(this, tr("Locate your web browser"), fi.path());
120 	if (!s.isEmpty())
121 		webBrowserLineEdit->setText( QDir::toNativeSeparators(s) );
122 }
123 
changePDFViewer()124 void Prefs_ExternalTools::changePDFViewer()
125 {
126 	QFileInfo fi(pdfViewerLineEdit->text());
127 	QString s = QFileDialog::getOpenFileName(this, tr("Locate your PDF viewer"), fi.path());
128 	if (!s.isEmpty())
129 		pdfViewerLineEdit->setText( QDir::toNativeSeparators(s) );
130 }
131 
changeUniconvertor()132 void Prefs_ExternalTools::changeUniconvertor()
133 {
134 	QFileInfo fi(uniconvertorLineEdit->text());
135 	QString s = QFileDialog::getOpenFileName(this, tr("Locate the uniconvertor executable"), fi.path());
136 	if (!s.isEmpty())
137 		uniconvertorLineEdit->setText( QDir::toNativeSeparators(s) );
138 }
139 
changeLatexEditor()140 void Prefs_ExternalTools::changeLatexEditor()
141 {
142 	QFileInfo fi(latexEditorLineEdit->text());
143 	QString s = QFileDialog::getOpenFileName(this, tr("Locate your editor"), fi.path());
144 	if (!s.isEmpty())
145 	{
146 		s = QDir::toNativeSeparators(s);
147 		if (s.contains(' ') && !s.contains('"'))
148 			s = QString("\"%1\"").arg(s);
149 		latexEditorLineEdit->setText(s);
150 	}
151 }
152 
rescanForTools()153 void Prefs_ExternalTools::rescanForTools()
154 {
155 	if (!fileInPath(psToolLineEdit->text()))
156 	{
157 		QString gsDef = getGSDefaultExeName();
158 		psToolLineEdit->setText( QDir::toNativeSeparators(gsDef) );
159 	}
160 
161 	if (!fileInPath(imageToolLineEdit->text()))
162 		imageToolLineEdit->setText("gimp");
163 
164 	if (!fileInPath(uniconvertorLineEdit->text()))
165 	{
166 		if (fileInPath("uniconvertor"))
167 			uniconvertorLineEdit->setText("uniconvertor");
168 		else if (fileInPath("uniconv"))
169 			uniconvertorLineEdit->setText("uniconv");
170 		else
171 		{
172 			ScMessageBox::warning(nullptr, CommonStrings::trWarning, tr("Uniconvertor executable not found!"));
173 			uniconvertorLineEdit->setText("");
174 		}
175 	}
176 
177 	if (!fileInPath(latexEditorLineEdit->text()))
178 	{
179 		QStringList editors;
180 		editors <<
181 				/*Linux */ "kwrite" << "kate" << "gedit" << "gvim" <<
182 				/*Windows */ "notepad" <<
183 				/*Mac OS*/ "open";
184 		foreach (const QString& editor, editors)
185 		{
186 			if (fileInPath(editor))
187 			{
188 				latexEditorLineEdit->setText(editor);
189 				break;
190 			}
191 		}
192 	}
193 
194 	//Scan for render frame render applications
195 	for (int i=0; i < latexConfigsListWidget->count(); i++)
196 	{
197 		QString config(latexConfigsListWidget->item(i)->data(Qt::UserRole).toString());
198 		QString oldCommand = commands[config];
199 		if (config=="100_latex.xml")
200 		{
201 			if (!fileInPath(oldCommand))
202 			{
203 				QStringList pdflatexPaths;
204 #ifdef Q_OS_MAC
205 				pdflatexPaths	<<"/opt/local/bin/pdflatex"
206 								<<"/sw/bin/pdflatex"
207 								<<"/usr/local/texlive/2009/bin/universal-darwin/pdflatex"
208 								<<"/usr/local/texlive/2008/bin/universal-darwin/pdflatex";
209 #endif
210 #ifdef Q_OS_LINUX
211 				pdflatexPaths	<<"/usr/local/bin/pdflatex"
212 								<<"/usr/bin/pdflatex";
213 #endif
214 				QString parms(" --interaction nonstopmode");
215 				for (int i = 0; i < pdflatexPaths.size(); ++i) //do nothing when we have no paths.. need some more from other OSes
216 				{
217 					QString cmd(pdflatexPaths.at(i));
218 					QFileInfo fInfo(cmd);
219 					if (fInfo.exists())
220 					{
221 						cmd.append(parms);
222 						int ret = ScMessageBox::question(this, tr("LaTeX Command"),
223 								tr("Scribus has found the following pdflatex command:\n%1\nDo you want to use this?").arg(cmd),
224 								QMessageBox::Yes|QMessageBox::No,
225 								QMessageBox::No,	// GUI default
226 								QMessageBox::Yes);	// batch default
227 						if (ret==QMessageBox::Yes)
228 						{
229 							commands[config]=cmd;
230 							setConfigItemText(latexConfigsListWidget->item(i));
231 						}
232 					}
233 				}
234 			}
235 		}
236 	}
237 }
238 
upButtonPressed()239 void Prefs_ExternalTools::upButtonPressed()
240 {
241 	if (latexConfigsListWidget->currentRow() < 1)
242 		return;
243 	QListWidgetItem *old = latexConfigsListWidget->currentItem();
244 	QString config = old->data(Qt::UserRole).toString();
245 	insertConfigItem(config, latexConfigsListWidget->currentRow()-1);
246 	delete old;
247 }
248 
downButtonPressed()249 void Prefs_ExternalTools::downButtonPressed()
250 {
251 	if (latexConfigsListWidget->currentRow() >= latexConfigsListWidget->count()-1)
252 		return;
253 	QListWidgetItem *old = latexConfigsListWidget->currentItem();
254 	QString config = old->data(Qt::UserRole).toString();
255 	insertConfigItem(config, latexConfigsListWidget->currentRow()+2);
256 	delete old;
257 }
258 
addConfig()259 void Prefs_ExternalTools::addConfig()
260 {
261 	QString s = QFileDialog::getOpenFileName(this,
262 		tr("Locate a Configuration file"),
263 		LatexConfigParser::configBase(),
264 		tr("Configuration files")+" (*.xml)");
265 	if (!s.isEmpty())
266 		insertConfigItem(s);
267 }
268 
deleteConfig()269 void Prefs_ExternalTools::deleteConfig()
270 {
271 	if (latexConfigsListWidget->currentItem())
272 		delete latexConfigsListWidget->currentItem();
273 }
274 
changeLatexPath()275 void Prefs_ExternalTools::changeLatexPath()
276 {
277 	QListWidgetItem *item = latexConfigsListWidget->currentItem();
278 	QString config = item->data(Qt::UserRole).toString();
279 	//TODO: Better dialog
280 	QString oldCommand = commands[config];
281 	if (oldCommand.isEmpty())
282 		oldCommand = LatexConfigCache::instance()->parser(config)->executable();
283 	bool ok=false;
284 	QString newCommand = QInputDialog::getText(this, tr("Change Command"),
285 		tr("Enter new command: (leave empty to reset to default command; use quotes around arguments with spaces)"), QLineEdit::Normal, oldCommand, &ok);
286 	if (ok)
287 	{
288 		commands[config] = newCommand;
289 		setConfigItemText(item);
290 	}
291 }
292 
insertConfigItem(const QString & config,int row)293 void Prefs_ExternalTools::insertConfigItem(const QString& config, int row)
294 {
295 	QListWidgetItem *item = new QListWidgetItem();
296 	item->setData(Qt::UserRole, config);
297 	setConfigItemText(item);
298 	if (row == -1)
299 		latexConfigsListWidget->addItem(item);
300 	else
301 		latexConfigsListWidget->insertItem(row, item);
302 	latexConfigsListWidget->setCurrentItem(item);
303 }
304 
setConfigItemText(QListWidgetItem * item)305 void Prefs_ExternalTools::setConfigItemText(QListWidgetItem *item)
306 {
307 	QString config = item->data(Qt::UserRole).toString();
308 	QString description = LatexConfigCache::instance()->parser(config)->description();
309 	QString command = commands[config];
310 	if (command.isEmpty())
311 		item->setText(description);
312 	else
313 	{
314 		item->setText(QString("%1 (" + tr("Command: ") + "%2)" ).arg(description, QDir::toNativeSeparators(QDir::cleanPath(command))));
315 	}
316 }
317 
318