Skip to content

Commit

Permalink
Watchonly balances are shown separately in gui.
Browse files Browse the repository at this point in the history
  • Loading branch information
sdkfjlsfjlskdfjlsdjflsjf committed Jul 2, 2014
1 parent 2935b21 commit ffd40da
Show file tree
Hide file tree
Showing 14 changed files with 601 additions and 237 deletions.
533 changes: 349 additions & 184 deletions src/qt/forms/overviewpage.ui

Large diffs are not rendered by default.

34 changes: 28 additions & 6 deletions src/qt/overviewpage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ OverviewPage::OverviewPage(QWidget *parent) :
currentBalance(-1),
currentUnconfirmedBalance(-1),
currentImmatureBalance(-1),
currentWatchOnlyBalance(-1),
currentWatchUnconfBalance(-1),
currentWatchImmatureBalance(-1),
txdelegate(new TxViewDelegate()),
filter(0)
{
Expand Down Expand Up @@ -135,22 +138,39 @@ OverviewPage::~OverviewPage()
delete ui;
}

void OverviewPage::setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance)
void OverviewPage::setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance, qint64 watchOnlyBalance, qint64 watchUnconfBalance, qint64 watchImmatureBalance)
{
int unit = walletModel->getOptionsModel()->getDisplayUnit();
currentBalance = balance;
currentUnconfirmedBalance = unconfirmedBalance;
currentImmatureBalance = immatureBalance;
currentWatchOnlyBalance = watchOnlyBalance;
currentWatchUnconfBalance = watchUnconfBalance;
currentWatchImmatureBalance = watchImmatureBalance;
ui->labelBalance->setText(BitcoinUnits::formatWithUnit(unit, balance));
ui->labelUnconfirmed->setText(BitcoinUnits::formatWithUnit(unit, unconfirmedBalance));
ui->labelImmature->setText(BitcoinUnits::formatWithUnit(unit, immatureBalance));
ui->labelTotal->setText(BitcoinUnits::formatWithUnit(unit, balance + unconfirmedBalance + immatureBalance));
ui->labelWatchAvailable->setText(BitcoinUnits::formatWithUnit(unit, watchOnlyBalance));
ui->labelWatchPending->setText(BitcoinUnits::formatWithUnit(unit, watchUnconfBalance));
ui->labelWatchImmature->setText(BitcoinUnits::formatWithUnit(unit, watchImmatureBalance));
ui->labelWatchTotal->setText(BitcoinUnits::formatWithUnit(unit, watchOnlyBalance + watchUnconfBalance + watchImmatureBalance));

// only show immature (newly mined) balance if it's non-zero, so as not to complicate things
// for the non-mining users
bool showImmature = immatureBalance != 0;
ui->labelImmature->setVisible(showImmature);
ui->labelImmatureText->setVisible(showImmature);
bool showWatchOnlyImmature = watchImmatureBalance != 0;
bool showWatchOnly = (watchOnlyBalance != 0 || watchUnconfBalance != 0 || showWatchOnlyImmature);

// for symmetry reasons also show immature label when the watchonly one is shown
ui->labelImmature->setVisible(showImmature || showWatchOnlyImmature);
ui->labelImmatureText->setVisible(showImmature || showWatchOnlyImmature);
ui->labelWatchonly->setVisible(showWatchOnly); // show Watchonly label
ui->lineWatchBalance->setVisible(showWatchOnly); // show watchonly balance separator line
ui->labelWatchAvailable->setVisible(showWatchOnly); // show watchonly available balance
ui->labelWatchImmature->setVisible(showWatchOnlyImmature); // show watchonly immature balance
ui->labelWatchPending->setVisible(showWatchOnly); // show watchonly pending balance
ui->labelWatchTotal->setVisible(showWatchOnly); // show watchonly total balance
}

void OverviewPage::setClientModel(ClientModel *model)
Expand Down Expand Up @@ -182,8 +202,9 @@ void OverviewPage::setWalletModel(WalletModel *model)
ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress);

