Skip to content

Commit

Permalink
Implement consolidateunspent wizard
Browse files Browse the repository at this point in the history
This implements a three step wizard that leads the user through
the process of selecting inputs, selecting a destination, and
then reviewing the overall transaction.

Select Inputs:

The select inputs screen uses similar code to that in coincontroldialog
to support the consolidate button there. Pointers to the coincontrol
data structures constructed in sendcoinsdialog are passed into
both coincontrol and the consolidateunspentwizard to faciliate using
the underlying machinery in a unified manner. This is possible because
both coincontrol and consolidateunspendwizard are called with the
sendcoinsdialog and are modal.

Note that there is a stop sign and the next button is disabled if more than
600 outputs are selected. The next button is also disabled if less than 2
outputs are selected (as it makes no sense to consolidate when there is no
consolidation achievable based on the selection). If a filter operation
is applied based on the filter criteria, and that criteria would result in
more than 600 inputs being selected, the selection is reduced to 600 inputs
and a warning triangle is presented.

Select Destination Address:

If all of the inputs selected in the prior page are from one address, then
that address will already be preselected (but allow the opportunity for it
to be changed by the user prior to pressing next). If the inputs selected
correspond to more than one address, an address will NOT be pre-selected,
and the user will be required to pick an address to proceed. The next button
will be disabled until a valid address is selected for the destination.

Confirmation:

The final screen presents the details of the intended transaction for review
by the user. When the "Finish" button is pressed, the transaction to send
is filled in in the send dialog sreen, and the user can review the details
again if desired and press the send button to send.
  • Loading branch information
jamescowens committed May 6, 2021
1 parent 851744b commit e17906a
Show file tree
Hide file tree
Showing 19 changed files with 1,956 additions and 30 deletions.
16 changes: 16 additions & 0 deletions src/Makefile.qt.include
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ QT_FORMS_UI = \
qt/forms/aboutdialog.ui \
qt/forms/coincontroldialog.ui \
qt/forms/consolidateunspentdialog.ui \
qt/forms/consolidateunspentwizard.ui \
qt/forms/consolidateunspentwizardselectdestinationpage.ui \
qt/forms/consolidateunspentwizardselectinputspage.ui \
qt/forms/consolidateunspentwizardsendpage.ui \
qt/forms/diagnosticsdialog.ui \
qt/forms/optionsdialog.ui \
qt/forms/rpcconsole.ui \
Expand Down Expand Up @@ -113,6 +117,10 @@ QT_MOC_CPP = \
qt/moc_coincontroldialog.cpp \
qt/moc_coincontroltreewidget.cpp \
qt/moc_consolidateunspentdialog.cpp \
qt/moc_consolidateunspentwizard.cpp \
qt/moc_consolidateunspentwizardselectdestinationpage.cpp \
qt/moc_consolidateunspentwizardselectinputspage.cpp \
qt/moc_consolidateunspentwizardsendpage.cpp \
qt/moc_csvmodelwriter.cpp \
qt/moc_diagnosticsdialog.cpp \
qt/moc_editaddressdialog.cpp \
Expand Down Expand Up @@ -184,6 +192,10 @@ GRIDCOINRESEARCH_QT_H = \
qt/coincontroldialog.h \
qt/coincontroltreewidget.h \
qt/consolidateunspentdialog.h \
qt/consolidateunspentwizard.h \
qt/consolidateunspentwizardselectdestinationpage.h \
qt/consolidateunspentwizardselectinputspage.h \
qt/consolidateunspentwizardsendpage.h \
qt/csvmodelwriter.h \
qt/decoration.h \
qt/diagnosticsdialog.h \
Expand Down Expand Up @@ -247,6 +259,10 @@ GRIDCOINRESEARCH_QT_CPP = \
qt/coincontroldialog.cpp \
qt/coincontroltreewidget.cpp \
qt/consolidateunspentdialog.cpp \
qt/consolidateunspentwizard.cpp \
qt/consolidateunspentwizardselectdestinationpage.cpp \
qt/consolidateunspentwizardselectinputspage.cpp \
qt/consolidateunspentwizardsendpage.cpp \
qt/csvmodelwriter.cpp \
qt/decoration.cpp \
qt/diagnosticsdialog.cpp \
Expand Down
25 changes: 15 additions & 10 deletions src/qt/coincontroldialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@
#include <QTreeWidgetItem>

using namespace std;
QList<qint64> CoinControlDialog::payAmounts;
CCoinControl* CoinControlDialog::coinControl = new CCoinControl();

