Bitcoin ABC  0.22.13
P2P Digital Currency
overviewpage.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2016 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 
5 #include <qt/forms/ui_overviewpage.h>
6 #include <qt/overviewpage.h>
7 
8 #include <qt/bitcoinunits.h>
9 #include <qt/clientmodel.h>
10 #include <qt/guiconstants.h>
11 #include <qt/guiutil.h>
12 #include <qt/optionsmodel.h>
13 #include <qt/platformstyle.h>
16 #include <qt/walletmodel.h>
17 
18 #include <QAbstractItemDelegate>
19 #include <QPainter>
20 
21 #define DECORATION_SIZE 54
22 #define NUM_ITEMS 5
23 
24 Q_DECLARE_METATYPE(interfaces::WalletBalances)
25 
26 class TxViewDelegate : public QAbstractItemDelegate {
27  Q_OBJECT
28 public:
29  explicit TxViewDelegate(const PlatformStyle *_platformStyle,
30  QObject *parent = nullptr)
31  : QAbstractItemDelegate(parent), unit(BitcoinUnits::BCH),
32  platformStyle(_platformStyle) {}
33 
34  inline void paint(QPainter *painter, const QStyleOptionViewItem &option,
35  const QModelIndex &index) const {
36  painter->save();
37 
38  QIcon icon = qvariant_cast<QIcon>(
40  QRect mainRect = option.rect;
41  QRect decorationRect(mainRect.topLeft(),
43  int xspace = DECORATION_SIZE + 8;
44  int ypad = 6;
45  int halfheight = (mainRect.height() - 2 * ypad) / 2;
46  QRect amountRect(mainRect.left() + xspace, mainRect.top() + ypad,
47  mainRect.width() - xspace, halfheight);
48  QRect addressRect(mainRect.left() + xspace,
49  mainRect.top() + ypad + halfheight,
50  mainRect.width() - xspace, halfheight);
51  icon = platformStyle->SingleColorIcon(icon);
52  icon.paint(painter, decorationRect);
53 
54  QDateTime date =
55  index.data(TransactionTableModel::DateRole).toDateTime();
56  QString address = index.data(Qt::DisplayRole).toString();
57  Amount amount(
58  int64_t(
59  index.data(TransactionTableModel::AmountRole).toLongLong()) *
60  SATOSHI);
61  bool confirmed =
62  index.data(TransactionTableModel::ConfirmedRole).toBool();
63  QVariant value = index.data(Qt::ForegroundRole);
64  QColor foreground = option.palette.color(QPalette::Text);
65  if (value.canConvert<QBrush>()) {
66  QBrush brush = qvariant_cast<QBrush>(value);
67  foreground = brush.color();
68  }
69 
70  painter->setPen(foreground);
71  QRect boundingRect;
72  painter->drawText(addressRect, Qt::AlignLeft | Qt::AlignVCenter,
73  address, &boundingRect);
74 
75  if (index.data(TransactionTableModel::WatchonlyRole).toBool()) {
76  QIcon iconWatchonly = qvariant_cast<QIcon>(
78  QRect watchonlyRect(boundingRect.right() + 5,
79  mainRect.top() + ypad + halfheight, 16,
80  halfheight);
81  iconWatchonly.paint(painter, watchonlyRect);
82  }
83 
84  if (amount < Amount::zero()) {
85  foreground = COLOR_NEGATIVE;
86  } else if (!confirmed) {
87  foreground = COLOR_UNCONFIRMED;
88  } else {
89  foreground = option.palette.color(QPalette::Text);
90  }
91  painter->setPen(foreground);
92  QString amountText = BitcoinUnits::formatWithUnit(
93  unit, amount, true, BitcoinUnits::separatorAlways);
94  if (!confirmed) {
95  amountText = QString("[") + amountText + QString("]");
96  }
97  painter->drawText(amountRect, Qt::AlignRight | Qt::AlignVCenter,
98  amountText);
99 
100  painter->setPen(option.palette.color(QPalette::Text));
101  painter->drawText(amountRect, Qt::AlignLeft | Qt::AlignVCenter,
102  GUIUtil::dateTimeStr(date));
103 
104  painter->restore();
105  }
106 
107  inline QSize sizeHint(const QStyleOptionViewItem &option,
108  const QModelIndex &index) const {
109  return QSize(DECORATION_SIZE, DECORATION_SIZE);
110  }
111 
112  int unit;
114 };
115 #include <qt/overviewpage.moc>
116 
117 OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent)
118  : QWidget(parent), ui(new Ui::OverviewPage), clientModel(nullptr),
119  walletModel(nullptr),
120  txdelegate(new TxViewDelegate(platformStyle, this)) {
121  ui->setupUi(this);
122 
124 
125  // use a SingleColorIcon for the "out of sync warning" icon
126  QIcon icon = platformStyle->SingleColorIcon(":/icons/warning");
127  // also set the disabled icon because we are using a disabled QPushButton to
128  // work around missing HiDPI support of QLabel
129  // (https://bugreports.qt.io/browse/QTBUG-42503)
130  icon.addPixmap(icon.pixmap(QSize(64, 64), QIcon::Normal), QIcon::Disabled);
131  ui->labelTransactionsStatus->setIcon(icon);
132  ui->labelWalletStatus->setIcon(icon);
133 
134  // Recent transactions
135  ui->listTransactions->setItemDelegate(txdelegate);
136  ui->listTransactions->setIconSize(QSize(DECORATION_SIZE, DECORATION_SIZE));
137  ui->listTransactions->setMinimumHeight(NUM_ITEMS * (DECORATION_SIZE + 2));
138  ui->listTransactions->setAttribute(Qt::WA_MacShowFocusRect, false);
139 
140  connect(ui->listTransactions, &QListView::clicked, this,
142 
143  // start with displaying the "out of sync" warnings
144  showOutOfSyncWarning(true);
145  connect(ui->labelWalletStatus, &QPushButton::clicked, this,
147  connect(ui->labelTransactionsStatus, &QPushButton::clicked, this,
149 }
150 
151 void OverviewPage::handleTransactionClicked(const QModelIndex &index) {
152  if (filter) {
153  Q_EMIT transactionClicked(filter->mapToSource(index));
154  }
155 }
156 
158  Q_EMIT outOfSyncWarningClicked();
159 }
160 
162  delete ui;
163 }
164 
166  int unit = walletModel->getOptionsModel()->getDisplayUnit();
167  m_balances = balances;
168  if (walletModel->wallet().isLegacy()) {
170  ui->labelBalance->setText(BitcoinUnits::formatWithUnit(
171  unit, balances.watch_only_balance, false,
173  ui->labelUnconfirmed->setText(BitcoinUnits::formatWithUnit(
174  unit, balances.unconfirmed_watch_only_balance, false,
176  ui->labelImmature->setText(BitcoinUnits::formatWithUnit(
177  unit, balances.immature_watch_only_balance, false,
179  ui->labelTotal->setText(BitcoinUnits::formatWithUnit(
180  unit,
181  balances.watch_only_balance +
185  } else {
186  ui->labelBalance->setText(BitcoinUnits::formatWithUnit(
187  unit, balances.balance, false, BitcoinUnits::separatorAlways));
188  ui->labelUnconfirmed->setText(BitcoinUnits::formatWithUnit(
189  unit, balances.unconfirmed_balance, false,
191  ui->labelImmature->setText(BitcoinUnits::formatWithUnit(
192  unit, balances.immature_balance, false,
194  ui->labelTotal->setText(BitcoinUnits::formatWithUnit(
195  unit,
196  balances.balance + balances.unconfirmed_balance +
197  balances.immature_balance,
199  ui->labelWatchAvailable->setText(BitcoinUnits::formatWithUnit(
200  unit, balances.watch_only_balance, false,
202  ui->labelWatchPending->setText(BitcoinUnits::formatWithUnit(
203  unit, balances.unconfirmed_watch_only_balance, false,
205  ui->labelWatchImmature->setText(BitcoinUnits::formatWithUnit(
206  unit, balances.immature_watch_only_balance, false,
208  ui->labelWatchTotal->setText(BitcoinUnits::formatWithUnit(
209  unit,
210  balances.watch_only_balance +
214  }
215  } else {
216  ui->labelBalance->setText(BitcoinUnits::formatWithUnit(
217  unit, balances.balance, false, BitcoinUnits::separatorAlways));
218  ui->labelUnconfirmed->setText(
221  ui->labelImmature->setText(
222  BitcoinUnits::formatWithUnit(unit, balances.immature_balance, false,
224  ui->labelTotal->setText(BitcoinUnits::formatWithUnit(
225  unit,
226  balances.balance + balances.unconfirmed_balance +
227  balances.immature_balance,
229  }
230 
231  // only show immature (newly mined) balance if it's non-zero, so as not to
232  // complicate things for the non-mining users
233  bool showImmature = balances.immature_balance != Amount::zero();
234  bool showWatchOnlyImmature =
236 
237  // for symmetry reasons also show immature label when the watch-only one is
238  // shown
239  ui->labelImmature->setVisible(showImmature || showWatchOnlyImmature);
240  ui->labelImmatureText->setVisible(showImmature || showWatchOnlyImmature);
241  // show watch-only immature balance
242  ui->labelWatchImmature->setVisible(
243  !walletModel->wallet().privateKeysDisabled() && showWatchOnlyImmature);
244 }
245 
246 // show/hide watch-only labels
247 void OverviewPage::updateWatchOnlyLabels(bool showWatchOnly) {
248  // show spendable label (only when watch-only is active)
249  ui->labelSpendable->setVisible(showWatchOnly);
250  // show watch-only label
251  ui->labelWatchonly->setVisible(showWatchOnly);
252  // show watch-only balance separator line
253  ui->lineWatchBalance->setVisible(showWatchOnly);
254  // show watch-only available balance
255  ui->labelWatchAvailable->setVisible(showWatchOnly);
256  // show watch-only pending balance
257  ui->labelWatchPending->setVisible(showWatchOnly);
258  // show watch-only total balance
259  ui->labelWatchTotal->setVisible(showWatchOnly);
260 
261  if (!showWatchOnly) {
262  ui->labelWatchImmature->hide();
263  }
264 }
265 
267  this->clientModel = model;
268  if (model) {
269  // Show warning, for example if this is a prerelease version
270  connect(model, &ClientModel::alertsChanged, this,
273  }
274 }
275 
277  this->walletModel = model;
278  if (model && model->getOptionsModel()) {
279  // Set up transaction list
280  filter.reset(new TransactionFilterProxy());
281  filter->setSourceModel(model->getTransactionTableModel());
282  filter->setLimit(NUM_ITEMS);
283  filter->setDynamicSortFilter(true);
284  filter->setSortRole(Qt::EditRole);
285  filter->setShowInactive(false);
286  filter->sort(TransactionTableModel::Date, Qt::DescendingOrder);
287 
288  ui->listTransactions->setModel(filter.get());
289  ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress);
290 
291  // Keep up to date with wallet
292  interfaces::Wallet &wallet = model->wallet();
293  interfaces::WalletBalances balances = wallet.getBalances();
294  setBalance(balances);
295  connect(model, &WalletModel::balanceChanged, this,
297 
300 
302  !model->wallet().privateKeysDisabled());
303  connect(model, &WalletModel::notifyWatchonlyChanged,
304  [this](bool showWatchOnly) {
306  showWatchOnly &&
308  });
309  }
310 
311  // update the display unit, to not use the default ("BCH")
313 }
314 
317  if (m_balances.balance != -SATOSHI) {
319  }
320 
321  // Update txdelegate->unit with the current unit
323 
324  ui->listTransactions->update();
325  }
326 }
327 
328 void OverviewPage::updateAlerts(const QString &warnings) {
329  this->ui->labelAlerts->setVisible(!warnings.isEmpty());
330  this->ui->labelAlerts->setText(warnings);
331 }
332 
334  ui->labelWalletStatus->setVisible(fShow);
335  ui->labelTransactionsStatus->setVisible(fShow);
336 }
virtual bool privateKeysDisabled()=0
static QString formatWithUnit(int unit, const Amount amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as string (with unit)
void setWalletModel(WalletModel *walletModel)
interfaces::Wallet & wallet() const
Definition: walletmodel.h:150
Bitcoin unit definitions.
Definition: bitcoinunits.h:32
static constexpr Amount zero()
Definition: amount.h:35
void updateAlerts(const QString &warnings)
#define DECORATION_SIZE
void handleTransactionClicked(const QModelIndex &index)
interfaces::WalletBalances m_balances
Definition: overviewpage.h:51
std::unique_ptr< TransactionFilterProxy > filter
Definition: overviewpage.h:54
Amount unconfirmed_watch_only_balance
Definition: wallet.h:325
QString dateTimeStr(const QDateTime &date)
Definition: guiutil.cpp:66
Definition: amount.h:17
TxViewDelegate(const PlatformStyle *_platformStyle, QObject *parent=nullptr)
static constexpr Amount SATOSHI
Definition: amount.h:151
QIcon SingleColorIcon(const QString &filename) const
Colorize an icon (given filename) with the icon color.
TxViewDelegate * txdelegate
Definition: overviewpage.h:53
WalletModel * walletModel
Definition: overviewpage.h:50
virtual bool isLegacy()=0
Return whether is a legacy wallet.
void outOfSyncWarningClicked()
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
QString getStatusBarWarnings() const
Return warnings to be displayed in status bar.
void alertsChanged(const QString &warnings)
int getDisplayUnit() const
Definition: optionsmodel.h:96
#define NUM_ITEMS
Collection of wallet balances.
Definition: wallet.h:319
void updateWatchOnlyLabels(bool showWatchOnly)
Interface for accessing a wallet.
Definition: wallet.h:56
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
Date and time this transaction was created.
TransactionTableModel * getTransactionTableModel()
void displayUnitChanged(int unit)
#define COLOR_UNCONFIRMED
Definition: guiconstants.h:25
Model for Bitcoin network client.
Definition: clientmodel.h:34
ClientModel * clientModel
Definition: overviewpage.h:49
void transactionClicked(const QModelIndex &index)
const PlatformStyle * platformStyle
void showOutOfSyncWarning(bool fShow)
Filter the transaction list according to pre-specified rules.
void updateDisplayUnit()
Interface to Bitcoin wallet from Qt view code.
Definition: walletmodel.h:47
Amount immature_watch_only_balance
Definition: wallet.h:326
virtual bool haveWatchOnly()=0
Return whether wallet has watch only keys.
void notifyWatchonlyChanged(bool fHaveWatchonly)
void setClientModel(ClientModel *clientModel)
void setBalance(const interfaces::WalletBalances &balances)
void handleOutOfSyncWarningClicks()
OverviewPage(const PlatformStyle *platformStyle, QWidget *parent=nullptr)
virtual WalletBalances getBalances()=0
Get balances.
Overview ("home") page widget.
Definition: overviewpage.h:28
Ui::OverviewPage * ui
Definition: overviewpage.h:48
void balanceChanged(const interfaces::WalletBalances &balances)
#define COLOR_NEGATIVE
Definition: guiconstants.h:27
OptionsModel * getOptionsModel()