// Keep up to date with wallet
setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance());
connect(model, SIGNAL(balanceChanged(qint64, qint64, qint64)), this, SLOT(setBalance(qint64, qint64, qint64)));
setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance(),
model->getWatchBalance(), model->getWatchUnconfirmedBalance(), model->getWatchImmatureBalance());
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()));
}
Expand All @@ -197,7 +218,8 @@ void OverviewPage::updateDisplayUnit()
if(walletModel && walletModel->getOptionsModel())
{
if(currentBalance != -1)
setBalance(currentBalance, currentUnconfirmedBalance, currentImmatureBalance);
setBalance(currentBalance, currentUnconfirmedBalance, currentImmatureBalance,
currentWatchOnlyBalance, currentWatchUnconfBalance, currentWatchImmatureBalance);

// Update txdelegate->unit with the current unit
txdelegate->unit = walletModel->getOptionsModel()->getDisplayUnit();
Expand Down
6 changes: 5 additions & 1 deletion src/qt/overviewpage.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ class OverviewPage : public QWidget
void showOutOfSyncWarning(bool fShow);

public slots:
void setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance);
void setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance,
qint64 watchOnlyBalance, qint64 watchUnconfBalance, qint64 watchImmatureBalance);

signals:
void transactionClicked(const QModelIndex &index);
Expand All @@ -46,6 +47,9 @@ public slots:
qint64 currentBalance;
qint64 currentUnconfirmedBalance;
qint64 currentImmatureBalance;
qint64 currentWatchOnlyBalance;
qint64 currentWatchUnconfBalance;
qint64 currentWatchImmatureBalance;

TxViewDelegate *txdelegate;
TransactionFilterProxy *filter;
Expand Down
13 changes: 9 additions & 4 deletions src/qt/sendcoinsdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,9 @@ void SendCoinsDialog::setModel(WalletModel *model)
}
}

setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance());
connect(model, SIGNAL(balanceChanged(qint64, qint64, qint64)), this, SLOT(setBalance(qint64, qint64, qint64)));
setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance(),
model->getWatchBalance(), model->getWatchUnconfirmedBalance(), model->getWatchImmatureBalance());
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()));

// Coin Control
Expand Down Expand Up @@ -383,10 +384,14 @@ bool SendCoinsDialog::handlePaymentRequest(const SendCoinsRecipient &rv)
return true;
}

void SendCoinsDialog::setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance)
void SendCoinsDialog::setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance,
qint64 watchBalance, qint64 watchUnconfirmedBalance, qint64 watchImmatureBalance)
{
Q_UNUSED(unconfirmedBalance);
Q_UNUSED(immatureBalance);
Q_UNUSED(watchBalance);
Q_UNUSED(watchUnconfirmedBalance);
Q_UNUSED(watchImmatureBalance);

if(model && model->getOptionsModel())
{
Expand All @@ -396,7 +401,7 @@ void SendCoinsDialog::setBalance(qint64 balance, qint64 unconfirmedBalance, qint

void SendCoinsDialog::updateDisplayUnit()
{
setBalance(model->getBalance(), 0, 0);
setBalance(model->getBalance(), 0, 0, 0, 0, 0);
}

void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn, const QString &msgArg)
Expand Down
3 changes: 2 additions & 1 deletion src/qt/sendcoinsdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ public slots:
void accept();
SendCoinsEntry *addEntry();
void updateTabsAndLabels();
void setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance);
void setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance,
qint64 watchOnlyBalance, qint64 watchUnconfBalance, qint64 watchImmatureBalance);

