break;
}
case QDialog::Accepted:
- m_ctx->commitTransaction(tx);
+ m_ctx->commitTransaction(tx, m_ctx->tmpTxDescription);
break;
}
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");
this->wallet->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) {
}
void AppContext::onTransactionCommitted(bool status, PendingTransaction *tx, const QStringList& txid){
- if (status) {
- for (const auto &entry: txid) {
- this->wallet->setUserNote(entry, this->tmpTxDescription);
- }
- this->tmpTxDescription = "";
- }
-
// Store wallet immediately so we don't risk losing tx key if wallet crashes
this->wallet->store();
// 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();
#include <QFileDialog>
#include <QMessageBox>
+#include "constants.h"
#include "dialog/QrCodeDialog.h"
#include "libwalletqt/Input.h"
#include "libwalletqt/Transfer.h"
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());
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) {
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<QString> 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<QString> 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();
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() {
void TxConfAdvDialog::broadcastTransaction() {
if (m_tx == nullptr) return;
- m_ctx->commitTransaction(m_tx);
+ m_ctx->commitTransaction(m_tx, ui->line_description->text());
QDialog::accept();
}
void signTransaction();
void broadcastTransaction();
void closeDialog();
+ void setAmounts(quint64 amount, quint64 fee);
void unsignedCopy();
void unsignedQrCode();
QMenu *m_exportUnsignedMenu;
QMenu *m_exportSignedMenu;
QMenu *m_exportTxKeyMenu;
+ QString m_txid;
};
#endif //FEATHER_TXCONFADVDIALOG_H
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
- <layout class="QHBoxLayout" name="horizontalLayout_3">
- <item>
+ <layout class="QFormLayout" name="formLayout_2">
+ <item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Transaction ID:</string>
</property>
</widget>
</item>
- <item>
+ <item row="0" column="1">
<widget class="QLineEdit" name="txid">
<property name="text">
<string>txid</string>
</item>
</layout>
</item>
- <item>
- <widget class="Line" name="line_3">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
- <widget class="QLabel" name="label_description">
- <property name="text">
- <string>Description:</string>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QLabel" name="label_description">
+ <property name="text">
+ <string>Description:</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="line_description"/>
+ </item>
+ </layout>
</item>
<item>
<widget class="QLabel" name="label_size">
</property>
</widget>
</item>
- <item>
- <widget class="QLabel" name="label_unlockTime">
- <property name="text">
- <string>Unlock time: </string>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
<item>
<widget class="QLabel" name="label_ringSize">
<property name="text">
}
}
-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);
});
}
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);