ecoin.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. // ECOin - Copyright (c) - 2014/2024 - GPLv3 - epsylon@riseup.net (https://03c8.net)
  2. #include "ecoingui.h"
  3. #include "clientmodel.h"
  4. #include "walletmodel.h"
  5. #include "optionsmodel.h"
  6. #include "guiutil.h"
  7. #include "guiutil.cpp"
  8. #include "guiconstants.h"
  9. #include "init.h"
  10. #include "ui_interface.h"
  11. #include "qtipcserver.h"
  12. #include <QApplication>
  13. #include <QMessageBox>
  14. #include <QTextCodec>
  15. #include <QLocale>
  16. #include <QTranslator>
  17. #include <QSplashScreen>
  18. #include <QLibraryInfo>
  19. #if defined(ECOIN_NEED_QT_PLUGINS) && !defined(_ECOIN_QT_PLUGINS_INCLUDED)
  20. #define _ECOIN_QT_PLUGINS_INCLUDED
  21. #define __INSURE__
  22. #include <QtPlugin>
  23. Q_IMPORT_PLUGIN(qcncodecs)
  24. Q_IMPORT_PLUGIN(qjpcodecs)
  25. Q_IMPORT_PLUGIN(qtwcodecs)
  26. Q_IMPORT_PLUGIN(qkrcodecs)
  27. Q_IMPORT_PLUGIN(qtaccessiblewidgets)
  28. #endif
  29. // Need a global reference for the notifications to find the GUI
  30. static EcoinGUI *guiref;
  31. static QSplashScreen *splashref;
  32. static void ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style)
  33. {
  34. // Message from network thread
  35. if(guiref)
  36. {
  37. bool modal = (style & CClientUIInterface::MODAL);
  38. // in case of modal message, use blocking connection to wait for user to click OK
  39. QMetaObject::invokeMethod(guiref, "error",
  40. modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
  41. Q_ARG(QString, QString::fromStdString(caption)),
  42. Q_ARG(QString, QString::fromStdString(message)),
  43. Q_ARG(bool, modal));
  44. }
  45. else
  46. {
  47. printf("%s: %s\n", caption.c_str(), message.c_str());
  48. fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str());
  49. }
  50. }
  51. static bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption)
  52. {
  53. if(!guiref)
  54. return false;
  55. if(nFeeRequired < MIN_TX_FEE || nFeeRequired <= nTransactionFee || fDaemon)
  56. return true;
  57. bool payFee = false;
  58. QMetaObject::invokeMethod(guiref, "askFee", GUIUtil::blockingGUIThreadConnection(),
  59. Q_ARG(qint64, nFeeRequired),
  60. Q_ARG(bool*, &payFee));
  61. return payFee;
  62. }
  63. static void ThreadSafeHandleURI(const std::string& strURI)
  64. {
  65. if(!guiref)
  66. return;
  67. QMetaObject::invokeMethod(guiref, "handleURI", GUIUtil::blockingGUIThreadConnection(),
  68. Q_ARG(QString, QString::fromStdString(strURI)));
  69. }
  70. static void InitMessage(const std::string &message)
  71. {
  72. if(splashref)
  73. {
  74. splashref->showMessage(QString::fromStdString(message), Qt::AlignBottom|Qt::AlignHCenter, QColor(255,255,200));
  75. QApplication::instance()->processEvents();
  76. }
  77. }
  78. static void QueueShutdown()
  79. {
  80. QMetaObject::invokeMethod(QCoreApplication::instance(), "quit", Qt::QueuedConnection);
  81. }
  82. /*
  83. Translate string to current locale using Qt.
  84. */
  85. static std::string Translate(const char* psz)
  86. {
  87. return QCoreApplication::translate("ecoin-core", psz).toStdString();
  88. }
  89. /* Handle runaway exceptions. Shows a message box with the problem and quits the program.
  90. */
  91. static void handleRunawayException(std::exception *e)
  92. {
  93. PrintExceptionContinue(e, "Runaway exception");
  94. QMessageBox::critical(0, "Runaway exception", EcoinGUI::tr("A fatal error occurred. Ecoin can no longer continue safely and will quit.") + QString("\n\n") + QString::fromStdString(strMiscWarning));
  95. exit(1);
  96. }
  97. #ifndef ECOIN_QT_TEST
  98. int main(int argc, char *argv[])
  99. {
  100. // Do this early as we don't want to bother initializing if we are just calling IPC
  101. ipcScanRelay(argc, argv);
  102. // Internal string conversion is all UTF-8
  103. QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
  104. Q_INIT_RESOURCE(ecoin);
  105. QApplication app(argc, argv);
  106. // Install global event filter that makes sure that long tooltips can be word-wrapped
  107. app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app));
  108. // Command-line options take precedence:
  109. ParseParameters(argc, argv);
  110. if (!boost::filesystem::is_directory(GetDataDir(false)))
  111. {
  112. QMessageBox::critical(0, "Ecoin",
  113. QString("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(mapArgs["-datadir"])));
  114. return 1;
  115. }
  116. ReadConfigFile(mapArgs, mapMultiArgs);
  117. app.setOrganizationName("Ecoin");
  118. app.setOrganizationDomain("ecoin.su");
  119. if(GetBoolArg("-testnet")) // Separate UI settings for testnet
  120. app.setApplicationName("Ecoin-Qt-testnet");
  121. else
  122. app.setApplicationName("Ecoin-Qt");
  123. OptionsModel optionsModel;
  124. QString lang_territory = QString::fromStdString(GetArg("-lang", QLocale::system().name().toStdString()));
  125. QString lang = lang_territory;
  126. lang.truncate(lang_territory.lastIndexOf('_'));
  127. QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
  128. if (qtTranslatorBase.load("qt_" + lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
  129. app.installTranslator(&qtTranslatorBase);
  130. if (qtTranslator.load("qt_" + lang_territory, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
  131. app.installTranslator(&qtTranslator);
  132. if (translatorBase.load(lang, ":/translations/"))
  133. app.installTranslator(&translatorBase);
  134. if (translator.load(lang_territory, ":/translations/"))
  135. app.installTranslator(&translator);
  136. uiInterface.ThreadSafeMessageBox.connect(ThreadSafeMessageBox);
  137. uiInterface.ThreadSafeAskFee.connect(ThreadSafeAskFee);
  138. uiInterface.ThreadSafeHandleURI.connect(ThreadSafeHandleURI);
  139. uiInterface.InitMessage.connect(InitMessage);
  140. uiInterface.QueueShutdown.connect(QueueShutdown);
  141. uiInterface.Translate.connect(Translate);
  142. if (mapArgs.count("-?") || mapArgs.count("--help"))
  143. {
  144. GUIUtil::HelpMessageBox help;
  145. help.showOrPrint();
  146. return 1;
  147. }
  148. QSplashScreen splash(QPixmap(":/images/splash"), 0);
  149. if (GetBoolArg("-splash", true) && !GetBoolArg("-min"))
  150. {
  151. splash.show();
  152. splash.setAutoFillBackground(true);
  153. splashref = &splash;
  154. }
  155. app.processEvents();
  156. app.setQuitOnLastWindowClosed(false);
  157. try
  158. {
  159. // Regenerate startup link, to fix links to old versions
  160. if (GUIUtil::GetStartOnSystemStartup())
  161. GUIUtil::SetStartOnSystemStartup(true);
  162. EcoinGUI window;
  163. guiref = &window;
  164. if(AppInit2())
  165. {
  166. {
  167. optionsModel.Upgrade(); // Must be done after AppInit2
  168. if (splashref)
  169. splash.finish(&window);
  170. ClientModel clientModel(&optionsModel);
  171. WalletModel walletModel(pwalletMain, &optionsModel);
  172. window.setClientModel(&clientModel);
  173. window.setWalletModel(&walletModel);
  174. // If -min option passed, start window minimized.
  175. if(GetBoolArg("-min"))
  176. {
  177. window.showMinimized();
  178. }
  179. else
  180. {
  181. window.show();
  182. }
  183. // Place this here as guiref has to be defined if we don't want to lose URIs
  184. ipcInit(argc, argv);
  185. app.exec();
  186. window.hide();
  187. window.setClientModel(0);
  188. window.setWalletModel(0);
  189. guiref = 0;
  190. }
  191. // Shutdown the core and its threads, but don't exit Ecoin-Qt here
  192. Shutdown(NULL);
  193. }
  194. else
  195. {
  196. return 1;
  197. }
  198. } catch (std::exception& e) {
  199. handleRunawayException(&e);
  200. } catch (...) {
  201. handleRunawayException(NULL);
  202. }
  203. return 0;
  204. }
  205. #endif // ECOIN_QT_TEST