Scribus Developer Documentation - API
logo-pen

Scribus Developer Documentation - API

scribusapp.cpp

Go to the documentation of this file.
00001 /*
00002 For general Scribus (>=1.3.2) copyright and licensing information please refer
00003 to the COPYING file provided with the program. Following this notice may exist
00004 a copyright and/or license notice that predates the release of Scribus 1.3.2
00005 for which a new license (GPL+exception) is in place.
00006 */
00007 /***************************************************************************
00008     begin                : May 2005
00009     copyright            : (C) 2005 by Craig Bradney
00010     email                : cbradney@zip.com.au
00011     copyright            : (C) 2001 by Franz Schmid
00012     email                : Franz.Schmid@altmuehlnet.de
00013 ***************************************************************************/
00014 
00015 /***************************************************************************
00016 *                                                                         *
00017 *   ScMW program is free software; you can redistribute it and/or modify  *
00018 *   it under the terms of the GNU General Public License as published by  *
00019 *   the Free Software Foundation; either version 2 of the License, or     *
00020 *   (at your option) any later version.                                   *
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 // Qt wants -display not --display or -d
00080 #define ARG_DISPLAY_QT "-display"
00081 
00082 // Windows specific options, allows to display a console windows
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     //Parse for command line information options, and lang
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     //Init translations
00148     initLang();
00149     //Show command line help
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     //Dont run the GUI init process called from main.cpp, and return
00164     if (!header)
00165         useGUI=true;
00166     else
00167         return;
00168     //We are going to run something other than command line help
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             // allow setting of display, QT expect the option -display <display_name> so we discard the
00192             // last argument. FIXME: Qt only understands -display not --display and -d , we need to work
00193             // around this.
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             // Andreas Vox: Qt/Mac has -psn_blah flags that must be accepted.
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     // read the locales
00249     if (!lang.isEmpty())
00250         langs.push_back(lang);
00251 
00252     //add in user preferences lang, only overridden by lang command line option
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     // remove duplicate entries...
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     /* CB TODO, currently disabled, because its broken broken broken
00355     path = ScPaths::instance().pluginDir();
00356     QDir dir(path , "*.*", QDir::Name, QDir::Files | QDir::NoSymLinks);
00357     if (dir.exists() && (dir.count() != 0)) {
00358         for (uint i = 0; i < dir.count(); ++i) {
00359             QFileInfo file(path + dir[i]);
00360             if ((file.extension(false).toLower() == "qm")
00361             && (file.extension(true).toLower().left(5) == lang)) {
00362                 trans = new QTranslator(0);
00363                 trans->load(QString(path + dir[i]), ".");
00364                 installTranslator(trans);
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;   // Short argument width
00391     const int aw = -18;   // Argument width (negative is left aligned)
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 /* Delete me?
00424     std::cout << "-file|-- name Open file 'name'" ; endl(ts);
00425     std::cout << "name          Open file 'name', the file name must not begin with '-'" ; endl(ts);
00426     std::cout << "QT specific options as -display ..." ; endl(ts);
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     // Build a separator of ----s the same width as the heading
00461     QString separator = QString("").rightJustified(heading.length(),'-');
00462     // Then output the heading, separator, and docs/www/etc info in an aligned table
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 }
Created with personalized Doxygen. This is documentation for GPL software Scribus - Open Source Desktop Publishing.