BSHA3  0.17.99
P2P Blockchain, based on Bitcoin
transactiontablemodel.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2018 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 <qt/addresstablemodel.h>
8 #include <qt/guiconstants.h>
9 #include <qt/guiutil.h>
10 #include <qt/optionsmodel.h>
11 #include <qt/platformstyle.h>
12 #include <qt/transactiondesc.h>
13 #include <qt/transactionrecord.h>
14 #include <qt/walletmodel.h>
15 
16 #include <core_io.h>
17 #include <interfaces/handler.h>
18 #include <interfaces/node.h>
19 #include <sync.h>
20 #include <uint256.h>
21 #include <util.h>
22 #include <validation.h>
23 
24 #include <QColor>
25 #include <QDateTime>
26 #include <QDebug>
27 #include <QIcon>
28 #include <QList>
29 
30 #include <boost/bind.hpp>
31 
32 // Amount column is right-aligned it contains numbers
33 static int column_alignments[] = {
34  Qt::AlignLeft|Qt::AlignVCenter, /* status */
35  Qt::AlignLeft|Qt::AlignVCenter, /* watchonly */
36  Qt::AlignLeft|Qt::AlignVCenter, /* date */
37  Qt::AlignLeft|Qt::AlignVCenter, /* type */
38  Qt::AlignLeft|Qt::AlignVCenter, /* address */
39  Qt::AlignRight|Qt::AlignVCenter /* amount */
40  };
41 
42 // Comparison operator for sort/binary search of model tx list
43 struct TxLessThan
44 {
45  bool operator()(const TransactionRecord &a, const TransactionRecord &b) const
46  {
47  return a.hash < b.hash;
48  }
49  bool operator()(const TransactionRecord &a, const uint256 &b) const
50  {
51  return a.hash < b;
52  }
53  bool operator()(const uint256 &a, const TransactionRecord &b) const
54  {
55  return a < b.hash;
56  }
57 };
58 
59 // Private implementation
61 {
62 public:
64  parent(_parent)
65  {
66  }
67 
69 
70  /* Local cache of wallet.
71  * As it is in the same order as the CWallet, by definition
72  * this is sorted by sha3.
73  */
74  QList<TransactionRecord> cachedWallet;
75 
76  /* Query entire wallet anew from core.
77  */
79  {
80  qDebug() << "TransactionTablePriv::refreshWallet";
81  cachedWallet.clear();
82  {
83  for (const auto& wtx : wallet.getWalletTxs()) {
86  }
87  }
88  }
89  }
90 
91  /* Update our model of the wallet incrementally, to synchronize our model of the wallet
92  with that of the core.
93 
94  Call with transaction that was added, removed or changed.
95  */
96  void updateWallet(interfaces::Wallet& wallet, const uint256 &hash, int status, bool showTransaction)
97  {
98  qDebug() << "TransactionTablePriv::updateWallet: " + QString::fromStdString(hash.ToString()) + " " + QString::number(status);
99 
100  // Find bounds of this transaction in model
101  QList<TransactionRecord>::iterator lower = qLowerBound(
102  cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan());
103  QList<TransactionRecord>::iterator upper = qUpperBound(
104  cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan());
105  int lowerIndex = (lower - cachedWallet.begin());
106  int upperIndex = (upper - cachedWallet.begin());
107  bool inModel = (lower != upper);
108 
109  if(status == CT_UPDATED)
110  {
111  if(showTransaction && !inModel)
112  status = CT_NEW; /* Not in model, but want to show, treat as new */
113  if(!showTransaction && inModel)
114  status = CT_DELETED; /* In model, but want to hide, treat as deleted */
115  }
116 
117  qDebug() << " inModel=" + QString::number(inModel) +
118  " Index=" + QString::number(lowerIndex) + "-" + QString::number(upperIndex) +
119  " showTransaction=" + QString::number(showTransaction) + " derivedStatus=" + QString::number(status);
120 
121  switch(status)
122  {
123  case CT_NEW:
124  if(inModel)
125  {
126  qWarning() << "TransactionTablePriv::updateWallet: Warning: Got CT_NEW, but transaction is already in model";
127  break;
128  }
129  if(showTransaction)
130  {
131  // Find transaction in wallet
132  interfaces::WalletTx wtx = wallet.getWalletTx(hash);
133  if(!wtx.tx)
134  {
135  qWarning() << "TransactionTablePriv::updateWallet: Warning: Got CT_NEW, but transaction is not in wallet";
136  break;
137  }
138  // Added -- insert at the right position
139  QList<TransactionRecord> toInsert =
141  if(!toInsert.isEmpty()) /* only if something to insert */
142  {
143  parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1);
144  int insert_idx = lowerIndex;
145  for (const TransactionRecord &rec : toInsert)
146  {
147  cachedWallet.insert(insert_idx, rec);
148  insert_idx += 1;
149  }
150  parent->endInsertRows();
151  }
152  }
153  break;
154  case CT_DELETED:
155  if(!inModel)
156  {
157  qWarning() << "TransactionTablePriv::updateWallet: Warning: Got CT_DELETED, but transaction is not in model";
158  break;
159  }
160  // Removed -- remove entire transaction from table
161  parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1);
162  cachedWallet.erase(lower, upper);
163  parent->endRemoveRows();
164  break;
165  case CT_UPDATED:
166  // Miscellaneous updates -- nothing to do, status update will take care of this, and is only computed for
167  // visible transactions.
168  for (int i = lowerIndex; i < upperIndex; i++) {
169  TransactionRecord *rec = &cachedWallet[i];
170  rec->status.needsUpdate = true;
171  }
172  break;
173  }
174  }
175 
176  int size()
177  {
178  return cachedWallet.size();
179  }
180 
182  {
183  if(idx >= 0 && idx < cachedWallet.size())
184  {
185  TransactionRecord *rec = &cachedWallet[idx];
186 
187  // Get required locks upfront. This avoids the GUI from getting
188  // stuck if the core is holding the locks for a longer time - for
189  // example, during a wallet rescan.
190  //
191  // If a status update is needed (blocks came in since last check),
192  // update the status of this transaction from the wallet. Otherwise,
193  // simply re-use the cached status.
195  int numBlocks;
196  int64_t adjustedTime;
197  if (wallet.tryGetTxStatus(rec->hash, wtx, numBlocks, adjustedTime) && rec->statusUpdateNeeded(numBlocks)) {
198  rec->updateStatus(wtx, numBlocks, adjustedTime);
199  }
200  return rec;
201  }
202  return 0;
203  }
204 
205  QString describe(interfaces::Node& node, interfaces::Wallet& wallet, TransactionRecord *rec, int unit)
206  {
207  return TransactionDesc::toHTML(node, wallet, rec, unit);
208  }
209 
211  {
212  auto tx = wallet.getTx(rec->hash);
213  if (tx) {
214  std::string strHex = EncodeHexTx(*tx);
215  return QString::fromStdString(strHex);
216  }
217  return QString();
218  }
219 };
220 
222  QAbstractTableModel(parent),
223  walletModel(parent),
224  priv(new TransactionTablePriv(this)),
225  fProcessingQueuedTransactions(false),
226  platformStyle(_platformStyle)
227 {
228  columns << QString() << QString() << tr("Date") << tr("Type") << tr("Label") << BitcoinUnits::getAmountColumnTitle(walletModel->getOptionsModel()->getDisplayUnit());
230 
232 
234 }
235 
237 {
239  delete priv;
240 }
241 
244 {
246  Q_EMIT headerDataChanged(Qt::Horizontal,Amount,Amount);
247 }
248 
249 void TransactionTableModel::updateTransaction(const QString &hash, int status, bool showTransaction)
250 {
251  uint256 updated;
252  updated.SetHex(hash.toStdString());
253 
254  priv->updateWallet(walletModel->wallet(), updated, status, showTransaction);
255 }
256 
258 {
259  // Blocks came in since last poll.
260  // Invalidate status (number of confirmations) and (possibly) description
261  // for all rows. Qt is smart enough to only actually request the data for the
262  // visible rows.
263  Q_EMIT dataChanged(index(0, Status), index(priv->size()-1, Status));
264  Q_EMIT dataChanged(index(0, ToAddress), index(priv->size()-1, ToAddress));
265 }
266 
267 int TransactionTableModel::rowCount(const QModelIndex &parent) const
268 {
269  Q_UNUSED(parent);
270  return priv->size();
271 }
272 
273 int TransactionTableModel::columnCount(const QModelIndex &parent) const
274 {
275  Q_UNUSED(parent);
276  return columns.length();
277 }
278 
280 {
281  QString status;
282 
283  switch(wtx->status.status)
284  {
286  status = tr("Open for %n more block(s)","",wtx->status.open_for);
287  break;
289  status = tr("Open until %1").arg(GUIUtil::dateTimeStr(wtx->status.open_for));
290  break;
292  status = tr("Unconfirmed");
293  break;
295  status = tr("Abandoned");
296  break;
298  status = tr("Confirming (%1 of %2 recommended confirmations)").arg(wtx->status.depth).arg(TransactionRecord::RecommendedNumConfirmations);
299  break;
301  status = tr("Confirmed (%1 confirmations)").arg(wtx->status.depth);
302  break;
304  status = tr("Conflicted");
305  break;
307  status = tr("Immature (%1 confirmations, will be available after %2)").arg(wtx->status.depth).arg(wtx->status.depth + wtx->status.matures_in);
308  break;
310  status = tr("Generated but not accepted");
311  break;
312  }
313 
314  return status;
315 }
316 
318 {
319  if(wtx->time)
320  {
321  return GUIUtil::dateTimeStr(wtx->time);
322  }
323  return QString();
324 }
325 
326 /* Look up address in address book, if found return label (address)
327  otherwise just return (address)
328  */
329 QString TransactionTableModel::lookupAddress(const std::string &address, bool tooltip) const
330 {
331  QString label = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(address));
332  QString description;
333  if(!label.isEmpty())
334  {
335  description += label;
336  }
337  if(label.isEmpty() || tooltip)
338  {
339  description += QString(" (") + QString::fromStdString(address) + QString(")");
340  }
341  return description;
342 }
343 
345 {
346  switch(wtx->type)
347  {
349  return tr("Received with");
351  return tr("Received from");
354  return tr("Sent to");
356  return tr("Payment to yourself");
358  return tr("Mined");
359  default:
360  return QString();
361  }
362 }
363 
365 {
366  switch(wtx->type)
367  {
369  return QIcon(":/icons/tx_mined");
372  return QIcon(":/icons/tx_input");
375  return QIcon(":/icons/tx_output");
376  default:
377  return QIcon(":/icons/tx_inout");
378  }
379 }
380 
381 QString TransactionTableModel::formatTxToAddress(const TransactionRecord *wtx, bool tooltip) const
382 {
383  QString watchAddress;
384  if (tooltip) {
385  // Mark transactions involving watch-only addresses by adding " (watch-only)"
386  watchAddress = wtx->involvesWatchAddress ? QString(" (") + tr("watch-only") + QString(")") : "";
387  }
388 
389  switch(wtx->type)
390  {
392  return QString::fromStdString(wtx->address) + watchAddress;
396  return lookupAddress(wtx->address, tooltip) + watchAddress;
398  return QString::fromStdString(wtx->address) + watchAddress;
400  default:
401  return tr("(n/a)") + watchAddress;
402  }
403 }
404 
406 {
407  // Show addresses without label in a less visible color
408  switch(wtx->type)
409  {
413  {
414  QString label = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(wtx->address));
415  if(label.isEmpty())
416  return COLOR_BAREADDRESS;
417  } break;
419  return COLOR_BAREADDRESS;
420  default:
421  break;
422  }
423  return QVariant();
424 }
425 
426 QString TransactionTableModel::formatTxAmount(const TransactionRecord *wtx, bool showUnconfirmed, BitcoinUnits::SeparatorStyle separators) const
427 {
428  QString str = BitcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), wtx->credit + wtx->debit, false, separators);
429  if(showUnconfirmed)
430  {
431  if(!wtx->status.countsForBalance)
432  {
433  str = QString("[") + str + QString("]");
434  }
435  }
436  return QString(str);
437 }
438 
440 {
441  switch(wtx->status.status)
442  {
447  return QIcon(":/icons/transaction_0");
449  return QIcon(":/icons/transaction_abandoned");
451  switch(wtx->status.depth)
452  {
453  case 1: return QIcon(":/icons/transaction_1");
454  case 2: return QIcon(":/icons/transaction_2");
455  case 3: return QIcon(":/icons/transaction_3");
456  case 4: return QIcon(":/icons/transaction_4");
457  default: return QIcon(":/icons/transaction_5");
458  };
460  return QIcon(":/icons/transaction_confirmed");
462  return QIcon(":/icons/transaction_conflicted");
464  int total = wtx->status.depth + wtx->status.matures_in;
465  int part = (wtx->status.depth * 4 / total) + 1;
466  return QIcon(QString(":/icons/transaction_%1").arg(part));
467  }
469  return QIcon(":/icons/transaction_0");
470  default:
471  return COLOR_BLACK;
472  }
473 }
474 
476 {
477  if (wtx->involvesWatchAddress)
478  return QIcon(":/icons/eye");
479  else
480  return QVariant();
481 }
482 
484 {
485  QString tooltip = formatTxStatus(rec) + QString("\n") + formatTxType(rec);
488  {
489  tooltip += QString(" ") + formatTxToAddress(rec, true);
490  }
491  return tooltip;
492 }
493 
494 QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
495 {
496  if(!index.isValid())
497  return QVariant();
498  TransactionRecord *rec = static_cast<TransactionRecord*>(index.internalPointer());
499 
500  switch(role)
501  {
502  case RawDecorationRole:
503  switch(index.column())
504  {
505  case Status:
506  return txStatusDecoration(rec);
507  case Watchonly:
508  return txWatchonlyDecoration(rec);
509  case ToAddress:
510  return txAddressDecoration(rec);
511  }
512  break;
513  case Qt::DecorationRole:
514  {
515  QIcon icon = qvariant_cast<QIcon>(index.data(RawDecorationRole));
516  return platformStyle->TextColorIcon(icon);
517  }
518  case Qt::DisplayRole:
519  switch(index.column())
520  {
521  case Date:
522  return formatTxDate(rec);
523  case Type:
524  return formatTxType(rec);
525  case ToAddress:
526  return formatTxToAddress(rec, false);
527  case Amount:
529  }
530  break;
531  case Qt::EditRole:
532  // Edit role is used for sorting, so return the unformatted values
533  switch(index.column())
534  {
535  case Status:
536  return QString::fromStdString(rec->status.sortKey);
537  case Date:
538  return rec->time;
539  case Type:
540  return formatTxType(rec);
541  case Watchonly:
542  return (rec->involvesWatchAddress ? 1 : 0);
543  case ToAddress:
544  return formatTxToAddress(rec, true);
545  case Amount:
546  return qint64(rec->credit + rec->debit);
547  }
548  break;
549  case Qt::ToolTipRole:
550  return formatTooltip(rec);
551  case Qt::TextAlignmentRole:
552  return column_alignments[index.column()];
553  case Qt::ForegroundRole:
554  // Use the "danger" color for abandoned transactions
556  {
557  return COLOR_TX_STATUS_DANGER;
558  }
559  // Non-confirmed (but not immature) as transactions are grey
561  {
562  return COLOR_UNCONFIRMED;
563  }
564  if(index.column() == Amount && (rec->credit+rec->debit) < 0)
565  {
566  return COLOR_NEGATIVE;
567  }
568  if(index.column() == ToAddress)
569  {
570  return addressColor(rec);
571  }
572  break;
573  case TypeRole:
574  return rec->type;
575  case DateRole:
576  return QDateTime::fromTime_t(static_cast<uint>(rec->time));
577  case WatchonlyRole:
578  return rec->involvesWatchAddress;
580  return txWatchonlyDecoration(rec);
581  case LongDescriptionRole:
583  case AddressRole:
584  return QString::fromStdString(rec->address);
585  case LabelRole:
586  return walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(rec->address));
587  case AmountRole:
588  return qint64(rec->credit + rec->debit);
589  case TxHashRole:
590  return rec->getTxHash();
591  case TxHexRole:
592  return priv->getTxHex(walletModel->wallet(), rec);
593  case TxPlainTextRole:
594  {
595  QString details;
596  QDateTime date = QDateTime::fromTime_t(static_cast<uint>(rec->time));
597  QString txLabel = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(rec->address));
598 
599  details.append(date.toString("M/d/yy HH:mm"));
600  details.append(" ");
601  details.append(formatTxStatus(rec));
602  details.append(". ");
603  if(!formatTxType(rec).isEmpty()) {
604  details.append(formatTxType(rec));
605  details.append(" ");
606  }
607  if(!rec->address.empty()) {
608  if(txLabel.isEmpty())
609  details.append(tr("(no label)") + " ");
610  else {
611  details.append("(");
612  details.append(txLabel);
613  details.append(") ");
614  }
615  details.append(QString::fromStdString(rec->address));
616  details.append(" ");
617  }
618  details.append(formatTxAmount(rec, false, BitcoinUnits::separatorNever));
619  return details;
620  }
621  case ConfirmedRole:
622  return rec->status.countsForBalance;
623  case FormattedAmountRole:
624  // Used for copy/export, so don't include separators
625  return formatTxAmount(rec, false, BitcoinUnits::separatorNever);
626  case StatusRole:
627  return rec->status.status;
628  }
629  return QVariant();
630 }
631 
632 QVariant TransactionTableModel::headerData(int section, Qt::Orientation orientation, int role) const
633 {
634  if(orientation == Qt::Horizontal)
635  {
636  if(role == Qt::DisplayRole)
637  {
638  return columns[section];
639  }
640  else if (role == Qt::TextAlignmentRole)
641  {
642  return column_alignments[section];
643  } else if (role == Qt::ToolTipRole)
644  {
645  switch(section)
646  {
647  case Status:
648  return tr("Transaction status. Hover over this field to show number of confirmations.");
649  case Date:
650  return tr("Date and time that the transaction was received.");
651  case Type:
652  return tr("Type of transaction.");
653  case Watchonly:
654  return tr("Whether or not a watch-only address is involved in this transaction.");
655  case ToAddress:
656  return tr("User-defined intent/purpose of the transaction.");
657  case Amount:
658  return tr("Amount removed from or added to balance.");
659  }
660  }
661  }
662  return QVariant();
663 }
664 
665 QModelIndex TransactionTableModel::index(int row, int column, const QModelIndex &parent) const
666 {
667  Q_UNUSED(parent);
669  if(data)
670  {
671  return createIndex(row, column, priv->index(walletModel->wallet(), row));
672  }
673  return QModelIndex();
674 }
675 
677 {
678  // emit dataChanged to update Amount column with the current unit
680  Q_EMIT dataChanged(index(0, Amount), index(priv->size()-1, Amount));
681 }
682 
683 // queue notifications to show a non freezing progress dialog e.g. for rescan
685 {
686 public:
688  TransactionNotification(uint256 _hash, ChangeType _status, bool _showTransaction):
689  hash(_hash), status(_status), showTransaction(_showTransaction) {}
690 
691  void invoke(QObject *ttm)
692  {
693  QString strHash = QString::fromStdString(hash.GetHex());
694  qDebug() << "NotifyTransactionChanged: " + strHash + " status= " + QString::number(status);
695  QMetaObject::invokeMethod(ttm, "updateTransaction", Qt::QueuedConnection,
696  Q_ARG(QString, strHash),
697  Q_ARG(int, status),
698  Q_ARG(bool, showTransaction));
699  }
700 private:
704 };
705 
706 static bool fQueueNotifications = false;
707 static std::vector< TransactionNotification > vQueueNotifications;
708 
709 static void NotifyTransactionChanged(TransactionTableModel *ttm, const uint256 &hash, ChangeType status)
710 {
711  // Find transaction in wallet
712  // Determine whether to show transaction or not (determine this here so that no relocking is needed in GUI thread)
713  bool showTransaction = TransactionRecord::showTransaction();
714 
715  TransactionNotification notification(hash, status, showTransaction);
716 
717  if (fQueueNotifications)
718  {
719  vQueueNotifications.push_back(notification);
720  return;
721  }
722  notification.invoke(ttm);
723 }
724 
725 static void ShowProgress(TransactionTableModel *ttm, const std::string &title, int nProgress)
726 {
727  if (nProgress == 0)
728  fQueueNotifications = true;
729 
730  if (nProgress == 100)
731  {
732  fQueueNotifications = false;
733  if (vQueueNotifications.size() > 10) // prevent balloon spam, show maximum 10 balloons
734  QMetaObject::invokeMethod(ttm, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, true));
735  for (unsigned int i = 0; i < vQueueNotifications.size(); ++i)
736  {
737  if (vQueueNotifications.size() - i <= 10)
738  QMetaObject::invokeMethod(ttm, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, false));
739 
740  vQueueNotifications[i].invoke(ttm);
741  }
742  std::vector<TransactionNotification >().swap(vQueueNotifications); // clear
743  }
744 }
745 
747 {
748  // Connect signals to wallet
749  m_handler_transaction_changed = walletModel->wallet().handleTransactionChanged(boost::bind(NotifyTransactionChanged, this, _1, _2));
750  m_handler_show_progress = walletModel->wallet().handleShowProgress(boost::bind(ShowProgress, this, _1, _2));
751 }
752 
754 {
755  // Disconnect signals from wallet
756  m_handler_transaction_changed->disconnect();
757  m_handler_show_progress->disconnect();
758 }
void updateWallet(interfaces::Wallet &wallet, const uint256 &hash, int status, bool showTransaction)
void updateAmountColumnTitle()
Updates the column title to "Amount (DisplayUnit)" and emits headerDataChanged() signal for table hea...
bool statusUpdateNeeded(int numBlocks) const
Return whether a status update is needed.
virtual bool tryGetTxStatus(const uint256 &txid, WalletTxStatus &tx_status, int &num_blocks, int64_t &adjusted_time)=0
Try to get updated status for a particular transaction, if possible without blocking.
Confirmed, but waiting for the recommended number of confirmations.
interfaces::Wallet & wallet() const
Definition: walletmodel.h:219
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)
QString formatTxAmount(const TransactionRecord *wtx, bool showUnconfirmed=true, BitcoinUnits::SeparatorStyle separators=BitcoinUnits::separatorStandard) const
Generated (mined) transactions.
QString formatTooltip(const TransactionRecord *rec) const
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.
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)
Definition: guiutil.cpp:65
TransactionTablePriv(TransactionTableModel *_parent)
static QList< TransactionRecord > decomposeTransaction(const interfaces::WalletTx &wtx)
QVariant txStatusDecoration(const TransactionRecord *wtx) const
bool operator()(const TransactionRecord &a, const TransactionRecord &b) const
Mined but not accepted.
Not yet mined into a block.
static QString toHTML(interfaces::Node &node, interfaces::Wallet &wallet, TransactionRecord *rec, int unit)
CTransactionRef tx
Definition: wallet.h:332
TransactionTableModel(const PlatformStyle *platformStyle, WalletModel *parent=0)
AddressTableModel * getAddressTableModel()
Transaction data, hex-encoded.
TransactionTableModel * parent
TransactionTablePriv * priv
virtual WalletTx getWalletTx(const uint256 &txid)=0
Get transaction information.
int getDisplayUnit() const
Definition: optionsmodel.h:74
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
QIcon TextColorIcon(const QString &filename) const
Colorize an icon (given filename) with the text color.
QList< TransactionRecord > cachedWallet
void updateStatus(const interfaces::WalletTxStatus &wtx, int numBlocks, int64_t adjustedTime)
Update status from core wallet tx.
bool operator()(const TransactionRecord &a, const uint256 &b) 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
Whole transaction as plain text.
ChangeType
General change type (added, updated, removed).
Definition: ui_interface.h:23
std::unique_ptr< interfaces::Handler > m_handler_transaction_changed
#define COLOR_TX_STATUS_DANGER
Definition: guiconstants.h:31
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.
Definition: wallet.h:46
TransactionNotification(uint256 _hash, ChangeType _status, bool _showTransaction)
bool countsForBalance
Transaction counts towards available balance.
Date and time this transaction was created.
std::string ToString() const
Definition: uint256.cpp:62
#define COLOR_BLACK
Definition: guiconstants.h:33
interfaces::Node & node() const
Definition: walletmodel.h:218
void displayUnitChanged(int unit)
UI model for the transaction table of a wallet.
#define COLOR_UNCONFIRMED
Definition: guiconstants.h:23
void refreshWallet(interfaces::Wallet &wallet)
Normal (sent/received) transactions.
QString lookupAddress(const std::string &address, bool tooltip) const
std::unique_ptr< interfaces::Handler > m_handler_show_progress
static bool showTransaction()
Decompose CWallet transaction to model transaction records.
QVariant data(const QModelIndex &index, int role) const
256-bit opaque blob.
Definition: uint256.h:122
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.
Definition: walletmodel.h:125
int columnCount(const QModelIndex &parent) const
int rowCount(const QModelIndex &parent) const
bool involvesWatchAddress
Whether the transaction was sent/received with a watch-only address.
QVariant headerData(int section, Qt::Orientation orientation, int role) const
std::string GetHex() const
Definition: uint256.cpp:21
QString getTxHex(interfaces::Wallet &wallet, TransactionRecord *rec)
std::string EncodeHexTx(const CTransaction &tx, const int serializeFlags=0)
Definition: core_write.cpp:131
Label of address related to transaction.
QString formatTxStatus(const TransactionRecord *wtx) const
QVariant addressColor(const TransactionRecord *wtx) const
#define COLOR_TX_STATUS_OPENUNTILDATE
Definition: guiconstants.h:29
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.
void SetHex(const char *psz)
Definition: uint256.cpp:27
TransactionRecord * index(interfaces::Wallet &wallet, int idx)
Abandoned from the wallet.
#define COLOR_BAREADDRESS
Definition: guiconstants.h:27
Top-level interface for a bitcoin node (bsha3d process).
Definition: node.h:35
const PlatformStyle * platformStyle
Updated transaction status.
Definition: wallet.h:346
#define COLOR_NEGATIVE
Definition: guiconstants.h:25
static const int RecommendedNumConfirmations
Number of confirmation recommended for accepting a transaction.
static QString format(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as string.
OptionsModel * getOptionsModel()
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
QString formatTxDate(const TransactionRecord *wtx) const