]> Git Repo - VerusCoin.git/blame - src/qt/bitcoin.cpp
Shutdown cleanup prep-work
[VerusCoin.git] / src / qt / bitcoin.cpp
CommitLineData
aaa1c3c4 1/*
246c20e8 2 * W.J. van der Laan 2011-2012
aaa1c3c4 3 */
32af5266
PK
4
5#include <QApplication>
6
0fd01780 7#include "bitcoingui.h"
18cab09a 8#include "clientmodel.h"
ef079e18 9#include "walletmodel.h"
ee014e5b 10#include "optionsmodel.h"
7e7bcce2 11#include "guiutil.h"
3793fa09 12#include "guiconstants.h"
18cab09a 13#include "init.h"
c8c2fbe0 14#include "util.h"
6b6aaa16 15#include "ui_interface.h"
8269a095 16#include "paymentserver.h"
aaa1c3c4 17
467c31ea 18#include <QMessageBox>
3f0816e3 19#include <QTextCodec>
daaee738 20#include <QLocale>
8269a095 21#include <QTimer>
daaee738 22#include <QTranslator>
10d680cf 23#include <QSplashScreen>
527137e3 24#include <QLibraryInfo>
467c31ea 25
55f69a47
WL
26#if defined(BITCOIN_NEED_QT_PLUGINS) && !defined(_BITCOIN_QT_PLUGINS_INCLUDED)
27#define _BITCOIN_QT_PLUGINS_INCLUDED
28#define __INSURE__
29#include <QtPlugin>
30Q_IMPORT_PLUGIN(qcncodecs)
31Q_IMPORT_PLUGIN(qjpcodecs)
32Q_IMPORT_PLUGIN(qtwcodecs)
33Q_IMPORT_PLUGIN(qkrcodecs)
34Q_IMPORT_PLUGIN(qtaccessiblewidgets)
35#endif
36
00b8acdf 37// Need a global reference for the notifications to find the GUI
98e61758
WL
38static BitcoinGUI *guiref;
39static QSplashScreen *splashref;
467c31ea 40
f7f3a96b 41static bool ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style)
467c31ea
WL
42{
43 // Message from network thread
44 if(guiref)
45 {
239c11d0 46 bool modal = (style & CClientUIInterface::MODAL);
f7f3a96b 47 bool ret = false;
5350ea41
PK
48 // In case of modal message, use blocking connection to wait for user to click a button
49 QMetaObject::invokeMethod(guiref, "message",
7cfbe1fe 50 modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
467c31ea 51 Q_ARG(QString, QString::fromStdString(caption)),
7cfbe1fe 52 Q_ARG(QString, QString::fromStdString(message)),
f7f3a96b
PW
53 Q_ARG(unsigned int, style),
54 Q_ARG(bool*, &ret));
55 return ret;
467c31ea
WL
56 }
57 else
58 {
59 printf("%s: %s\n", caption.c_str(), message.c_str());
60 fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str());
f7f3a96b 61 return false;
467c31ea 62 }
467c31ea
WL
63}
64
15d8ff20 65static bool ThreadSafeAskFee(int64 nFeeRequired)
467c31ea 66{
b7726d92
WL
67 if(!guiref)
68 return false;
69 if(nFeeRequired < MIN_TX_FEE || nFeeRequired <= nTransactionFee || fDaemon)
70 return true;
15d8ff20 71
b7726d92
WL
72 bool payFee = false;
73
7e7bcce2 74 QMetaObject::invokeMethod(guiref, "askFee", GUIUtil::blockingGUIThreadConnection(),
b7726d92
WL
75 Q_ARG(qint64, nFeeRequired),
76 Q_ARG(bool*, &payFee));
77
78 return payFee;
467c31ea
WL
79}
80
ab1b288f 81static void InitMessage(const std::string &message)
10d680cf
WL
82{
83 if(splashref)
84 {
5762295e 85 splashref->showMessage(QString::fromStdString(message), Qt::AlignBottom|Qt::AlignHCenter, QColor(255,255,200));
1ce04488 86 qApp->processEvents();
10d680cf 87 }
bb41a87d 88 printf("init message: %s\n", message.c_str());
10d680cf
WL
89}
90
ab1b288f 91static void QueueShutdown()
1a3f0da9 92{
1ce04488 93 QMetaObject::invokeMethod(qApp, "quit", Qt::QueuedConnection);
1a3f0da9
WL
94}
95
39cf857d
WL
96/*
97 Translate string to current locale using Qt.
98 */
ab1b288f 99static std::string Translate(const char* psz)
39cf857d
WL
100{
101 return QCoreApplication::translate("bitcoin-core", psz).toStdString();
102}
103
a7a0c7a1
WL
104/* Handle runaway exceptions. Shows a message box with the problem and quits the program.
105 */
106static void handleRunawayException(std::exception *e)
107{
108 PrintExceptionContinue(e, "Runaway exception");
951f7d35 109 QMessageBox::critical(0, "Runaway exception", BitcoinGUI::tr("A fatal error occurred. Bitcoin can no longer continue safely and will quit.") + QString("\n\n") + QString::fromStdString(strMiscWarning));
a7a0c7a1
WL
110 exit(1);
111}
112
24548467 113#ifndef BITCOIN_QT_TEST
aaa1c3c4
WL
114int main(int argc, char *argv[])
115{
8ffbd6c3
PK
116 // Command-line options take precedence:
117 ParseParameters(argc, argv);
118
c75abc9f 119 // Internal string conversion is all UTF-8
3f0816e3
MSV
120 QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
121 QTextCodec::setCodecForCStrings(QTextCodec::codecForTr());
122
45c4a0b3 123 Q_INIT_RESOURCE(bitcoin);
aaa1c3c4 124 QApplication app(argc, argv);
daaee738 125
8269a095
GA
126 // Do this early as we don't want to bother initializing if we are just calling IPC
127 // ... but do it after creating app, so QCoreApplication::arguments is initialized:
128 if (PaymentServer::ipcSendCommandLine())
129 exit(0);
130 PaymentServer* paymentServer = new PaymentServer(&app);
131
3793fa09
WL
132 // Install global event filter that makes sure that long tooltips can be word-wrapped
133 app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app));
134
3f8cb2c5 135 // ... then bitcoin.conf:
f4203de3 136 if (!boost::filesystem::is_directory(GetDataDir(false)))
3f8cb2c5 137 {
61fd7269
WL
138 // This message can not be translated, as translation is not initialized yet
139 // (which not yet possible because lang=XX can be overridden in bitcoin.conf in the data directory)
140 QMessageBox::critical(0, "Bitcoin",
141 QString("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(mapArgs["-datadir"])));
3f8cb2c5
GA
142 return 1;
143 }
f4203de3 144 ReadConfigFile(mapArgs, mapMultiArgs);
3f8cb2c5
GA
145
146 // Application identification (must be set before OptionsModel is initialized,
147 // as it is used to locate QSettings)
148 app.setOrganizationName("Bitcoin");
149 app.setOrganizationDomain("bitcoin.org");
150 if(GetBoolArg("-testnet")) // Separate UI settings for testnet
151 app.setApplicationName("Bitcoin-Qt-testnet");
152 else
153 app.setApplicationName("Bitcoin-Qt");
154
155 // ... then GUI settings:
156 OptionsModel optionsModel;
157
aab1f950 158 // Get desired locale (e.g. "de_DE") from command line or use system locale
72075eda 159 QString lang_territory = QString::fromStdString(GetArg("-lang", QLocale::system().name().toStdString()));
5c92622a 160 QString lang = lang_territory;
aab1f950
PK
161 // Convert to "de" only by truncating "_DE"
162 lang.truncate(lang_territory.lastIndexOf('_'));
72075eda 163
5c92622a 164 QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
aab1f950
PK
165 // Load language files for configured locale:
166 // - First load the translator for the base language, without territory
167 // - Then load the more specific locale translator
5c92622a 168
aab1f950
PK
169 // Load e.g. qt_de.qm
170 if (qtTranslatorBase.load("qt_" + lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
5c92622a
WL
171 app.installTranslator(&qtTranslatorBase);
172
aab1f950
PK
173 // Load e.g. qt_de_DE.qm
174 if (qtTranslator.load("qt_" + lang_territory, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
527137e3 175 app.installTranslator(&qtTranslator);
5c92622a 176
aab1f950
PK
177 // Load e.g. bitcoin_de.qm (shortcut "de" needs to be defined in bitcoin.qrc)
178 if (translatorBase.load(lang, ":/translations/"))
5c92622a
WL
179 app.installTranslator(&translatorBase);
180
aab1f950
PK
181 // Load e.g. bitcoin_de_DE.qm (shortcut "de_DE" needs to be defined in bitcoin.qrc)
182 if (translator.load(lang_territory, ":/translations/"))
608dacf6 183 app.installTranslator(&translator);
daaee738 184
ab1b288f
WL
185 // Subscribe to global signals from core
186 uiInterface.ThreadSafeMessageBox.connect(ThreadSafeMessageBox);
187 uiInterface.ThreadSafeAskFee.connect(ThreadSafeAskFee);
ab1b288f
WL
188 uiInterface.InitMessage.connect(InitMessage);
189 uiInterface.QueueShutdown.connect(QueueShutdown);
190 uiInterface.Translate.connect(Translate);
191
9f5b11e6
WL
192 // Show help message immediately after parsing command-line options (for "-lang") and setting locale,
193 // but before showing splash screen.
194 if (mapArgs.count("-?") || mapArgs.count("--help"))
195 {
5d6b3027 196 GUIUtil::HelpMessageBox help;
7d72a8c3 197 help.showOrPrint();
9f5b11e6
WL
198 return 1;
199 }
200
8c4738d5 201 QSplashScreen splash(QPixmap(":/images/splash"), 0);
ec4efde4
CM
202 if (GetBoolArg("-splash", true) && !GetBoolArg("-min"))
203 {
204 splash.show();
205 splash.setAutoFillBackground(true);
206 splashref = &splash;
207 }
10d680cf
WL
208
209 app.processEvents();
210
352083cb 211 app.setQuitOnLastWindowClosed(false);
aaa1c3c4 212
8e86dca2
WL
213 try
214 {
67d4cbab
WL
215 // Regenerate startup link, to fix links to old versions
216 if (GUIUtil::GetStartOnSystemStartup())
217 GUIUtil::SetStartOnSystemStartup(true);
218
c8c2fbe0 219 boost::thread_group threadGroup;
7cfbe1fe
WL
220 BitcoinGUI window;
221 guiref = &window;
c8c2fbe0 222 if(AppInit2(threadGroup))
18cab09a 223 {
8fe2308b 224 {
7cfbe1fe
WL
225 // Put this in a block, so that the Model objects are cleaned up before
226 // calling Shutdown().
3f8cb2c5
GA
227
228 optionsModel.Upgrade(); // Must be done after AppInit2
229
ec4efde4
CM
230 if (splashref)
231 splash.finish(&window);
3f8cb2c5 232
ee014e5b
WL
233 ClientModel clientModel(&optionsModel);
234 WalletModel walletModel(pwalletMain, &optionsModel);
0b814f9e 235
8fe2308b 236 window.setClientModel(&clientModel);
67155d92
EL
237 window.addWallet("~Default", &walletModel);
238 window.setCurrentWallet("~Default");
8fe2308b 239
7915370c
WL
240 // If -min option passed, start window minimized.
241 if(GetBoolArg("-min"))
242 {
243 window.showMinimized();
244 }
245 else
246 {
247 window.show();
248 }
8fe2308b 249
8269a095
GA
250 // Now that initialization/startup is done, process any command-line
251 // bitcoin: URIs
252 QObject::connect(paymentServer, SIGNAL(receivedURI(QString)), &window, SLOT(handleURI(QString)));
253 QTimer::singleShot(100, paymentServer, SLOT(uiReady()));
7b90edb5 254
8fe2308b
WL
255 app.exec();
256
46f552a9 257 window.hide();
7cfbe1fe 258 window.setClientModel(0);
67155d92 259 window.removeAllWallets();
8fe2308b
WL
260 guiref = 0;
261 }
b49f1398 262 // Shutdown the core and its threads, but don't exit Bitcoin-Qt here
18cab09a 263 Shutdown(NULL);
c8c2fbe0
GA
264 threadGroup.interrupt_all();
265 threadGroup.join_all();
18cab09a
WL
266 }
267 else
268 {
269 return 1;
270 }
271 } catch (std::exception& e) {
a7a0c7a1 272 handleRunawayException(&e);
18cab09a 273 } catch (...) {
a7a0c7a1 274 handleRunawayException(NULL);
18cab09a 275 }
8fe2308b 276 return 0;
aaa1c3c4 277}
24548467 278#endif // BITCOIN_QT_TEST
This page took 0.160276 seconds and 4 git commands to generate.