diff --git a/main.qml b/main.qml index 9872409d..3a98d9b8 100644 --- a/main.qml +++ b/main.qml @@ -207,12 +207,14 @@ ApplicationWindow { currentWallet.newBlock.disconnect(onWalletNewBlock) currentWallet.moneySpent.disconnect(onWalletMoneySent) currentWallet.moneyReceived.disconnect(onWalletMoneyReceived) + currentWallet.transactionCreated.disconnect(onTransactionCreated) currentWallet.refreshed.connect(onWalletRefresh) currentWallet.updated.connect(onWalletUpdate) currentWallet.newBlock.connect(onWalletNewBlock) currentWallet.moneySpent.connect(onWalletMoneySent) currentWallet.moneyReceived.connect(onWalletMoneyReceived) + currentWallet.transactionCreated.connect(onTransactionCreated) console.log("initializing with daemon address: ", persistentSettings.daemon_address) @@ -363,6 +365,43 @@ ApplicationWindow { } + function onTransactionCreated(pendingTransaction,address,paymentId,mixinCount){ + console.log("Transaction created"); + hideProcessingSplash(); + transaction = pendingTransaction; + // validate address; + if (transaction.status !== PendingTransaction.Status_Ok) { + console.error("Can't create transaction: ", transaction.errorString); + informationPopup.title = qsTr("Error") + translationManager.emptyString; + if (currentWallet.connected == Wallet.ConnectionStatus_WrongVersion) + informationPopup.text = qsTr("Can't create transaction: Wrong daemon version: ") + transaction.errorString + else + 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 { + 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("\nAddress: ") + address + + qsTr("\nPayment ID: ") + paymentId + + qsTr("\n\nAmount: ") + walletManager.displayAmount(transaction.amount) + + qsTr("\nFee: ") + walletManager.displayAmount(transaction.fee) + + qsTr("\n\nMixin: ") + mixinCount + + qsTr("\n\nDescription: ") + transactionDescription; + + translationManager.emptyString + transactionConfirmationPopup.icon = StandardIcon.Question + transactionConfirmationPopup.open() + } + } // called on "transfer" @@ -375,7 +414,10 @@ ApplicationWindow { ", priority: ", priority, ", description: ", description); - + showProcessingSplash("Creating transaction"); + + transactionDescription = description; + // validate amount; var amountxmr = walletManager.amountFromString(amount); console.log("integer amount: ", amountxmr); @@ -403,42 +445,7 @@ ApplicationWindow { return; } - // validate address; - transaction = currentWallet.createTransaction(address, paymentId, amountxmr, mixinCount, priority); - if (transaction.status !== PendingTransaction.Status_Ok) { - console.error("Can't create transaction: ", transaction.errorString); - informationPopup.title = qsTr("Error") + translationManager.emptyString; - if (currentWallet.connected == Wallet.ConnectionStatus_WrongVersion) - informationPopup.text = qsTr("Can't create transaction: Wrong daemon version: ") + transaction.errorString - else - 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 { - console.log("Transaction created, amount: " + walletManager.displayAmount(transaction.amount) - + ", fee: " + walletManager.displayAmount(transaction.fee)); - - transactionDescription = description; - - // here we show confirmation popup; - - transactionConfirmationPopup.title = qsTr("Confirmation") + translationManager.emptyString - transactionConfirmationPopup.text = qsTr("Please confirm transaction:\n") - + qsTr("\nAddress: ") + address - + qsTr("\nPayment ID: ") + paymentId - + qsTr("\n\nAmount: ") + walletManager.displayAmount(transaction.amount) - + qsTr("\nFee: ") + walletManager.displayAmount(transaction.fee) - + qsTr("\n\nMixin: ") + mixinCount - + qsTr("\n\nDescription: ") + description - + translationManager.emptyString - transactionConfirmationPopup.icon = StandardIcon.Question - transactionConfirmationPopup.open() - // committing transaction - } + currentWallet.createTransactionAsync(address, paymentId, amountxmr, mixinCount, priority); } // called after user confirms transaction @@ -536,7 +543,8 @@ ApplicationWindow { function showProcessingSplash(message) { console.log("Displaying processing splash") if (typeof message != 'undefined') { - splash.message = message + splash.messageText = message + splash.heightProgressText = "" } splash.show() } diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp index 18ded2c8..78cb6949 100644 --- a/src/libwalletqt/Wallet.cpp +++ b/src/libwalletqt/Wallet.cpp @@ -10,6 +10,7 @@ #include #include #include +#include namespace { static const int DAEMON_BLOCKCHAIN_HEIGHT_CACHE_TTL_SECONDS = 10; @@ -211,10 +212,29 @@ PendingTransaction *Wallet::createTransaction(const QString &dst_addr, const QSt Bitmonero::PendingTransaction * ptImpl = m_walletImpl->createTransaction( dst_addr.toStdString(), payment_id.toStdString(), amount, mixin_count, static_cast(priority)); - PendingTransaction * result = new PendingTransaction(ptImpl, this); + PendingTransaction * result = new PendingTransaction(ptImpl,0); return result; } + +void Wallet::createTransactionAsync(const QString &dst_addr, const QString &payment_id, + quint64 amount, quint32 mixin_count, + PendingTransaction::Priority priority) +{ + QFuture future = QtConcurrent::run(this, &Wallet::createTransaction, + dst_addr, payment_id,amount, mixin_count, priority); + QFutureWatcher * watcher = new QFutureWatcher(); + watcher->setFuture(future); + connect(watcher, &QFutureWatcher::finished, + this, [this, watcher,dst_addr,payment_id,mixin_count]() { + QFuture future = watcher->future(); + watcher->deleteLater(); + emit transactionCreated(future.result(),dst_addr,payment_id,mixin_count); + }); +} + + + void Wallet::disposeTransaction(PendingTransaction *t) { m_walletImpl->disposeTransaction(t->m_pimpl); diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h index 102429d5..74c4fea1 100644 --- a/src/libwalletqt/Wallet.h +++ b/src/libwalletqt/Wallet.h @@ -125,6 +125,10 @@ 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); //! deletes transaction and frees memory Q_INVOKABLE void disposeTransaction(PendingTransaction * t); @@ -172,6 +176,8 @@ signals: void newBlock(quint64 height); void historyModelChanged() const; + // emitted when transaction is created async + void transactionCreated(PendingTransaction * transaction, QString address, QString paymentId, quint32 mixinCount); private: Wallet(QObject * parent = nullptr);