X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fqt%2Fbitcoin.cpp;h=bfb49cbcab2965daa01bb5f8d5176e9f0850b5f6;hb=fa2544e79faf75923766624acd638e3cbdb9be0d;hp=9b4d88d91f47973633e1d6f8d327f2263a5c43dd;hpb=8c4738d5a7c9c1e6f29c558c49d7948fc357b9e3;p=novacoin.git diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 9b4d88d..bfb49cb 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -1,51 +1,55 @@ /* - * W.J. van der Laan 2011 + * W.J. van der Laan 2011-2012 */ #include "bitcoingui.h" #include "clientmodel.h" #include "walletmodel.h" #include "optionsmodel.h" -#include "qtwin.h" +#include "guiutil.h" #include "headers.h" #include "init.h" +#include "qtipcserver.h" #include #include -#include +#include #include #include #include +#include -// Need a global reference for the notifications to find the GUI -BitcoinGUI *guiref; -QSplashScreen *splashref; +#include -int MyMessageBox(const std::string& message, const std::string& caption, int style, wxWindow* parent, int x, int y) -{ - // Message from main thread - if(guiref) - { - guiref->error(QString::fromStdString(caption), - QString::fromStdString(message)); - } - else - { - QMessageBox::critical(0, QString::fromStdString(caption), - QString::fromStdString(message), - QMessageBox::Ok, QMessageBox::Ok); - } - return 4; -} +#if defined(BITCOIN_NEED_QT_PLUGINS) && !defined(_BITCOIN_QT_PLUGINS_INCLUDED) +#define _BITCOIN_QT_PLUGINS_INCLUDED +#define __INSURE__ +#include +Q_IMPORT_PLUGIN(qcncodecs) +Q_IMPORT_PLUGIN(qjpcodecs) +Q_IMPORT_PLUGIN(qtwcodecs) +Q_IMPORT_PLUGIN(qkrcodecs) +Q_IMPORT_PLUGIN(qtaccessiblewidgets) +#endif -int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style, wxWindow* parent, int x, int y) +// Need a global reference for the notifications to find the GUI +static BitcoinGUI *guiref; +static QSplashScreen *splashref; +static WalletModel *walletmodel; +static ClientModel *clientmodel; + +int 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 & wxMODAL); + // 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 { @@ -55,7 +59,7 @@ int ThreadSafeMessageBox(const std::string& message, const std::string& caption, return 4; } -bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption, wxWindow* parent) +bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption) { if(!guiref) return false; @@ -63,33 +67,34 @@ bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption, wxWindo return true; bool payFee = false; - // Call slot on GUI thread. - // If called from another thread, use a blocking QueuedConnection. - Qt::ConnectionType connectionType = Qt::DirectConnection; - if(QThread::currentThread() != QCoreApplication::instance()->thread()) - { - connectionType = Qt::BlockingQueuedConnection; - } - - QMetaObject::invokeMethod(guiref, "askFee", connectionType, + QMetaObject::invokeMethod(guiref, "askFee", GUIUtil::blockingGUIThreadConnection(), Q_ARG(qint64, nFeeRequired), Q_ARG(bool*, &payFee)); return payFee; } -void CalledSetStatusBar(const std::string& strText, int nField) +void ThreadSafeHandleURI(const std::string& strURI) { - // Only used for built-in mining, which is disabled, simple ignore + if(!guiref) + return; + + QMetaObject::invokeMethod(guiref, "handleURI", GUIUtil::blockingGUIThreadConnection(), + Q_ARG(QString, QString::fromStdString(strURI))); } -void UIThreadCall(boost::function0 fn) +void MainFrameRepaint() { - // Only used for built-in mining, which is disabled, simple ignore + if(clientmodel) + QMetaObject::invokeMethod(clientmodel, "update", Qt::QueuedConnection); + if(walletmodel) + QMetaObject::invokeMethod(walletmodel, "update", Qt::QueuedConnection); } -void MainFrameRepaint() +void AddressBookRepaint() { + if(walletmodel) + QMetaObject::invokeMethod(walletmodel, "updateAddressList", Qt::QueuedConnection); } void InitMessage(const std::string &message) @@ -101,6 +106,11 @@ void InitMessage(const std::string &message) } } +void QueueShutdown() +{ + QMetaObject::invokeMethod(QCoreApplication::instance(), "quit", Qt::QueuedConnection); +} + /* Translate string to current locale using Qt. */ @@ -109,21 +119,97 @@ std::string _(const char* psz) return QCoreApplication::translate("bitcoin-core", psz).toStdString(); } +#ifdef WIN32 +#define strncasecmp strnicmp +#endif +#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 *strURI = argv[i]; + try { + boost::interprocess::message_queue mq(boost::interprocess::open_only, BITCOINURI_QUEUE_NAME); + if(mq.try_send(strURI, strlen(strURI), 0)) + exit(0); + else + break; + } + catch (boost::interprocess::interprocess_exception &ex) { + break; + } + } + } +#endif + + // Internal string conversion is all UTF-8 + QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8")); + QTextCodec::setCodecForCStrings(QTextCodec::codecForTr()); + Q_INIT_RESOURCE(bitcoin); QApplication app(argc, argv); - // Load language file for system locale - QString locale = QLocale::system().name(); - QTranslator translator; - translator.load("bitcoin_"+locale); - app.installTranslator(&translator); + // Command-line options take precedence: + ParseParameters(argc, argv); + + // ... then bitcoin.conf: + if (!ReadConfigFile(mapArgs, mapMultiArgs)) + { + fprintf(stderr, "Error: Specified directory does not exist\n"); + 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"); + + // ... 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); QSplashScreen splash(QPixmap(":/images/splash"), 0); - splash.show(); - splash.setAutoFillBackground(true); - splashref = &splash; + if (GetBoolArg("-splash", true) && !GetBoolArg("-min")) + { + splash.show(); + splash.setAutoFillBackground(true); + splashref = &splash; + } app.processEvents(); @@ -131,44 +217,65 @@ int main(int argc, char *argv[]) try { + BitcoinGUI window; + guiref = &window; if(AppInit2(argc, argv)) { { - // Put this in a block, so that BitcoinGUI is cleaned up properly before + // Put this in a block, so that the Model objects are cleaned up before // calling Shutdown(). - BitcoinGUI window; - splash.finish(&window); - OptionsModel optionsModel(pwalletMain); + + optionsModel.Upgrade(); // Must be done after AppInit2 + + if (splashref) + splash.finish(&window); + ClientModel clientModel(&optionsModel); + clientmodel = &clientModel; WalletModel walletModel(pwalletMain, &optionsModel); + walletmodel = &walletModel; - guiref = &window; window.setClientModel(&clientModel); window.setWalletModel(&walletModel); - if (QtWin::isCompositionEnabled()) + // If -min option passed, start window minimized. + if(GetBoolArg("-min")) { -#ifdef Q_WS_WIN32 - // Windows-specific customization - window.setAttribute(Qt::WA_TranslucentBackground); - window.setAttribute(Qt::WA_NoSystemBackground, false); - QPalette pal = window.palette(); - QColor bg = pal.window().color(); - bg.setAlpha(0); - pal.setColor(QPalette::Window, bg); - window.setPalette(pal); - window.ensurePolished(); - window.setAttribute(Qt::WA_StyledBackground, false); -#endif - QtWin::extendFrameIntoClientArea(&window); - window.setContentsMargins(0, 0, 0, 0); + window.showMinimized(); + } + else + { + window.show(); } - window.show(); + // Place this here as guiref has to be defined if we dont want to lose URIs + ipcInit(); + +#if !defined(MAC_OSX) && !defined(WIN32) +// TODO: implement qtipcserver.cpp for Mac and Windows + // Check for URI in argv + for (int i = 1; i < argc; i++) + { + if (strlen(argv[i]) > 7 && strncasecmp(argv[i], "bitcoin:", 8) == 0) + { + const char *strURI = argv[i]; + try { + boost::interprocess::message_queue mq(boost::interprocess::open_only, BITCOINURI_QUEUE_NAME); + mq.try_send(strURI, strlen(strURI), 0); + } + catch (boost::interprocess::interprocess_exception &ex) { + } + } + } +#endif app.exec(); + window.setClientModel(0); + window.setWalletModel(0); guiref = 0; + clientmodel = 0; + walletmodel = 0; } Shutdown(NULL); } @@ -183,3 +290,4 @@ int main(int argc, char *argv[]) } return 0; } +#endif // BITCOIN_QT_TEST