[Qt] New status bar Unit Display Control and related changes.
- New status bar control shows the current Unit of Display. When clicked (left,or right button) it shows a context menu that allows the user to switch the current Unit of Display (BTC, mBTC, uBTC) - Recent Requests and Transaction Table headers are now updated when unit of display is changed, because their "Amount" column now displays the current unit of display. - Takes care of issue #3970 Units in transaction export csv file. - Small refactors for reusability. - Demo Video https://www.youtube.com/watch?v=wwcr0Yh68go&list=UUG3jF2hgofmLWP0tRPisQAQ - changes after Diapolo's feedback. Have not been able to build after last pool, issues with boost on MacOSX, will test on Ubuntu these changes. - removed return statement on switch - renamed onDisplayUnitsChanged(int) to updateDisplayUnit(int) - now getAmountColumnTitle(int unit) takes a simple unit parameter. moved to BitcoinUnits.
This commit is contained in:
parent
343feecf56
commit
8969828d06
11 changed files with 187 additions and 7 deletions
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include <iostream>
|
||||
|
||||
#include <QAction>
|
||||
#include <QApplication>
|
||||
#include <QDateTime>
|
||||
#include <QDesktopWidget>
|
||||
|
@ -39,6 +40,7 @@
|
|||
#include <QMenuBar>
|
||||
#include <QMessageBox>
|
||||
#include <QMimeData>
|
||||
#include <QPoint>
|
||||
#include <QProgressBar>
|
||||
#include <QProgressDialog>
|
||||
#include <QSettings>
|
||||
|
@ -49,6 +51,8 @@
|
|||
#include <QToolBar>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
#include <QUrl>
|
||||
#include <QTextDocument>
|
||||
|
@ -156,10 +160,13 @@ BitcoinGUI::BitcoinGUI(bool fIsTestnet, QWidget *parent) :
|
|||
QHBoxLayout *frameBlocksLayout = new QHBoxLayout(frameBlocks);
|
||||
frameBlocksLayout->setContentsMargins(3,0,3,0);
|
||||
frameBlocksLayout->setSpacing(3);
|
||||
unitDisplayControl = new UnitDisplayStatusBarControl();
|
||||
labelEncryptionIcon = new QLabel();
|
||||
labelConnectionsIcon = new QLabel();
|
||||
labelBlocksIcon = new QLabel();
|
||||
frameBlocksLayout->addStretch();
|
||||
frameBlocksLayout->addWidget(unitDisplayControl);
|
||||
frameBlocksLayout->addStretch();
|
||||
frameBlocksLayout->addWidget(labelEncryptionIcon);
|
||||
frameBlocksLayout->addStretch();
|
||||
frameBlocksLayout->addWidget(labelConnectionsIcon);
|
||||
|
@ -420,6 +427,8 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel)
|
|||
walletFrame->setClientModel(clientModel);
|
||||
}
|
||||
#endif
|
||||
|
||||
this->unitDisplayControl->setOptionsModel(clientModel->getOptionsModel());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1000,3 +1009,72 @@ void BitcoinGUI::unsubscribeFromCoreSignals()
|
|||
// Disconnect signals from client
|
||||
uiInterface.ThreadSafeMessageBox.disconnect(boost::bind(ThreadSafeMessageBox, this, _1, _2, _3));
|
||||
}
|
||||
|
||||
UnitDisplayStatusBarControl::UnitDisplayStatusBarControl():QLabel()
|
||||
{
|
||||
optionsModel = 0;
|
||||
createContextMenu();
|
||||
setStyleSheet("font:11pt; color: #333333");
|
||||
setToolTip(tr("Unit to show amounts in. Click to select another unit."));
|
||||
}
|
||||
|
||||
/** So that it responds to left-button clicks */
|
||||
void UnitDisplayStatusBarControl::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
onDisplayUnitsClicked(event->pos());
|
||||
}
|
||||
|
||||
/** Creates context menu, its actions, and wires up all the relevant signals for mouse events. */
|
||||
void UnitDisplayStatusBarControl::createContextMenu()
|
||||
{
|
||||
menu = new QMenu();
|
||||
foreach(BitcoinUnits::Unit u, BitcoinUnits::availableUnits())
|
||||
{
|
||||
QAction *menuAction = new QAction(QString(BitcoinUnits::name(u)), this);
|
||||
menuAction->setData(QVariant(u));
|
||||
menu->addAction(menuAction);
|
||||
}
|
||||
connect(menu,SIGNAL(triggered(QAction*)),this,SLOT(onMenuSelection(QAction*)));
|
||||
|
||||
// what happens on right click.
|
||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(this,SIGNAL(customContextMenuRequested(const QPoint&)),this,SLOT(onDisplayUnitsClicked(const QPoint&)));
|
||||
}
|
||||
|
||||
/** Lets the control know about the Options Model (and its signals) */
|
||||
void UnitDisplayStatusBarControl::setOptionsModel(OptionsModel *optionsModel)
|
||||
{
|
||||
if (optionsModel)
|
||||
{
|
||||
this->optionsModel = optionsModel;
|
||||
|
||||
// be aware of a display unit change reported by the OptionsModel object.
|
||||
connect(optionsModel,SIGNAL(displayUnitChanged(int)),this,SLOT(updateDisplayUnit(int)));
|
||||
|
||||
// initialize the display units label with the current value in the model.
|
||||
updateDisplayUnit(optionsModel->getDisplayUnit());
|
||||
}
|
||||
}
|
||||
|
||||
/** When Display Units are changed on OptionsModel it will refresh the display text of the control on the status bar */
|
||||
void UnitDisplayStatusBarControl::updateDisplayUnit(int newUnits)
|
||||
{
|
||||
setText(BitcoinUnits::name(newUnits));
|
||||
}
|
||||
|
||||
/** Shows context menu with Display Unit options by the mouse coordinates */
|
||||
void UnitDisplayStatusBarControl::onDisplayUnitsClicked(const QPoint& point)
|
||||
{
|
||||
QPoint globalPos = mapToGlobal(point);
|
||||
menu->exec(globalPos);
|
||||
}
|
||||
|
||||
/** Tells underlying optionsModel to update its current display unit. */
|
||||
void UnitDisplayStatusBarControl::onMenuSelection(QAction* action)
|
||||
{
|
||||
if (action)
|
||||
{
|
||||
optionsModel->setDisplayUnit(action->data());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,12 +9,16 @@
|
|||
#include "config/bitcoin-config.h"
|
||||
#endif
|
||||
|
||||
#include <QLabel>
|
||||
#include <QMainWindow>
|
||||
#include <QMap>
|
||||
#include <QMenu>
|
||||
#include <QPoint>
|
||||
#include <QSystemTrayIcon>
|
||||
|
||||
class ClientModel;
|
||||
class Notificator;
|
||||
class OptionsModel;
|
||||
class RPCConsole;
|
||||
class SendCoinsRecipient;
|
||||
class WalletFrame;
|
||||
|
@ -22,9 +26,13 @@ class WalletModel;
|
|||
|
||||
class CWallet;
|
||||
|
||||
class UnitDisplayStatusBarControl;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAction;
|
||||
class QLabel;
|
||||
class QMenu;
|
||||
class QPoint;
|
||||
class QProgressBar;
|
||||
class QProgressDialog;
|
||||
QT_END_NAMESPACE
|
||||
|
@ -69,6 +77,7 @@ private:
|
|||
ClientModel *clientModel;
|
||||
WalletFrame *walletFrame;
|
||||
|
||||
UnitDisplayStatusBarControl *unitDisplayControl;
|
||||
QLabel *labelEncryptionIcon;
|
||||
QLabel *labelConnectionsIcon;
|
||||
QLabel *labelBlocksIcon;
|
||||
|
@ -198,4 +207,32 @@ private slots:
|
|||
void showProgress(const QString &title, int nProgress);
|
||||
};
|
||||
|
||||
class UnitDisplayStatusBarControl : public QLabel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit UnitDisplayStatusBarControl();
|
||||
/** Lets the control know about the Options Model (and its signals) */
|
||||
void setOptionsModel(OptionsModel *optionsModel);
|
||||
|
||||
protected:
|
||||
/** So that it responds to left-button clicks */
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
|
||||
private:
|
||||
OptionsModel *optionsModel;
|
||||
QMenu* menu;
|
||||
/** Shows context menu with Display Unit options by the mouse coordinates */
|
||||
void onDisplayUnitsClicked(const QPoint& point);
|
||||
/** Creates context menu, its actions, and wires up all the relevant signals for mouse events. */
|
||||
void createContextMenu();
|
||||
|
||||
private slots:
|
||||
/** When Display Units are changed on OptionsModel it will refresh the display text of the control on the status bar */
|
||||
void updateDisplayUnit(int newUnits);
|
||||
/** Tells underlying optionsModel to update its current display unit. */
|
||||
void onMenuSelection(QAction* action);
|
||||
};
|
||||
|
||||
#endif // BITCOINGUI_H
|
||||
|
|
|
@ -169,6 +169,16 @@ bool BitcoinUnits::parse(int unit, const QString &value, qint64 *val_out)
|
|||
return ok;
|
||||
}
|
||||
|
||||
QString BitcoinUnits::getAmountColumnTitle(int unit)
|
||||
{
|
||||
QString amountTitle = QObject::tr("Amount");
|
||||
if (BitcoinUnits::valid(unit))
|
||||
{
|
||||
amountTitle += " ("+BitcoinUnits::name(unit) + ")";
|
||||
}
|
||||
return amountTitle;
|
||||
}
|
||||
|
||||
int BitcoinUnits::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
|
|
|
@ -54,6 +54,8 @@ public:
|
|||
static QString formatWithUnit(int unit, qint64 amount, bool plussign=false);
|
||||
//! Parse string to coin amount
|
||||
static bool parse(int unit, const QString &value, qint64 *val_out);
|
||||
//! Gets title for amount column including current display unit if optionsModel reference available */
|
||||
static QString getAmountColumnTitle(int unit);
|
||||
///@}
|
||||
|
||||
//! @name AbstractListModel implementation
|
||||
|
|
|
@ -308,9 +308,7 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
|
|||
break;
|
||||
#endif
|
||||
case DisplayUnit:
|
||||
nDisplayUnit = value.toInt();
|
||||
settings.setValue("nDisplayUnit", nDisplayUnit);
|
||||
emit displayUnitChanged(nDisplayUnit);
|
||||
setDisplayUnit(value);
|
||||
break;
|
||||
case DisplayAddresses:
|
||||
bDisplayAddresses = value.toBool();
|
||||
|
@ -356,11 +354,24 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
emit dataChanged(index, index);
|
||||
|
||||
return successful;
|
||||
}
|
||||
|
||||
/** Updates current unit in memory, settings and emits displayUnitChanged(newUnit) signal */
|
||||
void OptionsModel::setDisplayUnit(const QVariant &value)
|
||||
{
|
||||
if (!value.isNull())
|
||||
{
|
||||
QSettings settings;
|
||||
nDisplayUnit = value.toInt();
|
||||
settings.setValue("nDisplayUnit", nDisplayUnit);
|
||||
emit displayUnitChanged(nDisplayUnit);
|
||||
}
|
||||
}
|
||||
|
||||
bool OptionsModel::getProxySettings(QNetworkProxy& proxy) const
|
||||
{
|
||||
// Directly query current base proxy, because
|
||||
|
|
|
@ -52,6 +52,8 @@ public:
|
|||
int rowCount(const QModelIndex & parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
|
||||
bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole);
|
||||
/** Updates current unit in memory, settings and emits displayUnitChanged(newUnit) signal */
|
||||
void setDisplayUnit(const QVariant &value);
|
||||
|
||||
/* Explicit getters */
|
||||
bool getMinimizeToTray() { return fMinimizeToTray; }
|
||||
|
|
|
@ -21,7 +21,9 @@ RecentRequestsTableModel::RecentRequestsTableModel(CWallet *wallet, WalletModel
|
|||
addNewRequest(request);
|
||||
|
||||
/* These columns must match the indices in the ColumnIndex enumeration */
|
||||
columns << tr("Date") << tr("Label") << tr("Message") << tr("Amount");
|
||||
columns << tr("Date") << tr("Label") << tr("Message") << getAmountTitle();
|
||||
|
||||
connect(walletModel->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
|
||||
}
|
||||
|
||||
RecentRequestsTableModel::~RecentRequestsTableModel()
|
||||
|
@ -101,6 +103,24 @@ QVariant RecentRequestsTableModel::headerData(int section, Qt::Orientation orien
|
|||
return QVariant();
|
||||
}
|
||||
|
||||
/** Updates the column title to "Amount (DisplayUnit)" and emits headerDataChanged() signal for table headers to react. */
|
||||
void RecentRequestsTableModel::updateAmountColumnTitle()
|
||||
{
|
||||
columns[Amount] = getAmountTitle();
|
||||
emit headerDataChanged(Qt::Horizontal,Amount,Amount);
|
||||
}
|
||||
|
||||
/** Gets title for amount column including current display unit if optionsModel reference available. */
|
||||
QString RecentRequestsTableModel::getAmountTitle()
|
||||
{
|
||||
QString amountTitle = tr("Amount");
|
||||
if (this->walletModel->getOptionsModel() != NULL)
|
||||
{
|
||||
amountTitle += " ("+BitcoinUnits::name(this->walletModel->getOptionsModel()->getDisplayUnit()) + ")";
|
||||
}
|
||||
return amountTitle;
|
||||
}
|
||||
|
||||
QModelIndex RecentRequestsTableModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
|
@ -185,6 +205,11 @@ void RecentRequestsTableModel::sort(int column, Qt::SortOrder order)
|
|||
emit dataChanged(index(0, 0, QModelIndex()), index(list.size() - 1, NUMBER_OF_COLUMNS - 1, QModelIndex()));
|
||||
}
|
||||
|
||||
void RecentRequestsTableModel::updateDisplayUnit()
|
||||
{
|
||||
updateAmountColumnTitle();
|
||||
}
|
||||
|
||||
bool RecentRequestEntryLessThan::operator()(RecentRequestEntry &left, RecentRequestEntry &right) const
|
||||
{
|
||||
RecentRequestEntry *pLeft = &left;
|
||||
|
|
|
@ -91,12 +91,18 @@ public:
|
|||
|
||||
public slots:
|
||||
void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
|
||||
void updateDisplayUnit();
|
||||
|
||||
private:
|
||||
WalletModel *walletModel;
|
||||
QStringList columns;
|
||||
QList<RecentRequestEntry> list;
|
||||
int64_t nReceiveRequestsMaxId;
|
||||
|
||||
/** Updates the column title to "Amount (DisplayUnit)" and emits headerDataChanged() signal for table headers to react. */
|
||||
void updateAmountColumnTitle();
|
||||
/** Gets title for amount column including current display unit if optionsModel reference available. */
|
||||
QString getAmountTitle();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -235,8 +235,7 @@ TransactionTableModel::TransactionTableModel(CWallet* wallet, WalletModel *paren
|
|||
walletModel(parent),
|
||||
priv(new TransactionTablePriv(wallet, this))
|
||||
{
|
||||
columns << QString() << tr("Date") << tr("Type") << tr("Address") << tr("Amount");
|
||||
|
||||
columns << QString() << tr("Date") << tr("Type") << tr("Address") << BitcoinUnits::getAmountColumnTitle(walletModel->getOptionsModel()->getDisplayUnit());
|
||||
priv->refreshWallet();
|
||||
|
||||
connect(walletModel->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
|
||||
|
@ -247,6 +246,13 @@ TransactionTableModel::~TransactionTableModel()
|
|||
delete priv;
|
||||
}
|
||||
|
||||
/** Updates the column title to "Amount (DisplayUnit)" and emits headerDataChanged() signal for table headers to react. */
|
||||
void TransactionTableModel::updateAmountColumnTitle()
|
||||
{
|
||||
columns[Amount] = BitcoinUnits::getAmountColumnTitle(walletModel->getOptionsModel()->getDisplayUnit());
|
||||
emit headerDataChanged(Qt::Horizontal,Amount,Amount);
|
||||
}
|
||||
|
||||
void TransactionTableModel::updateTransaction(const QString &hash, int status)
|
||||
{
|
||||
uint256 updated;
|
||||
|
@ -624,5 +630,6 @@ QModelIndex TransactionTableModel::index(int row, int column, const QModelIndex
|
|||
void TransactionTableModel::updateDisplayUnit()
|
||||
{
|
||||
// emit dataChanged to update Amount column with the current unit
|
||||
updateAmountColumnTitle();
|
||||
emit dataChanged(index(0, Amount), index(priv->size()-1, Amount));
|
||||
}
|
||||
|
|
|
@ -87,6 +87,8 @@ public slots:
|
|||
void updateTransaction(const QString &hash, int status);
|
||||
void updateConfirmations();
|
||||
void updateDisplayUnit();
|
||||
/** Updates the column title to "Amount (DisplayUnit)" and emits headerDataChanged() signal for table headers to react. */
|
||||
void updateAmountColumnTitle();
|
||||
|
||||
friend class TransactionTablePriv;
|
||||
};
|
||||
|
|
|
@ -309,7 +309,7 @@ void TransactionView::exportClicked()
|
|||
writer.addColumn(tr("Type"), TransactionTableModel::Type, Qt::EditRole);
|
||||
writer.addColumn(tr("Label"), 0, TransactionTableModel::LabelRole);
|
||||
writer.addColumn(tr("Address"), 0, TransactionTableModel::AddressRole);
|
||||
writer.addColumn(tr("Amount"), 0, TransactionTableModel::FormattedAmountRole);
|
||||
writer.addColumn(BitcoinUnits::getAmountColumnTitle(model->getOptionsModel()->getDisplayUnit()), 0, TransactionTableModel::FormattedAmountRole);
|
||||
writer.addColumn(tr("ID"), 0, TransactionTableModel::TxIDRole);
|
||||
|
||||
if(!writer.write()) {
|
||||
|
|
Loading…
Reference in a new issue