Merge pull request #4673
1c5f0af
[Qt] Add column Watch-only to transactions list (Cozz Lovan)939ed97
Add boolean HaveWatchonly and signal NotifyWatchonlyChanged (Cozz Lovan)
This commit is contained in:
commit
d49b0876a4
@ -233,6 +233,9 @@ RES_ICONS = \
|
||||
qt/res/icons/editcopy.png \
|
||||
qt/res/icons/editpaste.png \
|
||||
qt/res/icons/export.png \
|
||||
qt/res/icons/eye.png \
|
||||
qt/res/icons/eye_minus.png \
|
||||
qt/res/icons/eye_plus.png \
|
||||
qt/res/icons/filesave.png \
|
||||
qt/res/icons/history.png \
|
||||
qt/res/icons/key.png \
|
||||
|
@ -72,3 +72,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());
|
||||
}
|
||||
|
@ -41,6 +41,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<CKeyID, CKey> KeyMap;
|
||||
@ -98,6 +99,7 @@ public:
|
||||
|
||||
virtual bool AddWatchOnly(const CScript &dest);
|
||||
virtual bool HaveWatchOnly(const CScript &dest) const;
|
||||
virtual bool HaveWatchOnly() const;
|
||||
};
|
||||
|
||||
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
|
||||
|
@ -17,6 +17,9 @@
|
||||
<file alias="transaction_3">res/icons/clock3.png</file>
|
||||
<file alias="transaction_4">res/icons/clock4.png</file>
|
||||
<file alias="transaction_5">res/icons/clock5.png</file>
|
||||
<file alias="eye">res/icons/eye.png</file>
|
||||
<file alias="eye_minus">res/icons/eye_minus.png</file>
|
||||
<file alias="eye_plus">res/icons/eye_plus.png</file>
|
||||
<file alias="options">res/icons/configure.png</file>
|
||||
<file alias="receiving_addresses">res/icons/receive.png</file>
|
||||
<file alias="editpaste">res/icons/editpaste.png</file>
|
||||
|
@ -57,7 +57,15 @@ public:
|
||||
}
|
||||
|
||||
painter->setPen(foreground);
|
||||
painter->drawText(addressRect, Qt::AlignLeft|Qt::AlignVCenter, address);
|
||||
QRect boundingRect;
|
||||
painter->drawText(addressRect, Qt::AlignLeft|Qt::AlignVCenter, address, &boundingRect);
|
||||
|
||||
if (index.data(TransactionTableModel::WatchonlyRole).toBool())
|
||||
{
|
||||
QIcon iconWatchonly = qvariant_cast<QIcon>(index.data(TransactionTableModel::WatchonlyDecorationRole));
|
||||
QRect watchonlyRect(boundingRect.right() + 5, mainRect.top()+ypad+halfheight, 16, halfheight);
|
||||
iconWatchonly.paint(painter, watchonlyRect);
|
||||
}
|
||||
|
||||
if(amount < 0)
|
||||
{
|
||||
@ -160,18 +168,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 +223,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")
|
||||
|
@ -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
|
||||
|
BIN
src/qt/res/icons/eye.png
Normal file
BIN
src/qt/res/icons/eye.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 536 B |
BIN
src/qt/res/icons/eye_minus.png
Normal file
BIN
src/qt/res/icons/eye_minus.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 595 B |
BIN
src/qt/res/icons/eye_plus.png
Normal file
BIN
src/qt/res/icons/eye_plus.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 661 B |
@ -22,6 +22,7 @@ TransactionFilterProxy::TransactionFilterProxy(QObject *parent) :
|
||||
dateTo(MAX_DATE),
|
||||
addrPrefix(),
|
||||
typeFilter(ALL_TYPES),
|
||||
watchOnlyFilter(WatchOnlyFilter_All),
|
||||
minAmount(0),
|
||||
limitRows(-1),
|
||||
showInactive(true)
|
||||
@ -34,6 +35,7 @@ bool TransactionFilterProxy::filterAcceptsRow(int sourceRow, const QModelIndex &
|
||||
|
||||
int type = index.data(TransactionTableModel::TypeRole).toInt();
|
||||
QDateTime datetime = index.data(TransactionTableModel::DateRole).toDateTime();
|
||||
bool involvesWatchAddress = index.data(TransactionTableModel::WatchonlyRole).toBool();
|
||||
QString address = index.data(TransactionTableModel::AddressRole).toString();
|
||||
QString label = index.data(TransactionTableModel::LabelRole).toString();
|
||||
qint64 amount = llabs(index.data(TransactionTableModel::AmountRole).toLongLong());
|
||||
@ -43,6 +45,10 @@ bool TransactionFilterProxy::filterAcceptsRow(int sourceRow, const QModelIndex &
|
||||
return false;
|
||||
if(!(TYPE(type) & typeFilter))
|
||||
return false;
|
||||
if (involvesWatchAddress && watchOnlyFilter == WatchOnlyFilter_No)
|
||||
return false;
|
||||
if (!involvesWatchAddress && watchOnlyFilter == WatchOnlyFilter_Yes)
|
||||
return false;
|
||||
if(datetime < dateFrom || datetime > dateTo)
|
||||
return false;
|
||||
if (!address.contains(addrPrefix, Qt::CaseInsensitive) && !label.contains(addrPrefix, Qt::CaseInsensitive))
|
||||
@ -78,6 +84,12 @@ void TransactionFilterProxy::setMinAmount(qint64 minimum)
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
void TransactionFilterProxy::setWatchOnlyFilter(WatchOnlyFilter filter)
|
||||
{
|
||||
this->watchOnlyFilter = filter;
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
void TransactionFilterProxy::setLimit(int limit)
|
||||
{
|
||||
this->limitRows = limit;
|
||||
|
@ -25,6 +25,13 @@ public:
|
||||
|
||||
static quint32 TYPE(int type) { return 1<<type; }
|
||||
|
||||
enum WatchOnlyFilter
|
||||
{
|
||||
WatchOnlyFilter_All,
|
||||
WatchOnlyFilter_Yes,
|
||||
WatchOnlyFilter_No
|
||||
};
|
||||
|
||||
void setDateRange(const QDateTime &from, const QDateTime &to);
|
||||
void setAddressPrefix(const QString &addrPrefix);
|
||||
/**
|
||||
@ -32,6 +39,7 @@ public:
|
||||
*/
|
||||
void setTypeFilter(quint32 modes);
|
||||
void setMinAmount(qint64 minimum);
|
||||
void setWatchOnlyFilter(WatchOnlyFilter filter);
|
||||
|
||||
/** Set maximum number of rows returned, -1 if unlimited. */
|
||||
void setLimit(int limit);
|
||||
@ -49,6 +57,7 @@ private:
|
||||
QDateTime dateTo;
|
||||
QString addrPrefix;
|
||||
quint32 typeFilter;
|
||||
WatchOnlyFilter watchOnlyFilter;
|
||||
qint64 minAmount;
|
||||
int limitRows;
|
||||
bool showInactive;
|
||||
|
@ -27,6 +27,7 @@
|
||||
// Amount column is right-aligned it contains numbers
|
||||
static int column_alignments[] = {
|
||||
Qt::AlignLeft|Qt::AlignVCenter, /* status */
|
||||
Qt::AlignLeft|Qt::AlignVCenter, /* watchonly */
|
||||
Qt::AlignLeft|Qt::AlignVCenter, /* date */
|
||||
Qt::AlignLeft|Qt::AlignVCenter, /* type */
|
||||
Qt::AlignLeft|Qt::AlignVCenter, /* address */
|
||||
@ -234,7 +235,7 @@ TransactionTableModel::TransactionTableModel(CWallet* wallet, WalletModel *paren
|
||||
walletModel(parent),
|
||||
priv(new TransactionTablePriv(wallet, this))
|
||||
{
|
||||
columns << QString() << tr("Date") << tr("Type") << tr("Address") << BitcoinUnits::getAmountColumnTitle(walletModel->getOptionsModel()->getDisplayUnit());
|
||||
columns << QString() << QString() << tr("Date") << tr("Type") << tr("Address") << BitcoinUnits::getAmountColumnTitle(walletModel->getOptionsModel()->getDisplayUnit());
|
||||
priv->refreshWallet();
|
||||
|
||||
connect(walletModel->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
|
||||
@ -393,22 +394,19 @@ QVariant TransactionTableModel::txAddressDecoration(const TransactionRecord *wtx
|
||||
|
||||
QString TransactionTableModel::formatTxToAddress(const TransactionRecord *wtx, bool tooltip) const
|
||||
{
|
||||
// mark transactions involving watch-only addresses:
|
||||
QString watchAddress = wtx->involvesWatchAddress ? " (w) " : "";
|
||||
|
||||
switch(wtx->type)
|
||||
{
|
||||
case TransactionRecord::RecvFromOther:
|
||||
return QString::fromStdString(wtx->address) + watchAddress;
|
||||
return QString::fromStdString(wtx->address);
|
||||
case TransactionRecord::RecvWithAddress:
|
||||
case TransactionRecord::SendToAddress:
|
||||
case TransactionRecord::Generated:
|
||||
return lookupAddress(wtx->address, tooltip) + watchAddress;
|
||||
return lookupAddress(wtx->address, tooltip);
|
||||
case TransactionRecord::SendToOther:
|
||||
return QString::fromStdString(wtx->address) + watchAddress;
|
||||
return QString::fromStdString(wtx->address);
|
||||
case TransactionRecord::SendToSelf:
|
||||
default:
|
||||
return tr("(n/a)") + watchAddress;
|
||||
return tr("(n/a)");
|
||||
}
|
||||
}
|
||||
|
||||
@ -482,6 +480,14 @@ QVariant TransactionTableModel::txStatusDecoration(const TransactionRecord *wtx)
|
||||
return QColor(0,0,0);
|
||||
}
|
||||
|
||||
QVariant TransactionTableModel::txWatchonlyDecoration(const TransactionRecord *wtx) const
|
||||
{
|
||||
if (wtx->involvesWatchAddress)
|
||||
return QIcon(":/icons/eye");
|
||||
else
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QString TransactionTableModel::formatTooltip(const TransactionRecord *rec) const
|
||||
{
|
||||
QString tooltip = formatTxStatus(rec) + QString("\n") + formatTxType(rec);
|
||||
@ -506,6 +512,8 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
case Status:
|
||||
return txStatusDecoration(rec);
|
||||
case Watchonly:
|
||||
return txWatchonlyDecoration(rec);
|
||||
case ToAddress:
|
||||
return txAddressDecoration(rec);
|
||||
}
|
||||
@ -533,6 +541,8 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
|
||||
return rec->time;
|
||||
case Type:
|
||||
return formatTxType(rec);
|
||||
case Watchonly:
|
||||
return (rec->involvesWatchAddress ? 1 : 0);
|
||||
case ToAddress:
|
||||
return formatTxToAddress(rec, true);
|
||||
case Amount:
|
||||
@ -562,6 +572,10 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
|
||||
return rec->type;
|
||||
case DateRole:
|
||||
return QDateTime::fromTime_t(static_cast<uint>(rec->time));
|
||||
case WatchonlyRole:
|
||||
return rec->involvesWatchAddress;
|
||||
case WatchonlyDecorationRole:
|
||||
return txWatchonlyDecoration(rec);
|
||||
case LongDescriptionRole:
|
||||
return priv->describe(rec, walletModel->getOptionsModel()->getDisplayUnit());
|
||||
case AddressRole:
|
||||
@ -606,6 +620,8 @@ QVariant TransactionTableModel::headerData(int section, Qt::Orientation orientat
|
||||
return tr("Date and time that the transaction was received.");
|
||||
case Type:
|
||||
return tr("Type of transaction.");
|
||||
case Watchonly:
|
||||
return tr("Whether or not a watch-only address is involved in this transaction.");
|
||||
case ToAddress:
|
||||
return tr("Destination address of transaction.");
|
||||
case Amount:
|
||||
|
@ -28,10 +28,11 @@ public:
|
||||
|
||||
enum ColumnIndex {
|
||||
Status = 0,
|
||||
Date = 1,
|
||||
Type = 2,
|
||||
ToAddress = 3,
|
||||
Amount = 4
|
||||
Watchonly = 1,
|
||||
Date = 2,
|
||||
Type = 3,
|
||||
ToAddress = 4,
|
||||
Amount = 5
|
||||
};
|
||||
|
||||
/** Roles to get specific information from a transaction row.
|
||||
@ -42,6 +43,10 @@ public:
|
||||
TypeRole = Qt::UserRole,
|
||||
/** Date and time this transaction was created */
|
||||
DateRole,
|
||||
/** Watch-only boolean */
|
||||
WatchonlyRole,
|
||||
/** Watch-only icon */
|
||||
WatchonlyDecorationRole,
|
||||
/** Long description (HTML format) */
|
||||
LongDescriptionRole,
|
||||
/** Address of transaction */
|
||||
@ -83,6 +88,7 @@ private:
|
||||
QString formatTxAmount(const TransactionRecord *wtx, bool showUnconfirmed=true, BitcoinUnits::SeparatorStyle separators=BitcoinUnits::separatorStandard) const;
|
||||
QString formatTooltip(const TransactionRecord *rec) const;
|
||||
QVariant txStatusDecoration(const TransactionRecord *wtx) const;
|
||||
QVariant txWatchonlyDecoration(const TransactionRecord *wtx) const;
|
||||
QVariant txAddressDecoration(const TransactionRecord *wtx) const;
|
||||
|
||||
public slots:
|
||||
|
@ -51,6 +51,13 @@ TransactionView::TransactionView(QWidget *parent) :
|
||||
hlayout->addSpacing(23);
|
||||
#endif
|
||||
|
||||
watchOnlyWidget = new QComboBox(this);
|
||||
watchOnlyWidget->setFixedWidth(24);
|
||||
watchOnlyWidget->addItem("", TransactionFilterProxy::WatchOnlyFilter_All);
|
||||
watchOnlyWidget->addItem(QIcon(":/icons/eye_plus"), "", TransactionFilterProxy::WatchOnlyFilter_Yes);
|
||||
watchOnlyWidget->addItem(QIcon(":/icons/eye_minus"), "", TransactionFilterProxy::WatchOnlyFilter_No);
|
||||
hlayout->addWidget(watchOnlyWidget);
|
||||
|
||||
dateWidget = new QComboBox(this);
|
||||
#ifdef Q_OS_MAC
|
||||
dateWidget->setFixedWidth(121);
|
||||
@ -150,6 +157,7 @@ TransactionView::TransactionView(QWidget *parent) :
|
||||
|
||||
connect(dateWidget, SIGNAL(activated(int)), this, SLOT(chooseDate(int)));
|
||||
connect(typeWidget, SIGNAL(activated(int)), this, SLOT(chooseType(int)));
|
||||
connect(watchOnlyWidget, SIGNAL(activated(int)), this, SLOT(chooseWatchonly(int)));
|
||||
connect(addressWidget, SIGNAL(textChanged(QString)), this, SLOT(changedPrefix(QString)));
|
||||
connect(amountWidget, SIGNAL(textChanged(QString)), this, SLOT(changedAmount(QString)));
|
||||
|
||||
@ -187,6 +195,7 @@ void TransactionView::setModel(WalletModel *model)
|
||||
transactionView->verticalHeader()->hide();
|
||||
|
||||
transactionView->setColumnWidth(TransactionTableModel::Status, STATUS_COLUMN_WIDTH);
|
||||
transactionView->setColumnWidth(TransactionTableModel::Watchonly, WATCHONLY_COLUMN_WIDTH);
|
||||
transactionView->setColumnWidth(TransactionTableModel::Date, DATE_COLUMN_WIDTH);
|
||||
transactionView->setColumnWidth(TransactionTableModel::Type, TYPE_COLUMN_WIDTH);
|
||||
transactionView->setColumnWidth(TransactionTableModel::Amount, AMOUNT_MINIMUM_COLUMN_WIDTH);
|
||||
@ -211,6 +220,12 @@ void TransactionView::setModel(WalletModel *model)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// show/hide column Watch-only
|
||||
updateWatchOnlyColumn(model->haveWatchOnly());
|
||||
|
||||
// Watch-only signal
|
||||
connect(model, SIGNAL(notifyWatchonlyChanged(bool)), this, SLOT(updateWatchOnlyColumn(bool)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -270,6 +285,14 @@ void TransactionView::chooseType(int idx)
|
||||
typeWidget->itemData(idx).toInt());
|
||||
}
|
||||
|
||||
void TransactionView::chooseWatchonly(int idx)
|
||||
{
|
||||
if(!transactionProxyModel)
|
||||
return;
|
||||
transactionProxyModel->setWatchOnlyFilter(
|
||||
(TransactionFilterProxy::WatchOnlyFilter)watchOnlyWidget->itemData(idx).toInt());
|
||||
}
|
||||
|
||||
void TransactionView::changedPrefix(const QString &prefix)
|
||||
{
|
||||
if(!transactionProxyModel)
|
||||
@ -307,6 +330,8 @@ void TransactionView::exportClicked()
|
||||
// name, column, role
|
||||
writer.setModel(transactionProxyModel);
|
||||
writer.addColumn(tr("Confirmed"), 0, TransactionTableModel::ConfirmedRole);
|
||||
if (model && model->haveWatchOnly())
|
||||
writer.addColumn(tr("Watchonly"), TransactionTableModel::Watchonly);
|
||||
writer.addColumn(tr("Date"), 0, TransactionTableModel::DateRole);
|
||||
writer.addColumn(tr("Type"), TransactionTableModel::Type, Qt::EditRole);
|
||||
writer.addColumn(tr("Label"), 0, TransactionTableModel::LabelRole);
|
||||
@ -501,3 +526,10 @@ bool TransactionView::eventFilter(QObject *obj, QEvent *event)
|
||||
}
|
||||
return QWidget::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
// show/hide column Watch-only
|
||||
void TransactionView::updateWatchOnlyColumn(bool fHaveWatchOnly)
|
||||
{
|
||||
watchOnlyWidget->setVisible(fHaveWatchOnly);
|
||||
transactionView->setColumnHidden(TransactionTableModel::Watchonly, !fHaveWatchOnly);
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ public:
|
||||
|
||||
enum ColumnWidths {
|
||||
STATUS_COLUMN_WIDTH = 23,
|
||||
WATCHONLY_COLUMN_WIDTH = 23,
|
||||
DATE_COLUMN_WIDTH = 120,
|
||||
TYPE_COLUMN_WIDTH = 120,
|
||||
AMOUNT_MINIMUM_COLUMN_WIDTH = 120,
|
||||
@ -63,6 +64,7 @@ private:
|
||||
|
||||
QComboBox *dateWidget;
|
||||
QComboBox *typeWidget;
|
||||
QComboBox *watchOnlyWidget;
|
||||
QLineEdit *addressWidget;
|
||||
QLineEdit *amountWidget;
|
||||
|
||||
@ -91,6 +93,7 @@ private slots:
|
||||
void copyAmount();
|
||||
void copyTxID();
|
||||
void openThirdPartyTxUrl(QString url);
|
||||
void updateWatchOnlyColumn(bool fHaveWatchOnly);
|
||||
|
||||
signals:
|
||||
void doubleClicked(const QModelIndex&);
|
||||
@ -101,6 +104,7 @@ signals:
|
||||
public slots:
|
||||
void chooseDate(int idx);
|
||||
void chooseType(int idx);
|
||||
void chooseWatchonly(int idx);
|
||||
void changedPrefix(const QString &prefix);
|
||||
void changedAmount(const QString &amount);
|
||||
void exportClicked();
|
||||
|
@ -35,6 +35,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);
|
||||
@ -80,6 +81,11 @@ qint64 WalletModel::getImmatureBalance() const
|
||||
return wallet->GetImmatureBalance();
|
||||
}
|
||||
|
||||
bool WalletModel::haveWatchOnly() const
|
||||
{
|
||||
return fHaveWatchOnly;
|
||||
}
|
||||
|
||||
qint64 WalletModel::getWatchBalance() const
|
||||
{
|
||||
return wallet->GetWatchOnlyBalance();
|
||||
@ -131,9 +137,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)
|
||||
@ -165,6 +177,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());
|
||||
@ -479,6 +497,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
|
||||
@ -486,6 +510,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()
|
||||
@ -495,6 +520,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
|
||||
|
@ -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;
|
||||
@ -197,6 +198,7 @@ public:
|
||||
private:
|
||||
CWallet *wallet;
|
||||
bool fProcessingQueuedTransactions;
|
||||
bool fHaveWatchOnly;
|
||||
|
||||
// Wallet has an options model for wallet-specific options
|
||||
// (transaction fee, for example)
|
||||
@ -244,6 +246,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();
|
||||
@ -251,6 +256,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 */
|
||||
|
@ -161,6 +161,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);
|
||||
|
@ -399,6 +399,9 @@ public:
|
||||
|
||||
/** Show progress e.g. for rescan */
|
||||
boost::signals2::signal<void (const std::string &title, int nProgress)> ShowProgress;
|
||||
|
||||
/** Watch-only address added */
|
||||
boost::signals2::signal<void (bool fHaveWatchOnly)> NotifyWatchonlyChanged;
|
||||
};
|
||||
|
||||
/** A key allocated from the key pool. */
|
||||
|
Loading…
Reference in New Issue
Block a user