2015-12-13 17:58:29 +01:00
// Copyright (c) 2011-2015 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.
2011-05-12 14:49:42 +02:00
# include "sendcoinsdialog.h"
2011-05-12 14:44:52 +02:00
# include "ui_sendcoinsdialog.h"
2013-01-23 21:51:02 +01:00
2013-11-16 17:37:31 +01:00
# include "addresstablemodel.h"
2011-07-25 21:35:45 +02:00
# include "bitcoinunits.h"
2014-11-02 00:14:47 +01:00
# include "clientmodel.h"
2013-11-16 17:37:31 +01:00
# include "coincontroldialog.h"
2013-04-13 07:13:08 +02:00
# include "guiutil.h"
2011-06-01 09:34:12 +02:00
# include "optionsmodel.h"
2015-07-28 15:20:14 +02:00
# include "platformstyle.h"
2011-07-16 19:01:05 +02:00
# include "sendcoinsentry.h"
2013-04-13 07:13:08 +02:00
# include "walletmodel.h"
2012-08-07 19:19:14 +02:00
# include "base58.h"
2013-08-12 17:03:03 +02:00
# include "coincontrol.h"
2015-07-05 14:30:07 +02:00
# include "main.h" // mempool and minRelayTxFee
2013-11-16 17:37:31 +01:00
# include "ui_interface.h"
2015-07-05 14:17:46 +02:00
# include "txmempool.h"
2015-02-03 21:09:47 +01:00
# include "wallet/wallet.h"
2011-05-12 17:55:24 +02:00
2011-05-15 19:31:20 +02:00
# include <QMessageBox>
2011-12-07 06:00:04 +01:00
# include <QScrollBar>
2014-11-02 00:14:47 +01:00
# include <QSettings>
2013-04-13 07:13:08 +02:00
# include <QTextDocument>
2016-05-10 04:26:57 +02:00
# include <QTimer>
# define SEND_CONFIRM_DELAY 3
2011-05-12 20:16:42 +02:00
2015-07-28 15:20:14 +02:00
SendCoinsDialog : : SendCoinsDialog ( const PlatformStyle * platformStyle , QWidget * parent ) :
2011-05-12 14:44:52 +02:00
QDialog ( parent ) ,
2011-05-30 20:20:12 +02:00
ui ( new Ui : : SendCoinsDialog ) ,
2014-11-20 13:06:10 +01:00
clientModel ( 0 ) ,
model ( 0 ) ,
fNewRecipientAllowed ( true ) ,
2015-07-28 15:20:14 +02:00
fFeeMinimized ( true ) ,
platformStyle ( platformStyle )
2011-05-12 14:44:52 +02:00
{
ui - > setupUi ( this ) ;
2011-07-08 19:25:35 +02:00
2015-07-28 15:20:14 +02:00
if ( ! platformStyle - > getImagesOnButtons ( ) ) {
ui - > addButton - > setIcon ( QIcon ( ) ) ;
ui - > clearButton - > setIcon ( QIcon ( ) ) ;
ui - > sendButton - > setIcon ( QIcon ( ) ) ;
} else {
ui - > addButton - > setIcon ( platformStyle - > SingleColorIcon ( " :/icons/add " ) ) ;
ui - > clearButton - > setIcon ( platformStyle - > SingleColorIcon ( " :/icons/remove " ) ) ;
ui - > sendButton - > setIcon ( platformStyle - > SingleColorIcon ( " :/icons/send " ) ) ;
}
2013-11-20 15:56:51 +01:00
GUIUtil : : setupAddressWidget ( ui - > lineEditCoinControlChange , this ) ;
2011-10-07 13:21:45 +02:00
2011-07-16 19:01:05 +02:00
addEntry ( ) ;
2011-05-15 19:31:20 +02:00
2011-07-16 19:01:05 +02:00
connect ( ui - > addButton , SIGNAL ( clicked ( ) ) , this , SLOT ( addEntry ( ) ) ) ;
2011-09-27 16:46:19 +02:00
connect ( ui - > clearButton , SIGNAL ( clicked ( ) ) , this , SLOT ( clear ( ) ) ) ;
2011-12-24 05:27:12 +01:00
2013-08-12 17:03:03 +02:00
// Coin Control
connect ( ui - > pushButtonCoinControl , SIGNAL ( clicked ( ) ) , this , SLOT ( coinControlButtonClicked ( ) ) ) ;
connect ( ui - > checkBoxCoinControlChange , SIGNAL ( stateChanged ( int ) ) , this , SLOT ( coinControlChangeChecked ( int ) ) ) ;
connect ( ui - > lineEditCoinControlChange , SIGNAL ( textEdited ( const QString & ) ) , this , SLOT ( coinControlChangeEdited ( const QString & ) ) ) ;
// Coin Control: clipboard actions
QAction * clipboardQuantityAction = new QAction ( tr ( " Copy quantity " ) , this ) ;
QAction * clipboardAmountAction = new QAction ( tr ( " Copy amount " ) , this ) ;
QAction * clipboardFeeAction = new QAction ( tr ( " Copy fee " ) , this ) ;
QAction * clipboardAfterFeeAction = new QAction ( tr ( " Copy after fee " ) , this ) ;
QAction * clipboardBytesAction = new QAction ( tr ( " Copy bytes " ) , this ) ;
2014-06-08 01:05:53 +02:00
QAction * clipboardLowOutputAction = new QAction ( tr ( " Copy dust " ) , this ) ;
2013-08-12 17:03:03 +02:00
QAction * clipboardChangeAction = new QAction ( tr ( " Copy change " ) , this ) ;
connect ( clipboardQuantityAction , SIGNAL ( triggered ( ) ) , this , SLOT ( coinControlClipboardQuantity ( ) ) ) ;
connect ( clipboardAmountAction , SIGNAL ( triggered ( ) ) , this , SLOT ( coinControlClipboardAmount ( ) ) ) ;
connect ( clipboardFeeAction , SIGNAL ( triggered ( ) ) , this , SLOT ( coinControlClipboardFee ( ) ) ) ;
connect ( clipboardAfterFeeAction , SIGNAL ( triggered ( ) ) , this , SLOT ( coinControlClipboardAfterFee ( ) ) ) ;
connect ( clipboardBytesAction , SIGNAL ( triggered ( ) ) , this , SLOT ( coinControlClipboardBytes ( ) ) ) ;
connect ( clipboardLowOutputAction , SIGNAL ( triggered ( ) ) , this , SLOT ( coinControlClipboardLowOutput ( ) ) ) ;
connect ( clipboardChangeAction , SIGNAL ( triggered ( ) ) , this , SLOT ( coinControlClipboardChange ( ) ) ) ;
ui - > labelCoinControlQuantity - > addAction ( clipboardQuantityAction ) ;
ui - > labelCoinControlAmount - > addAction ( clipboardAmountAction ) ;
ui - > labelCoinControlFee - > addAction ( clipboardFeeAction ) ;
ui - > labelCoinControlAfterFee - > addAction ( clipboardAfterFeeAction ) ;
ui - > labelCoinControlBytes - > addAction ( clipboardBytesAction ) ;
ui - > labelCoinControlLowOutput - > addAction ( clipboardLowOutputAction ) ;
ui - > labelCoinControlChange - > addAction ( clipboardChangeAction ) ;
2014-11-02 00:14:47 +01:00
// init transaction fee section
QSettings settings ;
if ( ! settings . contains ( " fFeeSectionMinimized " ) )
settings . setValue ( " fFeeSectionMinimized " , true ) ;
if ( ! settings . contains ( " nFeeRadio " ) & & settings . contains ( " nTransactionFee " ) & & settings . value ( " nTransactionFee " ) . toLongLong ( ) > 0 ) // compatibility
settings . setValue ( " nFeeRadio " , 1 ) ; // custom
if ( ! settings . contains ( " nFeeRadio " ) )
settings . setValue ( " nFeeRadio " , 0 ) ; // recommended
if ( ! settings . contains ( " nCustomFeeRadio " ) & & settings . contains ( " nTransactionFee " ) & & settings . value ( " nTransactionFee " ) . toLongLong ( ) > 0 ) // compatibility
settings . setValue ( " nCustomFeeRadio " , 1 ) ; // total at least
if ( ! settings . contains ( " nCustomFeeRadio " ) )
settings . setValue ( " nCustomFeeRadio " , 0 ) ; // per kilobyte
if ( ! settings . contains ( " nSmartFeeSliderPosition " ) )
settings . setValue ( " nSmartFeeSliderPosition " , 0 ) ;
if ( ! settings . contains ( " nTransactionFee " ) )
settings . setValue ( " nTransactionFee " , ( qint64 ) DEFAULT_TRANSACTION_FEE ) ;
if ( ! settings . contains ( " fPayOnlyMinFee " ) )
settings . setValue ( " fPayOnlyMinFee " , false ) ;
ui - > groupFee - > setId ( ui - > radioSmartFee , 0 ) ;
ui - > groupFee - > setId ( ui - > radioCustomFee , 1 ) ;
ui - > groupFee - > button ( ( int ) std : : max ( 0 , std : : min ( 1 , settings . value ( " nFeeRadio " ) . toInt ( ) ) ) ) - > setChecked ( true ) ;
ui - > groupCustomFee - > setId ( ui - > radioCustomPerKilobyte , 0 ) ;
ui - > groupCustomFee - > setId ( ui - > radioCustomAtLeast , 1 ) ;
ui - > groupCustomFee - > button ( ( int ) std : : max ( 0 , std : : min ( 1 , settings . value ( " nCustomFeeRadio " ) . toInt ( ) ) ) ) - > setChecked ( true ) ;
ui - > sliderSmartFee - > setValue ( settings . value ( " nSmartFeeSliderPosition " ) . toInt ( ) ) ;
ui - > customFee - > setValue ( settings . value ( " nTransactionFee " ) . toLongLong ( ) ) ;
ui - > checkBoxMinimumFee - > setChecked ( settings . value ( " fPayOnlyMinFee " ) . toBool ( ) ) ;
minimizeFeeSection ( settings . value ( " fFeeSectionMinimized " ) . toBool ( ) ) ;
2011-05-12 14:44:52 +02:00
}
2014-11-02 00:14:47 +01:00
void SendCoinsDialog : : setClientModel ( ClientModel * clientModel )
{
this - > clientModel = clientModel ;
2014-11-20 13:06:10 +01:00
if ( clientModel ) {
2016-04-28 16:18:45 +02:00
connect ( clientModel , SIGNAL ( numBlocksChanged ( int , QDateTime , double , bool ) ) , this , SLOT ( updateSmartFeeLabel ( ) ) ) ;
2014-11-20 13:06:10 +01:00
}
2014-11-02 00:14:47 +01:00
}
2011-06-30 18:05:29 +02:00
void SendCoinsDialog : : setModel ( WalletModel * model )
2011-05-30 20:20:12 +02:00
{
this - > model = model ;
2011-07-16 19:01:05 +02:00
2013-08-23 13:07:20 +02:00
if ( model & & model - > getOptionsModel ( ) )
2011-07-16 19:01:05 +02:00
{
2013-08-23 13:07:20 +02:00
for ( int i = 0 ; i < ui - > entries - > count ( ) ; + + i )
2011-07-16 19:01:05 +02:00
{
2013-08-23 13:07:20 +02:00
SendCoinsEntry * entry = qobject_cast < SendCoinsEntry * > ( ui - > entries - > itemAt ( i ) - > widget ( ) ) ;
if ( entry )
{
entry - > setModel ( model ) ;
}
2011-07-16 19:01:05 +02:00
}
2013-08-23 13:07:20 +02:00
2014-03-29 05:15:28 +01:00
setBalance ( model - > getBalance ( ) , model - > getUnconfirmedBalance ( ) , model - > getImmatureBalance ( ) ,
model - > getWatchBalance ( ) , model - > getWatchUnconfirmedBalance ( ) , model - > getWatchImmatureBalance ( ) ) ;
2014-10-01 10:09:08 +02:00
connect ( model , SIGNAL ( balanceChanged ( CAmount , CAmount , CAmount , CAmount , CAmount , CAmount ) ) , this , SLOT ( setBalance ( CAmount , CAmount , CAmount , CAmount , CAmount , CAmount ) ) ) ;
2012-06-09 15:41:21 +02:00
connect ( model - > getOptionsModel ( ) , SIGNAL ( displayUnitChanged ( int ) ) , this , SLOT ( updateDisplayUnit ( ) ) ) ;
2014-11-02 00:14:47 +01:00
updateDisplayUnit ( ) ;
2013-08-12 17:03:03 +02:00
// Coin Control
connect ( model - > getOptionsModel ( ) , SIGNAL ( displayUnitChanged ( int ) ) , this , SLOT ( coinControlUpdateLabels ( ) ) ) ;
connect ( model - > getOptionsModel ( ) , SIGNAL ( coinControlFeaturesChanged ( bool ) ) , this , SLOT ( coinControlFeatureChanged ( bool ) ) ) ;
ui - > frameCoinControl - > setVisible ( model - > getOptionsModel ( ) - > getCoinControlFeatures ( ) ) ;
coinControlUpdateLabels ( ) ;
2014-11-02 00:14:47 +01:00
// fee section
connect ( ui - > sliderSmartFee , SIGNAL ( valueChanged ( int ) ) , this , SLOT ( updateSmartFeeLabel ( ) ) ) ;
connect ( ui - > sliderSmartFee , SIGNAL ( valueChanged ( int ) ) , this , SLOT ( updateGlobalFeeVariables ( ) ) ) ;
connect ( ui - > sliderSmartFee , SIGNAL ( valueChanged ( int ) ) , this , SLOT ( coinControlUpdateLabels ( ) ) ) ;
connect ( ui - > groupFee , SIGNAL ( buttonClicked ( int ) ) , this , SLOT ( updateFeeSectionControls ( ) ) ) ;
connect ( ui - > groupFee , SIGNAL ( buttonClicked ( int ) ) , this , SLOT ( updateGlobalFeeVariables ( ) ) ) ;
connect ( ui - > groupFee , SIGNAL ( buttonClicked ( int ) ) , this , SLOT ( coinControlUpdateLabels ( ) ) ) ;
connect ( ui - > groupCustomFee , SIGNAL ( buttonClicked ( int ) ) , this , SLOT ( updateGlobalFeeVariables ( ) ) ) ;
connect ( ui - > groupCustomFee , SIGNAL ( buttonClicked ( int ) ) , this , SLOT ( coinControlUpdateLabels ( ) ) ) ;
connect ( ui - > customFee , SIGNAL ( valueChanged ( ) ) , this , SLOT ( updateGlobalFeeVariables ( ) ) ) ;
connect ( ui - > customFee , SIGNAL ( valueChanged ( ) ) , this , SLOT ( coinControlUpdateLabels ( ) ) ) ;
connect ( ui - > checkBoxMinimumFee , SIGNAL ( stateChanged ( int ) ) , this , SLOT ( setMinimumFee ( ) ) ) ;
connect ( ui - > checkBoxMinimumFee , SIGNAL ( stateChanged ( int ) ) , this , SLOT ( updateFeeSectionControls ( ) ) ) ;
connect ( ui - > checkBoxMinimumFee , SIGNAL ( stateChanged ( int ) ) , this , SLOT ( updateGlobalFeeVariables ( ) ) ) ;
connect ( ui - > checkBoxMinimumFee , SIGNAL ( stateChanged ( int ) ) , this , SLOT ( coinControlUpdateLabels ( ) ) ) ;
2015-10-25 02:47:04 +02:00
ui - > customFee - > setSingleStep ( CWallet : : GetRequiredFee ( 1000 ) ) ;
2014-11-02 00:14:47 +01:00
updateFeeSectionControls ( ) ;
updateMinFeeLabel ( ) ;
updateSmartFeeLabel ( ) ;
updateGlobalFeeVariables ( ) ;
2011-11-08 21:18:36 +01:00
}
2011-05-30 20:20:12 +02:00
}
2011-05-12 14:44:52 +02:00
SendCoinsDialog : : ~ SendCoinsDialog ( )
{
2014-11-02 00:14:47 +01:00
QSettings settings ;
settings . setValue ( " fFeeSectionMinimized " , fFeeMinimized ) ;
settings . setValue ( " nFeeRadio " , ui - > groupFee - > checkedId ( ) ) ;
settings . setValue ( " nCustomFeeRadio " , ui - > groupCustomFee - > checkedId ( ) ) ;
settings . setValue ( " nSmartFeeSliderPosition " , ui - > sliderSmartFee - > value ( ) ) ;
settings . setValue ( " nTransactionFee " , ( qint64 ) ui - > customFee - > value ( ) ) ;
settings . setValue ( " fPayOnlyMinFee " , ui - > checkBoxMinimumFee - > isChecked ( ) ) ;
2011-05-12 14:44:52 +02:00
delete ui ;
}
2011-05-12 17:55:24 +02:00
void SendCoinsDialog : : on_sendButton_clicked ( )
{
2013-08-24 15:07:17 +02:00
if ( ! model | | ! model - > getOptionsModel ( ) )
return ;
2011-07-16 19:01:05 +02:00
QList < SendCoinsRecipient > recipients ;
bool valid = true ;
2011-11-08 21:18:36 +01:00
2011-07-16 19:01:05 +02:00
for ( int i = 0 ; i < ui - > entries - > count ( ) ; + + i )
{
SendCoinsEntry * entry = qobject_cast < SendCoinsEntry * > ( ui - > entries - > itemAt ( i ) - > widget ( ) ) ;
if ( entry )
{
if ( entry - > validate ( ) )
{
recipients . append ( entry - > getValue ( ) ) ;
}
else
{
valid = false ;
}
}
}
2011-05-30 20:20:12 +02:00
2011-07-16 19:01:05 +02:00
if ( ! valid | | recipients . isEmpty ( ) )
2011-05-14 17:25:05 +02:00
{
2011-05-15 19:31:20 +02:00
return ;
2011-05-14 17:25:05 +02:00
}
2011-05-27 21:43:05 +02:00
2014-06-10 03:14:13 +02:00
fNewRecipientAllowed = false ;
WalletModel : : UnlockContext ctx ( model - > requestUnlock ( ) ) ;
if ( ! ctx . isValid ( ) )
{
// Unlock wallet was cancelled
fNewRecipientAllowed = true ;
return ;
}
// prepare transaction for getting txFee earlier
WalletModelTransaction currentTransaction ( recipients ) ;
WalletModel : : SendCoinsReturn prepareStatus ;
if ( model - > getOptionsModel ( ) - > getCoinControlFeatures ( ) ) // coin control enabled
prepareStatus = model - > prepareTransaction ( currentTransaction , CoinControlDialog : : coinControl ) ;
else
prepareStatus = model - > prepareTransaction ( currentTransaction ) ;
// process prepareStatus and on error generate message shown to user
processSendCoinsReturn ( prepareStatus ,
BitcoinUnits : : formatWithUnit ( model - > getOptionsModel ( ) - > getDisplayUnit ( ) , currentTransaction . getTransactionFee ( ) ) ) ;
if ( prepareStatus . status ! = WalletModel : : OK ) {
fNewRecipientAllowed = true ;
return ;
}
CAmount txFee = currentTransaction . getTransactionFee ( ) ;
2011-07-16 19:01:05 +02:00
// Format confirmation message
QStringList formatted ;
2015-07-14 13:59:05 +02:00
Q_FOREACH ( const SendCoinsRecipient & rcp , currentTransaction . getRecipients ( ) )
2011-07-16 19:01:05 +02:00
{
2013-09-13 16:49:35 +02:00
// generate bold amount string
2014-05-10 00:50:09 +02:00
QString amount = " <b> " + BitcoinUnits : : formatHtmlWithUnit ( model - > getOptionsModel ( ) - > getDisplayUnit ( ) , rcp . amount ) ;
2013-09-13 16:49:35 +02:00
amount . append ( " </b> " ) ;
// generate monospace address string
QString address = " <span style='font-family: monospace;'> " + rcp . address ;
address . append ( " </span> " ) ;
QString recipientElement ;
2013-10-24 16:02:39 +02:00
if ( ! rcp . paymentRequest . IsInitialized ( ) ) // normal payment
2013-07-22 08:50:39 +02:00
{
2013-09-13 16:49:35 +02:00
if ( rcp . label . length ( ) > 0 ) // label with address
2013-08-30 20:04:48 +02:00
{
2013-09-13 16:49:35 +02:00
recipientElement = tr ( " %1 to %2 " ) . arg ( amount , GUIUtil : : HtmlEscape ( rcp . label ) ) ;
recipientElement . append ( QString ( " (%1) " ) . arg ( address ) ) ;
2013-08-30 20:04:48 +02:00
}
2013-09-13 16:49:35 +02:00
else // just address
2013-08-30 20:04:48 +02:00
{
2013-09-13 16:49:35 +02:00
recipientElement = tr ( " %1 to %2 " ) . arg ( amount , address ) ;
2013-08-30 20:04:48 +02:00
}
2013-07-22 08:50:39 +02:00
}
2015-03-18 11:22:27 +01:00
else if ( ! rcp . authenticatedMerchant . isEmpty ( ) ) // authenticated payment request
2013-07-22 08:50:39 +02:00
{
2013-09-13 16:49:35 +02:00
recipientElement = tr ( " %1 to %2 " ) . arg ( amount , GUIUtil : : HtmlEscape ( rcp . authenticatedMerchant ) ) ;
2013-07-22 08:50:39 +02:00
}
2015-03-18 11:22:27 +01:00
else // unauthenticated payment request
2013-10-24 16:02:39 +02:00
{
recipientElement = tr ( " %1 to %2 " ) . arg ( amount , address ) ;
}
2013-09-13 16:49:35 +02:00
formatted . append ( recipientElement ) ;
2011-07-16 19:01:05 +02:00
}
2011-06-25 19:32:36 +02:00
2013-08-30 20:04:48 +02:00
QString questionString = tr ( " Are you sure you want to send? " ) ;
questionString . append ( " <br /><br />%1 " ) ;
if ( txFee > 0 )
{
// append fee string if a fee is required
questionString . append ( " <hr /><span style='color:#aa0000;'> " ) ;
2014-05-10 00:50:09 +02:00
questionString . append ( BitcoinUnits : : formatHtmlWithUnit ( model - > getOptionsModel ( ) - > getDisplayUnit ( ) , txFee ) ) ;
2013-08-30 20:04:48 +02:00
questionString . append ( " </span> " ) ;
questionString . append ( tr ( " added as transaction fee " ) ) ;
2014-11-02 00:14:47 +01:00
// append transaction size
questionString . append ( " ( " + QString : : number ( ( double ) currentTransaction . getTransactionSize ( ) / 1000 ) + " kB) " ) ;
2013-08-30 20:04:48 +02:00
}
2013-11-17 14:43:23 +01:00
// add total amount in all subdivision units
questionString . append ( " <hr /> " ) ;
2014-04-23 00:46:19 +02:00
CAmount totalAmount = currentTransaction . getTotalTransactionAmount ( ) + txFee ;
2013-11-17 14:43:23 +01:00
QStringList alternativeUnits ;
2015-07-14 13:59:05 +02:00
Q_FOREACH ( BitcoinUnits : : Unit u , BitcoinUnits : : availableUnits ( ) )
2013-08-30 20:04:48 +02:00
{
2013-11-17 14:43:23 +01:00
if ( u ! = model - > getOptionsModel ( ) - > getDisplayUnit ( ) )
2014-05-10 00:50:09 +02:00
alternativeUnits . append ( BitcoinUnits : : formatHtmlWithUnit ( u , totalAmount ) ) ;
2013-08-30 20:04:48 +02:00
}
2015-11-06 13:22:00 +01:00
questionString . append ( tr ( " Total Amount %1 " )
. arg ( BitcoinUnits : : formatHtmlWithUnit ( model - > getOptionsModel ( ) - > getDisplayUnit ( ) , totalAmount ) ) ) ;
questionString . append ( QString ( " <span style='font-size:10pt;font-weight:normal;'><br />(=%2)</span> " )
2015-09-18 13:51:28 +02:00
. arg ( alternativeUnits . join ( " " + tr ( " or " ) + " <br /> " ) ) ) ;
2013-08-30 20:04:48 +02:00
2016-05-10 04:26:57 +02:00
SendConfirmationDialog confirmationDialog ( tr ( " Confirm send coins " ) ,
questionString . arg ( formatted . join ( " <br /> " ) ) , SEND_CONFIRM_DELAY , this ) ;
confirmationDialog . exec ( ) ;
QMessageBox : : StandardButton retval = ( QMessageBox : : StandardButton ) confirmationDialog . result ( ) ;
2013-08-30 20:04:48 +02:00
if ( retval ! = QMessageBox : : Yes )
{
fNewRecipientAllowed = true ;
return ;
}
// now send the prepared transaction
2013-10-30 15:37:41 +01:00
WalletModel : : SendCoinsReturn sendStatus = model - > sendCoins ( currentTransaction ) ;
// process sendStatus and on error generate message shown to user
processSendCoinsReturn ( sendStatus ) ;
if ( sendStatus . status = = WalletModel : : OK )
2013-08-30 20:04:48 +02:00
{
2011-05-31 22:24:53 +02:00
accept ( ) ;
2013-08-12 17:03:03 +02:00
CoinControlDialog : : coinControl - > UnSelectAll ( ) ;
coinControlUpdateLabels ( ) ;
2011-05-14 17:25:05 +02:00
}
2011-12-24 05:27:12 +01:00
fNewRecipientAllowed = true ;
2011-05-12 17:55:24 +02:00
}
2011-07-16 19:01:05 +02:00
void SendCoinsDialog : : clear ( )
2011-05-12 17:55:24 +02:00
{
2011-07-16 19:01:05 +02:00
// Remove entries until only one left
2011-08-07 16:04:48 +02:00
while ( ui - > entries - > count ( ) )
2011-07-16 19:01:05 +02:00
{
2013-12-04 08:17:57 +01:00
ui - > entries - > takeAt ( 0 ) - > widget ( ) - > deleteLater ( ) ;
2011-07-16 19:01:05 +02:00
}
2011-08-07 16:04:48 +02:00
addEntry ( ) ;
2011-05-13 22:00:27 +02:00
2013-11-22 13:53:05 +01:00
updateTabsAndLabels ( ) ;
2011-07-07 17:33:15 +02:00
}
void SendCoinsDialog : : reject ( )
{
clear ( ) ;
}
void SendCoinsDialog : : accept ( )
{
clear ( ) ;
}
2011-07-16 19:01:05 +02:00
2011-08-07 16:04:48 +02:00
SendCoinsEntry * SendCoinsDialog : : addEntry ( )
2011-07-16 19:01:05 +02:00
{
2015-07-28 15:20:14 +02:00
SendCoinsEntry * entry = new SendCoinsEntry ( platformStyle , this ) ;
2011-07-16 19:01:05 +02:00
entry - > setModel ( model ) ;
ui - > entries - > addWidget ( entry ) ;
connect ( entry , SIGNAL ( removeEntry ( SendCoinsEntry * ) ) , this , SLOT ( removeEntry ( SendCoinsEntry * ) ) ) ;
2013-08-12 17:03:03 +02:00
connect ( entry , SIGNAL ( payAmountChanged ( ) ) , this , SLOT ( coinControlUpdateLabels ( ) ) ) ;
2014-07-23 14:34:36 +02:00
connect ( entry , SIGNAL ( subtractFeeFromAmountChanged ( ) ) , this , SLOT ( coinControlUpdateLabels ( ) ) ) ;
2011-07-16 19:01:05 +02:00
// Focus the field, so that entry can start immediately
entry - > clear ( ) ;
2011-12-07 06:00:04 +01:00
entry - > setFocus ( ) ;
ui - > scrollAreaWidgetContents - > resize ( ui - > scrollAreaWidgetContents - > sizeHint ( ) ) ;
2013-04-02 17:30:14 +02:00
qApp - > processEvents ( ) ;
2011-12-07 06:00:04 +01:00
QScrollBar * bar = ui - > scrollArea - > verticalScrollBar ( ) ;
2012-06-09 15:41:21 +02:00
if ( bar )
2011-12-07 06:00:04 +01:00
bar - > setSliderPosition ( bar - > maximum ( ) ) ;
2016-01-04 09:44:36 +01:00
updateTabsAndLabels ( ) ;
2011-08-07 16:04:48 +02:00
return entry ;
2011-07-16 19:01:05 +02:00
}
2013-11-22 13:53:05 +01:00
void SendCoinsDialog : : updateTabsAndLabels ( )
2011-07-16 19:01:05 +02:00
{
setupTabChain ( 0 ) ;
2013-08-12 17:03:03 +02:00
coinControlUpdateLabels ( ) ;
2011-07-16 19:01:05 +02:00
}
void SendCoinsDialog : : removeEntry ( SendCoinsEntry * entry )
{
2013-12-10 12:01:54 +01:00
entry - > hide ( ) ;
2013-11-22 13:53:05 +01:00
2013-12-10 12:01:54 +01:00
// If the last entry is about to be removed add an empty one
if ( ui - > entries - > count ( ) = = 1 )
2013-11-22 13:53:05 +01:00
addEntry ( ) ;
2013-12-10 12:01:54 +01:00
entry - > deleteLater ( ) ;
2013-11-22 13:53:05 +01:00
updateTabsAndLabels ( ) ;
2011-07-16 19:01:05 +02:00
}
QWidget * SendCoinsDialog : : setupTabChain ( QWidget * prev )
{
for ( int i = 0 ; i < ui - > entries - > count ( ) ; + + i )
{
SendCoinsEntry * entry = qobject_cast < SendCoinsEntry * > ( ui - > entries - > itemAt ( i ) - > widget ( ) ) ;
if ( entry )
{
prev = entry - > setupTabChain ( prev ) ;
}
}
2014-01-29 14:41:41 +01:00
QWidget : : setTabOrder ( prev , ui - > sendButton ) ;
QWidget : : setTabOrder ( ui - > sendButton , ui - > clearButton ) ;
QWidget : : setTabOrder ( ui - > clearButton , ui - > addButton ) ;
return ui - > addButton ;
2011-07-16 19:01:05 +02:00
}
2011-08-07 16:04:48 +02:00
2013-01-25 18:46:53 +01:00
void SendCoinsDialog : : setAddress ( const QString & address )
{
SendCoinsEntry * entry = 0 ;
// Replace the first entry if it is still unused
if ( ui - > entries - > count ( ) = = 1 )
{
SendCoinsEntry * first = qobject_cast < SendCoinsEntry * > ( ui - > entries - > itemAt ( 0 ) - > widget ( ) ) ;
if ( first - > isClear ( ) )
{
entry = first ;
}
}
if ( ! entry )
{
entry = addEntry ( ) ;
}
entry - > setAddress ( address ) ;
}
2011-08-07 16:04:48 +02:00
void SendCoinsDialog : : pasteEntry ( const SendCoinsRecipient & rv )
{
2012-06-09 15:41:21 +02:00
if ( ! fNewRecipientAllowed )
2011-12-24 05:27:12 +01:00
return ;
2011-08-07 16:04:48 +02:00
SendCoinsEntry * entry = 0 ;
// Replace the first entry if it is still unused
if ( ui - > entries - > count ( ) = = 1 )
{
SendCoinsEntry * first = qobject_cast < SendCoinsEntry * > ( ui - > entries - > itemAt ( 0 ) - > widget ( ) ) ;
if ( first - > isClear ( ) )
{
entry = first ;
}
}
if ( ! entry )
{
entry = addEntry ( ) ;
}
entry - > setValue ( rv ) ;
2013-11-22 13:53:05 +01:00
updateTabsAndLabels ( ) ;
2011-08-07 16:04:48 +02:00
}
2013-07-22 08:50:39 +02:00
bool SendCoinsDialog : : handlePaymentRequest ( const SendCoinsRecipient & rv )
2011-08-07 16:04:48 +02:00
{
2013-11-16 01:54:29 +01:00
// Just paste the entry, all pre-checks
// are done in paymentserver.cpp.
2013-07-22 08:50:39 +02:00
pasteEntry ( rv ) ;
return true ;
2011-08-07 16:04:48 +02:00
}
2011-09-22 19:02:01 +02:00
2014-11-20 13:06:10 +01:00
void SendCoinsDialog : : setBalance ( const CAmount & balance , const CAmount & unconfirmedBalance , const CAmount & immatureBalance ,
2014-04-23 00:46:19 +02:00
const CAmount & watchBalance , const CAmount & watchUnconfirmedBalance , const CAmount & watchImmatureBalance )
2011-09-22 19:02:01 +02:00
{
Q_UNUSED ( unconfirmedBalance ) ;
2012-02-14 12:08:00 +01:00
Q_UNUSED ( immatureBalance ) ;
2014-03-29 05:15:28 +01:00
Q_UNUSED ( watchBalance ) ;
Q_UNUSED ( watchUnconfirmedBalance ) ;
Q_UNUSED ( watchImmatureBalance ) ;
2011-11-08 21:18:36 +01:00
2013-08-24 15:07:17 +02:00
if ( model & & model - > getOptionsModel ( ) )
{
ui - > labelBalance - > setText ( BitcoinUnits : : formatWithUnit ( model - > getOptionsModel ( ) - > getDisplayUnit ( ) , balance ) ) ;
}
2011-09-22 19:02:01 +02:00
}
2012-06-09 15:41:21 +02:00
void SendCoinsDialog : : updateDisplayUnit ( )
{
2014-03-29 05:15:28 +01:00
setBalance ( model - > getBalance ( ) , 0 , 0 , 0 , 0 , 0 ) ;
2014-11-02 00:14:47 +01:00
ui - > customFee - > setDisplayUnit ( model - > getOptionsModel ( ) - > getDisplayUnit ( ) ) ;
updateMinFeeLabel ( ) ;
updateSmartFeeLabel ( ) ;
2012-06-09 15:41:21 +02:00
}
2013-10-30 15:37:41 +01:00
void SendCoinsDialog : : processSendCoinsReturn ( const WalletModel : : SendCoinsReturn & sendCoinsReturn , const QString & msgArg )
{
QPair < QString , CClientUIInterface : : MessageBoxFlags > msgParams ;
// Default to a warning message, override if error message is needed
msgParams . second = CClientUIInterface : : MSG_WARNING ;
// This comment is specific to SendCoinsDialog usage of WalletModel::SendCoinsReturn.
// WalletModel::TransactionCommitFailed is used only in WalletModel::sendCoins()
// all others are used only in WalletModel::prepareTransaction()
switch ( sendCoinsReturn . status )
{
case WalletModel : : InvalidAddress :
2015-04-28 16:48:28 +02:00
msgParams . first = tr ( " The recipient address is not valid. Please recheck. " ) ;
2013-10-30 15:37:41 +01:00
break ;
case WalletModel : : InvalidAmount :
msgParams . first = tr ( " The amount to pay must be larger than 0. " ) ;
break ;
case WalletModel : : AmountExceedsBalance :
msgParams . first = tr ( " The amount exceeds your balance. " ) ;
break ;
case WalletModel : : AmountWithFeeExceedsBalance :
msgParams . first = tr ( " The total exceeds your balance when the %1 transaction fee is included. " ) . arg ( msgArg ) ;
break ;
case WalletModel : : DuplicateAddress :
2015-04-28 16:47:17 +02:00
msgParams . first = tr ( " Duplicate address found: addresses should only be used once each. " ) ;
2013-10-30 15:37:41 +01:00
break ;
case WalletModel : : TransactionCreationFailed :
msgParams . first = tr ( " Transaction creation failed! " ) ;
msgParams . second = CClientUIInterface : : MSG_ERROR ;
break ;
case WalletModel : : TransactionCommitFailed :
msgParams . first = tr ( " The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. " ) ;
msgParams . second = CClientUIInterface : : MSG_ERROR ;
break ;
2015-01-31 03:54:55 +01:00
case WalletModel : : AbsurdFee :
2015-10-25 01:27:24 +02:00
msgParams . first = tr ( " A fee higher than %1 is considered an absurdly high fee. " ) . arg ( BitcoinUnits : : formatWithUnit ( model - > getOptionsModel ( ) - > getDisplayUnit ( ) , maxTxFee ) ) ;
2014-11-02 00:14:47 +01:00
break ;
2015-01-08 14:42:04 +01:00
case WalletModel : : PaymentRequestExpired :
2015-02-03 22:44:33 +01:00
msgParams . first = tr ( " Payment request expired. " ) ;
2015-01-08 14:42:04 +01:00
msgParams . second = CClientUIInterface : : MSG_ERROR ;
break ;
2013-12-16 09:46:55 +01:00
// included to prevent a compiler warning.
2013-10-30 15:37:41 +01:00
case WalletModel : : OK :
default :
return ;
}
2015-07-14 13:59:05 +02:00
Q_EMIT message ( tr ( " Send Coins " ) , msgParams . first , msgParams . second ) ;
2013-10-30 15:37:41 +01:00
}
2013-08-12 17:03:03 +02:00
2014-11-02 00:14:47 +01:00
void SendCoinsDialog : : minimizeFeeSection ( bool fMinimize )
{
ui - > labelFeeMinimized - > setVisible ( fMinimize ) ;
ui - > buttonChooseFee - > setVisible ( fMinimize ) ;
ui - > buttonMinimizeFee - > setVisible ( ! fMinimize ) ;
ui - > frameFeeSelection - > setVisible ( ! fMinimize ) ;
ui - > horizontalLayoutSmartFee - > setContentsMargins ( 0 , ( fMinimize ? 0 : 6 ) , 0 , 0 ) ;
fFeeMinimized = fMinimize ;
}
void SendCoinsDialog : : on_buttonChooseFee_clicked ( )
{
minimizeFeeSection ( false ) ;
}
void SendCoinsDialog : : on_buttonMinimizeFee_clicked ( )
{
updateFeeMinimizedLabel ( ) ;
minimizeFeeSection ( true ) ;
}
void SendCoinsDialog : : setMinimumFee ( )
{
ui - > radioCustomPerKilobyte - > setChecked ( true ) ;
2015-10-25 02:47:04 +02:00
ui - > customFee - > setValue ( CWallet : : GetRequiredFee ( 1000 ) ) ;
2014-11-02 00:14:47 +01:00
}
void SendCoinsDialog : : updateFeeSectionControls ( )
{
ui - > sliderSmartFee - > setEnabled ( ui - > radioSmartFee - > isChecked ( ) ) ;
ui - > labelSmartFee - > setEnabled ( ui - > radioSmartFee - > isChecked ( ) ) ;
ui - > labelSmartFee2 - > setEnabled ( ui - > radioSmartFee - > isChecked ( ) ) ;
ui - > labelSmartFee3 - > setEnabled ( ui - > radioSmartFee - > isChecked ( ) ) ;
ui - > labelFeeEstimation - > setEnabled ( ui - > radioSmartFee - > isChecked ( ) ) ;
ui - > labelSmartFeeNormal - > setEnabled ( ui - > radioSmartFee - > isChecked ( ) ) ;
ui - > labelSmartFeeFast - > setEnabled ( ui - > radioSmartFee - > isChecked ( ) ) ;
ui - > checkBoxMinimumFee - > setEnabled ( ui - > radioCustomFee - > isChecked ( ) ) ;
ui - > labelMinFeeWarning - > setEnabled ( ui - > radioCustomFee - > isChecked ( ) ) ;
ui - > radioCustomPerKilobyte - > setEnabled ( ui - > radioCustomFee - > isChecked ( ) & & ! ui - > checkBoxMinimumFee - > isChecked ( ) ) ;
2015-11-25 14:05:30 +01:00
ui - > radioCustomAtLeast - > setEnabled ( ui - > radioCustomFee - > isChecked ( ) & & ! ui - > checkBoxMinimumFee - > isChecked ( ) & & CoinControlDialog : : coinControl - > HasSelected ( ) ) ;
2014-11-02 00:14:47 +01:00
ui - > customFee - > setEnabled ( ui - > radioCustomFee - > isChecked ( ) & & ! ui - > checkBoxMinimumFee - > isChecked ( ) ) ;
}
void SendCoinsDialog : : updateGlobalFeeVariables ( )
{
if ( ui - > radioSmartFee - > isChecked ( ) )
{
2015-03-18 11:27:30 +01:00
nTxConfirmTarget = defaultConfirmTarget - ui - > sliderSmartFee - > value ( ) ;
2014-11-02 00:14:47 +01:00
payTxFee = CFeeRate ( 0 ) ;
}
else
{
2015-03-18 11:27:30 +01:00
nTxConfirmTarget = defaultConfirmTarget ;
2014-11-02 00:14:47 +01:00
payTxFee = CFeeRate ( ui - > customFee - > value ( ) ) ;
2015-11-25 14:05:30 +01:00
// if user has selected to set a minimum absolute fee, pass the value to coincontrol
// set nMinimumTotalFee to 0 in case of user has selected that the fee is per KB
CoinControlDialog : : coinControl - > nMinimumTotalFee = ui - > radioCustomAtLeast - > isChecked ( ) ? ui - > customFee - > value ( ) : 0 ;
2014-11-02 00:14:47 +01:00
}
}
void SendCoinsDialog : : updateFeeMinimizedLabel ( )
{
if ( ! model | | ! model - > getOptionsModel ( ) )
return ;
if ( ui - > radioSmartFee - > isChecked ( ) )
ui - > labelFeeMinimized - > setText ( ui - > labelSmartFee - > text ( ) ) ;
else {
ui - > labelFeeMinimized - > setText ( BitcoinUnits : : formatWithUnit ( model - > getOptionsModel ( ) - > getDisplayUnit ( ) , ui - > customFee - > value ( ) ) +
( ( ui - > radioCustomPerKilobyte - > isChecked ( ) ) ? " /kB " : " " ) ) ;
}
}
void SendCoinsDialog : : updateMinFeeLabel ( )
{
if ( model & & model - > getOptionsModel ( ) )
2015-10-25 02:47:04 +02:00
ui - > checkBoxMinimumFee - > setText ( tr ( " Pay only the required fee of %1 " ) . arg (
BitcoinUnits : : formatWithUnit ( model - > getOptionsModel ( ) - > getDisplayUnit ( ) , CWallet : : GetRequiredFee ( 1000 ) ) + " /kB " )
2014-11-02 00:14:47 +01:00
) ;
}
void SendCoinsDialog : : updateSmartFeeLabel ( )
{
if ( ! model | | ! model - > getOptionsModel ( ) )
return ;
2015-03-18 11:27:30 +01:00
int nBlocksToConfirm = defaultConfirmTarget - ui - > sliderSmartFee - > value ( ) ;
2015-11-16 21:15:32 +01:00
int estimateFoundAtBlocks = nBlocksToConfirm ;
CFeeRate feeRate = mempool . estimateSmartFee ( nBlocksToConfirm , & estimateFoundAtBlocks ) ;
2014-11-02 00:14:47 +01:00
if ( feeRate < = CFeeRate ( 0 ) ) // not enough data => minfee
{
2016-01-05 19:11:34 +01:00
ui - > labelSmartFee - > setText ( BitcoinUnits : : formatWithUnit ( model - > getOptionsModel ( ) - > getDisplayUnit ( ) ,
std : : max ( CWallet : : fallbackFee . GetFeePerK ( ) , CWallet : : GetRequiredFee ( 1000 ) ) ) + " /kB " ) ;
2014-11-02 00:14:47 +01:00
ui - > labelSmartFee2 - > show ( ) ; // (Smart fee not initialized yet. This usually takes a few blocks...)
ui - > labelFeeEstimation - > setText ( " " ) ;
}
else
{
2016-01-05 19:11:34 +01:00
ui - > labelSmartFee - > setText ( BitcoinUnits : : formatWithUnit ( model - > getOptionsModel ( ) - > getDisplayUnit ( ) ,
std : : max ( feeRate . GetFeePerK ( ) , CWallet : : GetRequiredFee ( 1000 ) ) ) + " /kB " ) ;
2014-11-02 00:14:47 +01:00
ui - > labelSmartFee2 - > hide ( ) ;
2015-11-16 21:15:32 +01:00
ui - > labelFeeEstimation - > setText ( tr ( " Estimated to begin confirmation within %n block(s). " , " " , estimateFoundAtBlocks ) ) ;
2014-11-02 00:14:47 +01:00
}
updateFeeMinimizedLabel ( ) ;
}
2013-08-12 17:03:03 +02:00
// Coin Control: copy label "Quantity" to clipboard
void SendCoinsDialog : : coinControlClipboardQuantity ( )
{
GUIUtil : : setClipboard ( ui - > labelCoinControlQuantity - > text ( ) ) ;
}
// Coin Control: copy label "Amount" to clipboard
void SendCoinsDialog : : coinControlClipboardAmount ( )
{
GUIUtil : : setClipboard ( ui - > labelCoinControlAmount - > text ( ) . left ( ui - > labelCoinControlAmount - > text ( ) . indexOf ( " " ) ) ) ;
}
// Coin Control: copy label "Fee" to clipboard
void SendCoinsDialog : : coinControlClipboardFee ( )
{
2015-01-12 23:26:29 +01:00
GUIUtil : : setClipboard ( ui - > labelCoinControlFee - > text ( ) . left ( ui - > labelCoinControlFee - > text ( ) . indexOf ( " " ) ) . replace ( ASYMP_UTF8 , " " ) ) ;
2013-08-12 17:03:03 +02:00
}
// Coin Control: copy label "After fee" to clipboard
void SendCoinsDialog : : coinControlClipboardAfterFee ( )
{
2015-01-12 23:26:29 +01:00
GUIUtil : : setClipboard ( ui - > labelCoinControlAfterFee - > text ( ) . left ( ui - > labelCoinControlAfterFee - > text ( ) . indexOf ( " " ) ) . replace ( ASYMP_UTF8 , " " ) ) ;
2013-08-12 17:03:03 +02:00
}
// Coin Control: copy label "Bytes" to clipboard
void SendCoinsDialog : : coinControlClipboardBytes ( )
{
2015-01-12 23:26:29 +01:00
GUIUtil : : setClipboard ( ui - > labelCoinControlBytes - > text ( ) . replace ( ASYMP_UTF8 , " " ) ) ;
2013-08-12 17:03:03 +02:00
}
2014-06-08 01:05:53 +02:00
// Coin Control: copy label "Dust" to clipboard
2013-08-12 17:03:03 +02:00
void SendCoinsDialog : : coinControlClipboardLowOutput ( )
{
GUIUtil : : setClipboard ( ui - > labelCoinControlLowOutput - > text ( ) ) ;
}
// Coin Control: copy label "Change" to clipboard
void SendCoinsDialog : : coinControlClipboardChange ( )
{
2015-01-12 23:26:29 +01:00
GUIUtil : : setClipboard ( ui - > labelCoinControlChange - > text ( ) . left ( ui - > labelCoinControlChange - > text ( ) . indexOf ( " " ) ) . replace ( ASYMP_UTF8 , " " ) ) ;
2013-08-12 17:03:03 +02:00
}
// Coin Control: settings menu - coin control enabled/disabled by user
void SendCoinsDialog : : coinControlFeatureChanged ( bool checked )
{
ui - > frameCoinControl - > setVisible ( checked ) ;
if ( ! checked & & model ) // coin control features disabled
CoinControlDialog : : coinControl - > SetNull ( ) ;
2014-01-27 19:15:56 +01:00
2015-11-25 14:05:30 +01:00
coinControlUpdateLabels ( ) ;
2013-08-12 17:03:03 +02:00
}
// Coin Control: button inputs -> show actual coin control dialog
void SendCoinsDialog : : coinControlButtonClicked ( )
{
2015-07-28 15:20:14 +02:00
CoinControlDialog dlg ( platformStyle ) ;
2013-08-12 17:03:03 +02:00
dlg . setModel ( model ) ;
dlg . exec ( ) ;
coinControlUpdateLabels ( ) ;
}
// Coin Control: checkbox custom change address
void SendCoinsDialog : : coinControlChangeChecked ( int state )
{
2013-11-20 15:49:34 +01:00
if ( state = = Qt : : Unchecked )
2013-08-12 17:03:03 +02:00
{
2013-11-20 15:49:34 +01:00
CoinControlDialog : : coinControl - > destChange = CNoDestination ( ) ;
ui - > labelCoinControlChangeLabel - > clear ( ) ;
2013-08-12 17:03:03 +02:00
}
2013-11-20 15:49:34 +01:00
else
// use this to re-validate an already entered address
coinControlChangeEdited ( ui - > lineEditCoinControlChange - > text ( ) ) ;
2013-08-12 17:03:03 +02:00
ui - > lineEditCoinControlChange - > setEnabled ( ( state = = Qt : : Checked ) ) ;
}
// Coin Control: custom change address changed
2013-12-10 12:01:54 +01:00
void SendCoinsDialog : : coinControlChangeEdited ( const QString & text )
2013-08-12 17:03:03 +02:00
{
2013-12-11 15:12:13 +01:00
if ( model & & model - > getAddressTableModel ( ) )
2013-08-12 17:03:03 +02:00
{
2013-12-11 15:12:13 +01:00
// Default to no change address until verified
CoinControlDialog : : coinControl - > destChange = CNoDestination ( ) ;
ui - > labelCoinControlChangeLabel - > setStyleSheet ( " QLabel{color:red;} " ) ;
CBitcoinAddress addr = CBitcoinAddress ( text . toStdString ( ) ) ;
2013-08-12 17:03:03 +02:00
2013-12-11 15:12:13 +01:00
if ( text . isEmpty ( ) ) // Nothing entered
{
2013-08-12 17:03:03 +02:00
ui - > labelCoinControlChangeLabel - > setText ( " " ) ;
2013-12-11 15:12:13 +01:00
}
else if ( ! addr . IsValid ( ) ) // Invalid address
2013-08-12 17:03:03 +02:00
{
ui - > labelCoinControlChangeLabel - > setText ( tr ( " Warning: Invalid Bitcoin address " ) ) ;
}
2013-12-11 15:12:13 +01:00
else // Valid address
2013-08-12 17:03:03 +02:00
{
2013-12-11 15:12:13 +01:00
CKeyID keyid ;
addr . GetKeyID ( keyid ) ;
2015-06-10 10:04:08 +02:00
if ( ! model - > havePrivKey ( keyid ) ) // Unknown change address
2013-08-12 17:03:03 +02:00
{
2013-12-11 15:12:13 +01:00
ui - > labelCoinControlChangeLabel - > setText ( tr ( " Warning: Unknown change address " ) ) ;
}
else // Known change address
{
ui - > labelCoinControlChangeLabel - > setStyleSheet ( " QLabel{color:black;} " ) ;
// Query label
QString associatedLabel = model - > getAddressTableModel ( ) - > labelForAddress ( text ) ;
if ( ! associatedLabel . isEmpty ( ) )
ui - > labelCoinControlChangeLabel - > setText ( associatedLabel ) ;
2013-08-12 17:03:03 +02:00
else
2013-12-11 15:12:13 +01:00
ui - > labelCoinControlChangeLabel - > setText ( tr ( " (no label) " ) ) ;
CoinControlDialog : : coinControl - > destChange = addr . Get ( ) ;
2013-08-12 17:03:03 +02:00
}
}
}
}
// Coin Control: update labels
void SendCoinsDialog : : coinControlUpdateLabels ( )
{
2015-11-25 14:05:30 +01:00
if ( ! model | | ! model - > getOptionsModel ( ) )
2013-08-12 17:03:03 +02:00
return ;
2015-11-25 14:05:30 +01:00
if ( model - > getOptionsModel ( ) - > getCoinControlFeatures ( ) )
{
2016-01-17 12:03:56 +01:00
// enable minimum absolute fee UI controls
2015-11-25 14:05:30 +01:00
ui - > radioCustomAtLeast - > setVisible ( true ) ;
// only enable the feature if inputs are selected
ui - > radioCustomAtLeast - > setEnabled ( CoinControlDialog : : coinControl - > HasSelected ( ) ) ;
}
else
{
// in case coin control is disabled (=default), hide minimum absolute fee UI controls
ui - > radioCustomAtLeast - > setVisible ( false ) ;
return ;
}
2013-08-12 17:03:03 +02:00
// set pay amounts
CoinControlDialog : : payAmounts . clear ( ) ;
2014-07-23 14:34:36 +02:00
CoinControlDialog : : fSubtractFeeFromAmount = false ;
2013-08-12 17:03:03 +02:00
for ( int i = 0 ; i < ui - > entries - > count ( ) ; + + i )
{
SendCoinsEntry * entry = qobject_cast < SendCoinsEntry * > ( ui - > entries - > itemAt ( i ) - > widget ( ) ) ;
2016-01-04 09:44:36 +01:00
if ( entry & & ! entry - > isHidden ( ) )
2014-07-23 14:34:36 +02:00
{
SendCoinsRecipient rcp = entry - > getValue ( ) ;
CoinControlDialog : : payAmounts . append ( rcp . amount ) ;
if ( rcp . fSubtractFeeFromAmount )
CoinControlDialog : : fSubtractFeeFromAmount = true ;
}
2013-08-12 17:03:03 +02:00
}
if ( CoinControlDialog : : coinControl - > HasSelected ( ) )
{
// actual coin control calculation
CoinControlDialog : : updateLabels ( model , this ) ;
// show coin control stats
ui - > labelCoinControlAutomaticallySelected - > hide ( ) ;
ui - > widgetCoinControl - > show ( ) ;
}
else
{
// hide coin control stats
ui - > labelCoinControlAutomaticallySelected - > show ( ) ;
ui - > widgetCoinControl - > hide ( ) ;
ui - > labelCoinControlInsuffFunds - > hide ( ) ;
}
}
2016-05-10 04:26:57 +02:00
SendConfirmationDialog : : SendConfirmationDialog ( const QString & title , const QString & text , int secDelay ,
QWidget * parent ) :
QMessageBox ( QMessageBox : : Question , title , text , QMessageBox : : Yes | QMessageBox : : Cancel , parent ) , secDelay ( secDelay )
{
setDefaultButton ( QMessageBox : : Cancel ) ;
yesButton = button ( QMessageBox : : Yes ) ;
updateYesButton ( ) ;
connect ( & countDownTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( countDown ( ) ) ) ;
}
int SendConfirmationDialog : : exec ( )
{
updateYesButton ( ) ;
countDownTimer . start ( 1000 ) ;
return QMessageBox : : exec ( ) ;
}
void SendConfirmationDialog : : countDown ( )
{
secDelay - - ;
updateYesButton ( ) ;
if ( secDelay < = 0 )
{
countDownTimer . stop ( ) ;
}
}
void SendConfirmationDialog : : updateYesButton ( )
{
if ( secDelay > 0 )
{
yesButton - > setEnabled ( false ) ;
yesButton - > setText ( tr ( " Yes " ) + " ( " + QString : : number ( secDelay ) + " ) " ) ;
}
else
{
yesButton - > setEnabled ( true ) ;
yesButton - > setText ( tr ( " Yes " ) ) ;
}
}