aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/qt/bitcoinamountfield.cpp49
-rw-r--r--src/qt/bitcoinunits.cpp39
-rw-r--r--src/qt/bitcoinunits.h53
-rw-r--r--src/qt/overviewpage.cpp10
-rw-r--r--src/qt/sendcoinsdialog.cpp8
-rw-r--r--src/qt/transactiondesc.cpp24
-rw-r--r--src/qt/transactiontablemodel.cpp10
-rw-r--r--src/qt/transactiontablemodel.h4
-rw-r--r--src/qt/transactionview.cpp21
-rw-r--r--src/qt/transactionview.h3
10 files changed, 184 insertions, 37 deletions
diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp
index 25ad0c66af..e047c278b7 100644
--- a/src/qt/bitcoinamountfield.cpp
+++ b/src/qt/bitcoinamountfield.cpp
@@ -14,6 +14,51 @@
#include <QKeyEvent>
#include <qmath.h> // for qPow()
+// QDoubleSpinBox that shows SI-style thin space thousands separators
+class AmountSpinBox: public QDoubleSpinBox
+{
+public:
+ explicit AmountSpinBox(QWidget *parent):
+ QDoubleSpinBox(parent)
+ {
+ }
+ QString textFromValue(double value) const
+ {
+ QStringList parts = QDoubleSpinBox::textFromValue(value).split(".");
+ QString quotient_str = parts[0];
+ QString remainder_str;
+ if(parts.size() > 1)
+ remainder_str = parts[1];
+
+ // Code duplication between here and BitcoinUnits::format
+ // TODO: Figure out how to share this code
+ QChar thin_sp(THIN_SP_CP);
+ int q_size = quotient_str.size();
+ if (q_size > 4)
+ for (int i = 3; i < q_size; i += 3)
+ quotient_str.insert(q_size - i, thin_sp);
+
+ int r_size = remainder_str.size();
+ if (r_size > 4)
+ for (int i = 3, adj = 0; i < r_size; i += 3, adj++)
+ remainder_str.insert(i + adj, thin_sp);
+
+ if(remainder_str.isEmpty())
+ return quotient_str;
+ else
+ return quotient_str + QString(".") + remainder_str;
+ }
+ QValidator::State validate (QString &text, int &pos) const
+ {
+ QString s(BitcoinUnits::removeSpaces(text));
+ return QDoubleSpinBox::validate(s, pos);
+ }
+ double valueFromText(const QString& text) const
+ {
+ return QDoubleSpinBox::valueFromText(BitcoinUnits::removeSpaces(text));
+ }
+};
+
BitcoinAmountField::BitcoinAmountField(QWidget *parent) :
QWidget(parent),
amount(0),
@@ -21,7 +66,7 @@ BitcoinAmountField::BitcoinAmountField(QWidget *parent) :
{
nSingleStep = 100000; // satoshis
- amount = new QDoubleSpinBox(this);
+ amount = new AmountSpinBox(this);
amount->setLocale(QLocale::c());
amount->installEventFilter(this);
amount->setMaximumWidth(170);
@@ -52,7 +97,7 @@ void BitcoinAmountField::setText(const QString &text)
if (text.isEmpty())
amount->clear();
else
- amount->setValue(text.toDouble());
+ amount->setValue(BitcoinUnits::removeSpaces(text).toDouble());
}
void BitcoinAmountField::clear()
diff --git a/src/qt/bitcoinunits.cpp b/src/qt/bitcoinunits.cpp
index 2fed443cf2..1b5eaa2dc5 100644
--- a/src/qt/bitcoinunits.cpp
+++ b/src/qt/bitcoinunits.cpp
@@ -50,8 +50,8 @@ QString BitcoinUnits::description(int unit)
switch(unit)
{
case BTC: return QString("Bitcoins");
- case mBTC: return QString("Milli-Bitcoins (1 / 1,000)");
- case uBTC: return QString("Micro-Bitcoins (1 / 1,000,000)");
+ case mBTC: return QString("Milli-Bitcoins (1 / 1" THIN_SP_UTF8 "000)");
+ case uBTC: return QString("Micro-Bitcoins (1 / 1" THIN_SP_UTF8 "000" THIN_SP_UTF8 "000)");
default: return QString("???");
}
}
@@ -100,7 +100,7 @@ int BitcoinUnits::decimals(int unit)
}
}
-QString BitcoinUnits::format(int unit, qint64 n, bool fPlus)
+QString BitcoinUnits::format(int unit, qint64 n, bool fPlus, SeparatorStyle separators, bool fAlign)
{
// Note: not using straight sprintf here because we do NOT want
// localized number formatting.
@@ -119,6 +119,23 @@ QString BitcoinUnits::format(int unit, qint64 n, bool fPlus)
for (int i = remainder_str.size()-1; i>=2 && (remainder_str.at(i) == '0'); --i)
++nTrim;
remainder_str.chop(nTrim);
+ if (fAlign)
+ remainder_str.append(QString(QChar(FIGURE_SP_CP)).repeated(nTrim));
+
+ // Use SI-stule separators as these are locale indendent and can't be
+ // confused with the decimal marker. Rule is to use a thin space every
+ // three digits on *both* sides of the decimal point - but only if there
+ // are five or more digits
+ QChar thin_sp(THIN_SP_CP);
+ int q_size = quotient_str.size();
+ if (separators == separatorAlways || (separators == separatorStandard && q_size > 4))
+ for (int i = 3; i < q_size; i += 3)
+ quotient_str.insert(q_size - i, thin_sp);
+
+ int r_size = remainder_str.size();
+ if (separators == separatorAlways || (separators == separatorStandard && r_size > 4))
+ for (int i = 3, adj = 0; i < r_size ; i += 3, adj++)
+ remainder_str.insert(i + adj, thin_sp);
if (n < 0)
quotient_str.insert(0, '-');
@@ -127,17 +144,27 @@ QString BitcoinUnits::format(int unit, qint64 n, bool fPlus)
return quotient_str + QString(".") + remainder_str;
}
-QString BitcoinUnits::formatWithUnit(int unit, qint64 amount, bool plussign)
+QString BitcoinUnits::formatWithUnit(int unit, qint64 amount, bool plussign, SeparatorStyle separators, bool fAlign)
{
- return format(unit, amount, plussign) + QString(" ") + name(unit);
+ return format(unit, amount, plussign, separators, fAlign) + QString(" ") + name(unit);
}
+QString BitcoinUnits::formatHtmlWithUnit(int unit, qint64 amount, bool plussign, SeparatorStyle separators)
+{
+ QString str(formatWithUnit(unit, amount, plussign, separators));
+ str.replace(QChar(THIN_SP_CP), QString(THIN_SP_HTML));
+ return QString("<span style='white-space: nowrap;'>%1</span>").arg(str);
+}
+
+
bool BitcoinUnits::parse(int unit, const QString &value, qint64 *val_out)
{
if(!valid(unit) || value.isEmpty())
return false; // Refuse to parse invalid unit or empty string
int num_decimals = decimals(unit);
- QStringList parts = value.split(".");
+
+ // Ignore spaces and thin spaces when parsing
+ QStringList parts = removeSpaces(value).split(".");
if(parts.size() > 2)
{
diff --git a/src/qt/bitcoinunits.h b/src/qt/bitcoinunits.h
index 46517fc07b..a3017b9a8b 100644
--- a/src/qt/bitcoinunits.h
+++ b/src/qt/bitcoinunits.h
@@ -8,6 +8,37 @@
#include <QAbstractListModel>
#include <QString>
+// U+2009 THIN SPACE = UTF-8 E2 80 89
+#define REAL_THIN_SP_CP 0x2009
+#define REAL_THIN_SP_UTF8 "\xE2\x80\x89"
+#define REAL_THIN_SP_HTML "&thinsp;"
+
+// U+200A HAIR SPACE = UTF-8 E2 80 8A
+#define HAIR_SP_CP 0x200A
+#define HAIR_SP_UTF8 "\xE2\x80\x8A"
+#define HAIR_SP_HTML "&#8202;"
+
+// U+2006 SIX-PER-EM SPACE = UTF-8 E2 80 86
+#define SIXPEREM_SP_CP 0x2006
+#define SIXPEREM_SP_UTF8 "\xE2\x80\x86"
+#define SIXPEREM_SP_HTML "&#8198;"
+
+// U+2007 FIGURE SPACE = UTF-8 E2 80 87
+#define FIGURE_SP_CP 0x2007
+#define FIGURE_SP_UTF8 "\xE2\x80\x87"
+#define FIGURE_SP_HTML "&#8199;"
+
+// QMessageBox seems to have a bug whereby it doesn't display thin/hair spaces
+// correctly. Workaround is to display a space in a small font. If you
+// change this, please test that it doesn't cause the parent span to start
+// wrapping.
+#define HTML_HACK_SP "<span style='white-space: nowrap; font-size: 6pt'> </span>"
+
+// Define THIN_SP_* variables to be our preferred type of thin space
+#define THIN_SP_CP REAL_THIN_SP_CP
+#define THIN_SP_UTF8 REAL_THIN_SP_UTF8
+#define THIN_SP_HTML HTML_HACK_SP
+
/** Bitcoin unit definitions. Encapsulates parsing and formatting
and serves as list model for drop-down selection boxes.
*/
@@ -28,6 +59,13 @@ public:
uBTC
};
+ enum SeparatorStyle
+ {
+ separatorNever,
+ separatorStandard,
+ separatorAlways
+ };
+
//! @name Static API
//! Unit conversion and formatting
///@{
@@ -49,9 +87,10 @@ public:
//! Number of decimals left
static int decimals(int unit);
//! Format as string
- static QString format(int unit, qint64 amount, bool plussign=false);
+ static QString format(int unit, qint64 amount, bool plussign=false, SeparatorStyle separators=separatorStandard, bool fAlign=false);
//! Format as string (with unit)
- static QString formatWithUnit(int unit, qint64 amount, bool plussign=false);
+ static QString formatWithUnit(int unit, qint64 amount, bool plussign=false, SeparatorStyle separators=separatorStandard, bool fAlign=false);
+ static QString formatHtmlWithUnit(int unit, qint64 amount, bool plussign=false, SeparatorStyle separators=separatorStandard);
//! Parse string to coin amount
static bool parse(int unit, const QString &value, qint64 *val_out);
///@}
@@ -67,6 +106,16 @@ public:
QVariant data(const QModelIndex &index, int role) const;
///@}
+ static QString removeSpaces(QString text)
+ {
+ text.remove(' ');
+ text.remove(QChar(THIN_SP_CP));
+#if (THIN_SP_CP != REAL_THIN_SP_CP)
+ text.remove(QChar(REAL_THIN_SP_CP));
+#endif
+ return text;
+ }
+
private:
QList<BitcoinUnits::Unit> unitlist;
};
diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp
index 1a9d1de571..311563d946 100644
--- a/src/qt/overviewpage.cpp
+++ b/src/qt/overviewpage.cpp
@@ -72,7 +72,7 @@ public:
foreground = option.palette.color(QPalette::Text);
}
painter->setPen(foreground);
- QString amountText = BitcoinUnits::formatWithUnit(unit, amount, true);
+ QString amountText = BitcoinUnits::formatWithUnit(unit, amount, true, BitcoinUnits::separatorAlways, true);
if(!confirmed)
{
amountText = QString("[") + amountText + QString("]");
@@ -141,10 +141,10 @@ void OverviewPage::setBalance(qint64 balance, qint64 unconfirmedBalance, qint64
currentBalance = balance;
currentUnconfirmedBalance = unconfirmedBalance;
currentImmatureBalance = immatureBalance;
- ui->labelBalance->setText(BitcoinUnits::formatWithUnit(unit, balance));
- ui->labelUnconfirmed->setText(BitcoinUnits::formatWithUnit(unit, unconfirmedBalance));
- ui->labelImmature->setText(BitcoinUnits::formatWithUnit(unit, immatureBalance));
- ui->labelTotal->setText(BitcoinUnits::formatWithUnit(unit, balance + unconfirmedBalance + immatureBalance));
+ ui->labelBalance->setText(BitcoinUnits::formatWithUnit(unit, balance, false, BitcoinUnits::separatorAlways, true));
+ ui->labelUnconfirmed->setText(BitcoinUnits::formatWithUnit(unit, unconfirmedBalance, false, BitcoinUnits::separatorAlways, true));
+ ui->labelImmature->setText(BitcoinUnits::formatWithUnit(unit, immatureBalance, false, BitcoinUnits::separatorAlways, true));
+ ui->labelTotal->setText(BitcoinUnits::formatWithUnit(unit, balance + unconfirmedBalance + immatureBalance, false, BitcoinUnits::separatorAlways, true));
// only show immature (newly mined) balance if it's non-zero, so as not to complicate things
// for the non-mining users
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index 33621e54b0..f432c4add6 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -142,7 +142,7 @@ void SendCoinsDialog::on_sendButton_clicked()
foreach(const SendCoinsRecipient &rcp, recipients)
{
// generate bold amount string
- QString amount = "<b>" + BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount);
+ QString amount = "<b>" + BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount);
amount.append("</b>");
// generate monospace address string
QString address = "<span style='font-family: monospace;'>" + rcp.address;
@@ -210,7 +210,7 @@ void SendCoinsDialog::on_sendButton_clicked()
{
// append fee string if a fee is required
questionString.append("<hr /><span style='color:#aa0000;'>");
- questionString.append(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), txFee));
+ questionString.append(BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), txFee));
questionString.append("</span> ");
questionString.append(tr("added as transaction fee"));
}
@@ -222,10 +222,10 @@ void SendCoinsDialog::on_sendButton_clicked()
foreach(BitcoinUnits::Unit u, BitcoinUnits::availableUnits())
{
if(u != model->getOptionsModel()->getDisplayUnit())
- alternativeUnits.append(BitcoinUnits::formatWithUnit(u, totalAmount));
+ alternativeUnits.append(BitcoinUnits::formatHtmlWithUnit(u, totalAmount));
}
questionString.append(tr("Total Amount %1 (= %2)")
- .arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), totalAmount))
+ .arg(BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), totalAmount))
.arg(alternativeUnits.join(" " + tr("or") + " ")));
QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm send coins"),
diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp
index 45fb3d40c2..0bb93035cc 100644
--- a/src/qt/transactiondesc.cpp
+++ b/src/qt/transactiondesc.cpp
@@ -138,7 +138,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, int vout, int u
nUnmatured += wallet->GetCredit(txout);
strHTML += "<b>" + tr("Credit") + ":</b> ";
if (wtx.IsInMainChain())
- strHTML += BitcoinUnits::formatWithUnit(unit, nUnmatured)+ " (" + tr("matures in %n more block(s)", "", wtx.GetBlocksToMaturity()) + ")";
+ strHTML += BitcoinUnits::formatHtmlWithUnit(unit, nUnmatured)+ " (" + tr("matures in %n more block(s)", "", wtx.GetBlocksToMaturity()) + ")";
else
strHTML += "(" + tr("not accepted") + ")";
strHTML += "<br>";
@@ -148,7 +148,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, int vout, int u
//
// Credit
//
- strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, nNet) + "<br>";
+ strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, nNet) + "<br>";
}
else
{
@@ -184,7 +184,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, int vout, int u
}
}
- strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, -txout.nValue) + "<br>";
+ strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, -txout.nValue) + "<br>";
}
if (fAllToMe)
@@ -192,13 +192,13 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, int vout, int u
// Payment to self
int64_t nChange = wtx.GetChange();
int64_t nValue = nCredit - nChange;
- strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, -nValue) + "<br>";
- strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, nValue) + "<br>";
+ strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, -nValue) + "<br>";
+ strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, nValue) + "<br>";
}
int64_t nTxFee = nDebit - wtx.GetValueOut();
if (nTxFee > 0)
- strHTML += "<b>" + tr("Transaction fee") + ":</b> " + BitcoinUnits::formatWithUnit(unit, -nTxFee) + "<br>";
+ strHTML += "<b>" + tr("Transaction fee") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, -nTxFee) + "<br>";
}
else
{
@@ -207,14 +207,14 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, int vout, int u
//
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
if (wallet->IsMine(txin))
- strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, -wallet->GetDebit(txin)) + "<br>";
+ strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, -wallet->GetDebit(txin)) + "<br>";
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
if (wallet->IsMine(txout))
- strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, wallet->GetCredit(txout)) + "<br>";
+ strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, wallet->GetCredit(txout)) + "<br>";
}
}
- strHTML += "<b>" + tr("Net amount") + ":</b> " + BitcoinUnits::formatWithUnit(unit, nNet, true) + "<br>";
+ strHTML += "<b>" + tr("Net amount") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, nNet, true) + "<br>";
//
// Message
@@ -260,10 +260,10 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, int vout, int u
strHTML += "<hr><br>" + tr("Debug information") + "<br><br>";
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
if(wallet->IsMine(txin))
- strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, -wallet->GetDebit(txin)) + "<br>";
+ strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, -wallet->GetDebit(txin)) + "<br>";
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
if(wallet->IsMine(txout))
- strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, wallet->GetCredit(txout)) + "<br>";
+ strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, wallet->GetCredit(txout)) + "<br>";
strHTML += "<br><b>" + tr("Transaction") + ":</b><br>";
strHTML += GUIUtil::HtmlEscape(wtx.ToString(), true);
@@ -289,7 +289,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, int vout, int u
strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[address].name) + " ";
strHTML += QString::fromStdString(CBitcoinAddress(address).ToString());
}
- strHTML = strHTML + " " + tr("Amount") + "=" + BitcoinUnits::formatWithUnit(unit, vout.nValue);
+ strHTML = strHTML + " " + tr("Amount") + "=" + BitcoinUnits::formatHtmlWithUnit(unit, vout.nValue);
strHTML = strHTML + " IsMine=" + (wallet->IsMine(vout) ? tr("true") : tr("false")) + "</li>";
}
}
diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp
index 8cf2b0a1b1..c0f7edd871 100644
--- a/src/qt/transactiontablemodel.cpp
+++ b/src/qt/transactiontablemodel.cpp
@@ -5,7 +5,6 @@
#include "transactiontablemodel.h"
#include "addresstablemodel.h"
-#include "bitcoinunits.h"
#include "guiconstants.h"
#include "guiutil.h"
#include "optionsmodel.h"
@@ -425,9 +424,9 @@ QVariant TransactionTableModel::addressColor(const TransactionRecord *wtx) const
return QVariant();
}
-QString TransactionTableModel::formatTxAmount(const TransactionRecord *wtx, bool showUnconfirmed) const
+QString TransactionTableModel::formatTxAmount(const TransactionRecord *wtx, bool showUnconfirmed, BitcoinUnits::SeparatorStyle separators, bool fAlign) const
{
- QString str = BitcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), wtx->credit + wtx->debit);
+ QString str = BitcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), wtx->credit + wtx->debit, false, separators, fAlign);
if(showUnconfirmed)
{
if(!wtx->status.countsForBalance)
@@ -512,7 +511,7 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
case ToAddress:
return formatTxToAddress(rec, false);
case Amount:
- return formatTxAmount(rec);
+ return formatTxAmount(rec, true, BitcoinUnits::separatorAlways, true);
}
break;
case Qt::EditRole:
@@ -569,7 +568,8 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
case ConfirmedRole:
return rec->status.countsForBalance;
case FormattedAmountRole:
- return formatTxAmount(rec, false);
+ // Used for copy/export, so don't include separators
+ return formatTxAmount(rec, false, BitcoinUnits::separatorNever);
case StatusRole:
return rec->status.status;
}
diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h
index 333e6bc6ed..9ee375d787 100644
--- a/src/qt/transactiontablemodel.h
+++ b/src/qt/transactiontablemodel.h
@@ -8,6 +8,8 @@
#include <QAbstractTableModel>
#include <QStringList>
+#include "bitcoinunits.h"
+
class TransactionRecord;
class TransactionTablePriv;
class WalletModel;
@@ -78,7 +80,7 @@ private:
QString formatTxDate(const TransactionRecord *wtx) const;
QString formatTxType(const TransactionRecord *wtx) const;
QString formatTxToAddress(const TransactionRecord *wtx, bool tooltip) const;
- QString formatTxAmount(const TransactionRecord *wtx, bool showUnconfirmed=true) const;
+ QString formatTxAmount(const TransactionRecord *wtx, bool showUnconfirmed=true, BitcoinUnits::SeparatorStyle separators=BitcoinUnits::separatorStandard, bool fAlign=false) const;
QString formatTooltip(const TransactionRecord *rec) const;
QVariant txStatusDecoration(const TransactionRecord *wtx) const;
QVariant txAddressDecoration(const TransactionRecord *wtx) const;
diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp
index d4d29416ca..98914fc2d0 100644
--- a/src/qt/transactionview.cpp
+++ b/src/qt/transactionview.cpp
@@ -123,6 +123,8 @@ TransactionView::TransactionView(QWidget *parent) :
view->setTabKeyNavigation(false);
view->setContextMenuPolicy(Qt::CustomContextMenu);
+ view->installEventFilter(this);
+
transactionView = view;
// Actions
@@ -480,3 +482,22 @@ void TransactionView::resizeEvent(QResizeEvent* event)
QWidget::resizeEvent(event);
columnResizingFixer->stretchColumnWidth(TransactionTableModel::ToAddress);
}
+
+// Need to override default Ctrl+C action for amount as default behaviour is just to copy DisplayRole text
+bool TransactionView::eventFilter(QObject *obj, QEvent *event)
+{
+ if (event->type() == QEvent::KeyPress)
+ {
+ QKeyEvent *ke = static_cast<QKeyEvent *>(event);
+ if (ke->key() == Qt::Key_C && ke->modifiers().testFlag(Qt::ControlModifier))
+ {
+ QModelIndex i = this->transactionView->currentIndex();
+ if (i.isValid() && i.column() == TransactionTableModel::Amount)
+ {
+ GUIUtil::setClipboard(i.data(TransactionTableModel::FormattedAmountRole).toString());
+ return true;
+ }
+ }
+ }
+ return QWidget::eventFilter(obj, event);
+}
diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h
index 7a89fa11ca..618efbc565 100644
--- a/src/qt/transactionview.h
+++ b/src/qt/transactionview.h
@@ -8,6 +8,7 @@
#include "guiutil.h"
#include <QWidget>
+#include <QKeyEvent>
class TransactionFilterProxy;
class WalletModel;
@@ -78,6 +79,8 @@ private:
virtual void resizeEvent(QResizeEvent* event);
+ bool eventFilter(QObject *obj, QEvent *event);
+
private slots:
void contextualMenu(const QPoint &);
void dateRangeChanged();