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 	begin                : May 2005
9 	copyright            : (C) 2005 by Craig Bradney
10 	email                : cbradney@zip.com.au
11 	copyright            : (C) 2001 by Franz Schmid
12 	email                : Franz.Schmid@altmuehlnet.de
13 ***************************************************************************/
14 
15 /***************************************************************************
16 *                                                                         *
17 *   Scribus program is free software; you can redistribute it and/or modify  *
18 *   it under the terms of the GNU General Public License as published by  *
19 *   the Free Software Foundation; either version 2 of the License, or     *
20 *   (at your option) any later version.                                   *
21 *                                                                         *
22 ***************************************************************************/
23 
24 #include <iostream>
25 #include <cstdlib>
26 
27 
28 #include <QDir>
29 #include <QFile>
30 #include <QFileInfo>
31 #include <QFont>
32 #include <QLibraryInfo>
33 #include <QLocale>
34 #include <QString>
35 #include <QStringList>
36 #include <QTextCodec>
37 #include <QTextStream>
38 #include <QTranslator>
39 
40 #include "scribusapp.h"
41 
42 #include "commonstrings.h"
43 #include "downloadmanager/scdlmgr.h"
44 #include "iconmanager.h"
45 #include "langmgr.h"
46 #include "localemgr.h"
47 #include "prefsfile.h"
48 #include "prefsmanager.h"
49 #include "scpaths.h"
50 #include "scribuscore.h"
51 #include "upgradechecker.h"
52 #include "util.h"
53 
54 #ifdef WITH_TESTS
55 #include "tests/runtests.h"
56 #endif
57 
58 #if defined(_WIN32)
59 #include <windows.h>
60 #endif
61 
62 #define ARG_VERSION "--version"
63 #define ARG_HELP "--help"
64 #define ARG_LANG "--lang"
65 #define ARG_AVAILLANG "--langs-available"
66 #define ARG_NOSPLASH "--no-splash"
67 #define ARG_NEVERSPLASH "--never-splash"
68 #define ARG_NOGUI "--no-gui"
69 #define ARG_DISPLAY "--display"
70 #define ARG_FONTINFO "--font-info"
71 #define ARG_PROFILEINFO "--profile-info"
72 #define ARG_PREFS "--prefs"
73 #define ARG_UPGRADECHECK "--upgradecheck"
74 #define ARG_TESTS "--tests"
75 #define ARG_PYTHONSCRIPT "--python-script"
76 #define CMD_OPTIONS_END "--"
77 
78 #define ARG_VERSION_SHORT "-v"
79 #define ARG_HELP_SHORT "-h"
80 #define ARG_LANG_SHORT "-l"
81 #define ARG_AVAILLANG_SHORT "-la"
82 #define ARG_NOSPLASH_SHORT "-ns"
83 #define ARG_NEVERSPLASH_SHORT "-nns"
84 #define ARG_NOGUI_SHORT "-g"
85 #define ARG_DISPLAY_SHORT "-d"
86 #define ARG_FONTINFO_SHORT "-fi"
87 #define ARG_PROFILEINFO_SHORT "-pi"
88 #define ARG_PREFS_SHORT "-pr"
89 #define ARG_UPGRADECHECK_SHORT "-u"
90 #define ARG_TESTS_SHORT "-T"
91 #define ARG_PYTHONSCRIPT_SHORT "-py"
92 
93 // Qt wants -display not --display or -d
94 #define ARG_DISPLAY_QT "-display"
95 
96 // Windows specific options, allows to display a console windows
97 extern const char ARG_CONSOLE[] =  "--console";
98 extern const char ARG_CONSOLE_SHORT[] = "-cl";
99 
100 bool ScribusQApp::useGUI = false;
101 
ScribusQApp(int & argc,char ** argv)102 ScribusQApp::ScribusQApp( int & argc, char ** argv ) : QApplication(argc, argv)
103 {
104 	ScQApp = this;
105 	ScCore = nullptr;
106 	initDLMgr();
107 	setAttribute(Qt::AA_UseHighDpiPixmaps, true);
108 }
109 
~ScribusQApp()110 ScribusQApp::~ScribusQApp()
111 {
112 	delete m_ScCore;
113 	delete m_scDLMgr;
114 	LanguageManager::deleteInstance();
115 }
116 
initLang()117 void ScribusQApp::initLang()
118 {
119 	QStringList langs = getLang(QString(m_lang));
120 
121 	if (!langs.isEmpty())
122 		installTranslators(langs);
123 }
124 
initDLMgr()125 void ScribusQApp::initDLMgr()
126 {
127 	m_scDLMgr = new ScDLManager(this);
128 	//connect(m_scDLMgr, SIGNAL(fileReceived(const QString&)), SLOT(downloadComplete(const QString&)));
129 }
130 
parseCommandLine()131 void ScribusQApp::parseCommandLine()
132 {
133 	m_showSplash=!neverSplashExists();
134 	QString arg;
135 	bool usage = false;
136 	bool header = false;
137 	bool availlangs = false;
138 	bool version = false;
139 	bool runUpgradeCheck = false;
140 #ifdef WITH_TESTS
141 	bool runtests = false;
142 	char** testargsv;
143 	int testargsc;
144 #endif
145 	m_showFontInfo = false;
146 	m_showProfileInfo = false;
147 	bool neversplash = false;
148 
149 	//Parse for command line options
150 	// Qt5 port: do this in a Qt compatible manner
151 	QStringList args = arguments();
152 	int argsc = args.count();
153 
154 	useGUI = true;
155 	int argi = 1;
156 	for ( ; argi < argsc; argi++)
157 	{ //handle options (not positional parameters)
158 		arg = args[argi];
159 		if (arg == ARG_PYTHONSCRIPT || arg == ARG_PYTHONSCRIPT_SHORT)
160 		{
161 			if (argi + 1 == argsc)
162 			{
163 				std::cout << tr("Option %1 requires an argument.").arg(arg).toLocal8Bit().data() << std::endl;
164 				std::exit(EXIT_FAILURE);
165 			}
166 			pythonScript = QFile::decodeName(args[argi + 1].toLocal8Bit());
167 			if (!QFileInfo::exists(pythonScript))
168 			{
169 				std::cout << tr("Python script %1 does not exist, aborting.").arg(pythonScript).toLocal8Bit().data() << std::endl;
170 				std::exit(EXIT_FAILURE);
171 			}
172 			++argi;
173 
174 			while (++argi < argsc && (args[argi] != CMD_OPTIONS_END))
175 			{
176 				pythonScriptArgs.append(args[argi]); // script argument
177 			}
178 			// We reached end of all arguments or CMD_OPTIONS_END marker. Stop parsing options
179 			if (argi < argsc)
180 			{
181 				argi++; // skip CMD_OPTIONS_END
182 			}
183 			break;
184 		}
185 		if ((arg == ARG_LANG || arg == ARG_LANG_SHORT))
186 		{
187 			if  (++argi < argsc)
188 				m_lang = args[argi];
189 			else
190 			{
191 				std::cout << tr("Option %1 requires an argument.").arg(arg).toLocal8Bit().data() << std::endl;
192 				std::exit(EXIT_FAILURE);
193 			}
194 		}
195 		else if (arg == ARG_VERSION || arg == ARG_VERSION_SHORT)
196 		{
197 			header = true;
198 			version = true;
199 		}
200 		else if (arg == ARG_HELP || arg == ARG_HELP_SHORT)
201 		{
202 			header = true;
203 			usage = true;
204 		}
205 #ifdef WITH_TESTS
206 		else if (arg == ARG_TESTS || arg == ARG_TESTS_SHORT)
207 		{
208 			header = true;
209 			runtests = true;
210 			testargsc = argc() - argi;
211 			testargsv = argv() + argi;
212 			break;
213 		}
214 #endif
215 		else if (arg == ARG_AVAILLANG || arg == ARG_AVAILLANG_SHORT)
216 		{
217 			header = true;
218 			availlangs = true;
219 		}
220 		else if (arg == ARG_UPGRADECHECK || arg == ARG_UPGRADECHECK_SHORT)
221 		{
222 			header = true;
223 			runUpgradeCheck = true;
224 		}
225 		else if (arg == ARG_CONSOLE || arg == ARG_CONSOLE_SHORT)
226 		{
227 			continue;
228 		}
229 		else if (arg == ARG_NOSPLASH || arg == ARG_NOSPLASH_SHORT)
230 		{
231 			m_showSplash = false;
232 		}
233 		else if (arg == ARG_NEVERSPLASH || arg == ARG_NEVERSPLASH_SHORT)
234 		{
235 			m_showSplash = false;
236 			neversplash = true;
237 		}
238 		else if (arg == ARG_NOGUI || arg == ARG_NOGUI_SHORT)
239 		{
240 			useGUI = false;
241 		}
242 		else if (arg == ARG_FONTINFO || arg == ARG_FONTINFO_SHORT)
243 		{
244 			m_showFontInfo = true;
245 		}
246 		else if (arg == ARG_PROFILEINFO || arg == ARG_PROFILEINFO_SHORT)
247 		{
248 			m_showProfileInfo = true;
249 		}
250 		else if ((arg == ARG_DISPLAY || arg == ARG_DISPLAY_SHORT || arg == ARG_DISPLAY_QT) && ++argi < argsc)
251 		{
252 			// allow setting of display, QT expect the option -display <display_name> so we discard the
253 			// last argument. FIXME: Qt only understands -display not --display and -d , we need to work
254 			// around this.
255 		}
256 		else if (arg == ARG_PREFS || arg == ARG_PREFS_SHORT)
257 		{
258 			if (argi + 1 == argsc)
259 			{
260 				std::cout << tr("Option %1 requires an argument.").arg(arg).toLocal8Bit().data() << std::endl;
261 				std::exit(EXIT_FAILURE);
262 			}
263 			m_prefsUserDir = QFile::decodeName(args[argi + 1].toLocal8Bit());
264 			if (!m_prefsUserDir.endsWith("/"))
265 				m_prefsUserDir.append('/');
266 			if (!QDir(m_prefsUserDir).exists())
267 			{
268 				std::cout << tr("Preferences directory %1 does not exist, aborting.").arg(m_prefsUserDir).toLocal8Bit().data() << std::endl;
269 				std::exit(EXIT_FAILURE);
270 			} else {
271 				++argi;
272 			}
273 		}
274 		else if (strncmp(arg.toLocal8Bit().data(), "-psn_", 4) == 0)
275 		{
276 			// Andreas Vox: Qt/Mac has -psn_blah flags that must be accepted.
277 		}
278 		else if (arg == CMD_OPTIONS_END)
279 		{ //double dash, indicates end of command line options, see http://unix.stackexchange.com/questions/11376/what-does-double-dash-mean-also-known-as-bare-double-dash
280 			argi++;
281 			break;
282 		}
283 		else
284 		{ //argument is not a known option, but either positional parameter or invalid.
285 			if (arg.at(0) == "-")
286 			{
287 				std::cout << tr("Invalid argument: %1").arg(arg).toLocal8Bit().data() << std::endl;
288 				std::exit(EXIT_FAILURE);
289 			}
290 			m_fileName = QFile::decodeName(args[argi].toLocal8Bit());
291 			if (!QFileInfo::exists(m_fileName))
292 			{
293 				std::cout << tr("File %1 does not exist, aborting.").arg(m_fileName).toLocal8Bit().data() << std::endl;
294 				std::exit(EXIT_FAILURE);
295 			}
296 			else
297 			{
298 				m_filesToLoad.append(m_fileName);
299 			}
300 		}
301 	}
302 	// parse for remaining (positional) arguments, if any
303 	for ( ; argi<argsc; argi++)
304 	{
305 		m_fileName = QFile::decodeName(args[argi].toLocal8Bit());
306 		if (!QFileInfo::exists(m_fileName))
307 		{
308 			std::cout << tr("File %1 does not exist, aborting.").arg(m_fileName).toLocal8Bit().data() << std::endl;
309 			std::exit(EXIT_FAILURE);
310 		}
311 		else
312 		{
313 			m_filesToLoad.append(m_fileName);
314 		}
315 	}
316 	//Init translations
317 	initLang();
318 
319 	//Show command line info
320 	if (header)
321 	{
322 		useGUI = false;
323 		showHeader();
324 	}
325 	if (version)
326 		showVersion();
327 	if (availlangs)
328 		showAvailLangs();
329 	if (usage)
330 		showUsage();
331 #ifdef WITH_TESTS
332 	if (runtests)
333 		RunTests::runTests(testargsc, testargsv);
334 #endif
335 	if (runUpgradeCheck)
336 	{
337 		UpgradeChecker uc;
338 		uc.fetch();
339 	}
340 	//Don't run the GUI init process called from main.cpp, and return
341 	if (header)
342 		std::exit(EXIT_SUCCESS);
343 	//proceed
344 	if (neversplash)
345 		neverSplash(true);
346 
347 }
348 
init()349 int ScribusQApp::init()
350 {
351 	m_ScCore = new ScribusCore();
352 	Q_CHECK_PTR(m_ScCore);
353 	if (!m_ScCore)
354 		return EXIT_FAILURE;
355 	ScCore = m_ScCore;
356 	processEvents(QEventLoop::ExcludeUserInputEvents|QEventLoop::ExcludeSocketNotifiers, 1000);
357 	ScCore->init(useGUI, m_filesToLoad);
358 	processEvents();
359 	/* TODO:
360 	 * When Scribus is truly able to run without GUI
361 	 * we should uncomment if (useGUI)
362 	 * and delete if (true)
363 	 */
364 	// if (useGUI)
365 	int retVal = ScCore->startGUI(m_showSplash, m_showFontInfo, m_showProfileInfo, m_lang);
366 	// A hook for plugins and scripts to trigger on. Some plugins and scripts
367 	// require the app to be fully set up (in particular, the main window to be
368 	// built and shown) before running their setup.
369 	emit appStarted();
370 
371 	return retVal;
372 }
373 
getLang(QString lang)374 QStringList ScribusQApp::getLang(QString lang)
375 {
376 	QStringList langs;
377 
378 	// read the locales
379 	if (!lang.isEmpty())
380 		langs.append(lang);
381 
382 	//add in user preferences lang, only overridden by lang command line option
383 	QString Pff = QDir::toNativeSeparators(ScPaths::preferencesDir());
384 	QFileInfo Pffi(Pff);
385 	if (Pffi.exists())
386 	{
387 		QString PrefsPfad;
388 		if (Pffi.isDir())
389 			PrefsPfad = Pff;
390 		else
391 			PrefsPfad = ScPaths::preferencesDir();
392 		QString prefsXMLFile = QDir::toNativeSeparators(PrefsPfad + "prefs150.xml");
393 		QFileInfo infoPrefsFile(prefsXMLFile);
394 		if (infoPrefsFile.exists())
395 		{
396 			PrefsFile* prefsFile = new PrefsFile(prefsXMLFile);
397 			if (prefsFile)
398 			{
399 				PrefsContext* userprefsContext = prefsFile->getContext("user_preferences");
400 				if (userprefsContext)
401 				{
402 					QString prefslang(cleanupLang(userprefsContext->get("gui_language", "")));
403 					if (!prefslang.isEmpty())
404 						langs.append(prefslang);
405 				}
406 			}
407 			delete prefsFile;
408 		}
409 	}
410 
411 	if (!(lang = ::getenv("LANG")).isEmpty())
412 	{
413 		lang = cleanupLang(lang);
414 		if (lang == "C")
415 			lang = "en";
416 		if (!lang.isEmpty())
417 			langs.append(lang);
418 	}
419 	if (!(lang = ::getenv("LC_MESSAGES")).isEmpty())
420 	{
421 		lang = cleanupLang(lang);
422 		if (lang == "C")
423 			lang = "en";
424 		if (!lang.isEmpty())
425 			langs.append(lang);
426 	}
427 	if (!(lang = ::getenv("LC_ALL")).isEmpty())
428 	{
429 		lang = cleanupLang(lang);
430 		if (lang == "C")
431 			lang = "en";
432 		if (!lang.isEmpty())
433 			langs.append(lang);
434 	}
435 
436 #if defined(_WIN32)
437 	wchar_t out[256];
438 	QString language, sublanguage;
439 	LCID lcIdo = GetUserDefaultLCID();
440 	WORD sortId = SORTIDFROMLCID(lcIdo);
441 	LANGID langId = GetUserDefaultUILanguage();
442 	LCID lcIdn = MAKELCID(langId, sortId);
443 	if (GetLocaleInfoW(lcIdn, LOCALE_SISO639LANGNAME , out, 255))
444 	{
445 		language = QString::fromUtf16( (ushort*)out );
446 		if (GetLocaleInfoW(lcIdn, LOCALE_SISO3166CTRYNAME, out, 255))
447 		{
448 			sublanguage = QString::fromUtf16( (ushort*)out ).toLower();
449 			lang = language;
450 			if (sublanguage != language && !sublanguage.isEmpty() )
451 				lang += "_" + sublanguage.toUpper();
452 			langs.append(lang);
453 		}
454 	}
455 #endif
456 
457 	langs.append(QLocale::system().name());
458 
459 	// remove duplicate entries...
460 	QStringList::Iterator it = langs.end();
461 	while (it != langs.begin())
462 	{
463 		--it;
464 		if (langs.count(*it) > 1)
465 			it = langs.erase(it);
466 	}
467 	return langs;
468 }
469 
installTranslators(const QStringList & langs)470 void ScribusQApp::installTranslators(const QStringList & langs)
471 {
472 	static QTranslator *transQt = nullptr;
473 	static QTranslator *trans = nullptr;
474 
475 	if (transQt)
476 	{
477 		removeTranslator( transQt );
478 		delete transQt;
479 		transQt = nullptr;
480 	}
481 	if (trans)
482 	{
483 		removeTranslator( trans );
484 		delete trans;
485 		trans = nullptr;
486 	}
487 
488 	transQt = new QTranslator(nullptr);
489 	trans = new QTranslator(nullptr);
490 	QString path(ScPaths::instance().translationDir());
491 
492 	bool loadedQt = false;
493 	bool loadedScribus = false;
494 	QString lang;
495 	for (QStringList::const_iterator it = langs.constBegin(); it != langs.constEnd() && !loadedScribus; ++it)
496 	{
497 		lang=(*it);
498 		if (lang == "en")
499 		{
500 			m_GUILang=lang;
501 			break;
502 		}
503 
504 		//CB: This might need adjusting for qm files distribution locations
505 		if (transQt->load("qt_" + lang,	QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
506 			loadedQt = true;
507 		if (trans->load(QString("scribus." + lang), path))
508 			loadedScribus = true;
509 		if (!loadedScribus)
510 		{
511 			QString altLang(LanguageManager::instance()->getAlternativeAbbrevfromAbbrev(lang));
512 			if (!altLang.isEmpty())
513 				if (trans->load(QString("scribus." + altLang), path))
514 					loadedScribus = true;
515 		}
516 	}
517 	if (loadedQt)
518 		installTranslator(transQt);
519 	if (loadedScribus)
520 	{
521 		installTranslator(trans);
522 		m_GUILang = lang;
523 	}
524 	else if (lang == "en")
525 		m_GUILang = lang;
526 	/* CB TODO, currently disabled, because its broken broken broken
527 	path = ScPaths::instance().pluginDir();
528 	QDir dir(path , "*.*", QDir::Name, QDir::Files | QDir::NoSymLinks);
529 	if (dir.exists() && (dir.count() != 0))
530 	{
531 		for (uint i = 0; i < dir.count(); ++i)
532 		{
533 			QFileInfo file(path + dir[i]);
534 			if ((file.extension(false).toLower() == "qm")
535 			&& (file.extension(true).toLower().left(5) == lang))
536 			{
537 				trans = new QTranslator(0);
538 				trans->load(QString(path + dir[i]), ".");
539 				installTranslator(trans);
540 			}
541 		}
542 	}*/
543 }
544 
changeGUILanguage(const QString & newGUILang)545 void ScribusQApp::changeGUILanguage(const QString & newGUILang)
546 {
547 	QStringList newLangs;
548 	if (newGUILang.isEmpty())
549 	{
550 		newLangs = getLang(QString());
551 		newLangs.append("en");
552 	}
553 	else
554 		newLangs.append(newGUILang);
555 	if (newLangs[0] != m_GUILang)
556 		installTranslators(newLangs);
557 }
558 
changeIconSet(const QString & newIconSet)559 void ScribusQApp::changeIconSet(const QString& newIconSet)
560 {
561 	IconManager& iconManager = IconManager::instance();
562 	iconManager.clearCache();
563 	iconManager.setActiveFromPrefs(newIconSet);
564 	emit iconSetChanged();
565 }
566 
setLocale()567 void ScribusQApp::setLocale()
568 {
569 	QLocale::setDefault(LocaleManager::instance().userPreferredLocale());
570 	emit localeChanged();
571 }
572 
573 /*! \brief Format an arguments line for printing
574 Helper procedure */
printArgLine(QTextStream & ts,const char * smallArg,const char * fullArg,const QString & desc)575 static void printArgLine(QTextStream & ts, const char * smallArg, const char* fullArg, const QString& desc)
576 {
577 	ts << QString("     %1 %2 %3").arg(QString("%1,").arg(smallArg), -5).arg(fullArg, -32).arg(desc);
578 	Qt::endl(ts);
579 }
580 
showUsage()581 void ScribusQApp::showUsage()
582 {
583 	QFile f;
584 	f.open(stderr, QIODevice::WriteOnly);
585 	QTextStream ts(&f);
586 	ts << tr("Usage: scribus [options] [files]") ; Qt::endl(ts); Qt::endl(ts);
587 	ts << tr("Options:") ; Qt::endl(ts);
588 	printArgLine(ts, ARG_FONTINFO_SHORT, ARG_FONTINFO, tr("Show information on the console when fonts are being loaded") );
589 	printArgLine(ts, ARG_HELP_SHORT, ARG_HELP, tr("Print help (this message) and exit") );
590 	printArgLine(ts, ARG_LANG_SHORT, ARG_LANG, tr("Uses xx as shortcut for a language, eg `en' or `de'") );
591 	printArgLine(ts, ARG_AVAILLANG_SHORT, ARG_AVAILLANG, tr("List the currently installed interface languages") );
592 	printArgLine(ts, ARG_NOSPLASH_SHORT, ARG_NOSPLASH, tr("Do not show the splashscreen on startup") );
593 	printArgLine(ts, ARG_NEVERSPLASH_SHORT, ARG_NEVERSPLASH, tr("Stop showing the splashscreen on startup. Writes an empty file called .neversplash in ~/.config/scribus") );
594 	printArgLine(ts, ARG_PREFS_SHORT, qPrintable(QString("%1 <%2>").arg(ARG_PREFS, tr("path"))), tr("Use path for user given preferences location") );
595 	printArgLine(ts, ARG_PROFILEINFO_SHORT, ARG_PROFILEINFO, tr("Show location of ICC profile information on console while starting") );
596 	printArgLine(ts, ARG_UPGRADECHECK_SHORT, ARG_UPGRADECHECK, tr("Download a file from the Scribus website and show the latest available version") );
597 	printArgLine(ts, ARG_VERSION_SHORT, ARG_VERSION, tr("Output version information and exit") );
598 	printArgLine(ts, ARG_PYTHONSCRIPT_SHORT, qPrintable(QString("%1 <%2> [%3] ").arg(ARG_PYTHONSCRIPT, tr("script"), tr("arguments ..."))), tr("Run script in Python [with optional arguments]. This option must be last option used") );
599 	printArgLine(ts, ARG_NOGUI_SHORT, ARG_NOGUI, tr("Do not start GUI") );
600 	ts << (QString("     %1").arg(CMD_OPTIONS_END,-39)) << tr("Explicit end of command line options"); Qt::endl(ts);
601 
602 
603 #if defined(_WIN32) && !defined(_CONSOLE)
604 	printArgLine(ts, ARG_CONSOLE_SHORT, ARG_CONSOLE, tr("Display a console window") );
605 #endif
606 
607 #if WITH_TESTS
608 	printArgLine(ts, ARG_TESTS_SHORT, ARG_TESTS, tr("Run unit tests and exit") );
609 #endif
610 
611 /* Delete me?
612 	std::cout << "-file|-- name Open file 'name'" ; endl(ts);
613 	std::cout << "name          Open file 'name', the file name must not begin with '-'" ; endl(ts);
614 	std::cout << "QT specific options as -display ..." ; endl(ts);
615 */
616 	Qt::endl(ts);
617 	f.close();
618 }
619 
showAvailLangs()620 void ScribusQApp::showAvailLangs()
621 {
622 	QFile f;
623 	if (!f.open(stderr, QIODevice::WriteOnly))
624 		return;
625 
626 	QTextStream ts(&f);
627 	ts << tr("Installed interface languages for Scribus are as follows:") << Qt::endl;
628 	Qt::endl(ts);
629 
630 	LanguageManager::instance()->printInstalledList();
631 	Qt::endl(ts);
632 
633 	ts << tr("To override the default language choice:") << Qt::endl;
634 	ts << tr("scribus -l xx or scribus --lang xx, where xx is the language of choice.") << Qt::endl;
635 }
636 
showVersion()637 void ScribusQApp::showVersion()
638 {
639 	std::cout << tr("Scribus Version").toLocal8Bit().data() << " " << VERSION << std::endl;
640 }
641 
showHeader()642 void ScribusQApp::showHeader()
643 {
644 	QFile f;
645 	f.open(stderr, QIODevice::WriteOnly);
646 	QTextStream ts(&f);
647 	ts << Qt::endl;
648 	QString heading( tr("Scribus, Open Source Desktop Publishing") );
649 	// Build a separator of ----s the same width as the heading
650 	QString separator = QString("").rightJustified(heading.length(),'-');
651 	// Then output the heading, separator, and docs/www/etc info in an aligned table
652 	const int urlwidth = 23;
653 	const int descwidth = -(heading.length() - urlwidth - 1);
654 	ts << heading << Qt::endl;
655 	ts << separator << Qt::endl;
656 	ts << QString("%1 %2").arg( tr("Homepage") + ":",      descwidth).arg("http://www.scribus.net" ) << Qt::endl;
657 	ts << QString("%1 %2").arg( tr("Documentation") + ":", descwidth).arg("http://docs.scribus.net") << Qt::endl;
658 	ts << QString("%1 %2").arg( tr("Wiki") + ":",          descwidth).arg("http://wiki.scribus.net") << Qt::endl;
659 	ts << QString("%1 %2").arg( tr("Issues") + ":",        descwidth).arg("http://bugs.scribus.net") << Qt::endl;
660 	ts << Qt::endl;
661 }
662 
neverSplash(bool splashOff)663 void ScribusQApp::neverSplash(bool splashOff)
664 {
665 	QString prefsDir = ScPaths::preferencesDir(true);
666 	QFile nsFile(prefsDir + ".neversplash");
667 	if (splashOff)
668 	{
669 		if (!nsFile.exists() && nsFile.open(QIODevice::WriteOnly))
670 			nsFile.close();
671 	}
672 	else
673 	{
674 		if (neverSplashExists())
675 			nsFile.remove();
676 	}
677 }
678 
neverSplashExists()679 bool ScribusQApp::neverSplashExists()
680 {
681 	return QFileInfo::exists(ScPaths::preferencesDir() + ".neversplash");
682 }
683 
downloadComplete(const QString & t)684 void ScribusQApp::downloadComplete(const QString &t)
685 {
686 	Q_UNUSED(t)
687 	//qDebug()<<"ScribusQApp: download finished:"<<t;
688 }
689 
event(QEvent * event)690 bool ScribusQApp::event(QEvent *event)
691 {
692 	switch (event->type())
693 	{
694 	case QEvent::FileOpen:
695 		{
696 			QString filename = static_cast<QFileOpenEvent*>(event)->file();
697 			if(m_ScCore && m_ScCore->initialized())
698 			{
699 				ScribusMainWindow* mw = m_ScCore->primaryMainWindow();
700 				mw->loadDoc(filename);
701 			}
702 			else
703 			{
704 				m_filesToLoad.append(filename);
705 			}
706 			return true;
707 		}
708 	default:
709 		return QApplication::event(event);
710 	}
711 }
712