aboutsummaryrefslogtreecommitdiff
path: root/src/qt/bitcoin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qt/bitcoin.cpp')
-rw-r--r--src/qt/bitcoin.cpp175
1 files changed, 124 insertions, 51 deletions
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index 73a5a12efa..e73a82978a 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
@@ -61,7 +62,7 @@ static bool ThreadSafeMessageBox(const std::string& message, const std::string&
}
else
{
- printf("%s: %s\n", caption.c_str(), message.c_str());
+ LogPrintf("%s: %s\n", caption.c_str(), message.c_str());
fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str());
return false;
}
@@ -90,7 +91,7 @@ static void InitMessage(const std::string &message)
splashref->showMessage(QString::fromStdString(message), Qt::AlignBottom|Qt::AlignHCenter, QColor(55,55,55));
qApp->processEvents();
}
- printf("init message: %s\n", message.c_str());
+ LogPrintf("init message: %s\n", message.c_str());
}
/*
@@ -110,11 +111,82 @@ 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)
+{
+ Q_UNUSED(type);
+ LogPrint("qt", "Bitcoin-Qt: %s\n", msg);
+}
+#else
+void DebugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &msg)
+{
+ Q_UNUSED(type);
+ Q_UNUSED(context);
+ LogPrint("qt", "Bitcoin-Qt: %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
@@ -128,64 +200,54 @@ 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(TestNet());
- // 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));
+ // Install qDebug() message handler to route to debug.log
+#if QT_VERSION < 0x050000
+ qInstallMsgHandler(DebugMessageHandler);
+#else
+ qInstallMessageHandler(DebugMessageHandler);
+#endif
- // 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);
@@ -224,7 +286,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);
@@ -239,6 +301,10 @@ int main(int argc, char *argv[])
optionsModel.Upgrade(); // Must be done after AppInit2
+ PaymentServer::LoadRootCAs();
+ paymentServer->setOptionsModel(&optionsModel);
+ paymentServer->initNetManager();
+
if (splashref)
splash.finish(&window);
@@ -260,8 +326,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(message(QString,QString,unsigned int)),
+ guiref, SLOT(message(QString,QString,unsigned int)));
QTimer::singleShot(100, paymentServer, SLOT(uiReady()));
app.exec();