31#include <QLatin1String>
37 Qt::AlignLeft|Qt::AlignVCenter,
38 Qt::AlignLeft|Qt::AlignVCenter,
39 Qt::AlignLeft|Qt::AlignVCenter,
40 Qt::AlignLeft|Qt::AlignVCenter,
41 Qt::AlignLeft|Qt::AlignVCenter,
42 Qt::AlignRight|Qt::AlignVCenter
72 QString strHash = QString::fromStdString(
hash.
GetHex());
73 qDebug() <<
"NotifyTransactionChanged: " + strHash +
" status= " + QString::number(
status);
74 bool invoked = QMetaObject::invokeMethod(ttm,
"updateTransaction", Qt::QueuedConnection,
75 Q_ARG(QString, strHash),
115 for (
const auto& wtx :
wallet.getWalletTxs()) {
132 qDebug() <<
"TransactionTablePriv::updateWallet: " + QString::fromStdString(hash.
ToString()) +
" " + QString::number(status);
135 QList<TransactionRecord>::iterator lower = std::lower_bound(
137 QList<TransactionRecord>::iterator upper = std::upper_bound(
141 bool inModel = (lower != upper);
145 if(showTransaction && !inModel)
147 if(!showTransaction && inModel)
151 qDebug() <<
" inModel=" + QString::number(inModel) +
152 " Index=" + QString::number(lowerIndex) +
"-" + QString::number(upperIndex) +
153 " showTransaction=" + QString::number(showTransaction) +
" derivedStatus=" + QString::number(status);
160 qWarning() <<
"TransactionTablePriv::updateWallet: Warning: Got CT_NEW, but transaction is already in model";
169 qWarning() <<
"TransactionTablePriv::updateWallet: Warning: Got CT_NEW, but transaction is not in wallet";
173 QList<TransactionRecord> toInsert =
175 if(!toInsert.isEmpty())
177 parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1);
178 int insert_idx = lowerIndex;
191 qWarning() <<
"TransactionTablePriv::updateWallet: Warning: Got CT_DELETED, but transaction is not in model";
195 parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1);
202 for (
int i = lowerIndex; i < upperIndex; i++) {
227 rec->
updateStatus(wtx, cur_block_hash, numBlocks, block_time);
244 return QString::fromStdString(strHex);
251 QAbstractTableModel(parent),
254 platformStyle(_platformStyle)
297 if (parent.isValid()) {
305 if (parent.isValid()) {
318 status = tr(
"Unconfirmed");
321 status = tr(
"Abandoned");
327 status = tr(
"Confirmed (%1 confirmations)").arg(wtx->
status.
depth);
330 status = tr(
"Conflicted");
336 status = tr(
"Generated but not accepted");
361 description += label;
363 if(label.isEmpty() || tooltip)
365 description += QString(
" (") + QString::fromStdString(address) + QString(
")");
375 return tr(
"Received with");
377 return tr(
"Received from");
380 return tr(
"Sent to");
393 return QIcon(
":/icons/tx_mined");
396 return QIcon(
":/icons/tx_input");
399 return QIcon(
":/icons/tx_output");
401 return QIcon(
":/icons/tx_inout");
407 QString watchAddress;
410 watchAddress = QLatin1String(
" (") + tr(
"watch-only") + QLatin1Char(
')');
416 return QString::fromStdString(wtx->
address) + watchAddress;
422 return QString::fromStdString(wtx->
address) + watchAddress;
424 return tr(
"(n/a)") + watchAddress;
454 str = QString(
"[") + str + QString(
"]");
465 return QIcon(
":/icons/transaction_0");
467 return QIcon(
":/icons/transaction_abandoned");
471 case 1:
return QIcon(
":/icons/transaction_1");
472 case 2:
return QIcon(
":/icons/transaction_2");
473 case 3:
return QIcon(
":/icons/transaction_3");
474 case 4:
return QIcon(
":/icons/transaction_4");
475 default:
return QIcon(
":/icons/transaction_5");
478 return QIcon(
":/icons/transaction_confirmed");
480 return QIcon(
":/icons/transaction_conflicted");
484 return QIcon(QString(
":/icons/transaction_%1").arg(part));
487 return QIcon(
":/icons/transaction_0");
496 return QIcon(
":/icons/eye");
526 case Date:
return {};
527 case Type:
return {};
533 case Qt::DecorationRole:
538 case Qt::DisplayRole:
569 case Qt::ToolTipRole:
571 case Qt::TextAlignmentRole:
573 case Qt::ForegroundRole:
596 return QDateTime::fromSecsSinceEpoch(rec->
time);
604 return QString::fromStdString(rec->
address);
616 QDateTime date = QDateTime::fromSecsSinceEpoch(rec->
time);
619 details.append(date.toString(
"M/d/yy HH:mm"));
622 details.append(
". ");
628 if(txLabel.isEmpty())
629 details.append(tr(
"(no label)") +
" ");
632 details.append(txLabel);
633 details.append(
") ");
635 details.append(QString::fromStdString(rec->
address));
642 return rec->
status.
status == TransactionStatus::Status::Confirming || rec->
status.
status == TransactionStatus::Status::Confirmed;
654 if(orientation == Qt::Horizontal)
656 if(role == Qt::DisplayRole)
660 else if (role == Qt::TextAlignmentRole)
663 }
else if (role == Qt::ToolTipRole)
668 return tr(
"Transaction status. Hover over this field to show number of confirmations.");
670 return tr(
"Date and time that the transaction was received.");
672 return tr(
"Type of transaction.");
674 return tr(
"Whether or not a watch-only address is involved in this transaction.");
676 return tr(
"User-defined intent/purpose of the transaction.");
678 return tr(
"Amount removed from or added to balance.");
691 return createIndex(row, column,
data);
693 return QModelIndex();
724 bool invoked = QMetaObject::invokeMethod(
parent,
"setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(
bool,
true));
730 bool invoked = QMetaObject::invokeMethod(
parent,
"setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(
bool,
false));
QString labelForAddress(const QString &address) const
Look up label for address in address book, if not found return empty string.
static QString format(Unit unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=SeparatorStyle::STANDARD, bool justify=false)
Format as string.
static QString getAmountColumnTitle(Unit unit)
Gets title for amount column including current display unit if optionsModel reference available */.
void displayUnitChanged(BitcoinUnit unit)
BitcoinUnit getDisplayUnit() const
static QString toHTML(interfaces::Node &node, interfaces::Wallet &wallet, TransactionRecord *rec, BitcoinUnit unit)
UI model for a transaction.
static QList< TransactionRecord > decomposeTransaction(const interfaces::WalletTx &wtx)
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.
QString getTxHash() const
Return the unique identifier for this transaction (part)
bool statusUpdateNeeded(const uint256 &block_hash) const
Return whether a status update is needed.
void updateStatus(const interfaces::WalletTxStatus &wtx, const uint256 &block_hash, int numBlocks, int64_t block_time)
Update status from core wallet tx.
bool involvesWatchAddress
Whether the transaction was sent/received with a watch-only address.
UI model for the transaction table of a wallet.
QVariant txStatusDecoration(const TransactionRecord *wtx) const
void subscribeToCoreSignals()
TransactionTablePriv * priv
void unsubscribeFromCoreSignals()
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.
@ 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
void updateConfirmations()
QVariant data(const QModelIndex &index, int role) const override
QVariant txWatchonlyDecoration(const TransactionRecord *wtx) const
void updateTransaction(const QString &hash, int status, bool showTransaction)
QString formatTxStatus(const TransactionRecord *wtx) const
WalletModel * walletModel
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
QVariant txAddressDecoration(const TransactionRecord *wtx) const
QString formatTxDate(const TransactionRecord *wtx) const
QString getTxHex(interfaces::Wallet &wallet, TransactionRecord *rec)
TransactionTablePriv(TransactionTableModel *_parent)
TransactionTableModel * parent
void DispatchNotifications()
QList< TransactionRecord > cachedWallet
Local cache of wallet sorted by transaction hash.
void refreshWallet(interfaces::Wallet &wallet)
bool m_loading
True when transactions are being notified, for instance when scanning.
void NotifyTransactionChanged(const uint256 &hash, ChangeType status)
void updateWallet(interfaces::Wallet &wallet, const uint256 &hash, int status, bool showTransaction)
TransactionRecord * index(interfaces::Wallet &wallet, const uint256 &cur_block_hash, const int idx)
std::vector< TransactionNotification > vQueueNotifications
QString describe(interfaces::Node &node, interfaces::Wallet &wallet, TransactionRecord *rec, BitcoinUnit unit)
bool m_loaded
True when model finishes loading all wallet transactions on start.
Interface to Bitcoin wallet from Qt view code.
interfaces::Node & node() const
AddressTableModel * getAddressTableModel() const
interfaces::Wallet & wallet() const
OptionsModel * getOptionsModel() const
uint256 getLastBlockProcessed() const
constexpr bool IsNull() const
std::string ToString() const
void SetHexDeprecated(std::string_view str)
Unlike FromHex this accepts any invalid input, thus it is fragile and deprecated!
std::string GetHex() const
Top-level interface for a bitcoin node (bitcoind process).
Interface for accessing a wallet.
virtual std::unique_ptr< Handler > handleShowProgress(ShowProgressFn fn)=0
virtual std::unique_ptr< Handler > handleTransactionChanged(TransactionChangedFn fn)=0
std::string EncodeHexTx(const CTransaction &tx)
#define COLOR_TX_STATUS_DANGER
#define COLOR_UNCONFIRMED
#define COLOR_BAREADDRESS
QString dateTimeStr(const QDateTime &date)
TransactionNotification()=default
void invoke(QObject *ttm)
TransactionNotification(uint256 _hash, ChangeType _status, bool _showTransaction)
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.
bool operator()(const TransactionRecord &a, const TransactionRecord &b) const
bool operator()(const TransactionRecord &a, const uint256 &b) const
bool operator()(const uint256 &a, const TransactionRecord &b) const
Updated transaction status.
static int column_alignments[]
ChangeType
General change type (added, updated, removed).