mirror of
https://github.com/monero-project/monero-gui.git
synced 2024-12-13 11:56:32 +02:00
Merge pull request #135
111248f
Make the new sweep functions use async transactions (moneromooo.monero)c779b37
Support for sweeping all outputs (moneromooo.monero)2143392
Add a button to sweep unmixable outputs (moneromooo.monero)
This commit is contained in:
commit
2fed96d048
@ -52,6 +52,7 @@ Rectangle {
|
|||||||
|
|
||||||
|
|
||||||
signal paymentClicked(string address, string paymentId, string amount, int mixinCount, int priority, string description)
|
signal paymentClicked(string address, string paymentId, string amount, int mixinCount, int priority, string description)
|
||||||
|
signal sweepUnmixableClicked()
|
||||||
signal generatePaymentIdInvoked()
|
signal generatePaymentIdInvoked()
|
||||||
signal checkPaymentClicked(string address, string txid, string txkey);
|
signal checkPaymentClicked(string address, string txid, string txkey);
|
||||||
|
|
||||||
@ -308,5 +309,9 @@ Rectangle {
|
|||||||
console.log("MiddlePanel: paymentClicked")
|
console.log("MiddlePanel: paymentClicked")
|
||||||
paymentClicked(address, paymentId, amount, mixinCount, priority, description)
|
paymentClicked(address, paymentId, amount, mixinCount, priority, description)
|
||||||
}
|
}
|
||||||
|
onSweepUnmixableClicked : {
|
||||||
|
console.log("MiddlePanel: sweepUnmixableClicked")
|
||||||
|
sweepUnmixableClicked()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
105
main.qml
105
main.qml
@ -157,6 +157,7 @@ ApplicationWindow {
|
|||||||
middlePanel.checkPaymentClicked.disconnect(handleCheckPayment);
|
middlePanel.checkPaymentClicked.disconnect(handleCheckPayment);
|
||||||
}
|
}
|
||||||
middlePanel.paymentClicked.connect(handlePayment);
|
middlePanel.paymentClicked.connect(handlePayment);
|
||||||
|
middlePanel.sweepUnmixableClicked.connect(handleSweepUnmixable);
|
||||||
// basicPanel.paymentClicked.connect(handlePayment);
|
// basicPanel.paymentClicked.connect(handlePayment);
|
||||||
middlePanel.checkPaymentClicked.connect(handleCheckPayment);
|
middlePanel.checkPaymentClicked.connect(handleCheckPayment);
|
||||||
|
|
||||||
@ -385,6 +386,14 @@ ApplicationWindow {
|
|||||||
// deleting transaction object, we don't want memleaks
|
// deleting transaction object, we don't want memleaks
|
||||||
currentWallet.disposeTransaction(transaction);
|
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 {
|
} else {
|
||||||
console.log("Transaction created, amount: " + walletManager.displayAmount(transaction.amount)
|
console.log("Transaction created, amount: " + walletManager.displayAmount(transaction.amount)
|
||||||
+ ", fee: " + walletManager.displayAmount(transaction.fee));
|
+ ", fee: " + walletManager.displayAmount(transaction.fee));
|
||||||
@ -393,13 +402,13 @@ ApplicationWindow {
|
|||||||
|
|
||||||
transactionConfirmationPopup.title = qsTr("Confirmation") + translationManager.emptyString
|
transactionConfirmationPopup.title = qsTr("Confirmation") + translationManager.emptyString
|
||||||
transactionConfirmationPopup.text = qsTr("Please confirm transaction:\n")
|
transactionConfirmationPopup.text = qsTr("Please confirm transaction:\n")
|
||||||
+ qsTr("\nAddress: ") + address
|
+ (address === "" ? "" : (qsTr("\nAddress: ") + address))
|
||||||
+ qsTr("\nPayment ID: ") + paymentId
|
+ (paymentId === "" ? "" : (qsTr("\nPayment ID: ") + paymentId))
|
||||||
+ qsTr("\n\nAmount: ") + walletManager.displayAmount(transaction.amount)
|
+ qsTr("\n\nAmount: ") + walletManager.displayAmount(transaction.amount)
|
||||||
+ qsTr("\nFee: ") + walletManager.displayAmount(transaction.fee)
|
+ qsTr("\nFee: ") + walletManager.displayAmount(transaction.fee)
|
||||||
+ qsTr("\n\nMixin: ") + mixinCount
|
+ qsTr("\n\nMixin: ") + mixinCount
|
||||||
+ qsTr("\n\Number of transactions: ") + transaction.txCount
|
+ qsTr("\n\Number of transactions: ") + transaction.txCount
|
||||||
+ qsTr("\n\nDescription: ") + transactionDescription
|
+ (transactionDescription === "" ? "" : (qsTr("\n\nDescription: ") + transactionDescription))
|
||||||
+ translationManager.emptyString
|
+ translationManager.emptyString
|
||||||
transactionConfirmationPopup.icon = StandardIcon.Question
|
transactionConfirmationPopup.icon = StandardIcon.Question
|
||||||
transactionConfirmationPopup.open()
|
transactionConfirmationPopup.open()
|
||||||
@ -422,33 +431,77 @@ ApplicationWindow {
|
|||||||
transactionDescription = description;
|
transactionDescription = description;
|
||||||
|
|
||||||
// validate amount;
|
// validate amount;
|
||||||
var amountxmr = walletManager.amountFromString(amount);
|
if (amount !== "(all)") {
|
||||||
console.log("integer amount: ", amountxmr);
|
var amountxmr = walletManager.amountFromString(amount);
|
||||||
console.log("integer unlocked",currentWallet.unlockedBalance)
|
console.log("integer amount: ", amountxmr);
|
||||||
if (amountxmr <= 0) {
|
console.log("integer unlocked",currentWallet.unlockedBalance)
|
||||||
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
if (amountxmr <= 0) {
|
||||||
informationPopup.text = qsTr("Amount is wrong: expected number from %1 to %2")
|
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
||||||
.arg(walletManager.displayAmount(0))
|
informationPopup.text = qsTr("Amount is wrong: expected number from %1 to %2")
|
||||||
.arg(walletManager.maximumAllowedAmountAsSting())
|
.arg(walletManager.displayAmount(0))
|
||||||
+ translationManager.emptyString
|
.arg(walletManager.maximumAllowedAmountAsSting())
|
||||||
|
+ translationManager.emptyString
|
||||||
|
|
||||||
informationPopup.icon = StandardIcon.Critical
|
informationPopup.icon = StandardIcon.Critical
|
||||||
informationPopup.onCloseCallback = null
|
informationPopup.onCloseCallback = null
|
||||||
informationPopup.open()
|
informationPopup.open()
|
||||||
return;
|
return;
|
||||||
} else if (amountxmr > currentWallet.unlockedBalance) {
|
} else if (amountxmr > currentWallet.unlockedBalance) {
|
||||||
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
||||||
informationPopup.text = qsTr("insufficient funds. Unlocked balance: %1")
|
informationPopup.text = qsTr("insufficient funds. Unlocked balance: %1")
|
||||||
.arg(walletManager.displayAmount(currentWallet.unlockedBalance))
|
.arg(walletManager.displayAmount(currentWallet.unlockedBalance))
|
||||||
+ translationManager.emptyString
|
+ translationManager.emptyString
|
||||||
|
|
||||||
informationPopup.icon = StandardIcon.Critical
|
informationPopup.icon = StandardIcon.Critical
|
||||||
informationPopup.onCloseCallback = null
|
informationPopup.onCloseCallback = null
|
||||||
informationPopup.open()
|
informationPopup.open()
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
currentWallet.createTransactionAsync(address, paymentId, amountxmr, mixinCount, priority);
|
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();
|
||||||
|
// 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));
|
||||||
|
|
||||||
|
// here we show confirmation popup;
|
||||||
|
|
||||||
|
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
|
// called after user confirms transaction
|
||||||
|
@ -35,6 +35,7 @@ Rectangle {
|
|||||||
id: root
|
id: root
|
||||||
signal paymentClicked(string address, string paymentId, string amount, int mixinCount,
|
signal paymentClicked(string address, string paymentId, string amount, int mixinCount,
|
||||||
int priority, string description)
|
int priority, string description)
|
||||||
|
signal sweepUnmixableClicked()
|
||||||
|
|
||||||
color: "#F0EEEE"
|
color: "#F0EEEE"
|
||||||
|
|
||||||
@ -88,7 +89,7 @@ Rectangle {
|
|||||||
LineEdit {
|
LineEdit {
|
||||||
id: amountLine
|
id: amountLine
|
||||||
placeholderText: qsTr("") + translationManager.emptyString
|
placeholderText: qsTr("") + translationManager.emptyString
|
||||||
width: parent.width - 37 - 17
|
width: parent.width - 37 - 17 - 60
|
||||||
validator: DoubleValidator {
|
validator: DoubleValidator {
|
||||||
bottom: 0.0
|
bottom: 0.0
|
||||||
top: 18446744.073709551615
|
top: 18446744.073709551615
|
||||||
@ -97,6 +98,21 @@ Rectangle {
|
|||||||
locale: "C"
|
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 {
|
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()
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,7 +216,6 @@ PendingTransaction *Wallet::createTransaction(const QString &dst_addr, const QSt
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Wallet::createTransactionAsync(const QString &dst_addr, const QString &payment_id,
|
void Wallet::createTransactionAsync(const QString &dst_addr, const QString &payment_id,
|
||||||
quint64 amount, quint32 mixin_count,
|
quint64 amount, quint32 mixin_count,
|
||||||
PendingTransaction::Priority priority)
|
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)
|
void Wallet::disposeTransaction(PendingTransaction *t)
|
||||||
{
|
{
|
||||||
|
@ -126,10 +126,26 @@ public:
|
|||||||
Q_INVOKABLE PendingTransaction * createTransaction(const QString &dst_addr, const QString &payment_id,
|
Q_INVOKABLE PendingTransaction * createTransaction(const QString &dst_addr, const QString &payment_id,
|
||||||
quint64 amount, quint32 mixin_count,
|
quint64 amount, quint32 mixin_count,
|
||||||
PendingTransaction::Priority priority);
|
PendingTransaction::Priority priority);
|
||||||
|
|
||||||
//! creates async transaction
|
//! creates async transaction
|
||||||
Q_INVOKABLE void createTransactionAsync(const QString &dst_addr, const QString &payment_id,
|
Q_INVOKABLE void createTransactionAsync(const QString &dst_addr, const QString &payment_id,
|
||||||
quint64 amount, quint32 mixin_count,
|
quint64 amount, quint32 mixin_count,
|
||||||
PendingTransaction::Priority priority);
|
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
|
//! deletes transaction and frees memory
|
||||||
Q_INVOKABLE void disposeTransaction(PendingTransaction * t);
|
Q_INVOKABLE void disposeTransaction(PendingTransaction * t);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user