From fe4a655042f7de31dce120aeed72345579f1b59f Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sat, 5 May 2012 16:07:14 +0200 Subject: Fine-grained UI updates Gets rid of `MainFrameRepaint` in favor of specific update functions that tell the UI exactly what changed. This improves the efficiency of various handlers. Also fixes problems with mined transactions not showing up until restart. The following notifications were added: - `NotifyBlocksChanged`: Block chain changed - `NotifyKeyStoreStatusChanged`: Wallet status (encrypted, locked) changed. - `NotifyAddressBookChanged`: Address book entry changed. - `NotifyTransactionChanged`: Wallet transaction added, removed or updated. - `NotifyNumConnectionsChanged`: Number of connections changed. - `NotifyAlertChanged`: New, updated or cancelled alert. As this finally makes it possible for the UI to know when a new alert arrived, it can be shown as OS notification. These notifications could also be useful for RPC clients. However, currently, they are ignored in bitcoind (in noui.cpp). Also brings back polling with timer for numBlocks in ClientModel. This value updates so frequently during initial download that the number of signals clogs the UI thread and causes heavy CPU usage. And after initial block download, the value changes so rarely that a delay of half a second until the UI updates is unnoticable. --- src/qt/walletmodel.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'src/qt/walletmodel.cpp') diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index b9ccb06c09..4e082a8abc 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -40,30 +40,38 @@ int WalletModel::getNumTransactions() const return numTransactions; } -void WalletModel::update() +void WalletModel::updateStatus() { + EncryptionStatus newEncryptionStatus = getEncryptionStatus(); + + if(cachedEncryptionStatus != newEncryptionStatus) + emit encryptionStatusChanged(newEncryptionStatus); +} + +void WalletModel::updateTransaction(const QString &hash, int status) +{ + if(transactionTableModel) + transactionTableModel->updateTransaction(hash, status); + + // Balance and number of transactions might have changed qint64 newBalance = getBalance(); qint64 newUnconfirmedBalance = getUnconfirmedBalance(); int newNumTransactions = getNumTransactions(); - EncryptionStatus newEncryptionStatus = getEncryptionStatus(); if(cachedBalance != newBalance || cachedUnconfirmedBalance != newUnconfirmedBalance) emit balanceChanged(newBalance, newUnconfirmedBalance); - if(cachedNumTransactions != newNumTransactions) emit numTransactionsChanged(newNumTransactions); - if(cachedEncryptionStatus != newEncryptionStatus) - emit encryptionStatusChanged(newEncryptionStatus); - cachedBalance = newBalance; cachedUnconfirmedBalance = newUnconfirmedBalance; cachedNumTransactions = newNumTransactions; } -void WalletModel::updateAddressList() +void WalletModel::updateAddressBook(const QString &address, const QString &label, int status) { - addressTableModel->update(); + if(addressTableModel) + addressTableModel->updateEntry(address, label, status); } bool WalletModel::validateAddress(const QString &address) -- cgit v1.2.3 From ab1b288fa7994db5f036e93d5f8ba73372017c40 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sun, 6 May 2012 19:40:58 +0200 Subject: 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. --- src/qt/walletmodel.cpp | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) (limited to 'src/qt/walletmodel.cpp') diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 4e082a8abc..1a9700ef09 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -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 QListNotifyStatusChanged.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() { -- cgit v1.2.3 From 0832c0d1669a3504b7ec21d583aecc79f84e8506 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sun, 6 May 2012 22:41:35 +0200 Subject: Process address book updates incrementally - No longer invalidates selection model, thus retains selection on address book changes - Fixes selection of new address when added --- src/qt/walletmodel.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/qt/walletmodel.cpp') diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 1a9700ef09..b89c3dba33 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -75,10 +75,10 @@ void WalletModel::updateTransaction(const QString &hash, int status) cachedNumTransactions = newNumTransactions; } -void WalletModel::updateAddressBook(const QString &address, const QString &label, int status) +void WalletModel::updateAddressBook(const QString &address, const QString &label, bool isMine, int status) { if(addressTableModel) - addressTableModel->updateEntry(address, label, status); + addressTableModel->updateEntry(address, label, isMine, status); } bool WalletModel::validateAddress(const QString &address) @@ -268,12 +268,13 @@ static void NotifyKeyStoreStatusChanged(WalletModel *walletmodel, CCryptoKeyStor QMetaObject::invokeMethod(walletmodel, "updateStatus", Qt::QueuedConnection); } -static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet, const std::string &address, const std::string &label, ChangeType status) +static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet, const std::string &address, const std::string &label, bool isMine, ChangeType status) { - OutputDebugStringF("NotifyAddressBookChanged %s %s status=%i\n", address.c_str(), label.c_str(), status); + OutputDebugStringF("NotifyAddressBookChanged %s %s isMine=%i status=%i\n", address.c_str(), label.c_str(), isMine, status); QMetaObject::invokeMethod(walletmodel, "updateAddressBook", Qt::QueuedConnection, Q_ARG(QString, QString::fromStdString(address)), Q_ARG(QString, QString::fromStdString(label)), + Q_ARG(bool, isMine), Q_ARG(int, status)); } @@ -289,7 +290,7 @@ 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->NotifyAddressBookChanged.connect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5)); wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3)); } @@ -297,7 +298,7 @@ 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->NotifyAddressBookChanged.disconnect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5)); wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3)); } -- cgit v1.2.3