Skip to content

Commit a8b5f1b

Browse files
committed
gui: Fix manual coin control with multiple wallets loaded
1 parent fbd5227 commit a8b5f1b

File tree

4 files changed

+45
-67
lines changed

4 files changed

+45
-67
lines changed

src/qt/coincontroldialog.cpp

Lines changed: 21 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,11 @@ bool CCoinControlWidgetItem::operator<(const QTreeWidgetItem &other) const {
4141
return QTreeWidgetItem::operator<(other);
4242
}
4343

44-
CoinControlDialog::CoinControlDialog(const PlatformStyle *_platformStyle, QWidget *parent) :
44+
CoinControlDialog::CoinControlDialog(CCoinControl& coin_control, WalletModel* _model, const PlatformStyle *_platformStyle, QWidget *parent) :
4545
QDialog(parent),
4646
ui(new Ui::CoinControlDialog),
47-
model(nullptr),
47+
m_coin_control(coin_control),
48+
model(_model),
4849
platformStyle(_platformStyle)
4950
{
5051
ui->setupUi(this);
@@ -136,6 +137,13 @@ CoinControlDialog::CoinControlDialog(const PlatformStyle *_platformStyle, QWidge
136137
sortView(settings.value("nCoinControlSortColumn").toInt(), (static_cast<Qt::SortOrder>(settings.value("nCoinControlSortOrder").toInt())));
137138

138139
GUIUtil::handleCloseWindowShortcut(this);
140+
141+
if(_model->getOptionsModel() && _model->getAddressTableModel())
142+
{
143+
updateView();
144+
updateLabelLocked();
145+
CoinControlDialog::updateLabels(m_coin_control, _model, this);
146+
}
139147
}
140148

141149
CoinControlDialog::~CoinControlDialog()
@@ -148,18 +156,6 @@ CoinControlDialog::~CoinControlDialog()
148156
delete ui;
149157
}
150158

151-
void CoinControlDialog::setModel(WalletModel *_model)
152-
{
153-
this->model = _model;
154-
155-
if(_model && _model->getOptionsModel() && _model->getAddressTableModel())
156-
{
157-
updateView();
158-
updateLabelLocked();
159-
CoinControlDialog::updateLabels(_model, this);
160-
}
161-
}
162-
163159
// ok button
164160
void CoinControlDialog::buttonBoxClicked(QAbstractButton* button)
165161
{
@@ -185,8 +181,8 @@ void CoinControlDialog::buttonSelectAllClicked()
185181
ui->treeWidget->topLevelItem(i)->setCheckState(COLUMN_CHECKBOX, state);
186182
ui->treeWidget->setEnabled(true);
187183
if (state == Qt::Unchecked)
188-
coinControl()->UnSelectAll(); // just to be sure
189-
CoinControlDialog::updateLabels(model, this);
184+
m_coin_control.UnSelectAll(); // just to be sure
185+
CoinControlDialog::updateLabels(m_coin_control, model, this);
190186
}
191187

192188
// context menu
@@ -371,15 +367,15 @@ void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column)
371367
COutPoint outpt(uint256S(item->data(COLUMN_ADDRESS, TxHashRole).toString().toStdString()), item->data(COLUMN_ADDRESS, VOutRole).toUInt());
372368

373369
if (item->checkState(COLUMN_CHECKBOX) == Qt::Unchecked)
374-
coinControl()->UnSelect(outpt);
370+
m_coin_control.UnSelect(outpt);
375371
else if (item->isDisabled()) // locked (this happens if "check all" through parent node)
376372
item->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
377373
else
378-
coinControl()->Select(outpt);
374+
m_coin_control.Select(outpt);
379375

380376
// selection changed -> update labels
381377
if (ui->treeWidget->isEnabled()) // do not update on every click for (un)select all
382-
CoinControlDialog::updateLabels(model, this);
378+
CoinControlDialog::updateLabels(m_coin_control, model, this);
383379
}
384380
}
385381

