diff options
Diffstat (limited to 'src/qt/bitcoin.cpp')
-rw-r--r-- | src/qt/bitcoin.cpp | 166 |
1 files changed, 117 insertions, 49 deletions
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 76e88b36a7..e7cf440044 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -2,8 +2,6 @@ * W.J. van der Laan 2011-2012 */ -#include <QApplication> - #include "bitcoingui.h" #include "clientmodel.h" #include "walletmodel.h" @@ -15,7 +13,9 @@ #include "ui_interface.h" #include "paymentserver.h" #include "splashscreen.h" +#include "intro.h" +#include <QApplication> #include <QMessageBox> #if QT_VERSION < 0x050000 #include <QTextCodec> @@ -24,6 +24,7 @@ #include <QTimer> #include <QTranslator> #include <QLibraryInfo> +#include <QSettings> #if defined(BITCOIN_NEED_QT_PLUGINS) && !defined(_BITCOIN_QT_PLUGINS_INCLUDED) #define _BITCOIN_QT_PLUGINS_INCLUDED @@ -110,13 +111,79 @@ static void handleRunawayException(std::exception *e) exit(1); } +/** Set up translations */ +static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator) +{ + QSettings settings; + + // Get desired locale (e.g. "de_DE") + // 1) System default language + QString lang_territory = QLocale::system().name(); + // 2) Language from QSettings + QString lang_territory_qsettings = settings.value("language", "").toString(); + if(!lang_territory_qsettings.isEmpty()) + lang_territory = lang_territory_qsettings; + // 3) -lang command line argument + lang_territory = QString::fromStdString(GetArg("-lang", lang_territory.toStdString())); + + // Convert to "de" only by truncating "_DE" + QString lang = lang_territory; + lang.truncate(lang_territory.lastIndexOf('_')); + + // Load language files for configured locale: + // - First load the translator for the base language, without territory + // - Then load the more specific locale translator + + // Load e.g. qt_de.qm + if (qtTranslatorBase.load("qt_" + lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) + QApplication::installTranslator(&qtTranslatorBase); + + // Load e.g. qt_de_DE.qm + if (qtTranslator.load("qt_" + lang_territory, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) + QApplication::installTranslator(&qtTranslator); + + // Load e.g. bitcoin_de.qm (shortcut "de" needs to be defined in bitcoin.qrc) + if (translatorBase.load(lang, ":/translations/")) + QApplication::installTranslator(&translatorBase); + + // Load e.g. bitcoin_de_DE.qm (shortcut "de_DE" needs to be defined in bitcoin.qrc) + if (translator.load(lang_territory, ":/translations/")) + QApplication::installTranslator(&translator); +} + +/* qDebug() message handler --> debug.log */ +#if QT_VERSION < 0x050000 +void DebugMessageHandler(QtMsgType type, const char * msg) +{ + OutputDebugStringF("%s\n", msg); +} +#else +void DebugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &msg) +{ + OutputDebugStringF("%s\n", qPrintable(msg)); +} +#endif + #ifndef BITCOIN_QT_TEST int main(int argc, char *argv[]) { + bool fMissingDatadir = false; + bool fSelParFromCLFailed = false; + fHaveGUI = true; // Command-line options take precedence: ParseParameters(argc, argv); + // ... then bitcoin.conf: + if (!boost::filesystem::is_directory(GetDataDir(false))) { + fMissingDatadir = true; + } else { + ReadConfigFile(mapArgs, mapMultiArgs); + } + // Check for -testnet or -regtest parameter (TestNet() calls are only valid after this clause) + if (!SelectParamsFromCommandLine()) { + fSelParFromCLFailed = true; + } #if QT_VERSION < 0x050000 // Internal string conversion is all UTF-8 @@ -130,64 +197,48 @@ int main(int argc, char *argv[]) // Register meta types used for QMetaObject::invokeMethod qRegisterMetaType< bool* >(); - // Do this early as we don't want to bother initializing if we are just calling IPC - // ... but do it after creating app, so QCoreApplication::arguments is initialized: - if (PaymentServer::ipcSendCommandLine()) - exit(0); - PaymentServer* paymentServer = new PaymentServer(&app); - - // Install global event filter that makes sure that long tooltips can be word-wrapped - app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app)); - - // ... then bitcoin.conf: - if (!boost::filesystem::is_directory(GetDataDir(false))) - { - // This message can not be translated, as translation is not initialized yet - // (which not yet possible because lang=XX can be overridden in bitcoin.conf in the data directory) - QMessageBox::critical(0, "Bitcoin", - QString("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(mapArgs["-datadir"]))); - return 1; - } - ReadConfigFile(mapArgs, mapMultiArgs); - // Application identification (must be set before OptionsModel is initialized, // as it is used to locate QSettings) QApplication::setOrganizationName("Bitcoin"); QApplication::setOrganizationDomain("bitcoin.org"); - if (GetBoolArg("-testnet", false)) // Separate UI settings for testnet + if (TestNet()) // Separate UI settings for testnet QApplication::setApplicationName("Bitcoin-Qt-testnet"); else QApplication::setApplicationName("Bitcoin-Qt"); - // ... then GUI settings: - OptionsModel optionsModel; + // Now that QSettings are accessible, initialize translations + QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator; + initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator); - // Get desired locale (e.g. "de_DE") from command line or use system locale - QString lang_territory = QString::fromStdString(GetArg("-lang", QLocale::system().name().toStdString())); - QString lang = lang_territory; - // Convert to "de" only by truncating "_DE" - lang.truncate(lang_territory.lastIndexOf('_')); + // Do this early as we don't want to bother initializing if we are just calling IPC + // ... but do it after creating app and setting up translations, so errors are + // translated properly. + if (PaymentServer::ipcSendCommandLine(argc, argv)) + exit(0); - QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator; - // Load language files for configured locale: - // - First load the translator for the base language, without territory - // - Then load the more specific locale translator + // Now that translations are initialized check for errors and allow a translatable error message + if (fMissingDatadir) { + QMessageBox::critical(0, QObject::tr("Bitcoin"), + QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(mapArgs["-datadir"]))); + return 1; + } + else if (fSelParFromCLFailed) { + QMessageBox::critical(0, QObject::tr("Bitcoin"), QObject::tr("Error: Invalid combination of -regtest and -testnet.")); + return 1; + } - // Load e.g. qt_de.qm - if (qtTranslatorBase.load("qt_" + lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) - app.installTranslator(&qtTranslatorBase); + // Start up the payment server early, too, so impatient users that click on + // bitcoin: links repeatedly have their payment requests routed to this process: + PaymentServer* paymentServer = new PaymentServer(&app); - // Load e.g. qt_de_DE.qm - if (qtTranslator.load("qt_" + lang_territory, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) - app.installTranslator(&qtTranslator); + // User language is set up: pick a data directory + Intro::pickDataDirectory(); - // Load e.g. bitcoin_de.qm (shortcut "de" needs to be defined in bitcoin.qrc) - if (translatorBase.load(lang, ":/translations/")) - app.installTranslator(&translatorBase); + // Install global event filter that makes sure that long tooltips can be word-wrapped + app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app)); - // Load e.g. bitcoin_de_DE.qm (shortcut "de_DE" needs to be defined in bitcoin.qrc) - if (translator.load(lang_territory, ":/translations/")) - app.installTranslator(&translator); + // ... now GUI settings: + OptionsModel optionsModel; // Subscribe to global signals from core uiInterface.ThreadSafeMessageBox.connect(ThreadSafeMessageBox); @@ -204,6 +255,13 @@ int main(int argc, char *argv[]) return 1; } + // Install qDebug() message handler to route to debug.log: +#if QT_VERSION < 0x050000 + qInstallMsgHandler(DebugMessageHandler); +#else + qInstallMessageHandler(DebugMessageHandler); +#endif + SplashScreen splash(QPixmap(), 0); if (GetBoolArg("-splash", true) && !GetBoolArg("-min", false)) { @@ -226,7 +284,7 @@ int main(int argc, char *argv[]) boost::thread_group threadGroup; - BitcoinGUI window(GetBoolArg("-testnet", false), 0); + BitcoinGUI window(TestNet(), 0); guiref = &window; QTimer* pollShutdownTimer = new QTimer(guiref); @@ -241,6 +299,9 @@ int main(int argc, char *argv[]) optionsModel.Upgrade(); // Must be done after AppInit2 + PaymentServer::LoadRootCAs(); + paymentServer->initNetManager(optionsModel); + if (splashref) splash.finish(&window); @@ -262,8 +323,15 @@ int main(int argc, char *argv[]) } // Now that initialization/startup is done, process any command-line - // bitcoin: URIs - QObject::connect(paymentServer, SIGNAL(receivedURI(QString)), &window, SLOT(handleURI(QString))); + // bitcoin: URIs or payment requests: + QObject::connect(paymentServer, SIGNAL(receivedPaymentRequest(SendCoinsRecipient)), + &window, SLOT(handlePaymentRequest(SendCoinsRecipient))); + QObject::connect(&walletModel, SIGNAL(coinsSent(CWallet*,SendCoinsRecipient,QByteArray)), + paymentServer, SLOT(fetchPaymentACK(CWallet*,const SendCoinsRecipient&,QByteArray))); + QObject::connect(paymentServer, SIGNAL(receivedPaymentACK(QString)), + &window, SLOT(showPaymentACK(QString))); + QObject::connect(paymentServer, SIGNAL(reportError(QString, QString, unsigned int)), + guiref, SLOT(message(QString, QString, unsigned int))); QTimer::singleShot(100, paymentServer, SLOT(uiReady())); app.exec(); |