diff --git a/src/keystore.cpp b/src/keystore.cpp index 2a4c88d56..81b7b076f 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -71,3 +71,9 @@ bool CBasicKeyStore::HaveWatchOnly(const CScript &dest) const LOCK(cs_KeyStore); return setWatchOnly.count(dest) > 0; } + +bool CBasicKeyStore::HaveWatchOnly() const +{ + LOCK(cs_KeyStore); + return (!setWatchOnly.empty()); +} diff --git a/src/keystore.h b/src/keystore.h index 72411a138..f10e24f36 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -50,6 +50,7 @@ public: // Support for Watch-only addresses virtual bool AddWatchOnly(const CScript &dest) =0; virtual bool HaveWatchOnly(const CScript &dest) const =0; + virtual bool HaveWatchOnly() const =0; }; typedef std::map KeyMap; @@ -107,6 +108,7 @@ public: virtual bool AddWatchOnly(const CScript &dest); virtual bool HaveWatchOnly(const CScript &dest) const; + virtual bool HaveWatchOnly() const; }; typedef std::vector > CKeyingMaterial; diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index b5a3de48c..8eed0856e 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -160,18 +160,25 @@ void OverviewPage::setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 // for the non-mining users bool showImmature = immatureBalance != 0; bool showWatchOnlyImmature = watchImmatureBalance != 0; - bool showWatchOnly = (watchOnlyBalance != 0 || watchUnconfBalance != 0 || showWatchOnlyImmature); // for symmetry reasons also show immature label when the watch-only one is shown ui->labelImmature->setVisible(showImmature || showWatchOnlyImmature); ui->labelImmatureText->setVisible(showImmature || showWatchOnlyImmature); - ui->labelSpendable->setVisible(showWatchOnly); // show spendable label (only when watch-only is active) - ui->labelWatchonly->setVisible(showWatchOnly); // show watch-only label - ui->lineWatchBalance->setVisible(showWatchOnly); // show watch-only balance separator line - ui->labelWatchAvailable->setVisible(showWatchOnly); // show watch-only available balance ui->labelWatchImmature->setVisible(showWatchOnlyImmature); // show watch-only immature balance - ui->labelWatchPending->setVisible(showWatchOnly); // show watch-only pending balance - ui->labelWatchTotal->setVisible(showWatchOnly); // show watch-only total balance +} + +// show/hide watch-only labels +void OverviewPage::updateWatchOnlyLabels(bool showWatchOnly) +{ + ui->labelSpendable->setVisible(showWatchOnly); // show spendable label (only when watch-only is active) + ui->labelWatchonly->setVisible(showWatchOnly); // show watch-only label + ui->lineWatchBalance->setVisible(showWatchOnly); // show watch-only balance separator line + ui->labelWatchAvailable->setVisible(showWatchOnly); // show watch-only available balance + ui->labelWatchPending->setVisible(showWatchOnly); // show watch-only pending balance + ui->labelWatchTotal->setVisible(showWatchOnly); // show watch-only total balance + + if (!showWatchOnly) + ui->labelWatchImmature->hide(); } void OverviewPage::setClientModel(ClientModel *model) @@ -208,6 +215,9 @@ void OverviewPage::setWalletModel(WalletModel *model) connect(model, SIGNAL(balanceChanged(qint64, qint64, qint64, qint64, qint64, qint64)), this, SLOT(setBalance(qint64, qint64, qint64, qint64, qint64, qint64))); connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + + updateWatchOnlyLabels(model->haveWatchOnly()); + connect(model, SIGNAL(notifyWatchonlyChanged(bool)), this, SLOT(updateWatchOnlyLabels(bool))); } // update the display unit, to not use the default ("BTC") diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index fe0010677..f46374efb 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -58,6 +58,7 @@ private slots: void updateDisplayUnit(); void handleTransactionClicked(const QModelIndex &index); void updateAlerts(const QString &warnings); + void updateWatchOnlyLabels(bool showWatchOnly); }; #endif // OVERVIEWPAGE_H diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 0ad123f39..30c9ecc96 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -36,6 +36,7 @@ WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *p cachedNumBlocks(0) { fProcessingQueuedTransactions = false; + fHaveWatchOnly = wallet->HaveWatchOnly(); addressTableModel = new AddressTableModel(wallet, this); transactionTableModel = new TransactionTableModel(wallet, this); @@ -81,6 +82,11 @@ qint64 WalletModel::getImmatureBalance() const return wallet->GetImmatureBalance(); } +bool WalletModel::haveWatchOnly() const +{ + return fHaveWatchOnly; +} + qint64 WalletModel::getWatchBalance() const { return wallet->GetWatchOnlyBalance(); @@ -144,9 +150,15 @@ void WalletModel::checkBalanceChanged() qint64 newBalance = getBalance(); qint64 newUnconfirmedBalance = getUnconfirmedBalance(); qint64 newImmatureBalance = getImmatureBalance(); - qint64 newWatchOnlyBalance = getWatchBalance(); - qint64 newWatchUnconfBalance = getWatchUnconfirmedBalance(); - qint64 newWatchImmatureBalance = getWatchImmatureBalance(); + qint64 newWatchOnlyBalance = 0; + qint64 newWatchUnconfBalance = 0; + qint64 newWatchImmatureBalance = 0; + if (haveWatchOnly()) + { + newWatchOnlyBalance = getWatchBalance(); + newWatchUnconfBalance = getWatchUnconfirmedBalance(); + newWatchImmatureBalance = getWatchImmatureBalance(); + } if(cachedBalance != newBalance || cachedUnconfirmedBalance != newUnconfirmedBalance || cachedImmatureBalance != newImmatureBalance || cachedWatchOnlyBalance != newWatchOnlyBalance || cachedWatchUnconfBalance != newWatchUnconfBalance || cachedWatchImmatureBalance != newWatchImmatureBalance) @@ -185,6 +197,12 @@ void WalletModel::updateAddressBook(const QString &address, const QString &label addressTableModel->updateEntry(address, label, isMine, purpose, status); } +void WalletModel::updateWatchOnlyFlag(bool fHaveWatchonly) +{ + fHaveWatchOnly = fHaveWatchonly; + emit notifyWatchonlyChanged(fHaveWatchonly); +} + bool WalletModel::validateAddress(const QString &address) { CBitcoinAddress addressParsed(address.toStdString()); @@ -499,6 +517,12 @@ static void ShowProgress(WalletModel *walletmodel, const std::string &title, int } } +static void NotifyWatchonlyChanged(WalletModel *walletmodel, bool fHaveWatchonly) +{ + QMetaObject::invokeMethod(walletmodel, "updateWatchOnlyFlag", Qt::QueuedConnection, + Q_ARG(bool, fHaveWatchonly)); +} + void WalletModel::subscribeToCoreSignals() { // Connect signals to wallet @@ -506,6 +530,7 @@ void WalletModel::subscribeToCoreSignals() wallet->NotifyAddressBookChanged.connect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6)); wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3)); wallet->ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2)); + wallet->NotifyWatchonlyChanged.connect(boost::bind(NotifyWatchonlyChanged, this, _1)); } void WalletModel::unsubscribeFromCoreSignals() @@ -515,6 +540,7 @@ void WalletModel::unsubscribeFromCoreSignals() wallet->NotifyAddressBookChanged.disconnect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6)); wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3)); wallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2)); + wallet->NotifyWatchonlyChanged.disconnect(boost::bind(NotifyWatchonlyChanged, this, _1)); } // WalletModel::UnlockContext implementation diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 2bb91d85a..1dad71606 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -128,6 +128,7 @@ public: qint64 getBalance(const CCoinControl *coinControl = NULL) const; qint64 getUnconfirmedBalance() const; qint64 getImmatureBalance() const; + bool haveWatchOnly() const; qint64 getWatchBalance() const; qint64 getWatchUnconfirmedBalance() const; qint64 getWatchImmatureBalance() const; @@ -198,6 +199,7 @@ public: private: CWallet *wallet; bool fProcessingQueuedTransactions; + bool fHaveWatchOnly; // Wallet has an options model for wallet-specific options // (transaction fee, for example) @@ -249,6 +251,9 @@ signals: // Show progress dialog e.g. for rescan void showProgress(const QString &title, int nProgress); + // Watch-only address added + void notifyWatchonlyChanged(bool fHaveWatchonly); + public slots: /* Wallet status might have changed */ void updateStatus(); @@ -256,6 +261,8 @@ public slots: void updateTransaction(const QString &hash, int status); /* New, updated or removed address book entry */ void updateAddressBook(const QString &address, const QString &label, bool isMine, const QString &purpose, int status); + /* Watchonly added */ + void updateWatchOnlyFlag(bool fHaveWatchonly); /* Current, immature or unconfirmed balance might have changed - emit 'balanceChanged' if so */ void pollBalanceChanged(); /* Needed to update fProcessingQueuedTransactions through a QueuedConnection */ diff --git a/src/wallet.cpp b/src/wallet.cpp index 7c04743c0..a293664f6 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -153,6 +153,7 @@ bool CWallet::AddWatchOnly(const CScript &dest) if (!CCryptoKeyStore::AddWatchOnly(dest)) return false; nTimeFirstKey = 1; // No birthday information for watch-only keys. + NotifyWatchonlyChanged(true); if (!fFileBacked) return true; return CWalletDB(strWalletFile).WriteWatchOnly(dest); diff --git a/src/wallet.h b/src/wallet.h index 73fcfa24e..1f727aec0 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -408,6 +408,9 @@ public: /** Show progress e.g. for rescan */ boost::signals2::signal ShowProgress; + + /** Watch-only address added */ + boost::signals2::signal NotifyWatchonlyChanged; }; /** A key allocated from the key pool. */