From 04b2f5f9a05633a2d2156c93967107682f899044 Mon Sep 17 00:00:00 2001 From: tobtoht Date: Mon, 28 Jun 2021 18:05:21 +0200 Subject: [PATCH] Coins: Sweep selected --- src/appcontext.cpp | 11 +++++++++ src/appcontext.h | 1 + src/coinswidget.cpp | 38 +++++++++++++++++++++++++++++++- src/coinswidget.h | 3 +++ src/dialog/OutputSweepDialog.cpp | 5 ++--- src/dialog/OutputSweepDialog.h | 2 +- src/libwalletqt/Wallet.cpp | 23 +++++++++++++++++++ src/libwalletqt/Wallet.h | 8 +++++++ src/mainwindow.ui | 4 ++-- 9 files changed, 88 insertions(+), 7 deletions(-) diff --git a/src/appcontext.cpp b/src/appcontext.cpp index 96b4563..006f8c9 100644 --- a/src/appcontext.cpp +++ b/src/appcontext.cpp @@ -121,6 +121,17 @@ void AppContext::onSweepOutput(const QString &keyImage, QString address, bool ch emit initiateTransaction(); } +void AppContext::onSweepOutputs(const QVector &keyImages, QString address, bool churn, int outputs) { + if (churn) { + address = this->wallet->address(0, 0); + } + + qInfo() << "Creating transaction"; + this->wallet->createTransactionSelectedAsync(keyImages, address, outputs, this->tx_priority); + + emit initiateTransaction(); +} + void AppContext::onCreateTransactionError(const QString &msg) { this->tmpTxDescription = ""; emit endTransaction(); diff --git a/src/appcontext.h b/src/appcontext.h index ebf482b..1a7d4db 100644 --- a/src/appcontext.h +++ b/src/appcontext.h @@ -51,6 +51,7 @@ public slots: void onCreateTransactionMultiDest(const QVector &addresses, const QVector &amounts, const QString &description); void onCancelTransaction(PendingTransaction *tx, const QVector &address); void onSweepOutput(const QString &keyImage, QString address, bool churn, int outputs); + void onSweepOutputs(const QVector &keyImages, QString address, bool churn, int outputs); void onCreateTransactionError(const QString &msg); void onOpenAliasResolve(const QString &openAlias); void onSetRestoreHeight(quint64 height); diff --git a/src/coinswidget.cpp b/src/coinswidget.cpp index 55c9441..c6f0d08 100644 --- a/src/coinswidget.cpp +++ b/src/coinswidget.cpp @@ -47,10 +47,12 @@ CoinsWidget::CoinsWidget(QSharedPointer ctx, QWidget *parent) m_viewOutputAction = new QAction(icons()->icon("info2.svg"), "Details", this); m_sweepOutputAction = new QAction("Sweep output", this); + m_sweepOutputsAction = new QAction("Sweep selected outputs", this); connect(m_freezeOutputAction, &QAction::triggered, this, &CoinsWidget::freezeOutput); connect(m_thawOutputAction, &QAction::triggered, this, &CoinsWidget::thawOutput); connect(m_viewOutputAction, &QAction::triggered, this, &CoinsWidget::viewOutput); connect(m_sweepOutputAction, &QAction::triggered, this, &CoinsWidget::onSweepOutput); + connect(m_sweepOutputsAction, &QAction::triggered, this, &CoinsWidget::onSweepMulti); connect(m_freezeAllSelectedAction, &QAction::triggered, this, &CoinsWidget::freezeAllSelected); connect(m_thawAllSelectedAction, &QAction::triggered, this, &CoinsWidget::thawAllSelected); @@ -88,6 +90,7 @@ void CoinsWidget::showContextMenu(const QPoint &point) { if (list.size() > 1) { menu->addAction(m_freezeAllSelectedAction); menu->addAction(m_thawAllSelectedAction); + menu->addAction(m_sweepOutputsAction); } else { CoinsInfo* c = this->currentEntry(); @@ -178,7 +181,7 @@ void CoinsWidget::onSweepOutput() { return; } - auto *dialog = new OutputSweepDialog(this, c); + auto *dialog = new OutputSweepDialog(this, c->amount()); int ret = dialog->exec(); if (!ret) return; @@ -186,6 +189,30 @@ void CoinsWidget::onSweepOutput() { dialog->deleteLater(); } +void CoinsWidget::onSweepMulti() { + QVector selectedCoins = this->currentEntries(); + QVector keyImages; + + quint64 totalAmount = 0; + for (const auto coin : selectedCoins) { + if (!coin) return; + + QString keyImage = coin->keyImage(); + if (!coin->keyImageKnown()) { + QMessageBox::warning(this, "Unable to sweep output", "Unable to sweep output: key image unknown"); + return; + } + keyImages.push_back(keyImage); + totalAmount += coin->amount(); + } + + OutputSweepDialog dialog{this, totalAmount}; + int ret = dialog.exec(); + if (!ret) return; + + m_ctx->onSweepOutputs(keyImages, dialog.address(), dialog.churn(), dialog.outputs()); +} + void CoinsWidget::copy(copyField field) { CoinsInfo* c = this->currentEntry(); if (!c) return; @@ -227,6 +254,15 @@ CoinsInfo* CoinsWidget::currentEntry() { } } +QVector CoinsWidget::currentEntries() { + QModelIndexList list = ui->coins->selectionModel()->selectedRows(); + QVector selectedCoins; + for (const auto index : list) { + selectedCoins.push_back(m_model->entryFromIndex(m_proxyModel->mapToSource(index))); + } + return selectedCoins; +} + void CoinsWidget::freezeCoins(const QVector& indexes) { for (int i : indexes) { m_ctx->wallet->coins()->freeze(i); diff --git a/src/coinswidget.h b/src/coinswidget.h index 2be9650..e87f2f1 100644 --- a/src/coinswidget.h +++ b/src/coinswidget.h @@ -35,6 +35,7 @@ private slots: void thawAllSelected(); void viewOutput(); void onSweepOutput(); + void onSweepMulti(); private: void freezeCoins(const QVector& indexes); @@ -63,6 +64,7 @@ private: QAction *m_thawAllSelectedAction; QAction *m_viewOutputAction; QAction *m_sweepOutputAction; + QAction *m_sweepOutputsAction; Coins *m_coins; CoinsModel * m_model; CoinsProxyModel * m_proxyModel; @@ -70,6 +72,7 @@ private: void showContextMenu(const QPoint & point); void copy(copyField field); CoinsInfo* currentEntry(); + QVector currentEntries(); }; diff --git a/src/dialog/OutputSweepDialog.cpp b/src/dialog/OutputSweepDialog.cpp index 0bb1c58..7c7d2fb 100644 --- a/src/dialog/OutputSweepDialog.cpp +++ b/src/dialog/OutputSweepDialog.cpp @@ -6,14 +6,13 @@ #include "libwalletqt/WalletManager.h" -OutputSweepDialog::OutputSweepDialog(QWidget *parent, CoinsInfo *coin) +OutputSweepDialog::OutputSweepDialog(QWidget *parent, quint64 amount) : QDialog(parent) , ui(new Ui::OutputSweepDialog) + , m_amount(amount) { ui->setupUi(this); - m_amount = coin->amount(); - connect(ui->checkBox_churn, &QCheckBox::toggled, [&](bool toggled){ ui->lineEdit_address->setEnabled(!toggled); ui->lineEdit_address->setText(toggled ? "Primary address" : ""); diff --git a/src/dialog/OutputSweepDialog.h b/src/dialog/OutputSweepDialog.h index d5c9101..4b565fb 100644 --- a/src/dialog/OutputSweepDialog.h +++ b/src/dialog/OutputSweepDialog.h @@ -17,7 +17,7 @@ class OutputSweepDialog : public QDialog Q_OBJECT public: - explicit OutputSweepDialog(QWidget *parent, CoinsInfo *coin); + explicit OutputSweepDialog(QWidget *parent, quint64 amount); ~OutputSweepDialog() override; QString address(); diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp index 003fd36..c4943c1 100644 --- a/src/libwalletqt/Wallet.cpp +++ b/src/libwalletqt/Wallet.cpp @@ -723,6 +723,29 @@ void Wallet::createTransactionSingleAsync(const QString &key_image, const QStrin }); } +PendingTransaction *Wallet::createTransactionSelected(const QVector &key_images, const QString &dst_addr, + size_t outputs, PendingTransaction::Priority priority) +{ + std::vector kis; + for (const auto &key_image : key_images) { + kis.push_back(key_image.toStdString()); + } + Monero::PendingTransaction *ptImpl = m_walletImpl->createTransactionSelected(kis, dst_addr.toStdString(), outputs, static_cast(priority)); + PendingTransaction *result = new PendingTransaction(ptImpl, this); + + return result; +} + +void Wallet::createTransactionSelectedAsync(const QVector &key_images, const QString &dst_addr, + size_t outputs, PendingTransaction::Priority priority) +{ + m_scheduler.run([this, key_images, dst_addr, outputs, priority] { + PendingTransaction *tx = createTransactionSelected(key_images, dst_addr, outputs, priority); + QVector address {dst_addr}; + emit transactionCreated(tx, address); + }); +} + PendingTransaction *Wallet::createSweepUnmixableTransaction() { // pauseRefresh(); diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h index 94dcc25..5f0a65a 100644 --- a/src/libwalletqt/Wallet.h +++ b/src/libwalletqt/Wallet.h @@ -298,6 +298,14 @@ public: void createTransactionSingleAsync(const QString &key_image, const QString &dst_addr, size_t outputs, PendingTransaction::Priority priority); + //! creates transaction with selected inputs + PendingTransaction * createTransactionSelected(const QVector &key_images, const QString &dst_addr, + size_t outputs, PendingTransaction::Priority priority); + + //! creates async transaction with selected inputs + void createTransactionSelectedAsync(const QVector &key_images, const QString &dst_addr, + size_t outputs, PendingTransaction::Priority priority); + //! creates sweep unmixable transaction PendingTransaction * createSweepUnmixableTransaction(); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index fc0c81d..8748ebf 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -809,13 +809,13 @@ CCSWidget QWidget -
widgets/ccswidget.h
+
widgets/CCSWidget.h
1
RedditWidget QWidget -
widgets/redditwidget.h
+
widgets/RedditWidget.h
1