Master Core  v0.0.9 - 2abfd2849db8ba7a83957c64eb976b406713c123
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
sendcoinsdialog.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2014 The Bitcoin developers
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include "sendcoinsdialog.h"
6 #include "ui_sendcoinsdialog.h"
7 
8 #include "addresstablemodel.h"
9 #include "bitcoinunits.h"
10 #include "coincontroldialog.h"
11 #include "guiutil.h"
12 #include "optionsmodel.h"
13 #include "sendcoinsentry.h"
14 #include "walletmodel.h"
15 
16 #include "base58.h"
17 #include "coincontrol.h"
18 #include "ui_interface.h"
19 
20 #include <QMessageBox>
21 #include <QScrollBar>
22 #include <QTextDocument>
23 
25  QDialog(parent),
26  ui(new Ui::SendCoinsDialog),
27  model(0)
28 {
29  ui->setupUi(this);
30 
31 #ifdef Q_OS_MAC // Icons on push buttons are very uncommon on Mac
32  ui->addButton->setIcon(QIcon());
33  ui->clearButton->setIcon(QIcon());
34  ui->sendButton->setIcon(QIcon());
35 #endif
36 
38 
39  addEntry();
40 
41  connect(ui->addButton, SIGNAL(clicked()), this, SLOT(addEntry()));
42  connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear()));
43 
44  // Coin Control
45  connect(ui->pushButtonCoinControl, SIGNAL(clicked()), this, SLOT(coinControlButtonClicked()));
46  connect(ui->checkBoxCoinControlChange, SIGNAL(stateChanged(int)), this, SLOT(coinControlChangeChecked(int)));
47  connect(ui->lineEditCoinControlChange, SIGNAL(textEdited(const QString &)), this, SLOT(coinControlChangeEdited(const QString &)));
48 
49  // Coin Control: clipboard actions
50  QAction *clipboardQuantityAction = new QAction(tr("Copy quantity"), this);
51  QAction *clipboardAmountAction = new QAction(tr("Copy amount"), this);
52  QAction *clipboardFeeAction = new QAction(tr("Copy fee"), this);
53  QAction *clipboardAfterFeeAction = new QAction(tr("Copy after fee"), this);
54  QAction *clipboardBytesAction = new QAction(tr("Copy bytes"), this);
55  QAction *clipboardPriorityAction = new QAction(tr("Copy priority"), this);
56  QAction *clipboardLowOutputAction = new QAction(tr("Copy low output"), this);
57  QAction *clipboardChangeAction = new QAction(tr("Copy change"), this);
58  connect(clipboardQuantityAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardQuantity()));
59  connect(clipboardAmountAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardAmount()));
60  connect(clipboardFeeAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardFee()));
61  connect(clipboardAfterFeeAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardAfterFee()));
62  connect(clipboardBytesAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardBytes()));
63  connect(clipboardPriorityAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardPriority()));
64  connect(clipboardLowOutputAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardLowOutput()));
65  connect(clipboardChangeAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardChange()));
66  ui->labelCoinControlQuantity->addAction(clipboardQuantityAction);
67  ui->labelCoinControlAmount->addAction(clipboardAmountAction);
68  ui->labelCoinControlFee->addAction(clipboardFeeAction);
69  ui->labelCoinControlAfterFee->addAction(clipboardAfterFeeAction);
70  ui->labelCoinControlBytes->addAction(clipboardBytesAction);
71  ui->labelCoinControlPriority->addAction(clipboardPriorityAction);
72  ui->labelCoinControlLowOutput->addAction(clipboardLowOutputAction);
73  ui->labelCoinControlChange->addAction(clipboardChangeAction);
74 
75  fNewRecipientAllowed = true;
76 }
77 
79 {
80  this->model = model;
81 
82  if(model && model->getOptionsModel())
83  {
84  for(int i = 0; i < ui->entries->count(); ++i)
85  {
86  SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget());
87  if(entry)
88  {
89  entry->setModel(model);
90  }
91  }
92 
93  setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance());
94  connect(model, SIGNAL(balanceChanged(qint64, qint64, qint64)), this, SLOT(setBalance(qint64, qint64, qint64)));
95  connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
96 
97  // Coin Control
98  connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(coinControlUpdateLabels()));
99  connect(model->getOptionsModel(), SIGNAL(coinControlFeaturesChanged(bool)), this, SLOT(coinControlFeatureChanged(bool)));
100  connect(model->getOptionsModel(), SIGNAL(transactionFeeChanged(qint64)), this, SLOT(coinControlUpdateLabels()));
101  ui->frameCoinControl->setVisible(model->getOptionsModel()->getCoinControlFeatures());
103  }
104 }
105 
107 {
108  delete ui;
109 }
110 
112 {
113  if(!model || !model->getOptionsModel())
114  return;
115 
116  QList<SendCoinsRecipient> recipients;
117  bool valid = true;
118 
119  for(int i = 0; i < ui->entries->count(); ++i)
120  {
121  SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget());
122  if(entry)
123  {
124  if(entry->validate())
125  {
126  recipients.append(entry->getValue());
127  }
128  else
129  {
130  valid = false;
131  }
132  }
133  }
134 
135  if(!valid || recipients.isEmpty())
136  {
137  return;
138  }
139 
140  // Format confirmation message
141  QStringList formatted;
142  foreach(const SendCoinsRecipient &rcp, recipients)
143  {
144  // generate bold amount string
145  QString amount = "<b>" + BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount);
146  amount.append("</b>");
147  // generate monospace address string
148  QString address = "<span style='font-family: monospace;'>" + rcp.address;
149  address.append("</span>");
150 
151  QString recipientElement;
152 
153  if (!rcp.paymentRequest.IsInitialized()) // normal payment
154  {
155  if(rcp.label.length() > 0) // label with address
156  {
157  recipientElement = tr("%1 to %2").arg(amount, GUIUtil::HtmlEscape(rcp.label));
158  recipientElement.append(QString(" (%1)").arg(address));
159  }
160  else // just address
161  {
162  recipientElement = tr("%1 to %2").arg(amount, address);
163  }
164  }
165  else if(!rcp.authenticatedMerchant.isEmpty()) // secure payment request
166  {
167  recipientElement = tr("%1 to %2").arg(amount, GUIUtil::HtmlEscape(rcp.authenticatedMerchant));
168  }
169  else // insecure payment request
170  {
171  recipientElement = tr("%1 to %2").arg(amount, address);
172  }
173 
174  formatted.append(recipientElement);
175  }
176 
177  fNewRecipientAllowed = false;
178 
179 
181  if(!ctx.isValid())
182  {
183  // Unlock wallet was cancelled
184  fNewRecipientAllowed = true;
185  return;
186  }
187 
188  // prepare transaction for getting txFee earlier
189  WalletModelTransaction currentTransaction(recipients);
190  WalletModel::SendCoinsReturn prepareStatus;
191  if (model->getOptionsModel()->getCoinControlFeatures()) // coin control enabled
192  prepareStatus = model->prepareTransaction(currentTransaction, CoinControlDialog::coinControl);
193  else
194  prepareStatus = model->prepareTransaction(currentTransaction);
195 
196  // process prepareStatus and on error generate message shown to user
197  processSendCoinsReturn(prepareStatus,
199 
200  if(prepareStatus.status != WalletModel::OK) {
201  fNewRecipientAllowed = true;
202  return;
203  }
204 
205  qint64 txFee = currentTransaction.getTransactionFee();
206  QString questionString = tr("Are you sure you want to send?");
207  questionString.append("<br /><br />%1");
208 
209  if(txFee > 0)
210  {
211  // append fee string if a fee is required
212  questionString.append("<hr /><span style='color:#aa0000;'>");
213  questionString.append(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), txFee));
214  questionString.append("</span> ");
215  questionString.append(tr("added as transaction fee"));
216  }
217 
218  // add total amount in all subdivision units
219  questionString.append("<hr />");
220  qint64 totalAmount = currentTransaction.getTotalTransactionAmount() + txFee;
221  QStringList alternativeUnits;
223  {
224  if(u != model->getOptionsModel()->getDisplayUnit())
225  alternativeUnits.append(BitcoinUnits::formatWithUnit(u, totalAmount));
226  }
227  questionString.append(tr("Total Amount %1 (= %2)")
229  .arg(alternativeUnits.join(" " + tr("or") + " ")));
230 
231  QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm send coins"),
232  questionString.arg(formatted.join("<br />")),
233  QMessageBox::Yes | QMessageBox::Cancel,
234  QMessageBox::Cancel);
235 
236  if(retval != QMessageBox::Yes)
237  {
238  fNewRecipientAllowed = true;
239  return;
240  }
241 
242  // now send the prepared transaction
243  WalletModel::SendCoinsReturn sendStatus = model->sendCoins(currentTransaction);
244  // process sendStatus and on error generate message shown to user
245  processSendCoinsReturn(sendStatus);
246 
247  if (sendStatus.status == WalletModel::OK)
248  {
249  accept();
252  }
253  fNewRecipientAllowed = true;
254 }
255 
257 {
258  // Remove entries until only one left
259  while(ui->entries->count())
260  {
261  ui->entries->takeAt(0)->widget()->deleteLater();
262  }
263  addEntry();
264 
266 }
267 
269 {
270  clear();
271 }
272 
274 {
275  clear();
276 }
277 
279 {
280  SendCoinsEntry *entry = new SendCoinsEntry(this);
281  entry->setModel(model);
282  ui->entries->addWidget(entry);
283  connect(entry, SIGNAL(removeEntry(SendCoinsEntry*)), this, SLOT(removeEntry(SendCoinsEntry*)));
284  connect(entry, SIGNAL(payAmountChanged()), this, SLOT(coinControlUpdateLabels()));
285 
287 
288  // Focus the field, so that entry can start immediately
289  entry->clear();
290  entry->setFocus();
292  qApp->processEvents();
293  QScrollBar* bar = ui->scrollArea->verticalScrollBar();
294  if(bar)
295  bar->setSliderPosition(bar->maximum());
296  return entry;
297 }
298 
300 {
301  setupTabChain(0);
303 }
304 
306 {
307  entry->hide();
308 
309  // If the last entry is about to be removed add an empty one
310  if (ui->entries->count() == 1)
311  addEntry();
312 
313  entry->deleteLater();
314 
316 }
317 
319 {
320  for(int i = 0; i < ui->entries->count(); ++i)
321  {
322  SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget());
323  if(entry)
324  {
325  prev = entry->setupTabChain(prev);
326  }
327  }
328  QWidget::setTabOrder(prev, ui->sendButton);
329  QWidget::setTabOrder(ui->sendButton, ui->clearButton);
330  QWidget::setTabOrder(ui->clearButton, ui->addButton);
331  return ui->addButton;
332 }
333 
334 void SendCoinsDialog::setAddress(const QString &address)
335 {
336  SendCoinsEntry *entry = 0;
337  // Replace the first entry if it is still unused
338  if(ui->entries->count() == 1)
339  {
340  SendCoinsEntry *first = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(0)->widget());
341  if(first->isClear())
342  {
343  entry = first;
344  }
345  }
346  if(!entry)
347  {
348  entry = addEntry();
349  }
350 
351  entry->setAddress(address);
352 }
353 
355 {
357  return;
358 
359  SendCoinsEntry *entry = 0;
360  // Replace the first entry if it is still unused
361  if(ui->entries->count() == 1)
362  {
363  SendCoinsEntry *first = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(0)->widget());
364  if(first->isClear())
365  {
366  entry = first;
367  }
368  }
369  if(!entry)
370  {
371  entry = addEntry();
372  }
373 
374  entry->setValue(rv);
376 }
377 
379 {
380  QString strSendCoins = tr("Send Coins");
381  if (rv.paymentRequest.IsInitialized()) {
382  // Expired payment request?
383  const payments::PaymentDetails& details = rv.paymentRequest.getDetails();
384  if (details.has_expires() && (int64_t)details.expires() < GetTime())
385  {
386  emit message(strSendCoins, tr("Payment request expired"),
388  return false;
389  }
390  }
391  else {
392  CBitcoinAddress address(rv.address.toStdString());
393  if (!address.IsValid()) {
394  emit message(strSendCoins, tr("Invalid payment address %1").arg(rv.address),
396  return false;
397  }
398  }
399 
400  pasteEntry(rv);
401  return true;
402 }
403 
404 void SendCoinsDialog::setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance)
405 {
406  Q_UNUSED(unconfirmedBalance);
407  Q_UNUSED(immatureBalance);
408 
409  if(model && model->getOptionsModel())
410  {
412  }
413 }
414 
416 {
417  setBalance(model->getBalance(), 0, 0);
418 }
419 
420 void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn, const QString &msgArg)
421 {
422  QPair<QString, CClientUIInterface::MessageBoxFlags> msgParams;
423  // Default to a warning message, override if error message is needed
424  msgParams.second = CClientUIInterface::MSG_WARNING;
425 
426  // This comment is specific to SendCoinsDialog usage of WalletModel::SendCoinsReturn.
427  // WalletModel::TransactionCommitFailed is used only in WalletModel::sendCoins()
428  // all others are used only in WalletModel::prepareTransaction()
429  switch(sendCoinsReturn.status)
430  {
432  msgParams.first = tr("The recipient address is not valid, please recheck.");
433  break;
435  msgParams.first = tr("The amount to pay must be larger than 0.");
436  break;
438  msgParams.first = tr("The amount exceeds your balance.");
439  break;
441  msgParams.first = tr("The total exceeds your balance when the %1 transaction fee is included.").arg(msgArg);
442  break;
444  msgParams.first = tr("Duplicate address found, can only send to each address once per send operation.");
445  break;
447  msgParams.first = tr("Transaction creation failed!");
448  msgParams.second = CClientUIInterface::MSG_ERROR;
449  break;
451  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.");
452  msgParams.second = CClientUIInterface::MSG_ERROR;
453  break;
454  // included to prevent a compiler warning.
455  case WalletModel::OK:
456  default:
457  return;
458  }
459 
460  emit message(tr("Send Coins"), msgParams.first, msgParams.second);
461 }
462 
463 // Coin Control: copy label "Quantity" to clipboard
465 {
467 }
468 
469 // Coin Control: copy label "Amount" to clipboard
471 {
472  GUIUtil::setClipboard(ui->labelCoinControlAmount->text().left(ui->labelCoinControlAmount->text().indexOf(" ")));
473 }
474 
475 // Coin Control: copy label "Fee" to clipboard
477 {
478  GUIUtil::setClipboard(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" ")));
479 }
480 
481 // Coin Control: copy label "After fee" to clipboard
483 {
484  GUIUtil::setClipboard(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" ")));
485 }
486 
487 // Coin Control: copy label "Bytes" to clipboard
489 {
491 }
492 
493 // Coin Control: copy label "Priority" to clipboard
495 {
497 }
498 
499 // Coin Control: copy label "Low output" to clipboard
501 {
503 }
504 
505 // Coin Control: copy label "Change" to clipboard
507 {
508  GUIUtil::setClipboard(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" ")));
509 }
510 
511 // Coin Control: settings menu - coin control enabled/disabled by user
513 {
514  ui->frameCoinControl->setVisible(checked);
515 
516  if (!checked && model) // coin control features disabled
518 
519  if (checked)
521 }
522 
523 // Coin Control: button inputs -> show actual coin control dialog
525 {
526  CoinControlDialog dlg;
527  dlg.setModel(model);
528  dlg.exec();
530 }
531 
532 // Coin Control: checkbox custom change address
534 {
535  if (state == Qt::Unchecked)
536  {
539  }
540  else
541  // use this to re-validate an already entered address
543 
544  ui->lineEditCoinControlChange->setEnabled((state == Qt::Checked));
545 }
546 
547 // Coin Control: custom change address changed
549 {
550  if (model && model->getAddressTableModel())
551  {
552  // Default to no change address until verified
554  ui->labelCoinControlChangeLabel->setStyleSheet("QLabel{color:red;}");
555 
556  CBitcoinAddress addr = CBitcoinAddress(text.toStdString());
557 
558  if (text.isEmpty()) // Nothing entered
559  {
560  ui->labelCoinControlChangeLabel->setText("");
561  }
562  else if (!addr.IsValid()) // Invalid address
563  {
564  ui->labelCoinControlChangeLabel->setText(tr("Warning: Invalid Bitcoin address"));
565  }
566  else // Valid address
567  {
568  CPubKey pubkey;
569  CKeyID keyid;
570  addr.GetKeyID(keyid);
571  if (!model->getPubKey(keyid, pubkey)) // Unknown change address
572  {
573  ui->labelCoinControlChangeLabel->setText(tr("Warning: Unknown change address"));
574  }
575  else // Known change address
576  {
577  ui->labelCoinControlChangeLabel->setStyleSheet("QLabel{color:black;}");
578 
579  // Query label
580  QString associatedLabel = model->getAddressTableModel()->labelForAddress(text);
581  if (!associatedLabel.isEmpty())
582  ui->labelCoinControlChangeLabel->setText(associatedLabel);
583  else
584  ui->labelCoinControlChangeLabel->setText(tr("(no label)"));
585 
587  }
588  }
589  }
590 }
591 
592 // Coin Control: update labels
594 {
596  return;
597 
598  // set pay amounts
600  for(int i = 0; i < ui->entries->count(); ++i)
601  {
602  SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget());
603  if(entry)
605  }
606 
607  if (CoinControlDialog::coinControl->HasSelected())
608  {
609  // actual coin control calculation
611 
612  // show coin control stats
614  ui->widgetCoinControl->show();
615  }
616  else
617  {
618  // hide coin control stats
620  ui->widgetCoinControl->hide();
622  }
623 }
bool IsValid() const
Definition: base58.cpp:215
void removeEntry(SendCoinsEntry *entry)
Unit
Bitcoin units.
Definition: bitcoinunits.h:24
void setValue(const SendCoinsRecipient &value)
PaymentRequestPlus paymentRequest
Definition: walletmodel.h:55
bool IsInitialized() const
static QString formatWithUnit(int unit, qint64 amount, bool plussign=false)
Format as string (with unit)
void coinControlClipboardPriority()
qint64 getImmatureBalance() const
Definition: walletmodel.cpp:74
static CCoinControl * coinControl
void setFocus()
QLabel * labelCoinControlPriority
SendCoinsRecipient getValue()
UnlockContext requestUnlock()
QPushButton * clearButton
QPushButton * sendButton
SendCoinsDialog(QWidget *parent=0)
void coinControlClipboardQuantity()
QPushButton * addButton
void coinControlClipboardAfterFee()
void setAddress(const QString &address)
QValidatedLineEdit * lineEditCoinControlChange
inline::google::protobuf::uint64 expires() const
SendCoinsReturn sendCoins(WalletModelTransaction &transaction)
QString HtmlEscape(const QString &str, bool fMultiLine)
Definition: guiutil.cpp:222
bool handlePaymentRequest(const SendCoinsRecipient &recipient)
QScrollArea * scrollArea
base58-encoded Bitcoin addresses.
Definition: base58.h:101
QLabel * labelCoinControlAfterFee
AddressTableModel * getAddressTableModel()
CTxDestination Get() const
Definition: base58.cpp:222
bool validate()
QLabel * labelCoinControlQuantity
A single entry in the dialog for sending bitcoins.
QLabel * labelCoinControlLowOutput
QPushButton * pushButtonCoinControl
QLabel * labelCoinControlAutomaticallySelected
void coinControlFeatureChanged(bool)
bool GetKeyID(CKeyID &keyID) const
Definition: base58.cpp:235
QWidget * setupTabChain(QWidget *prev)
Set up the tab chain manually, as Qt messes up the tab chain by default in some cases (issue https://...
bool getCoinControlFeatures()
Definition: optionsmodel.h:62
QWidget * setupTabChain(QWidget *prev)
Set up the tab chain manually, as Qt messes up the tab chain by default in some cases (issue https://...
Ui::SendCoinsDialog * ui
SendCoinsEntry * addEntry()
void clear()
void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent)
Definition: guiutil.cpp:94
void setAddress(const QString &address)
void coinControlClipboardChange()
void setClipboard(const QString &str)
Definition: guiutil.cpp:755
void SetNull()
Definition: coincontrol.h:21
CTxDestination destChange
Definition: coincontrol.h:14
qint64 getUnconfirmedBalance() const
Definition: walletmodel.cpp:69
An encapsulated public key.
Definition: key.h:42
bool getPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const
WalletModel * model
Dialog for sending bitcoins.
QCheckBox * checkBoxCoinControlChange
void coinControlChangeEdited(const QString &)
static void updateLabels(WalletModel *, QDialog *)
const payments::PaymentDetails & getDetails() const
int getDisplayUnit()
Definition: optionsmodel.h:58
int64_t GetTime()
Definition: util.cpp:1215
void coinControlUpdateLabels()
void UnSelectAll()
Definition: coincontrol.h:48
void setModel(WalletModel *model)
void setupUi(QDialog *SendCoinsDialog)
bool isClear()
Return whether the entry is still empty and unedited.
void coinControlClipboardLowOutput()
QLabel * labelCoinControlChangeLabel
QWidget * scrollAreaWidgetContents
static QList< Unit > availableUnits()
Get list of units, for drop-down box.
void setModel(WalletModel *model)
QString labelForAddress(const QString &address) const
Interface to Bitcoin wallet from Qt view code.
Definition: walletmodel.h:96
A reference to a CKey: the Hash160 of its serialized public key.
Definition: key.h:26
qint64 getBalance(const CCoinControl *coinControl=NULL) const
Definition: walletmodel.cpp:53
void setModel(WalletModel *model)
void processSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn, const QString &msgArg=QString())
Data model for a walletmodel transaction.
static QList< qint64 > payAmounts
SendCoinsReturn prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl=NULL)
void setEnabled(bool enabled)
void coinControlClipboardBytes()
void coinControlClipboardAmount()
void pasteEntry(const SendCoinsRecipient &rv)
void message(const QString &title, const QString &message, unsigned int style)
QString authenticatedMerchant
Definition: walletmodel.h:57
void coinControlButtonClicked()
void coinControlClipboardFee()
OptionsModel * getOptionsModel()
QLabel * labelCoinControlInsuffFunds
void setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance)
void coinControlChangeChecked(int)