29#include <QLatin1String>
35 Qt::AlignLeft|Qt::AlignVCenter,
36 Qt::AlignLeft|Qt::AlignVCenter,
37 Qt::AlignLeft|Qt::AlignVCenter,
38 Qt::AlignLeft|Qt::AlignVCenter,
39 Qt::AlignLeft|Qt::AlignVCenter,
40 Qt::AlignRight|Qt::AlignVCenter
70 QString strHash = QString::fromStdString(
hash.
GetHex());
71 qDebug() <<
"NotifyTransactionChanged: " + strHash +
" status= " + QString::number(
status);
72 bool invoked = QMetaObject::invokeMethod(ttm,
"updateTransaction", Qt::QueuedConnection,
73 Q_ARG(QString, strHash),
116 for (
const auto& wtx :
wallet.getWalletTxs()) {
133 qDebug() <<
"TransactionTablePriv::updateWallet: " + QString::fromStdString(hash.
ToString()) +
" " + QString::number(status);
136 QList<TransactionRecord>::iterator lower = std::lower_bound(
138 QList<TransactionRecord>::iterator upper = std::upper_bound(
142 bool inModel = (lower != upper);
146 if(showTransaction && !inModel)
148 if(!showTransaction && inModel)
152 qDebug() <<
" inModel=" + QString::number(inModel) +
153 " Index=" + QString::number(lowerIndex) +
"-" + QString::number(upperIndex) +
154 " showTransaction=" + QString::number(showTransaction) +
" derivedStatus=" + QString::number(status);
161 qWarning() <<
"TransactionTablePriv::updateWallet: Warning: Got CT_NEW, but transaction is already in model";
170 qWarning() <<
"TransactionTablePriv::updateWallet: Warning: Got CT_NEW, but transaction is not in wallet";
174 QList<TransactionRecord> toInsert =
176 if(!toInsert.isEmpty())
178 parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1);
179 int insert_idx = lowerIndex;
192 qWarning() <<
"TransactionTablePriv::updateWallet: Warning: Got CT_DELETED, but transaction is not in model";
196 parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1);
203 for (
int i = lowerIndex; i < upperIndex; i++) {
228 rec->
updateStatus(wtx, cur_block_hash, numBlocks, block_time);
245 return QString::fromStdString(strHex);
252 QAbstractTableModel(parent),
255 fProcessingQueuedTransactions(false),
256 platformStyle(_platformStyle)
282 updated.
SetHex(hash.toStdString());
299 if (parent.isValid()) {
307 if (parent.isValid()) {
326 status = tr(
"Unconfirmed");
329 status = tr(
"Abandoned");
335 status = tr(
"Confirmed (%1 confirmations)").arg(wtx->
status.
depth);
338 status = tr(
"Conflicted");
344 status = tr(
"Generated but not accepted");
369 description += label;
371 if(label.isEmpty() || tooltip)
373 description += QString(
" (") + QString::fromStdString(address) + QString(
")");
383 return tr(
"Received with");
385 return tr(
"Received from");
388 return tr(
"Sent to");
390 return tr(
"Payment to yourself");
403 return QIcon(
":/icons/tx_mined");
406 return QIcon(
":/icons/tx_input");
409 return QIcon(
":/icons/tx_output");
411 return QIcon(
":/icons/tx_inout");
417 QString watchAddress;
420 watchAddress = QLatin1String(
" (") + tr(
"watch-only") + QLatin1Char(
')');
426 return QString::fromStdString(wtx->
address) + watchAddress;
432 return QString::fromStdString(wtx->
address) + watchAddress;
436 return tr(
"(n/a)") + watchAddress;
468 str = QString(
"[") + str + QString(
"]");
482 return QIcon(
":/icons/transaction_0");
484 return QIcon(
":/icons/transaction_abandoned");
488 case 1:
return QIcon(
":/icons/transaction_1");
489 case 2:
return QIcon(
":/icons/transaction_2");
490 case 3:
return QIcon(
":/icons/transaction_3");
491 case 4:
return QIcon(
":/icons/transaction_4");
492 default:
return QIcon(
":/icons/transaction_5");
495 return QIcon(
":/icons/transaction_confirmed");
497 return QIcon(
":/icons/transaction_conflicted");
501 return QIcon(QString(
":/icons/transaction_%1").arg(part));
504 return QIcon(
":/icons/transaction_0");
513 return QIcon(
":/icons/eye");
543 case Date:
return {};
544 case Type:
return {};
550 case Qt::DecorationRole:
555 case Qt::DisplayRole:
586 case Qt::ToolTipRole:
588 case Qt::TextAlignmentRole:
590 case Qt::ForegroundRole:
613 return QDateTime::fromSecsSinceEpoch(rec->
time);
621 return QString::fromStdString(rec->
address);
633 QDateTime date = QDateTime::fromSecsSinceEpoch(rec->
time);
636 details.append(date.toString(
"M/d/yy HH:mm"));
639 details.append(
". ");
645 if(txLabel.isEmpty())
646 details.append(tr(
"(no label)") +
" ");
649 details.append(txLabel);
650 details.append(
") ");
652 details.append(QString::fromStdString(rec->
address));
659 return rec->
status.
status == TransactionStatus::Status::Confirming || rec->
status.
status == TransactionStatus::Status::Confirmed;
671 if(orientation == Qt::Horizontal)
673 if(role == Qt::DisplayRole)
677 else if (role == Qt::TextAlignmentRole)
680 }
else if (role == Qt::ToolTipRole)
685 return tr(
"Transaction status. Hover over this field to show number of confirmations.");
687 return tr(
"Date and time that the transaction was received.");
689 return tr(
"Type of transaction.");
691 return tr(
"Whether or not a watch-only address is involved in this transaction.");
693 return tr(
"User-defined intent/purpose of the transaction.");
695 return tr(
"Amount removed from or added to balance.");
708 return createIndex(row, column,
data);
710 return QModelIndex();
741 bool invoked = QMetaObject::invokeMethod(
parent,
"setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(
bool,
true));
747 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 getAmountColumnTitle(int unit)
Gets title for amount column including current display unit if optionsModel reference available */.
static QString format(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=SeparatorStyle::STANDARD, bool justify=false)
Format as string.
int getDisplayUnit() const
void displayUnitChanged(int unit)
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)
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.
bool countsForBalance
Transaction counts towards available balance.
qint64 open_for
Timestamp if status==OpenUntilDate, otherwise number of additional blocks that need to be mined befor...
@ Confirmed
Have 6 or more confirmations (normal tx) or fully mature (mined tx)
@ OpenUntilDate
Normal (sent/received) transactions.
@ Unconfirmed
Not yet mined into a block.
@ Immature
Generated (mined) transactions.
@ Confirming
Confirmed, but waiting for the recommended number of confirmations.
@ NotAccepted
Mined but not accepted.
@ OpenUntilBlock
Transaction not yet final, waiting for block.
@ 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
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
void refreshWallet(interfaces::Wallet &wallet)
bool m_loading
True when transactions are being notified, for instance when scanning.
QString describe(interfaces::Node &node, interfaces::Wallet &wallet, TransactionRecord *rec, int unit)
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
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()
OptionsModel * getOptionsModel()
interfaces::Wallet & wallet() const
uint256 getLastBlockProcessed() const
void SetHex(const char *psz)
std::string ToString() const
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, const int serializeFlags=0)
#define COLOR_TX_STATUS_DANGER
#define COLOR_UNCONFIRMED
#define COLOR_TX_STATUS_OPENUNTILDATE
#define COLOR_BAREADDRESS
QString dateTimeStr(const QDateTime &date)
void invoke(QObject *ttm)
TransactionNotification(uint256 _hash, ChangeType _status, bool _showTransaction)
TransactionNotification()
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).