Merge pull request #1988 from Diapolo/ThreadSafeMessageBox

update CClientUIInterface and remove orphan Wx stuff
This commit is contained in:
Wladimir J. van der Laan 2012-11-27 12:34:18 -08:00
commit 97c8e6389e
12 changed files with 133 additions and 66 deletions

View File

@ -769,7 +769,7 @@ void ThreadRPCServer2(void* parg)
strWhatAmI.c_str(), strWhatAmI.c_str(),
GetConfigFile().string().c_str(), GetConfigFile().string().c_str(),
EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32).c_str()), EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32).c_str()),
_("Error"), CClientUIInterface::OK | CClientUIInterface::MODAL); "", CClientUIInterface::MSG_ERROR);
StartShutdown(); StartShutdown();
return; return;
} }
@ -860,7 +860,7 @@ void ThreadRPCServer2(void* parg)
} }
if (!fListening) { if (!fListening) {
uiInterface.ThreadSafeMessageBox(strerr, _("Error"), CClientUIInterface::OK | CClientUIInterface::MODAL); uiInterface.ThreadSafeMessageBox(strerr, "", CClientUIInterface::MSG_ERROR);
StartShutdown(); StartShutdown();
return; return;
} }

View File

@ -2,6 +2,7 @@
// Copyright (c) 2009-2012 The Bitcoin developers // Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying // Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "txdb.h" #include "txdb.h"
#include "walletdb.h" #include "walletdb.h"
#include "bitcoinrpc.h" #include "bitcoinrpc.h"
@ -9,6 +10,7 @@
#include "init.h" #include "init.h"
#include "util.h" #include "util.h"
#include "ui_interface.h" #include "ui_interface.h"
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp> #include <boost/filesystem/fstream.hpp>
#include <boost/filesystem/convenience.hpp> #include <boost/filesystem/convenience.hpp>
@ -209,17 +211,16 @@ int main(int argc, char* argv[])
bool static InitError(const std::string &str) bool static InitError(const std::string &str)
{ {
uiInterface.ThreadSafeMessageBox(str, _("Bitcoin"), CClientUIInterface::OK | CClientUIInterface::MODAL); uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_ERROR);
return false; return false;
} }
bool static InitWarning(const std::string &str) 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; return true;
} }
bool static Bind(const CService &addr, unsigned int flags) { bool static Bind(const CService &addr, unsigned int flags) {
if (!(flags & BF_EXPLICIT) && IsLimited(addr)) if (!(flags & BF_EXPLICIT) && IsLimited(addr))
return false; return false;
@ -608,7 +609,7 @@ bool AppInit2()
" Original wallet.dat saved as wallet.{timestamp}.bak in %s; if" " Original wallet.dat saved as wallet.{timestamp}.bak in %s; if"
" your balance or transactions are incorrect you should" " your balance or transactions are incorrect you should"
" restore from a backup."), strDataDir.c_str()); " 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) if (r == CDBEnv::RECOVER_FAIL)
return InitError(_("wallet.dat corrupt, salvage failed")); 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" string msg(_("Warning: error reading wallet.dat! All keys read correctly, but transaction data"
" or address book entries might be missing or incorrect.")); " 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) else if (nLoadWalletRet == DB_TOO_NEW)
strErrors << _("Error loading wallet.dat: Wallet requires newer version of Bitcoin") << "\n"; strErrors << _("Error loading wallet.dat: Wallet requires newer version of Bitcoin") << "\n";
@ -914,7 +915,7 @@ bool AppInit2()
//// debug print //// debug print
printf("mapBlockIndex.size() = %"PRIszu"\n", mapBlockIndex.size()); 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("setKeyPool.size() = %"PRIszu"\n", pwalletMain->setKeyPool.size());
printf("mapWallet.size() = %"PRIszu"\n", pwalletMain->mapWallet.size()); printf("mapWallet.size() = %"PRIszu"\n", pwalletMain->mapWallet.size());
printf("mapAddressBook.size() = %"PRIszu"\n", pwalletMain->mapAddressBook.size()); printf("mapAddressBook.size() = %"PRIszu"\n", pwalletMain->mapAddressBook.size());

View File

@ -2197,10 +2197,10 @@ bool CheckDiskSpace(uint64 nAdditionalBytes)
if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes) if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
{ {
fShutdown = true; fShutdown = true;
string strMessage = _("Warning: Disk space is low!"); string strMessage = _("Error: Disk space is low!");
strMiscWarning = strMessage; strMiscWarning = strMessage;
printf("*** %s\n", strMessage.c_str()); printf("*** %s\n", strMessage.c_str());
uiInterface.ThreadSafeMessageBox(strMessage, "Bitcoin", CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL); uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_ERROR);
StartShutdown(); StartShutdown();
return false; return false;
} }
@ -3681,7 +3681,6 @@ public:
CBlock* CreateNewBlock(CReserveKey& reservekey) CBlock* CreateNewBlock(CReserveKey& reservekey)
{ {
// Create new block // Create new block
auto_ptr<CBlock> pblock(new CBlock()); auto_ptr<CBlock> pblock(new CBlock());
if (!pblock.get()) if (!pblock.get())

View File

@ -2,16 +2,33 @@
// Copyright (c) 2009-2012 The Bitcoin developers // Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying // Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "ui_interface.h" #include "ui_interface.h"
#include "init.h" #include "init.h"
#include "bitcoinrpc.h" #include "bitcoinrpc.h"
#include <string> #include <string>
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()); 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; return 4;
} }

