Dogecoin Core  1.14.2
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 "overviewpage.h"
6 #include "ui_overviewpage.h"
7 
8 #include "bitcoinunits.h"
9 #include "clientmodel.h"
10 #include "guiconstants.h"
11 #include "guiutil.h"
12 #include "optionsmodel.h"
13 #include "platformstyle.h"
14 #include "transactionfilterproxy.h"
15 #include "transactiontablemodel.h"
16 #include "walletmodel.h"
17 
18 #include <QAbstractItemDelegate>
19 #include <QPainter>
20 
21 #define DECORATION_SIZE 54
22 #define NUM_ITEMS 5
23 
24 class TxViewDelegate : public QAbstractItemDelegate
25 {
26  Q_OBJECT
27 public:
28  TxViewDelegate(const PlatformStyle *_platformStyle, QObject *parent=nullptr):
29  QAbstractItemDelegate(parent), unit(BitcoinUnits::BTC),
30  platformStyle(_platformStyle)
31  {
32 
33  }
34 
35  inline void paint(QPainter *painter, const QStyleOptionViewItem &option,
36  const QModelIndex &index ) const
37  {
38  painter->save();
39 
40  QIcon icon = qvariant_cast<QIcon>(index.data(TransactionTableModel::RawDecorationRole));
41  QRect mainRect = option.rect;
42  QRect decorationRect(mainRect.topLeft(), QSize(DECORATION_SIZE, DECORATION_SIZE));
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, mainRect.width() - xspace, halfheight);
47  QRect addressRect(mainRect.left() + xspace, mainRect.top()+ypad+halfheight, mainRect.width() - xspace, halfheight);
48  icon = platformStyle->SingleColorIcon(icon);
49  icon.paint(painter, decorationRect);
50 
51  QDateTime date = index.data(TransactionTableModel::DateRole).toDateTime();
52  QString address = index.data(Qt::DisplayRole).toString();
53  qint64 amount = index.data(TransactionTableModel::AmountRole).toLongLong();
54  bool confirmed = index.data(TransactionTableModel::ConfirmedRole).toBool();
55  QVariant value = index.data(Qt::ForegroundRole);
56  QColor foreground = option.palette.color(QPalette::Text);
57  if(value.canConvert<QBrush>())
58  {
59  QBrush brush = qvariant_cast<QBrush>(value);
60  foreground = brush.color();
61  }
62 
63  painter->setPen(foreground);
64  QRect boundingRect;
65  painter->drawText(addressRect, Qt::AlignLeft|Qt::AlignVCenter, address, &boundingRect);
66 
67  if (index.data(TransactionTableModel::WatchonlyRole).toBool())
68  {
69  QIcon iconWatchonly = qvariant_cast<QIcon>(index.data(TransactionTableModel::WatchonlyDecorationRole));
70  QRect watchonlyRect(boundingRect.right() + 5, mainRect.top()+ypad+halfheight, 16, halfheight);
71  iconWatchonly.paint(painter, watchonlyRect);
72  }
73 
74  if(amount < 0)
75  {
76  foreground = COLOR_NEGATIVE;
77  }
78  else if(!confirmed)
79  {
80  foreground = COLOR_UNCONFIRMED;
81  }
82  else
83  {
84  foreground = option.palette.color(QPalette::Text);
85  }
86  painter->setPen(foreground);
87  QString amountText = BitcoinUnits::formatWithUnit(unit, amount, true, BitcoinUnits::separatorAlways);
88  if(!confirmed)
89  {
90  amountText = QString("[") + amountText + QString("]");
91  }
92  painter->drawText(amountRect, Qt::AlignRight|Qt::AlignVCenter, amountText);
93 
94  painter->setPen(option.palette.color(QPalette::Text));
95  painter->drawText(amountRect, Qt::AlignLeft|Qt::AlignVCenter, GUIUtil::dateTimeStr(date));
96 
97  painter->restore();
98  }
99 
100  inline QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
101  {
102  return QSize(DECORATION_SIZE, DECORATION_SIZE);
103  }
104 
105  int unit;
107 
108 };
109 #include "overviewpage.moc"
110 
111 OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent) :
112  QWidget(parent),
113  ui(new Ui::OverviewPage),
114  clientModel(0),
115  walletModel(0),
116  currentBalance(-1),
117  currentUnconfirmedBalance(-1),
118  currentImmatureBalance(-1),
119  currentWatchOnlyBalance(-1),
120  currentWatchUnconfBalance(-1),
121  currentWatchImmatureBalance(-1),
122  txdelegate(new TxViewDelegate(platformStyle, this))
123 {
124  ui->setupUi(this);
125 
126  // use a SingleColorIcon for the "out of sync warning" icon
127  QIcon icon = platformStyle->SingleColorIcon(":/icons/warning");
128  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)
129  ui->labelTransactionsStatus->setIcon(icon);
130  ui->labelWalletStatus->setIcon(icon);
131 
132  // Recent transactions
133  ui->listTransactions->setItemDelegate(txdelegate);
134  ui->listTransactions->setIconSize(QSize(DECORATION_SIZE, DECORATION_SIZE));
135  ui->listTransactions->setMinimumHeight(NUM_ITEMS * (DECORATION_SIZE + 2));
136  ui->listTransactions->setAttribute(Qt::WA_MacShowFocusRect, false);
137 
138  connect(ui->listTransactions, SIGNAL(clicked(QModelIndex)), this, SLOT(handleTransactionClicked(QModelIndex)));
139 
140  // start with displaying the "out of sync" warnings
141  showOutOfSyncWarning(true);
142  connect(ui->labelWalletStatus, SIGNAL(clicked()), this, SLOT(handleOutOfSyncWarningClicks()));
143  connect(ui->labelTransactionsStatus, SIGNAL(clicked()), this, SLOT(handleOutOfSyncWarningClicks()));
144 }
145 
146 void OverviewPage::handleTransactionClicked(const QModelIndex &index)
147 {
148  if(filter)
149  Q_EMIT transactionClicked(filter->mapToSource(index));
150 }
151 
153 {
154  Q_EMIT outOfSyncWarningClicked();
155 }
156 
158 {
159  delete ui;
160 }
161 
162 void OverviewPage::setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance, const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance)
163 {
164  int unit = walletModel->getOptionsModel()->getDisplayUnit();
165  currentBalance = balance;
166  currentUnconfirmedBalance = unconfirmedBalance;
167  currentImmatureBalance = immatureBalance;
168  currentWatchOnlyBalance = watchOnlyBalance;
169  currentWatchUnconfBalance = watchUnconfBalance;
170  currentWatchImmatureBalance = watchImmatureBalance;
171  ui->labelBalance->setText(BitcoinUnits::formatWithUnit(unit, balance, false, BitcoinUnits::separatorAlways));
172  ui->labelUnconfirmed->setText(BitcoinUnits::formatWithUnit(unit, unconfirmedBalance, false, BitcoinUnits::separatorAlways));
173  ui->labelImmature->setText(BitcoinUnits::formatWithUnit(unit, immatureBalance, false, BitcoinUnits::separatorAlways));
174  ui->labelTotal->setText(BitcoinUnits::formatWithUnit(unit, balance + unconfirmedBalance + immatureBalance, false, BitcoinUnits::separatorAlways));
175  ui->labelWatchAvailable->setText(BitcoinUnits::formatWithUnit(unit, watchOnlyBalance, false, BitcoinUnits::separatorAlways));
176  ui->labelWatchPending->setText(BitcoinUnits::formatWithUnit(unit, watchUnconfBalance, false, BitcoinUnits::separatorAlways));
177  ui->labelWatchImmature->setText(BitcoinUnits::formatWithUnit(unit, watchImmatureBalance, false, BitcoinUnits::separatorAlways));
178  ui->labelWatchTotal->setText(BitcoinUnits::formatWithUnit(unit, watchOnlyBalance + watchUnconfBalance + watchImmatureBalance, false, BitcoinUnits::separatorAlways));
179 
180  // only show immature (newly mined) balance if it's non-zero, so as not to complicate things
181  // for the non-mining users
182  bool showImmature = immatureBalance != 0;
183  bool showWatchOnlyImmature = watchImmatureBalance != 0;
184 
185  // for symmetry reasons also show immature label when the watch-only one is shown
186  ui->labelImmature->setVisible(showImmature || showWatchOnlyImmature);
187  ui->labelImmatureText->setVisible(showImmature || showWatchOnlyImmature);
188  ui->labelWatchImmature->setVisible(showWatchOnlyImmature); // show watch-only immature balance
189 }
190 
191 // show/hide watch-only labels
192 void OverviewPage::updateWatchOnlyLabels(bool showWatchOnly)
193 {
194  ui->labelSpendable->setVisible(showWatchOnly); // show spendable label (only when watch-only is active)
195  ui->labelWatchonly->setVisible(showWatchOnly); // show watch-only label
196  ui->lineWatchBalance->setVisible(showWatchOnly); // show watch-only balance separator line
197  ui->labelWatchAvailable->setVisible(showWatchOnly); // show watch-only available balance
198  ui->labelWatchPending->setVisible(showWatchOnly); // show watch-only pending balance
199  ui->labelWatchTotal->setVisible(showWatchOnly); // show watch-only total balance
200 
201  if (!showWatchOnly)
202  ui->labelWatchImmature->hide();
203 }
204 
206 {
207  this->clientModel = model;
208  if(model)
209  {
210  // Show warning if this is a prerelease version
211  connect(model, SIGNAL(alertsChanged(QString)), this, SLOT(updateAlerts(QString)));
213  }
214 }
215 
217 {
218  this->walletModel = model;
219  if(model && model->getOptionsModel())
220  {
221  // Set up transaction list
222  filter.reset(new TransactionFilterProxy());
223  filter->setSourceModel(model->getTransactionTableModel());
224  filter->setLimit(NUM_ITEMS);
225  filter->setDynamicSortFilter(true);
226  filter->setSortRole(Qt::EditRole);
227  filter->setShowInactive(false);
228  filter->sort(TransactionTableModel::Date, Qt::DescendingOrder);
229 
230  ui->listTransactions->setModel(filter.get());
231  ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress);
232 
233  // Keep up to date with wallet
234  setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance(),
236  connect(model, SIGNAL(balanceChanged(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)), this, SLOT(setBalance(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)));
237 
238  connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
239 
241  connect(model, SIGNAL(notifyWatchonlyChanged(bool)), this, SLOT(updateWatchOnlyLabels(bool)));
242  }
243 
244  // update the display unit, to not use the default ("BTC")
246 }
247 
249 {
251  {
252  if(currentBalance != -1)
255 
256  // Update txdelegate->unit with the current unit
258 
259  ui->listTransactions->update();
260  }
261 }
262 
263 void OverviewPage::updateAlerts(const QString &warnings)
264 {
265  this->ui->labelAlerts->setVisible(!warnings.isEmpty());
266  this->ui->labelAlerts->setText(warnings);
267 }
268 
270 {
271  ui->labelWalletStatus->setVisible(fShow);
272  ui->labelTransactionsStatus->setVisible(fShow);
273 }
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:15
Bitcoin unit definitions.
Definition: bitcoinunits.h:48
static QString formatWithUnit(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as string (with unit)
Model for Bitcoin network client.
Definition: clientmodel.h:42
QString getStatusBarWarnings() const
Return warnings to be displayed in status bar.
int getDisplayUnit()
Definition: optionsmodel.h:65
Overview ("home") page widget.
Definition: overviewpage.h:29
void updateDisplayUnit()
CAmount currentImmatureBalance
Definition: overviewpage.h:54
CAmount currentWatchOnlyBalance
Definition: overviewpage.h:55
void setWalletModel(WalletModel *walletModel)
CAmount currentWatchUnconfBalance
Definition: overviewpage.h:56
void updateAlerts(const QString &warnings)
void updateWatchOnlyLabels(bool showWatchOnly)
void setClientModel(ClientModel *clientModel)
WalletModel * walletModel
Definition: overviewpage.h:51
Ui::OverviewPage * ui
Definition: overviewpage.h:49
CAmount currentWatchImmatureBalance
Definition: overviewpage.h:57
void handleTransactionClicked(const QModelIndex &index)
void transactionClicked(const QModelIndex &index)
OverviewPage(const PlatformStyle *platformStyle, QWidget *parent=0)
CAmount currentUnconfirmedBalance
Definition: overviewpage.h:53
void handleOutOfSyncWarningClicks()
CAmount currentBalance
Definition: overviewpage.h:52
std::unique_ptr< TransactionFilterProxy > filter
Definition: overviewpage.h:60
void outOfSyncWarningClicked()
void showOutOfSyncWarning(bool fShow)
ClientModel * clientModel
Definition: overviewpage.h:50
void setBalance(const CAmount &balance, const CAmount &unconfirmedBalance, const CAmount &immatureBalance, const CAmount &watchOnlyBalance, const CAmount &watchUnconfBalance, const CAmount &watchImmatureBalance)
TxViewDelegate * txdelegate
Definition: overviewpage.h:59
QIcon SingleColorIcon(const QString &filename) const
Colorize an icon (given filename) with the icon color.
Filter the transaction list according to pre-specified rules.
@ DateRole
Date and time this transaction was created.
@ RawDecorationRole
Unprocessed icon.
@ WatchonlyDecorationRole
Watch-only icon.
@ WatchonlyRole
Watch-only boolean.
@ AmountRole
Net amount of transaction.
@ ConfirmedRole
Is transaction confirmed?
TxViewDelegate(const PlatformStyle *_platformStyle, QObject *parent=nullptr)
const PlatformStyle * platformStyle
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
Interface to Bitcoin wallet from Qt view code.
Definition: walletmodel.h:99
CAmount getBalance(const CCoinControl *coinControl=NULL) const
Definition: walletmodel.cpp:62
CAmount getUnconfirmedBalance() const
Definition: walletmodel.cpp:79
CAmount getWatchUnconfirmedBalance() const
Definition: walletmodel.cpp:99
CAmount getWatchBalance() const
Definition: walletmodel.cpp:94
OptionsModel * getOptionsModel()
CAmount getWatchImmatureBalance() const
bool haveWatchOnly() const
Definition: walletmodel.cpp:89
CAmount getImmatureBalance() const
Definition: walletmodel.cpp:84
TransactionTableModel * getTransactionTableModel()
#define COLOR_UNCONFIRMED
Definition: guiconstants.h:23
#define COLOR_NEGATIVE
Definition: guiconstants.h:25
QString dateTimeStr(const QDateTime &date)
Definition: guiutil.cpp:86
#define DECORATION_SIZE
#define NUM_ITEMS