Fabcoin Core  0.16.2
P2P Digital Currency
tokentransactiontablemodel.cpp
Go to the documentation of this file.
2 
3 #include <addresstablemodel.h>
4 #include <guiconstants.h>
5 #include <guiutil.h>
6 #include <optionsmodel.h>
7 #include <platformstyle.h>
8 #include <tokentransactiondesc.h>
10 #include <walletmodel.h>
11 
12 #include <core_io.h>
13 #include <validation.h>
14 #include <sync.h>
15 #include <uint256.h>
16 #include <util.h>
17 #include <wallet/wallet.h>
18 
19 #include <QColor>
20 #include <QDateTime>
21 #include <QDebug>
22 #include <QIcon>
23 #include <QList>
24 
25 // Amount column is right-aligned it contains numbers
26 static int column_alignments[] = {
27  Qt::AlignLeft|Qt::AlignVCenter, /* status */
28  Qt::AlignLeft|Qt::AlignVCenter, /* date */
29  Qt::AlignLeft|Qt::AlignVCenter, /* type */
30  Qt::AlignLeft|Qt::AlignVCenter, /* address */
31  Qt::AlignLeft|Qt::AlignVCenter, /* name */
32  Qt::AlignRight|Qt::AlignVCenter /* amount */
33  };
34 
35 // Comparison operator for sort/binary search of model tx list
37 {
39  {
40  return a.hash < b.hash;
41  }
42  bool operator()(const TokenTransactionRecord &a, const uint256 &b) const
43  {
44  return a.hash < b;
45  }
46  bool operator()(const uint256 &a, const TokenTransactionRecord &b) const
47  {
48  return a < b.hash;
49  }
50 };
51 
52 // Private implementation
54 {
55 public:
57  wallet(_wallet),
58  parent(_parent)
59  {
60  }
61 
64 
65  /* Local cache of wallet.
66  * As it is in the same order as the CWallet, by definition
67  * this is sorted by sha256.
68  */
69  QList<TokenTransactionRecord> cachedWallet;
70 
71  /* Query entire wallet anew from core.
72  */
74  {
75  qDebug() << "TokenTransactionTablePriv::refreshWallet";
76  cachedWallet.clear();
77  {
78  LOCK2(cs_main, wallet->cs_wallet);
79  for(std::map<uint256, CTokenTx>::iterator it = wallet->mapTokenTx.begin(); it != wallet->mapTokenTx.end(); ++it)
80  {
81  // Update token transaction time if the block time is changed
82  CTokenTx wtokenTx = it->second;
83  const CBlockIndex *pIndex = chainActive[wtokenTx.blockNumber];
84  if(pIndex && pIndex->GetBlockTime() != wtokenTx.nCreateTime)
85  {
86  wtokenTx.nCreateTime = pIndex->GetBlockTime();
87  wallet->AddTokenTxEntry(wtokenTx, false);
88  }
89 
90  // Add token tx to the cache
91  cachedWallet.append(TokenTransactionRecord::decomposeTransaction(wallet, wtokenTx));
92  }
93  }
94  }
95 
96  /* Update our model of the wallet incrementally, to synchronize our model of the wallet
97  with that of the core.
98 
99  Call with transaction that was added, removed or changed.
100  */
101  void updateWallet(const uint256 &hash, int status, bool showTransaction)
102  {
103  qDebug() << "TokenTransactionTablePriv::updateWallet: " + QString::fromStdString(hash.ToString()) + " " + QString::number(status);
104 
105  // Find bounds of this transaction in model
106  QList<TokenTransactionRecord>::iterator lower = qLowerBound(
107  cachedWallet.begin(), cachedWallet.end(), hash, TokenTxLessThan());
108  QList<TokenTransactionRecord>::iterator upper = qUpperBound(
109  cachedWallet.begin(), cachedWallet.end(), hash, TokenTxLessThan());
110  int lowerIndex = (lower - cachedWallet.begin());
111  int upperIndex = (upper - cachedWallet.begin());
112  bool inModel = (lower != upper);
113 
114  if(status == CT_UPDATED)
115  {
116  if(showTransaction && !inModel)
117  status = CT_NEW; /* Not in model, but want to show, treat as new */
118  if(!showTransaction && inModel)
119  status = CT_DELETED; /* In model, but want to hide, treat as deleted */
120  }
121 
122  qDebug() << " inModel=" + QString::number(inModel) +
123  " Index=" + QString::number(lowerIndex) + "-" + QString::number(upperIndex) +
124  " showTransaction=" + QString::number(showTransaction) + " derivedStatus=" + QString::number(status);
125 
126  switch(status)
127  {
128  case CT_NEW:
129  if(inModel)
130  {
131  qWarning() << "TokenTransactionTablePriv::updateWallet: Warning: Got CT_NEW, but transaction is already in model";
132  break;
133  }
134  if(showTransaction)
135  {
136  LOCK2(cs_main, wallet->cs_wallet);
137  // Find transaction in wallet
138  std::map<uint256, CTokenTx>::iterator mi = wallet->mapTokenTx.find(hash);
139  if(mi == wallet->mapTokenTx.end())
140  {
141  qWarning() << "TokenTransactionTablePriv::updateWallet: Warning: Got CT_NEW, but transaction is not in wallet";
142  break;
143  }
144  // Added -- insert at the right position
145  QList<TokenTransactionRecord> toInsert =
147  if(!toInsert.isEmpty()) /* only if something to insert */
148  {
149  parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1);
150  int insert_idx = lowerIndex;
151  Q_FOREACH(const TokenTransactionRecord &rec, toInsert)
152  {
153  cachedWallet.insert(insert_idx, rec);
154  insert_idx += 1;
155  }
156  parent->endInsertRows();
157  }
158  }
159  break;
160  case CT_DELETED:
161  if(!inModel)
162  {
163  qWarning() << "TokenTransactionTablePriv::updateWallet: Warning: Got CT_DELETED, but transaction is not in model";
164  break;
165  }
166  // Removed -- remove entire transaction from table
167  parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1);
168  cachedWallet.erase(lower, upper);
169  parent->endRemoveRows();
170  break;
171  case CT_UPDATED:
172  if(!inModel)
173  {
174  qWarning() << "TokenTransactionTablePriv::updateWallet: Warning: Got CT_UPDATED, but entry is not in model";
175  break;
176  }
177  if(showTransaction)
178  {
179  LOCK2(cs_main, wallet->cs_wallet);
180  // Find transaction in wallet
181  std::map<uint256, CTokenTx>::iterator mi = wallet->mapTokenTx.find(hash);
182  if(mi == wallet->mapTokenTx.end())
183  {
184  qWarning() << "TokenTransactionTablePriv::updateWallet: Warning: Got CT_UPDATED, but transaction is not in wallet";
185  break;
186  }
187  // Updated -- update at the right position
188  QList<TokenTransactionRecord> toUpdate =
190  if(!toUpdate.isEmpty()) /* only if something to insert */
191  {
192  int update_idx = lowerIndex;
193  Q_FOREACH(const TokenTransactionRecord &rec, toUpdate)
194  {
195  cachedWallet[update_idx] = rec;
196  parent->emitDataChanged(update_idx);
197  update_idx += 1;
198  }
199  }
200  }
201  break;
202  }
203  }
204 
205  int size()
206  {
207  return cachedWallet.size();
208  }
209 
211  {
212  if(idx >= 0 && idx < cachedWallet.size())
213  {
214  TokenTransactionRecord *rec = &cachedWallet[idx];
215 
216  // Get required locks upfront. This avoids the GUI from getting
217  // stuck if the core is holding the locks for a longer time - for
218  // example, during a wallet rescan.
219  //
220  // If a status update is needed (blocks came in since last check),
221  // update the status of this transaction from the wallet. Otherwise,
222  // simply re-use the cached status.
223  TRY_LOCK(cs_main, lockMain);
224  if(lockMain)
225  {
226  TRY_LOCK(wallet->cs_wallet, lockWallet);
227  if(lockWallet && rec->statusUpdateNeeded())
228  {
229  std::map<uint256, CTokenTx>::iterator mi = wallet->mapTokenTx.find(rec->hash);
230 
231  if(mi != wallet->mapTokenTx.end())
232  {
233  CTokenTx wtx(mi->second);
234  rec->updateStatus(wallet, wtx);
235  }
236  }
237  }
238  return rec;
239  }
240  return 0;
241  }
242 
244  {
245  {
246  LOCK2(cs_main, wallet->cs_wallet);
247  std::map<uint256, CTokenTx>::iterator mi = wallet->mapTokenTx.find(rec->hash);
248  if(mi != wallet->mapTokenTx.end())
249  {
250  return TokenTransactionDesc::toHTML(wallet, mi->second, rec);
251  }
252  }
253  return QString();
254  }
255 
257  {
258  LOCK2(cs_main, wallet->cs_wallet);
259  std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->txid);
260  if(mi != wallet->mapWallet.end())
261  {
262  std::string strHex = EncodeHexTx(static_cast<CTransaction>(mi->second));
263  return QString::fromStdString(strHex);
264  }
265  return QString();
266  }
267 };
268 
270  QAbstractTableModel(parent),
271  wallet(_wallet),
272  walletModel(parent),
273  priv(new TokenTransactionTablePriv(_wallet, this)),
274  fProcessingQueuedTransactions(false),
275  platformStyle(_platformStyle)
276 {
277  columns << QString() << tr("Date") << tr("Type") << tr("Label") << tr("Name") << tr("Amount");
278  priv->refreshWallet();
279 
281 }
282 
284 {
286  delete priv;
287 }
288 
289 void TokenTransactionTableModel::updateTransaction(const QString &hash, int status, bool showTransaction)
290 {
291  uint256 updated;
292  updated.SetHex(hash.toStdString());
293 
294  priv->updateWallet(updated, status, showTransaction);
295 }
296 
298 {
299  // Blocks came in since last poll.
300  // Invalidate status (number of confirmations) and (possibly) description
301  // for all rows. Qt is smart enough to only actually request the data for the
302  // visible rows.
303  Q_EMIT dataChanged(index(0, Status), index(priv->size()-1, Status));
304  Q_EMIT dataChanged(index(0, ToAddress), index(priv->size()-1, ToAddress));
305 }
306 
307 int TokenTransactionTableModel::rowCount(const QModelIndex &parent) const
308 {
309  Q_UNUSED(parent);
310  return priv->size();
311 }
312 
313 int TokenTransactionTableModel::columnCount(const QModelIndex &parent) const
314 {
315  Q_UNUSED(parent);
316  return columns.length();
317 }
318 
320 {
321  QString status;
322 
323  switch(wtx->status.status)
324  {
326  status = tr("Offline");
327  break;
329  status = tr("Unconfirmed");
330  break;
332  status = tr("Confirming (%1 of %2 recommended confirmations)").arg(wtx->status.depth).arg(TokenTransactionRecord::RecommendedNumConfirmations);
333  break;
335  status = tr("Confirmed (%1 confirmations)").arg(wtx->status.depth);
336  break;
337  }
338 
339  return status;
340 }
341 
343 {
344  if(wtx->time)
345  {
346  return GUIUtil::dateTimeStr(wtx->time);
347  }
348  return QString();
349 }
350 
351 /* Look up address in address book, if found return label (address)
352  otherwise just return (address)
353  */
354 QString TokenTransactionTableModel::lookupAddress(const std::string &address, const std::string &_label, bool tooltip) const
355 {
356  QString label = QString::fromStdString(_label);
357  if(label.isEmpty())
358  {
359  label = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(address));
360  }
361  QString description;
362  if(!label.isEmpty())
363  {
364  description += label;
365  }
366  if(label.isEmpty() || tooltip)
367  {
368  description += QString(" (") + QString::fromStdString(address) + QString(")");
369  }
370  return description;
371 }
372 
374 {
375  switch(wtx->type)
376  {
378  return tr("Received with");
380  return tr("Received from");
383  return tr("Sent to");
385  return tr("Payment to yourself");
386  default:
387  return QString();
388  }
389 }
390 
392 {
393  switch(wtx->type)
394  {
397  return platformStyle->TableColorIcon(":/icons/tx_input", PlatformStyle::Input);
400  return platformStyle->TableColorIcon(":/icons/tx_output", PlatformStyle::Output);
401  default:
402  return platformStyle->TableColorIcon(":/icons/tx_inout", PlatformStyle::Inout);
403  }
404 }
405 
407 {
408  switch(wtx->type)
409  {
411  return QString::fromStdString(wtx->address);
414  return lookupAddress(wtx->address, wtx->label, tooltip);
416  return QString::fromStdString(wtx->address);
418  default:
419  return tr("(n/a)");
420  }
421 }
422 
424 {
425  return QString::fromStdString(wtx->tokenSymbol);
426 }
427 
429 {
430  // Show addresses without label in a less visible color
431  switch(wtx->type)
432  {
435  {
436  QString label = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(wtx->address));
437  if(label.isEmpty())
438  return COLOR_BAREADDRESS;
439  } break;
441  return COLOR_BAREADDRESS;
442  default:
443  break;
444  }
445  return QVariant();
446 }
447 
448 QString TokenTransactionTableModel::formatTxAmount(const TokenTransactionRecord *wtx, bool showUnconfirmed, FabcoinUnits::SeparatorStyle separators) const
449 {
450  QString str = FabcoinUnits::formatToken(wtx->decimals, wtx->credit + wtx->debit, false, separators);
451  if(showUnconfirmed)
452  {
453  if(!wtx->status.countsForBalance)
454  {
455  str = QString("[") + str + QString("]");
456  }
457  }
458  return QString(str);
459 }
460 
462 {
463  QString unit = QString::fromStdString(wtx->tokenSymbol);
464  QString str = FabcoinUnits::formatTokenWithUnit(unit, wtx->decimals, wtx->credit + wtx->debit, false, separators);
465  return QString(str);
466 }
467 
469 {
470  switch(wtx->status.status)
471  {
475  return platformStyle->TableColorIcon(":/icons/transaction_0", PlatformStyle::Normal);
478  if(iconNum > CONFIRM_ICONS) iconNum = CONFIRM_ICONS;
479  return platformStyle->TableColorIcon(QString(":/icons/transaction_%1").arg(iconNum), PlatformStyle::Normal);
480  };
482  return platformStyle->TableColorIcon(":/icons/transaction_confirmed", PlatformStyle::Normal);
483  default:
484  return COLOR_BLACK;
485  }
486 }
487 
489 {
490  QString tooltip = formatTxStatus(rec) + QString("\n") + formatTxType(rec);
493  {
494  tooltip += QString(" ") + formatTxToAddress(rec, true);
495  }
496  return tooltip;
497 }
498 
499 QVariant TokenTransactionTableModel::data(const QModelIndex &index, int role) const
500 {
501  if(!index.isValid())
502  return QVariant();
503  TokenTransactionRecord *rec = static_cast<TokenTransactionRecord*>(index.internalPointer());
504 
505  switch(role)
506  {
507  case RawDecorationRole:
508  switch(index.column())
509  {
510  case Status:
511  return txStatusDecoration(rec);
512  case ToAddress:
513  return txAddressDecoration(rec);
514  }
515  break;
516  case Qt::DecorationRole:
517  {
518  return qvariant_cast<QIcon>(index.data(RawDecorationRole));
519  }
520  case Qt::DisplayRole:
521  switch(index.column())
522  {
523  case Date:
524  return formatTxDate(rec);
525  case Type:
526  return formatTxType(rec);
527  case ToAddress:
528  return formatTxToAddress(rec, false);
529  case Name:
530  return formatTxTokenSymbol(rec);
531  case Amount:
533  }
534  break;
535  case Qt::EditRole:
536  // Edit role is used for sorting, so return the unformatted values
537  switch(index.column())
538  {
539  case Status:
540  return QString::fromStdString(rec->status.sortKey);
541  case Date:
542  return rec->time;
543  case Type:
544  return formatTxType(rec);
545  case ToAddress:
546  return formatTxToAddress(rec, true);
547  case Name:
548  return formatTxTokenSymbol(rec);
549  case Amount:
550  return QString::fromStdString((rec->credit + rec->debit).str());
551  }
552  break;
553  case Qt::ToolTipRole:
554  return formatTooltip(rec);
555  case Qt::TextAlignmentRole:
556  return column_alignments[index.column()];
557  case Qt::ForegroundRole:
558  // Non-confirmed as transactions are grey
559  if(!rec->status.countsForBalance)
560  {
561  return COLOR_UNCONFIRMED;
562  }
563  if(index.column() == Amount && (rec->credit+rec->debit) < 0)
564  {
565  return COLOR_NEGATIVE;
566  }
567  if(index.column() == ToAddress)
568  {
569  return addressColor(rec);
570  }
571  break;
572  case TypeRole:
573  return rec->type;
574  case DateRole:
575  return QDateTime::fromTime_t(static_cast<uint>(rec->time));
576  case LongDescriptionRole:
577  return priv->describe(rec);
578  case NameRole:
579  return QString::fromStdString(rec->tokenSymbol);
580  case AddressRole:
581  return QString::fromStdString(rec->address);
582  case LabelRole:
583  return walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(rec->address));
584  case AmountRole:
585  return QString::fromStdString((rec->credit + rec->debit).str());
586  case TxHashRole:
587  return QString::fromStdString(rec->txid.ToString());
588  case TxHexRole:
589  return priv->getTxHex(rec);
590  case TxPlainTextRole:
591  {
592  QString details;
593  QDateTime date = QDateTime::fromTime_t(static_cast<uint>(rec->time));
594  QString txLabel = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(rec->address));
595  QString symbol = QString::fromStdString(rec->tokenSymbol);
596 
597  details.append(date.toString("M/d/yy HH:mm"));
598  details.append(" ");
599  details.append(formatTxStatus(rec));
600  details.append(". ");
601  if(!formatTxType(rec).isEmpty()) {
602  details.append(formatTxType(rec));
603  details.append(" ");
604  }
605  if(!rec->address.empty()) {
606  if(txLabel.isEmpty())
607  details.append(tr("(no label)") + " ");
608  else {
609  details.append("(");
610  details.append(txLabel);
611  details.append(") ");
612  }
613  details.append(QString::fromStdString(rec->address));
614  details.append(" ");
615  }
616  details.append(formatTxAmount(rec, false, FabcoinUnits::separatorNever));
617  details.append(" " + symbol);
618  return details;
619  }
620  case ConfirmedRole:
621  return rec->status.countsForBalance;
622  case FormattedAmountRole:
623  // Used for copy/export, so don't include separators
624  return formatTxAmount(rec, false, FabcoinUnits::separatorNever);
627  case StatusRole:
628  return rec->status.status;
629  }
630  return QVariant();
631 }
632 
633 QVariant TokenTransactionTableModel::headerData(int section, Qt::Orientation orientation, int role) const
634 {
635  if(orientation == Qt::Horizontal)
636  {
637  if(role == Qt::DisplayRole)
638  {
639  return columns[section];
640  }
641  else if (role == Qt::TextAlignmentRole)
642  {
643  return column_alignments[section];
644  } else if (role == Qt::ToolTipRole)
645  {
646  switch(section)
647  {
648  case Status:
649  return tr("Transaction status. Hover over this field to show number of confirmations.");
650  case Date:
651  return tr("Date and time that the transaction was received.");
652  case Type:
653  return tr("Type of transaction.");
654  case ToAddress:
655  return tr("User-defined intent/purpose of the transaction.");
656  case Name:
657  return tr("Token name.");
658  case Amount:
659  return tr("Amount removed from or added to balance.");
660  }
661  }
662  }
663  return QVariant();
664 }
665 
666 QModelIndex TokenTransactionTableModel::index(int row, int column, const QModelIndex &parent) const
667 {
668  Q_UNUSED(parent);
670  if(data)
671  {
672  return createIndex(row, column, priv->index(row));
673  }
674  return QModelIndex();
675 }
676 
678 {
679  Q_EMIT dataChanged(index(idx, 0, QModelIndex()), index(idx, columns.length()-1, QModelIndex()));
680 }
681 
682 // queue notifications to show a non freezing progress dialog e.g. for rescan
684 {
685 public:
687  TokenTransactionNotification(uint256 _hash, ChangeType _status, bool _showTransaction):
688  hash(_hash), status(_status), showTransaction(_showTransaction) {}
689 
690  void invoke(QObject *ttm)
691  {
692  QString strHash = QString::fromStdString(hash.GetHex());
693  qDebug() << "NotifyTokenTransactionChanged: " + strHash + " status= " + QString::number(status);
694  QMetaObject::invokeMethod(ttm, "updateTransaction", Qt::QueuedConnection,
695  Q_ARG(QString, strHash),
696  Q_ARG(int, status),
697  Q_ARG(bool, showTransaction));
698  }
699 private:
703 };
704 
705 static bool fQueueNotifications = false;
706 static std::vector< TokenTransactionNotification > vQueueNotifications;
707 
708 static void NotifyTokenTransactionChanged(TokenTransactionTableModel *ttm, CWallet *wallet, const uint256 &hash, ChangeType status)
709 {
710  // Find transaction in wallet
711  std::map<uint256, CTokenTx>::iterator mi = wallet->mapTokenTx.find(hash);
712  // Determine whether to show transaction or not (determine this here so that no relocking is needed in GUI thread)
713  bool showTransaction = mi != wallet->mapTokenTx.end();
714  if(showTransaction)
715  {
716  showTransaction = wallet->IsTokenTxMine(mi->second);
717  }
718 
719  TokenTransactionNotification notification(hash, status, showTransaction);
720 
721  if (fQueueNotifications)
722  {
723  vQueueNotifications.push_back(notification);
724  return;
725  }
726  notification.invoke(ttm);
727 }
728 
729 static void ShowProgress(TokenTransactionTableModel *ttm, const std::string &title, int nProgress)
730 {
731  if (nProgress == 0)
732  fQueueNotifications = true;
733 
734  if (nProgress == 100)
735  {
736  fQueueNotifications = false;
737  if (vQueueNotifications.size() > 10) // prevent balloon spam, show maximum 10 balloons
738  QMetaObject::invokeMethod(ttm, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, true));
739  for (unsigned int i = 0; i < vQueueNotifications.size(); ++i)
740  {
741  if (vQueueNotifications.size() - i <= 10)
742  QMetaObject::invokeMethod(ttm, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, false));
743 
744  vQueueNotifications[i].invoke(ttm);
745  }
746  std::vector<TokenTransactionNotification >().swap(vQueueNotifications); // clear
747  }
748 }
749 
751 {
752  // Connect signals to wallet
753  wallet->NotifyTokenTransactionChanged.connect(boost::bind(NotifyTokenTransactionChanged, this, _1, _2, _3));
754  wallet->ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
755 }
756 
758 {
759  // Disconnect signals from wallet
760  wallet->NotifyTokenTransactionChanged.disconnect(boost::bind(NotifyTokenTransactionChanged, this, _1, _2, _3));
761  wallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
762 }
void updateStatus(const CWallet *wallet, const CTokenTx &wtx)
Update status from core wallet tx.
Date and time this transaction was created.
QString formatTxStatus(const TokenTransactionRecord *wtx) const
#define CONFIRM_ICONS
Definition: guiconstants.h:35
std::map< uint256, CTokenTx > mapTokenTx
Definition: wallet.h:836
#define TRY_LOCK(cs, name)
Definition: sync.h:177
TokenTransactionNotification(uint256 _hash, ChangeType _status, bool _showTransaction)
void swap(dev::eth::Watch &_a, dev::eth::Watch &_b)
Definition: Interface.h:284
Transaction status (TokenTransactionRecord::Status)
CCriticalSection cs_wallet
Definition: wallet.h:748
QString lookupAddress(const std::string &address, const std::string &label, bool tooltip) const
CCriticalSection cs_main
Definition: validation.cpp:77
QString dateTimeStr(const QDateTime &date)
Definition: guiutil.cpp:80
QIcon TableColorIcon(const QString &resourcename, TableColorType type) const
static QString formatTokenWithUnit(const QString unit, int decimals, const int256_t &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format token as string.
QVariant data(const QModelIndex &index, int role) const
UI model for a token transaction.
QString formatTxToAddress(const TokenTransactionRecord *wtx, bool tooltip) const
bool operator()(const TokenTransactionRecord &a, const TokenTransactionRecord &b) const
#define COLOR_TX_STATUS_OFFLINE
Definition: guiconstants.h:28
Confirmed, but waiting for the recommended number of confirmations.
int64_t blockNumber
Definition: wallet.h:1364
QVariant addressColor(const TokenTransactionRecord *wtx) const
QList< TokenTransactionRecord > cachedWallet
boost::signals2::signal< void(CWallet *wallet, const uint256 &hashTx, ChangeType status)> NotifyTokenTransactionChanged
Wallet token transaction added, removed or updated.
Definition: wallet.h:1127
TokenTransactionTablePriv(CWallet *_wallet, TokenTransactionTableModel *_parent)
AddressTableModel * getAddressTableModel()
QString getTxHex(TokenTransactionRecord *rec)
void updateWallet(const uint256 &hash, int status, bool showTransaction)
std::string sortKey
Sorting key based on status.
std::string ToString() const
Definition: uint256.cpp:95
QVariant headerData(int section, Qt::Orientation orientation, int role) const
#define a(i)
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
bool IsTokenTxMine(const CTokenTx &wtx) const
Definition: wallet.cpp:4586
bool countsForBalance
Token transaction counts towards available balance.
#define LOCK2(cs1, cs2)
Definition: sync.h:176
QString describe(TokenTransactionRecord *rec)
static QList< TokenTransactionRecord > decomposeTransaction(const CWallet *wallet, const CTokenTx &wtx)
Decompose Token transaction into a record.
Have 6 or more confirmations (normal tx) or fully mature (mined tx)
ChangeType
General change type (added, updated, removed).
Definition: ui_interface.h:19
int rowCount(const QModelIndex &parent) const
QString formatTxDate(const TokenTransactionRecord *wtx) const
TokenTransactionRecord * index(int idx)
UI model for the transaction table of a wallet.
int columnCount(const QModelIndex &parent) const
static QString toHTML(CWallet *wallet, CTokenTx &wtx, TokenTransactionRecord *rec)
QString formatTxTokenSymbol(const TokenTransactionRecord *wtx) const
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).
Definition: validation.cpp:80
QString formatTxType(const TokenTransactionRecord *wtx) const
bool operator()(const uint256 &a, const TokenTransactionRecord &b) const
#define COLOR_BLACK
Definition: guiconstants.h:32
QVariant txAddressDecoration(const TokenTransactionRecord *wtx) const
#define COLOR_UNCONFIRMED
Definition: guiconstants.h:20
TokenTransactionTableModel * parent
#define b(i, j)
Formatted amount, without brackets when unconfirmed.
static QString formatToken(int decimal_units, const int256_t &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format token as string.
256-bit opaque blob.
Definition: uint256.h:132
int64_t nCreateTime
Definition: wallet.h:1362
QString labelForAddress(const QString &address) const
void updateTransaction(const QString &hash, int status, bool showTransaction)
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: chain.h:177
Normal (sent/received) token transactions.
Interface to Fabcoin wallet from Qt view code.
Definition: walletmodel.h:103
QString formatTxAmount(const TokenTransactionRecord *wtx, bool showUnconfirmed=true, FabcoinUnits::SeparatorStyle separators=FabcoinUnits::separatorStandard) const
TokenTransactionTableModel(const PlatformStyle *platformStyle, CWallet *wallet, WalletModel *parent=0)
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances...
Definition: wallet.h:672
std::string EncodeHexTx(const CTransaction &tx, const int serializeFlags=0)
Definition: core_write.cpp:124
QVariant txStatusDecoration(const TokenTransactionRecord *wtx) const
std::map< uint256, CWalletTx > mapWallet
Definition: wallet.h:815
boost::signals2::signal< void(const std::string &title, int nProgress)> ShowProgress
Show progress e.g.
Definition: wallet.h:1130
Label of address related to transaction.
bool operator()(const TokenTransactionRecord &a, const uint256 &b) const
TokenTransactionStatus status
Status: can change with block chain update.
struct evm_uint160be address(struct evm_env *env)
Definition: capi.c:13
QString formatTooltip(const TokenTransactionRecord *rec) const
int64_t GetBlockTime() const
Definition: chain.h:329
void SetHex(const char *psz)
Definition: uint256.cpp:39
#define COLOR_BAREADDRESS
Definition: guiconstants.h:24
bool statusUpdateNeeded()
Return whether a status update is needed.
QString formatTxAmountWithUnit(const TokenTransactionRecord *wtx, bool showUnconfirmed=true, FabcoinUnits::SeparatorStyle separators=FabcoinUnits::separatorStandard) const
#define COLOR_NEGATIVE
Definition: guiconstants.h:22
static const int RecommendedNumConfirmations
Number of confirmation recommended for accepting a token transaction.
bool AddTokenTxEntry(const CTokenTx &tokenTx, bool fFlushOnClose=true)
Definition: wallet.cpp:4421
TokenTransactionTablePriv * priv