Convert UI interface to boost::signals2.
- Signals now go directly from the core to WalletModel/ClientModel. - WalletModel subscribes to signals on CWallet: Prepares for multi-wallet support, by no longer assuming an implicit global wallet. - Gets rid of noui.cpp, the few lines that were left are merged into init.cpp - Rename wxXXX message flags to MF_XXX, to make them UI indifferent. - ThreadSafeMessageBox no longer returns the value `4` which was never used, converted to void.
This commit is contained in:
parent
fe4a655042
commit
ab1b288fa7
21 changed files with 267 additions and 226 deletions
|
@ -435,7 +435,7 @@ Value stop(const Array& params, bool fHelp)
|
|||
"stop\n"
|
||||
"Stop Bitcoin server.");
|
||||
// Shutdown will take long enough that the response should get back
|
||||
QueueShutdown();
|
||||
uiInterface.QueueShutdown();
|
||||
return "Bitcoin server stopping";
|
||||
}
|
||||
|
||||
|
@ -1928,7 +1928,7 @@ Value encryptwallet(const Array& params, bool fHelp)
|
|||
// BDB seems to have a bad habit of writing old data into
|
||||
// slack space in .dat files; that is bad if the old data is
|
||||
// unencrypted private keys. So:
|
||||
QueueShutdown();
|
||||
uiInterface.QueueShutdown();
|
||||
return "wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet";
|
||||
}
|
||||
|
||||
|
@ -2620,7 +2620,7 @@ void ThreadRPCServer2(void* parg)
|
|||
strWhatAmI = strprintf(_("To use the %s option"), "\"-server\"");
|
||||
else if (mapArgs.count("-daemon"))
|
||||
strWhatAmI = strprintf(_("To use the %s option"), "\"-daemon\"");
|
||||
ThreadSafeMessageBox(strprintf(
|
||||
uiInterface.ThreadSafeMessageBox(strprintf(
|
||||
_("%s, you must set a rpcpassword in the configuration file:\n %s\n"
|
||||
"It is recommended you use the following random password:\n"
|
||||
"rpcuser=bitcoinrpc\n"
|
||||
|
@ -2630,8 +2630,8 @@ void ThreadRPCServer2(void* parg)
|
|||
strWhatAmI.c_str(),
|
||||
GetConfigFile().string().c_str(),
|
||||
EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32).c_str()),
|
||||
_("Error"), wxOK | wxMODAL);
|
||||
QueueShutdown();
|
||||
_("Error"), MF_OK | MF_MODAL);
|
||||
uiInterface.QueueShutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2650,9 +2650,9 @@ void ThreadRPCServer2(void* parg)
|
|||
}
|
||||
catch(boost::system::system_error &e)
|
||||
{
|
||||
ThreadSafeMessageBox(strprintf(_("An error occured while setting up the RPC port %i for listening: %s"), endpoint.port(), e.what()),
|
||||
_("Error"), wxOK | wxMODAL);
|
||||
QueueShutdown();
|
||||
uiInterface.ThreadSafeMessageBox(strprintf(_("An error occured while setting up the RPC port %i for listening: %s"), endpoint.port(), e.what()),
|
||||
_("Error"), MF_OK | MF_MODAL);
|
||||
uiInterface.QueueShutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
39
src/init.cpp
39
src/init.cpp
|
@ -22,6 +22,7 @@ using namespace std;
|
|||
using namespace boost;
|
||||
|
||||
CWallet* pwalletMain;
|
||||
CClientUIInterface uiInterface;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
@ -90,9 +91,33 @@ void HandleSIGTERM(int)
|
|||
// Start
|
||||
//
|
||||
#if !defined(QT_GUI)
|
||||
static int noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style)
|
||||
{
|
||||
printf("%s: %s\n", caption.c_str(), message.c_str());
|
||||
fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str());
|
||||
return 4;
|
||||
}
|
||||
|
||||
static bool noui_ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static void noui_QueueShutdown()
|
||||
{
|
||||
// Without UI, Shutdown can simply be started in a new thread
|
||||
CreateThread(Shutdown, NULL);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
bool fRet = false;
|
||||
|
||||
// Connect bitcoind signal handlers
|
||||
uiInterface.ThreadSafeMessageBox.connect(noui_ThreadSafeMessageBox);
|
||||
uiInterface.ThreadSafeAskFee.connect(noui_ThreadSafeAskFee);
|
||||
uiInterface.QueueShutdown.connect(noui_QueueShutdown);
|
||||
|
||||
fRet = AppInit(argc, argv);
|
||||
|
||||
if (fRet && fDaemon)
|
||||
|
@ -160,13 +185,13 @@ bool AppInit(int argc, char* argv[])
|
|||
|
||||
bool static InitError(const std::string &str)
|
||||
{
|
||||
ThreadSafeMessageBox(str, _("Bitcoin"), wxOK | wxMODAL);
|
||||
uiInterface.ThreadSafeMessageBox(str, _("Bitcoin"), MF_OK|MF_MODAL);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool static InitWarning(const std::string &str)
|
||||
{
|
||||
ThreadSafeMessageBox(str, _("Bitcoin"), wxOK | wxICON_EXCLAMATION | wxMODAL);
|
||||
uiInterface.ThreadSafeMessageBox(str, _("Bitcoin"), MF_OK | MF_ICON_EXCLAMATION | MF_MODAL);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -367,7 +392,7 @@ bool AppInit2()
|
|||
fprintf(stdout, "Bitcoin server starting\n");
|
||||
int64 nStart;
|
||||
|
||||
InitMessage(_("Loading addresses..."));
|
||||
uiInterface.InitMessage(_("Loading addresses..."));
|
||||
printf("Loading addresses...\n");
|
||||
nStart = GetTimeMillis();
|
||||
|
||||
|
@ -380,7 +405,7 @@ bool AppInit2()
|
|||
printf("Loaded %i addresses from peers.dat %"PRI64d"ms\n",
|
||||
addrman.size(), GetTimeMillis() - nStart);
|
||||
|
||||
InitMessage(_("Loading block index..."));
|
||||
uiInterface.InitMessage(_("Loading block index..."));
|
||||
printf("Loading block index...\n");
|
||||
nStart = GetTimeMillis();
|
||||
if (!LoadBlockIndex())
|
||||
|
@ -406,7 +431,7 @@ bool AppInit2()
|
|||
}
|
||||
}
|
||||
|
||||
InitMessage(_("Loading wallet..."));
|
||||
uiInterface.InitMessage(_("Loading wallet..."));
|
||||
printf("Loading wallet...\n");
|
||||
nStart = GetTimeMillis();
|
||||
bool fFirstRun;
|
||||
|
@ -474,14 +499,14 @@ bool AppInit2()
|
|||
}
|
||||
if (pindexBest != pindexRescan)
|
||||
{
|
||||
InitMessage(_("Rescanning..."));
|
||||
uiInterface.InitMessage(_("Rescanning..."));
|
||||
printf("Rescanning last %i blocks (from block %i)...\n", pindexBest->nHeight - pindexRescan->nHeight, pindexRescan->nHeight);
|
||||
nStart = GetTimeMillis();
|
||||
pwalletMain->ScanForWalletTransactions(pindexRescan, true);
|
||||
printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart);
|
||||
}
|
||||
|
||||
InitMessage(_("Done loading"));
|
||||
uiInterface.InitMessage(_("Done loading"));
|
||||
printf("Done loading\n");
|
||||
|
||||
//// debug print
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#include "keystore.h"
|
||||
#include "script.h"
|
||||
#include "ui_interface.h"
|
||||
|
||||
bool CKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char> &vchPubKeyOut) const
|
||||
{
|
||||
|
@ -84,7 +83,7 @@ bool CCryptoKeyStore::Lock()
|
|||
vMasterKey.clear();
|
||||
}
|
||||
|
||||
NotifyKeyStoreStatusChanged(this);
|
||||
NotifyStatusChanged(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -114,7 +113,7 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
|
|||
}
|
||||
vMasterKey = vMasterKeyIn;
|
||||
}
|
||||
NotifyKeyStoreStatusChanged(this);
|
||||
NotifyStatusChanged(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "crypter.h"
|
||||
#include "sync.h"
|
||||
#include "base58.h"
|
||||
#include <boost/signals2/signal.hpp>
|
||||
|
||||
class CScript;
|
||||
|
||||
|
@ -174,6 +175,11 @@ public:
|
|||
mi++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wallet status (encrypted, locked) changed.
|
||||
* Note: Called without locks held.
|
||||
*/
|
||||
boost::signals2::signal<void (CCryptoKeyStore* wallet)> NotifyStatusChanged;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
14
src/main.cpp
14
src/main.cpp
|
@ -946,7 +946,7 @@ void static InvalidChainFound(CBlockIndex* pindexNew)
|
|||
{
|
||||
bnBestInvalidWork = pindexNew->bnChainWork;
|
||||
CTxDB().WriteBestInvalidWork(bnBestInvalidWork);
|
||||
NotifyBlocksChanged();
|
||||
uiInterface.NotifyBlocksChanged();
|
||||
}
|
||||
printf("InvalidChainFound: invalid block=%s height=%d work=%s\n", pindexNew->GetBlockHash().ToString().substr(0,20).c_str(), pindexNew->nHeight, pindexNew->bnChainWork.ToString().c_str());
|
||||
printf("InvalidChainFound: current best=%s height=%d work=%s\n", hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainWork.ToString().c_str());
|
||||
|
@ -1647,7 +1647,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
|
|||
hashPrevBestCoinBase = vtx[0].GetHash();
|
||||
}
|
||||
|
||||
NotifyBlocksChanged();
|
||||
uiInterface.NotifyBlocksChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1858,8 +1858,8 @@ bool CheckDiskSpace(uint64 nAdditionalBytes)
|
|||
string strMessage = _("Warning: Disk space is low");
|
||||
strMiscWarning = strMessage;
|
||||
printf("*** %s\n", strMessage.c_str());
|
||||
ThreadSafeMessageBox(strMessage, "Bitcoin", wxOK | wxICON_EXCLAMATION | wxMODAL);
|
||||
QueueShutdown();
|
||||
uiInterface.ThreadSafeMessageBox(strMessage, "Bitcoin", MF_OK | MF_ICON_EXCLAMATION | MF_MODAL);
|
||||
uiInterface.QueueShutdown();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -2204,13 +2204,13 @@ bool CAlert::ProcessAlert()
|
|||
if (Cancels(alert))
|
||||
{
|
||||
printf("cancelling alert %d\n", alert.nID);
|
||||
NotifyAlertChanged((*mi).first, CT_DELETED);
|
||||
uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED);
|
||||
mapAlerts.erase(mi++);
|
||||
}
|
||||
else if (!alert.IsInEffect())
|
||||
{
|
||||
printf("expiring alert %d\n", alert.nID);
|
||||
NotifyAlertChanged((*mi).first, CT_DELETED);
|
||||
uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED);
|
||||
mapAlerts.erase(mi++);
|
||||
}
|
||||
else
|
||||
|
@ -2232,7 +2232,7 @@ bool CAlert::ProcessAlert()
|
|||
mapAlerts.insert(make_pair(GetHash(), *this));
|
||||
// Notify UI if it applies to me
|
||||
if(AppliesToMe())
|
||||
NotifyAlertChanged(GetHash(), CT_NEW);
|
||||
uiInterface.NotifyAlertChanged(GetHash(), CT_NEW);
|
||||
}
|
||||
|
||||
printf("accepted alert %d, AppliesToMe()=%d\n", nID, AppliesToMe());
|
||||
|
|
|
@ -64,8 +64,7 @@ OBJS= \
|
|||
obj/sync.o \
|
||||
obj/util.o \
|
||||
obj/wallet.o \
|
||||
obj/walletdb.o \
|
||||
obj/noui.o
|
||||
obj/walletdb.o
|
||||
|
||||
all: bitcoind.exe
|
||||
|
||||
|
|
|
@ -61,8 +61,7 @@ OBJS= \
|
|||
obj/sync.o \
|
||||
obj/util.o \
|
||||
obj/wallet.o \
|
||||
obj/walletdb.o \
|
||||
obj/noui.o
|
||||
obj/walletdb.o
|
||||
|
||||
|
||||
all: bitcoind.exe
|
||||
|
|
|
@ -88,8 +88,7 @@ OBJS= \
|
|||
obj/sync.o \
|
||||
obj/util.o \
|
||||
obj/wallet.o \
|
||||
obj/walletdb.o \
|
||||
obj/noui.o
|
||||
obj/walletdb.o
|
||||
|
||||
ifdef USE_UPNP
|
||||
DEFS += -DUSE_UPNP=$(USE_UPNP)
|
||||
|
|
|
@ -108,8 +108,7 @@ OBJS= \
|
|||
obj/sync.o \
|
||||
obj/util.o \
|
||||
obj/wallet.o \
|
||||
obj/walletdb.o \
|
||||
obj/noui.o
|
||||
obj/walletdb.o
|
||||
|
||||
|
||||
all: bitcoind
|
||||
|
|
|
@ -705,7 +705,7 @@ void ThreadSocketHandler2(void* parg)
|
|||
if (vNodes.size() != nPrevNodeCount)
|
||||
{
|
||||
nPrevNodeCount = vNodes.size();
|
||||
NotifyNumConnectionsChanged(vNodes.size());
|
||||
uiInterface.NotifyNumConnectionsChanged(vNodes.size());
|
||||
}
|
||||
|
||||
|
||||
|
|
59
src/noui.cpp
59
src/noui.cpp
|
@ -1,59 +0,0 @@
|
|||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2012 The Bitcoin developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
#include "ui_interface.h"
|
||||
|
||||
#include <string>
|
||||
#include "init.h"
|
||||
|
||||
int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void InitMessage(const std::string &message)
|
||||
{
|
||||
}
|
||||
|
||||
std::string _(const char* psz)
|
||||
{
|
||||
return psz;
|
||||
}
|
||||
|
||||
void QueueShutdown()
|
||||
{
|
||||
// Without UI, Shutdown can simply be started in a new thread
|
||||
CreateThread(Shutdown, NULL);
|
||||
}
|
||||
|
||||
void NotifyBlocksChanged()
|
||||
{
|
||||
}
|
||||
|
||||
void NotifyKeyStoreStatusChanged(CBasicKeyStore *wallet)
|
||||
{
|
||||
}
|
||||
|
||||
void NotifyAddressBookChanged(CWallet *wallet, const std::string &address, const std::string &label, EntryStatus status)
|
||||
{
|
||||
}
|
||||
|
||||
void NotifyTransactionChanged(CWallet *wallet, const uint256 &hashTx, EntryStatus status)
|
||||
{
|
||||
}
|
||||
|
||||
void NotifyNumConnectionsChanged(int newNumConnections)
|
||||
{
|
||||
}
|
||||
|
||||
void NotifyAlertChanged(const uint256 &hash, EntryStatus status)
|
||||
{
|
||||
}
|
|
@ -36,15 +36,13 @@ Q_IMPORT_PLUGIN(qtaccessiblewidgets)
|
|||
// 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)
|
||||
static void ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style)
|
||||
{
|
||||
// Message from network thread
|
||||
if(guiref)
|
||||
{
|
||||
bool modal = (style & wxMODAL);
|
||||
bool modal = (style & MF_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,
|
||||
|
@ -57,10 +55,9 @@ int ThreadSafeMessageBox(const std::string& message, const std::string& caption,
|
|||
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)
|
||||
static bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption)
|
||||
{
|
||||
if(!guiref)
|
||||
return false;
|
||||
|
@ -75,7 +72,7 @@ bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption)
|
|||
return payFee;
|
||||
}
|
||||
|
||||
void ThreadSafeHandleURI(const std::string& strURI)
|
||||
static void ThreadSafeHandleURI(const std::string& strURI)
|
||||
{
|
||||
if(!guiref)
|
||||
return;
|
||||
|
@ -84,7 +81,7 @@ void ThreadSafeHandleURI(const std::string& strURI)
|
|||
Q_ARG(QString, QString::fromStdString(strURI)));
|
||||
}
|
||||
|
||||
void InitMessage(const std::string &message)
|
||||
static void InitMessage(const std::string &message)
|
||||
{
|
||||
if(splashref)
|
||||
{
|
||||
|
@ -93,7 +90,7 @@ void InitMessage(const std::string &message)
|
|||
}
|
||||
}
|
||||
|
||||
void QueueShutdown()
|
||||
static void QueueShutdown()
|
||||
{
|
||||
QMetaObject::invokeMethod(QCoreApplication::instance(), "quit", Qt::QueuedConnection);
|
||||
}
|
||||
|
@ -101,66 +98,11 @@ void QueueShutdown()
|
|||
/*
|
||||
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();
|
||||
}
|
||||
|
||||
void NotifyBlocksChanged()
|
||||
{
|
||||
// This notification is too frequent. Don't trigger a signal.
|
||||
// Don't remove it, though, as it might be useful later.
|
||||
}
|
||||
|
||||
void NotifyKeyStoreStatusChanged(CBasicKeyStore *wallet)
|
||||
{
|
||||
// This currently ignores the wallet argument. When multiple wallet support is implemented, this
|
||||
// parameter should be mapped to a specific WalletModel for that wallet.
|
||||
OutputDebugStringF("NotifyKeyStoreStatusChanged\n");
|
||||
if(walletmodel)
|
||||
QMetaObject::invokeMethod(walletmodel, "updateStatus", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void NotifyAddressBookChanged(CWallet *wallet, const std::string &address, const std::string &label, ChangeType status)
|
||||
{
|
||||
// This currently ignores the wallet argument. When multiple wallet support is implemented, this
|
||||
// parameter should be mapped to a specific WalletModel for that wallet.
|
||||
OutputDebugStringF("NotifyAddressBookChanged %s %s status=%i\n", address.c_str(), label.c_str(), status);
|
||||
if(walletmodel)
|
||||
QMetaObject::invokeMethod(walletmodel, "updateAddressBook", Qt::QueuedConnection,
|
||||
Q_ARG(QString, QString::fromStdString(address)),
|
||||
Q_ARG(QString, QString::fromStdString(label)),
|
||||
Q_ARG(int, status));
|
||||
}
|
||||
|
||||
void NotifyTransactionChanged(CWallet *wallet, const uint256 &hash, ChangeType status)
|
||||
{
|
||||
// This currently ignores the wallet argument. When multiple wallet support is implemented, this
|
||||
// parameter should be mapped to a specific WalletModel for that wallet.
|
||||
OutputDebugStringF("NotifyTransactionChanged %s status=%i\n", hash.GetHex().c_str(), status);
|
||||
if(walletmodel)
|
||||
QMetaObject::invokeMethod(walletmodel, "updateTransaction", Qt::QueuedConnection,
|
||||
Q_ARG(QString, QString::fromStdString(hash.GetHex())),
|
||||
Q_ARG(int, status));
|
||||
}
|
||||
|
||||
void NotifyNumConnectionsChanged(int newNumConnections)
|
||||
{
|
||||
// Too noisy: OutputDebugStringF("NotifyNumConnectionsChanged %i\n", newNumConnections);
|
||||
if(clientmodel)
|
||||
QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection,
|
||||
Q_ARG(int, newNumConnections));
|
||||
}
|
||||
|
||||
void NotifyAlertChanged(const uint256 &hash, ChangeType status)
|
||||
{
|
||||
OutputDebugStringF("NotifyAlertChanged %s status=%i\n", hash.GetHex().c_str(), status);
|
||||
if(clientmodel)
|
||||
QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection,
|
||||
Q_ARG(QString, QString::fromStdString(hash.GetHex())),
|
||||
Q_ARG(int, status));
|
||||
}
|
||||
|
||||
/* Handle runaway exceptions. Shows a message box with the problem and quits the program.
|
||||
*/
|
||||
static void handleRunawayException(std::exception *e)
|
||||
|
@ -307,6 +249,14 @@ int main(int argc, char *argv[])
|
|||
if (translator.load(lang_territory, ":/translations/"))
|
||||
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"))
|
||||
|
@ -348,9 +298,7 @@ int main(int argc, char *argv[])
|
|||
splash.finish(&window);
|
||||
|
||||
ClientModel clientModel(&optionsModel);
|
||||
clientmodel = &clientModel;
|
||||
WalletModel walletModel(pwalletMain, &optionsModel);
|
||||
walletmodel = &walletModel;
|
||||
|
||||
window.setClientModel(&clientModel);
|
||||
window.setWalletModel(&walletModel);
|
||||
|
@ -392,8 +340,6 @@ int main(int argc, char *argv[])
|
|||
window.setClientModel(0);
|
||||
window.setWalletModel(0);
|
||||
guiref = 0;
|
||||
clientmodel = 0;
|
||||
walletmodel = 0;
|
||||
}
|
||||
Shutdown(NULL);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,13 @@ ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) :
|
|||
pollTimer->setInterval(MODEL_UPDATE_DELAY);
|
||||
pollTimer->start();
|
||||
connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer()));
|
||||
|
||||
subscribeToCoreSignals();
|
||||
}
|
||||
|
||||
ClientModel::~ClientModel()
|
||||
{
|
||||
unsubscribeFromCoreSignals();
|
||||
}
|
||||
|
||||
int ClientModel::getNumConnections() const
|
||||
|
@ -127,3 +134,41 @@ QDateTime ClientModel::formatClientStartupTime() const
|
|||
{
|
||||
return QDateTime::fromTime_t(nClientStartupTime);
|
||||
}
|
||||
|
||||
// Handlers for core signals
|
||||
static void NotifyBlocksChanged(ClientModel *clientmodel)
|
||||
{
|
||||
// This notification is too frequent. Don't trigger a signal.
|
||||
// Don't remove it, though, as it might be useful later.
|
||||
}
|
||||
|
||||
static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections)
|
||||
{
|
||||
// Too noisy: OutputDebugStringF("NotifyNumConnectionsChanged %i\n", newNumConnections);
|
||||
QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection,
|
||||
Q_ARG(int, newNumConnections));
|
||||
}
|
||||
|
||||
static void NotifyAlertChanged(ClientModel *clientmodel, const uint256 &hash, ChangeType status)
|
||||
{
|
||||
OutputDebugStringF("NotifyAlertChanged %s status=%i\n", hash.GetHex().c_str(), status);
|
||||
QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection,
|
||||
Q_ARG(QString, QString::fromStdString(hash.GetHex())),
|
||||
Q_ARG(int, status));
|
||||
}
|
||||
|
||||
void ClientModel::subscribeToCoreSignals()
|
||||
{
|
||||
// Connect signals to client
|
||||
uiInterface.NotifyBlocksChanged.connect(boost::bind(NotifyBlocksChanged, this));
|
||||
uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1));
|
||||
uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this, _1, _2));
|
||||
}
|
||||
|
||||
void ClientModel::unsubscribeFromCoreSignals()
|
||||
{
|
||||
// Disconnect signals from client
|
||||
uiInterface.NotifyBlocksChanged.disconnect(boost::bind(NotifyBlocksChanged, this));
|
||||
uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1));
|
||||
uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this, _1, _2));
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ class ClientModel : public QObject
|
|||
Q_OBJECT
|
||||
public:
|
||||
explicit ClientModel(OptionsModel *optionsModel, QObject *parent = 0);
|
||||
~ClientModel();
|
||||
|
||||
OptionsModel *getOptionsModel();
|
||||
|
||||
|
@ -52,6 +53,8 @@ private:
|
|||
|
||||
QTimer *pollTimer;
|
||||
|
||||
void subscribeToCoreSignals();
|
||||
void unsubscribeFromCoreSignals();
|
||||
signals:
|
||||
void numConnectionsChanged(int count);
|
||||
void numBlocksChanged(int count, int countOfPeers);
|
||||
|
|
|
@ -31,7 +31,7 @@ void ipcThread(void* parg)
|
|||
ptime d = boost::posix_time::microsec_clock::universal_time() + millisec(100);
|
||||
if(mq->timed_receive(&strBuf, sizeof(strBuf), nSize, nPriority, d))
|
||||
{
|
||||
ThreadSafeHandleURI(std::string(strBuf, nSize));
|
||||
uiInterface.ThreadSafeHandleURI(std::string(strBuf, nSize));
|
||||
Sleep(1000);
|
||||
}
|
||||
if (fShutdown)
|
||||
|
@ -69,7 +69,7 @@ void ipcInit()
|
|||
ptime d = boost::posix_time::microsec_clock::universal_time() + millisec(1);
|
||||
if(mq->timed_receive(&strBuf, sizeof(strBuf), nSize, nPriority, d))
|
||||
{
|
||||
ThreadSafeHandleURI(std::string(strBuf, nSize));
|
||||
uiInterface.ThreadSafeHandleURI(std::string(strBuf, nSize));
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
|
|
@ -18,6 +18,13 @@ WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *p
|
|||
{
|
||||
addressTableModel = new AddressTableModel(wallet, this);
|
||||
transactionTableModel = new TransactionTableModel(wallet, this);
|
||||
|
||||
subscribeToCoreSignals();
|
||||
}
|
||||
|
||||
WalletModel::~WalletModel()
|
||||
{
|
||||
unsubscribeFromCoreSignals();
|
||||
}
|
||||
|
||||
qint64 WalletModel::getBalance() const
|
||||
|
@ -147,7 +154,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipie
|
|||
}
|
||||
return TransactionCreationFailed;
|
||||
}
|
||||
if(!ThreadSafeAskFee(nFeeRequired, tr("Sending...").toStdString()))
|
||||
if(!uiInterface.ThreadSafeAskFee(nFeeRequired, tr("Sending...").toStdString()))
|
||||
{
|
||||
return Aborted;
|
||||
}
|
||||
|
@ -254,6 +261,46 @@ bool WalletModel::backupWallet(const QString &filename)
|
|||
return BackupWallet(*wallet, filename.toLocal8Bit().data());
|
||||
}
|
||||
|
||||
// Handlers for core signals
|
||||
static void NotifyKeyStoreStatusChanged(WalletModel *walletmodel, CCryptoKeyStore *wallet)
|
||||
{
|
||||
OutputDebugStringF("NotifyKeyStoreStatusChanged\n");
|
||||
QMetaObject::invokeMethod(walletmodel, "updateStatus", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet, const std::string &address, const std::string &label, ChangeType status)
|
||||
{
|
||||
OutputDebugStringF("NotifyAddressBookChanged %s %s status=%i\n", address.c_str(), label.c_str(), status);
|
||||
QMetaObject::invokeMethod(walletmodel, "updateAddressBook", Qt::QueuedConnection,
|
||||
Q_ARG(QString, QString::fromStdString(address)),
|
||||
Q_ARG(QString, QString::fromStdString(label)),
|
||||
Q_ARG(int, status));
|
||||
}
|
||||
|
||||
static void NotifyTransactionChanged(WalletModel *walletmodel, CWallet *wallet, const uint256 &hash, ChangeType status)
|
||||
{
|
||||
OutputDebugStringF("NotifyTransactionChanged %s status=%i\n", hash.GetHex().c_str(), status);
|
||||
QMetaObject::invokeMethod(walletmodel, "updateTransaction", Qt::QueuedConnection,
|
||||
Q_ARG(QString, QString::fromStdString(hash.GetHex())),
|
||||
Q_ARG(int, status));
|
||||
}
|
||||
|
||||
void WalletModel::subscribeToCoreSignals()
|
||||
{
|
||||
// Connect signals to wallet
|
||||
wallet->NotifyStatusChanged.connect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
|
||||
wallet->NotifyAddressBookChanged.connect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4));
|
||||
wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
|
||||
}
|
||||
|
||||
void WalletModel::unsubscribeFromCoreSignals()
|
||||
{
|
||||
// Disconnect signals from wallet
|
||||
wallet->NotifyStatusChanged.disconnect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
|
||||
wallet->NotifyAddressBookChanged.disconnect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4));
|
||||
wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
|
||||
}
|
||||
|
||||
// WalletModel::UnlockContext implementation
|
||||
WalletModel::UnlockContext WalletModel::requestUnlock()
|
||||
{
|
||||
|
|
|
@ -24,6 +24,7 @@ class WalletModel : public QObject
|
|||
Q_OBJECT
|
||||
public:
|
||||
explicit WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent = 0);
|
||||
~WalletModel();
|
||||
|
||||
enum StatusCode // Returned by sendCoins
|
||||
{
|
||||
|
@ -118,6 +119,8 @@ private:
|
|||
qint64 cachedNumTransactions;
|
||||
EncryptionStatus cachedEncryptionStatus;
|
||||
|
||||
void subscribeToCoreSignals();
|
||||
void unsubscribeFromCoreSignals();
|
||||
signals:
|
||||
// Signal that balance in wallet changed
|
||||
void balanceChanged(qint64 balance, qint64 unconfirmedBalance);
|
||||
|
|
|
@ -6,40 +6,47 @@
|
|||
|
||||
#include <string>
|
||||
#include "util.h" // for int64
|
||||
#include <boost/signals2/signal.hpp>
|
||||
#include <boost/signals2/last_value.hpp>
|
||||
|
||||
class CBasicKeyStore;
|
||||
class CWallet;
|
||||
class uint256;
|
||||
|
||||
#define wxYES 0x00000002
|
||||
#define wxOK 0x00000004
|
||||
#define wxNO 0x00000008
|
||||
#define wxYES_NO (wxYES|wxNO)
|
||||
#define wxCANCEL 0x00000010
|
||||
#define wxAPPLY 0x00000020
|
||||
#define wxCLOSE 0x00000040
|
||||
#define wxOK_DEFAULT 0x00000000
|
||||
#define wxYES_DEFAULT 0x00000000
|
||||
#define wxNO_DEFAULT 0x00000080
|
||||
#define wxCANCEL_DEFAULT 0x80000000
|
||||
#define wxICON_EXCLAMATION 0x00000100
|
||||
#define wxICON_HAND 0x00000200
|
||||
#define wxICON_WARNING wxICON_EXCLAMATION
|
||||
#define wxICON_ERROR wxICON_HAND
|
||||
#define wxICON_QUESTION 0x00000400
|
||||
#define wxICON_INFORMATION 0x00000800
|
||||
#define wxICON_STOP wxICON_HAND
|
||||
#define wxICON_ASTERISK wxICON_INFORMATION
|
||||
#define wxICON_MASK (0x00000100|0x00000200|0x00000400|0x00000800)
|
||||
#define wxFORWARD 0x00001000
|
||||
#define wxBACKWARD 0x00002000
|
||||
#define wxRESET 0x00004000
|
||||
#define wxHELP 0x00008000
|
||||
#define wxMORE 0x00010000
|
||||
#define wxSETUP 0x00020000
|
||||
// Force blocking, modal message box dialog (not just notification)
|
||||
#define wxMODAL 0x00040000
|
||||
/** Flags for CClientUIInterface::ThreadSafeMessageBox */
|
||||
enum MessageBoxFlags
|
||||
{
|
||||
MF_YES = 0x00000002,
|
||||
MF_OK = 0x00000004,
|
||||
MF_NO = 0x00000008,
|
||||
MF_YES_NO = (MF_YES|MF_NO),
|
||||
MF_CANCEL = 0x00000010,
|
||||
MF_APPLY = 0x00000020,
|
||||
MF_CLOSE = 0x00000040,
|
||||
MF_OK_DEFAULT = 0x00000000,
|
||||
MF_YES_DEFAULT = 0x00000000,
|
||||
MF_NO_DEFAULT = 0x00000080,
|
||||
MF_CANCEL_DEFAULT = 0x80000000,
|
||||
MF_ICON_EXCLAMATION = 0x00000100,
|
||||
MF_ICON_HAND = 0x00000200,
|
||||
MF_ICON_WARNING = MF_ICON_EXCLAMATION,
|
||||
MF_ICON_ERROR = MF_ICON_HAND,
|
||||
MF_ICON_QUESTION = 0x00000400,
|
||||
MF_ICON_INFORMATION = 0x00000800,
|
||||
MF_ICON_STOP = MF_ICON_HAND,
|
||||
MF_ICON_ASTERISK = MF_ICON_INFORMATION,
|
||||
MF_ICON_MASK = (0x00000100|0x00000200|0x00000400|0x00000800),
|
||||
MF_FORWARD = 0x00001000,
|
||||
MF_BACKWARD = 0x00002000,
|
||||
MF_RESET = 0x00004000,
|
||||
MF_HELP = 0x00008000,
|
||||
MF_MORE = 0x00010000,
|
||||
MF_SETUP = 0x00020000,
|
||||
// Force blocking, modal message box dialog (not just OS notification)
|
||||
MF_MODAL = 0x00040000
|
||||
};
|
||||
|
||||
/** General change type (added, updated, removed). */
|
||||
enum ChangeType
|
||||
{
|
||||
CT_NEW,
|
||||
|
@ -47,39 +54,51 @@ enum ChangeType
|
|||
CT_DELETED
|
||||
};
|
||||
|
||||
/* These UI communication functions are implemented in bitcoin.cpp (for ui) and noui.cpp (no ui) */
|
||||
/** Signals for UI communication. */
|
||||
class CClientUIInterface
|
||||
{
|
||||
public:
|
||||
/** Show message box. */
|
||||
boost::signals2::signal<void (const std::string& message, const std::string& caption, int style)> ThreadSafeMessageBox;
|
||||
|
||||
extern int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style=wxOK);
|
||||
extern bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption);
|
||||
extern void ThreadSafeHandleURI(const std::string& strURI);
|
||||
extern void QueueShutdown();
|
||||
extern void InitMessage(const std::string &message);
|
||||
extern std::string _(const char* psz);
|
||||
/** Ask the user whether he want to pay a fee or not. */
|
||||
boost::signals2::signal<bool (int64 nFeeRequired, const std::string& strCaption), boost::signals2::last_value<bool> > ThreadSafeAskFee;
|
||||
|
||||
/* Block chain changed. */
|
||||
extern void NotifyBlocksChanged();
|
||||
/** Handle an URL passed on the command line. */
|
||||
boost::signals2::signal<void (const std::string& strURI)> ThreadSafeHandleURI;
|
||||
|
||||
/* Wallet status (encrypted, locked) changed.
|
||||
* Note: Called without locks held.
|
||||
/** Progress message during initialization. */
|
||||
boost::signals2::signal<void (const std::string &message)> InitMessage;
|
||||
|
||||
/** Initiate client shutdown. */
|
||||
boost::signals2::signal<void ()> QueueShutdown;
|
||||
|
||||
/** Translate a message to the native language of the user. */
|
||||
boost::signals2::signal<std::string (const char* psz)> Translate;
|
||||
|
||||
/** Block chain changed. */
|
||||
boost::signals2::signal<void ()> NotifyBlocksChanged;
|
||||
|
||||
/** Number of network connections changed. */
|
||||
boost::signals2::signal<void (int newNumConnections)> NotifyNumConnectionsChanged;
|
||||
|
||||
/**
|
||||
* New, updated or cancelled alert.
|
||||
* @note called with lock cs_mapAlerts held.
|
||||
*/
|
||||
boost::signals2::signal<void (const uint256 &hash, ChangeType status)> NotifyAlertChanged;
|
||||
};
|
||||
|
||||
extern CClientUIInterface uiInterface;
|
||||
|
||||
/**
|
||||
* Translation function: Call Translate signal on UI interface, which returns a boost::optional result.
|
||||
* If no translation slot is registered, nothing is returned, and simply return the input.
|
||||
*/
|
||||
extern void NotifyKeyStoreStatusChanged(CBasicKeyStore *wallet);
|
||||
|
||||
/* Address book entry changed.
|
||||
* Note: called with lock cs_wallet held.
|
||||
*/
|
||||
extern void NotifyAddressBookChanged(CWallet *wallet, const std::string &address, const std::string &label, ChangeType status);
|
||||
|
||||
/* Wallet transaction added, removed or updated.
|
||||
* Note: called with lock cs_wallet held.
|
||||
*/
|
||||
extern void NotifyTransactionChanged(CWallet *wallet, const uint256 &hashTx, ChangeType status);
|
||||
|
||||
/* Number of connections changed. */
|
||||
extern void NotifyNumConnectionsChanged(int newNumConnections);
|
||||
|
||||
/* New, updated or cancelled alert.
|
||||
* Note: called with lock cs_mapAlerts held.
|
||||
*/
|
||||
extern void NotifyAlertChanged(const uint256 &hash, ChangeType status);
|
||||
inline std::string _(const char* psz)
|
||||
{
|
||||
boost::optional<std::string> rv = uiInterface.Translate(psz);
|
||||
return rv ? (*rv) : psz;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1000,7 +1000,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());
|
||||
ThreadSafeMessageBox(strMessage+" ", string("Bitcoin"), wxOK | wxICON_EXCLAMATION);
|
||||
uiInterface.ThreadSafeMessageBox(strMessage+" ", string("Bitcoin"), MF_OK | MF_ICON_EXCLAMATION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -276,7 +276,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
|
|||
CDB::Rewrite(strWalletFile);
|
||||
|
||||
}
|
||||
NotifyKeyStoreStatusChanged(this);
|
||||
NotifyStatusChanged(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1229,7 +1229,7 @@ string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew,
|
|||
return strError;
|
||||
}
|
||||
|
||||
if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending...")))
|
||||
if (fAskFee && !uiInterface.ThreadSafeAskFee(nFeeRequired, _("Sending...")))
|
||||
return "ABORTED";
|
||||
|
||||
if (!CommitTransaction(wtxNew, reservekey))
|
||||
|
|
11
src/wallet.h
11
src/wallet.h
|
@ -9,6 +9,7 @@
|
|||
#include "key.h"
|
||||
#include "keystore.h"
|
||||
#include "script.h"
|
||||
#include "ui_interface.h"
|
||||
|
||||
class CWalletTx;
|
||||
class CReserveKey;
|
||||
|
@ -261,6 +262,16 @@ public:
|
|||
|
||||
// get the current wallet format (the oldest client version guaranteed to understand this wallet)
|
||||
int GetVersion() { return nWalletVersion; }
|
||||
|
||||
/** Address book entry changed.
|
||||
* @note called with lock cs_wallet held.
|
||||
*/
|
||||
boost::signals2::signal<void (CWallet *wallet, const std::string &address, const std::string &label, ChangeType status)> NotifyAddressBookChanged;
|
||||
|
||||
/** Wallet transaction added, removed or updated.
|
||||
* @note called with lock cs_wallet held.
|
||||
*/
|
||||
boost::signals2::signal<void (CWallet *wallet, const uint256 &hashTx, ChangeType status)> NotifyTransactionChanged;
|
||||
};
|
||||
|
||||
/** A key allocated from the key pool. */
|
||||
|
|
Loading…
Reference in a new issue