2 * W.J. van der Laan 2011-2012
4 #include "bitcoingui.h"
5 #include "clientmodel.h"
6 #include "walletmodel.h"
7 #include "optionsmodel.h"
9 #include "guiconstants.h"
12 #include "ui_interface.h"
13 #include "qtipcserver.h"
15 #include <QApplication>
16 #include <QMessageBox>
17 #if QT_VERSION < 0x050000
21 #include <QTranslator>
22 #include <QSplashScreen>
23 #include <QLibraryInfo>
25 #if defined(BITCOIN_NEED_QT_PLUGINS) && !defined(_BITCOIN_QT_PLUGINS_INCLUDED)
26 #define _BITCOIN_QT_PLUGINS_INCLUDED
29 Q_IMPORT_PLUGIN(qcncodecs)
30 Q_IMPORT_PLUGIN(qjpcodecs)
31 Q_IMPORT_PLUGIN(qtwcodecs)
32 Q_IMPORT_PLUGIN(qkrcodecs)
33 Q_IMPORT_PLUGIN(qtaccessiblewidgets)
36 // Need a global reference for the notifications to find the GUI
37 static BitcoinGUI *guiref;
38 static QSplashScreen *splashref;
40 static void ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style)
42 // Message from network thread
45 bool modal = (style & CClientUIInterface::MODAL);
46 // in case of modal message, use blocking connection to wait for user to click OK
47 QMetaObject::invokeMethod(guiref, "error",
48 modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
49 Q_ARG(QString, QString::fromStdString(caption)),
50 Q_ARG(QString, QString::fromStdString(message)),
55 printf("%s: %s\n", caption.c_str(), message.c_str());
56 fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str());
60 static bool ThreadSafeAskFee(int64_t nFeeRequired, const std::string& strCaption)
64 if(nFeeRequired < MIN_TX_FEE || nFeeRequired <= nTransactionFee || fDaemon)
68 QMetaObject::invokeMethod(guiref, "askFee", GUIUtil::blockingGUIThreadConnection(),
69 Q_ARG(qint64, nFeeRequired),
70 Q_ARG(bool*, &payFee));
75 static void ThreadSafeHandleURI(const std::string& strURI)
80 QMetaObject::invokeMethod(guiref, "handleURI", GUIUtil::blockingGUIThreadConnection(),
81 Q_ARG(QString, QString::fromStdString(strURI)));
84 static void InitMessage(const std::string &message)
88 splashref->showMessage(QString::fromStdString(message), Qt::AlignBottom|Qt::AlignHCenter, QColor(255,255,200));
89 QApplication::instance()->processEvents();
93 static void QueueShutdown()
95 QMetaObject::invokeMethod(QCoreApplication::instance(), "quit", Qt::QueuedConnection);
99 Translate string to current locale using Qt.
101 static std::string Translate(const char* psz)
103 return QCoreApplication::translate("bitcoin-core", psz).toStdString();
106 /* Handle runaway exceptions. Shows a message box with the problem and quits the program.
108 static void handleRunawayException(std::exception *e)
110 PrintExceptionContinue(e, "Runaway exception");
111 QMessageBox::critical(0, "Runaway exception", BitcoinGUI::tr("A fatal error occurred. NovaCoin can no longer continue safely and will quit.") + QString("\n\n") + QString::fromStdString(strMiscWarning));
115 #ifndef BITCOIN_QT_TEST
116 int main(int argc, char *argv[])
118 // Do this early as we don't want to bother initializing if we are just calling IPC
119 ipcScanRelay(argc, argv);
120 #if QT_VERSION < 0x050000
121 // Internal string conversion is all UTF-8
122 QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
123 QTextCodec::setCodecForCStrings(QTextCodec::codecForTr());
125 Q_INIT_RESOURCE(bitcoin);
126 QApplication app(argc, argv);
128 // Install global event filter that makes sure that long tooltips can be word-wrapped
129 app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app));
131 // Command-line options take precedence:
132 ParseParameters(argc, argv);
134 // ... then bitcoin.conf:
135 if (!boost::filesystem::is_directory(GetDataDir(false)))
137 // This message can not be translated, as translation is not initialized yet
138 // (which not yet possible because lang=XX can be overridden in bitcoin.conf in the data directory)
139 QMessageBox::critical(0, "NovaCoin",
140 QString("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(mapArgs["-datadir"])));
143 ReadConfigFile(mapArgs, mapMultiArgs);
145 // Application identification (must be set before OptionsModel is initialized,
146 // as it is used to locate QSettings)
147 app.setOrganizationName("NovaCoin");
148 app.setOrganizationDomain("novacoin.su");
149 if(GetBoolArg("-testnet")) // Separate UI settings for testnet
150 app.setApplicationName("NovaCoin-Qt-testnet");
152 app.setApplicationName("NovaCoin-Qt");
154 // ... then GUI settings:
155 OptionsModel optionsModel;
157 // Get desired locale (e.g. "de_DE") from command line or use system locale
158 QString lang_territory = QString::fromStdString(GetArg("-lang", QLocale::system().name().toStdString()));
159 QString lang = lang_territory;
160 // Convert to "de" only by truncating "_DE"
161 lang.truncate(lang_territory.lastIndexOf('_'));
163 QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
164 // Load language files for configured locale:
165 // - First load the translator for the base language, without territory
166 // - Then load the more specific locale translator
168 // Load e.g. qt_de.qm
169 if (qtTranslatorBase.load("qt_" + lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
170 app.installTranslator(&qtTranslatorBase);
172 // Load e.g. qt_de_DE.qm
173 if (qtTranslator.load("qt_" + lang_territory, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
174 app.installTranslator(&qtTranslator);
176 // Load e.g. bitcoin_de.qm (shortcut "de" needs to be defined in bitcoin.qrc)
177 if (translatorBase.load(lang, ":/translations/"))
178 app.installTranslator(&translatorBase);
180 // Load e.g. bitcoin_de_DE.qm (shortcut "de_DE" needs to be defined in bitcoin.qrc)
181 if (translator.load(lang_territory, ":/translations/"))
182 app.installTranslator(&translator);
184 // Subscribe to global signals from core
185 uiInterface.ThreadSafeMessageBox.connect(ThreadSafeMessageBox);
186 uiInterface.ThreadSafeAskFee.connect(ThreadSafeAskFee);
187 uiInterface.ThreadSafeHandleURI.connect(ThreadSafeHandleURI);
188 uiInterface.InitMessage.connect(InitMessage);
189 uiInterface.QueueShutdown.connect(QueueShutdown);
190 uiInterface.Translate.connect(Translate);
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"))
196 GUIUtil::HelpMessageBox help;
201 QSplashScreen splash(QPixmap(":/images/splash"), 0);
202 if (GetBoolArg("-splash", true) && !GetBoolArg("-min"))
205 splash.setAutoFillBackground(true);
211 app.setQuitOnLastWindowClosed(false);
215 // Regenerate startup link, to fix links to old versions
216 if (GUIUtil::GetStartOnSystemStartup())
217 GUIUtil::SetStartOnSystemStartup(true);
224 // Put this in a block, so that the Model objects are cleaned up before
225 // calling Shutdown().
228 splash.finish(&window);
230 ClientModel clientModel(&optionsModel);
231 WalletModel walletModel(pwalletMain, &optionsModel);
233 window.setClientModel(&clientModel);
234 window.setWalletModel(&walletModel);
236 // If -min option passed, start window minimized.
237 if(GetBoolArg("-min"))
239 window.showMinimized();
246 // Place this here as guiref has to be defined if we don't want to lose URIs
252 window.setClientModel(0);
253 window.setWalletModel(0);
256 // Shutdown the core and its threads, but don't exit Bitcoin-Qt here
263 } catch (std::exception& e) {
264 handleRunawayException(&e);
266 handleRunawayException(NULL);
270 #endif // BITCOIN_QT_TEST