28 #include <QLatin1Char> 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::fromTime_t(static_cast<uint>(rec->
time));
621 return QString::fromStdString(rec->
address);
633 QDateTime date = QDateTime::fromTime_t(static_cast<uint>(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));
void updateWallet(interfaces::Wallet &wallet, const uint256 &hash, int status, bool showTransaction)
bool statusUpdateNeeded(const uint256 &block_hash) const
Return whether a status update is needed.
void updateAmountColumnTitle()
Updates the column title to "Amount (DisplayUnit)" and emits headerDataChanged() signal for table hea...
TransactionRecord * index(interfaces::Wallet &wallet, const uint256 &cur_block_hash, const int idx)
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
Confirmed, but waiting for the recommended number of confirmations.
interfaces::Wallet & wallet() const
QVariant txWatchonlyDecoration(const TransactionRecord *wtx) const
Transaction not yet final, waiting for block.
Transaction status (TransactionRecord::Status)
QString getTxHash() const
Return the unique identifier for this transaction (part)
Generated (mined) transactions.
static int column_alignments[]
QString formatTooltip(const TransactionRecord *rec) const
WalletModel * walletModel
Have 6 or more confirmations (normal tx) or fully mature (mined tx)
std::string sortKey
Sorting key based on status.
static QString format(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=SeparatorStyle::STANDARD, bool justify=false)
Format as string.
void updateTransaction(const QString &hash, int status, bool showTransaction)
QString describe(interfaces::Node &node, interfaces::Wallet &wallet, TransactionRecord *rec, int unit)
QString dateTimeStr(const QDateTime &date)
TransactionTablePriv(TransactionTableModel *_parent)
static QList< TransactionRecord > decomposeTransaction(const interfaces::WalletTx &wtx)
void unsubscribeFromCoreSignals()
QVariant txStatusDecoration(const TransactionRecord *wtx) const
void NotifyTransactionChanged(const uint256 &hash, ChangeType status)
bool operator()(const TransactionRecord &a, const TransactionRecord &b) const
void DispatchNotifications()
Not yet mined into a block.
static QString toHTML(interfaces::Node &node, interfaces::Wallet &wallet, TransactionRecord *rec, int unit)
int columnCount(const QModelIndex &parent) const override
AddressTableModel * getAddressTableModel()
Transaction data, hex-encoded.
TransactionTableModel * parent
int rowCount(const QModelIndex &parent) const override
Long description (HTML format)
TransactionTablePriv * priv
void updateStatus(const interfaces::WalletTxStatus &wtx, const uint256 &block_hash, int numBlocks, int64_t block_time)
Update status from core wallet tx.
int getDisplayUnit() const
static QString getAmountColumnTitle(int unit)
Gets title for amount column including current display unit if optionsModel reference available */...
bool operator()(const uint256 &a, const TransactionRecord &b) const
QList< TransactionRecord > cachedWallet
bool operator()(const TransactionRecord &a, const uint256 &b) const
uint256 getLastBlockProcessed() const
virtual std::unique_ptr< Handler > handleTransactionChanged(TransactionChangedFn fn)=0
UI model for a transaction.
TransactionStatus status
Status: can change with block chain update.
QString formatTxType(const TransactionRecord *wtx) const
virtual std::unique_ptr< Handler > handleShowProgress(ShowProgressFn fn)=0
TransactionNotification()
Whole transaction as plain text.
std::unique_ptr< interfaces::Handler > m_handler_transaction_changed
std::vector< TransactionNotification > vQueueNotifications
#define COLOR_TX_STATUS_DANGER
QString labelForAddress(const QString &address) const
Look up label for address in address book, if not found return empty string.
Interface for accessing a wallet.
Is transaction confirmed?
TransactionNotification(uint256 _hash, ChangeType _status, bool _showTransaction)
bool countsForBalance
Transaction counts towards available balance.
TransactionTableModel(const PlatformStyle *platformStyle, WalletModel *parent=nullptr)
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
Date and time this transaction was created.
std::string ToString() const
interfaces::Node & node() const
void displayUnitChanged(int unit)
UI model for the transaction table of a wallet.
#define COLOR_UNCONFIRMED
void refreshWallet(interfaces::Wallet &wallet)
Normal (sent/received) transactions.
QString lookupAddress(const std::string &address, bool tooltip) const
void subscribeToCoreSignals()
std::unique_ptr< interfaces::Handler > m_handler_show_progress
static bool showTransaction()
Decompose CWallet transaction to model transaction records.
Net amount of transaction.
QString formatTxToAddress(const TransactionRecord *wtx, bool tooltip) const
bool m_loading
True when transactions are being notified, for instance when scanning.
Conflicts with other transaction or mempool.
Interface to Bitcoin wallet from Qt view code.
bool involvesWatchAddress
Whether the transaction was sent/received with a watch-only address.
std::string GetHex() const
QString getTxHex(interfaces::Wallet &wallet, TransactionRecord *rec)
std::string EncodeHexTx(const CTransaction &tx, const int serializeFlags=0)
Label of address related to transaction.
bool m_loaded
True when model finishes loading all wallet transactions on start.
QString formatTxStatus(const TransactionRecord *wtx) const
QVariant addressColor(const TransactionRecord *wtx) const
void invoke(QObject *ttm)
#define COLOR_TX_STATUS_OPENUNTILDATE
qint64 open_for
Timestamp if status==OpenUntilDate, otherwise number of additional blocks that need to be mined befor...
QVariant txAddressDecoration(const TransactionRecord *wtx) const
Formatted amount, without brackets when unconfirmed.
QVariant data(const QModelIndex &index, int role) const override
ChangeType
General change type (added, updated, removed).
void updateConfirmations()
void SetHex(const char *psz)
Abandoned from the wallet.
#define COLOR_BAREADDRESS
Top-level interface for a bitcoin node (bitcoind process).
const PlatformStyle * platformStyle
Updated transaction status.
static const int RecommendedNumConfirmations
Number of confirmation recommended for accepting a transaction.
QString formatTxAmount(const TransactionRecord *wtx, bool showUnconfirmed=true, BitcoinUnits::SeparatorStyle separators=BitcoinUnits::SeparatorStyle::STANDARD) const
OptionsModel * getOptionsModel()
QString formatTxDate(const TransactionRecord *wtx) const