Fabcoin Core  0.16.2
P2P Digital Currency
transactiontablemodel.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2017 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 <addresstablemodel.h>
8 #include <guiconstants.h>
9 #include <guiutil.h>
10 #include <optionsmodel.h>
11 #include <platformstyle.h>
12 #include <transactiondesc.h>
13 #include <transactionrecord.h>
14 #include <walletmodel.h>
15 
16 #include <core_io.h>
17 #include <validation.h>
18 #include <sync.h>
19 #include <uint256.h>
20 #include <util.h>
21 #include <wallet/wallet.h>
22 
23 #include <QColor>
24 #include <QDateTime>
25 #include <QDebug>
26 #include <QIcon>
27 #include <QList>
28 
29 // Amount column is right-aligned it contains numbers
30 static int column_alignments[] = {
31  Qt::AlignLeft|Qt::AlignVCenter, /* status */
32  Qt::AlignLeft|Qt::AlignVCenter, /* watchonly */
33  Qt::AlignLeft|Qt::AlignVCenter, /* date */
34  Qt::AlignLeft|Qt::AlignVCenter, /* type */
35  Qt::AlignLeft|Qt::AlignVCenter, /* address */
36  Qt::AlignRight|Qt::AlignVCenter /* amount */
37  };
38 
39 // Comparison operator for sort/binary search of model tx list
40 struct TxLessThan
41 {
42  bool operator()(const TransactionRecord &a, const TransactionRecord &b) const
43  {
44  return a.hash < b.hash;
45  }
46  bool operator()(const TransactionRecord &a, const uint256 &b) const
47  {
48  return a.hash < b;
49  }
50  bool operator()(const uint256 &a, const TransactionRecord &b) const
51  {
52  return a < b.hash;
53  }
54 };
55 
56 // Private implementation
58 {
59 public:
61  wallet(_wallet),
62  parent(_parent)
63  {
64  }
65 
68 
69  /* Local cache of wallet.
70  * As it is in the same order as the CWallet, by definition
71  * this is sorted by sha256.
72  */
73  QList<TransactionRecord> cachedWallet;
74 
75  /* Query entire wallet anew from core.
76  */
78  {
79  qDebug() << "TransactionTablePriv::refreshWallet";
80  cachedWallet.clear();
81  {
82  LOCK2(cs_main, wallet->cs_wallet);
83  for(std::map<uint256, CWalletTx>::iterator it = wallet->mapWallet.begin(); it != wallet->mapWallet.end(); ++it)
84  {
86  cachedWallet.append(TransactionRecord::decomposeTransaction(wallet, it->second));
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(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  LOCK2(cs_main, wallet->cs_wallet);
132  // Find transaction in wallet
133  std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(hash);
134  if(mi == wallet->mapWallet.end())
135  {
136  qWarning() << "TransactionTablePriv::updateWallet: Warning: Got CT_NEW, but transaction is not in wallet";
137  break;
138  }
139  // Added -- insert at the right position
140  QList<TransactionRecord> toInsert =
141  TransactionRecord::decomposeTransaction(wallet, mi->second);
142  if(!toInsert.isEmpty()) /* only if something to insert */
143  {
144  parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1);
145  int insert_idx = lowerIndex;
146  for (const TransactionRecord &rec : toInsert)
147  {
148  cachedWallet.insert(insert_idx, rec);
149  insert_idx += 1;
150  }
151  parent->endInsertRows();
152  }
153  }
154  break;
155  case CT_DELETED:
156  if(!inModel)
157  {
158  qWarning() << "TransactionTablePriv::updateWallet: Warning: Got CT_DELETED, but transaction is not in model";
159  break;
160  }
161  // Removed -- remove entire transaction from table
162  parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1);
163  cachedWallet.erase(lower, upper);
164  parent->endRemoveRows();
165  break;
166  case CT_UPDATED:
167  // Miscellaneous updates -- nothing to do, status update will take care of this, and is only computed for
168  // visible transactions.
169  for (int i = lowerIndex; i < upperIndex; i++) {
170  TransactionRecord *rec = &cachedWallet[i];
171  rec->status.needsUpdate = true;
172  }
173  break;
174  }
175  }
176 
177  int size()
178  {
179  return cachedWallet.size();
180  }
181 
183  {
184  if(idx >= 0 && idx < cachedWallet.size())
185  {
186  TransactionRecord *rec = &cachedWallet[idx];
187 
188  // Get required locks upfront. This avoids the GUI from getting
189  // stuck if the core is holding the locks for a longer time - for
190  // example, during a wallet rescan.
191  //
192  // If a status update is needed (blocks came in since last check),
193  // update the status of this transaction from the wallet. Otherwise,
194  // simply re-use the cached status.
195  TRY_LOCK(cs_main, lockMain);
196  if(lockMain)
197  {
198  TRY_LOCK(wallet->cs_wallet, lockWallet);
199  if(lockWallet && rec->statusUpdateNeeded())
200  {
201  std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->hash);
202 
203  if(mi != wallet->mapWallet.end())
204  {
205  rec->updateStatus(mi->second);
206  }
207  }
208  }
209  return rec;
210  }
211  return 0;
212  }
213 
214  QString describe(TransactionRecord *rec, int unit)
215  {
216  {
217  LOCK2(cs_main, wallet->cs_wallet);
218  std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->hash);
219  if(mi != wallet->mapWallet.end())
220  {
221  return TransactionDesc::toHTML(wallet, mi->second, rec, unit);
222  }
223  }
224  return QString();
225  }
226 
228  {
229  LOCK2(cs_main, wallet->cs_wallet);
230  std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->hash);
231  if(mi != wallet->mapWallet.end())
232  {
233  std::string strHex = EncodeHexTx(static_cast<CTransaction>(mi->second));
234  return QString::fromStdString(strHex);
235  }
236  return QString();
237  }
238 };
239 
241  QAbstractTableModel(parent),
242  wallet(_wallet),
243  walletModel(parent),
244  priv(new TransactionTablePriv(_wallet, this)),
245  fProcessingQueuedTransactions(false),
246  platformStyle(_platformStyle)
247 {
248  columns << QString() << QString() << tr("Date") << tr("Type") << tr("Label") << FabcoinUnits::getAmountColumnTitle(walletModel->getOptionsModel()->getDisplayUnit());
249  priv->refreshWallet();
250 
251  connect(walletModel->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
252 
254 }
255 
257 {
259  delete priv;
260 }
261 
264 {
266  Q_EMIT headerDataChanged(Qt::Horizontal,Amount,Amount);
267 }
268 
269 void TransactionTableModel::updateTransaction(const QString &hash, int status, bool showTransaction)
270 {
271  uint256 updated;
272  updated.SetHex(hash.toStdString());
273 
274  priv->updateWallet(updated, status, showTransaction);
275 }
276 
278 {
279  // Blocks came in since last poll.
280  // Invalidate status (number of confirmations) and (possibly) description
281  // for all rows. Qt is smart enough to only actually request the data for the
282  // visible rows.
283  Q_EMIT dataChanged(index(0, Status), index(priv->size()-1, Status));
284  Q_EMIT dataChanged(index(0, ToAddress), index(priv->size()-1, ToAddress));
285 }
286 
287 int TransactionTableModel::rowCount(const QModelIndex &parent) const
288 {
289  Q_UNUSED(parent);
290  return priv->size();
291 }
292 
293 int TransactionTableModel::columnCount(const QModelIndex &parent) const
294 {
295  Q_UNUSED(parent);
296  return columns.length();
297 }
298 
300 {
301  QString status;
302 
303  switch(wtx->status.status)
304  {
306  status = tr("Open for %n more block(s)","",wtx->status.open_for);
307  break;
309  status = tr("Open until %1").arg(GUIUtil::dateTimeStr(wtx->status.open_for));
310  break;
312  status = tr("Offline");
313  break;
315  status = tr("Unconfirmed");
316  break;
318  status = tr("Abandoned");
319  break;
321  status = tr("Confirming (%1 of %2 recommended confirmations)").arg(wtx->status.depth).arg(TransactionRecord::RecommendedNumConfirmations);
322  break;
324  status = tr("Confirmed (%1 confirmations)").arg(wtx->status.depth);
325  break;
327  status = tr("Conflicted");
328  break;
330  status = tr("Immature (%1 confirmations, will be available after %2)").arg(wtx->status.depth).arg(wtx->status.depth + wtx->status.matures_in);
331  break;
333  status = tr("This block was not received by any other nodes and will probably not be accepted!");
334  break;
336  status = tr("Generated but not accepted");
337  break;
338  }
339 
340  return status;
341 }
342 
344 {
345  if(wtx->time)
346  {
347  return GUIUtil::dateTimeStr(wtx->time);
348  }
349  return QString();
350 }
351 
352 /* Look up address in address book, if found return label (address)
353  otherwise just return (address)
354  */
355 QString TransactionTableModel::lookupAddress(const std::string &address, bool tooltip) const
356 {
357  QString label = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(address));
358  QString description;
359  if(!label.isEmpty())
360  {
361  description += label;
362  }
363  if(label.isEmpty() || tooltip)
364  {
365  description += QString(" (") + QString::fromStdString(address) + QString(")");
366  }
367  return description;
368 }
369 
371 {
372  switch(wtx->type)
373  {
375  return tr("Received with");
377  return tr("Received from");
380  return tr("Sent to");
382  return tr("Payment to yourself");
384  return tr("Mined");
386  return tr("Contract receive");
388  return tr("Contract send");
389  default:
390  return QString();
391  }
392 }
393 
395 {
396  switch(wtx->type)
397  {
399  return platformStyle->TableColorIcon(":/icons/tx_mined", PlatformStyle::Input);
402  return platformStyle->TableColorIcon(":/icons/tx_input", PlatformStyle::Input);
405  return platformStyle->TableColorIcon(":/icons/tx_output", PlatformStyle::Output);
407  return platformStyle->TableColorIcon(":/icons/contract_output", PlatformStyle::Output);
409  return platformStyle->TableColorIcon(":/icons/contract_input", PlatformStyle::Input);
410  default:
411  return platformStyle->TableColorIcon(":/icons/tx_inout", PlatformStyle::Inout);
412  }
413 }
414 
415 QString TransactionTableModel::formatTxToAddress(const TransactionRecord *wtx, bool tooltip) const
416 {
417  QString watchAddress;
418  if (tooltip) {
419  // Mark transactions involving watch-only addresses by adding " (watch-only)"
420  watchAddress = wtx->involvesWatchAddress ? QString(" (") + tr("watch-only") + QString(")") : "";
421  }
422 
423  switch(wtx->type)
424  {
426  return QString::fromStdString(wtx->address) + watchAddress;
432  return lookupAddress(wtx->address, tooltip) + watchAddress;
434  return QString::fromStdString(wtx->address) + watchAddress;
436  default:
437  return tr("(n/a)") + watchAddress;
438  }
439 }
440 
442 {
443  // Show addresses without label in a less visible color
444  switch(wtx->type)
445  {
451  {
452  QString label = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(wtx->address));
453  if(label.isEmpty())
454  return COLOR_BAREADDRESS;
455  } break;
457  return COLOR_BAREADDRESS;
458  default:
459  break;
460  }
461  return QVariant();
462 }
463 
464 QString TransactionTableModel::formatTxAmount(const TransactionRecord *wtx, bool showUnconfirmed, FabcoinUnits::SeparatorStyle separators) const
465 {
466  QString str = FabcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), wtx->credit + wtx->debit, false, separators);
467  if(showUnconfirmed)
468  {
469  if(!wtx->status.countsForBalance)
470  {
471  str = QString("[") + str + QString("]");
472  }
473  }
474  return QString(str);
475 }
476 
478 {
479  switch(wtx->status.status)
480  {
487  return platformStyle->TableColorIcon(":/icons/transaction_0", PlatformStyle::Normal);
489  return platformStyle->TableColorIcon(":/icons/transaction_abandoned", PlatformStyle::Error);
492  if(iconNum > CONFIRM_ICONS) iconNum = CONFIRM_ICONS;
493  return platformStyle->TableColorIcon(QString(":/icons/transaction_%1").arg(iconNum), PlatformStyle::Normal);
494  };
496  return platformStyle->TableColorIcon(":/icons/transaction_confirmed", PlatformStyle::Normal);
498  return platformStyle->TableColorIcon(":/icons/transaction_conflicted", PlatformStyle::Error);
500  int total = wtx->status.depth + wtx->status.matures_in;
501  int part = (wtx->status.depth * 4 / total) + 1;
502  return platformStyle->TableColorIcon(QString(":/icons/transaction_%1").arg(part), PlatformStyle::Normal);
503  }
506  return platformStyle->TableColorIcon(":/icons/transaction_0", PlatformStyle::Error);
507  default:
508  return COLOR_BLACK;
509  }
510 }
511 
513 {
514  if (wtx->involvesWatchAddress)
515  return platformStyle->TableColorIcon(":/icons/eye", PlatformStyle::Normal);
516  else
517  return QVariant();
518 }
519 
521 {
522  QString tooltip = formatTxStatus(rec) + QString("\n") + formatTxType(rec);
525  {
526  tooltip += QString(" ") + formatTxToAddress(rec, true);
527  }
528  return tooltip;
529 }
530 
531 QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
532 {
533  if(!index.isValid())
534  return QVariant();
535  TransactionRecord *rec = static_cast<TransactionRecord*>(index.internalPointer());
536 
537  switch(role)
538  {
539  case RawDecorationRole:
540  switch(index.column())
541  {
542  case Status:
543  return txStatusDecoration(rec);
544  case Watchonly:
545  return txWatchonlyDecoration(rec);
546  case ToAddress:
547  return txAddressDecoration(rec);
548  }
549  break;
550  case Qt::DecorationRole:
551  {
552  return qvariant_cast<QIcon>(index.data(RawDecorationRole));
553  }
554  case Qt::DisplayRole:
555  switch(index.column())
556  {
557  case Date:
558  return formatTxDate(rec);
559  case Type:
560  return formatTxType(rec);
561  case ToAddress:
562  return formatTxToAddress(rec, false);
563  case Amount:
565  }
566  break;
567  case Qt::EditRole:
568  // Edit role is used for sorting, so return the unformatted values
569  switch(index.column())
570  {
571  case Status:
572  return QString::fromStdString(rec->status.sortKey);
573  case Date:
574  return rec->time;
575  case Type:
576  return formatTxType(rec);
577  case Watchonly:
578  return (rec->involvesWatchAddress ? 1 : 0);
579  case ToAddress:
580  return formatTxToAddress(rec, true);
581  case Amount:
582  return qint64(rec->credit + rec->debit);
583  }
584  break;
585  case Qt::ToolTipRole:
586  return formatTooltip(rec);
587  case Qt::TextAlignmentRole:
588  return column_alignments[index.column()];
589  case Qt::ForegroundRole:
590  // Use the "danger" color for abandoned transactions
592  {
593  return COLOR_TX_STATUS_DANGER;
594  }
595  // Non-confirmed (but not immature) as transactions are grey
597  {
598  return COLOR_UNCONFIRMED;
599  }
600  if(index.column() == Amount && (rec->credit+rec->debit) < 0)
601  {
602  return COLOR_NEGATIVE;
603  }
604  if(index.column() == ToAddress)
605  {
606  return addressColor(rec);
607  }
608  break;
609  case TypeRole:
610  return rec->type;
611  case DateRole:
612  return QDateTime::fromTime_t(static_cast<uint>(rec->time));
613  case WatchonlyRole:
614  return rec->involvesWatchAddress;
616  return txWatchonlyDecoration(rec);
617  case LongDescriptionRole:
619  case AddressRole:
620  return QString::fromStdString(rec->address);
621  case LabelRole:
622  return walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(rec->address));
623  case AmountRole:
624  return qint64(rec->credit + rec->debit);
625  case TxIDRole:
626  return rec->getTxID();
627  case TxHashRole:
628  return QString::fromStdString(rec->hash.ToString());
629  case TxHexRole:
630  return priv->getTxHex(rec);
631  case TxPlainTextRole:
632  {
633  QString details;
634  QDateTime date = QDateTime::fromTime_t(static_cast<uint>(rec->time));
635  QString txLabel = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(rec->address));
636 
637  details.append(date.toString("M/d/yy HH:mm"));
638  details.append(" ");
639  details.append(formatTxStatus(rec));
640  details.append(". ");
641  if(!formatTxType(rec).isEmpty()) {
642  details.append(formatTxType(rec));
643  details.append(" ");
644  }
645  if(!rec->address.empty()) {
646  if(txLabel.isEmpty())
647  details.append(tr("(no label)") + " ");
648  else {
649  details.append("(");
650  details.append(txLabel);
651  details.append(") ");
652  }
653  details.append(QString::fromStdString(rec->address));
654  details.append(" ");
655  }
656  details.append(formatTxAmount(rec, false, FabcoinUnits::separatorNever));
657  return details;
658  }
659  case ConfirmedRole:
660  return rec->status.countsForBalance;
661  case FormattedAmountRole:
662  // Used for copy/export, so don't include separators
663  return formatTxAmount(rec, false, FabcoinUnits::separatorNever);
664  case StatusRole:
665  return rec->status.status;
666  }
667  return QVariant();
668 }
669 
670 QVariant TransactionTableModel::headerData(int section, Qt::Orientation orientation, int role) const
671 {
672  if(orientation == Qt::Horizontal)
673  {
674  if(role == Qt::DisplayRole)
675  {
676  return columns[section];
677  }
678  else if (role == Qt::TextAlignmentRole)
679  {
680  return column_alignments[section];
681  } else if (role == Qt::ToolTipRole)
682  {
683  switch(section)
684  {
685  case Status:
686  return tr("Transaction status. Hover over this field to show number of confirmations.");
687  case Date:
688  return tr("Date and time that the transaction was received.");
689  case Type:
690  return tr("Type of transaction.");
691  case Watchonly:
692  return tr("Whether or not a watch-only address is involved in this transaction.");
693  case ToAddress:
694  return tr("User-defined intent/purpose of the transaction.");
695  case Amount:
696  return tr("Amount removed from or added to balance.");
697  }
698  }
699  }
700  return QVariant();
701 }
702 
703 QModelIndex TransactionTableModel::index(int row, int column, const QModelIndex &parent) const
704 {
705  Q_UNUSED(parent);
706  TransactionRecord *data = priv->index(row);
707  if(data)
708  {
709  return createIndex(row, column, priv->index(row));
710  }
711  return QModelIndex();
712 }
713 
715 {
716  // emit dataChanged to update Amount column with the current unit
718  Q_EMIT dataChanged(index(0, Amount), index(priv->size()-1, Amount));
719 }
720 
721 // queue notifications to show a non freezing progress dialog e.g. for rescan
723 {
724 public:
726  TransactionNotification(uint256 _hash, ChangeType _status, bool _showTransaction):
727  hash(_hash), status(_status), showTransaction(_showTransaction) {}
728 
729  void invoke(QObject *ttm)
730  {
731  QString strHash = QString::fromStdString(hash.GetHex());
732  qDebug() << "NotifyTransactionChanged: " + strHash + " status= " + QString::number(status);
733  QMetaObject::invokeMethod(ttm, "updateTransaction", Qt::QueuedConnection,
734  Q_ARG(QString, strHash),
735  Q_ARG(int, status),
736  Q_ARG(bool, showTransaction));
737  }
738 private:
742 };
743 
744 static bool fQueueNotifications = false;
745 static std::vector< TransactionNotification > vQueueNotifications;
746 
747 static void NotifyTransactionChanged(TransactionTableModel *ttm, CWallet *wallet, const uint256 &hash, ChangeType status)
748 {
749  // Find transaction in wallet
750  std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(hash);
751  // Determine whether to show transaction or not (determine this here so that no relocking is needed in GUI thread)
752  bool inWallet = mi != wallet->mapWallet.end();
753  bool showTransaction = (inWallet && TransactionRecord::showTransaction(mi->second));
754 
755  TransactionNotification notification(hash, status, showTransaction);
756 
757  if (fQueueNotifications)
758  {
759  vQueueNotifications.push_back(notification);
760  return;
761  }
762  notification.invoke(ttm);
763 }
764 
765 static void ShowProgress(TransactionTableModel *ttm, const std::string &title, int nProgress)
766 {
767  if (nProgress == 0)
768  fQueueNotifications = true;
769 
770  if (nProgress == 100)
771  {
772  fQueueNotifications = false;
773  if (vQueueNotifications.size() > 10) // prevent balloon spam, show maximum 10 balloons
774  QMetaObject::invokeMethod(ttm, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, true));
775  for (unsigned int i = 0; i < vQueueNotifications.size(); ++i)
776  {
777  if (vQueueNotifications.size() - i <= 10)
778  QMetaObject::invokeMethod(ttm, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, false));
779 
780  vQueueNotifications[i].invoke(ttm);
781  }
782  std::vector<TransactionNotification >().swap(vQueueNotifications); // clear
783  }
784 }
785 
787 {
788  // Connect signals to wallet
789  wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
790  wallet->ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
791 }
792 
794 {
795  // Disconnect signals from wallet
796  wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
797  wallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
798 }
QVariant addressColor(const TransactionRecord *wtx) const
void updateAmountColumnTitle()
Updates the column title to "Amount (DisplayUnit)" and emits headerDataChanged() signal for table hea...
int columnCount(const QModelIndex &parent) const
QVariant data(const QModelIndex &index, int role) const
QVariant txStatusDecoration(const TransactionRecord *wtx) const
QString describe(TransactionRecord *rec, int unit)
Confirmed, but waiting for the recommended number of confirmations.
bool operator()(const uint256 &a, const TransactionRecord &b) const
Transaction not yet final, waiting for block.
Transaction status (TransactionRecord::Status)
#define CONFIRM_ICONS
Definition: guiconstants.h:35
#define TRY_LOCK(cs, name)
Definition: sync.h:177
QString formatTxAmount(const TransactionRecord *wtx, bool showUnconfirmed=true, FabcoinUnits::SeparatorStyle separators=FabcoinUnits::separatorStandard) const
void swap(dev::eth::Watch &_a, dev::eth::Watch &_b)
Definition: Interface.h:284
QString getTxID() const
Return the unique identifier for this transaction (part)
Not sent to any other nodes.
CCriticalSection cs_wallet
Definition: wallet.h:748
Generated (mined) transactions.
QString formatTxToAddress(const TransactionRecord *wtx, bool tooltip) const
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)
CCriticalSection cs_main
Definition: validation.cpp:77
QString dateTimeStr(const QDateTime &date)
Definition: guiutil.cpp:80
QIcon TableColorIcon(const QString &resourcename, TableColorType type) const
QVariant txAddressDecoration(const TransactionRecord *wtx) const
TransactionRecord * index(int idx)
Mined but not accepted.
Not yet mined into a block.
QString lookupAddress(const std::string &address, bool tooltip) const
#define COLOR_TX_STATUS_OFFLINE
Definition: guiconstants.h:28
static bool showTransaction(const CWalletTx &wtx)
Decompose CWallet transaction to model transaction records.
AddressTableModel * getAddressTableModel()
Transaction data, hex-encoded.
TransactionTableModel * parent
QVariant headerData(int section, Qt::Orientation orientation, int role) const
TransactionTableModel(const PlatformStyle *platformStyle, CWallet *wallet, WalletModel *parent=0)
void updateWallet(const uint256 &hash, int status, bool showTransaction)
TransactionTablePriv * priv
QString formatTxStatus(const TransactionRecord *wtx) const
std::string ToString() const
Definition: uint256.cpp:95
QList< TransactionRecord > cachedWallet
boost::signals2::signal< void(CWallet *wallet, const uint256 &hashTx, ChangeType status)> NotifyTransactionChanged
Wallet transaction added, removed or updated.
Definition: wallet.h:1120
#define a(i)
#define LOCK2(cs1, cs2)
Definition: sync.h:176
UI model for a transaction.
TransactionStatus status
Status: can change with block chain update.
TransactionTablePriv(CWallet *_wallet, TransactionTableModel *_parent)
Whole transaction as plain text.
static QList< TransactionRecord > decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx)
ChangeType
General change type (added, updated, removed).
Definition: ui_interface.h:19
static QString format(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as string.
bool operator()(const TransactionRecord &a, const uint256 &b) const
#define COLOR_TX_STATUS_DANGER
Definition: guiconstants.h:30
TransactionNotification(uint256 _hash, ChangeType _status, bool _showTransaction)
bool countsForBalance
Transaction counts towards available balance.
void updateStatus(const CWalletTx &wtx)
Update status from core wallet tx.
QString getTxHex(TransactionRecord *rec)
Date and time this transaction was created.
#define COLOR_BLACK
Definition: guiconstants.h:32
int getDisplayUnit()
Definition: optionsmodel.h:70
UI model for the transaction table of a wallet.
#define COLOR_UNCONFIRMED
Definition: guiconstants.h:20
Normal (sent/received) transactions.
QString formatTxType(const TransactionRecord *wtx) const
QString formatTooltip(const TransactionRecord *rec) const
#define b(i, j)
QVariant txWatchonlyDecoration(const TransactionRecord *wtx) const
256-bit opaque blob.
Definition: uint256.h:132
static QString getAmountColumnTitle(int unit)
Gets title for amount column including current display unit if optionsModel reference available */...
bool operator()(const TransactionRecord &a, const TransactionRecord &b) const
QString labelForAddress(const QString &address) const
Conflicts with other transaction or mempool.
Interface to Fabcoin wallet from Qt view code.
Definition: walletmodel.h:103
int rowCount(const QModelIndex &parent) const
bool involvesWatchAddress
Whether the transaction was sent/received with a watch-only address.
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
Label of address related to transaction.
bool statusUpdateNeeded()
Return whether a status update is needed.
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
struct evm_uint160be address(struct evm_env *env)
Definition: capi.c:13
#define COLOR_TX_STATUS_OPENUNTILDATE
Definition: guiconstants.h:26
qint64 open_for
Timestamp if status==OpenUntilDate, otherwise number of additional blocks that need to be mined befor...
Formatted amount, without brackets when unconfirmed.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
void SetHex(const char *psz)
Definition: uint256.cpp:39
static QString toHTML(CWallet *wallet, CWalletTx &wtx, TransactionRecord *rec, int unit)
Abandoned from the wallet.
#define COLOR_BAREADDRESS
Definition: guiconstants.h:24
const PlatformStyle * platformStyle
#define COLOR_NEGATIVE
Definition: guiconstants.h:22
QString formatTxDate(const TransactionRecord *wtx) const
static const int RecommendedNumConfirmations
Number of confirmation recommended for accepting a transaction.
Transaction will likely not mature because no nodes have confirmed.
OptionsModel * getOptionsModel()