aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MiddlePanel.qml5
-rw-r--r--main.qml99
-rw-r--r--pages/Transfer.qml38
-rw-r--r--src/libwalletqt/Wallet.cpp45
-rw-r--r--src/libwalletqt/Wallet.h16
5 files changed, 178 insertions, 25 deletions
diff --git a/MiddlePanel.qml b/MiddlePanel.qml
index 7080e338..74c731c8 100644
--- a/MiddlePanel.qml
+++ b/MiddlePanel.qml
@@ -52,6 +52,7 @@ Rectangle {
signal paymentClicked(string address, string paymentId, string amount, int mixinCount, int priority, string description)
+ signal sweepUnmixableClicked()
signal generatePaymentIdInvoked()
signal checkPaymentClicked(string address, string txid, string txkey);
@@ -308,5 +309,9 @@ Rectangle {
console.log("MiddlePanel: paymentClicked")
paymentClicked(address, paymentId, amount, mixinCount, priority, description)
}
+ onSweepUnmixableClicked : {
+ console.log("MiddlePanel: sweepUnmixableClicked")
+ sweepUnmixableClicked()
+ }
}
}
diff --git a/main.qml b/main.qml
index 1114a56e..2e8d432c 100644
--- a/main.qml
+++ b/main.qml
@@ -157,6 +157,7 @@ ApplicationWindow {
middlePanel.checkPaymentClicked.disconnect(handleCheckPayment);
}
middlePanel.paymentClicked.connect(handlePayment);
+ middlePanel.sweepUnmixableClicked.connect(handleSweepUnmixable);
// basicPanel.paymentClicked.connect(handlePayment);
middlePanel.checkPaymentClicked.connect(handleCheckPayment);
@@ -385,6 +386,14 @@ ApplicationWindow {
// deleting transaction object, we don't want memleaks
currentWallet.disposeTransaction(transaction);
+ } else if (transaction.txCount == 0) {
+ informationPopup.title = qsTr("No unmixable outputs to sweep") + translationManager.emptyString
+ informationPopup.text = qsTr("No unmixable outputs to sweep") + translationManager.emptyString
+ informationPopup.icon = StandardIcon.Information
+ informationPopup.onCloseCallback = null
+ informationPopup.open()
+ // deleting transaction object, we don't want memleaks
+ currentWallet.disposeTransaction(transaction);
} else {
console.log("Transaction created, amount: " + walletManager.displayAmount(transaction.amount)
+ ", fee: " + walletManager.displayAmount(transaction.fee));
@@ -393,13 +402,13 @@ ApplicationWindow {
transactionConfirmationPopup.title = qsTr("Confirmation") + translationManager.emptyString
transactionConfirmationPopup.text = qsTr("Please confirm transaction:\n")
- + qsTr("\nAddress: ") + address
- + qsTr("\nPayment ID: ") + paymentId
+ + (address === "" ? "" : (qsTr("\nAddress: ") + address))
+ + (paymentId === "" ? "" : (qsTr("\nPayment ID: ") + paymentId))
+ qsTr("\n\nAmount: ") + walletManager.displayAmount(transaction.amount)
+ qsTr("\nFee: ") + walletManager.displayAmount(transaction.fee)
+ qsTr("\n\nMixin: ") + mixinCount
+ qsTr("\n\Number of transactions: ") + transaction.txCount
- + qsTr("\n\nDescription: ") + transactionDescription
+ + (transactionDescription === "" ? "" : (qsTr("\n\nDescription: ") + transactionDescription))
+ translationManager.emptyString
transactionConfirmationPopup.icon = StandardIcon.Question
transactionConfirmationPopup.open()
@@ -422,33 +431,77 @@ ApplicationWindow {
transactionDescription = description;
// validate amount;
- var amountxmr = walletManager.amountFromString(amount);
- console.log("integer amount: ", amountxmr);
- console.log("integer unlocked",currentWallet.unlockedBalance)
- if (amountxmr <= 0) {
- informationPopup.title = qsTr("Error") + translationManager.emptyString;
- informationPopup.text = qsTr("Amount is wrong: expected number from %1 to %2")
- .arg(walletManager.displayAmount(0))
- .arg(walletManager.maximumAllowedAmountAsSting())
- + translationManager.emptyString
+ if (amount !== "(all)") {
+ var amountxmr = walletManager.amountFromString(amount);
+ console.log("integer amount: ", amountxmr);
+ console.log("integer unlocked",currentWallet.unlockedBalance)
+ if (amountxmr <= 0) {
+ informationPopup.title = qsTr("Error") + translationManager.emptyString;
+ informationPopup.text = qsTr("Amount is wrong: expected number from %1 to %2")
+ .arg(walletManager.displayAmount(0))
+ .arg(walletManager.maximumAllowedAmountAsSting())
+ + translationManager.emptyString
+
+ informationPopup.icon = StandardIcon.Critical
+ informationPopup.onCloseCallback = null
+ informationPopup.open()
+ return;
+ } else if (amountxmr > currentWallet.unlockedBalance) {
+ informationPopup.title = qsTr("Error") + translationManager.emptyString;
+ informationPopup.text = qsTr("insufficient funds. Unlocked balance: %1")
+ .arg(walletManager.displayAmount(currentWallet.unlockedBalance))
+ + translationManager.emptyString
+ informationPopup.icon = StandardIcon.Critical
+ informationPopup.onCloseCallback = null
+ informationPopup.open()
+ return;
+ }
+ }
+
+ if (amount === "(all)")
+ currentWallet.createTransactionAllAsync(address, paymentId, amountxmr, mixinCount, priority);
+ else
+ currentWallet.createTransactionAsync(address, paymentId, amountxmr, mixinCount, priority);
+ }
+
+ function handleSweepUnmixable() {
+ console.log("Creating transaction: ")
+
+ transaction = currentWallet.createSweepUnmixableTransaction();
+ if (transaction.status !== PendingTransaction.Status_Ok) {
+ console.error("Can't create transaction: ", transaction.errorString);
+ informationPopup.title = qsTr("Error") + translationManager.emptyString;
+ informationPopup.text = qsTr("Can't create transaction: ") + transaction.errorString
informationPopup.icon = StandardIcon.Critical
informationPopup.onCloseCallback = null
- informationPopup.open()
- return;
- } else if (amountxmr > currentWallet.unlockedBalance) {
- informationPopup.title = qsTr("Error") + translationManager.emptyString;
- informationPopup.text = qsTr("insufficient funds. Unlocked balance: %1")
- .arg(walletManager.displayAmount(currentWallet.unlockedBalance))
- + translationManager.emptyString
+ informationPopup.open();
+ // deleting transaction object, we don't want memleaks
+ currentWallet.disposeTransaction(transaction);
- informationPopup.icon = StandardIcon.Critical
+ } else if (transaction.txCount == 0) {
+ informationPopup.title = qsTr("No unmixable outputs to sweep") + translationManager.emptyString
+ informationPopup.text = qsTr("No unmixable outputs to sweep") + translationManager.emptyString
+ informationPopup.icon = StandardIcon.Information
informationPopup.onCloseCallback = null
informationPopup.open()
- return;
- }
+ // deleting transaction object, we don't want memleaks
+ currentWallet.disposeTransaction(transaction);
+ } else {
+ console.log("Transaction created, amount: " + walletManager.displayAmount(transaction.amount)
+ + ", fee: " + walletManager.displayAmount(transaction.fee));
+
+ // here we show confirmation popup;
- currentWallet.createTransactionAsync(address, paymentId, amountxmr, mixinCount, priority);
+ transactionConfirmationPopup.title = qsTr("Confirmation") + translationManager.emptyString
+ transactionConfirmationPopup.text = qsTr("Please confirm transaction:\n")
+ + qsTr("\n\nAmount: ") + walletManager.displayAmount(transaction.amount)
+ + qsTr("\nFee: ") + walletManager.displayAmount(transaction.fee)
+ + translationManager.emptyString
+ transactionConfirmationPopup.icon = StandardIcon.Question
+ transactionConfirmationPopup.open()
+ // committing transaction
+ }
}
// called after user confirms transaction
diff --git a/pages/Transfer.qml b/pages/Transfer.qml
index 95c3e993..3c687ff1 100644
--- a/pages/Transfer.qml
+++ b/pages/Transfer.qml
@@ -35,6 +35,7 @@ Rectangle {
id: root
signal paymentClicked(string address, string paymentId, string amount, int mixinCount,
int priority, string description)
+ signal sweepUnmixableClicked()
color: "#F0EEEE"
@@ -88,7 +89,7 @@ Rectangle {
LineEdit {
id: amountLine
placeholderText: qsTr("") + translationManager.emptyString
- width: parent.width - 37 - 17
+ width: parent.width - 37 - 17 - 60
validator: DoubleValidator {
bottom: 0.0
top: 18446744.073709551615
@@ -97,6 +98,21 @@ Rectangle {
locale: "C"
}
}
+
+ StandardButton {
+ id: amountAllButton
+ //anchors.left: amountLine.right
+ //anchors.top: amountLine.top
+ //anchors.bottom: amountLine.bottom
+ width: 60
+ text: qsTr("or ALL") + translationManager.emptyString
+ shadowReleasedColor: "#FF4304"
+ shadowPressedColor: "#B32D00"
+ releasedColor: "#FF6C3C"
+ pressedColor: "#FF4304"
+ enabled : true
+ onClicked: amountLine.text = "(all)"
+ }
}
ListModel {
@@ -295,4 +311,24 @@ Rectangle {
}
}
+
+ StandardButton {
+ id: sweepUnmixableButton
+ anchors.right: parent.right
+ anchors.top: descriptionLine.bottom
+ anchors.rightMargin: 17
+ anchors.topMargin: 17
+ width: 60*2
+ text: qsTr("SWEEP UNMIXABLE") + translationManager.emptyString
+ shadowReleasedColor: "#FF4304"
+ shadowPressedColor: "#B32D00"
+ releasedColor: "#FF6C3C"
+ pressedColor: "#FF4304"
+ enabled : true
+ onClicked: {
+ console.log("Transfer: sweepUnmixableClicked")
+ root.sweepUnmixableClicked()
+
+ }
+ }
}
diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp
index 78cb6949..5f3cd5f3 100644
--- a/src/libwalletqt/Wallet.cpp
+++ b/src/libwalletqt/Wallet.cpp
@@ -216,7 +216,6 @@ PendingTransaction *Wallet::createTransaction(const QString &dst_addr, const QSt
return result;
}
-
void Wallet::createTransactionAsync(const QString &dst_addr, const QString &payment_id,
quint64 amount, quint32 mixin_count,
PendingTransaction::Priority priority)
@@ -233,7 +232,51 @@ void Wallet::createTransactionAsync(const QString &dst_addr, const QString &paym
});
}
+PendingTransaction *Wallet::createTransactionAll(const QString &dst_addr, const QString &payment_id,
+ quint32 mixin_count, PendingTransaction::Priority priority)
+{
+ Bitmonero::PendingTransaction * ptImpl = m_walletImpl->createTransaction(
+ dst_addr.toStdString(), payment_id.toStdString(), Bitmonero::optional<uint64_t>(), mixin_count,
+ static_cast<Bitmonero::PendingTransaction::Priority>(priority));
+ PendingTransaction * result = new PendingTransaction(ptImpl, this);
+ return result;
+}
+
+void Wallet::createTransactionAllAsync(const QString &dst_addr, const QString &payment_id,
+ quint32 mixin_count,
+ PendingTransaction::Priority priority)
+{
+ QFuture<PendingTransaction*> future = QtConcurrent::run(this, &Wallet::createTransactionAll,
+ dst_addr, payment_id, mixin_count, priority);
+ QFutureWatcher<PendingTransaction*> * watcher = new QFutureWatcher<PendingTransaction*>();
+ watcher->setFuture(future);
+ connect(watcher, &QFutureWatcher<PendingTransaction*>::finished,
+ this, [this, watcher,dst_addr,payment_id,mixin_count]() {
+ QFuture<PendingTransaction*> future = watcher->future();
+ watcher->deleteLater();
+ emit transactionCreated(future.result(),dst_addr,payment_id,mixin_count);
+ });
+}
+
+PendingTransaction *Wallet::createSweepUnmixableTransaction()
+{
+ Bitmonero::PendingTransaction * ptImpl = m_walletImpl->createSweepUnmixableTransaction();
+ PendingTransaction * result = new PendingTransaction(ptImpl, this);
+ return result;
+}
+void Wallet::createSweepUnmixableTransactionAsync()
+{
+ QFuture<PendingTransaction*> future = QtConcurrent::run(this, &Wallet::createSweepUnmixableTransaction);
+ QFutureWatcher<PendingTransaction*> * watcher = new QFutureWatcher<PendingTransaction*>();
+ watcher->setFuture(future);
+ connect(watcher, &QFutureWatcher<PendingTransaction*>::finished,
+ this, [this, watcher]() {
+ QFuture<PendingTransaction*> future = watcher->future();
+ watcher->deleteLater();
+ emit transactionCreated(future.result(),"","",0);
+ });
+}
void Wallet::disposeTransaction(PendingTransaction *t)
{
diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h
index fc7363e8..14308ce5 100644
--- a/src/libwalletqt/Wallet.h
+++ b/src/libwalletqt/Wallet.h
@@ -126,10 +126,26 @@ public:
Q_INVOKABLE PendingTransaction * createTransaction(const QString &dst_addr, const QString &payment_id,
quint64 amount, quint32 mixin_count,
PendingTransaction::Priority priority);
+
//! creates async transaction
Q_INVOKABLE void createTransactionAsync(const QString &dst_addr, const QString &payment_id,
quint64 amount, quint32 mixin_count,
PendingTransaction::Priority priority);
+
+ //! creates transaction with all outputs
+ Q_INVOKABLE PendingTransaction * createTransactionAll(const QString &dst_addr, const QString &payment_id,
+ quint32 mixin_count, PendingTransaction::Priority priority);
+
+ //! creates async transaction with all outputs
+ Q_INVOKABLE void createTransactionAllAsync(const QString &dst_addr, const QString &payment_id,
+ quint32 mixin_count, PendingTransaction::Priority priority);
+
+ //! creates sweep unmixable transaction
+ Q_INVOKABLE PendingTransaction * createSweepUnmixableTransaction();
+
+ //! creates async sweep unmixable transaction
+ Q_INVOKABLE void createSweepUnmixableTransactionAsync();
+
//! deletes transaction and frees memory
Q_INVOKABLE void disposeTransaction(PendingTransaction * t);