diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 07b616438..481ceb9f4 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -769,7 +769,7 @@ void ThreadRPCServer2(void* parg) strWhatAmI.c_str(), GetConfigFile().string().c_str(), EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32).c_str()), - _("Error"), CClientUIInterface::OK | CClientUIInterface::MODAL); + "", CClientUIInterface::MSG_ERROR); StartShutdown(); return; } @@ -860,7 +860,7 @@ void ThreadRPCServer2(void* parg) } if (!fListening) { - uiInterface.ThreadSafeMessageBox(strerr, _("Error"), CClientUIInterface::OK | CClientUIInterface::MODAL); + uiInterface.ThreadSafeMessageBox(strerr, "", CClientUIInterface::MSG_ERROR); StartShutdown(); return; } diff --git a/src/init.cpp b/src/init.cpp index 06f7359f8..e0fbb3133 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -2,6 +2,7 @@ // Copyright (c) 2009-2012 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. + #include "txdb.h" #include "walletdb.h" #include "bitcoinrpc.h" @@ -9,6 +10,7 @@ #include "init.h" #include "util.h" #include "ui_interface.h" + #include #include #include @@ -209,17 +211,16 @@ int main(int argc, char* argv[]) bool static InitError(const std::string &str) { - uiInterface.ThreadSafeMessageBox(str, _("Bitcoin"), CClientUIInterface::OK | CClientUIInterface::MODAL); + uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_ERROR); return false; } bool static InitWarning(const std::string &str) { - uiInterface.ThreadSafeMessageBox(str, _("Bitcoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL); + uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_WARNING); return true; } - bool static Bind(const CService &addr, unsigned int flags) { if (!(flags & BF_EXPLICIT) && IsLimited(addr)) return false; @@ -608,7 +609,7 @@ bool AppInit2() " Original wallet.dat saved as wallet.{timestamp}.bak in %s; if" " your balance or transactions are incorrect you should" " restore from a backup."), strDataDir.c_str()); - uiInterface.ThreadSafeMessageBox(msg, _("Bitcoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL); + InitWarning(msg); } if (r == CDBEnv::RECOVER_FAIL) return InitError(_("wallet.dat corrupt, salvage failed")); @@ -808,7 +809,7 @@ bool AppInit2() { string msg(_("Warning: error reading wallet.dat! All keys read correctly, but transaction data" " or address book entries might be missing or incorrect.")); - uiInterface.ThreadSafeMessageBox(msg, _("Bitcoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL); + InitWarning(msg); } else if (nLoadWalletRet == DB_TOO_NEW) strErrors << _("Error loading wallet.dat: Wallet requires newer version of Bitcoin") << "\n"; @@ -914,7 +915,7 @@ bool AppInit2() //// debug print printf("mapBlockIndex.size() = %"PRIszu"\n", mapBlockIndex.size()); - printf("nBestHeight = %d\n", nBestHeight); + printf("nBestHeight = %d\n", nBestHeight); printf("setKeyPool.size() = %"PRIszu"\n", pwalletMain->setKeyPool.size()); printf("mapWallet.size() = %"PRIszu"\n", pwalletMain->mapWallet.size()); printf("mapAddressBook.size() = %"PRIszu"\n", pwalletMain->mapAddressBook.size()); diff --git a/src/main.cpp b/src/main.cpp index 4c2115688..8279924a3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2197,10 +2197,10 @@ bool CheckDiskSpace(uint64 nAdditionalBytes) if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes) { fShutdown = true; - string strMessage = _("Warning: Disk space is low!"); + string strMessage = _("Error: Disk space is low!"); strMiscWarning = strMessage; printf("*** %s\n", strMessage.c_str()); - uiInterface.ThreadSafeMessageBox(strMessage, "Bitcoin", CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL); + uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_ERROR); StartShutdown(); return false; } @@ -3681,7 +3681,6 @@ public: CBlock* CreateNewBlock(CReserveKey& reservekey) { - // Create new block auto_ptr pblock(new CBlock()); if (!pblock.get()) diff --git a/src/noui.cpp b/src/noui.cpp index db25f2d28..ba2b1aab4 100644 --- a/src/noui.cpp +++ b/src/noui.cpp @@ -2,16 +2,33 @@ // Copyright (c) 2009-2012 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. + #include "ui_interface.h" #include "init.h" #include "bitcoinrpc.h" #include -static int noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style) +static int noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style) { + std::string strCaption; + // Check for usage of predefined caption + switch (style) { + case CClientUIInterface::MSG_ERROR: + strCaption += _("Error"); + break; + case CClientUIInterface::MSG_WARNING: + strCaption += _("Warning"); + break; + case CClientUIInterface::MSG_INFORMATION: + strCaption += _("Information"); + break; + default: + strCaption += caption; // Use supplied caption + } + printf("%s: %s\n", caption.c_str(), message.c_str()); - fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str()); + fprintf(stderr, "%s: %s\n", strCaption.c_str(), message.c_str()); return 4; } diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index cd1764a53..d64114e13 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -7,7 +7,6 @@ #include "optionsmodel.h" #include "guiutil.h" #include "guiconstants.h" - #include "init.h" #include "ui_interface.h" #include "qtipcserver.h" @@ -35,18 +34,19 @@ Q_IMPORT_PLUGIN(qtaccessiblewidgets) static BitcoinGUI *guiref; static QSplashScreen *splashref; -static void ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style) +static void ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style) { // Message from network thread if(guiref) { bool modal = (style & CClientUIInterface::MODAL); - // in case of modal message, use blocking connection to wait for user to click OK - QMetaObject::invokeMethod(guiref, "error", + // In case of modal message, use blocking connection to wait for user to click a button + QMetaObject::invokeMethod(guiref, "message", modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection, Q_ARG(QString, QString::fromStdString(caption)), Q_ARG(QString, QString::fromStdString(message)), - Q_ARG(bool, modal)); + Q_ARG(bool, modal), + Q_ARG(unsigned int, style)); } else { diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 0198a92c0..e2350c09e 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -25,6 +25,7 @@ #include "notificator.h" #include "guiutil.h" #include "rpcconsole.h" +#include "ui_interface.h" #ifdef Q_OS_MAC #include "macdockiconhandler.h" @@ -366,8 +367,8 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel) setNumBlocks(clientModel->getNumBlocks(), clientModel->getNumBlocksOfPeers()); connect(clientModel, SIGNAL(numBlocksChanged(int,int)), this, SLOT(setNumBlocks(int,int))); - // Report errors from network/worker thread - connect(clientModel, SIGNAL(error(QString,QString,bool)), this, SLOT(error(QString,QString,bool))); + // Receive and report messages from network/worker thread + connect(clientModel, SIGNAL(message(QString,QString,bool,unsigned int)), this, SLOT(message(QString,QString,bool,unsigned int))); overviewPage->setClientModel(clientModel); rpcConsole->setClientModel(clientModel); @@ -381,8 +382,8 @@ void BitcoinGUI::setWalletModel(WalletModel *walletModel) this->walletModel = walletModel; if(walletModel) { - // Report errors from wallet thread - connect(walletModel, SIGNAL(error(QString,QString,bool)), this, SLOT(error(QString,QString,bool))); + // Receive and report messages from wallet thread + connect(walletModel, SIGNAL(message(QString,QString,bool,unsigned int)), this, SLOT(message(QString,QString,bool,unsigned int))); // Put transaction list in tabs transactionView->setModel(walletModel); @@ -592,15 +593,50 @@ void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks) progressBar->setToolTip(tooltip); } -void BitcoinGUI::error(const QString &title, const QString &message, bool modal) +void BitcoinGUI::message(const QString &title, const QString &message, bool modal, unsigned int style) { - // Report errors from network/worker thread - if(modal) - { - QMessageBox::critical(this, title, message, QMessageBox::Ok, QMessageBox::Ok); - } else { - notificator->notify(Notificator::Critical, title, message); + QString strTitle = tr("Bitcoin") + " - "; + // Default to information icon + int nMBoxIcon = QMessageBox::Information; + int nNotifyIcon = Notificator::Information; + + // Check for usage of predefined title + switch (style) { + case CClientUIInterface::MSG_ERROR: + strTitle += tr("Error"); + break; + case CClientUIInterface::MSG_WARNING: + strTitle += tr("Warning"); + break; + case CClientUIInterface::MSG_INFORMATION: + strTitle += tr("Information"); + break; + default: + strTitle += title; // Use supplied title + } + + // Check for error/warning icon + if (style & CClientUIInterface::ICON_ERROR) { + nMBoxIcon = QMessageBox::Critical; + nNotifyIcon = Notificator::Critical; + } + else if (style & CClientUIInterface::ICON_WARNING) { + nMBoxIcon = QMessageBox::Warning; + nNotifyIcon = Notificator::Warning; + } + + // Display message + if (modal) { + // Check for buttons, use OK as default, if none was supplied + QMessageBox::StandardButton buttons; + if (!(buttons = (QMessageBox::StandardButton)(style & CClientUIInterface::BTN_MASK))) + buttons = QMessageBox::Ok; + + QMessageBox mBox((QMessageBox::Icon)nMBoxIcon, strTitle, message, buttons); + mBox.exec(); } + else + notificator->notify((Notificator::Class)nNotifyIcon, strTitle, message); } void BitcoinGUI::changeEvent(QEvent *e) diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 8b4607d3e..151b108be 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -119,8 +119,14 @@ public slots: */ void setEncryptionStatus(int status); - /** Notify the user of an error in the network or transaction handling code. */ - void error(const QString &title, const QString &message, bool modal); + /** Notify the user of an event from the core network or transaction handling code. + @param[in] title the message box / notification title + @param[in] message the displayed text + @param[in] modal true to use a message box, false to use a notification + @param[in] style style definitions (icon and used buttons - buttons only for message boxes) + @see CClientUIInterface::MessageBoxFlags + */ + void message(const QString &title, const QString &message, bool modal, unsigned int style); /** Asks the user whether to pay the transaction fee or to cancel the transaction. It is currently not possible to pass a return value to another thread through BlockingQueuedConnection, so an indirected pointer is used. diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 9b7362d75..f8fa41201 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -84,7 +84,7 @@ void ClientModel::updateAlert(const QString &hash, int status) CAlert alert = CAlert::getAlertByHash(hash_256); if(!alert.IsNull()) { - emit error(tr("Network Alert"), QString::fromStdString(alert.strStatusBar), false); + emit message(tr("Network Alert"), QString::fromStdString(alert.strStatusBar), false, CClientUIInterface::ICON_ERROR); } } diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 7d6401ab2..b16b2d500 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -70,8 +70,8 @@ signals: void numBlocksChanged(int count, int countOfPeers); void alertsChanged(const QString &warnings); - //! Asynchronous error notification - void error(const QString &title, const QString &message, bool modal); + //! Asynchronous message notification + void message(const QString &title, const QString &message, bool modal, unsigned int style); public slots: void updateTimer(); diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 62558a49d..3c8d5903b 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -147,8 +147,8 @@ signals: // this means that the unlocking failed or was cancelled. void requireUnlock(); - // Asynchronous error notification - void error(const QString &title, const QString &message, bool modal); + // Asynchronous message notification + void message(const QString &title, const QString &message, bool modal, unsigned int style); public slots: /* Wallet status might have changed */ diff --git a/src/ui_interface.h b/src/ui_interface.h index 0f7fdef26..693411aa6 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -29,38 +29,46 @@ public: /** Flags for CClientUIInterface::ThreadSafeMessageBox */ enum MessageBoxFlags { - YES = 0x00000002, - OK = 0x00000004, - NO = 0x00000008, - YES_NO = (YES|NO), - CANCEL = 0x00000010, - APPLY = 0x00000020, - CLOSE = 0x00000040, - OK_DEFAULT = 0x00000000, - YES_DEFAULT = 0x00000000, - NO_DEFAULT = 0x00000080, - CANCEL_DEFAULT = 0x80000000, - ICON_EXCLAMATION = 0x00000100, - ICON_HAND = 0x00000200, - ICON_WARNING = ICON_EXCLAMATION, - ICON_ERROR = ICON_HAND, - ICON_QUESTION = 0x00000400, - ICON_INFORMATION = 0x00000800, - ICON_STOP = ICON_HAND, - ICON_ASTERISK = ICON_INFORMATION, - ICON_MASK = (0x00000100|0x00000200|0x00000400|0x00000800), - FORWARD = 0x00001000, - BACKWARD = 0x00002000, - RESET = 0x00004000, - HELP = 0x00008000, - MORE = 0x00010000, - SETUP = 0x00020000, - // Force blocking, modal message box dialog (not just OS notification) - MODAL = 0x00040000 + ICON_INFORMATION = 0, + ICON_WARNING = (1U << 0), + ICON_ERROR = (1U << 1), + /** + * Mask of all available icons in CClientUIInterface::MessageBoxFlags + * This needs to be updated, when icons are changed there! + */ + ICON_MASK = (ICON_INFORMATION | ICON_WARNING | ICON_ERROR), + + /** These values are taken from qmessagebox.h "enum StandardButton" to be directly usable */ + BTN_OK = 0x00000400U, // QMessageBox::Ok + BTN_YES = 0x00004000U, // QMessageBox::Yes + BTN_NO = 0x00010000U, // QMessageBox::No + BTN_ABORT = 0x00040000U, // QMessageBox::Abort + BTN_RETRY = 0x00080000U, // QMessageBox::Retry + BTN_IGNORE = 0x00100000U, // QMessageBox::Ignore + BTN_CLOSE = 0x00200000U, // QMessageBox::Close + BTN_CANCEL = 0x00400000U, // QMessageBox::Cancel + BTN_DISCARD = 0x00800000U, // QMessageBox::Discard + BTN_HELP = 0x01000000U, // QMessageBox::Help + BTN_APPLY = 0x02000000U, // QMessageBox::Apply + BTN_RESET = 0x04000000U, // QMessageBox::Reset + /** + * Mask of all available buttons in CClientUIInterface::MessageBoxFlags + * This needs to be updated, when buttons are changed there! + */ + BTN_MASK = (BTN_OK | BTN_YES | BTN_NO | BTN_ABORT | BTN_RETRY | BTN_IGNORE | + BTN_CLOSE | BTN_CANCEL | BTN_DISCARD | BTN_HELP | BTN_APPLY | BTN_RESET), + + /** Force blocking, modal message box dialog (not just OS notification) */ + MODAL = 0x10000000U, + + /** Predefined combinations for certain default usage cases */ + MSG_INFORMATION = (ICON_INFORMATION | BTN_OK), + MSG_WARNING = (ICON_WARNING | BTN_OK | MODAL), + MSG_ERROR = (ICON_ERROR | BTN_OK | MODAL) }; /** Show message box. */ - boost::signals2::signal ThreadSafeMessageBox; + boost::signals2::signal ThreadSafeMessageBox; /** Ask the user whether they want to pay a fee or not. */ boost::signals2::signal > ThreadSafeAskFee; diff --git a/src/util.cpp b/src/util.cpp index 03014a5da..2f36c6606 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1248,7 +1248,7 @@ void AddTimeData(const CNetAddr& ip, int64 nTime) string strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin will not work properly."); strMiscWarning = strMessage; printf("*** %s\n", strMessage.c_str()); - uiInterface.ThreadSafeMessageBox(strMessage+" ", string("Bitcoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION); + uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING); } } }