32 Qt::AlignLeft|Qt::AlignVCenter,
33 Qt::AlignLeft|Qt::AlignVCenter,
34 Qt::AlignLeft|Qt::AlignVCenter,
35 Qt::AlignLeft|Qt::AlignVCenter,
36 Qt::AlignLeft|Qt::AlignVCenter,
37 Qt::AlignRight|Qt::AlignVCenter
63 hash(_hash), status(_status), showTransaction(_showTransaction) {}
67 QString strHash = QString::fromStdString(hash.GetHex());
68 qDebug() <<
"NotifyTransactionChanged: " + strHash +
" status= " + QString::number(status);
69 bool invoked = QMetaObject::invokeMethod(ttm,
"updateTransaction", Qt::QueuedConnection,
70 Q_ARG(QString, strHash),
72 Q_ARG(
bool, showTransaction));
98 bool fQueueNotifications =
false;
102 void ShowProgress(
const std::string &title,
int nProgress);
108 qDebug() <<
"TransactionTablePriv::refreshWallet";
109 cachedWallet.clear();
126 qDebug() <<
"TransactionTablePriv::updateWallet: " + QString::fromStdString(hash.
ToString()) +
" " + QString::number(status);
129 QList<TransactionRecord>::iterator lower = std::lower_bound(
130 cachedWallet.begin(), cachedWallet.end(), hash,
TxLessThan());
131 QList<TransactionRecord>::iterator upper = std::upper_bound(
132 cachedWallet.begin(), cachedWallet.end(), hash,
TxLessThan());
133 int lowerIndex = (lower - cachedWallet.begin());
134 int upperIndex = (upper - cachedWallet.begin());
135 bool inModel = (lower != upper);
139 if(showTransaction && !inModel)
141 if(!showTransaction && inModel)
145 qDebug() <<
" inModel=" + QString::number(inModel) +
146 " Index=" + QString::number(lowerIndex) +
"-" + QString::number(upperIndex) +
147 " showTransaction=" + QString::number(showTransaction) +
" derivedStatus=" + QString::number(status);
154 qWarning() <<
"TransactionTablePriv::updateWallet: Warning: Got CT_NEW, but transaction is already in model";
163 qWarning() <<
"TransactionTablePriv::updateWallet: Warning: Got CT_NEW, but transaction is not in wallet";
167 QList<TransactionRecord> toInsert =
169 if(!toInsert.isEmpty())
171 parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1);
172 int insert_idx = lowerIndex;
175 cachedWallet.insert(insert_idx, rec);
178 parent->endInsertRows();
185 qWarning() <<
"TransactionTablePriv::updateWallet: Warning: Got CT_DELETED, but transaction is not in model";
189 parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1);
190 cachedWallet.erase(lower, upper);
191 parent->endRemoveRows();
196 for (
int i = lowerIndex; i < upperIndex; i++) {
206 return cachedWallet.size();
211 if (idx >= 0 && idx < cachedWallet.size()) {
221 rec->
updateStatus(wtx, cur_block_hash, numBlocks, block_time);
238 return QString::fromStdString(strHex);
245 QAbstractTableModel(parent),
248 fProcessingQueuedTransactions(false),
249 platformStyle(_platformStyle)
275 updated.
SetHex(hash.toStdString());
292 if (parent.isValid()) {
300 if (parent.isValid()) {
319 status = tr(
"Unconfirmed");
322 status = tr(
"Abandoned");
328 status = tr(
"Confirmed (%1 confirmations)").arg(wtx->
status.
depth);
331 status = tr(
"Conflicted");
337 status = tr(
"Generated but not accepted");
362 description += label;
364 if(label.isEmpty() || tooltip)
366 description += QString(
" (") + QString::fromStdString(address) + QString(
")");
376 return tr(
"Received with");
378 return tr(
"Received from");
381 return tr(
"Sent to");
383 return tr(
"Payment to yourself");
396 return QIcon(
":/icons/tx_mined");
399 return QIcon(
":/icons/tx_input");
402 return QIcon(
":/icons/tx_output");
404 return QIcon(
":/icons/tx_inout");
410 QString watchAddress;
413 watchAddress = wtx->
involvesWatchAddress ? QString(
" (") + tr(
"watch-only") + QString(
")") :
"";
419 return QString::fromStdString(wtx->
address) + watchAddress;
425 return QString::fromStdString(wtx->
address) + watchAddress;
429 return tr(
"(n/a)") + watchAddress;
461 str = QString(
"[") + str + QString(
"]");
475 return QIcon(
":/icons/transaction_0");
477 return QIcon(
":/icons/transaction_abandoned");
481 case 1:
return QIcon(
":/icons/transaction_1");
482 case 2:
return QIcon(
":/icons/transaction_2");
483 case 3:
return QIcon(
":/icons/transaction_3");
484 case 4:
return QIcon(
":/icons/transaction_4");
485 default:
return QIcon(
":/icons/transaction_5");
488 return QIcon(
":/icons/transaction_confirmed");
490 return QIcon(
":/icons/transaction_conflicted");
494 return QIcon(QString(
":/icons/transaction_%1").arg(part));
497 return QIcon(
":/icons/transaction_0");
506 return QIcon(
":/icons/eye");
531 switch(index.column())
541 case Qt::DecorationRole:
546 case Qt::DisplayRole:
547 switch(index.column())
561 switch(index.column())
577 case Qt::ToolTipRole:
579 case Qt::TextAlignmentRole:
581 case Qt::ForegroundRole:
604 return QDateTime::fromTime_t(static_cast<uint>(rec->
time));
612 return QString::fromStdString(rec->
address);
624 QDateTime date = QDateTime::fromTime_t(static_cast<uint>(rec->
time));
627 details.append(date.toString(
"M/d/yy HH:mm"));
630 details.append(
". ");
636 if(txLabel.isEmpty())
637 details.append(tr(
"(no label)") +
" ");
640 details.append(txLabel);
641 details.append(
") ");
643 details.append(QString::fromStdString(rec->
address));
650 return rec->
status.
status == TransactionStatus::Status::Confirming || rec->
status.
status == TransactionStatus::Status::Confirmed;
662 if(orientation == Qt::Horizontal)
664 if(role == Qt::DisplayRole)
668 else if (role == Qt::TextAlignmentRole)
671 }
else if (role == Qt::ToolTipRole)
676 return tr(
"Transaction status. Hover over this field to show number of confirmations.");
678 return tr(
"Date and time that the transaction was received.");
680 return tr(
"Type of transaction.");
682 return tr(
"Whether or not a watch-only address is involved in this transaction.");
684 return tr(
"User-defined intent/purpose of the transaction.");
686 return tr(
"Amount removed from or added to balance.");
699 return createIndex(row, column, data);
701 return QModelIndex();
719 if (fQueueNotifications)
721 vQueueNotifications.push_back(notification);
724 notification.
invoke(parent);
730 fQueueNotifications =
true;
732 if (nProgress == 100)
734 fQueueNotifications =
false;
735 if (vQueueNotifications.size() > 10) {
736 bool invoked = QMetaObject::invokeMethod(parent,
"setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(
bool,
true));
739 for (
unsigned int i = 0; i < vQueueNotifications.size(); ++i)
741 if (vQueueNotifications.size() - i <= 10) {
742 bool invoked = QMetaObject::invokeMethod(parent,
"setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(
bool,
false));
746 vQueueNotifications[i].invoke(parent);
748 vQueueNotifications.clear();
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
void ShowProgress(const std::string &title, int nProgress)
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
virtual CTransactionRef getTx(const uint256 &txid)=0
Get a transaction.
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)
static void ShowProgress(ClientModel *clientmodel, const std::string &title, int nProgress)
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
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
virtual WalletTx getWalletTx(const uint256 &txid)=0
Get transaction information.
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.
virtual bool tryGetTxStatus(const uint256 &txid, WalletTxStatus &tx_status, int &num_blocks, int64_t &block_time)=0
Try to get updated status for a particular transaction, if possible without blocking.
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.
virtual std::vector< WalletTx > getWalletTxs()=0
Get list of all wallet transactions.
QString formatTxToAddress(const TransactionRecord *wtx, bool tooltip) const
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.
static void NotifyTransactionChanged(WalletModel *walletmodel, const uint256 &hash, ChangeType status)
QString getTxHex(interfaces::Wallet &wallet, TransactionRecord *rec)
std::string EncodeHexTx(const CTransaction &tx, const int serializeFlags=0)
Label of address related to transaction.
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