00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <iostream>
00026 #include <cstdlib>
00027
00028 #include <QString>
00029 #include <QFont>
00030 #include <QTranslator>
00031 #include <QFileInfo>
00032 #include <QFile>
00033 #include <QDir>
00034 #include <QTextCodec>
00035 #include <QLocale>
00036 #include <QTextStream>
00037
00038 #include "scribusapp.h"
00039 #include "scribuscore.h"
00040 #include "scpaths.h"
00041 #include "prefsfile.h"
00042 #include "langmgr.h"
00043 #include "prefsmanager.h"
00044 #include "commonstrings.h"
00045 #include "upgradechecker.h"
00046
00047 #if defined(_WIN32)
00048 #include <windows.h>
00049 #endif
00050
00051 #define ARG_VERSION "--version"
00052 #define ARG_HELP "--help"
00053 #define ARG_LANG "--lang"
00054 #define ARG_AVAILLANG "--langs-available"
00055 #define ARG_NOSPLASH "--no-splash"
00056 #define ARG_NEVERSPLASH "--never-splash"
00057 #define ARG_NOGUI "--no-gui"
00058 #define ARG_DISPLAY "--display"
00059 #define ARG_FONTINFO "--font-info"
00060 #define ARG_PROFILEINFO "--profile-info"
00061 #define ARG_SWAPDIABUTTONS "--swap-buttons"
00062 #define ARG_PREFS "--prefs"
00063 #define ARG_UPGRADECHECK "--upgradecheck"
00064
00065 #define ARG_VERSION_SHORT "-v"
00066 #define ARG_HELP_SHORT "-h"
00067 #define ARG_LANG_SHORT "-l"
00068 #define ARG_AVAILLANG_SHORT "-la"
00069 #define ARG_NOSPLASH_SHORT "-ns"
00070 #define ARG_NEVERSPLASH_SHORT "-nns"
00071 #define ARG_NOGUI_SHORT "-g"
00072 #define ARG_DISPLAY_SHORT "-d"
00073 #define ARG_FONTINFO_SHORT "-fi"
00074 #define ARG_PROFILEINFO_SHORT "-pi"
00075 #define ARG_SWAPDIABUTTONS_SHORT "-sb"
00076 #define ARG_PREFS_SHORT "-pr"
00077 #define ARG_UPGRADECHECK_SHORT "-u"
00078
00079
00080 #define ARG_DISPLAY_QT "-display"
00081
00082
00083 extern const char ARG_CONSOLE[] = "--console";
00084 extern const char ARG_CONSOLE_SHORT[] = "-cl";
00085
00086 extern ScribusQApp* ScQApp;
00087 extern ScribusCore* ScCore;
00088
00089 bool ScribusQApp::useGUI=false;
00090
00091 ScribusQApp::ScribusQApp( int & argc, char ** argv ) : QApplication(argc, argv),
00092 lang(""),
00093 GUILang("")
00094 {
00095 ScQApp=this;
00096 ScCore=NULL;
00097 }
00098
00099 ScribusQApp::~ScribusQApp()
00100 {
00101 PrefsManager::deleteInstance();
00102 }
00103
00104 void ScribusQApp::initLang()
00105 {
00106 QStringList langs = getLang(QString(lang));
00107
00108 if (!langs.isEmpty())
00109 installTranslators(langs);
00110 }
00111
00112 void ScribusQApp::parseCommandLine()
00113 {
00114 showSplash=!neverSplashExists();
00115 QString arg("");
00116 bool usage=false;
00117 bool header=false;
00118 bool availlangs=false;
00119 bool version=false;
00120 bool runUpgradeCheck=false;
00121 showFontInfo=false;
00122 showProfileInfo=false;
00123 swapDialogButtonOrder=false;
00124
00125
00126 for(int i = 1; i < argc(); i++)
00127 {
00128 arg = argv()[i];
00129
00130 if ((arg == ARG_LANG || arg == ARG_LANG_SHORT) && (++i < argc())) {
00131 lang = argv()[i];
00132 }
00133 else if (arg == ARG_VERSION || arg == ARG_VERSION_SHORT) {
00134 header=true;
00135 version=true;
00136 } else if (arg == ARG_HELP || arg == ARG_HELP_SHORT) {
00137 header=true;
00138 usage=true;
00139 } else if (arg == ARG_AVAILLANG || arg == ARG_AVAILLANG_SHORT) {
00140 header=true;
00141 availlangs=true;
00142 } else if (arg == ARG_UPGRADECHECK || arg == ARG_UPGRADECHECK_SHORT) {
00143 header=true;
00144 runUpgradeCheck=true;
00145 }
00146 }
00147
00148 initLang();
00149
00150 if (header)
00151 showHeader();
00152 if (version)
00153 showVersion();
00154 if (availlangs)
00155 showAvailLangs();
00156 if (usage)
00157 showUsage();
00158 if (runUpgradeCheck)
00159 {
00160 UpgradeChecker uc;
00161 uc.fetch();
00162 }
00163
00164 if (!header)
00165 useGUI=true;
00166 else
00167 return;
00168
00169 for(int i = 1; i < argc(); i++) {
00170 arg = argv()[i];
00171
00172 if ((arg == ARG_LANG || arg == ARG_LANG_SHORT) && (++i < argc())) {
00173 continue;
00174 } else if ( arg == ARG_CONSOLE || arg == ARG_CONSOLE_SHORT ) {
00175 continue;
00176 } else if (arg == ARG_NOSPLASH || arg == ARG_NOSPLASH_SHORT) {
00177 showSplash = false;
00178 }
00179 else if (arg == ARG_NEVERSPLASH || arg == ARG_NEVERSPLASH_SHORT) {
00180 showSplash = false;
00181 neverSplash(true);
00182 } else if (arg == ARG_NOGUI || arg == ARG_NOGUI_SHORT) {
00183 useGUI=false;
00184 } else if (arg == ARG_FONTINFO || arg == ARG_FONTINFO_SHORT) {
00185 showFontInfo=true;
00186 } else if (arg == ARG_PROFILEINFO || arg == ARG_PROFILEINFO_SHORT) {
00187 showProfileInfo=true;
00188 } else if (arg == ARG_SWAPDIABUTTONS || arg == ARG_SWAPDIABUTTONS_SHORT) {
00189 swapDialogButtonOrder=true;
00190 } else if ((arg == ARG_DISPLAY || arg==ARG_DISPLAY_SHORT || arg==ARG_DISPLAY_QT) && ++i < argc()) {
00191
00192
00193
00194 } else if (arg == ARG_PREFS || arg == ARG_PREFS_SHORT) {
00195 prefsUserFile = QFile::decodeName(argv()[i + 1]);
00196 if (!QFileInfo(prefsUserFile).exists()) {
00197 showHeader();
00198 if (file.left(1) == "-" || file.left(2) == "--") {
00199 std::cout << tr("Invalid argument: ").toLocal8Bit().data() << file.toLocal8Bit().data() << std::endl;
00200 } else {
00201 std::cout << tr("File %1 does not exist, aborting.").arg(file).toLocal8Bit().data() << std::endl;
00202 }
00203 showUsage();
00204 useGUI=false;
00205 return;
00206 } else {
00207 ++i;
00208 }
00209 } else if (strncmp(arg.toLocal8Bit().data(),"-psn_",4) == 0)
00210 {
00211
00212 } else {
00213 file = QFile::decodeName(argv()[i]);
00214 if (!QFileInfo(file).exists()) {
00215 showHeader();
00216 if (file.left(1) == "-" || file.left(2) == "--") {
00217 std::cout << tr("Invalid argument: %1").arg(file).toLocal8Bit().data() << std::endl;
00218 } else {
00219 std::cout << tr("File %1 does not exist, aborting.").arg(file).toLocal8Bit().data() << std::endl;
00220 }
00221 showUsage();
00222 useGUI=false;
00223 return;
00224 }
00225 }
00226 }
00227 }
00228
00229 int ScribusQApp::init()
00230 {
00231 m_ScCore=new ScribusCore();
00232 Q_CHECK_PTR(m_ScCore);
00233 if (!m_ScCore)
00234 return EXIT_FAILURE;
00235 ScCore=m_ScCore;
00236 processEvents();
00237 ScCore->init(useGUI, swapDialogButtonOrder, file);
00238 int retVal=EXIT_SUCCESS;
00239 if (useGUI)
00240 retVal=ScCore->startGUI(showSplash, showFontInfo, showProfileInfo, lang, prefsUserFile);
00241 return retVal;
00242 }
00243
00244 QStringList ScribusQApp::getLang(QString lang)
00245 {
00246 QStringList langs;
00247
00248
00249 if (!lang.isEmpty())
00250 langs.push_back(lang);
00251
00252
00253 QString Pff = QDir::convertSeparators(ScPaths::getApplicationDataDir());
00254 QFileInfo Pffi = QFileInfo(Pff);
00255 if (Pffi.exists())
00256 {
00257 QString PrefsPfad;
00258 if (Pffi.isDir())
00259 PrefsPfad = Pff;
00260 else
00261 PrefsPfad = QDir::homePath();
00262 QString prefsXMLFile=QDir::convertSeparators(PrefsPfad + "/prefs135.xml");
00263 QFileInfo infoPrefsFile(prefsXMLFile);
00264 if (infoPrefsFile.exists())
00265 {
00266 PrefsFile* prefsFile = new PrefsFile(prefsXMLFile);
00267 if (prefsFile) {
00268 PrefsContext* userprefsContext = prefsFile->getContext("user_preferences");
00269 if (userprefsContext) {
00270 QString prefslang = userprefsContext->get("gui_language","");
00271 if (!prefslang.isEmpty())
00272 langs.push_back(prefslang);
00273 }
00274 }
00275 delete prefsFile;
00276 }
00277 }
00278
00279 if (!(lang = ::getenv("LC_ALL")).isEmpty())
00280 langs.push_back(lang);
00281 if (!(lang = ::getenv("LC_MESSAGES")).isEmpty())
00282 langs.push_back(lang);
00283 if (!(lang = ::getenv("LANG")).isEmpty())
00284 langs.push_back(lang);
00285
00286 #if defined(_WIN32)
00287 wchar_t out[256];
00288 QString language, sublanguage;
00289 LCID lcIdo = GetUserDefaultLCID();
00290 WORD sortId = SORTIDFROMLCID(lcIdo);
00291 LANGID langId = GetUserDefaultUILanguage();
00292 LCID lcIdn = MAKELCID(langId, sortId);
00293 if ( GetLocaleInfoW(lcIdn, LOCALE_SISO639LANGNAME , out, 255) )
00294 {
00295 language = QString::fromUtf16( (ushort*)out );
00296 if ( GetLocaleInfoW(lcIdn, LOCALE_SISO3166CTRYNAME, out, 255) )
00297 {
00298 sublanguage = QString::fromUtf16( (ushort*)out ).toLower();
00299 lang = language;
00300 if ( sublanguage != language && !sublanguage.isEmpty() )
00301 lang += "_" + sublanguage.toUpper();
00302 langs.push_back(lang);
00303 }
00304 }
00305 #endif
00306
00307 langs.push_back(QString(QLocale::system().name()));
00308
00309
00310 QStringList::Iterator it = langs.end();
00311 while (it != langs.begin())
00312 {
00313 --it;
00314 if (langs.count(*it) > 1)
00315 it = langs.erase(it);
00316 }
00317
00318 return langs;
00319 }
00320
00321 void ScribusQApp::installTranslators(const QStringList & langs)
00322 {
00323 static QTranslator *trans = 0;
00324
00325 if ( trans )
00326 {
00327 removeTranslator( trans );
00328 delete trans;
00329 }
00330 trans = new QTranslator(0);
00331 QString path(ScPaths::instance().translationDir());
00332 path += "scribus";
00333
00334 bool loaded = false;
00335 QString lang;
00336 for (QStringList::const_iterator it = langs.constBegin(); it != langs.constEnd() && !loaded; ++it)
00337 {
00338 lang=(*it).left(5);
00339 if (lang == "en")
00340 {
00341 GUILang=lang;
00342 break;
00343 }
00344 else if (trans->load(QString(path + '.' + lang), "."))
00345 loaded = true;
00346 }
00347 if (loaded)
00348 {
00349 installTranslator(trans);
00350 GUILang=lang;
00351 }
00352 else if (lang == "en")
00353 GUILang=lang;
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368 }
00369
00370 void ScribusQApp::changeGUILanguage(const QString & newGUILang)
00371 {
00372 QStringList newLangs;
00373 if (newGUILang.isEmpty())
00374 {
00375 newLangs = getLang(QString());
00376 newLangs.append("en");
00377 }
00378 else
00379 newLangs.append(newGUILang);
00380 if (newLangs[0] != GUILang)
00381 installTranslators(newLangs);
00382 }
00383
00386 static void printArgLine(QTextStream & ts, const char * smallArg,
00387 const char* fullArg, const QString desc)
00388 {
00389 const char* lineformat = " %1, %2 %3";
00390 const int saw = 4;
00391 const int aw = -18;
00392 QString line = QString(lineformat)
00393 .arg(smallArg, saw)
00394 .arg(fullArg, aw)
00395 .arg(desc);
00396 ts << line;
00397 endl(ts);
00398 }
00399
00400 void ScribusQApp::showUsage()
00401 {
00402 QFile f;
00403 f.open(stderr, QIODevice::WriteOnly);
00404 QTextStream ts(&f);
00405 ts << tr("Usage: scribus [option ... ] [file]") ; endl(ts);
00406 ts << tr("Options:") ; endl(ts);
00407 printArgLine(ts, ARG_FONTINFO_SHORT, ARG_FONTINFO, tr("Show information on the console when fonts are being loaded") );
00408 printArgLine(ts, ARG_HELP_SHORT, ARG_HELP, tr("Print help (this message) and exit") );
00409 printArgLine(ts, ARG_LANG_SHORT, ARG_LANG, tr("Uses xx as shortcut for a language, eg `en' or `de'") );
00410 printArgLine(ts, ARG_AVAILLANG_SHORT, ARG_AVAILLANG, tr("List the currently installed interface languages") );
00411 printArgLine(ts, ARG_NOSPLASH_SHORT, ARG_NOSPLASH, tr("Do not show the splashscreen on startup") );
00412 printArgLine(ts, ARG_NEVERSPLASH_SHORT, ARG_NEVERSPLASH, tr("Stop the showing of the splashscreen on startup. Writes an empty file called .neversplash in ~/.scribus.") );
00413 printArgLine(ts, ARG_PREFS_SHORT, QString(QString(ARG_PREFS) + QString(" ") + tr("filename")).toLocal8Bit().constData(), tr("Use filename as path for user given preferences") );
00414 printArgLine(ts, ARG_PROFILEINFO_SHORT, ARG_PROFILEINFO, tr("Show location ICC profile information on console while starting") );
00415 printArgLine(ts, ARG_SWAPDIABUTTONS_SHORT, ARG_SWAPDIABUTTONS, tr("Use right to left dialog button ordering (eg. Cancel/No/Yes instead of Yes/No/Cancel)") );
00416 printArgLine(ts, ARG_UPGRADECHECK_SHORT, ARG_UPGRADECHECK, tr("Download a file from the Scribus website and show the latest available version.") );
00417 printArgLine(ts, ARG_VERSION_SHORT, ARG_VERSION, tr("Output version information and exit") );
00418
00419
00420 #if defined(_WIN32) && !defined(_CONSOLE)
00421 printArgLine(ts, ARG_CONSOLE_SHORT, ARG_CONSOLE, tr("Display a console window") );
00422 #endif
00423
00424
00425
00426
00427
00428 endl(ts);
00429 }
00430
00431 void ScribusQApp::showAvailLangs()
00432 {
00433 QFile f;
00434 f.open(stderr, QIODevice::WriteOnly);
00435 QTextStream ts(&f);
00436 ts << tr("Installed interface languages for Scribus are as follows:"); endl(ts);
00437 endl(ts);
00438
00439 LanguageManager langMgr;
00440 langMgr.init();
00441 langMgr.printInstalledList();
00442
00443 endl(ts);
00444 ts << tr("To override the default language choice:"); endl(ts);
00445 ts << tr("scribus -l xx or scribus --lang xx, where xx is the language of choice."); endl(ts);
00446 }
00447
00448 void ScribusQApp::showVersion()
00449 {
00450 std::cout << tr("Scribus Version").toLocal8Bit().data() << " " << VERSION << std::endl;
00451 }
00452
00453 void ScribusQApp::showHeader()
00454 {
00455 QFile f;
00456 f.open(stderr, QIODevice::WriteOnly);
00457 QTextStream ts(&f);
00458 endl(ts);
00459 QString heading( tr("Scribus, Open Source Desktop Publishing") );
00460
00461 QString separator = QString("").rightJustified(heading.length(),'-');
00462
00463 const int urlwidth = 23;
00464 const int descwidth = -(heading.length() - urlwidth - 1);
00465 ts << heading; endl(ts);
00466 ts << separator; endl(ts);
00467 ts << QString("%1 %2").arg( tr("Homepage")+":", descwidth).arg("http://www.scribus.net" ); endl(ts);
00468 ts << QString("%1 %2").arg( tr("Documentation")+":", descwidth).arg("http://docs.scribus.net"); endl(ts);
00469 ts << QString("%1 %2").arg( tr("Wiki")+":", descwidth).arg("http://wiki.scribus.net"); endl(ts);
00470 ts << QString("%1 %2").arg( tr("Issues")+":", descwidth).arg("http://bugs.scribus.net"); endl(ts);
00471 endl(ts);
00472 }
00473
00474 void ScribusQApp::neverSplash(bool splashOff)
00475 {
00476 QString prefsDir = ScPaths::getApplicationDataDir();
00477 QFile ns(prefsDir + ".neversplash");
00478 if (splashOff)
00479 {
00480 if (QFileInfo(QDir::homePath()).exists())
00481 {
00482 QDir prefsDirectory(prefsDir);
00483 if (!QFileInfo(prefsDir).exists())
00484 prefsDirectory.mkdir(prefsDir);
00485 if (!ns.exists() && ns.open(QIODevice::WriteOnly))
00486 ns.close();
00487 }
00488 }
00489 else
00490 {
00491 if (neverSplashExists())
00492 ns.remove();
00493 }
00494 }
00495
00496 bool ScribusQApp::neverSplashExists()
00497 {
00498 return QFileInfo(ScPaths::getApplicationDataDir() + ".neversplash").exists();
00499 }