View File

@ -7,7 +7,6 @@
#include "optionsmodel.h" #include "optionsmodel.h"
#include "guiutil.h" #include "guiutil.h"
#include "guiconstants.h" #include "guiconstants.h"
#include "init.h" #include "init.h"
#include "ui_interface.h" #include "ui_interface.h"
#include "qtipcserver.h" #include "qtipcserver.h"
@ -35,18 +34,19 @@ Q_IMPORT_PLUGIN(qtaccessiblewidgets)
static BitcoinGUI *guiref; static BitcoinGUI *guiref;
static QSplashScreen *splashref; 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 // Message from network thread
if(guiref) if(guiref)
{ {
bool modal = (style & CClientUIInterface::MODAL); bool modal = (style & CClientUIInterface::MODAL);
// in case of modal message, use blocking connection to wait for user to click OK // In case of modal message, use blocking connection to wait for user to click a button
QMetaObject::invokeMethod(guiref, "error", QMetaObject::invokeMethod(guiref, "message",
modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection, modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
Q_ARG(QString, QString::fromStdString(caption)), Q_ARG(QString, QString::fromStdString(caption)),
Q_ARG(QString, QString::fromStdString(message)), Q_ARG(QString, QString::fromStdString(message)),
Q_ARG(bool, modal)); Q_ARG(bool, modal),
Q_ARG(unsigned int, style));
} }
else else
{ {

View File

@ -25,6 +25,7 @@
#include "notificator.h" #include "notificator.h"
#include "guiutil.h" #include "guiutil.h"
#include "rpcconsole.h" #include "rpcconsole.h"
#include "ui_interface.h"
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
#include "macdockiconhandler.h" #include "macdockiconhandler.h"
@ -366,8 +367,8 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel)
setNumBlocks(clientModel->getNumBlocks(), clientModel->getNumBlocksOfPeers()); setNumBlocks(clientModel->getNumBlocks(), clientModel->getNumBlocksOfPeers());
connect(clientModel, SIGNAL(numBlocksChanged(int,int)), this, SLOT(setNumBlocks(int,int))); connect(clientModel, SIGNAL(numBlocksChanged(int,int)), this, SLOT(setNumBlocks(int,int)));
// Report errors from network/worker thread // Receive and report messages from network/worker thread
connect(clientModel, SIGNAL(error(QString,QString,bool)), this, SLOT(error(QString,QString,bool))); connect(clientModel, SIGNAL(message(QString,QString,bool,unsigned int)), this, SLOT(message(QString,QString,bool,unsigned int)));
overviewPage->setClientModel(clientModel); overviewPage->setClientModel(clientModel);
rpcConsole->setClientModel(clientModel); rpcConsole->setClientModel(clientModel);
@ -381,8 +382,8 @@ void BitcoinGUI::setWalletModel(WalletModel *walletModel)
this->walletModel = walletModel; this->walletModel = walletModel;
if(walletModel) if(walletModel)
{ {
// Report errors from wallet thread // Receive and report messages from wallet thread
connect(walletModel, SIGNAL(error(QString,QString,bool)), this, SLOT(error(QString,QString,bool))); connect(walletModel, SIGNAL(message(QString,QString,bool,unsigned int)), this, SLOT(message(QString,QString,bool,unsigned int)));
// Put transaction list in tabs // Put transaction list in tabs
transactionView->setModel(walletModel); transactionView->setModel(walletModel);
@ -592,15 +593,50 @@ void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks)
progressBar->setToolTip(tooltip); 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 QString strTitle = tr("Bitcoin") + " - ";
if(modal) // Default to information icon
{ int nMBoxIcon = QMessageBox::Information;
QMessageBox::critical(this, title, message, QMessageBox::Ok, QMessageBox::Ok); int nNotifyIcon = Notificator::Information;
} else {
notificator->notify(Notificator::Critical, title, message); // 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) void BitcoinGUI::changeEvent(QEvent *e)

View File

@ -119,8 +119,14 @@ public slots:
*/ */
void setEncryptionStatus(int status); void setEncryptionStatus(int status);
/** Notify the user of an error in the network or transaction handling code. */ /** Notify the user of an event from the core network or transaction handling code.
void error(const QString &title, const QString &message, bool modal); @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. /** 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 It is currently not possible to pass a return value to another thread through
BlockingQueuedConnection, so an indirected pointer is used. BlockingQueuedConnection, so an indirected pointer is used.

View File

@ -84,7 +84,7 @@ void ClientModel::updateAlert(const QString &hash, int status)
CAlert alert = CAlert::getAlertByHash(hash_256); CAlert alert = CAlert::getAlertByHash(hash_256);
if(!alert.IsNull()) 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);
} }
} }

View File

@ -70,8 +70,8 @@ signals:
void numBlocksChanged(int count, int countOfPeers); void numBlocksChanged(int count, int countOfPeers);
void alertsChanged(const QString &warnings); void alertsChanged(const QString &warnings);
//! Asynchronous error notification //! Asynchronous message notification
void error(const QString &title, const QString &message, bool modal); void message(const QString &title, const QString &message, bool modal, unsigned int style);
public slots: public slots:
void updateTimer(); void updateTimer();

View File

@ -147,8 +147,8 @@ signals:
// this means that the unlocking failed or was cancelled. // this means that the unlocking failed or was cancelled.
void requireUnlock(); void requireUnlock();
// Asynchronous error notification // Asynchronous message notification
void error(const QString &title, const QString &message, bool modal); void message(const QString &title, const QString &message, bool modal, unsigned int style);
public slots: public slots:
/* Wallet status might have changed */ /* Wallet status might have changed */

View File

@ -29,38 +29,46 @@ public:
/** Flags for CClientUIInterface::ThreadSafeMessageBox */ /** Flags for CClientUIInterface::ThreadSafeMessageBox */
enum MessageBoxFlags enum MessageBoxFlags
{ {
YES = 0x00000002, ICON_INFORMATION = 0,
OK = 0x00000004, ICON_WARNING = (1U << 0),
NO = 0x00000008, ICON_ERROR = (1U << 1),
YES_NO = (YES|NO), /**
CANCEL = 0x00000010, * Mask of all available icons in CClientUIInterface::MessageBoxFlags
APPLY = 0x00000020, * This needs to be updated, when icons are changed there!
CLOSE = 0x00000040, */
OK_DEFAULT = 0x00000000, ICON_MASK = (ICON_INFORMATION | ICON_WARNING | ICON_ERROR),
YES_DEFAULT = 0x00000000,
NO_DEFAULT = 0x00000080, /** These values are taken from qmessagebox.h "enum StandardButton" to be directly usable */
CANCEL_DEFAULT = 0x80000000, BTN_OK = 0x00000400U, // QMessageBox::Ok
ICON_EXCLAMATION = 0x00000100, BTN_YES = 0x00004000U, // QMessageBox::Yes
ICON_HAND = 0x00000200, BTN_NO = 0x00010000U, // QMessageBox::No
ICON_WARNING = ICON_EXCLAMATION, BTN_ABORT = 0x00040000U, // QMessageBox::Abort
ICON_ERROR = ICON_HAND, BTN_RETRY = 0x00080000U, // QMessageBox::Retry
ICON_QUESTION = 0x00000400, BTN_IGNORE = 0x00100000U, // QMessageBox::Ignore
ICON_INFORMATION = 0x00000800, BTN_CLOSE = 0x00200000U, // QMessageBox::Close
ICON_STOP = ICON_HAND, BTN_CANCEL = 0x00400000U, // QMessageBox::Cancel
ICON_ASTERISK = ICON_INFORMATION, BTN_DISCARD = 0x00800000U, // QMessageBox::Discard
ICON_MASK = (0x00000100|0x00000200|0x00000400|0x00000800), BTN_HELP = 0x01000000U, // QMessageBox::Help
FORWARD = 0x00001000, BTN_APPLY = 0x02000000U, // QMessageBox::Apply
BACKWARD = 0x00002000, BTN_RESET = 0x04000000U, // QMessageBox::Reset
RESET = 0x00004000, /**
HELP = 0x00008000, * Mask of all available buttons in CClientUIInterface::MessageBoxFlags
MORE = 0x00010000, * This needs to be updated, when buttons are changed there!
SETUP = 0x00020000, */
// Force blocking, modal message box dialog (not just OS notification) BTN_MASK = (BTN_OK | BTN_YES | BTN_NO | BTN_ABORT | BTN_RETRY | BTN_IGNORE |
MODAL = 0x00040000 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. */ /** Show message box. */
boost::signals2::signal<void (const std::string& message, const std::string& caption, int style)> ThreadSafeMessageBox; boost::signals2::signal<void (const std::string& message, const std::string& caption, unsigned int style)> ThreadSafeMessageBox;
/** Ask the user whether they want to pay a fee or not. */ /** Ask the user whether they want to pay a fee or not. */
boost::signals2::signal<bool (int64 nFeeRequired, const std::string& strCaption), boost::signals2::last_value<bool> > ThreadSafeAskFee; boost::signals2::signal<bool (int64 nFeeRequired, const std::string& strCaption), boost::signals2::last_value<bool> > ThreadSafeAskFee;

View File

@ -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."); 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; strMiscWarning = strMessage;
printf("*** %s\n", strMessage.c_str()); printf("*** %s\n", strMessage.c_str());
uiInterface.ThreadSafeMessageBox(strMessage+" ", string("Bitcoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION); uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING);
} }
} }
} }