Update CMakeLists.txt - play with openssl
[novacoin.git] / src / qt / bitcoin.cpp
1 /*
2  * W.J. van der Laan 2011-2012
3  */
4 #include "bitcoingui.h"
5 #include "clientmodel.h"
6 #include "walletmodel.h"
7 #include "optionsmodel.h"
8 #include "guiutil.h"
9 #include "guiconstants.h"
10
11 #include "init.h"
12 #include "main.h"
13 #include "interface.h"
14 #include "qtipcserver.h"
15 #include "intro.h"
16
17 #include <QApplication>
18 #include <QMessageBox>
19 #if QT_VERSION < 0x050000
20 #include <QTextCodec>
21 #endif
22 #include <QLocale>
23 #include <QTranslator>
24 #include <QSplashScreen>
25 #include <QLibraryInfo>
26 #include <QSettings>
27
28 #if defined(BITCOIN_NEED_QT_PLUGINS) && !defined(_BITCOIN_QT_PLUGINS_INCLUDED)
29 #define _BITCOIN_QT_PLUGINS_INCLUDED
30 #define __INSURE__
31 #include <QtPlugin>
32 Q_IMPORT_PLUGIN(qcncodecs)
33 Q_IMPORT_PLUGIN(qjpcodecs)
34 Q_IMPORT_PLUGIN(qtwcodecs)
35 Q_IMPORT_PLUGIN(qkrcodecs)
36 Q_IMPORT_PLUGIN(qtaccessiblewidgets)
37 #endif
38
39 // Need a global reference for the notifications to find the GUI
40 static BitcoinGUI *guiref;
41 static QSplashScreen *splashref;
42
43 /** Set up translations */
44 static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator)
45 {
46     QSettings settings;
47     // Get desired locale (e.g. "de_DE")
48     // 1) System default language
49     QString lang_territory = QLocale::system().name();
50     // 2) Language from QSettings
51     QString lang_territory_qsettings = settings.value("language", "").toString();
52     if(!lang_territory_qsettings.isEmpty())
53         lang_territory = lang_territory_qsettings;
54     // 3) -lang command line argument
55     lang_territory = QString::fromStdString(GetArg("-lang", lang_territory.toStdString()));
56     // Convert to "de" only by truncating "_DE"
57     QString lang = lang_territory;
58     lang.truncate(lang_territory.lastIndexOf('_'));
59     // Load language files for configured locale:
60     // - First load the translator for the base language, without territory
61     // - Then load the more specific locale translator
62     // Load e.g. qt_de.qm
63     if (qtTranslatorBase.load("qt_" + lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
64         QApplication::installTranslator(&qtTranslatorBase);
65     // Load e.g. qt_de_DE.qm
66     if (qtTranslator.load("qt_" + lang_territory, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
67         QApplication::installTranslator(&qtTranslator);
68     // Load e.g. bitcoin_de.qm (shortcut "de" needs to be defined in bitcoin.qrc)
69     if (translatorBase.load(lang, ":/translations/"))
70         QApplication::installTranslator(&translatorBase);
71     // Load e.g. bitcoin_de_DE.qm (shortcut "de_DE" needs to be defined in bitcoin.qrc)
72     if (translator.load(lang_territory, ":/translations/"))
73         QApplication::installTranslator(&translator);
74 }
75
76 static void ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style)
77 {
78     // Message from network thread
79     if(guiref)
80     {
81         bool modal = (style & CClientUIInterface::MODAL);
82         // in case of modal message, use blocking connection to wait for user to click OK
83         QMetaObject::invokeMethod(guiref, "error",
84                                    modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
85                                    Q_ARG(QString, QString::fromStdString(caption)),
86                                    Q_ARG(QString, QString::fromStdString(message)),
87                                    Q_ARG(bool, modal));
88     }
89     else
90     {
91         printf("%s: %s\n", caption.c_str(), message.c_str());
92         fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str());
93     }
94 }
95
96 static bool ThreadSafeAskFee(int64_t nFeeRequired, const std::string& strCaption)
97 {
98     if(!guiref)
99         return false;
100     if(nFeeRequired < MIN_TX_FEE || nFeeRequired <= nTransactionFee || fDaemon)
101         return true;
102     bool payFee = false;
103
104     QMetaObject::invokeMethod(guiref, "askFee", GUIUtil::blockingGUIThreadConnection(),
105                                Q_ARG(qint64, nFeeRequired),
106                                Q_ARG(bool*, &payFee));
107
108     return payFee;
109 }
110
111 static void ThreadSafeHandleURI(const std::string& strURI)
112 {
113     if(!guiref)
114         return;
115
116     QMetaObject::invokeMethod(guiref, "handleURI", GUIUtil::blockingGUIThreadConnection(),
117                                Q_ARG(QString, QString::fromStdString(strURI)));
118 }
119
120 static void InitMessage(const std::string &message)
121 {
122     if(splashref)
123     {
124         splashref->showMessage(QString::fromStdString(message), Qt::AlignBottom|Qt::AlignHCenter, QColor(255,255,200));
125         QApplication::instance()->processEvents();
126     }
127 }
128
129 static void QueueShutdown()
130 {
131     QMetaObject::invokeMethod(QCoreApplication::instance(), "quit", Qt::QueuedConnection);
132 }
133
134 /*
135    Translate string to current locale using Qt.
136  */
137 static std::string Translate(const char* psz)
138 {
139     return QCoreApplication::translate("bitcoin-core", psz).toStdString();
140 }
141
142 /* Handle runaway exceptions. Shows a message box with the problem and quits the program.
143  */
144 static void handleRunawayException(std::exception *e)
145 {
146     PrintExceptionContinue(e, "Runaway exception");
147     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));
148     exit(1);
149 }
150
151 #ifndef BITCOIN_QT_TEST
152 int main(int argc, char *argv[])
153 {
154     // Do this early as we don't want to bother initializing if we are just calling IPC
155     ipcScanRelay(argc, argv);
156 #if QT_VERSION < 0x050000
157     // Internal string conversion is all UTF-8
158     QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
159     QTextCodec::setCodecForCStrings(QTextCodec::codecForTr());
160 #endif
161     Q_INIT_RESOURCE(bitcoin);
162     QApplication app(argc, argv);
163
164     // Application identification (must be set before OptionsModel is initialized,
165     // as it is used to locate QSettings)
166     app.setOrganizationName("NovaCoin");
167     app.setOrganizationDomain("novacoin.su");
168     if(GetBoolArg("-testnet")) // Separate UI settings for testnet
169         app.setApplicationName("NovaCoin-Qt-testnet");
170     else
171         app.setApplicationName("NovaCoin-Qt");
172     // Now that QSettings are accessible, initialize translations
173     QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
174     initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
175
176     // Command-line options take precedence:
177     ParseParameters(argc, argv);
178
179     // User language is set up: pick a data directory
180     Intro::pickDataDirectory();
181
182     // Install global event filter that makes sure that long tooltips can be word-wrapped
183     app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app));
184
185     // ... then bitcoin.conf:
186     if (!boost::filesystem::is_directory(GetDataDir(false)))
187     {
188         QMessageBox::critical(0, "NovaCoin",
189                               QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(mapArgs["-datadir"])));
190         return 1;
191     }
192     ReadConfigFile(mapArgs, mapMultiArgs);
193
194     // ... then GUI settings:
195     OptionsModel optionsModel;
196
197     // Subscribe to global signals from core
198     uiInterface.ThreadSafeMessageBox.connect(ThreadSafeMessageBox);
199     uiInterface.ThreadSafeAskFee.connect(ThreadSafeAskFee);
200     uiInterface.ThreadSafeHandleURI.connect(ThreadSafeHandleURI);
201     uiInterface.InitMessage.connect(InitMessage);
202     uiInterface.QueueShutdown.connect(QueueShutdown);
203     uiInterface.Translate.connect(Translate);
204
205     // Show help message immediately after parsing command-line options (for "-lang") and setting locale,
206     // but before showing splash screen.
207     if (mapArgs.count("-?") || mapArgs.count("--help"))
208     {
209         GUIUtil::HelpMessageBox help;
210         help.showOrPrint();
211         return 1;
212     }
213
214     QSplashScreen splash(QPixmap(":/images/splash"), 0);
215     if (GetBoolArg("-splash", true) && !GetBoolArg("-min"))
216     {
217         splash.show();
218         splash.setAutoFillBackground(true);
219         splashref = &splash;
220     }
221
222     app.processEvents();
223
224     app.setQuitOnLastWindowClosed(false);
225
226     try
227     {
228         // Regenerate startup link, to fix links to old versions
229         if (GUIUtil::GetStartOnSystemStartup())
230             GUIUtil::SetStartOnSystemStartup(true);
231
232         BitcoinGUI window;
233         guiref = &window;
234         if(AppInit2())
235         {
236             {
237                 // Put this in a block, so that the Model objects are cleaned up before
238                 // calling Shutdown().
239
240                 if (splashref)
241                     splash.finish(&window);
242
243                 ClientModel clientModel(&optionsModel);
244                 WalletModel walletModel(pwalletMain, &optionsModel);
245
246                 window.setClientModel(&clientModel);
247                 window.setWalletModel(&walletModel);
248
249                 // If -min option passed, start window minimized.
250                 if(GetBoolArg("-min"))
251                 {
252                     window.showMinimized();
253                 }
254                 else
255                 {
256                     window.show();
257                 }
258
259                 // Place this here as guiref has to be defined if we don't want to lose URIs
260                 ipcInit(argc, argv);
261
262                 app.exec();
263
264                 window.hide();
265                 window.setClientModel(0);
266                 window.setWalletModel(0);
267                 guiref = 0;
268             }
269             // Shutdown the core and its threads, but don't exit Bitcoin-Qt here
270             Shutdown(NULL);
271         }
272         else
273         {
274             return 1;
275         }
276     } catch (std::exception& e) {
277         handleRunawayException(&e);
278     } catch (...) {
279         handleRunawayException(NULL);
280     }
281     return 0;
282 }
283 #endif // BITCOIN_QT_TEST