Bitcoin Core  0.18.99
P2P Digital Currency
overviewpage.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 
5 #include <qt/overviewpage.h>
6 #include <qt/forms/ui_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 {
28  Q_OBJECT
29 public:
30  explicit TxViewDelegate(const PlatformStyle *_platformStyle, QObject *parent=nullptr):
31  QAbstractItemDelegate(parent), unit(BitcoinUnits::BTC),
32  platformStyle(_platformStyle)
33  {
34 
35  }
36 
37  inline void paint(QPainter *painter, const QStyleOptionViewItem &option,
38  const QModelIndex &index ) const
39  {
40  painter->save();
41 
42  QIcon icon = qvariant_cast<QIcon>(index.data(TransactionTableModel::RawDecorationRole));
43  QRect mainRect = option.rect;
44  QRect decorationRect(mainRect.topLeft(), QSize(DECORATION_SIZE, DECORATION_SIZE));
45  int xspace = DECORATION_SIZE + 8;
46  int ypad = 6;
47  int halfheight = (mainRect.height() - 2*ypad)/2;
48  QRect amountRect(mainRect.left() + xspace, mainRect.top()+ypad, mainRect.width() - xspace, halfheight);
49  QRect addressRect(mainRect.left() + xspace, mainRect.top()+ypad+halfheight, mainRect.width() - xspace, halfheight);
50  icon = platformStyle->SingleColorIcon(icon);
51  icon.paint(painter, decorationRect);
52 
53  QDateTime date = index.data(TransactionTableModel::DateRole).toDateTime();
54  QString address = index.data(Qt::DisplayRole).toString();
55  qint64 amount = index.data(TransactionTableModel::AmountRole).toLongLong();
56  bool confirmed = index.data(TransactionTableModel::ConfirmedRole).toBool();
57  QVariant value = index.data(Qt::ForegroundRole);
58  QColor foreground = option.palette.color(QPalette::Text);
59  if(value.canConvert<QBrush>())
60  {
61  QBrush brush = qvariant_cast<QBrush>(value);
62  foreground = brush.color();
63  }
64 
65  painter->setPen(foreground);
66  QRect boundingRect;
67  painter->drawText(addressRect, Qt::AlignLeft|Qt::AlignVCenter, address, &boundingRect);
68 
69  if (index.data(TransactionTableModel::WatchonlyRole).toBool())
70  {
71  QIcon iconWatchonly = qvariant_cast<QIcon>(index.data(TransactionTableModel::WatchonlyDecorationRole));
72  QRect watchonlyRect(boundingRect.right() + 5, mainRect.top()+ypad+halfheight, 16, halfheight);
73  iconWatchonly.paint(painter, watchonlyRect);
74  }
75 
76  if(amount < 0)
77  {
78  foreground = COLOR_NEGATIVE;
79  }
80  else if(!confirmed)
81  {
82  foreground = COLOR_UNCONFIRMED;
83  }
84  else
85  {
86  foreground = option.palette.color(QPalette::Text);
87  }
88  painter->setPen(foreground);
89  QString amountText = BitcoinUnits::formatWithUnit(unit, amount, true, BitcoinUnits::separatorAlways);
90  if(!confirmed)
91  {
92  amountText = QString("[") + amountText + QString("]");
93  }
94  painter->drawText(amountRect, Qt::AlignRight|Qt::AlignVCenter, amountText);
95 
96  painter->setPen(option.palette.color(QPalette::Text));
97  painter->drawText(amountRect, Qt::AlignLeft|Qt::AlignVCenter, GUIUtil::dateTimeStr(date));
98 
99  painter->restore();
100  }
101 
102  inline QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
103  {
104  return QSize(DECORATION_SIZE, DECORATION_SIZE);
105  }
106 
107  int unit;
109 
110 };
111 #include <qt/overviewpage.moc>
112 
113 OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent) :
114  QWidget(parent),
115  ui(new Ui::OverviewPage),
116  clientModel(nullptr),
117  walletModel(nullptr),
118  txdelegate(new TxViewDelegate(platformStyle, this))
119 {
120  ui->setupUi(this);
121 
122  m_balances.balance = -1;
123 
124  // use a SingleColorIcon for the "out of sync warning" icon
125  QIcon icon = platformStyle->SingleColorIcon(":/icons/warning");
126  icon.addPixmap(icon.pixmap(QSize(64,64), QIcon::Normal), QIcon::Disabled); // also set the disabled icon because we are using a disabled QPushButton to work around missing HiDPI support of QLabel (https://bugreports.qt.io/browse/QTBUG-42503)
127  ui->labelTransactionsStatus->setIcon(icon);
128  ui->labelWalletStatus->setIcon(icon);
129 
130  // Recent transactions
131  ui->listTransactions->setItemDelegate(txdelegate);
132  ui->listTransactions->setIconSize(QSize(DECORATION_SIZE, DECORATION_SIZE));
133  ui->listTransactions->setMinimumHeight(NUM_ITEMS * (DECORATION_SIZE + 2));
134  ui->listTransactions->setAttribute(Qt::WA_MacShowFocusRect, false);
135 
136  connect(ui->listTransactions, &QListView::clicked, this, &OverviewPage::handleTransactionClicked);
137 
138  // start with displaying the "out of sync" warnings
139  showOutOfSyncWarning(true);
140  connect(ui->labelWalletStatus, &QPushButton::clicked, this, &OverviewPage::handleOutOfSyncWarningClicks);
141  connect(ui->labelTransactionsStatus, &QPushButton::clicked, this, &OverviewPage::handleOutOfSyncWarningClicks);
142 }
143 
144 void OverviewPage::handleTransactionClicked(const QModelIndex &index)
145 {
146  if(filter)
147  Q_EMIT transactionClicked(filter->mapToSource(index));
148 }
149 
151 {
152  Q_EMIT outOfSyncWarningClicked();
153 }
154 
156 {
157  delete ui;
158 }
159 
161 {
162  int unit = walletModel->getOptionsModel()->getDisplayUnit();
163  m_balances = balances;
165  ui->labelBalance->setText(BitcoinUnits::formatWithUnit(unit, balances.watch_only_balance, false, BitcoinUnits::separatorAlways));
166  ui->labelUnconfirmed->setText(BitcoinUnits::formatWithUnit(unit, balances.unconfirmed_watch_only_balance, false, BitcoinUnits::separatorAlways));
167  ui->labelImmature->setText(BitcoinUnits::formatWithUnit(unit, balances.immature_watch_only_balance, false, BitcoinUnits::separatorAlways));
169  } else {
170  ui->labelBalance->setText(BitcoinUnits::formatWithUnit(unit, balances.balance, false, BitcoinUnits::separatorAlways));
171  ui->labelUnconfirmed->setText(BitcoinUnits::formatWithUnit(unit, balances.unconfirmed_balance, false, BitcoinUnits::separatorAlways));
172  ui->labelImmature->setText(BitcoinUnits::formatWithUnit(unit, balances.immature_balance, false, BitcoinUnits::separatorAlways));
173  ui->labelTotal->setText(BitcoinUnits::formatWithUnit(unit, balances.balance + balances.unconfirmed_balance + balances.immature_balance, false, BitcoinUnits::separatorAlways));
174  ui->labelWatchAvailable->setText(BitcoinUnits::formatWithUnit(unit, balances.watch_only_balance, false, BitcoinUnits::separatorAlways));
175  ui->labelWatchPending->setText(BitcoinUnits::formatWithUnit(unit, balances.unconfirmed_watch_only_balance, false, BitcoinUnits::separatorAlways));
176  ui->labelWatchImmature->setText(BitcoinUnits::formatWithUnit(unit, balances.immature_watch_only_balance, false, BitcoinUnits::separatorAlways));
178  }
179  // only show immature (newly mined) balance if it's non-zero, so as not to complicate things
180  // for the non-mining users
181  bool showImmature = balances.immature_balance != 0;
182  bool showWatchOnlyImmature = balances.immature_watch_only_balance != 0;
183 
184  // for symmetry reasons also show immature label when the watch-only one is shown
185  ui->labelImmature->setVisible(showImmature || showWatchOnlyImmature);
186  ui->labelImmatureText->setVisible(showImmature || showWatchOnlyImmature);
187  ui->labelWatchImmature->setVisible(!walletModel->privateKeysDisabled() && showWatchOnlyImmature); // show watch-only immature balance
188 }
189 
190 // show/hide watch-only labels
191 void OverviewPage::updateWatchOnlyLabels(bool showWatchOnly)
192 {
193  ui->labelSpendable->setVisible(showWatchOnly); // show spendable label (only when watch-only is active)
194  ui->labelWatchonly->setVisible(showWatchOnly); // show watch-only label
195  ui->lineWatchBalance->setVisible(showWatchOnly); // show watch-only balance separator line
196  ui->labelWatchAvailable->setVisible(showWatchOnly); // show watch-only available balance
197  ui->labelWatchPending->setVisible(showWatchOnly); // show watch-only pending balance
198  ui->labelWatchTotal->setVisible(showWatchOnly); // show watch-only total balance
199 
200  if (!showWatchOnly)
201  ui->labelWatchImmature->hide();
202 }
203 
205 {
206  this->clientModel = model;
207  if(model)
208  {
209  // Show warning if this is a prerelease version
212  }
213 }
214 
216 {
217  this->walletModel = model;
218  if(model && model->getOptionsModel())
219  {
220  // Set up transaction list
221  filter.reset(new TransactionFilterProxy());
222  filter->setSourceModel(model->getTransactionTableModel());
223  filter->setLimit(NUM_ITEMS);
224  filter->setDynamicSortFilter(true);
225  filter->setSortRole(Qt::EditRole);
226  filter->setShowInactive(false);
227  filter->sort(TransactionTableModel::Date, Qt::DescendingOrder);
228 
229  ui->listTransactions->setModel(filter.get());
230  ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress);
231 
232  // Keep up to date with wallet
233  interfaces::Wallet& wallet = model->wallet();
234  interfaces::WalletBalances balances = wallet.getBalances();
235  setBalance(balances);
236  connect(model, &WalletModel::balanceChanged, this, &OverviewPage::setBalance);
237 
239 
241  connect(model, &WalletModel::notifyWatchonlyChanged, [this](bool showWatchOnly) {
243  });
244  }
245 
246  // update the display unit, to not use the default ("BTC")
248 }
249 
251 {
253  {
254  if (m_balances.balance != -1) {
256  }
257 
258  // Update txdelegate->unit with the current unit
260 
261  ui->listTransactions->update();
262  }
263 }
264 
265 void OverviewPage::updateAlerts(const QString &warnings)
266 {
267  this->ui->labelAlerts->setVisible(!warnings.isEmpty());
268  this->ui->labelAlerts->setText(warnings);
269 }
270 
272 {
273  ui->labelWalletStatus->setVisible(fShow);
274  ui->labelTransactionsStatus->setVisible(fShow);
275 }
void setWalletModel(WalletModel *walletModel)
interfaces::Wallet & wallet() const
Definition: walletmodel.h:223
Bitcoin unit definitions.
Definition: bitcoinunits.h:47
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
QString dateTimeStr(const QDateTime &date)
Definition: guiutil.cpp:68
TxViewDelegate(const PlatformStyle *_platformStyle, QObject *parent=nullptr)
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
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:74
#define NUM_ITEMS
Collection of wallet balances.
Definition: wallet.h:311
void updateWatchOnlyLabels(bool showWatchOnly)
Interface for accessing a wallet.
Definition: wallet.h:47
bool privateKeysDisabled() const
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
CAmount immature_watch_only_balance
Definition: wallet.h:319
Date and time this transaction was created.
TransactionTableModel * getTransactionTableModel()
void displayUnitChanged(int unit)
#define COLOR_UNCONFIRMED
Definition: guiconstants.h:23
Model for Bitcoin network client.
Definition: clientmodel.h:44
ClientModel * clientModel
Definition: overviewpage.h:49
void transactionClicked(const QModelIndex &index)
const PlatformStyle * platformStyle
void showOutOfSyncWarning(bool fShow)
CAmount unconfirmed_watch_only_balance
Definition: wallet.h:318
Filter the transaction list according to pre-specified rules.
void updateDisplayUnit()
Interface to Bitcoin wallet from Qt view code.
Definition: walletmodel.h:125
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)
static QString formatWithUnit(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as string (with unit)
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:25
OptionsModel * getOptionsModel()