Bitcoin ABC 0.30.5
P2P Digital Currency
transactiontablemodel.cpp
Go to the documentation of this file.
1// Copyright (c) 2011-2016 The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
6
7#include <core_io.h>
10#include <qt/clientmodel.h>
11#include <qt/guiconstants.h>
12#include <qt/guiutil.h>
13#include <qt/optionsmodel.h>
14#include <qt/platformstyle.h>
15#include <qt/transactiondesc.h>
17#include <qt/walletmodel.h>
18#include <uint256.h>
19
20#include <algorithm>
21#include <functional>
22
23#include <QColor>
24#include <QDateTime>
25#include <QDebug>
26#include <QIcon>
27#include <QList>
28
29// Amount column is right-aligned it contains numbers
30static int column_alignments[] = {
31 Qt::AlignLeft | Qt::AlignVCenter, /* status */
32 Qt::AlignLeft | Qt::AlignVCenter, /* watchonly */
33 Qt::AlignLeft | Qt::AlignVCenter, /* date */
34 Qt::AlignLeft | Qt::AlignVCenter, /* type */
35 Qt::AlignLeft | Qt::AlignVCenter, /* address */
36 Qt::AlignRight | Qt::AlignVCenter /* amount */
37};
38
39// Comparison operator for sort/binary search of model tx list
40struct TxLessThan {
42 const TransactionRecord &b) const {
43 return a.txid < b.txid;
44 }
45 bool operator()(const TransactionRecord &a, const TxId &b) const {
46 return a.txid < b;
47 }
48 bool operator()(const TxId &a, const TransactionRecord &b) const {
49 return a < b.txid;
50 }
51};
52
53// queue notifications to show a non freezing progress dialog e.g. for rescan
55public:
58 bool _showTransaction)
59 : txid(_txid), status(_status), showTransaction(_showTransaction) {}
60
61 void invoke(QObject *ttm) {
62 QString strHash = QString::fromStdString(txid.GetHex());
63 qDebug() << "NotifyTransactionChanged: " + strHash +
64 " status= " + QString::number(status);
65 bool invoked = QMetaObject::invokeMethod(
66 ttm, "updateTransaction", Qt::QueuedConnection,
67 Q_ARG(QString, strHash), Q_ARG(int, status),
68 Q_ARG(bool, showTransaction));
69 assert(invoked);
70 }
71
72private:
76};
77
78// Private implementation
80public:
82 : parent(_parent) {}
83
85
86 /* Local cache of wallet.
87 * As it is in the same order as the CWallet, by definition this is sorted
88 * by sha256.
89 */
90 QList<TransactionRecord> cachedWallet;
91
92 bool fQueueNotifications = false;
93 std::vector<TransactionNotification> vQueueNotifications;
94
95 void NotifyTransactionChanged(const TxId &txidc, ChangeType status);
96 void ShowProgress(const std::string &title, int nProgress);
97
102 qDebug() << "TransactionTablePriv::refreshWallet";
103 cachedWallet.clear();
104 for (const auto &wtx : wallet.getWalletTxs()) {
106 cachedWallet.append(
108 }
109 }
110 }
111
117 void updateWallet(interfaces::Wallet &wallet, const TxId &txid, int status,
118 bool showTransaction) {
119 qDebug() << "TransactionTablePriv::updateWallet: " +
120 QString::fromStdString(txid.ToString()) + " " +
121 QString::number(status);
122
123 // Find bounds of this transaction in model
124 QList<TransactionRecord>::iterator lower = std::lower_bound(
125 cachedWallet.begin(), cachedWallet.end(), txid, TxLessThan());
126 QList<TransactionRecord>::iterator upper = std::upper_bound(
127 cachedWallet.begin(), cachedWallet.end(), txid, TxLessThan());
128 int lowerIndex = (lower - cachedWallet.begin());
129 int upperIndex = (upper - cachedWallet.begin());
130 bool inModel = (lower != upper);
131
132 if (status == CT_UPDATED) {
133 // Not in model, but want to show, treat as new.
134 if (showTransaction && !inModel) {
135 status = CT_NEW;
136 }
137 // In model, but want to hide, treat as deleted.
138 if (!showTransaction && inModel) {
139 status = CT_DELETED;
140 }
141 }
142
143 qDebug() << " inModel=" + QString::number(inModel) +
144 " Index=" + QString::number(lowerIndex) + "-" +
145 QString::number(upperIndex) +
146 " showTransaction=" + QString::number(showTransaction) +
147 " derivedStatus=" + QString::number(status);
148
149 switch (status) {
150 case CT_NEW:
151 if (inModel) {
152 qWarning() << "TransactionTablePriv::updateWallet: "
153 "Warning: Got CT_NEW, but transaction is "
154 "already in model";
155 break;
156 }
157 if (showTransaction) {
158 // Find transaction in wallet
159 interfaces::WalletTx wtx = wallet.getWalletTx(txid);
160 if (!wtx.tx) {
161 qWarning() << "TransactionTablePriv::updateWallet: "
162 "Warning: Got CT_NEW, but transaction is "
163 "not in wallet";
164 break;
165 }
166 // Added -- insert at the right position
167 QList<TransactionRecord> toInsert =
169 /* only if something to insert */
170 if (!toInsert.isEmpty()) {
171 parent->beginInsertRows(QModelIndex(), lowerIndex,
172 lowerIndex + toInsert.size() -
173 1);
174 int insert_idx = lowerIndex;
175 for (const TransactionRecord &rec : toInsert) {
176 cachedWallet.insert(insert_idx, rec);
177 insert_idx += 1;
178 }
179 parent->endInsertRows();
180 }
181 }
182 break;
183 case CT_DELETED:
184 if (!inModel) {
185 qWarning() << "TransactionTablePriv::updateWallet: "
186 "Warning: Got CT_DELETED, but transaction is "
187 "not in model";
188 break;
189 }
190 // Removed -- remove entire transaction from table
191 parent->beginRemoveRows(QModelIndex(), lowerIndex,
192 upperIndex - 1);
193 cachedWallet.erase(lower, upper);
194 parent->endRemoveRows();
195 break;
196 case CT_UPDATED:
197 // Miscellaneous updates -- nothing to do, status update will
198 // take care of this, and is only computed for visible
199 // transactions.
200 break;
201 }
202 }
203
204 int size() { return cachedWallet.size(); }
205
207 const BlockHash &cur_block_hash, const int idx) {
208 if (idx >= 0 && idx < cachedWallet.size()) {
209 TransactionRecord *rec = &cachedWallet[idx];
210
211 // If a status update is needed (blocks came in since last check),
212 // try to update the status of this transaction from the wallet.
213 // Otherwise, simply re-use the cached status.
215 int numBlocks;
216 int64_t block_time;
217 if (!cur_block_hash.IsNull() &&
218 rec->statusUpdateNeeded(cur_block_hash) &&
219 wallet.tryGetTxStatus(rec->txid, wtx, numBlocks, block_time)) {
220 rec->updateStatus(wtx, cur_block_hash, numBlocks, block_time);
221 }
222 return rec;
223 }
224 return nullptr;
225 }
226
228 TransactionRecord *rec, int unit) {
229 return TransactionDesc::toHTML(node, wallet, rec, unit);
230 }
231
233 auto tx = wallet.getTx(rec->txid);
234 if (tx) {
235 std::string strHex = EncodeHexTx(*tx);
236 return QString::fromStdString(strHex);
237 }
238 return QString();
239 }
240};
241
243 const PlatformStyle *_platformStyle, WalletModel *parent)
244 : QAbstractTableModel(parent), walletModel(parent),
245 priv(new TransactionTablePriv(this)),
246 fProcessingQueuedTransactions(false), platformStyle(_platformStyle) {
247 columns << QString() << QString() << tr("Date") << tr("Type") << tr("Label")
251
254
256}
257
260 delete priv;
261}
262
268 Q_EMIT headerDataChanged(Qt::Horizontal, Amount, Amount);
269}
270
271void TransactionTableModel::updateTransaction(const QString &hash, int status,
272 bool showTransaction) {
273 TxId updated;
274 updated.SetHex(hash.toStdString());
275
276 priv->updateWallet(walletModel->wallet(), updated, status, showTransaction);
277}
278
280 // Blocks came in since last poll.
281 // Invalidate status (number of confirmations) and (possibly) description
282 // for all rows. Qt is smart enough to only actually request the data for
283 // the visible rows.
284 Q_EMIT dataChanged(index(0, Status), index(priv->size() - 1, Status));
285 Q_EMIT dataChanged(index(0, ToAddress), index(priv->size() - 1, ToAddress));
286}
287
288int TransactionTableModel::rowCount(const QModelIndex &parent) const {
289 Q_UNUSED(parent);
290 return priv->size();
291}
292
293int TransactionTableModel::columnCount(const QModelIndex &parent) const {
294 Q_UNUSED(parent);
295 return columns.length();
296}
297
298QString
300 QString status;
301
302 switch (wtx->status.status) {
304 status = tr("Unconfirmed");
305 break;
307 status = tr("Abandoned");
308 break;
310 status = tr("Confirming (%1 of %2 recommended confirmations)")
311 .arg(wtx->status.depth)
313 break;
315 status = tr("Confirmed (%1 confirmations)").arg(wtx->status.depth);
316 break;
318 status = tr("Conflicted");
319 break;
321 status =
322 tr("Immature (%1 confirmations, will be available after %2)")
323 .arg(wtx->status.depth)
324 .arg(wtx->status.depth + wtx->status.matures_in);
325 break;
327 status = tr("Generated but not accepted");
328 break;
329 }
330
331 return status;
332}
333
334QString
336 if (wtx->time) {
337 return GUIUtil::dateTimeStr(wtx->time);
338 }
339 return QString();
340}
341
346QString TransactionTableModel::lookupAddress(const std::string &address,
347 bool tooltip) const {
349 QString::fromStdString(address));
350 QString description;
351 if (!label.isEmpty()) {
352 description += label;
353 }
354 if (label.isEmpty() || tooltip) {
355 description +=
356 QString(" (") + QString::fromStdString(address) + QString(")");
357 }
358 return description;
359}
360
361QString
363 switch (wtx->type) {
365 return tr("Received with");
367 return tr("Received from");
370 return tr("Sent to");
372 return tr("Payment to yourself");
374 return tr("Mined");
375 default:
376 return QString();
377 }
378}
379
380QVariant
382 switch (wtx->type) {
384 return QIcon(":/icons/tx_mined");
387 return QIcon(":/icons/tx_input");
390 return QIcon(":/icons/tx_output");
391 default:
392 return QIcon(":/icons/tx_inout");
393 }
394}
395
397 bool tooltip) const {
398 QString watchAddress;
399 if (tooltip) {
400 // Mark transactions involving watch-only addresses by adding "
401 // (watch-only)"
402 watchAddress = wtx->involvesWatchAddress
403 ? QString(" (") + tr("watch-only") + QString(")")
404 : "";
405 }
406
407 switch (wtx->type) {
409 return QString::fromStdString(wtx->address) + watchAddress;
413 return lookupAddress(wtx->address, tooltip) + watchAddress;
415 return QString::fromStdString(wtx->address) + watchAddress;
417 return lookupAddress(wtx->address, tooltip) + watchAddress;
418 default:
419 return tr("(n/a)") + watchAddress;
420 }
421}
422
423QVariant
425 // Show addresses without label in a less visible color
426 switch (wtx->type) {
430 QString label =
432 QString::fromStdString(wtx->address));
433 if (label.isEmpty()) {
434 return COLOR_BAREADDRESS;
435 }
436 } break;
438 return COLOR_BAREADDRESS;
439 default:
440 break;
441 }
442 return QVariant();
443}
444
446 const TransactionRecord *wtx, bool showUnconfirmed,
447 BitcoinUnits::SeparatorStyle separators) const {
448 QString str =
450 wtx->credit + wtx->debit, false, separators);
451 if (showUnconfirmed) {
452 if (!wtx->status.countsForBalance) {
453 str = QString("[") + str + QString("]");
454 }
455 }
456 return QString(str);
457}
458
459QVariant
461 switch (wtx->status.status) {
463 return QIcon(":/icons/transaction_0");
465 return QIcon(":/icons/transaction_abandoned");
467 switch (wtx->status.depth) {
468 case 1:
469 return QIcon(":/icons/transaction_1");
470 case 2:
471 return QIcon(":/icons/transaction_2");
472 case 3:
473 return QIcon(":/icons/transaction_3");
474 case 4:
475 return QIcon(":/icons/transaction_4");
476 default:
477 return QIcon(":/icons/transaction_5");
478 };
480 return QIcon(":/icons/transaction_confirmed");
482 return QIcon(":/icons/transaction_conflicted");
484 int total = wtx->status.depth + wtx->status.matures_in;
485 int part = (wtx->status.depth * 4 / total) + 1;
486 return QIcon(QString(":/icons/transaction_%1").arg(part));
487 }
489 return QIcon(":/icons/transaction_0");
490 default:
491 return COLOR_BLACK;
492 }
493}
494
496 const TransactionRecord *wtx) const {
497 if (wtx->involvesWatchAddress) {
498 return QIcon(":/icons/eye");
499 }
500
501 return QVariant();
502}
503
504QString
506 QString tooltip = formatTxStatus(rec) + QString("\n") + formatTxType(rec);
511 tooltip += QString(" ") + formatTxToAddress(rec, true);
512 }
513 return tooltip;
514}
515
516QVariant TransactionTableModel::data(const QModelIndex &index, int role) const {
517 if (!index.isValid()) {
518 return QVariant();
519 }
520
521 TransactionRecord *rec =
522 static_cast<TransactionRecord *>(index.internalPointer());
523
524 switch (role) {
526 switch (index.column()) {
527 case Status:
528 return txStatusDecoration(rec);
529 case Watchonly:
530 return txWatchonlyDecoration(rec);
531 case ToAddress:
532 return txAddressDecoration(rec);
533 }
534 break;
535 case Qt::DecorationRole: {
536 QIcon icon = qvariant_cast<QIcon>(index.data(RawDecorationRole));
537 return platformStyle->TextColorIcon(icon);
538 }
539 case Qt::DisplayRole:
540 switch (index.column()) {
541 case Date:
542 return formatTxDate(rec);
543 case Type:
544 return formatTxType(rec);
545 case ToAddress:
546 return formatTxToAddress(rec, false);
547 case Amount:
548 return formatTxAmount(rec, true,
550 }
551 break;
552 case Qt::EditRole:
553 // Edit role is used for sorting, so return the unformatted values
554 switch (index.column()) {
555 case Status:
556 return QString::fromStdString(rec->status.sortKey);
557 case Date:
558 return rec->time;
559 case Type:
560 return formatTxType(rec);
561 case Watchonly:
562 return (rec->involvesWatchAddress ? 1 : 0);
563 case ToAddress:
564 return formatTxToAddress(rec, true);
565 case Amount:
566 return qint64((rec->credit + rec->debit) / SATOSHI);
567 }
568 break;
569 case Qt::ToolTipRole:
570 return formatTooltip(rec);
571 case Qt::TextAlignmentRole:
572 return column_alignments[index.column()];
573 case Qt::ForegroundRole:
574 // Use the "danger" color for abandoned transactions
577 }
578 // Non-confirmed (but not immature) as transactions are grey
579 if (!rec->status.countsForBalance &&
581 return COLOR_UNCONFIRMED;
582 }
583 if (index.column() == Amount &&
584 (rec->credit + rec->debit) < ::Amount::zero()) {
585 return COLOR_NEGATIVE;
586 }
587 if (index.column() == ToAddress) {
588 return addressColor(rec);
589 }
590 break;
591 case TypeRole:
592 return rec->type;
593 case DateRole:
594 return QDateTime::fromTime_t(static_cast<uint>(rec->time));
595 case WatchonlyRole:
596 return rec->involvesWatchAddress;
598 return txWatchonlyDecoration(rec);
600 return priv->describe(
603 case AddressRole:
604 return QString::fromStdString(rec->address);
605 case LabelRole:
607 QString::fromStdString(rec->address));
608 case AmountRole:
609 return qint64((rec->credit + rec->debit) / SATOSHI);
610 case TxIDRole:
611 return rec->getTxID();
612 case TxHashRole:
613 return QString::fromStdString(rec->txid.ToString());
614 case TxHexRole:
615 return priv->getTxHex(walletModel->wallet(), rec);
616 case TxPlainTextRole: {
617 QString details;
618 QDateTime date =
619 QDateTime::fromTime_t(static_cast<uint>(rec->time));
620 QString txLabel =
622 QString::fromStdString(rec->address));
623
624 details.append(date.toString("M/d/yy HH:mm"));
625 details.append(" ");
626 details.append(formatTxStatus(rec));
627 details.append(". ");
628 if (!formatTxType(rec).isEmpty()) {
629 details.append(formatTxType(rec));
630 details.append(" ");
631 }
632 if (!rec->address.empty()) {
633 if (txLabel.isEmpty()) {
634 details.append(tr("(no label)") + " ");
635 } else {
636 details.append("(");
637 details.append(txLabel);
638 details.append(") ");
639 }
640 details.append(QString::fromStdString(rec->address));
641 details.append(" ");
642 }
643 details.append(formatTxAmount(rec, false,
645 return details;
646 }
647 case ConfirmedRole:
648 return rec->status.status ==
649 TransactionStatus::Status::Confirming ||
650 rec->status.status == TransactionStatus::Status::Confirmed;
652 // Used for copy/export, so don't include separators
653 return formatTxAmount(rec, false,
655 case StatusRole:
656 return rec->status.status;
657 }
658 return QVariant();
659}
660
662 Qt::Orientation orientation,
663 int role) const {
664 if (orientation == Qt::Horizontal) {
665 if (role == Qt::DisplayRole) {
666 return columns[section];
667 } else if (role == Qt::TextAlignmentRole) {
668 return column_alignments[section];
669 } else if (role == Qt::ToolTipRole) {
670 switch (section) {
671 case Status:
672 return tr("Transaction status. Hover over this field to "
673 "show number of confirmations.");
674 case Date:
675 return tr(
676 "Date and time that the transaction was received.");
677 case Type:
678 return tr("Type of transaction.");
679 case Watchonly:
680 return tr("Whether or not a watch-only address is involved "
681 "in this transaction.");
682 case ToAddress:
683 return tr(
684 "User-defined intent/purpose of the transaction.");
685 case Amount:
686 return tr("Amount removed from or added to balance.");
687 }
688 }
689 }
690 return QVariant();
691}
692
693QModelIndex TransactionTableModel::index(int row, int column,
694 const QModelIndex &parent) const {
695 Q_UNUSED(parent);
698 if (data) {
699 return createIndex(row, column, data);
700 }
701 return QModelIndex();
702}
703
705 // emit dataChanged to update Amount column with the current unit
707 Q_EMIT dataChanged(index(0, Amount), index(priv->size() - 1, Amount));
708}
709
711 ChangeType status) {
712 // Find transaction in wallet
713 // Determine whether to show transaction or not (determine this here so that
714 // no relocking is needed in GUI thread)
715 bool showTransaction = TransactionRecord::showTransaction();
716
717 TransactionNotification notification(txid, status, showTransaction);
718
720 vQueueNotifications.push_back(notification);
721 return;
722 }
723 notification.invoke(parent);
724}
725
726void TransactionTablePriv::ShowProgress(const std::string &title,
727 int nProgress) {
728 if (nProgress == 0) {
729 fQueueNotifications = true;
730 }
731
732 if (nProgress == 100) {
733 fQueueNotifications = false;
734 if (vQueueNotifications.size() > 10) {
735 // prevent balloon spam, show maximum 10 balloons
736 bool invoked = QMetaObject::invokeMethod(
737 parent, "setProcessingQueuedTransactions", Qt::QueuedConnection,
738 Q_ARG(bool, true));
739 assert(invoked);
740 }
741
742 for (size_t i = 0; i < vQueueNotifications.size(); ++i) {
743 if (vQueueNotifications.size() - i <= 10) {
744 bool invoked = QMetaObject::invokeMethod(
745 parent, "setProcessingQueuedTransactions",
746 Qt::QueuedConnection, Q_ARG(bool, false));
747 assert(invoked);
748 }
749
750 vQueueNotifications[i].invoke(parent);
751 }
752 vQueueNotifications.clear();
753 }
754}
755
757 // Connect signals to wallet
761 std::placeholders::_1, std::placeholders::_2));
764 std::placeholders::_1, std::placeholders::_2));
765}
766
768 // Disconnect signals from wallet
769 m_handler_transaction_changed->disconnect();
770 m_handler_show_progress->disconnect();
771}
static constexpr Amount SATOSHI
Definition: amount.h:143
QString labelForAddress(const QString &address) const
Look up label for address in address book, if not found return empty string.
static QString format(int unit, const Amount amount, bool plussign=false, SeparatorStyle separators=SeparatorStyle::STANDARD, bool justify=false)
Format as string.
static QString getAmountColumnTitle(int unit)
Gets title for amount column including current display unit if optionsModel reference available *‍/.
int getDisplayUnit() const
Definition: optionsmodel.h:97
void displayUnitChanged(int unit)
QIcon TextColorIcon(const QIcon &icon) const
Colorize an icon (given object) with the text color.
static QString toHTML(interfaces::Node &node, interfaces::Wallet &wallet, TransactionRecord *rec, int unit)
UI model for a transaction.
static QList< TransactionRecord > decomposeTransaction(const interfaces::WalletTx &wtx)
Decompose CWallet transaction to model transaction records.
static const int RecommendedNumConfirmations
Number of confirmation recommended for accepting a transaction.
static bool showTransaction()
Decompose CWallet transaction to model transaction records.
TransactionStatus status
Status: can change with block chain update.
void updateStatus(const interfaces::WalletTxStatus &wtx, const BlockHash &block_hash, int numBlocks, int64_t block_time)
Update status from core wallet tx.
bool statusUpdateNeeded(const BlockHash &block_hash) const
Return whether a status update is needed.
QString getTxID() const
Return the unique identifier for this transaction (part)
bool involvesWatchAddress
Whether the transaction was sent/received with a watch-only address.
bool countsForBalance
Transaction counts towards available balance.
@ Confirmed
Have 6 or more confirmations (normal tx) or fully mature (mined tx)
@ Unconfirmed
Normal (sent/received) transactions.
@ Immature
Generated (mined) transactions.
@ Confirming
Confirmed, but waiting for the recommended number of confirmations.
@ NotAccepted
Mined but not accepted.
@ Conflicted
Conflicts with other transaction or mempool.
@ Abandoned
Abandoned from the wallet.
std::string sortKey
Sorting key based on status.
UI model for the transaction table of a wallet.
QVariant txStatusDecoration(const TransactionRecord *wtx) const
TransactionTablePriv * priv
QVariant addressColor(const TransactionRecord *wtx) const
@ TxPlainTextRole
Whole transaction as plain text.
@ LabelRole
Label of address related to transaction.
@ LongDescriptionRole
Long description (HTML format)
@ TypeRole
Type of transaction.
@ StatusRole
Transaction status (TransactionRecord::Status)
@ DateRole
Date and time this transaction was created.
@ TxHashRole
Transaction hash.
@ TxHexRole
Transaction data, hex-encoded.
@ RawDecorationRole
Unprocessed icon.
@ TxIDRole
Unique identifier.
@ AddressRole
Address of transaction.
@ WatchonlyDecorationRole
Watch-only icon.
@ WatchonlyRole
Watch-only boolean.
@ AmountRole
Net amount of transaction.
@ ConfirmedRole
Is transaction confirmed?
@ FormattedAmountRole
Formatted amount, without brackets when unconfirmed.
QString formatTooltip(const TransactionRecord *rec) const
QString formatTxAmount(const TransactionRecord *wtx, bool showUnconfirmed=true, BitcoinUnits::SeparatorStyle separators=BitcoinUnits::SeparatorStyle::STANDARD) const
QVariant data(const QModelIndex &index, int role) const override
QVariant txWatchonlyDecoration(const TransactionRecord *wtx) const
void updateTransaction(const QString &hash, int status, bool showTransaction)
New transaction, or transaction changed status.
QString formatTxStatus(const TransactionRecord *wtx) const
std::unique_ptr< interfaces::Handler > m_handler_transaction_changed
int columnCount(const QModelIndex &parent) const override
std::unique_ptr< interfaces::Handler > m_handler_show_progress
TransactionTableModel(const PlatformStyle *platformStyle, WalletModel *parent=nullptr)
int rowCount(const QModelIndex &parent) const override
void updateAmountColumnTitle()
Updates the column title to "Amount (DisplayUnit)" and emits headerDataChanged() signal for table hea...
QString formatTxToAddress(const TransactionRecord *wtx, bool tooltip) const
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
const PlatformStyle * platformStyle
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
QString formatTxType(const TransactionRecord *wtx) const
QString lookupAddress(const std::string &address, bool tooltip) const
Look up address in address book, if found return label (address) otherwise just return (address)
QVariant txAddressDecoration(const TransactionRecord *wtx) const
QString formatTxDate(const TransactionRecord *wtx) const
QString getTxHex(interfaces::Wallet &wallet, TransactionRecord *rec)
void updateWallet(interfaces::Wallet &wallet, const TxId &txid, int status, bool showTransaction)
Update our model of the wallet incrementally, to synchronize our model of the wallet with that of the...
TransactionTablePriv(TransactionTableModel *_parent)
TransactionTableModel * parent
QList< TransactionRecord > cachedWallet
std::vector< TransactionNotification > vQueueNotifications
void refreshWallet(interfaces::Wallet &wallet)
Query entire wallet anew from core.
QString describe(interfaces::Node &node, interfaces::Wallet &wallet, TransactionRecord *rec, int unit)
void ShowProgress(const std::string &title, int nProgress)
void NotifyTransactionChanged(const TxId &txidc, ChangeType status)
TransactionRecord * index(interfaces::Wallet &wallet, const BlockHash &cur_block_hash, const int idx)
Interface to Bitcoin wallet from Qt view code.
Definition: walletmodel.h:47
interfaces::Node & node() const
Definition: walletmodel.h:149
BlockHash getLastBlockProcessed() const
AddressTableModel * getAddressTableModel()
OptionsModel * getOptionsModel()
interfaces::Wallet & wallet() const
Definition: walletmodel.h:150
void SetHex(const char *psz)
Definition: uint256.cpp:24
std::string ToString() const
Definition: uint256.h:80
bool IsNull() const
Definition: uint256.h:32
std::string GetHex() const
Definition: uint256.cpp:16
Top-level interface for a bitcoin node (bitcoind process).
Definition: node.h:59
Interface for accessing a wallet.
Definition: wallet.h:59
virtual std::unique_ptr< Handler > handleShowProgress(ShowProgressFn fn)=0
virtual std::unique_ptr< Handler > handleTransactionChanged(TransactionChangedFn fn)=0
std::string EncodeHexTx(const CTransaction &tx, const int serializeFlags=0)
Definition: core_write.cpp:169
#define COLOR_TX_STATUS_DANGER
Definition: guiconstants.h:31
#define COLOR_UNCONFIRMED
Definition: guiconstants.h:25
#define COLOR_NEGATIVE
Definition: guiconstants.h:27
#define COLOR_BLACK
Definition: guiconstants.h:33
#define COLOR_BAREADDRESS
Definition: guiconstants.h:29
QString dateTimeStr(const QDateTime &date)
Definition: guiutil.cpp:78
Definition: init.h:28
Definition: amount.h:19
static constexpr Amount zero() noexcept
Definition: amount.h:32
A BlockHash is a unqiue identifier for a block.
Definition: blockhash.h:13
TransactionNotification(TxId _txid, ChangeType _status, bool _showTransaction)
A TxId is the identifier of a transaction.
Definition: txid.h:14
bool operator()(const TransactionRecord &a, const TxId &b) const
bool operator()(const TransactionRecord &a, const TransactionRecord &b) const
bool operator()(const TxId &a, const TransactionRecord &b) const
CTransactionRef tx
Definition: wallet.h:369
Updated transaction status.
Definition: wallet.h:383
static int column_alignments[]
ChangeType
General change type (added, updated, removed).
Definition: ui_change_type.h:9
@ CT_UPDATED
Definition: ui_change_type.h:9
@ CT_DELETED
Definition: ui_change_type.h:9
@ CT_NEW
Definition: ui_change_type.h:9
assert(!tx.IsCoinBase())