QTfrontend/main.cpp
branchios-develop
changeset 13413 ba39a1d396c0
parent 13304 5ac2bdefa173
child 13516 d44ca1f04bbe
equal deleted inserted replaced
13411:6e8b807bda4b 13413:ba39a1d396c0
    18 
    18 
    19 #include "HWApplication.h"
    19 #include "HWApplication.h"
    20 
    20 
    21 #include <QTranslator>
    21 #include <QTranslator>
    22 #include <QLocale>
    22 #include <QLocale>
    23 #include <QPlastiqueStyle>
       
    24 #include <QRegExp>
    23 #include <QRegExp>
    25 #include <QMap>
    24 #include <QMap>
    26 #include <QSettings>
    25 #include <QSettings>
    27 #include <QStringListModel>
    26 #include <QStringListModel>
    28 #include <QDate>
    27 #include <QDate>
    29 #include <QDesktopWidget>
    28 #include <QDesktopWidget>
    30 #include <QLabel>
    29 #include <QLabel>
    31 #include <QLibraryInfo>
    30 #include <QLibraryInfo>
       
    31 #include <QStyle>
       
    32 #include <QStyleFactory>
    32 
    33 
    33 #include "hwform.h"
    34 #include "hwform.h"
    34 #include "hwconsts.h"
    35 #include "hwconsts.h"
    35 #include "newnetclient.h"
    36 #include "newnetclient.h"
    36 
    37 
    48 #endif
    49 #endif
    49 
    50 
    50 #ifdef Q_OS_WIN
    51 #ifdef Q_OS_WIN
    51 #include <QSplashScreen>
    52 #include <QSplashScreen>
    52 #endif
    53 #endif
       
    54 
       
    55 #include <QMessageBox>
    53 
    56 
    54 // Program resources
    57 // Program resources
    55 #ifdef __APPLE__
    58 #ifdef __APPLE__
    56 static CocoaInitializer * cocoaInit = NULL;
    59 static CocoaInitializer * cocoaInit = NULL;
    57 #endif
    60 #endif
    90     //Hedgewars birthday?
    93     //Hedgewars birthday?
    91     else if (date.month() == 10 && date.day() == 31)
    94     else if (date.month() == 10 && date.day() == 31)
    92     {
    95     {
    93         season = SEASON_HWBDAY;
    96         season = SEASON_HWBDAY;
    94         years_since_foundation = date.year() - 2004;
    97         years_since_foundation = date.year() - 2004;
       
    98     }
       
    99     else if (date.month() == 4 && date.day() == 1)
       
   100     {
       
   101         season = SEASON_APRIL1;
    95     }
   102     }
    96     //Easter?
   103     //Easter?
    97     else if (calculateEaster(date.year()) == date)
   104     else if (calculateEaster(date.year()) == date)
    98         season = SEASON_EASTER;
   105         season = SEASON_EASTER;
    99     else
   106     else
   151 .arg(HWApplication::tr("Custom path for configuration data and user data", "command-line"))
   158 .arg(HWApplication::tr("Custom path for configuration data and user data", "command-line"))
   152 .arg(HWApplication::tr("Custom path to the game data folder", "command-line"))
   159 .arg(HWApplication::tr("Custom path to the game data folder", "command-line"))
   153 .arg(HWApplication::tr("Hedgewars can use a %1 (e.g. \"%2\") to connect on start.", "command-line").arg(HWApplication::tr("CONNECTSTRING", "command-line")).arg(QString("hwplay://") + NETGAME_DEFAULT_SERVER));
   160 .arg(HWApplication::tr("Hedgewars can use a %1 (e.g. \"%2\") to connect on start.", "command-line").arg(HWApplication::tr("CONNECTSTRING", "command-line")).arg(QString("hwplay://") + NETGAME_DEFAULT_SERVER));
   154 }
   161 }
   155 
   162 
   156 int main(int argc, char *argv[])
   163 int main(int argc, char *argv[]) {
   157 {
   164     /* Qt5 Base removed Motif, Plastique. These are now in the Qt style plugins
       
   165     (Ubuntu: qt5-style-plugins, which was NOT backported by Debian/Ubuntu to stable/LTS).
       
   166     Windows appears to render best of the remaining options but still isn't quite right. */
       
   167 
       
   168     // Try setting Plastique if available
       
   169     QStyle* coreStyle;
       
   170     coreStyle = QStyleFactory::create("Plastique");
       
   171     if(coreStyle != 0) {
       
   172         QApplication::setStyle(coreStyle);
       
   173         qDebug("Qt style set: Plastique");
       
   174     } else {
       
   175         // Use Windows as fallback.
       
   176         // FIXME: Under Windows style, some widgets like scrollbars don't render as nicely
       
   177         coreStyle = QStyleFactory::create("Windows");
       
   178         if(coreStyle != 0) {
       
   179             QApplication::setStyle(coreStyle);
       
   180             qDebug("Qt style set: Windows");
       
   181         } else {
       
   182             // Windows style should not be missing in Qt5 Base. If it does, something went terribly wrong!
       
   183             qWarning("No Qt style could be set! Using the default one.");
       
   184         }
       
   185     }
       
   186 
   158     // Since we're calling this first, closeResources() will be the last thing called after main() returns.
   187     // Since we're calling this first, closeResources() will be the last thing called after main() returns.
   159     atexit(closeResources);
   188     atexit(closeResources);
   160 
   189 
   161 #ifdef __APPLE__
   190 #ifdef __APPLE__
   162     cocoaInit = new CocoaInitializer(); // Creates the autoreleasepool preventing cocoa object leaks on OS X.
   191     cocoaInit = new CocoaInitializer(); // Creates the autoreleasepool preventing cocoa object leaks on OS X.
   250     QPixmap pixmap(":/res/splash.png");
   279     QPixmap pixmap(":/res/splash.png");
   251     QSplashScreen splash(pixmap);
   280     QSplashScreen splash(pixmap);
   252     splash.show();
   281     splash.show();
   253 #endif
   282 #endif
   254 
   283 
   255     app.setStyle(new QPlastiqueStyle());
       
   256 
       
   257     QDateTime now = QDateTime::currentDateTime();
   284     QDateTime now = QDateTime::currentDateTime();
   258     srand(now.toTime_t());
   285     srand(now.toTime_t());
   259     rand();
   286     rand();
   260 
   287 
   261     Q_INIT_RESOURCE(hedgewars);
   288     Q_INIT_RESOURCE(hedgewars);
   293         // alternative loading/lookup paths
   320         // alternative loading/lookup paths
   294         checkForDir(cfgdir->absolutePath() + "/Data");
   321         checkForDir(cfgdir->absolutePath() + "/Data");
   295 
   322 
   296         // config/save paths
   323         // config/save paths
   297         checkForDir(cfgdir->absolutePath() + "/Demos");
   324         checkForDir(cfgdir->absolutePath() + "/Demos");
       
   325         checkForDir(cfgdir->absolutePath() + "/DrawnMaps");
   298         checkForDir(cfgdir->absolutePath() + "/Saves");
   326         checkForDir(cfgdir->absolutePath() + "/Saves");
   299         checkForDir(cfgdir->absolutePath() + "/Screenshots");
   327         checkForDir(cfgdir->absolutePath() + "/Screenshots");
   300         checkForDir(cfgdir->absolutePath() + "/Teams");
   328         checkForDir(cfgdir->absolutePath() + "/Teams");
   301         checkForDir(cfgdir->absolutePath() + "/Logs");
   329         checkForDir(cfgdir->absolutePath() + "/Logs");
   302         checkForDir(cfgdir->absolutePath() + "/Videos");
   330         checkForDir(cfgdir->absolutePath() + "/Videos");
   308     if (!datadir->cd("Data"))
   336     if (!datadir->cd("Data"))
   309     {
   337     {
   310         MessageDialog::ShowFatalMessage(HWApplication::tr("Failed to open data directory:\n%1\n\nPlease check your installation!").arg(datadir->absolutePath()+"/Data"));
   338         MessageDialog::ShowFatalMessage(HWApplication::tr("Failed to open data directory:\n%1\n\nPlease check your installation!").arg(datadir->absolutePath()+"/Data"));
   311         return 1;
   339         return 1;
   312     }
   340     }
       
   341 
       
   342     bool isProbablyNewPlayer = false;
   313 
   343 
   314     // setup PhysFS
   344     // setup PhysFS
   315     engine = new FileEngineHandler(argv[0]);
   345     engine = new FileEngineHandler(argv[0]);
   316     engine->mount(datadir->absolutePath());
   346     engine->mount(datadir->absolutePath());
   317     engine->mount(cfgdir->absolutePath() + "/Data");
   347     engine->mount(cfgdir->absolutePath() + "/Data");
   323     QTranslator TranslatorQt;
   353     QTranslator TranslatorQt;
   324     {
   354     {
   325         QSettings settings(DataManager::instance().settingsFileName(), QSettings::IniFormat);
   355         QSettings settings(DataManager::instance().settingsFileName(), QSettings::IniFormat);
   326         settings.setIniCodec("UTF-8");
   356         settings.setIniCodec("UTF-8");
   327 
   357 
       
   358         // Heuristic to figure out if the user is (probably) a first-time player.
       
   359         // If nickname is not set, then probably yes.
       
   360         // The hidden setting firstLaunch is, if present, used to force HW to
       
   361         // treat iself as if it were launched the first time.
       
   362         QString nick = settings.value("net/nick", QString()).toString();
       
   363         if (settings.contains("frontend/firstLaunch"))
       
   364         {
       
   365             isProbablyNewPlayer = settings.value("frontend/firstLaunch").toBool();
       
   366         }
       
   367         else
       
   368         {
       
   369             isProbablyNewPlayer = nick.isNull();
       
   370         }
       
   371 
       
   372         // Set firstLaunch to false to make sure we remember we have been launched before.
       
   373         settings.setValue("frontend/firstLaunch", false);
       
   374 
   328         QString cc = settings.value("misc/locale", QString()).toString();
   375         QString cc = settings.value("misc/locale", QString()).toString();
   329         if (cc.isEmpty())
   376         if (cc.isEmpty())
   330         {
   377         {
   331             cc = QLocale::system().name();
   378             cc = QLocale::system().name();
       
   379             qDebug("Detected system locale: %s", qPrintable(cc));
   332 
   380 
   333             // Fallback to current input locale if "C" locale is returned
   381             // Fallback to current input locale if "C" locale is returned
   334             if(cc == "C")
   382             if(cc == "C")
   335                 cc = HWApplication::keyboardInputLocale().name();
   383                 cc = HWApplication::inputMethod()->locale().name();
   336         }
   384         }
   337 
   385         else
   338         // Load locale files into translators
   386         {
   339         if (!TranslatorHedgewars.load(QString("physfs://Locale/hedgewars_%1").arg(cc)))
   387             qDebug("Configured frontend locale: %s", qPrintable(cc));
   340             qWarning("Failed to install Hedgewars translation (%s)", qPrintable(cc));
   388         }
   341         if (!TranslatorQt.load(QString("%1/qt_%2").arg(QLibraryInfo::location(QLibraryInfo::TranslationsPath), cc)))
   389         QLocale::setDefault(cc);
   342             qWarning("Failed to install Qt translation (%s)", qPrintable(cc));
   390         QString defaultLocaleName = QLocale().name();
   343         app.installTranslator(&TranslatorHedgewars);
   391         qDebug("Frontend uses locale: %s", qPrintable(defaultLocaleName));
   344         app.installTranslator(&TranslatorQt);
   392 
   345         app.setLayoutDirection(QLocale(cc).textDirection());
   393         if (defaultLocaleName != "C")
       
   394         {
       
   395             // Load locale files into translators
       
   396             if (!TranslatorHedgewars.load(QLocale(), "hedgewars", "_", QString("physfs://Locale")))
       
   397                 qWarning("Failed to install Hedgewars translation (%s)", qPrintable(defaultLocaleName));
       
   398             if (!TranslatorQt.load(QLocale(), "qt", "_", QString(QLibraryInfo::location(QLibraryInfo::TranslationsPath))))
       
   399                 qWarning("Failed to install Qt translation (%s)", qPrintable(defaultLocaleName));
       
   400             app.installTranslator(&TranslatorHedgewars);
       
   401             app.installTranslator(&TranslatorQt);
       
   402         }
       
   403         app.setLayoutDirection(QLocale().textDirection());
   346     }
   404     }
   347 
   405 
   348 #ifdef _WIN32
   406 #ifdef _WIN32
   349     // Win32 registry setup (used for external software detection etc.
   407     // Win32 registry setup (used for external software detection etc.
   350     // don't set it if running in "portable" mode with a custom config dir)
   408     // don't set it if running in "portable" mode with a custom config dir)
   366     //with an appropriate background
   424     //with an appropriate background
   367     switch (season)
   425     switch (season)
   368     {
   426     {
   369         case SEASON_CHRISTMAS :
   427         case SEASON_CHRISTMAS :
   370             fname = "christmas.css";
   428             fname = "christmas.css";
       
   429             break;
       
   430         case SEASON_APRIL1 :
       
   431             fname = "april1.css";
   371             break;
   432             break;
   372         case SEASON_EASTER :
   433         case SEASON_EASTER :
   373             fname = "easter.css";
   434             fname = "easter.css";
   374             break;
   435             break;
   375         case SEASON_HWBDAY :
   436         case SEASON_HWBDAY :
   396 #ifdef Q_OS_WIN
   457 #ifdef Q_OS_WIN
   397     splash.finish(app.form);
   458     splash.finish(app.form);
   398 #endif
   459 #endif
   399     app.form->show();
   460     app.form->show();
   400 
   461 
       
   462     // Show welcome message for (suspected) first-time player and
       
   463     // point towards the Training menu.
       
   464     if(isProbablyNewPlayer) {
       
   465         QMessageBox questionTutorialMsg(app.form);
       
   466         questionTutorialMsg.setIcon(QMessageBox::Question);
       
   467         questionTutorialMsg.setWindowTitle(QMessageBox::tr("Welcome to Hedgewars"));
       
   468         questionTutorialMsg.setText(QMessageBox::tr("Welcome to Hedgewars!\n\nYou seem to be new around here. Would you like to play some training missions first to learn the basics of Hedgewars?"));
       
   469         questionTutorialMsg.setWindowModality(Qt::WindowModal);
       
   470         questionTutorialMsg.addButton(QMessageBox::Yes);
       
   471         questionTutorialMsg.addButton(QMessageBox::No);
       
   472 
       
   473         int answer = questionTutorialMsg.exec();
       
   474         if (answer == QMessageBox::Yes) {
       
   475             app.form->GoToTraining();
       
   476         }
       
   477     }
       
   478 
   401     if (app.urlString)
   479     if (app.urlString)
   402         app.fakeEvent();
   480         app.fakeEvent();
   403     return app.exec();
   481     return app.exec();
   404 }
   482 }