private:
Ui::SendCoinsDialog *ui;
Expand Down
64 changes: 45 additions & 19 deletions src/qt/transactiondesc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,19 +89,27 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco
if (nNet > 0)
{
// Credit
if (CBitcoinAddress(rec->address).IsValid())
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
{
CTxDestination address = CBitcoinAddress(rec->address).Get();
if (wallet->mapAddressBook.count(address))
if (wallet->IsMine(txout))
{
strHTML += "<b>" + tr("From") + ":</b> " + tr("unknown") + "<br>";
strHTML += "<b>" + tr("To") + ":</b> ";
strHTML += GUIUtil::HtmlEscape(rec->address);
if (!wallet->mapAddressBook[address].name.empty())
strHTML += " (" + tr("own address") + ", " + tr("label") + ": " + GUIUtil::HtmlEscape(wallet->mapAddressBook[address].name) + ")";
else
strHTML += " (" + tr("own address") + ")";
strHTML += "<br>";
if (CBitcoinAddress(rec->address).IsValid())
{
CTxDestination address = CBitcoinAddress(rec->address).Get();
if (wallet->mapAddressBook.count(address))
{
strHTML += "<b>" + tr("From") + ":</b> " + tr("unknown") + "<br>";
strHTML += "<b>" + tr("To") + ":</b> ";
strHTML += GUIUtil::HtmlEscape(rec->address);
std::string addressOwned = wallet->IsMine(txout) == MINE_SPENDABLE ? "own address" : "watch-only";
if (!wallet->mapAddressBook[address].name.empty())
strHTML += " (" + tr(addressOwned.c_str()) + ", " + tr("label") + ": " + GUIUtil::HtmlEscape(wallet->mapAddressBook[address].name) + ")";
else
strHTML += " (" + tr(addressOwned.c_str()) + ")";
strHTML += "<br>";
}
}
break;
}
}
}
Expand Down Expand Up @@ -148,22 +156,33 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco
}
else
{
bool fAllFromMe = true;
isminetype fAllFromMe = MINE_SPENDABLE;
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
fAllFromMe = fAllFromMe && wallet->IsMine(txin);
{
isminetype mine = wallet->IsMine(txin);
if(fAllFromMe > mine) fAllFromMe = mine;
}

bool fAllToMe = true;
isminetype fAllToMe = MINE_SPENDABLE;
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
fAllToMe = fAllToMe && wallet->IsMine(txout);
{
isminetype mine = wallet->IsMine(txout);
if(fAllToMe > mine) fAllToMe = mine;
}

if (fAllFromMe)
{
if(fAllFromMe == MINE_WATCH_ONLY)
strHTML += "<b>" + tr("From") + ":</b> " + tr("watch-only") + "<br>";

//
// Debit
//
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
{
if (wallet->IsMine(txout))
// Ignore change
isminetype toSelf = wallet->IsMine(txout);
if ((toSelf == MINE_SPENDABLE) && (fAllFromMe == MINE_SPENDABLE))
continue;

if (!wtx.mapValue.count("to") || wtx.mapValue["to"].empty())
Expand All @@ -176,20 +195,26 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco
if (wallet->mapAddressBook.count(address) && !wallet->mapAddressBook[address].name.empty())
strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[address].name) + " ";
strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString());
if(toSelf == MINE_SPENDABLE)
strHTML += " (own address)";
else if(toSelf == MINE_WATCH_ONLY)
strHTML += " (watch-only)";
strHTML += "<br>";
}
}

strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, -txout.nValue) + "<br>";
if(toSelf)
strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, txout.nValue) + "<br>";
}

