diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index 2a6fb40cae8d1..56d6df93557a4 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -421,11 +421,21 @@ bool AddressTableModel::removeRows(int row, int count, const QModelIndex &parent /* Look up label for address in address book, if not found return empty string. */ QString AddressTableModel::labelForAddress(const QString &address) const +{ + CBitcoinAddress address_parsed(address.toStdString()); + return labelForAddress(address_parsed); +} + +QString AddressTableModel::labelForAddress(const CBitcoinAddress &address) const +{ + return labelForDestination(address.Get()); +} + +QString AddressTableModel::labelForDestination(const CTxDestination &dest) const { { LOCK(wallet->cs_wallet); - CBitcoinAddress address_parsed(address.toStdString()); - std::map::iterator mi = wallet->mapAddressBook.find(address_parsed.Get()); + std::map::iterator mi = wallet->mapAddressBook.find(dest); if (mi != wallet->mapAddressBook.end()) { return QString::fromStdString(mi->second.name); diff --git a/src/qt/addresstablemodel.h b/src/qt/addresstablemodel.h index d04b95ebaeb36..f55921bc6dd06 100644 --- a/src/qt/addresstablemodel.h +++ b/src/qt/addresstablemodel.h @@ -5,6 +5,8 @@ #ifndef BITCOIN_QT_ADDRESSTABLEMODEL_H #define BITCOIN_QT_ADDRESSTABLEMODEL_H +#include "base58.h" + #include #include @@ -66,6 +68,8 @@ class AddressTableModel : public QAbstractTableModel /* Look up label for address in address book, if not found return empty string. */ QString labelForAddress(const QString &address) const; + QString labelForAddress(const CBitcoinAddress &address) const; + QString labelForDestination(const CTxDestination &dest) const; /* Look up row index of an address in the model. Return -1 if not found. diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index a3d8706c78a7f..6c10ffd22dcc9 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -107,14 +107,14 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco if (nNet > 0) { // Credit - if (CBitcoinAddress(rec->address).IsValid()) + if (rec->address.IsValid()) { - CTxDestination address = CBitcoinAddress(rec->address).Get(); + CTxDestination address = rec->txDest; if (wallet->mapAddressBook.count(address)) { strHTML += "" + tr("From") + ": " + tr("unknown") + "
"; strHTML += "" + tr("To") + ": "; - strHTML += GUIUtil::HtmlEscape(rec->address); + strHTML += GUIUtil::HtmlEscape(rec->strAddress); QString addressOwned = (::IsMine(*wallet, address) == ISMINE_SPENDABLE) ? tr("own address") : tr("watch-only"); if (!wallet->mapAddressBook[address].name.empty()) strHTML += " (" + addressOwned + ", " + tr("label") + ": " + GUIUtil::HtmlEscape(wallet->mapAddressBook[address].name) + ")"; diff --git a/src/qt/transactionfilterproxy.cpp b/src/qt/transactionfilterproxy.cpp index e4eff3e3fc141..b50fe7923ef47 100644 --- a/src/qt/transactionfilterproxy.cpp +++ b/src/qt/transactionfilterproxy.cpp @@ -18,8 +18,8 @@ const QDateTime TransactionFilterProxy::MAX_DATE = QDateTime::fromTime_t(0xFFFFF TransactionFilterProxy::TransactionFilterProxy(QObject *parent) : QSortFilterProxyModel(parent), - dateFrom(MIN_DATE), - dateTo(MAX_DATE), + dateFrom(MIN_DATE.toTime_t()), + dateTo(MAX_DATE.toTime_t()), addrPrefix(), typeFilter(COMMON_TYPES), watchOnlyFilter(WatchOnlyFilter_All), @@ -35,7 +35,7 @@ bool TransactionFilterProxy::filterAcceptsRow(int sourceRow, const QModelIndex & QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); int type = index.data(TransactionTableModel::TypeRole).toInt(); - QDateTime datetime = index.data(TransactionTableModel::DateRole).toDateTime(); + qint64 datetime = index.data(TransactionTableModel::DateRoleInt).toLongLong(); bool involvesWatchAddress = index.data(TransactionTableModel::WatchonlyRole).toBool(); bool lockedByInstantSend = index.data(TransactionTableModel::InstantSendRole).toBool(); QString address = index.data(TransactionTableModel::AddressRole).toString(); @@ -67,8 +67,8 @@ bool TransactionFilterProxy::filterAcceptsRow(int sourceRow, const QModelIndex & void TransactionFilterProxy::setDateRange(const QDateTime &from, const QDateTime &to) { - this->dateFrom = from; - this->dateTo = to; + this->dateFrom = from.toTime_t(); + this->dateTo = to.toTime_t(); invalidateFilter(); } diff --git a/src/qt/transactionfilterproxy.h b/src/qt/transactionfilterproxy.h index ed25b29c99c8c..026ca31c9efdf 100644 --- a/src/qt/transactionfilterproxy.h +++ b/src/qt/transactionfilterproxy.h @@ -65,8 +65,8 @@ class TransactionFilterProxy : public QSortFilterProxyModel bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const; private: - QDateTime dateFrom; - QDateTime dateTo; + qint64 dateFrom; + qint64 dateTo; QString addrPrefix; quint32 typeFilter; WatchOnlyFilter watchOnlyFilter; diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 205bc14daf687..c2d180093e600 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -58,13 +58,13 @@ QList TransactionRecord::decomposeTransaction(const CWallet * { // Received by Dash Address sub.type = TransactionRecord::RecvWithAddress; - sub.address = CBitcoinAddress(address).ToString(); + sub.strAddress = CBitcoinAddress(address).ToString(); } else { // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction sub.type = TransactionRecord::RecvFromOther; - sub.address = mapValue["from"]; + sub.strAddress = mapValue["from"]; } if (wtx.IsCoinBase()) { @@ -72,6 +72,8 @@ QList TransactionRecord::decomposeTransaction(const CWallet * sub.type = TransactionRecord::Generated; } + sub.address.SetString(sub.strAddress); + sub.txDest = sub.address.Get(); parts.append(sub); } } @@ -119,7 +121,7 @@ QList TransactionRecord::decomposeTransaction(const CWallet * TransactionRecord sub(hash, nTime); // Payment to self by default sub.type = TransactionRecord::SendToSelf; - sub.address = ""; + sub.strAddress = ""; if(mapValue["DS"] == "1") { @@ -128,12 +130,12 @@ QList TransactionRecord::decomposeTransaction(const CWallet * if (ExtractDestination(wtx.tx->vout[0].scriptPubKey, address)) { // Sent to Dash Address - sub.address = CBitcoinAddress(address).ToString(); + sub.strAddress = CBitcoinAddress(address).ToString(); } else { // Sent to IP, or other non-address transaction like OP_EVAL - sub.address = mapValue["to"]; + sub.strAddress = mapValue["to"]; } } else @@ -162,6 +164,8 @@ QList TransactionRecord::decomposeTransaction(const CWallet * sub.debit = -(nDebit - nChange); sub.credit = nCredit - nChange; + sub.address.SetString(sub.strAddress); + sub.txDest = sub.address.Get(); parts.append(sub); parts.last().involvesWatchAddress = involvesWatchAddress; // maybe pass to TransactionRecord as constructor argument } @@ -205,13 +209,13 @@ QList TransactionRecord::decomposeTransaction(const CWallet * { // Sent to Dash Address sub.type = TransactionRecord::SendToAddress; - sub.address = CBitcoinAddress(address).ToString(); + sub.strAddress = CBitcoinAddress(address).ToString(); } else { // Sent to IP, or other non-address transaction like OP_EVAL sub.type = TransactionRecord::SendToOther; - sub.address = mapValue["to"]; + sub.strAddress = mapValue["to"]; } if(mapValue["DS"] == "1") @@ -228,6 +232,9 @@ QList TransactionRecord::decomposeTransaction(const CWallet * } sub.debit = -nValue; + sub.address.SetString(sub.strAddress); + sub.txDest = sub.address.Get(); + parts.append(sub); } } @@ -244,9 +251,10 @@ QList TransactionRecord::decomposeTransaction(const CWallet * return parts; } -void TransactionRecord::updateStatus(const CWalletTx &wtx, int numISLocks, int chainLockHeight) +void TransactionRecord::updateStatus(const CWalletTx &wtx, int chainLockHeight) { AssertLockHeld(cs_main); + AssertLockHeld(wtx.GetWallet()->cs_wallet); // Determine transaction status // Find the block the tx is in @@ -264,9 +272,20 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx, int numISLocks, int c status.countsForBalance = wtx.IsTrusted() && !(wtx.GetBlocksToMaturity() > 0); status.depth = wtx.GetDepthInMainChain(); status.cur_num_blocks = chainActive.Height(); - status.cachedNumISLocks = numISLocks; status.cachedChainLockHeight = chainLockHeight; + bool oldLockedByChainLocks = status.lockedByChainLocks; + if (!status.lockedByChainLocks) { + status.lockedByChainLocks = wtx.IsChainLocked(); + } + + auto addrBookIt = wtx.GetWallet()->mapAddressBook.find(this->txDest); + if (addrBookIt == wtx.GetWallet()->mapAddressBook.end()) { + status.label = ""; + } else { + status.label = QString::fromStdString(addrBookIt->second.name); + } + if (!CheckFinalTx(wtx)) { if (wtx.tx->nLockTime < LOCKTIME_THRESHOLD) @@ -307,7 +326,17 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx, int numISLocks, int c } else { - status.lockedByInstantSend = wtx.IsLockedByInstantSend(); + // The IsLockedByInstantSend call is quite expensive, so we only do it when a state change is actually possible. + if (status.lockedByChainLocks) { + if (oldLockedByChainLocks != status.lockedByChainLocks) { + status.lockedByInstantSend = wtx.IsLockedByInstantSend(); + } else { + status.lockedByInstantSend = false; + } + } else if (!status.lockedByInstantSend) { + status.lockedByInstantSend = wtx.IsLockedByInstantSend(); + } + if (status.depth < 0) { status.status = TransactionStatus::Conflicted; @@ -322,7 +351,7 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx, int numISLocks, int c if (wtx.isAbandoned()) status.status = TransactionStatus::Abandoned; } - else if (status.depth < RecommendedNumConfirmations && !wtx.IsChainLocked()) + else if (status.depth < RecommendedNumConfirmations && !status.lockedByChainLocks) { status.status = TransactionStatus::Confirming; } @@ -331,15 +360,14 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx, int numISLocks, int c status.status = TransactionStatus::Confirmed; } } - + status.needsUpdate = false; } -bool TransactionRecord::statusUpdateNeeded(int numISLocks, int chainLockHeight) +bool TransactionRecord::statusUpdateNeeded(int chainLockHeight) { AssertLockHeld(cs_main); - return status.cur_num_blocks != chainActive.Height() - || status.cachedNumISLocks != numISLocks - || status.cachedChainLockHeight != chainLockHeight; + return status.cur_num_blocks != chainActive.Height() || status.needsUpdate + || (!status.lockedByChainLocks && status.cachedChainLockHeight != chainLockHeight); } QString TransactionRecord::getTxID() const diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h index 3ad6556fd0a83..309f3fd005f48 100644 --- a/src/qt/transactionrecord.h +++ b/src/qt/transactionrecord.h @@ -7,6 +7,7 @@ #include "amount.h" #include "uint256.h" +#include "base58.h" #include #include @@ -20,9 +21,9 @@ class TransactionStatus { public: TransactionStatus(): - countsForBalance(false), lockedByInstantSend(false), sortKey(""), + countsForBalance(false), lockedByInstantSend(false), lockedByChainLocks(false), sortKey(""), matures_in(0), status(Offline), depth(0), open_for(0), cur_num_blocks(-1), - cachedNumISLocks(-1), cachedChainLockHeight(-1) + cachedChainLockHeight(-1), needsUpdate(false) { } enum Status { @@ -45,8 +46,12 @@ class TransactionStatus bool countsForBalance; /// Transaction was locked via InstantSend bool lockedByInstantSend; + /// Transaction was locked via ChainLocks + bool lockedByChainLocks; /// Sorting key based on status std::string sortKey; + /// Label + QString label; /** @name Generated (mined) transactions @{*/ @@ -65,10 +70,10 @@ class TransactionStatus /** Current number of blocks (to know whether cached status is still valid) */ int cur_num_blocks; - //** Know when to update transaction for IS-locks **/ - int cachedNumISLocks; //** Know when to update transaction for chainlocks **/ int cachedChainLockHeight; + + bool needsUpdate; }; /** UI model for a transaction. A core transaction can be represented by multiple UI transactions if it has @@ -98,22 +103,28 @@ class TransactionRecord static const int RecommendedNumConfirmations = 6; TransactionRecord(): - hash(), time(0), type(Other), address(""), debit(0), credit(0), idx(0) + hash(), time(0), type(Other), strAddress(""), debit(0), credit(0), idx(0) { + address = CBitcoinAddress(strAddress); + txDest = address.Get(); } TransactionRecord(uint256 _hash, qint64 _time): - hash(_hash), time(_time), type(Other), address(""), debit(0), + hash(_hash), time(_time), type(Other), strAddress(""), debit(0), credit(0), idx(0) { + address = CBitcoinAddress(strAddress); + txDest = address.Get(); } TransactionRecord(uint256 _hash, qint64 _time, - Type _type, const std::string &_address, + Type _type, const std::string &_strAddress, const CAmount& _debit, const CAmount& _credit): - hash(_hash), time(_time), type(_type), address(_address), debit(_debit), credit(_credit), + hash(_hash), time(_time), type(_type), strAddress(_strAddress), debit(_debit), credit(_credit), idx(0) { + address = CBitcoinAddress(strAddress); + txDest = address.Get(); } /** Decompose CWallet transaction to model transaction records. @@ -126,7 +137,10 @@ class TransactionRecord uint256 hash; qint64 time; Type type; - std::string address; + std::string strAddress; + CBitcoinAddress address; + CTxDestination txDest; + CAmount debit; CAmount credit; /**@}*/ @@ -148,11 +162,11 @@ class TransactionRecord /** Update status from core wallet tx. */ - void updateStatus(const CWalletTx &wtx, int numISLocks, int chainLockHeight); + void updateStatus(const CWalletTx &wtx, int chainLockHeight); /** Return whether a status update is needed. */ - bool statusUpdateNeeded(int numISLocks, int chainLockHeight); + bool statusUpdateNeeded(int chainLockHeight); }; #endif // BITCOIN_QT_TRANSACTIONRECORD_H diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 03b2dbf4156c0..75fa2f43571f9 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -167,10 +167,28 @@ class TransactionTablePriv case CT_UPDATED: // Miscellaneous updates -- nothing to do, status update will take care of this, and is only computed for // visible transactions. + for (int i = lowerIndex; i < upperIndex; i++) { + TransactionRecord *rec = &cachedWallet[i]; + rec->status.needsUpdate = true; + } + Q_EMIT parent->dataChanged(parent->index(lowerIndex, TransactionTableModel::Status), parent->index(upperIndex, TransactionTableModel::Status)); break; } } + void updateAddressBook(const QString& address, const QString& label, bool isMine, const QString& purpose, int status) + { + std::string address2 = address.toStdString(); + int index = 0; + for (auto& rec : cachedWallet) { + if (rec.strAddress == address2) { + rec.status.needsUpdate = true; + Q_EMIT parent->dataChanged(parent->index(index, TransactionTableModel::ToAddress), parent->index(index, TransactionTableModel::ToAddress)); + } + index++; + } + } + int size() { return cachedWallet.size(); @@ -193,13 +211,13 @@ class TransactionTablePriv if(lockMain) { TRY_LOCK(wallet->cs_wallet, lockWallet); - if(lockWallet && (rec->statusUpdateNeeded(parent->getNumISLocks(), parent->getChainLockHeight()))) + if(lockWallet && (rec->statusUpdateNeeded(parent->getChainLockHeight()))) { std::map::iterator mi = wallet->mapWallet.find(rec->hash); if(mi != wallet->mapWallet.end()) { - rec->updateStatus(mi->second, parent->getNumISLocks(), parent->getChainLockHeight()); + rec->updateStatus(mi->second, parent->getChainLockHeight()); } } } @@ -271,6 +289,12 @@ void TransactionTableModel::updateTransaction(const QString &hash, int status, b priv->updateWallet(updated, status, showTransaction); } +void TransactionTableModel::updateAddressBook(const QString& address, const QString& label, bool isMine, + const QString& purpose, int status) +{ + priv->updateAddressBook(address, label, isMine, purpose, status); +} + void TransactionTableModel::updateConfirmations() { // Blocks came in since last poll. @@ -281,20 +305,10 @@ void TransactionTableModel::updateConfirmations() Q_EMIT dataChanged(index(0, ToAddress), index(priv->size()-1, ToAddress)); } -void TransactionTableModel::updateNumISLocks(int numISLocks) -{ - cachedNumISLocks = numISLocks; -} void TransactionTableModel::updateChainLockHeight(int chainLockHeight) { cachedChainLockHeight = chainLockHeight; - updateConfirmations(); -} - -int TransactionTableModel::getNumISLocks() const -{ - return cachedNumISLocks; } int TransactionTableModel::getChainLockHeight() const @@ -449,15 +463,15 @@ QString TransactionTableModel::formatTxToAddress(const TransactionRecord *wtx, b switch(wtx->type) { case TransactionRecord::RecvFromOther: - return QString::fromStdString(wtx->address) + watchAddress; + return QString::fromStdString(wtx->strAddress) + watchAddress; case TransactionRecord::RecvWithAddress: case TransactionRecord::RecvWithPrivateSend: case TransactionRecord::SendToAddress: case TransactionRecord::Generated: case TransactionRecord::PrivateSend: - return lookupAddress(wtx->address, tooltip) + watchAddress; + return lookupAddress(wtx->strAddress, tooltip) + watchAddress; case TransactionRecord::SendToOther: - return QString::fromStdString(wtx->address) + watchAddress; + return QString::fromStdString(wtx->strAddress) + watchAddress; case TransactionRecord::SendToSelf: default: return tr("(n/a)") + watchAddress; @@ -475,7 +489,7 @@ QVariant TransactionTableModel::addressColor(const TransactionRecord *wtx) const case TransactionRecord::PrivateSend: case TransactionRecord::RecvWithPrivateSend: { - QString label = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(wtx->address)); + QString label = walletModel->getAddressTableModel()->labelForDestination(wtx->txDest); if(label.isEmpty()) return COLOR_BAREADDRESS; } break; @@ -660,6 +674,8 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const return rec->type; case DateRole: return QDateTime::fromTime_t(static_cast(rec->time)); + case DateRoleInt: + return qint64(rec->time); case WatchonlyRole: return rec->involvesWatchAddress; case WatchonlyDecorationRole: @@ -671,9 +687,9 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const case LongDescriptionRole: return priv->describe(rec, walletModel->getOptionsModel()->getDisplayUnit()); case AddressRole: - return QString::fromStdString(rec->address); + return QString::fromStdString(rec->strAddress); case LabelRole: - return walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(rec->address)); + return rec->status.label; case AmountRole: return qint64(rec->credit + rec->debit); case TxIDRole: @@ -685,7 +701,7 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const case TxPlainTextRole: { QString details; - QString txLabel = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(rec->address)); + QString txLabel = rec->status.label; details.append(formatTxDate(rec)); details.append(" "); @@ -695,7 +711,7 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const details.append(formatTxType(rec)); details.append(" "); } - if(!rec->address.empty()) { + if(!rec->strAddress.empty()) { if(txLabel.isEmpty()) details.append(tr("(no label)") + " "); else { @@ -703,7 +719,7 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const details.append(txLabel); details.append(") "); } - details.append(QString::fromStdString(rec->address)); + details.append(QString::fromStdString(rec->strAddress)); details.append(" "); } details.append(formatTxAmount(rec, false, BitcoinUnits::separatorNever)); @@ -817,6 +833,16 @@ static void NotifyTransactionChanged(TransactionTableModel *ttm, CWallet *wallet notification.invoke(ttm); } +static void NotifyAddressBookChanged(TransactionTableModel *ttm, CWallet *wallet, const CTxDestination &address, const std::string &label, bool isMine, const std::string &purpose, ChangeType status) +{ + QMetaObject::invokeMethod(ttm, "updateAddressBook", Qt::QueuedConnection, + Q_ARG(QString, QString::fromStdString(CBitcoinAddress(address).ToString())), + Q_ARG(QString, QString::fromStdString(label)), + Q_ARG(bool, isMine), + Q_ARG(QString, QString::fromStdString(purpose)), + Q_ARG(int, (int)status)); +} + static void ShowProgress(TransactionTableModel *ttm, const std::string &title, int nProgress) { if (nProgress == 0) @@ -842,6 +868,7 @@ void TransactionTableModel::subscribeToCoreSignals() { // Connect signals to wallet wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3)); + wallet->NotifyAddressBookChanged.connect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6)); wallet->ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2)); } @@ -849,5 +876,6 @@ void TransactionTableModel::unsubscribeFromCoreSignals() { // Disconnect signals from wallet wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3)); + wallet->NotifyAddressBookChanged.disconnect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6)); wallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2)); } diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h index 81c94dcfc62c6..16669ac2ef5fe 100644 --- a/src/qt/transactiontablemodel.h +++ b/src/qt/transactiontablemodel.h @@ -45,6 +45,8 @@ class TransactionTableModel : public QAbstractTableModel TypeRole = Qt::UserRole, /** Date and time this transaction was created */ DateRole, + /** Date and time this transaction was created in MSec since epoch */ + DateRoleInt, /** Watch-only boolean */ WatchonlyRole, /** Watch-only icon */ @@ -85,9 +87,7 @@ class TransactionTableModel : public QAbstractTableModel QVariant headerData(int section, Qt::Orientation orientation, int role) const; QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const; bool processingQueuedTransactions() { return fProcessingQueuedTransactions; } - void updateNumISLocks(int numISLocks); void updateChainLockHeight(int chainLockHeight); - int getNumISLocks() const; int getChainLockHeight() const; private: @@ -97,7 +97,6 @@ class TransactionTableModel : public QAbstractTableModel TransactionTablePriv *priv; bool fProcessingQueuedTransactions; const PlatformStyle *platformStyle; - int cachedNumISLocks; int cachedChainLockHeight; void subscribeToCoreSignals(); @@ -119,6 +118,8 @@ class TransactionTableModel : public QAbstractTableModel public Q_SLOTS: /* New transaction, or transaction changed status */ void updateTransaction(const QString &hash, int status, bool showTransaction); + void updateAddressBook(const QString &address, const QString &label, + bool isMine, const QString &purpose, int status); void updateConfirmations(); void updateDisplayUnit(); /** Updates the column title to "Amount (DisplayUnit)" and emits headerDataChanged() signal for table headers to react. */ diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 780e95275b385..0abd177e6a461 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -192,16 +192,15 @@ void WalletModel::updateTransaction() void WalletModel::updateNumISLocks() { - fForceCheckBalanceChanged = true; cachedNumISLocks++; - if (transactionTableModel) - transactionTableModel->updateNumISLocks(cachedNumISLocks); } void WalletModel::updateChainLockHeight(int chainLockHeight) { if (transactionTableModel) transactionTableModel->updateChainLockHeight(chainLockHeight); + // Number and status of confirmations might have changed (WalletModel::pollBalanceChanged handles this as well) + fForceCheckBalanceChanged = true; } int WalletModel::getNumISLocks() const diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index c877af059969c..65b978b50a787 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -484,6 +484,11 @@ class CWalletTx : public CMerkleTx MarkDirty(); } + const CWallet* GetWallet() const + { + return pwallet; + } + //! filter decides which addresses will count towards the debit CAmount GetDebit(const isminefilter& filter) const; CAmount GetCredit(const isminefilter& filter) const;