diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 4f08352..bced3c9 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -634,7 +634,7 @@ void MainWindow::onCreateTransactionSuccess(PendingTransaction *tx, const QVecto break; } case QDialog::Accepted: - m_ctx->commitTransaction(tx); + m_ctx->commitTransaction(tx, m_ctx->tmpTxDescription); break; } diff --git a/src/appcontext.cpp b/src/appcontext.cpp index 12ba636..2318557 100644 --- a/src/appcontext.cpp +++ b/src/appcontext.cpp @@ -72,7 +72,8 @@ void AppContext::onCreateTransaction(const QString &address, quint64 amount, con quint64 unlocked_balance = this->wallet->unlockedBalance(); if (!all && amount > unlocked_balance) { - emit createTransactionError("Not enough money to spend"); + emit createTransactionError(QString("Not enough money to spend.\n\n" + "Spendable balance: %1").arg(WalletManager::displayAmount(unlocked_balance))); return; } else if (unlocked_balance == 0) { emit createTransactionError("No money to spend"); @@ -129,14 +130,14 @@ void AppContext::onCancelTransaction(PendingTransaction *tx, const QVectorwallet->disposeTransaction(tx); } -void AppContext::commitTransaction(PendingTransaction *tx) { +void AppContext::commitTransaction(PendingTransaction *tx, const QString &description) { // Nodes - even well-connected, properly configured ones - consistently fail to relay transactions // To mitigate transactions failing we just send the transaction to every node we know about over Tor if (config()->get(Config::multiBroadcast).toBool()) { this->onMultiBroadcast(tx); } - this->wallet->commitTransactionAsync(tx); + this->wallet->commitTransactionAsync(tx, description); } void AppContext::onMultiBroadcast(PendingTransaction *tx) { @@ -305,13 +306,6 @@ void AppContext::onTransactionCreated(PendingTransaction *tx, const QVectorwallet->setUserNote(entry, this->tmpTxDescription); - } - this->tmpTxDescription = ""; - } - // Store wallet immediately so we don't risk losing tx key if wallet crashes this->wallet->store(); diff --git a/src/appcontext.h b/src/appcontext.h index d3850e2..806bb88 100644 --- a/src/appcontext.h +++ b/src/appcontext.h @@ -37,7 +37,7 @@ public: // libwalletqt bool refreshed = false; - void commitTransaction(PendingTransaction *tx); + void commitTransaction(PendingTransaction *tx, const QString &description=""); void syncStatusUpdated(quint64 height, quint64 target); void updateBalance(); void refreshModels(); diff --git a/src/dialog/TxConfAdvDialog.cpp b/src/dialog/TxConfAdvDialog.cpp index db3b230..95db78c 100644 --- a/src/dialog/TxConfAdvDialog.cpp +++ b/src/dialog/TxConfAdvDialog.cpp @@ -7,6 +7,7 @@ #include #include +#include "constants.h" #include "dialog/QrCodeDialog.h" #include "libwalletqt/Input.h" #include "libwalletqt/Transfer.h" @@ -35,12 +36,16 @@ TxConfAdvDialog::TxConfAdvDialog(QSharedPointer ctx, const QString & m_exportTxKeyMenu->addAction("Copy to clipboard", this, &TxConfAdvDialog::txKeyCopy); ui->btn_exportTxKey->setMenu(m_exportTxKeyMenu); - ui->label_description->setText(QString("Description: %1").arg(description)); + ui->line_description->setText(description); connect(ui->btn_sign, &QPushButton::clicked, this, &TxConfAdvDialog::signTransaction); connect(ui->btn_send, &QPushButton::clicked, this, &TxConfAdvDialog::broadcastTransaction); connect(ui->btn_close, &QPushButton::clicked, this, &TxConfAdvDialog::closeDialog); + ui->amount->setFont(ModelUtils::getMonospaceFont()); + ui->fee->setFont(ModelUtils::getMonospaceFont()); + ui->total->setFont(ModelUtils::getMonospaceFont()); + ui->inputs->setFont(ModelUtils::getMonospaceFont()); ui->outputs->setFont(ModelUtils::getMonospaceFont()); @@ -64,11 +69,10 @@ void TxConfAdvDialog::setTransaction(PendingTransaction *tx, bool isSigned) { ui->btn_exportTxKey->hide(); } - ui->txid->setText(tx->txid().first()); + m_txid = tx->txid().first(); + ui->txid->setText(m_txid); - ui->amount->setText(WalletManager::displayAmount(tx->amount())); - ui->fee->setText(WalletManager::displayAmount(ptx->fee())); - ui->total->setText(WalletManager::displayAmount(tx->amount() + ptx->fee())); + this->setAmounts(tx->amount(), tx->fee()); auto size_str = [this, isSigned]{ if (isSigned) { @@ -97,14 +101,38 @@ void TxConfAdvDialog::setUnsignedTransaction(UnsignedTransaction *utx) { ui->txid->setText("n/a"); ui->label_size->setText("Size: n/a"); - ui->amount->setText(WalletManager::displayAmount(utx->amount(0))); - ui->fee->setText(WalletManager::displayAmount(utx->fee(0))); - ui->total->setText(WalletManager::displayAmount(utx->amount(0) + utx->fee(0))); + this->setAmounts(utx->amount(0), utx->fee(0)); ConstructionInfo *ci = m_utx->constructionInfo(0); this->setupConstructionData(ci); } +void TxConfAdvDialog::setAmounts(quint64 amount, quint64 fee) { + QString preferredCur = config()->get(Config::preferredFiatCurrency).toString(); + + auto convert = [preferredCur](double amount){ + return QString::number(appData()->prices.convert("XMR", preferredCur, amount), 'f', 2); + }; + + QString amount_str = WalletManager::displayAmount(amount); + QString fee_str = WalletManager::displayAmount(fee); + QString total = WalletManager::displayAmount(amount + fee); + QVector amounts = {amount_str, fee_str, total}; + int maxLength = Utils::maxLength(amounts); + std::for_each(amounts.begin(), amounts.end(), [maxLength](QString& amount){amount = amount.rightJustified(maxLength, ' ');}); + + QString amount_fiat = convert(amount / constants::cdiv); + QString fee_fiat = convert(fee / constants::cdiv); + QString total_fiat = convert((amount + fee) / constants::cdiv); + QVector amounts_fiat = {amount_fiat, fee_fiat, total_fiat}; + int maxLengthFiat = Utils::maxLength(amounts_fiat); + std::for_each(amounts_fiat.begin(), amounts_fiat.end(), [maxLengthFiat](QString& amount){amount = amount.rightJustified(maxLengthFiat, ' ');}); + + ui->amount->setText(QString("%1 (%2 %3)").arg(amounts[0], amounts_fiat[0], preferredCur)); + ui->fee->setText(QString("%1 (%2 %3)").arg(amounts[1], amounts_fiat[1], preferredCur)); + ui->total->setText(QString("%1 (%2 %3)").arg(amounts[2], amounts_fiat[2], preferredCur)); +} + void TxConfAdvDialog::setupConstructionData(ConstructionInfo *ci) { QString inputs_str; auto inputs = ci->inputs(); @@ -128,7 +156,6 @@ void TxConfAdvDialog::setupConstructionData(ConstructionInfo *ci) { ui->label_outputs->setText(QString("Outputs (%1)").arg(QString::number(outputs.size()))); ui->label_ringSize->setText(QString("Ring size: %1").arg(QString::number(ci->minMixinCount() + 1))); - ui->label_unlockTime->setText(QString("Unlock time: %1 (height)").arg(QString::number(ci->unlockTime()))); } void TxConfAdvDialog::signTransaction() { @@ -186,7 +213,7 @@ void TxConfAdvDialog::signedQrCode() { void TxConfAdvDialog::broadcastTransaction() { if (m_tx == nullptr) return; - m_ctx->commitTransaction(m_tx); + m_ctx->commitTransaction(m_tx, ui->line_description->text()); QDialog::accept(); } diff --git a/src/dialog/TxConfAdvDialog.h b/src/dialog/TxConfAdvDialog.h index a0e5069..3e2a7f0 100644 --- a/src/dialog/TxConfAdvDialog.h +++ b/src/dialog/TxConfAdvDialog.h @@ -33,6 +33,7 @@ private: void signTransaction(); void broadcastTransaction(); void closeDialog(); + void setAmounts(quint64 amount, quint64 fee); void unsignedCopy(); void unsignedQrCode(); @@ -51,6 +52,7 @@ private: QMenu *m_exportUnsignedMenu; QMenu *m_exportSignedMenu; QMenu *m_exportTxKeyMenu; + QString m_txid; }; #endif //FEATHER_TXCONFADVDIALOG_H diff --git a/src/dialog/TxConfAdvDialog.ui b/src/dialog/TxConfAdvDialog.ui index 7030ee1..2a37803 100644 --- a/src/dialog/TxConfAdvDialog.ui +++ b/src/dialog/TxConfAdvDialog.ui @@ -21,15 +21,15 @@ - - + + Transaction ID: - + txid @@ -41,13 +41,6 @@ - - - - Qt::Horizontal - - - @@ -122,14 +115,21 @@ - - - Description: - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse - - + + + + + Description: + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + @@ -141,16 +141,6 @@ - - - - Unlock time: - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse - - - diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp index 41225dd..8cfefe3 100644 --- a/src/libwalletqt/Wallet.cpp +++ b/src/libwalletqt/Wallet.cpp @@ -826,11 +826,19 @@ bool Wallet::refresh(bool historyAndSubaddresses /* = true */) } } -void Wallet::commitTransactionAsync(PendingTransaction *t) +void Wallet::commitTransactionAsync(PendingTransaction *t, const QString &description) { - m_scheduler.run([this, t] { + m_scheduler.run([this, t, description] { auto txIdList = t->txid(); // retrieve before commit - emit transactionCommitted(t->commit(), t, txIdList); + bool success = t->commit(); + + if (success && !description.isEmpty()) { + for (const auto &txid : txIdList) { + this->setUserNote(txid, description); + } + } + + emit transactionCommitted(success, t, txIdList); }); } diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h index 9bcdd67..5bf5bc2 100644 --- a/src/libwalletqt/Wallet.h +++ b/src/libwalletqt/Wallet.h @@ -329,7 +329,7 @@ public: bool submitTxFile(const QString &fileName) const; //! asynchronous transaction commit - void commitTransactionAsync(PendingTransaction * t); + void commitTransactionAsync(PendingTransaction * t, const QString &description=""); //! deletes transaction and frees memory void disposeTransaction(PendingTransaction * t);