if (fAllToMe)
{
// Payment to self
int64_t nChange = wtx.GetChange();
int64_t nValue = nCredit - nChange;
strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, -nValue) + "<br>";
strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, nValue) + "<br>";
strHTML += "<b>" + tr("Total debit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, -nValue) + "<br>";
strHTML += "<b>" + tr("Total credit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, nValue) + "<br>";
}

int64_t nTxFee = nDebit - wtx.GetValueOut();
Expand Down Expand Up @@ -286,7 +311,8 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco
strHTML += QString::fromStdString(CBitcoinAddress(address).ToString());
}
strHTML = strHTML + " " + tr("Amount") + "=" + BitcoinUnits::formatWithUnit(unit, vout.nValue);
strHTML = strHTML + " IsMine=" + (wallet->IsMine(vout) ? tr("true") : tr("false")) + "</li>";
strHTML = strHTML + " IsMine=" + (wallet->IsMine(vout) & MINE_SPENDABLE ? tr("true") : tr("false")) + "</li>";
strHTML = strHTML + " IsWatchOnly=" + (wallet->IsMine(vout) & MINE_WATCH_ONLY ? tr("true") : tr("false")) + "</li>";
}
}
}
Expand Down
17 changes: 12 additions & 5 deletions src/qt/transactionrecord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
//
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
{
if(wallet->IsMine(txout))
isminetype mine = wallet->IsMine(txout);
if(mine)
{
TransactionRecord sub(hash, nTime);
CTxDestination address;
Expand Down Expand Up @@ -75,13 +76,19 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
}
else
{
bool fAllFromMe = true;
isminetype fAllFromMe = MINE_SPENDABLE;
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
fAllFromMe = fAllFromMe && wallet->IsMine(txin);
{
isminetype mine = wallet->IsMine(txin);
if(fAllFromMe > mine) fAllFromMe = mine;
}

bool fAllToMe = true;
isminetype fAllToMe = MINE_SPENDABLE;
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
fAllToMe = fAllToMe && wallet->IsMine(txout);
{
isminetype mine = wallet->IsMine(txout);
if(fAllToMe > mine) fAllToMe = mine;
}

if (fAllFromMe && fAllToMe)
{
Expand Down
27 changes: 25 additions & 2 deletions src/qt/walletmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,21 @@ qint64 WalletModel::getImmatureBalance() const
return wallet->GetImmatureBalance();
}

qint64 WalletModel::getWatchBalance() const
{
return wallet->GetWatchOnlyBalance();
}

qint64 WalletModel::getWatchUnconfirmedBalance() const
{
return wallet->GetUnconfirmedWatchOnlyBalance();
}

qint64 WalletModel::getWatchImmatureBalance() const
{
return wallet->GetImmatureWatchOnlyBalance();
}

int WalletModel::getNumTransactions() const
{
int numTransactions = 0;
Expand Down Expand Up @@ -127,13 +142,21 @@ void WalletModel::checkBalanceChanged()
qint64 newBalance = getBalance();
qint64 newUnconfirmedBalance = getUnconfirmedBalance();
qint64 newImmatureBalance = getImmatureBalance();
qint64 newWatchOnlyBalance = getWatchBalance();
qint64 newWatchUnconfBalance = getWatchUnconfirmedBalance();
qint64 newWatchImmatureBalance = getWatchImmatureBalance();

if(cachedBalance != newBalance || cachedUnconfirmedBalance != newUnconfirmedBalance || cachedImmatureBalance != newImmatureBalance)
if(cachedBalance != newBalance || cachedUnconfirmedBalance != newUnconfirmedBalance || cachedImmatureBalance != newImmatureBalance ||
cachedWatchOnlyBalance != newWatchOnlyBalance || cachedWatchUnconfBalance != newWatchUnconfBalance || cachedWatchImmatureBalance != newWatchImmatureBalance)
{
cachedBalance = newBalance;
cachedUnconfirmedBalance = newUnconfirmedBalance;
cachedImmatureBalance = newImmatureBalance;
emit balanceChanged(newBalance, newUnconfirmedBalance, newImmatureBalance);
cachedWatchOnlyBalance = newWatchOnlyBalance;
cachedWatchUnconfBalance = newWatchUnconfBalance;
cachedWatchImmatureBalance = newWatchImmatureBalance;
emit balanceChanged(newBalance, newUnconfirmedBalance, newImmatureBalance,
newWatchOnlyBalance, newWatchUnconfBalance, newWatchImmatureBalance);
}
}

Expand Down
9 changes: 8 additions & 1 deletion src/qt/walletmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ class WalletModel : public QObject
qint64 getBalance(const CCoinControl *coinControl = NULL) const;
qint64 getUnconfirmedBalance() const;
qint64 getImmatureBalance() const;
qint64 getWatchBalance() const;
qint64 getWatchUnconfirmedBalance() const;
qint64 getWatchImmatureBalance() const;
int getNumTransactions() const;
EncryptionStatus getEncryptionStatus() const;

Expand Down Expand Up @@ -206,6 +209,9 @@ class WalletModel : public QObject
qint64 cachedBalance;
qint64 cachedUnconfirmedBalance;
qint64 cachedImmatureBalance;
qint64 cachedWatchOnlyBalance;
qint64 cachedWatchUnconfBalance;
qint64 cachedWatchImmatureBalance;
qint64 cachedNumTransactions;
EncryptionStatus cachedEncryptionStatus;
int cachedNumBlocks;
Expand All @@ -218,7 +224,8 @@ class WalletModel : public QObject

signals:
// Signal that balance in wallet changed
void balanceChanged(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance);
void balanceChanged(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance,
qint64 watchOnlyBalance, qint64 watchUnconfBalance, qint64 watchImmatureBalance);

// Number of transactions in wallet changed
void numTransactionsChanged(int count);
Expand Down
4 changes: 3 additions & 1 deletion src/rpcdump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,14 @@ Value importaddress(const Array& params, bool fHelp)
{
LOCK2(cs_main, pwalletMain->cs_wallet);

// add to address book or update label
pwalletMain->SetAddressBook(dest, strLabel, "receive");

// Don't throw error in case an address is already there
if (pwalletMain->HaveWatchOnly(dest))
return Value::null;

pwalletMain->MarkDirty();
pwalletMain->SetAddressBook(dest, strLabel, "receive");

if (!pwalletMain->AddWatchOnly(dest))
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
Expand Down
2 changes: 1 addition & 1 deletion src/rpcmisc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ Value validateaddress(const Array& params, bool fHelp)
ret.push_back(Pair("address", currentAddress));
#ifdef ENABLE_WALLET
isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : MINE_NO;
ret.push_back(Pair("ismine", mine != MINE_NO));
ret.push_back(Pair("ismine", mine == MINE_SPENDABLE));
if (mine != MINE_NO) {
ret.push_back(Pair("watchonly", mine == MINE_WATCH_ONLY));
Object detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest);
Expand Down
Loading

0 comments on commit ffd40da

Please sign in to comment.