Back to index

scribus-ng  1.3.4.dfsg+svn20071115
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.h>
00029 #include <qfont.h>
00030 #include <qtranslator.h>
00031 #include <qfileinfo.h>
00032 #include <qfile.h>
00033 #include <qdir.h>
00034 #include <qtextcodec.h>
00035 
00036 #include "scribusapp.h"
00037 #include "scribusapp.moc"
00038 #include "scribuscore.h"
00039 #include "scpaths.h"
00040 #include "prefsfile.h"
00041 #include "langmgr.h"
00042 #include "prefsmanager.h"
00043 #include "commonstrings.h"
00044 #include "upgradechecker.h"
00045 
00046 #if defined(_WIN32)
00047 #include <windows.h>
00048 #endif
00049 
00050 #define ARG_VERSION "--version"
00051 #define ARG_HELP "--help"
00052 #define ARG_LANG "--lang"
00053 #define ARG_AVAILLANG "--langs-available"
00054 #define ARG_NOSPLASH "--no-splash"
00055 #define ARG_NEVERSPLASH "--never-splash"
00056 #define ARG_NOGUI "--no-gui"
00057 #define ARG_DISPLAY "--display"
00058 #define ARG_FONTINFO "--font-info"
00059 #define ARG_PROFILEINFO "--profile-info"
00060 #define ARG_SWAPDIABUTTONS "--swap-buttons"
00061 #define ARG_PREFS "--prefs"
00062 #define ARG_UPGRADECHECK "--upgradecheck"
00063 
00064 #define ARG_VERSION_SHORT "-v"
00065 #define ARG_HELP_SHORT "-h"
00066 #define ARG_LANG_SHORT "-l"
00067 #define ARG_AVAILLANG_SHORT "-la"
00068 #define ARG_NOSPLASH_SHORT "-ns"
00069 #define ARG_NEVERSPLASH_SHORT "-nns"
00070 #define ARG_NOGUI_SHORT "-g"
00071 #define ARG_DISPLAY_SHORT "-d"
00072 #define ARG_FONTINFO_SHORT "-fi"
00073 #define ARG_PROFILEINFO_SHORT "-pi"
00074 #define ARG_SWAPDIABUTTONS_SHORT "-sb"
00075 #define ARG_PREFS_SHORT "-pr"
00076 #define ARG_UPGRADECHECK_SHORT "-u"
00077 
00078 // Qt wants -display not --display or -d
00079 #define ARG_DISPLAY_QT "-display"
00080 
00081 // Windows specific options, allows to display a console windows
00082 extern const char ARG_CONSOLE[] =  "--console";
00083 extern const char ARG_CONSOLE_SHORT[] = "-cl";
00084 
00085 extern ScribusQApp* ScQApp;
00086 extern ScribusCore* ScCore;
00087 
00088 bool ScribusQApp::useGUI=false;
00089 
00090 ScribusQApp::ScribusQApp( int & argc, char ** argv ) : QApplication(argc, argv),
00091        lang(""),
00092        GUILang("")
00093 {
00094        ScQApp=this;
00095        ScCore=NULL;
00096 }
00097 
00098 ScribusQApp::~ScribusQApp()
00099 {
00100        PrefsManager::deleteInstance();
00101 }
00102 
00103 void ScribusQApp::initLang()
00104 {
00105        QStringList langs = getLang(QString(lang));
00106 
00107        if (!langs.isEmpty())
00108               installTranslators(langs);
00109 }
00110 
00111 void ScribusQApp::parseCommandLine()
00112 {
00113        showSplash=!neverSplashExists();
00114        QString arg("");
00115        bool usage=false;
00116        bool header=false;
00117        bool availlangs=false;
00118        bool version=false;
00119        bool runUpgradeCheck=false;
00120        showFontInfo=false;
00121        showProfileInfo=false;
00122        swapDialogButtonOrder=false;
00123 
00124        //Parse for command line information options, and lang
00125        for(int i = 1; i < argc(); i++)
00126        {
00127               arg = argv()[i];
00128 
00129               if ((arg == ARG_LANG || arg == ARG_LANG_SHORT) && (++i < argc())) {
00130                      lang = argv()[i];
00131               }
00132               else if (arg == ARG_VERSION || arg == ARG_VERSION_SHORT) {
00133                      header=true;
00134                      version=true;
00135               } else if (arg == ARG_HELP || arg == ARG_HELP_SHORT) {
00136                      header=true;
00137                      usage=true;
00138               } else if (arg == ARG_AVAILLANG || arg == ARG_AVAILLANG_SHORT) {
00139                      header=true;
00140                      availlangs=true;
00141               } else if (arg == ARG_UPGRADECHECK || arg == ARG_UPGRADECHECK_SHORT) {
00142                      header=true;
00143                      runUpgradeCheck=true;
00144               }
00145        }
00146        //Init translations
00147        initLang();
00148        //Show command line help
00149        if (header)
00150               showHeader();
00151        if (version)
00152               showVersion();
00153        if (availlangs)
00154               showAvailLangs();
00155        if (usage)
00156               showUsage();
00157        if (runUpgradeCheck)
00158        {
00159               UpgradeChecker uc;
00160               bool error=uc.fetch();
00161               uc.show(error);
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: ").local8Bit() << file << std::endl;
00200                             } else {
00201                                    std::cout << tr("File %1 does not exist, aborting.").arg(file).local8Bit() << std::endl;
00202                             }
00203                             showUsage();
00204                             useGUI=false;
00205                             return;
00206                      } else {
00207                             ++i;
00208                      }
00209               } else if (strncmp(arg,"-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: ").local8Bit() << file << std::endl;
00218                             } else {
00219                                    std::cout << tr("File %1 does not exist, aborting.").arg(file).local8Bit() << 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::homeDirPath();
00262               QString prefsXMLFile=QDir::convertSeparators(PrefsPfad + "/prefs134.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::fromUcs2( (ushort*)out );
00296               if ( GetLocaleInfoW(lcIdn, LOCALE_SISO3166CTRYNAME, out, 255) )
00297               {
00298                      sublanguage = QString::fromUcs2( (ushort*)out ).lower();
00299                      lang = language;
00300                      if ( sublanguage != language && !sublanguage.isEmpty() )
00301                             lang += "_" + sublanguage.upper();
00302                      langs.push_back(lang);
00303               }
00304        }
00305 #endif
00306 
00307        langs.push_back(QString(QTextCodec::locale()));
00308 
00309        // remove duplicate entries...
00310        for (QStringList::Iterator it = langs.fromLast(); it != langs.begin(); --it)
00311               if (langs.contains(*it) > 1)
00312                      it = langs.remove(it);
00313 
00314        return langs;
00315 }
00316 
00317 void ScribusQApp::installTranslators(const QStringList & langs)
00318 {
00319        static QTranslator *trans = 0;
00320 
00321        if ( trans )
00322        {
00323               removeTranslator( trans );
00324               delete trans;
00325        }
00326        trans = new QTranslator(0);
00327        QString path(ScPaths::instance().translationDir());
00328        path += "scribus";
00329 
00330        bool loaded = false;
00331        QString lang;
00332        for (QStringList::const_iterator it = langs.constBegin(); it != langs.constEnd() && !loaded; ++it) 
00333        {
00334               lang=(*it).left(5);
00335               if (lang == "en")
00336                      break;
00337               else if (loaded = trans->load(QString(path + '.' + lang), "."))
00338                      loaded = true;
00339        }
00340        if (loaded)
00341        {
00342               installTranslator(trans);
00343               GUILang=lang;
00344        }
00345        /* CB TODO, currently disabled, because its broken broken broken
00346        path = ScPaths::instance().pluginDir();
00347        QDir dir(path , "*.*", QDir::Name, QDir::Files | QDir::NoSymLinks);
00348        if (dir.exists() && (dir.count() != 0)) {
00349               for (uint i = 0; i < dir.count(); ++i) {
00350                      QFileInfo file(path + dir[i]);
00351                      if ((file.extension(false).lower() == "qm")
00352                      && (file.extension(true).lower().left(5) == lang)) {
00353                             trans = new QTranslator(0);
00354                             trans->load(QString(path + dir[i]), ".");
00355                             installTranslator(trans);
00356                      }
00357               }
00358        }*/
00359 }
00360 
00361 void ScribusQApp::changeGUILanguage(const QString & newGUILang)
00362 {
00363        QStringList newLangs;
00364        if (newGUILang.isEmpty())
00365               newLangs.append("en");
00366        else
00367               newLangs.append(newGUILang);
00368        installTranslators(newLangs);
00369 }
00370 
00373 static void printArgLine(QTextStream & ts, const char * smallArg,
00374                                             const char* fullArg, const QString desc)
00375 {
00376        const char* lineformat = "  %1, %2 %3";
00377        const int saw = 4;   // Short argument width
00378        const int aw = -18;   // Argument width (negative is left aligned)
00379        QString line = QString(lineformat)
00380               .arg(smallArg, saw)
00381               .arg(fullArg, aw)
00382               .arg(desc);
00383        ts << line;
00384        endl(ts);
00385 }
00386 
00387 void ScribusQApp::showUsage()
00388 {
00389        QFile f;
00390        f.open(IO_WriteOnly, stderr);
00391        QTextStream ts(&f);
00392        ts << tr("Usage: scribus [option ... ] [file]") ; endl(ts);
00393        ts << tr("Options:") ; endl(ts);
00394        printArgLine(ts, ARG_FONTINFO_SHORT, ARG_FONTINFO, tr("Show information on the console when fonts are being loaded") );
00395        printArgLine(ts, ARG_HELP_SHORT, ARG_HELP, tr("Print help (this message) and exit") );
00396        printArgLine(ts, ARG_LANG_SHORT, ARG_LANG, tr("Uses xx as shortcut for a language, eg `en' or `de'") );
00397        printArgLine(ts, ARG_AVAILLANG_SHORT, ARG_AVAILLANG, tr("List the currently installed interface languages") );
00398        printArgLine(ts, ARG_NOSPLASH_SHORT, ARG_NOSPLASH, tr("Do not show the splashscreen on startup") );
00399        printArgLine(ts, ARG_NEVERSPLASH_SHORT, ARG_NEVERSPLASH, tr("Stop the showing of the splashscreen on startup. Writes an empty file called .neversplash in ~/.scribus.") );
00400        printArgLine(ts, ARG_PREFS_SHORT, QString(ARG_PREFS)+" "+ tr("filename"), tr("Use filename as path for user given preferences") );
00401        printArgLine(ts, ARG_PROFILEINFO_SHORT, ARG_PROFILEINFO, tr("Show location ICC profile information on console while starting") );
00402        printArgLine(ts, ARG_SWAPDIABUTTONS_SHORT, ARG_SWAPDIABUTTONS, tr("Use right to left dialog button ordering (eg. Cancel/No/Yes instead of Yes/No/Cancel)") );
00403        printArgLine(ts, ARG_UPGRADECHECK_SHORT, ARG_UPGRADECHECK, tr("Download a file from the Scribus website and show the latest available version.") );
00404        printArgLine(ts, ARG_VERSION_SHORT, ARG_VERSION, tr("Output version information and exit") );
00405        
00406        
00407 #if defined(_WIN32) && !defined(_CONSOLE)
00408        printArgLine(ts, ARG_CONSOLE_SHORT, ARG_CONSOLE, tr("Display a console window") );
00409 #endif
00410 /* Delete me?
00411        std::cout << "-file|-- name Open file 'name'" ; endl(ts);
00412        std::cout << "name          Open file 'name', the file name must not begin with '-'" ; endl(ts);
00413        std::cout << "QT specific options as -display ..." ; endl(ts);
00414 */
00415        endl(ts);
00416 }
00417 
00418 void ScribusQApp::showAvailLangs()
00419 {
00420        QFile f;
00421        f.open(IO_WriteOnly, stderr);
00422        QTextStream ts(&f);
00423        ts << tr("Installed interface languages for Scribus are as follows:"); endl(ts);
00424        endl(ts);
00425 
00426        LanguageManager langMgr;
00427        langMgr.init();
00428        langMgr.printInstalledList();
00429 
00430        endl(ts);
00431        ts << tr("To override the default language choice:"); endl(ts);
00432        ts << tr("scribus -l xx or scribus --lang xx, where xx is the language of choice."); endl(ts);
00433 }
00434 
00435 void ScribusQApp::showVersion()
00436 {
00437        std::cout << tr("Scribus Version").local8Bit() << " " << VERSION << std::endl;
00438 }
00439 
00440 void ScribusQApp::showHeader()
00441 {
00442        QFile f;
00443        f.open(IO_WriteOnly, stderr);
00444        QTextStream ts(&f);
00445        endl(ts);
00446        QString heading( tr("Scribus, Open Source Desktop Publishing") );
00447        // Build a separator of ----s the same width as the heading
00448        QString separator = QString("").rightJustify(heading.length(),'-');
00449        // Then output the heading, separator, and docs/www/etc info in an aligned table
00450        const int urlwidth = 23;
00451        const int descwidth = -(heading.length() - urlwidth - 1);
00452        ts << heading; endl(ts);
00453        ts << separator; endl(ts);
00454        ts << QString("%1 %2").arg( tr("Homepage")+":",      descwidth).arg("http://www.scribus.net" ); endl(ts);
00455        ts << QString("%1 %2").arg( tr("Documentation")+":", descwidth).arg("http://docs.scribus.net"); endl(ts);
00456        ts << QString("%1 %2").arg( tr("Wiki")+":",          descwidth).arg("http://wiki.scribus.net"); endl(ts);
00457        ts << QString("%1 %2").arg( tr("Issues")+":",        descwidth).arg("http://bugs.scribus.net"); endl(ts);
00458        endl(ts);
00459 }
00460 
00461 void ScribusQApp::neverSplash(bool splashOff)
00462 {
00463        QString prefsDir = ScPaths::getApplicationDataDir();
00464        QFile ns(prefsDir+"/.neversplash");
00465        if (splashOff)
00466        {
00467               if (QFileInfo(QDir::homeDirPath()).exists())
00468               {
00469                      QDir prefsDirectory(prefsDir);
00470                      if (!QFileInfo(prefsDir).exists())
00471                             prefsDirectory.mkdir(prefsDir);
00472                      if (!ns.exists() && ns.open(IO_WriteOnly))
00473                             ns.close();
00474               }
00475        }
00476        else
00477        {
00478               if (neverSplashExists())
00479                      ns.remove();
00480        }
00481 }
00482 
00483 bool ScribusQApp::neverSplashExists()
00484 {
00485        return QFileInfo(ScPaths::getApplicationDataDir() + ".neversplash").exists();
00486 }