2018-07-27 00:36:45 +02:00
// Copyright (c) 2011-2018 The Bitcoin Core developers
2014-12-13 05:09:33 +01:00
// Distributed under the MIT software license, see the accompanying
2013-11-04 16:20:43 +01:00
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
2017-11-10 01:57:53 +01:00
# include <qt/overviewpage.h>
2017-08-15 17:31:26 +02:00
# include <qt/forms/ui_overviewpage.h>
2017-11-10 01:57:53 +01:00
# include <qt/bitcoinunits.h>
# include <qt/clientmodel.h>
# include <qt/guiconstants.h>
# include <qt/guiutil.h>
# include <qt/optionsmodel.h>
# include <qt/platformstyle.h>
# include <qt/transactionfilterproxy.h>
# include <qt/transactiontablemodel.h>
# include <qt/walletmodel.h>
2011-07-29 14:36:35 +02:00
2011-08-03 21:28:11 +02:00
# include <QAbstractItemDelegate>
2011-08-03 20:52:18 +02:00
# include <QPainter>
2015-05-05 21:55:19 +02:00
# define DECORATION_SIZE 54
# define NUM_ITEMS 5
2011-08-03 21:04:15 +02:00
2018-04-07 09:42:02 +02:00
Q_DECLARE_METATYPE ( interfaces : : WalletBalances )
2018-03-31 12:41:33 +02:00
2011-08-03 21:28:11 +02:00
class TxViewDelegate : public QAbstractItemDelegate
2011-08-03 20:52:18 +02:00
{
2011-09-19 12:40:23 +02:00
Q_OBJECT
2011-08-03 20:52:18 +02:00
public :
2017-08-01 12:22:41 +02:00
explicit TxViewDelegate ( const PlatformStyle * _platformStyle , QObject * parent = nullptr ) :
2016-11-18 15:47:20 +01:00
QAbstractItemDelegate ( parent ) , unit ( BitcoinUnits : : BTC ) ,
2016-09-09 13:43:29 +02:00
platformStyle ( _platformStyle )
2011-08-03 20:52:18 +02:00
{
}
inline void paint ( QPainter * painter , const QStyleOptionViewItem & option ,
const QModelIndex & index ) const
{
painter - > save ( ) ;
2014-11-06 20:55:52 +01:00
QIcon icon = qvariant_cast < QIcon > ( index . data ( TransactionTableModel : : RawDecorationRole ) ) ;
2011-08-03 20:52:18 +02:00
QRect mainRect = option . rect ;
QRect decorationRect ( mainRect . topLeft ( ) , QSize ( DECORATION_SIZE , DECORATION_SIZE ) ) ;
int xspace = DECORATION_SIZE + 8 ;
int ypad = 6 ;
int halfheight = ( mainRect . height ( ) - 2 * ypad ) / 2 ;
QRect amountRect ( mainRect . left ( ) + xspace , mainRect . top ( ) + ypad , mainRect . width ( ) - xspace , halfheight ) ;
QRect addressRect ( mainRect . left ( ) + xspace , mainRect . top ( ) + ypad + halfheight , mainRect . width ( ) - xspace , halfheight ) ;
2015-07-28 15:20:14 +02:00
icon = platformStyle - > SingleColorIcon ( icon ) ;
2011-08-03 20:52:18 +02:00
icon . paint ( painter , decorationRect ) ;
QDateTime date = index . data ( TransactionTableModel : : DateRole ) . toDateTime ( ) ;
QString address = index . data ( Qt : : DisplayRole ) . toString ( ) ;
qint64 amount = index . data ( TransactionTableModel : : AmountRole ) . toLongLong ( ) ;
bool confirmed = index . data ( TransactionTableModel : : ConfirmedRole ) . toBool ( ) ;
QVariant value = index . data ( Qt : : ForegroundRole ) ;
QColor foreground = option . palette . color ( QPalette : : Text ) ;
2013-04-14 19:50:15 +02:00
if ( value . canConvert < QBrush > ( ) )
2011-08-03 20:52:18 +02:00
{
2013-04-14 19:50:15 +02:00
QBrush brush = qvariant_cast < QBrush > ( value ) ;
foreground = brush . color ( ) ;
2011-08-03 20:52:18 +02:00
}
painter - > setPen ( foreground ) ;
2014-08-10 02:26:04 +02:00
QRect boundingRect ;
painter - > drawText ( addressRect , Qt : : AlignLeft | Qt : : AlignVCenter , address , & boundingRect ) ;
if ( index . data ( TransactionTableModel : : WatchonlyRole ) . toBool ( ) )
{
QIcon iconWatchonly = qvariant_cast < QIcon > ( index . data ( TransactionTableModel : : WatchonlyDecorationRole ) ) ;
QRect watchonlyRect ( boundingRect . right ( ) + 5 , mainRect . top ( ) + ypad + halfheight , 16 , halfheight ) ;
iconWatchonly . paint ( painter , watchonlyRect ) ;
}
2011-08-03 20:52:18 +02:00
if ( amount < 0 )
{
foreground = COLOR_NEGATIVE ;
}
2011-08-03 21:04:15 +02:00
else if ( ! confirmed )
{
foreground = COLOR_UNCONFIRMED ;
}
2011-08-03 20:52:18 +02:00
else
{
foreground = option . palette . color ( QPalette : : Text ) ;
}
painter - > setPen ( foreground ) ;
2014-07-07 23:27:09 +02:00
QString amountText = BitcoinUnits : : formatWithUnit ( unit , amount , true , BitcoinUnits : : separatorAlways ) ;
2011-08-03 20:52:18 +02:00
if ( ! confirmed )
{
amountText = QString ( " [ " ) + amountText + QString ( " ] " ) ;
}
painter - > drawText ( amountRect , Qt : : AlignRight | Qt : : AlignVCenter , amountText ) ;
painter - > setPen ( option . palette . color ( QPalette : : Text ) ) ;
2011-08-08 17:38:17 +02:00
painter - > drawText ( amountRect , Qt : : AlignLeft | Qt : : AlignVCenter , GUIUtil : : dateTimeStr ( date ) ) ;
2011-08-03 20:52:18 +02:00
painter - > restore ( ) ;
}
2011-08-03 21:28:11 +02:00
inline QSize sizeHint ( const QStyleOptionViewItem & option , const QModelIndex & index ) const
{
return QSize ( DECORATION_SIZE , DECORATION_SIZE ) ;
}
2011-08-03 20:52:18 +02:00
int unit ;
2015-07-28 15:20:14 +02:00
const PlatformStyle * platformStyle ;
2011-08-03 20:52:18 +02:00
} ;
2017-08-15 17:31:26 +02:00
# include <qt/overviewpage.moc>
2011-07-05 22:09:39 +02:00
2015-07-28 15:20:14 +02:00
OverviewPage : : OverviewPage ( const PlatformStyle * platformStyle , QWidget * parent ) :
2011-07-05 22:09:39 +02:00
QWidget ( parent ) ,
2011-07-29 14:36:35 +02:00
ui ( new Ui : : OverviewPage ) ,
2012-10-24 21:47:07 +02:00
clientModel ( 0 ) ,
walletModel ( 0 ) ,
2016-11-18 15:47:20 +01:00
txdelegate ( new TxViewDelegate ( platformStyle , this ) )
2011-07-05 22:09:39 +02:00
{
ui - > setupUi ( this ) ;
2018-03-31 12:41:33 +02:00
m_balances . balance = - 1 ;
2015-05-19 15:30:45 +02:00
// use a SingleColorIcon for the "out of sync warning" icon
2015-07-28 15:20:14 +02:00
QIcon icon = platformStyle - > SingleColorIcon ( " :/icons/warning " ) ;
2015-05-19 15:30:45 +02:00
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)
ui - > labelTransactionsStatus - > setIcon ( icon ) ;
ui - > labelWalletStatus - > setIcon ( icon ) ;
2011-08-03 20:52:18 +02:00
// Recent transactions
ui - > listTransactions - > setItemDelegate ( txdelegate ) ;
ui - > listTransactions - > setIconSize ( QSize ( DECORATION_SIZE , DECORATION_SIZE ) ) ;
2011-08-03 21:04:15 +02:00
ui - > listTransactions - > setMinimumHeight ( NUM_ITEMS * ( DECORATION_SIZE + 2 ) ) ;
2011-10-07 13:21:45 +02:00
ui - > listTransactions - > setAttribute ( Qt : : WA_MacShowFocusRect , false ) ;
2011-08-04 04:41:01 +02:00
2018-06-24 17:18:22 +02:00
connect ( ui - > listTransactions , & QListView : : clicked , this , & OverviewPage : : handleTransactionClicked ) ;
2012-05-15 16:57:59 +02:00
// start with displaying the "out of sync" warnings
showOutOfSyncWarning ( true ) ;
2018-06-24 17:18:22 +02:00
connect ( ui - > labelWalletStatus , & QPushButton : : clicked , this , & OverviewPage : : handleOutOfSyncWarningClicks ) ;
connect ( ui - > labelTransactionsStatus , & QPushButton : : clicked , this , & OverviewPage : : handleOutOfSyncWarningClicks ) ;
2012-05-12 13:19:44 +02:00
}
void OverviewPage : : handleTransactionClicked ( const QModelIndex & index )
{
if ( filter )
2015-07-14 13:59:05 +02:00
Q_EMIT transactionClicked ( filter - > mapToSource ( index ) ) ;
2011-07-05 22:09:39 +02:00
}
2016-07-19 15:27:14 +02:00
void OverviewPage : : handleOutOfSyncWarningClicks ( )
{
Q_EMIT outOfSyncWarningClicked ( ) ;
}
2011-07-05 22:09:39 +02:00
OverviewPage : : ~ OverviewPage ( )
{
delete ui ;
}
2018-04-07 09:42:02 +02:00
void OverviewPage : : setBalance ( const interfaces : : WalletBalances & balances )
2011-07-05 22:09:39 +02:00
{
2012-10-24 21:47:07 +02:00
int unit = walletModel - > getOptionsModel ( ) - > getDisplayUnit ( ) ;
2018-03-31 12:41:33 +02:00
m_balances = balances ;
2018-08-14 12:50:39 +02:00
if ( walletModel - > privateKeysDisabled ( ) ) {
ui - > labelBalance - > setText ( BitcoinUnits : : formatWithUnit ( unit , balances . watch_only_balance , false , BitcoinUnits : : separatorAlways ) ) ;
ui - > labelUnconfirmed - > setText ( BitcoinUnits : : formatWithUnit ( unit , balances . unconfirmed_watch_only_balance , false , BitcoinUnits : : separatorAlways ) ) ;
ui - > labelImmature - > setText ( BitcoinUnits : : formatWithUnit ( unit , balances . immature_watch_only_balance , false , BitcoinUnits : : separatorAlways ) ) ;
ui - > labelTotal - > setText ( BitcoinUnits : : formatWithUnit ( unit , balances . watch_only_balance + balances . unconfirmed_watch_only_balance + balances . immature_watch_only_balance , false , BitcoinUnits : : separatorAlways ) ) ;
} else {
ui - > labelBalance - > setText ( BitcoinUnits : : formatWithUnit ( unit , balances . balance , false , BitcoinUnits : : separatorAlways ) ) ;
ui - > labelUnconfirmed - > setText ( BitcoinUnits : : formatWithUnit ( unit , balances . unconfirmed_balance , false , BitcoinUnits : : separatorAlways ) ) ;
ui - > labelImmature - > setText ( BitcoinUnits : : formatWithUnit ( unit , balances . immature_balance , false , BitcoinUnits : : separatorAlways ) ) ;
ui - > labelTotal - > setText ( BitcoinUnits : : formatWithUnit ( unit , balances . balance + balances . unconfirmed_balance + balances . immature_balance , false , BitcoinUnits : : separatorAlways ) ) ;
ui - > labelWatchAvailable - > setText ( BitcoinUnits : : formatWithUnit ( unit , balances . watch_only_balance , false , BitcoinUnits : : separatorAlways ) ) ;
ui - > labelWatchPending - > setText ( BitcoinUnits : : formatWithUnit ( unit , balances . unconfirmed_watch_only_balance , false , BitcoinUnits : : separatorAlways ) ) ;
ui - > labelWatchImmature - > setText ( BitcoinUnits : : formatWithUnit ( unit , balances . immature_watch_only_balance , false , BitcoinUnits : : separatorAlways ) ) ;
ui - > labelWatchTotal - > setText ( BitcoinUnits : : formatWithUnit ( unit , balances . watch_only_balance + balances . unconfirmed_watch_only_balance + balances . immature_watch_only_balance , false , BitcoinUnits : : separatorAlways ) ) ;
}
2012-02-14 12:08:00 +01:00
// only show immature (newly mined) balance if it's non-zero, so as not to complicate things
// for the non-mining users
2018-03-31 12:41:33 +02:00
bool showImmature = balances . immature_balance ! = 0 ;
bool showWatchOnlyImmature = balances . immature_watch_only_balance ! = 0 ;
2014-03-29 05:15:28 +01:00
2014-08-04 13:50:17 +02:00
// for symmetry reasons also show immature label when the watch-only one is shown
2014-03-29 05:15:28 +01:00
ui - > labelImmature - > setVisible ( showImmature | | showWatchOnlyImmature ) ;
ui - > labelImmatureText - > setVisible ( showImmature | | showWatchOnlyImmature ) ;
2018-08-14 12:50:39 +02:00
ui - > labelWatchImmature - > setVisible ( ! walletModel - > privateKeysDisabled ( ) & & showWatchOnlyImmature ) ; // show watch-only immature balance
2014-07-26 21:05:11 +02:00
}
// show/hide watch-only labels
void OverviewPage : : updateWatchOnlyLabels ( bool showWatchOnly )
{
ui - > labelSpendable - > setVisible ( showWatchOnly ) ; // show spendable label (only when watch-only is active)
ui - > labelWatchonly - > setVisible ( showWatchOnly ) ; // show watch-only label
ui - > lineWatchBalance - > setVisible ( showWatchOnly ) ; // show watch-only balance separator line
ui - > labelWatchAvailable - > setVisible ( showWatchOnly ) ; // show watch-only available balance
ui - > labelWatchPending - > setVisible ( showWatchOnly ) ; // show watch-only pending balance
ui - > labelWatchTotal - > setVisible ( showWatchOnly ) ; // show watch-only total balance
if ( ! showWatchOnly )
ui - > labelWatchImmature - > hide ( ) ;
2011-07-05 22:09:39 +02:00
}
2011-07-07 10:59:00 +02:00
2012-10-24 21:47:07 +02:00
void OverviewPage : : setClientModel ( ClientModel * model )
2011-07-11 20:42:10 +02:00
{
2012-10-24 21:47:07 +02:00
this - > clientModel = model ;
if ( model )
{
// Show warning if this is a prerelease version
2018-06-24 17:18:22 +02:00
connect ( model , & ClientModel : : alertsChanged , this , & OverviewPage : : updateAlerts ) ;
2012-10-24 21:47:07 +02:00
updateAlerts ( model - > getStatusBarWarnings ( ) ) ;
}
}
void OverviewPage : : setWalletModel ( WalletModel * model )
{
this - > walletModel = model ;
2012-06-09 15:41:21 +02:00
if ( model & & model - > getOptionsModel ( ) )
2011-11-08 21:18:36 +01:00
{
// Set up transaction list
2016-11-18 15:47:20 +01:00
filter . reset ( new TransactionFilterProxy ( ) ) ;
2011-11-08 21:18:36 +01:00
filter - > setSourceModel ( model - > getTransactionTableModel ( ) ) ;
filter - > setLimit ( NUM_ITEMS ) ;
filter - > setDynamicSortFilter ( true ) ;
filter - > setSortRole ( Qt : : EditRole ) ;
2014-02-14 07:59:07 +01:00
filter - > setShowInactive ( false ) ;
2016-05-10 04:46:33 +02:00
filter - > sort ( TransactionTableModel : : Date , Qt : : DescendingOrder ) ;
2011-07-11 20:42:10 +02:00
2016-11-18 15:47:20 +01:00
ui - > listTransactions - > setModel ( filter . get ( ) ) ;
2011-11-08 21:18:36 +01:00
ui - > listTransactions - > setModelColumn ( TransactionTableModel : : ToAddress ) ;
2011-08-03 20:52:18 +02:00
2011-11-08 21:18:36 +01:00
// Keep up to date with wallet
2018-04-07 09:42:02 +02:00
interfaces : : Wallet & wallet = model - > wallet ( ) ;
interfaces : : WalletBalances balances = wallet . getBalances ( ) ;
2018-03-31 12:41:33 +02:00
setBalance ( balances ) ;
2018-06-24 17:18:22 +02:00
connect ( model , & WalletModel : : balanceChanged , this , & OverviewPage : : setBalance ) ;
2011-07-11 20:42:10 +02:00
2018-06-24 17:18:22 +02:00
connect ( model - > getOptionsModel ( ) , & OptionsModel : : displayUnitChanged , this , & OverviewPage : : updateDisplayUnit ) ;
2014-07-26 21:05:11 +02:00
2018-08-14 12:50:39 +02:00
updateWatchOnlyLabels ( wallet . haveWatchOnly ( ) & & ! model - > privateKeysDisabled ( ) ) ;
connect ( model , & WalletModel : : notifyWatchonlyChanged , [ this ] ( bool showWatchOnly ) {
updateWatchOnlyLabels ( showWatchOnly & & ! walletModel - > privateKeysDisabled ( ) ) ;
} ) ;
2011-11-08 21:18:36 +01:00
}
2012-06-09 15:41:21 +02:00
// update the display unit, to not use the default ("BTC")
updateDisplayUnit ( ) ;
2011-07-29 14:36:35 +02:00
}
2012-06-09 15:41:21 +02:00
void OverviewPage : : updateDisplayUnit ( )
2011-07-29 14:36:35 +02:00
{
2012-10-24 21:47:07 +02:00
if ( walletModel & & walletModel - > getOptionsModel ( ) )
2012-06-09 15:41:21 +02:00
{
2018-03-31 12:41:33 +02:00
if ( m_balances . balance ! = - 1 ) {
setBalance ( m_balances ) ;
}
2011-08-03 20:52:18 +02:00
2012-06-09 15:41:21 +02:00
// Update txdelegate->unit with the current unit
2012-10-24 21:47:07 +02:00
txdelegate - > unit = walletModel - > getOptionsModel ( ) - > getDisplayUnit ( ) ;
2012-06-09 15:41:21 +02:00
ui - > listTransactions - > update ( ) ;
}
2011-07-11 20:42:10 +02:00
}
2012-05-15 16:57:59 +02:00
2012-10-24 21:47:07 +02:00
void OverviewPage : : updateAlerts ( const QString & warnings )
{
this - > ui - > labelAlerts - > setVisible ( ! warnings . isEmpty ( ) ) ;
this - > ui - > labelAlerts - > setText ( warnings ) ;
}
2012-05-15 16:57:59 +02:00
void OverviewPage : : showOutOfSyncWarning ( bool fShow )
{
ui - > labelWalletStatus - > setVisible ( fShow ) ;
ui - > labelTransactionsStatus - > setVisible ( fShow ) ;
}