CoinControlDialog::CoinControlDialog(QWidget *parent) :
CoinControlDialog::CoinControlDialog(QWidget *parent, CCoinControl *coinControl, QList<qint64> *payAmounts) :
QDialog(parent),
m_inputSelectionLimit(GetMaxInputsForConsolidationTxn()),
ui(new Ui::CoinControlDialog),
coinControl(coinControl),
payAmounts(payAmounts),
model(0)
{
ui->setupUi(this);
Expand Down Expand Up @@ -158,7 +158,7 @@ void CoinControlDialog::setModel(WalletModel *model)
{
updateView();
//updateLabelLocked();
CoinControlDialog::updateLabels(model, this);
CoinControlDialog::updateLabels(model, coinControl, payAmounts, this);
}
}

Expand Down Expand Up @@ -226,7 +226,7 @@ void CoinControlDialog::buttonSelectAllClicked()
ui->selectAllPushButton->setText("Select None");
}

CoinControlDialog::updateLabels(model, this);
CoinControlDialog::updateLabels(model, coinControl, payAmounts, this);
showHideConsolidationReadyToSend();
}

Expand Down Expand Up @@ -353,7 +353,7 @@ bool CoinControlDialog::filterInputsByValue(const bool& less, const CAmount& inp
// Reenable update signals.
ui->treeWidget->setEnabled(true);

CoinControlDialog::updateLabels(model, this);
CoinControlDialog::updateLabels(model, coinControl, payAmounts, this);

// If the number of inputs selected was limited, then true is returned.
return culled_inputs;
Expand Down Expand Up @@ -596,7 +596,9 @@ void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column)

// selection changed -> update labels
if (ui->treeWidget->isEnabled()) // do not update on every click for (un)select all
CoinControlDialog::updateLabels(model, this);
{
CoinControlDialog::updateLabels(model, coinControl, payAmounts, this);
}
}

showHideConsolidationReadyToSend();
Expand Down Expand Up @@ -633,7 +635,10 @@ QString CoinControlDialog::getPriorityLabel(double dPriority)
else ui->labelLocked->setVisible(false);
}*/