@@ -396,7 +392,7 @@ void CoinControlDialog::updateLabelLocked()
396392
else ui->labelLocked->setVisible(false);
397393
}
398394

399-
void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
395+
void CoinControlDialog::updateLabels(CCoinControl& m_coin_control, WalletModel *model, QDialog* dialog)
400396
{
401397
if (!model)
402398
return;
@@ -428,7 +424,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
428424
bool fWitness = false;
429425

430426
std::vector<COutPoint> vCoinControl;
431-
coinControl()->ListSelected(vCoinControl);
427+
m_coin_control.ListSelected(vCoinControl);
432428

433429
size_t i = 0;
434430
for (const auto& out : model->wallet().getCoins(vCoinControl)) {
@@ -439,7 +435,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
439435
const COutPoint& outpt = vCoinControl[i++];
440436
if (out.is_spent)
441437
{
442-
coinControl()->UnSelect(outpt);
438+
m_coin_control.UnSelect(outpt);
443439
continue;
444440
}
445441

@@ -492,7 +488,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
492488
nBytes -= 34;
493489

494490
// Fee
495-
nPayFee = model->wallet().getMinimumFee(nBytes, *coinControl(), nullptr /* returned_target */, nullptr /* reason */);
491+
nPayFee = model->wallet().getMinimumFee(nBytes, m_coin_control, nullptr /* returned_target */, nullptr /* reason */);
496492

497493
if (nPayAmount > 0)
498494
{
@@ -584,12 +580,6 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
584580
label->setVisible(nChange < 0);
585581
}
586582

587-
CCoinControl* CoinControlDialog::coinControl()
588-
{
589-
static CCoinControl coin_control;
590-
return &coin_control;
591-
}
592-
593583
void CoinControlDialog::updateView()
594584
{
595585
if (!model || !model->getOptionsModel() || !model->getAddressTableModel())
@@ -690,13 +680,13 @@ void CoinControlDialog::updateView()
690680
// disable locked coins
691681
if (model->wallet().isLockedCoin(output))
692682
{
693-
coinControl()->UnSelect(output); // just to be sure
683+
m_coin_control.UnSelect(output); // just to be sure
694684
itemOutput->setDisabled(true);
695685
itemOutput->setIcon(COLUMN_CHECKBOX, platformStyle->SingleColorIcon(":/icons/lock_closed"));
696686
}
697687

698688
// set checkbox
699-
if (coinControl()->IsSelected(output))
689+
if (m_coin_control.IsSelected(output))
700690
itemOutput->setCheckState(COLUMN_CHECKBOX, Qt::Checked);
701691
}
702692

src/qt/coincontroldialog.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,18 @@ class CoinControlDialog : public QDialog
4343
Q_OBJECT
4444

4545
public:
46-
explicit CoinControlDialog(const PlatformStyle *platformStyle, QWidget *parent = nullptr);
46+
explicit CoinControlDialog(CCoinControl& coin_control, WalletModel* model, const PlatformStyle *platformStyle, QWidget *parent = nullptr);
4747
~CoinControlDialog();
4848

49-
void setModel(WalletModel *model);
50-
5149
// static because also called from sendcoinsdialog
52-
static void updateLabels(WalletModel*, QDialog*);
50+
static void updateLabels(CCoinControl& m_coin_control, WalletModel*, QDialog*);
5351

5452
static QList<CAmount> payAmounts;
55-
static CCoinControl *coinControl();
5653
static bool fSubtractFeeFromAmount;
5754

5855
private:
5956
Ui::CoinControlDialog *ui;
57+
CCoinControl& m_coin_control;
6058
WalletModel *model;
6159
int sortColumn;
6260
Qt::SortOrder sortOrder;

src/qt/sendcoinsdialog.cpp

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ SendCoinsDialog::SendCoinsDialog(const PlatformStyle *_platformStyle, QWidget *p
5757
ui(new Ui::SendCoinsDialog),
5858
clientModel(nullptr),
5959
model(nullptr),
60+
m_coin_control(new CCoinControl),
6061
fNewRecipientAllowed(true),
6162
fFeeMinimized(true),
6263
platformStyle(_platformStyle)
@@ -259,14 +260,9 @@ bool SendCoinsDialog::PrepareSendText(QString& question_string, QString& informa
259260
m_current_transaction = MakeUnique<WalletModelTransaction>(recipients);
260261
WalletModel::SendCoinsReturn prepareStatus;
261262

262-
// Always use a CCoinControl instance, use the CoinControlDialog instance if CoinControl has been enabled
263-
CCoinControl ctrl;
264-
if (model->getOptionsModel()->getCoinControlFeatures())
265-
ctrl = *CoinControlDialog::coinControl();
263+
updateCoinControlState(*m_coin_control);
266264

267-
updateCoinControlState(ctrl);
268-
269-
prepareStatus = model->prepareTransaction(*m_current_transaction, ctrl);
265+
prepareStatus = model->prepareTransaction(*m_current_transaction, *m_coin_control);
270266

271267
// process prepareStatus and on error generate message shown to user
272268
processSendCoinsReturn(prepareStatus,
@@ -454,7 +450,7 @@ void SendCoinsDialog::on_sendButton_clicked()
454450
}
455451
if (!send_failure) {
456452
accept();
457-
CoinControlDialog::coinControl()->UnSelectAll();
453+
m_coin_control->UnSelectAll();
458454
coinControlUpdateLabels();
459455
}
460456
fNewRecipientAllowed = true;
@@ -466,7 +462,7 @@ void SendCoinsDialog::clear()
466462
m_current_transaction.reset();
467463

468464
// Clear coin control settings
469-
CoinControlDialog::coinControl()->UnSelectAll();
465+
m_coin_control->UnSelectAll();
470466
ui->checkBoxCoinControlChange->setChecked(false);
471467
ui->lineEditCoinControlChange->clear();
472468
coinControlUpdateLabels();
@@ -689,17 +685,11 @@ void SendCoinsDialog::on_buttonMinimizeFee_clicked()
689685

690686
void SendCoinsDialog::useAvailableBalance(SendCoinsEntry* entry)
691687
{
692-
// Get CCoinControl instance if CoinControl is enabled or create a new one.
693-
CCoinControl coin_control;
694-
if (model->getOptionsModel()->getCoinControlFeatures()) {
695-
coin_control = *CoinControlDialog::coinControl();
696-
}
697-
698688
// Include watch-only for wallets without private key
699-
coin_control.fAllowWatchOnly = model->wallet().privateKeysDisabled();
689+
m_coin_control->fAllowWatchOnly = model->wallet().privateKeysDisabled();
700690

701691
// Calculate available amount to send.
702-
CAmount amount = model->wallet().getAvailableBalance(coin_control);
692+
CAmount amount = model->wallet().getAvailableBalance(*m_coin_control);
703693
for (int i = 0; i < ui->entries->count(); ++i) {
704694
SendCoinsEntry* e = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget());
705695
if (e && !e->isHidden() && e != entry) {
@@ -758,12 +748,11 @@ void SendCoinsDialog::updateSmartFeeLabel()
758748
{
759749
if(!model || !model->getOptionsModel())
760750
return;
761-
CCoinControl coin_control;
762-
updateCoinControlState(coin_control);
763-
coin_control.m_feerate.reset(); // Explicitly use only fee estimation rate for smart fee labels
751+
updateCoinControlState(*m_coin_control);
752+
m_coin_control->m_feerate.reset(); // Explicitly use only fee estimation rate for smart fee labels
764753
int returned_target;
765754
FeeReason reason;
766-
CFeeRate feeRate = CFeeRate(model->wallet().getMinimumFee(1000, coin_control, &returned_target, &reason));
755+
CFeeRate feeRate = CFeeRate(model->wallet().getMinimumFee(1000, *m_coin_control, &returned_target, &reason));
767756

768757
ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), feeRate.GetFeePerK()) + "/kB");
769758

@@ -834,16 +823,15 @@ void SendCoinsDialog::coinControlFeatureChanged(bool checked)
834823
ui->frameCoinControl->setVisible(checked);
835824

836825
if (!checked && model) // coin control features disabled
837-
CoinControlDialog::coinControl()->SetNull();
826+
m_coin_control->SetNull();
838827

839828
coinControlUpdateLabels();
840829
}
841830

842831
// Coin Control: button inputs -> show actual coin control dialog
843832
void SendCoinsDialog::coinControlButtonClicked()
844833
{
845-
CoinControlDialog dlg(platformStyle);
846-
dlg.setModel(model);
834+
CoinControlDialog dlg(*m_coin_control, model, platformStyle);
847835
dlg.exec();
848836
coinControlUpdateLabels();
849837
}
@@ -853,7 +841,7 @@ void SendCoinsDialog::coinControlChangeChecked(int state)
853841
{
854842
if (state == Qt::Unchecked)
855843
{
856-
CoinControlDialog::coinControl()->destChange = CNoDestination();
844+
m_coin_control->destChange = CNoDestination();
857845
ui->labelCoinControlChangeLabel->clear();
858846
}
859847
else
@@ -869,7 +857,7 @@ void SendCoinsDialog::coinControlChangeEdited(const QString& text)
869857
if (model && model->getAddressTableModel())
870858
{
871859
// Default to no change address until verified
872-
CoinControlDialog::coinControl()->destChange = CNoDestination();
860+
m_coin_control->destChange = CNoDestination();
873861
ui->labelCoinControlChangeLabel->setStyleSheet("QLabel{color:red;}");
874862

875863
const CTxDestination dest = DecodeDestination(text.toStdString());
@@ -892,7 +880,7 @@ void SendCoinsDialog::coinControlChangeEdited(const QString& text)
892880
QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel);
893881

894882
if(btnRetVal == QMessageBox::Yes)
895-
CoinControlDialog::coinControl()->destChange = dest;
883+
m_coin_control->destChange = dest;
896884
else
897885
{
898886
ui->lineEditCoinControlChange->setText("");
@@ -911,7 +899,7 @@ void SendCoinsDialog::coinControlChangeEdited(const QString& text)
911899
else
912900
ui->labelCoinControlChangeLabel->setText(tr("(no label)"));
913901

914-
CoinControlDialog::coinControl()->destChange = dest;
902+
m_coin_control->destChange = dest;
915903
}
916904
}
917905
}
@@ -923,7 +911,7 @@ void SendCoinsDialog::coinControlUpdateLabels()
923911
if (!model || !model->getOptionsModel())
924912
return;
925913

926-
updateCoinControlState(*CoinControlDialog::coinControl());
914+
updateCoinControlState(*m_coin_control);
927915

928916
// set pay amounts
929917
CoinControlDialog::payAmounts.clear();
@@ -941,10 +929,10 @@ void SendCoinsDialog::coinControlUpdateLabels()
941929
}
942930
}
943931

944-
if (CoinControlDialog::coinControl()->HasSelected())
932+
if (m_coin_control->HasSelected())
945933
{
946934
// actual coin control calculation
947-
CoinControlDialog::updateLabels(model, this);
935+
CoinControlDialog::updateLabels(*m_coin_control, model, this);
948936

949937
// show coin control stats
950938
ui->labelCoinControlAutomaticallySelected->hide();

src/qt/sendcoinsdialog.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <QString>
1313
#include <QTimer>
1414

15+
class CCoinControl;
1516
class ClientModel;
1617
class PlatformStyle;
1718
class SendCoinsEntry;
@@ -60,6 +61,7 @@ public Q_SLOTS:
6061
Ui::SendCoinsDialog *ui;
6162
ClientModel *clientModel;
6263
WalletModel *model;
64+
std::unique_ptr<CCoinControl> m_coin_control;
6365
std::unique_ptr<WalletModelTransaction> m_current_transaction;
6466
bool fNewRecipientAllowed;
6567
bool fFeeMinimized;

0 commit comments

Comments
 (0)