Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F12428736
sendcoinsdialog.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
20 KB
Subscribers
None
sendcoinsdialog.cpp
View Options
// Copyright (c) 2011-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include
"sendcoinsdialog.h"
#include
"ui_sendcoinsdialog.h"
#include
"addresstablemodel.h"
#include
"bitcoinunits.h"
#include
"coincontroldialog.h"
#include
"guiutil.h"
#include
"optionsmodel.h"
#include
"sendcoinsentry.h"
#include
"walletmodel.h"
#include
"base58.h"
#include
"coincontrol.h"
#include
"ui_interface.h"
#include
<QMessageBox>
#include
<QScrollBar>
#include
<QTextDocument>
SendCoinsDialog
::
SendCoinsDialog
(
QWidget
*
parent
)
:
QDialog
(
parent
),
ui
(
new
Ui
::
SendCoinsDialog
),
model
(
0
)
{
ui
->
setupUi
(
this
);
#ifdef Q_OS_MAC
// Icons on push buttons are very uncommon on Mac
ui
->
addButton
->
setIcon
(
QIcon
());
ui
->
clearButton
->
setIcon
(
QIcon
());
ui
->
sendButton
->
setIcon
(
QIcon
());
#endif
GUIUtil
::
setupAddressWidget
(
ui
->
lineEditCoinControlChange
,
this
);
addEntry
();
connect
(
ui
->
addButton
,
SIGNAL
(
clicked
()),
this
,
SLOT
(
addEntry
()));
connect
(
ui
->
clearButton
,
SIGNAL
(
clicked
()),
this
,
SLOT
(
clear
()));
// 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
);
QAction
*
clipboardPriorityAction
=
new
QAction
(
tr
(
"Copy priority"
),
this
);
QAction
*
clipboardLowOutputAction
=
new
QAction
(
tr
(
"Copy dust"
),
this
);
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
(
clipboardPriorityAction
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
coinControlClipboardPriority
()));
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
->
labelCoinControlPriority
->
addAction
(
clipboardPriorityAction
);
ui
->
labelCoinControlLowOutput
->
addAction
(
clipboardLowOutputAction
);
ui
->
labelCoinControlChange
->
addAction
(
clipboardChangeAction
);
fNewRecipientAllowed
=
true
;
}
void
SendCoinsDialog
::
setModel
(
WalletModel
*
model
)
{
this
->
model
=
model
;
if
(
model
&&
model
->
getOptionsModel
())
{
for
(
int
i
=
0
;
i
<
ui
->
entries
->
count
();
++
i
)
{
SendCoinsEntry
*
entry
=
qobject_cast
<
SendCoinsEntry
*>
(
ui
->
entries
->
itemAt
(
i
)
->
widget
());
if
(
entry
)
{
entry
->
setModel
(
model
);
}
}
setBalance
(
model
->
getBalance
(),
model
->
getUnconfirmedBalance
(),
model
->
getImmatureBalance
(),
model
->
getWatchBalance
(),
model
->
getWatchUnconfirmedBalance
(),
model
->
getWatchImmatureBalance
());
connect
(
model
,
SIGNAL
(
balanceChanged
(
qint64
,
qint64
,
qint64
,
qint64
,
qint64
,
qint64
)),
this
,
SLOT
(
setBalance
(
qint64
,
qint64
,
qint64
,
qint64
,
qint64
,
qint64
)));
connect
(
model
->
getOptionsModel
(),
SIGNAL
(
displayUnitChanged
(
int
)),
this
,
SLOT
(
updateDisplayUnit
()));
// Coin Control
connect
(
model
->
getOptionsModel
(),
SIGNAL
(
displayUnitChanged
(
int
)),
this
,
SLOT
(
coinControlUpdateLabels
()));
connect
(
model
->
getOptionsModel
(),
SIGNAL
(
coinControlFeaturesChanged
(
bool
)),
this
,
SLOT
(
coinControlFeatureChanged
(
bool
)));
connect
(
model
->
getOptionsModel
(),
SIGNAL
(
transactionFeeChanged
(
qint64
)),
this
,
SLOT
(
coinControlUpdateLabels
()));
ui
->
frameCoinControl
->
setVisible
(
model
->
getOptionsModel
()
->
getCoinControlFeatures
());
coinControlUpdateLabels
();
}
}
SendCoinsDialog
::~
SendCoinsDialog
()
{
delete
ui
;
}
void
SendCoinsDialog
::
on_sendButton_clicked
()
{
if
(
!
model
||
!
model
->
getOptionsModel
())
return
;
QList
<
SendCoinsRecipient
>
recipients
;
bool
valid
=
true
;
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
;
}
}
}
if
(
!
valid
||
recipients
.
isEmpty
())
{
return
;
}
// Format confirmation message
QStringList
formatted
;
foreach
(
const
SendCoinsRecipient
&
rcp
,
recipients
)
{
// generate bold amount string
QString
amount
=
"<b>"
+
BitcoinUnits
::
formatHtmlWithUnit
(
model
->
getOptionsModel
()
->
getDisplayUnit
(),
rcp
.
amount
);
amount
.
append
(
"</b>"
);
// generate monospace address string
QString
address
=
"<span style='font-family: monospace;'>"
+
rcp
.
address
;
address
.
append
(
"</span>"
);
QString
recipientElement
;
if
(
!
rcp
.
paymentRequest
.
IsInitialized
())
// normal payment
{
if
(
rcp
.
label
.
length
()
>
0
)
// label with address
{
recipientElement
=
tr
(
"%1 to %2"
).
arg
(
amount
,
GUIUtil
::
HtmlEscape
(
rcp
.
label
));
recipientElement
.
append
(
QString
(
" (%1)"
).
arg
(
address
));
}
else
// just address
{
recipientElement
=
tr
(
"%1 to %2"
).
arg
(
amount
,
address
);
}
}
else
if
(
!
rcp
.
authenticatedMerchant
.
isEmpty
())
// secure payment request
{
recipientElement
=
tr
(
"%1 to %2"
).
arg
(
amount
,
GUIUtil
::
HtmlEscape
(
rcp
.
authenticatedMerchant
));
}
else
// insecure payment request
{
recipientElement
=
tr
(
"%1 to %2"
).
arg
(
amount
,
address
);
}
formatted
.
append
(
recipientElement
);
}
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
;
}
qint64
txFee
=
currentTransaction
.
getTransactionFee
();
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;'>"
);
questionString
.
append
(
BitcoinUnits
::
formatHtmlWithUnit
(
model
->
getOptionsModel
()
->
getDisplayUnit
(),
txFee
));
questionString
.
append
(
"</span> "
);
questionString
.
append
(
tr
(
"added as transaction fee"
));
}
// add total amount in all subdivision units
questionString
.
append
(
"<hr />"
);
qint64
totalAmount
=
currentTransaction
.
getTotalTransactionAmount
()
+
txFee
;
QStringList
alternativeUnits
;
foreach
(
BitcoinUnits
::
Unit
u
,
BitcoinUnits
::
availableUnits
())
{
if
(
u
!=
model
->
getOptionsModel
()
->
getDisplayUnit
())
alternativeUnits
.
append
(
BitcoinUnits
::
formatHtmlWithUnit
(
u
,
totalAmount
));
}
questionString
.
append
(
tr
(
"Total Amount %1 (= %2)"
)
.
arg
(
BitcoinUnits
::
formatHtmlWithUnit
(
model
->
getOptionsModel
()
->
getDisplayUnit
(),
totalAmount
))
.
arg
(
alternativeUnits
.
join
(
" "
+
tr
(
"or"
)
+
" "
)));
QMessageBox
::
StandardButton
retval
=
QMessageBox
::
question
(
this
,
tr
(
"Confirm send coins"
),
questionString
.
arg
(
formatted
.
join
(
"<br />"
)),
QMessageBox
::
Yes
|
QMessageBox
::
Cancel
,
QMessageBox
::
Cancel
);
if
(
retval
!=
QMessageBox
::
Yes
)
{
fNewRecipientAllowed
=
true
;
return
;
}
// now send the prepared transaction
WalletModel
::
SendCoinsReturn
sendStatus
=
model
->
sendCoins
(
currentTransaction
);
// process sendStatus and on error generate message shown to user
processSendCoinsReturn
(
sendStatus
);
if
(
sendStatus
.
status
==
WalletModel
::
OK
)
{
accept
();
CoinControlDialog
::
coinControl
->
UnSelectAll
();
coinControlUpdateLabels
();
}
fNewRecipientAllowed
=
true
;
}
void
SendCoinsDialog
::
clear
()
{
// Remove entries until only one left
while
(
ui
->
entries
->
count
())
{
ui
->
entries
->
takeAt
(
0
)
->
widget
()
->
deleteLater
();
}
addEntry
();
updateTabsAndLabels
();
}
void
SendCoinsDialog
::
reject
()
{
clear
();
}
void
SendCoinsDialog
::
accept
()
{
clear
();
}
SendCoinsEntry
*
SendCoinsDialog
::
addEntry
()
{
SendCoinsEntry
*
entry
=
new
SendCoinsEntry
(
this
);
entry
->
setModel
(
model
);
ui
->
entries
->
addWidget
(
entry
);
connect
(
entry
,
SIGNAL
(
removeEntry
(
SendCoinsEntry
*
)),
this
,
SLOT
(
removeEntry
(
SendCoinsEntry
*
)));
connect
(
entry
,
SIGNAL
(
payAmountChanged
()),
this
,
SLOT
(
coinControlUpdateLabels
()));
updateTabsAndLabels
();
// Focus the field, so that entry can start immediately
entry
->
clear
();
entry
->
setFocus
();
ui
->
scrollAreaWidgetContents
->
resize
(
ui
->
scrollAreaWidgetContents
->
sizeHint
());
qApp
->
processEvents
();
QScrollBar
*
bar
=
ui
->
scrollArea
->
verticalScrollBar
();
if
(
bar
)
bar
->
setSliderPosition
(
bar
->
maximum
());
return
entry
;
}
void
SendCoinsDialog
::
updateTabsAndLabels
()
{
setupTabChain
(
0
);
coinControlUpdateLabels
();
}
void
SendCoinsDialog
::
removeEntry
(
SendCoinsEntry
*
entry
)
{
entry
->
hide
();
// If the last entry is about to be removed add an empty one
if
(
ui
->
entries
->
count
()
==
1
)
addEntry
();
entry
->
deleteLater
();
updateTabsAndLabels
();
}
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
);
}
}
QWidget
::
setTabOrder
(
prev
,
ui
->
sendButton
);
QWidget
::
setTabOrder
(
ui
->
sendButton
,
ui
->
clearButton
);
QWidget
::
setTabOrder
(
ui
->
clearButton
,
ui
->
addButton
);
return
ui
->
addButton
;
}
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
);
}
void
SendCoinsDialog
::
pasteEntry
(
const
SendCoinsRecipient
&
rv
)
{
if
(
!
fNewRecipientAllowed
)
return
;
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
);
updateTabsAndLabels
();
}
bool
SendCoinsDialog
::
handlePaymentRequest
(
const
SendCoinsRecipient
&
rv
)
{
// Just paste the entry, all pre-checks
// are done in paymentserver.cpp.
pasteEntry
(
rv
);
return
true
;
}
void
SendCoinsDialog
::
setBalance
(
qint64
balance
,
qint64
unconfirmedBalance
,
qint64
immatureBalance
,
qint64
watchBalance
,
qint64
watchUnconfirmedBalance
,
qint64
watchImmatureBalance
)
{
Q_UNUSED
(
unconfirmedBalance
);
Q_UNUSED
(
immatureBalance
);
Q_UNUSED
(
watchBalance
);
Q_UNUSED
(
watchUnconfirmedBalance
);
Q_UNUSED
(
watchImmatureBalance
);
if
(
model
&&
model
->
getOptionsModel
())
{
ui
->
labelBalance
->
setText
(
BitcoinUnits
::
formatWithUnit
(
model
->
getOptionsModel
()
->
getDisplayUnit
(),
balance
));
}
}
void
SendCoinsDialog
::
updateDisplayUnit
()
{
setBalance
(
model
->
getBalance
(),
0
,
0
,
0
,
0
,
0
);
}
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
:
msgParams
.
first
=
tr
(
"The recipient address is not valid, please recheck."
);
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
:
msgParams
.
first
=
tr
(
"Duplicate address found, can only send to each address once per send operation."
);
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
;
// included to prevent a compiler warning.
case
WalletModel
::
OK
:
default
:
return
;
}
emit
message
(
tr
(
"Send Coins"
),
msgParams
.
first
,
msgParams
.
second
);
}
// 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
()
{
GUIUtil
::
setClipboard
(
ui
->
labelCoinControlFee
->
text
().
left
(
ui
->
labelCoinControlFee
->
text
().
indexOf
(
" "
)));
}
// Coin Control: copy label "After fee" to clipboard
void
SendCoinsDialog
::
coinControlClipboardAfterFee
()
{
GUIUtil
::
setClipboard
(
ui
->
labelCoinControlAfterFee
->
text
().
left
(
ui
->
labelCoinControlAfterFee
->
text
().
indexOf
(
" "
)));
}
// Coin Control: copy label "Bytes" to clipboard
void
SendCoinsDialog
::
coinControlClipboardBytes
()
{
GUIUtil
::
setClipboard
(
ui
->
labelCoinControlBytes
->
text
());
}
// Coin Control: copy label "Priority" to clipboard
void
SendCoinsDialog
::
coinControlClipboardPriority
()
{
GUIUtil
::
setClipboard
(
ui
->
labelCoinControlPriority
->
text
());
}
// Coin Control: copy label "Dust" to clipboard
void
SendCoinsDialog
::
coinControlClipboardLowOutput
()
{
GUIUtil
::
setClipboard
(
ui
->
labelCoinControlLowOutput
->
text
());
}
// Coin Control: copy label "Change" to clipboard
void
SendCoinsDialog
::
coinControlClipboardChange
()
{
GUIUtil
::
setClipboard
(
ui
->
labelCoinControlChange
->
text
().
left
(
ui
->
labelCoinControlChange
->
text
().
indexOf
(
" "
)));
}
// 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
();
if
(
checked
)
coinControlUpdateLabels
();
}
// Coin Control: button inputs -> show actual coin control dialog
void
SendCoinsDialog
::
coinControlButtonClicked
()
{
CoinControlDialog
dlg
;
dlg
.
setModel
(
model
);
dlg
.
exec
();
coinControlUpdateLabels
();
}
// Coin Control: checkbox custom change address
void
SendCoinsDialog
::
coinControlChangeChecked
(
int
state
)
{
if
(
state
==
Qt
::
Unchecked
)
{
CoinControlDialog
::
coinControl
->
destChange
=
CNoDestination
();
ui
->
labelCoinControlChangeLabel
->
clear
();
}
else
// use this to re-validate an already entered address
coinControlChangeEdited
(
ui
->
lineEditCoinControlChange
->
text
());
ui
->
lineEditCoinControlChange
->
setEnabled
((
state
==
Qt
::
Checked
));
}
// Coin Control: custom change address changed
void
SendCoinsDialog
::
coinControlChangeEdited
(
const
QString
&
text
)
{
if
(
model
&&
model
->
getAddressTableModel
())
{
// Default to no change address until verified
CoinControlDialog
::
coinControl
->
destChange
=
CNoDestination
();
ui
->
labelCoinControlChangeLabel
->
setStyleSheet
(
"QLabel{color:red;}"
);
CBitcoinAddress
addr
=
CBitcoinAddress
(
text
.
toStdString
());
if
(
text
.
isEmpty
())
// Nothing entered
{
ui
->
labelCoinControlChangeLabel
->
setText
(
""
);
}
else
if
(
!
addr
.
IsValid
())
// Invalid address
{
ui
->
labelCoinControlChangeLabel
->
setText
(
tr
(
"Warning: Invalid Bitcoin address"
));
}
else
// Valid address
{
CPubKey
pubkey
;
CKeyID
keyid
;
addr
.
GetKeyID
(
keyid
);
if
(
!
model
->
getPubKey
(
keyid
,
pubkey
))
// Unknown change address
{
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
);
else
ui
->
labelCoinControlChangeLabel
->
setText
(
tr
(
"(no label)"
));
CoinControlDialog
::
coinControl
->
destChange
=
addr
.
Get
();
}
}
}
}
// Coin Control: update labels
void
SendCoinsDialog
::
coinControlUpdateLabels
()
{
if
(
!
model
||
!
model
->
getOptionsModel
()
||
!
model
->
getOptionsModel
()
->
getCoinControlFeatures
())
return
;
// set pay amounts
CoinControlDialog
::
payAmounts
.
clear
();
for
(
int
i
=
0
;
i
<
ui
->
entries
->
count
();
++
i
)
{
SendCoinsEntry
*
entry
=
qobject_cast
<
SendCoinsEntry
*>
(
ui
->
entries
->
itemAt
(
i
)
->
widget
());
if
(
entry
)
CoinControlDialog
::
payAmounts
.
append
(
entry
->
getValue
().
amount
);
}
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
();
}
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Sun, Dec 29, 19:28 (17 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4844948
Default Alt Text
sendcoinsdialog.cpp (20 KB)
Attached To
rSTAGING Bitcoin ABC staging
Event Timeline
Log In to Comment