X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fqt%2Fbitcoin.cpp;h=f856c3904eb847d153bc1bdd214810d7237d90e3;hb=HEAD;hp=0f7c96e6a80611fd9a2ffe7089f3100113a449ab;hpb=7e7bcce2d992c6fd53fdc4d9eb40f21c951d5347;p=novacoin.git diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 0f7c96e..f856c39 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -6,20 +6,24 @@ #include "walletmodel.h" #include "optionsmodel.h" #include "guiutil.h" +#include "guiconstants.h" -#include "headers.h" #include "init.h" +#include "main.h" +#include "interface.h" #include "qtipcserver.h" +#include "intro.h" #include #include +#if QT_VERSION < 0x050000 #include +#endif #include #include #include #include - -#include +#include #if defined(BITCOIN_NEED_QT_PLUGINS) && !defined(_BITCOIN_QT_PLUGINS_INCLUDED) #define _BITCOIN_QT_PLUGINS_INCLUDED @@ -33,36 +37,63 @@ Q_IMPORT_PLUGIN(qtaccessiblewidgets) #endif // Need a global reference for the notifications to find the GUI -BitcoinGUI *guiref; -QSplashScreen *splashref; +static BitcoinGUI *guiref; +static QSplashScreen *splashref; -int MyMessageBox(const std::string& message, const std::string& caption, int style, wxWindow* parent, int x, int y) +/** Set up translations */ +static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator) { - // Message from AppInit2(), always in main thread before main window is constructed - QMessageBox::critical(0, QString::fromStdString(caption), - QString::fromStdString(message), - QMessageBox::Ok, QMessageBox::Ok); - return 4; + 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); } -int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style, wxWindow* parent, int x, int y) +static void ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style) { // Message from network thread if(guiref) { - QMetaObject::invokeMethod(guiref, "error", Qt::QueuedConnection, + bool modal = (style & CClientUIInterface::MODAL); + // in case of modal message, use blocking connection to wait for user to click OK + QMetaObject::invokeMethod(guiref, "error", + modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection, Q_ARG(QString, QString::fromStdString(caption)), - Q_ARG(QString, QString::fromStdString(message))); + Q_ARG(QString, QString::fromStdString(message)), + Q_ARG(bool, modal)); } else { printf("%s: %s\n", caption.c_str(), message.c_str()); fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str()); } - return 4; } -bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption, wxWindow* parent) +static bool ThreadSafeAskFee(int64_t nFeeRequired, const std::string& strCaption) { if(!guiref) return false; @@ -77,32 +108,16 @@ bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption, wxWindo return payFee; } -void ThreadSafeHandleURL(const std::string& strURL) +static void ThreadSafeHandleURI(const std::string& strURI) { if(!guiref) return; - QMetaObject::invokeMethod(guiref, "handleURL", GUIUtil::blockingGUIThreadConnection(), - Q_ARG(QString, QString::fromStdString(strURL))); -} - -void CalledSetStatusBar(const std::string& strText, int nField) -{ - // Only used for built-in mining, which is disabled, simple ignore + QMetaObject::invokeMethod(guiref, "handleURI", GUIUtil::blockingGUIThreadConnection(), + Q_ARG(QString, QString::fromStdString(strURI))); } -void UIThreadCall(boost::function0 fn) -{ - // Only used for built-in mining, which is disabled, simple ignore -} - -void MainFrameRepaint() -{ - if(guiref) - QMetaObject::invokeMethod(guiref, "refreshStatusBar", Qt::QueuedConnection); -} - -void InitMessage(const std::string &message) +static void InitMessage(const std::string &message) { if(splashref) { @@ -111,97 +126,90 @@ void InitMessage(const std::string &message) } } +static void QueueShutdown() +{ + QMetaObject::invokeMethod(QCoreApplication::instance(), "quit", Qt::QueuedConnection); +} + /* Translate string to current locale using Qt. */ -std::string _(const char* psz) +static std::string Translate(const char* psz) { return QCoreApplication::translate("bitcoin-core", psz).toStdString(); } -#ifdef WIN32 -#define strncasecmp strnicmp -#endif +/* Handle runaway exceptions. Shows a message box with the problem and quits the program. + */ +static void handleRunawayException(std::exception *e) +{ + PrintExceptionContinue(e, "Runaway exception"); + 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)); + exit(1); +} + #ifndef BITCOIN_QT_TEST int main(int argc, char *argv[]) { -#if !defined(MAC_OSX) && !defined(WIN32) -// TODO: implement qtipcserver.cpp for Mac and Windows - // Do this early as we don't want to bother initializing if we are just calling IPC - for (int i = 1; i < argc; i++) - { - if (strlen(argv[i]) > 7 && strncasecmp(argv[i], "bitcoin:", 8) == 0) - { - const char *strURL = argv[i]; - try { - boost::interprocess::message_queue mq(boost::interprocess::open_only, "BitcoinURL"); - if(mq.try_send(strURL, strlen(strURL), 0)) - exit(0); - else - break; - } - catch (boost::interprocess::interprocess_exception &ex) { - break; - } - } - } -#endif - + ipcScanRelay(argc, argv); +#if QT_VERSION < 0x050000 // Internal string conversion is all UTF-8 QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8")); QTextCodec::setCodecForCStrings(QTextCodec::codecForTr()); - +#endif Q_INIT_RESOURCE(bitcoin); QApplication app(argc, argv); + // Application identification (must be set before OptionsModel is initialized, + // as it is used to locate QSettings) + app.setOrganizationName("NovaCoin"); + app.setOrganizationDomain("novacoin.su"); + if(GetBoolArg("-testnet")) // Separate UI settings for testnet + app.setApplicationName("NovaCoin-Qt-testnet"); + else + app.setApplicationName("NovaCoin-Qt"); + // Now that QSettings are accessible, initialize translations + QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator; + initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator); + // Command-line options take precedence: ParseParameters(argc, argv); + // User language is set up: pick a data directory + Intro::pickDataDirectory(); + + // 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 (!ReadConfigFile(mapArgs, mapMultiArgs)) + if (!boost::filesystem::is_directory(GetDataDir(false))) { - fprintf(stderr, "Error: Specified directory does not exist\n"); + QMessageBox::critical(0, "NovaCoin", + QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(mapArgs["-datadir"]))); return 1; } - - // Application identification (must be set before OptionsModel is initialized, - // as it is used to locate QSettings) - app.setOrganizationName("Bitcoin"); - app.setOrganizationDomain("bitcoin.org"); - if(GetBoolArg("-testnet")) // Separate UI settings for testnet - app.setApplicationName("Bitcoin-Qt-testnet"); - else - app.setApplicationName("Bitcoin-Qt"); + ReadConfigFile(mapArgs, mapMultiArgs); // ... then GUI settings: OptionsModel optionsModel; - // Get desired locale ("en_US") from command line or system locale - QString lang_territory = QString::fromStdString(GetArg("-lang", QLocale::system().name().toStdString())); - // Load language files for configured locale: - // - First load the translator for the base language, without territory - // - Then load the more specific locale translator - QString lang = lang_territory; - - lang.truncate(lang_territory.lastIndexOf('_')); // "en" - QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator; - - qtTranslatorBase.load(QLibraryInfo::location(QLibraryInfo::TranslationsPath) + "/qt_" + lang); - if (!qtTranslatorBase.isEmpty()) - app.installTranslator(&qtTranslatorBase); - - qtTranslator.load(QLibraryInfo::location(QLibraryInfo::TranslationsPath) + "/qt_" + lang_territory); - if (!qtTranslator.isEmpty()) - app.installTranslator(&qtTranslator); - - translatorBase.load(":/translations/"+lang); - if (!translatorBase.isEmpty()) - app.installTranslator(&translatorBase); - - translator.load(":/translations/"+lang_territory); - if (!translator.isEmpty()) - app.installTranslator(&translator); + // Subscribe to global signals from core + uiInterface.ThreadSafeMessageBox.connect(ThreadSafeMessageBox); + uiInterface.ThreadSafeAskFee.connect(ThreadSafeAskFee); + uiInterface.ThreadSafeHandleURI.connect(ThreadSafeHandleURI); + uiInterface.InitMessage.connect(InitMessage); + uiInterface.QueueShutdown.connect(QueueShutdown); + uiInterface.Translate.connect(Translate); + + // Show help message immediately after parsing command-line options (for "-lang") and setting locale, + // but before showing splash screen. + if (mapArgs.count("-?") || mapArgs.count("--help")) + { + GUIUtil::HelpMessageBox help; + help.showOrPrint(); + return 1; + } QSplashScreen splash(QPixmap(":/images/splash"), 0); if (GetBoolArg("-splash", true) && !GetBoolArg("-min")) @@ -217,22 +225,24 @@ int main(int argc, char *argv[]) try { - if(AppInit2(argc, argv)) + // Regenerate startup link, to fix links to old versions + if (GUIUtil::GetStartOnSystemStartup()) + GUIUtil::SetStartOnSystemStartup(true); + + BitcoinGUI window; + guiref = &window; + if(AppInit2()) { { - // Put this in a block, so that BitcoinGUI is cleaned up properly before - // calling Shutdown() in case of exceptions. - - optionsModel.Upgrade(); // Must be done after AppInit2 + // Put this in a block, so that the Model objects are cleaned up before + // calling Shutdown(). - BitcoinGUI window; if (splashref) splash.finish(&window); ClientModel clientModel(&optionsModel); WalletModel walletModel(pwalletMain, &optionsModel); - guiref = &window; window.setClientModel(&clientModel); window.setWalletModel(&walletModel); @@ -246,31 +256,17 @@ int main(int argc, char *argv[]) window.show(); } - // Place this here as guiref has to be defined if we dont want to lose URLs - ipcInit(); + // Place this here as guiref has to be defined if we don't want to lose URIs + ipcInit(argc, argv); -#if !defined(MAC_OSX) && !defined(WIN32) -// TODO: implement qtipcserver.cpp for Mac and Windows - - // Check for URL in argv - for (int i = 1; i < argc; i++) - { - if (strlen(argv[i]) > 7 && strncasecmp(argv[i], "bitcoin:", 8) == 0) - { - const char *strURL = argv[i]; - try { - boost::interprocess::message_queue mq(boost::interprocess::open_only, "BitcoinURL"); - mq.try_send(strURL, strlen(strURL), 0); - } - catch (boost::interprocess::interprocess_exception &ex) { - } - } - } -#endif app.exec(); + window.hide(); + window.setClientModel(0); + window.setWalletModel(0); guiref = 0; } + // Shutdown the core and its threads, but don't exit Bitcoin-Qt here Shutdown(NULL); } else @@ -278,9 +274,9 @@ int main(int argc, char *argv[]) return 1; } } catch (std::exception& e) { - PrintException(&e, "Runaway exception"); + handleRunawayException(&e); } catch (...) { - PrintException(NULL, "Runaway exception"); + handleRunawayException(NULL); } return 0; }