void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
void CoinControlDialog::updateLabels(WalletModel *model,
CCoinControl *coinControl,
QList<qint64>* payAmounts,
QDialog* dialog)
{
if (!model) return;

Expand All @@ -642,7 +647,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
bool fLowOutput = false;
bool fDust = false;
CTransaction txDummy;
foreach(const qint64 &amount, CoinControlDialog::payAmounts)
foreach(const qint64 &amount, *payAmounts)
{
nPayAmount += amount;

Expand Down Expand Up @@ -704,7 +709,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
if (nQuantity > 0)
{
// Bytes
nBytes = nBytesInputs + ((CoinControlDialog::payAmounts.size() > 0 ? CoinControlDialog::payAmounts.size() + 1 : 2) * 34) + 10; // always assume +1 output for change here
nBytes = nBytesInputs + ((payAmounts->size() > 0 ? payAmounts->size() + 1 : 2) * 34) + 10; // always assume +1 output for change here

// Priority
dPriority = dPriorityInputs / nBytes;
Expand Down
12 changes: 8 additions & 4 deletions src/qt/coincontroldialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,19 @@ class CoinControlDialog : public QDialog
Q_OBJECT

public:
explicit CoinControlDialog(QWidget *parent = 0);
explicit CoinControlDialog(QWidget *parent = 0,
CCoinControl *coinControl = nullptr,
QList<qint64> *payAmounts = nullptr);
~CoinControlDialog();

void setModel(WalletModel *model);

// static because also called from sendcoinsdialog
static void updateLabels(WalletModel*, QDialog*);
static void updateLabels(WalletModel*, CCoinControl*, QList<qint64>*, QDialog*);
static QString getPriorityLabel(double);

static QList<qint64> payAmounts;
static CCoinControl *coinControl;
//static QList<qint64> payAmounts;
//static CCoinControl *coinControl;

// This is based on what will guarantee a successful transaction.
const size_t m_inputSelectionLimit;
Expand All @@ -47,6 +49,8 @@ public slots:

private:
Ui::CoinControlDialog *ui;
CCoinControl *coinControl;
QList<qint64> *payAmounts;
WalletModel *model;
int sortColumn;
Qt::SortOrder sortOrder;
Expand Down
4 changes: 3 additions & 1 deletion src/qt/consolidateunspentdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

#include <QDialogButtonBox>
#include <QDialog>
#include <QWizard>
#include <QString>
#include <QLabel>

namespace Ui {
class ConsolidateUnspentDialog;
Expand All @@ -14,7 +16,7 @@ class ConsolidateUnspentDialog : public QDialog
Q_OBJECT

public:
explicit ConsolidateUnspentDialog(QWidget *parent = 0, size_t inputSelectionLimit = 600);
explicit ConsolidateUnspentDialog(QWidget *parent = nullptr, size_t inputSelectionLimit = 600);
~ConsolidateUnspentDialog();

void SetAddressList(const std::map<QString, QString>& addressList);
Expand Down
59 changes: 59 additions & 0 deletions src/qt/consolidateunspentwizard.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#include "coincontroldialog.h"
#include "consolidateunspentwizard.h"
#include "consolidateunspentdialog.h"
#include "ui_consolidateunspentwizard.h"

#include "util.h"


ConsolidateUnspentWizard::ConsolidateUnspentWizard(QWidget *parent,
CCoinControl *coinControl,
QList<qint64> *payAmounts,
size_t inputSelectionLimit) :
QWizard(parent),
ui(new Ui::ConsolidateUnspentWizard),
coinControl(coinControl),
payAmounts(payAmounts),
m_inputSelectionLimit(inputSelectionLimit)
{
ui->setupUi(this);
this->setStartId(SelectInputsPage);

ui->selectInputsPage->setCoinControl(coinControl);
ui->selectInputsPage->setPayAmounts(payAmounts);

connect(this, SIGNAL(setModelSignal(WalletModel*)), ui->selectInputsPage, SLOT(setModel(WalletModel*)));
connect(this, SIGNAL(setModelSignal(WalletModel*)), ui->sendPage, SLOT(setModel(WalletModel*)));

connect(ui->selectInputsPage, SIGNAL(setAddressListSignal(std::map<QString, QString>)),
ui->selectDestinationPage, SLOT(SetAddressList(const std::map<QString, QString>)));

connect(ui->selectInputsPage, SIGNAL(setDefaultAddressSignal(QString)),
ui->selectDestinationPage, SLOT(setDefaultAddressSelection(QString)));

connect(this->button(QWizard::FinishButton), SIGNAL(clicked()), ui->sendPage, SLOT(onFinishButtonClicked()));
connect(ui->sendPage, SIGNAL(selectedConsolidationRecipientSignal(SendCoinsRecipient)),
this, SIGNAL(selectedConsolidationRecipientSignal(SendCoinsRecipient)));
}

ConsolidateUnspentWizard::~ConsolidateUnspentWizard()
{
delete ui;
}

void ConsolidateUnspentWizard::accept()
{
QDialog::accept();
//emit sendConsolidationTransactionSignal();
}

void ConsolidateUnspentWizard::setModel(WalletModel *model)
{
this->model = model;
emit setModelSignal(model);
}

WalletModel* ConsolidateUnspentWizard::getModel()
{
return this->model;
}
56 changes: 56 additions & 0 deletions src/qt/consolidateunspentwizard.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#ifndef CONSOLIDATEUNSPENTWIZARD_H
#define CONSOLIDATEUNSPENTWIZARD_H

#include "walletmodel.h"

#include <QDialogButtonBox>
#include <QDialog>
#include <QWizard>
#include <QString>
#include <QLabel>

namespace Ui {
class ConsolidateUnspentWizard;
}

class CoinControlDialog;

class ConsolidateUnspentWizard : public QWizard
{
Q_OBJECT

public:
enum Pages
{
SelectInputsPage,
SelectDestinationPage,
SendPage
};

explicit ConsolidateUnspentWizard(QWidget *parent = nullptr,
CCoinControl *coinControl = nullptr,
QList<qint64> *payAmounts = nullptr,
size_t inputSelectionLimit = 600);
~ConsolidateUnspentWizard();

void setModel(WalletModel *model);
WalletModel* getModel();

void accept() override;

signals:
void setModelSignal(WalletModel*);
void passCoinControlSignal(CCoinControl*);
void selectedConsolidationRecipientSignal(SendCoinsRecipient);
void sendConsolidationTransactionSignal();

private:
Ui::ConsolidateUnspentWizard *ui;
CCoinControl *coinControl;
QList<qint64> *payAmounts;
WalletModel *model;

size_t m_inputSelectionLimit;
};

#endif // CONSOLIDATEUNSPENTWIZARD_H
Loading

0 comments on commit e17906a

Please sign in to comment.