mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 11:32:46 +01:00
Merge #6285: backport: bitcoin-core/gui#29, gui#123, #164, gui#256, gui#309, gui#313, gui#329, gui#331, gui#333, gui#346, gui#393
6431f71b3a
Merge bitcoin-core/gui#393: Fix regression in "Encrypt Wallet" menu item (Hennadii Stepanov)fc900a8aea
Merge bitcoin-core/gui#333: refactor: Signal-slot connections cleanup (Hennadii Stepanov)9ca2aad0b3
Merge bitcoin-core/gui#164: Handle peer addition/removal in a right way (Hennadii Stepanov)7d9ce32562
Merge bitcoin-core/gui#29: refactor: Optimize signal-slot connections logic (Hennadii Stepanov)3be79a9ed9
Merge bitcoin-core/gui#256: Save/restore column sizes of the tables in the Peers tab (Hennadii Stepanov)f4fccd31cb
Merge bitcoin-core/gui#329: Make console buttons look clickable (Hennadii Stepanov)5a0d524506
Merge bitcoin-core/gui#123: rpc: Do not accept command while executing another one (Hennadii Stepanov)19310646e0
Merge bitcoin-core/gui#331: Make RPC console welcome message translation-friendly (Hennadii Stepanov)69a1305978
Merge bitcoin-core/gui#309: Add access to the Peers tab from the network icon (Hennadii Stepanov)c858325d40
Merge bitcoin-core/gui#346: English translations update (Hennadii Stepanov)412445afb5
Merge bitcoin-core/gui#313: qt: Optimize string concatenation by default (W. J. van der Laan) Pull request description: ## Issue being fixed or feature implemented Gui related backports from bitcoin v22 ## What was done? See commits ## How Has This Been Tested? Run unit/functional tests See also: <img alt="right menu" src="https://user-images.githubusercontent.com/32963518/116794314-d64b9b80-aad4-11eb-89ca-7f75c7442ba8.gif"/> ## Breaking Changes N/A ## Checklist: - [x] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have added or updated relevant unit/integration/functional/e2e tests - [ ] I have made corresponding changes to the documentation - [x] I have assigned this pull request to a milestone ACKs for top commit: UdjinM6: light ACK6431f71b3a
PastaPastaPasta: utACK6431f71b3a
Tree-SHA512: bb14de71c9375b10da695db6c521c26686815b8b5ca2748bfe3bd2eafa9d332acd60acd85a1f2eed3aa831d16e5741ecc7570130ce9cf5bff011c065b55d62b2
This commit is contained in:
commit
750475ffaa
@ -364,7 +364,7 @@ RES_ANIMATION = $(wildcard $(srcdir)/qt/res/animation/spinner-*.png)
|
||||
|
||||
BITCOIN_RC = qt/res/dash-qt-res.rc
|
||||
|
||||
BITCOIN_QT_INCLUDES = -DQT_NO_KEYWORDS
|
||||
BITCOIN_QT_INCLUDES = -DQT_NO_KEYWORDS -DQT_USE_QSTRINGBUILDER
|
||||
|
||||
qt_libbitcoinqt_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \
|
||||
$(QT_INCLUDES) $(QT_DBUS_INCLUDES) $(QR_CFLAGS)
|
||||
|
@ -54,7 +54,6 @@
|
||||
#include <QMessageBox>
|
||||
#include <QProcess>
|
||||
#include <QSettings>
|
||||
#include <QStringBuilder>
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
#include <QTranslator>
|
||||
@ -492,8 +491,8 @@ void BitcoinApplication::handleRunawayException(const QString &message)
|
||||
{
|
||||
QMessageBox::critical(
|
||||
nullptr, tr("Runaway exception"),
|
||||
tr("A fatal error occurred. %1 can no longer continue safely and will quit.").arg(PACKAGE_NAME) %
|
||||
QLatin1String("<br><br>") % GUIUtil::MakeHtmlLink(message, PACKAGE_BUGREPORT));
|
||||
tr("A fatal error occurred. %1 can no longer continue safely and will quit.").arg(PACKAGE_NAME) +
|
||||
QLatin1String("<br><br>") + GUIUtil::MakeHtmlLink(message, PACKAGE_BUGREPORT));
|
||||
::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@ -503,8 +502,8 @@ void BitcoinApplication::handleNonFatalException(const QString& message)
|
||||
QMessageBox::warning(
|
||||
nullptr, tr("Internal error"),
|
||||
tr("An internal error occurred. %1 will attempt to continue safely. This is "
|
||||
"an unexpected bug which can be reported as described below.").arg(PACKAGE_NAME) %
|
||||
QLatin1String("<br><br>") % GUIUtil::MakeHtmlLink(message, PACKAGE_BUGREPORT));
|
||||
"an unexpected bug which can be reported as described below.").arg(PACKAGE_NAME) +
|
||||
QLatin1String("<br><br>") + GUIUtil::MakeHtmlLink(message, PACKAGE_BUGREPORT));
|
||||
}
|
||||
|
||||
WId BitcoinApplication::getMainWinId() const
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include <QApplication>
|
||||
#include <QButtonGroup>
|
||||
#include <QComboBox>
|
||||
#include <QCursor>
|
||||
#include <QDateTime>
|
||||
#include <QDragEnterEvent>
|
||||
#include <QKeySequence>
|
||||
@ -114,6 +115,11 @@ BitcoinGUI::BitcoinGUI(interfaces::Node& node, const NetworkStyle* networkStyle,
|
||||
connect(walletFrame, &WalletFrame::message, [this](const QString& title, const QString& message, unsigned int style) {
|
||||
this->message(title, message, style);
|
||||
});
|
||||
connect(walletFrame, &WalletFrame::createWalletButtonClicked, [this] {
|
||||
auto activity = new CreateWalletActivity(getWalletController(), this);
|
||||
connect(activity, &CreateWalletActivity::finished, activity, &QObject::deleteLater);
|
||||
activity->create();
|
||||
});
|
||||
} else
|
||||
#endif // ENABLE_WALLET
|
||||
{
|
||||
@ -211,8 +217,6 @@ BitcoinGUI::BitcoinGUI(interfaces::Node& node, const NetworkStyle* networkStyle,
|
||||
// Subscribe to notifications from core
|
||||
subscribeToCoreSignals();
|
||||
|
||||
// Jump to peers tab by clicking on connections icon
|
||||
connect(labelConnectionsIcon, &GUIUtil::ClickableLabel::clicked, this, &BitcoinGUI::showPeers);
|
||||
connect(labelProxyIcon, &GUIUtil::ClickableLabel::clicked, [this] {
|
||||
openOptionsDialogWithTab(OptionsDialog::TAB_NETWORK);
|
||||
});
|
||||
@ -220,11 +224,6 @@ BitcoinGUI::BitcoinGUI(interfaces::Node& node, const NetworkStyle* networkStyle,
|
||||
modalOverlay = new ModalOverlay(enableWallet, this->centralWidget());
|
||||
connect(labelBlocksIcon, &GUIUtil::ClickableLabel::clicked, this, &BitcoinGUI::showModalOverlay);
|
||||
connect(progressBar, &GUIUtil::ClickableProgressBar::clicked, this, &BitcoinGUI::showModalOverlay);
|
||||
#ifdef ENABLE_WALLET
|
||||
if(enableWallet) {
|
||||
connect(walletFrame, &WalletFrame::requestedSyncWarningInfo, this, &BitcoinGUI::showModalOverlay);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
m_app_nap_inhibitor = new CAppNapInhibitor;
|
||||
@ -812,8 +811,11 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel, interfaces::BlockAndH
|
||||
}
|
||||
|
||||
// Keep up to date with client
|
||||
updateNetworkState();
|
||||
setNetworkActive(m_node.getNetworkActive());
|
||||
setNumConnections(_clientModel->getNumConnections());
|
||||
connect(labelConnectionsIcon, &GUIUtil::ClickableLabel::clicked, [this] {
|
||||
GUIUtil::PopupMenu(m_network_context_menu, QCursor::pos());
|
||||
});
|
||||
connect(_clientModel, &ClientModel::numConnectionsChanged, this, &BitcoinGUI::setNumConnections);
|
||||
connect(_clientModel, &ClientModel::networkActiveChanged, this, &BitcoinGUI::setNetworkActive);
|
||||
|
||||
@ -911,13 +913,28 @@ WalletController* BitcoinGUI::getWalletController()
|
||||
void BitcoinGUI::addWallet(WalletModel* walletModel)
|
||||
{
|
||||
if (!walletFrame) return;
|
||||
if (!walletFrame->addWallet(walletModel)) return;
|
||||
|
||||
WalletView* wallet_view = new WalletView(walletFrame);
|
||||
if (!walletFrame->addWallet(walletModel, wallet_view)) return;
|
||||
|
||||
rpcConsole->addWallet(walletModel);
|
||||
if (m_wallet_selector->count() == 0) {
|
||||
setWalletActionsEnabled(true);
|
||||
} else if (m_wallet_selector->count() == 1) {
|
||||
m_wallet_selector_action->setVisible(true);
|
||||
}
|
||||
|
||||
connect(wallet_view, &WalletView::outOfSyncWarningClicked, this, &BitcoinGUI::showModalOverlay);
|
||||
connect(wallet_view, &WalletView::transactionClicked, this, &BitcoinGUI::gotoHistoryPage);
|
||||
connect(wallet_view, &WalletView::coinsSent, this, &BitcoinGUI::gotoHistoryPage);
|
||||
connect(wallet_view, &WalletView::message, [this](const QString& title, const QString& message, unsigned int style) {
|
||||
this->message(title, message, style);
|
||||
});
|
||||
connect(wallet_view, &WalletView::encryptionStatusChanged, this, &BitcoinGUI::updateWalletStatus);
|
||||
connect(wallet_view, &WalletView::incomingTransaction, this, &BitcoinGUI::incomingTransaction);
|
||||
connect(wallet_view, &WalletView::hdEnabledStatusChanged, this, &BitcoinGUI::updateWalletStatus);
|
||||
connect(this, &BitcoinGUI::setPrivacy, wallet_view, &WalletView::setPrivacy);
|
||||
wallet_view->setPrivacy(isPrivacyModeActivated());
|
||||
const QString display_name = walletModel->getDisplayName();
|
||||
m_wallet_selector->addItem(display_name, QVariant::fromValue(walletModel));
|
||||
}
|
||||
@ -1270,14 +1287,21 @@ void BitcoinGUI::updateNetworkState()
|
||||
nCountPrev = count;
|
||||
fNetworkActivePrev = fNetworkActive;
|
||||
|
||||
QString tooltip;
|
||||
if (fNetworkActive) {
|
||||
labelConnectionsIcon->setToolTip(tr("%n active connection(s) to Dash network", "", count));
|
||||
//: A substring of the tooltip.
|
||||
tooltip = tr("%n active connection(s) to Dash network", "", count);
|
||||
} else {
|
||||
labelConnectionsIcon->setToolTip(tr("Network activity disabled"));
|
||||
tooltip = tr("Network activity disabled");
|
||||
icon = "connect_4";
|
||||
color = GUIUtil::ThemedColor::RED;
|
||||
}
|
||||
|
||||
// Don't word-wrap this (fixed-width) tooltip
|
||||
tooltip = QLatin1String("<nobr>") + tooltip + QLatin1String("<br>") +
|
||||
//: A substring of the tooltip. "More actions" are available via the context menu.
|
||||
tr("Click for more actions.") + QLatin1String("</nobr>");
|
||||
|
||||
if (fNetworkActive && count == 0) {
|
||||
startConnectingAnimation();
|
||||
}
|
||||
@ -1285,6 +1309,7 @@ void BitcoinGUI::updateNetworkState()
|
||||
stopConnectingAnimation();
|
||||
labelConnectionsIcon->setPixmap(GUIUtil::getIcon(icon, color).pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
|
||||
}
|
||||
labelConnectionsIcon->setToolTip(tooltip);
|
||||
}
|
||||
|
||||
void BitcoinGUI::setNumConnections(int count)
|
||||
@ -1292,9 +1317,24 @@ void BitcoinGUI::setNumConnections(int count)
|
||||
updateNetworkState();
|
||||
}
|
||||
|
||||
void BitcoinGUI::setNetworkActive(bool networkActive)
|
||||
void BitcoinGUI::setNetworkActive(bool network_active)
|
||||
{
|
||||
updateNetworkState();
|
||||
m_network_context_menu->clear();
|
||||
m_network_context_menu->addAction(
|
||||
//: A context menu item. The "Peers tab" is an element of the "Node window".
|
||||
tr("Show Peers tab"),
|
||||
[this] {
|
||||
rpcConsole->setTabFocus(RPCConsole::TabTypes::PEERS);
|
||||
showDebugWindow();
|
||||
});
|
||||
m_network_context_menu->addAction(
|
||||
network_active ?
|
||||
//: A context menu item.
|
||||
tr("Disable network activity") :
|
||||
//: A context menu item. The network activity was disabled previously.
|
||||
tr("Enable network activity"),
|
||||
[this, new_state = !network_active] { m_node.setNetworkActive(new_state); });
|
||||
}
|
||||
|
||||
void BitcoinGUI::updateHeadersSyncProgressLabel()
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <QLabel>
|
||||
#include <QMainWindow>
|
||||
#include <QMap>
|
||||
#include <QMenu>
|
||||
#include <QPoint>
|
||||
#include <QPushButton>
|
||||
#include <QSystemTrayIcon>
|
||||
@ -51,7 +52,6 @@ class QAction;
|
||||
class QButtonGroup;
|
||||
class QComboBox;
|
||||
class QDateTime;
|
||||
class QMenu;
|
||||
class QProgressBar;
|
||||
class QProgressDialog;
|
||||
class QToolButton;
|
||||
@ -190,6 +190,8 @@ private:
|
||||
ModalOverlay* modalOverlay = nullptr;
|
||||
QButtonGroup* tabGroup = nullptr;
|
||||
|
||||
QMenu* m_network_context_menu = new QMenu(this);
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
CAppNapInhibitor* m_app_nap_inhibitor = nullptr;
|
||||
#endif
|
||||
@ -264,7 +266,7 @@ public Q_SLOTS:
|
||||
/** Set number of connections shown in the UI */
|
||||
void setNumConnections(int count);
|
||||
/** Set network state shown in the UI */
|
||||
void setNetworkActive(bool networkActive);
|
||||
void setNetworkActive(bool network_active);
|
||||
/** Get restart command-line parameters and request restart */
|
||||
void handleRestart(QStringList args);
|
||||
/** Set number of blocks and last block date shown in the UI */
|
||||
|
@ -69,7 +69,6 @@
|
||||
#include <QShortcut>
|
||||
#include <QSize>
|
||||
#include <QString>
|
||||
#include <QStringBuilder>
|
||||
#include <QTextDocument> // for Qt::mightBeRichText
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
@ -1931,7 +1930,7 @@ QString MakeHtmlLink(const QString& source, const QString& link)
|
||||
{
|
||||
return QString(source).replace(
|
||||
link,
|
||||
QLatin1String("<a href=\"") % link % QLatin1String("\">") % link % QLatin1String("</a>"));
|
||||
QLatin1String("<a href=\"") + link + QLatin1String("\">") + link + QLatin1String("</a>"));
|
||||
}
|
||||
|
||||
void PrintSlotException(
|
||||
|
@ -26,6 +26,7 @@
|
||||
#endif
|
||||
|
||||
#include <QDebug>
|
||||
#include <QLatin1Char>
|
||||
#include <QSettings>
|
||||
#include <QStringList>
|
||||
|
||||
@ -376,7 +377,7 @@ static ProxySetting GetProxySetting(QSettings &settings, const QString &name)
|
||||
|
||||
static void SetProxySetting(QSettings &settings, const QString &name, const ProxySetting &ip_port)
|
||||
{
|
||||
settings.setValue(name, ip_port.ip + ":" + ip_port.port);
|
||||
settings.setValue(name, QString{ip_port.ip + QLatin1Char(':') + ip_port.port});
|
||||
}
|
||||
|
||||
static const QString GetDefaultProxyAddress()
|
||||
|
@ -199,11 +199,6 @@ void OverviewPage::handleTransactionClicked(const QModelIndex &index)
|
||||
Q_EMIT transactionClicked(filter->mapToSource(index));
|
||||
}
|
||||
|
||||
void OverviewPage::handleOutOfSyncWarningClicks()
|
||||
{
|
||||
Q_EMIT outOfSyncWarningClicked();
|
||||
}
|
||||
|
||||
void OverviewPage::setPrivacy(bool privacy)
|
||||
{
|
||||
m_privacy = privacy;
|
||||
@ -469,7 +464,7 @@ void OverviewPage::updateCoinJoinProgress()
|
||||
|
||||
ui->coinJoinProgress->setValue(progress);
|
||||
|
||||
QString strToolPip = ("<b>" + tr("Overall progress") + ": %1%</b><br/>" +
|
||||
QString strToolPip = QString("<b>" + tr("Overall progress") + ": %1%</b><br/>" +
|
||||
tr("Denominated") + ": %2%<br/>" +
|
||||
tr("Partially mixed") + ": %3%<br/>" +
|
||||
tr("Mixed") + ": %4%<br/>" +
|
||||
|
@ -70,7 +70,6 @@ private Q_SLOTS:
|
||||
void handleTransactionClicked(const QModelIndex &index);
|
||||
void updateAlerts(const QString &warnings);
|
||||
void updateWatchOnlyLabels(bool showWatchOnly);
|
||||
void handleOutOfSyncWarningClicks();
|
||||
};
|
||||
|
||||
#endif // BITCOIN_QT_OVERVIEWPAGE_H
|
||||
|
@ -14,53 +14,11 @@
|
||||
#include <QList>
|
||||
#include <QTimer>
|
||||
|
||||
// private implementation
|
||||
class PeerTablePriv
|
||||
{
|
||||
public:
|
||||
/** Local cache of peer information */
|
||||
QList<CNodeCombinedStats> cachedNodeStats;
|
||||
|
||||
/** Pull a full list of peers from vNodes into our cache */
|
||||
void refreshPeers(interfaces::Node& node)
|
||||
{
|
||||
cachedNodeStats.clear();
|
||||
|
||||
interfaces::Node::NodesStats nodes_stats;
|
||||
node.getNodesStats(nodes_stats);
|
||||
cachedNodeStats.reserve(nodes_stats.size());
|
||||
|
||||
for (const auto& node_stats : nodes_stats)
|
||||
{
|
||||
CNodeCombinedStats stats;
|
||||
stats.nodeStats = std::get<0>(node_stats);
|
||||
stats.fNodeStateStatsAvailable = std::get<1>(node_stats);
|
||||
stats.nodeStateStats = std::get<2>(node_stats);
|
||||
cachedNodeStats.append(stats);
|
||||
}
|
||||
}
|
||||
|
||||
int size() const
|
||||
{
|
||||
return cachedNodeStats.size();
|
||||
}
|
||||
|
||||
CNodeCombinedStats *index(int idx)
|
||||
{
|
||||
if (idx >= 0 && idx < cachedNodeStats.size())
|
||||
return &cachedNodeStats[idx];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
PeerTableModel::PeerTableModel(interfaces::Node& node, QObject* parent) :
|
||||
QAbstractTableModel(parent),
|
||||
m_node(node),
|
||||
timer(nullptr)
|
||||
{
|
||||
priv.reset(new PeerTablePriv());
|
||||
|
||||
// set up timer for auto refresh
|
||||
timer = new QTimer(this);
|
||||
connect(timer, &QTimer::timeout, this, &PeerTableModel::refresh);
|
||||
@ -85,15 +43,15 @@ void PeerTableModel::stopAutoRefresh()
|
||||
timer->stop();
|
||||
}
|
||||
|
||||
int PeerTableModel::rowCount(const QModelIndex &parent) const
|
||||
int PeerTableModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
if (parent.isValid()) {
|
||||
return 0;
|
||||
}
|
||||
return priv->size();
|
||||
return m_peers_data.size();
|
||||
}
|
||||
|
||||
int PeerTableModel::columnCount(const QModelIndex &parent) const
|
||||
int PeerTableModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
if (parent.isValid()) {
|
||||
return 0;
|
||||
@ -101,7 +59,7 @@ int PeerTableModel::columnCount(const QModelIndex &parent) const
|
||||
return columns.length();
|
||||
}
|
||||
|
||||
QVariant PeerTableModel::data(const QModelIndex &index, int role) const
|
||||
QVariant PeerTableModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
if(!index.isValid())
|
||||
return QVariant();
|
||||
@ -115,7 +73,7 @@ QVariant PeerTableModel::data(const QModelIndex &index, int role) const
|
||||
return (qint64)rec->nodeStats.nodeid;
|
||||
case Address:
|
||||
// prepend to peer address down-arrow symbol for inbound connection and up-arrow for outbound connection
|
||||
return QString(rec->nodeStats.fInbound ? "↓ " : "↑ ") + QString::fromStdString(rec->nodeStats.m_addr_name);
|
||||
return QString::fromStdString((rec->nodeStats.fInbound ? "↓ " : "↑ ") + rec->nodeStats.m_addr_name);
|
||||
case ConnectionType:
|
||||
return GUIUtil::ConnectionTypeToQString(rec->nodeStats.m_conn_type, /* prepend_direction */ false);
|
||||
case Network:
|
||||
@ -174,19 +132,52 @@ Qt::ItemFlags PeerTableModel::flags(const QModelIndex &index) const
|
||||
return retval;
|
||||
}
|
||||
|
||||
QModelIndex PeerTableModel::index(int row, int column, const QModelIndex &parent) const
|
||||
QModelIndex PeerTableModel::index(int row, int column, const QModelIndex& parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
CNodeCombinedStats *data = priv->index(row);
|
||||
|
||||
if (data)
|
||||
return createIndex(row, column, data);
|
||||
if (0 <= row && row < rowCount() && 0 <= column && column < columnCount()) {
|
||||
return createIndex(row, column, const_cast<CNodeCombinedStats*>(&m_peers_data[row]));
|
||||
}
|
||||
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
void PeerTableModel::refresh()
|
||||
{
|
||||
Q_EMIT layoutAboutToBeChanged();
|
||||
priv->refreshPeers(m_node);
|
||||
Q_EMIT layoutChanged();
|
||||
interfaces::Node::NodesStats nodes_stats;
|
||||
m_node.getNodesStats(nodes_stats);
|
||||
decltype(m_peers_data) new_peers_data;
|
||||
new_peers_data.reserve(nodes_stats.size());
|
||||
for (const auto& node_stats : nodes_stats) {
|
||||
const CNodeCombinedStats stats{std::get<0>(node_stats), std::get<2>(node_stats), std::get<1>(node_stats)};
|
||||
new_peers_data.append(stats);
|
||||
}
|
||||
|
||||
// Handle peer addition or removal as suggested in Qt Docs. See:
|
||||
// - https://doc.qt.io/qt-5/model-view-programming.html#inserting-and-removing-rows
|
||||
// - https://doc.qt.io/qt-5/model-view-programming.html#resizable-models
|
||||
// We take advantage of the fact that the std::vector returned
|
||||
// by interfaces::Node::getNodesStats is sorted by nodeid.
|
||||
for (int i = 0; i < m_peers_data.size();) {
|
||||
if (i < new_peers_data.size() && m_peers_data.at(i).nodeStats.nodeid == new_peers_data.at(i).nodeStats.nodeid) {
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
// A peer has been removed from the table.
|
||||
beginRemoveRows(QModelIndex(), i, i);
|
||||
m_peers_data.erase(m_peers_data.begin() + i);
|
||||
endRemoveRows();
|
||||
}
|
||||
|
||||
if (m_peers_data.size() < new_peers_data.size()) {
|
||||
// Some peers have been added to the end of the table.
|
||||
beginInsertRows(QModelIndex(), m_peers_data.size(), new_peers_data.size() - 1);
|
||||
m_peers_data.swap(new_peers_data);
|
||||
endInsertRows();
|
||||
} else {
|
||||
m_peers_data.swap(new_peers_data);
|
||||
}
|
||||
|
||||
Q_EMIT changed();
|
||||
}
|
||||
|
@ -8,10 +8,11 @@
|
||||
#include <net_processing.h> // For CNodeStateStats
|
||||
#include <net.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QList>
|
||||
#include <QModelIndex>
|
||||
#include <QStringList>
|
||||
#include <QVariant>
|
||||
|
||||
class PeerTablePriv;
|
||||
|
||||
@ -61,18 +62,23 @@ public:
|
||||
|
||||
/** @name Methods overridden from QAbstractTableModel
|
||||
@{*/
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
int columnCount(const QModelIndex &parent) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent) const override;
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
/*@}*/
|
||||
|
||||
public Q_SLOTS:
|
||||
void refresh();
|
||||
|
||||
Q_SIGNALS:
|
||||
void changed();
|
||||
|
||||
private:
|
||||
//! Internal peer data structure.
|
||||
QList<CNodeCombinedStats> m_peers_data{};
|
||||
interfaces::Node& m_node;
|
||||
const QStringList columns{
|
||||
/*: Title of Peers Table column which contains a
|
||||
@ -99,7 +105,6 @@ private:
|
||||
/*: Title of Peers Table column which contains the peer's
|
||||
User Agent string. */
|
||||
tr("User Agent")};
|
||||
std::unique_ptr<PeerTablePriv> priv;
|
||||
QTimer *timer;
|
||||
};
|
||||
|
||||
|
@ -17,6 +17,9 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <QLatin1Char>
|
||||
#include <QLatin1String>
|
||||
|
||||
RecentRequestsTableModel::RecentRequestsTableModel(WalletModel *parent) :
|
||||
QAbstractTableModel(parent), walletModel(parent)
|
||||
{
|
||||
@ -126,7 +129,11 @@ void RecentRequestsTableModel::updateAmountColumnTitle()
|
||||
/** Gets title for amount column including current display unit if optionsModel reference available. */
|
||||
QString RecentRequestsTableModel::getAmountTitle()
|
||||
{
|
||||
return (this->walletModel->getOptionsModel() != nullptr) ? tr("Requested") + " ("+BitcoinUnits::name(this->walletModel->getOptionsModel()->getDisplayUnit()) + ")" : "";
|
||||
if (!walletModel->getOptionsModel()) return {};
|
||||
return tr("Requested") +
|
||||
QLatin1String(" (") +
|
||||
BitcoinUnits::name(this->walletModel->getOptionsModel()->getDisplayUnit()) +
|
||||
QLatin1Char(')');
|
||||
}
|
||||
|
||||
QModelIndex RecentRequestsTableModel::index(int row, int column, const QModelIndex &parent) const
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <wallet/walletutil.h>
|
||||
#endif
|
||||
|
||||
#include <QAbstractButton>
|
||||
#include <QButtonGroup>
|
||||
#include <QDir>
|
||||
#include <QFont>
|
||||
@ -504,6 +505,9 @@ RPCConsole::RPCConsole(interfaces::Node& node, QWidget* parent, Qt::WindowFlags
|
||||
ui->splitter->restoreState(settings.value("RPCConsoleWidgetPeersTabSplitterSizes").toByteArray());
|
||||
}
|
||||
|
||||
m_peer_widget_header_state = settings.value("PeersTabPeerHeaderState").toByteArray();
|
||||
m_banlist_widget_header_state = settings.value("PeersTabBanlistHeaderState").toByteArray();
|
||||
|
||||
constexpr QChar nonbreaking_hyphen(8209);
|
||||
const std::vector<QString> CONNECTION_TYPE_DOC{
|
||||
//: Explanatory text for an inbound peer connection.
|
||||
@ -547,9 +551,9 @@ RPCConsole::RPCConsole(interfaces::Node& node, QWidget* parent, Qt::WindowFlags
|
||||
ui->lineEdit->setMaxLength(16 * 1024 * 1024);
|
||||
ui->messagesWidget->installEventFilter(this);
|
||||
|
||||
connect(ui->clearButton, &QPushButton::clicked, [this] { clear(); });
|
||||
connect(ui->fontBiggerButton, &QPushButton::clicked, this, &RPCConsole::fontBigger);
|
||||
connect(ui->fontSmallerButton, &QPushButton::clicked, this, &RPCConsole::fontSmaller);
|
||||
connect(ui->clearButton, &QAbstractButton::clicked, [this] { clear(); });
|
||||
connect(ui->fontBiggerButton, &QAbstractButton::clicked, this, &RPCConsole::fontBigger);
|
||||
connect(ui->fontSmallerButton, &QAbstractButton::clicked, this, &RPCConsole::fontSmaller);
|
||||
connect(ui->btnClearTrafficGraph, &QPushButton::clicked, ui->trafficGraph, &TrafficGraphWidget::clear);
|
||||
|
||||
// disable the wallet selector by default
|
||||
@ -609,6 +613,9 @@ RPCConsole::~RPCConsole()
|
||||
settings.setValue("RPCConsoleWidgetPeersTabSplitterSizes", ui->splitter->saveState());
|
||||
}
|
||||
|
||||
settings.setValue("PeersTabPeerHeaderState", m_peer_widget_header_state);
|
||||
settings.setValue("PeersTabBanlistHeaderState", m_banlist_widget_header_state);
|
||||
|
||||
m_node.rpcUnsetTimerInterface(rpcTimerInterface);
|
||||
delete rpcTimerInterface;
|
||||
delete pageButtons;
|
||||
@ -700,9 +707,12 @@ void RPCConsole::setClientModel(ClientModel *model, int bestblock_height, int64_
|
||||
ui->peerWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
ui->peerWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
ui->peerWidget->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
ui->peerWidget->setColumnWidth(PeerTableModel::Address, ADDRESS_COLUMN_WIDTH);
|
||||
ui->peerWidget->setColumnWidth(PeerTableModel::Subversion, SUBVERSION_COLUMN_WIDTH);
|
||||
ui->peerWidget->setColumnWidth(PeerTableModel::Ping, PING_COLUMN_WIDTH);
|
||||
|
||||
if (!ui->peerWidget->horizontalHeader()->restoreState(m_peer_widget_header_state)) {
|
||||
ui->peerWidget->setColumnWidth(PeerTableModel::Address, ADDRESS_COLUMN_WIDTH);
|
||||
ui->peerWidget->setColumnWidth(PeerTableModel::Subversion, SUBVERSION_COLUMN_WIDTH);
|
||||
ui->peerWidget->setColumnWidth(PeerTableModel::Ping, PING_COLUMN_WIDTH);
|
||||
}
|
||||
ui->peerWidget->horizontalHeader()->setStretchLastSection(true);
|
||||
ui->peerWidget->setItemDelegateForColumn(PeerTableModel::NetNodeId, new PeerIdViewDelegate(this));
|
||||
|
||||
@ -717,7 +727,7 @@ void RPCConsole::setClientModel(ClientModel *model, int bestblock_height, int64_
|
||||
|
||||
// peer table signal handling - update peer details when selecting new node
|
||||
connect(ui->peerWidget->selectionModel(), &QItemSelectionModel::selectionChanged, this, &RPCConsole::updateDetailWidget);
|
||||
connect(model->getPeerTableModel(), &PeerTableModel::layoutChanged, this, &RPCConsole::updateDetailWidget);
|
||||
connect(model->getPeerTableModel(), &PeerTableModel::changed, this, &RPCConsole::updateDetailWidget);
|
||||
|
||||
// set up ban table
|
||||
ui->banlistWidget->setModel(model->getBanTableModel());
|
||||
@ -725,8 +735,11 @@ void RPCConsole::setClientModel(ClientModel *model, int bestblock_height, int64_
|
||||
ui->banlistWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
ui->banlistWidget->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
ui->banlistWidget->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
ui->banlistWidget->setColumnWidth(BanTableModel::Address, BANSUBNET_COLUMN_WIDTH);
|
||||
ui->banlistWidget->setColumnWidth(BanTableModel::Bantime, BANTIME_COLUMN_WIDTH);
|
||||
|
||||
if (!ui->banlistWidget->horizontalHeader()->restoreState(m_banlist_widget_header_state)) {
|
||||
ui->banlistWidget->setColumnWidth(BanTableModel::Address, BANSUBNET_COLUMN_WIDTH);
|
||||
ui->banlistWidget->setColumnWidth(BanTableModel::Bantime, BANTIME_COLUMN_WIDTH);
|
||||
}
|
||||
ui->banlistWidget->horizontalHeader()->setStretchLastSection(true);
|
||||
|
||||
// create ban table context menu
|
||||
@ -936,23 +949,29 @@ void RPCConsole::clear(bool keep_prompt)
|
||||
).arg(consoleFontSize)
|
||||
);
|
||||
|
||||
message(CMD_REPLY,
|
||||
tr("Welcome to the %1 RPC console.").arg(PACKAGE_NAME) +
|
||||
"<br>" +
|
||||
tr("Use up and down arrows to navigate history, and %1 to clear screen.")
|
||||
.arg("<b>" + ui->clearButton->shortcut().toString(QKeySequence::NativeText) + "</b>") +
|
||||
"<br>" +
|
||||
tr("Use %1 and %2 to increase or decrease the font size.")
|
||||
.arg("<b>" + ui->fontBiggerButton->shortcut().toString(QKeySequence::NativeText) + "</b>")
|
||||
.arg("<b>" + ui->fontSmallerButton->shortcut().toString(QKeySequence::NativeText) + "</b>") +
|
||||
"<br>" +
|
||||
tr("Type %1 for an overview of available commands.").arg("<b>help</b>") +
|
||||
"<br>" +
|
||||
tr("For more information on using this console type %1.").arg("<b>help-console</b>") +
|
||||
"<br><span class=\"secwarning\"><br>" +
|
||||
tr("WARNING: Scammers have been active, telling users to type commands here, stealing their wallet contents. Do not use this console without fully understanding the ramifications of a command.") +
|
||||
"</span>",
|
||||
true);
|
||||
static const QString welcome_message =
|
||||
/*: RPC console welcome message.
|
||||
Placeholders %7 and %8 are style tags for the warning content, and
|
||||
they are not space separated from the rest of the text intentionally. */
|
||||
tr("Welcome to the %1 RPC console.\n"
|
||||
"Use up and down arrows to navigate history, and %2 to clear screen.\n"
|
||||
"Use %3 and %4 to increase or decrease the font size.\n"
|
||||
"Type %5 for an overview of available commands.\n"
|
||||
"For more information on using this console, type %6.\n"
|
||||
"\n"
|
||||
"%7WARNING: Scammers have been active, telling users to type"
|
||||
" commands here, stealing their wallet contents. Do not use this console"
|
||||
" without fully understanding the ramifications of a command.%8")
|
||||
.arg(PACKAGE_NAME,
|
||||
"<b>" + ui->clearButton->shortcut().toString(QKeySequence::NativeText) + "</b>",
|
||||
"<b>" + ui->fontBiggerButton->shortcut().toString(QKeySequence::NativeText) + "</b>",
|
||||
"<b>" + ui->fontSmallerButton->shortcut().toString(QKeySequence::NativeText) + "</b>",
|
||||
"<b>help</b>",
|
||||
"<b>help-console</b>",
|
||||
"<span class=\"secwarning\">",
|
||||
"<span>");
|
||||
|
||||
message(CMD_REPLY, welcome_message, true);
|
||||
}
|
||||
|
||||
void RPCConsole::keyPressEvent(QKeyEvent *event)
|
||||
@ -1074,57 +1093,71 @@ void RPCConsole::showPage(int index)
|
||||
|
||||
void RPCConsole::on_lineEdit_returnPressed()
|
||||
{
|
||||
QString cmd = ui->lineEdit->text();
|
||||
QString cmd = ui->lineEdit->text().trimmed();
|
||||
|
||||
if(!cmd.isEmpty())
|
||||
{
|
||||
std::string strFilteredCmd;
|
||||
try {
|
||||
std::string dummy;
|
||||
if (!RPCParseCommandLine(nullptr, dummy, cmd.toStdString(), false, &strFilteredCmd)) {
|
||||
// Failed to parse command, so we cannot even filter it for the history
|
||||
throw std::runtime_error("Invalid command line");
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
QMessageBox::critical(this, "Error", QString("Error: ") + QString::fromStdString(e.what()));
|
||||
return;
|
||||
if (cmd.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string strFilteredCmd;
|
||||
try {
|
||||
std::string dummy;
|
||||
if (!RPCParseCommandLine(nullptr, dummy, cmd.toStdString(), false, &strFilteredCmd)) {
|
||||
// Failed to parse command, so we cannot even filter it for the history
|
||||
throw std::runtime_error("Invalid command line");
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
QMessageBox::critical(this, "Error", QString("Error: ") + QString::fromStdString(e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
ui->lineEdit->clear();
|
||||
// A special case allows to request shutdown even a long-running command is executed.
|
||||
if (cmd == QLatin1String("stop")) {
|
||||
std::string dummy;
|
||||
RPCExecuteCommandLine(m_node, dummy, cmd.toStdString());
|
||||
return;
|
||||
}
|
||||
|
||||
cmdBeforeBrowsing = QString();
|
||||
if (m_is_executing) {
|
||||
return;
|
||||
}
|
||||
|
||||
ui->lineEdit->clear();
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
WalletModel* wallet_model = ui->WalletSelector->currentData().value<WalletModel*>();
|
||||
WalletModel* wallet_model = ui->WalletSelector->currentData().value<WalletModel*>();
|
||||
|
||||
if (m_last_wallet_model != wallet_model) {
|
||||
if (wallet_model) {
|
||||
message(CMD_REQUEST, tr("Executing command using \"%1\" wallet").arg(wallet_model->getWalletName()));
|
||||
} else {
|
||||
message(CMD_REQUEST, tr("Executing command without any wallet"));
|
||||
}
|
||||
m_last_wallet_model = wallet_model;
|
||||
if (m_last_wallet_model != wallet_model) {
|
||||
if (wallet_model) {
|
||||
message(CMD_REQUEST, tr("Executing command using \"%1\" wallet").arg(wallet_model->getWalletName()));
|
||||
} else {
|
||||
message(CMD_REQUEST, tr("Executing command without any wallet"));
|
||||
}
|
||||
#endif
|
||||
|
||||
message(CMD_REQUEST, QString::fromStdString(strFilteredCmd));
|
||||
Q_EMIT cmdRequest(cmd, m_last_wallet_model);
|
||||
|
||||
cmd = QString::fromStdString(strFilteredCmd);
|
||||
|
||||
// Remove command, if already in history
|
||||
history.removeOne(cmd);
|
||||
// Append command to history
|
||||
history.append(cmd);
|
||||
// Enforce maximum history size
|
||||
while(history.size() > CONSOLE_HISTORY)
|
||||
history.removeFirst();
|
||||
// Set pointer to end of history
|
||||
historyPtr = history.size();
|
||||
|
||||
// Scroll console view to end
|
||||
scrollToEnd();
|
||||
m_last_wallet_model = wallet_model;
|
||||
}
|
||||
#endif // ENABLE_WALLET
|
||||
|
||||
message(CMD_REQUEST, QString::fromStdString(strFilteredCmd));
|
||||
//: A console message indicating an entered command is currently being executed.
|
||||
message(CMD_REPLY, tr("Executing…"));
|
||||
m_is_executing = true;
|
||||
Q_EMIT cmdRequest(cmd, m_last_wallet_model);
|
||||
|
||||
cmd = QString::fromStdString(strFilteredCmd);
|
||||
|
||||
// Remove command, if already in history
|
||||
history.removeOne(cmd);
|
||||
// Append command to history
|
||||
history.append(cmd);
|
||||
// Enforce maximum history size
|
||||
while (history.size() > CONSOLE_HISTORY) {
|
||||
history.removeFirst();
|
||||
}
|
||||
// Set pointer to end of history
|
||||
historyPtr = history.size();
|
||||
|
||||
// Scroll console view to end
|
||||
scrollToEnd();
|
||||
}
|
||||
|
||||
void RPCConsole::browseHistory(int offset)
|
||||
@ -1154,7 +1187,13 @@ void RPCConsole::startExecutor()
|
||||
executor->moveToThread(&thread);
|
||||
|
||||
// Replies from executor object must go to this object
|
||||
connect(executor, &RPCExecutor::reply, this, qOverload<int, const QString&>(&RPCConsole::message));
|
||||
connect(executor, &RPCExecutor::reply, this, [this](int category, const QString& command) {
|
||||
// Remove "Executing…" message.
|
||||
ui->messagesWidget->undo();
|
||||
message(category, command);
|
||||
scrollToEnd();
|
||||
m_is_executing = false;
|
||||
});
|
||||
|
||||
// Requests from this object must go to executor
|
||||
connect(this, &RPCConsole::cmdRequest, executor, &RPCExecutor::request);
|
||||
@ -1330,6 +1369,11 @@ void RPCConsole::showEvent(QShowEvent *event)
|
||||
|
||||
void RPCConsole::hideEvent(QHideEvent *event)
|
||||
{
|
||||
// It is too late to call QHeaderView::saveState() in ~RPCConsole(), as all of
|
||||
// the columns of QTableView child widgets will have zero width at that moment.
|
||||
m_peer_widget_header_state = ui->peerWidget->horizontalHeader()->saveState();
|
||||
m_banlist_widget_header_state = ui->banlistWidget->horizontalHeader()->saveState();
|
||||
|
||||
QWidget::hideEvent(event);
|
||||
|
||||
if (!clientModel || !clientModel->getPeerTableModel())
|
||||
|
@ -12,9 +12,10 @@
|
||||
#include <net.h>
|
||||
#include <uint256.h>
|
||||
|
||||
#include <QWidget>
|
||||
#include <QByteArray>
|
||||
#include <QCompleter>
|
||||
#include <QThread>
|
||||
#include <QWidget>
|
||||
|
||||
class ClientModel;
|
||||
class RPCTimerInterface;
|
||||
@ -189,6 +190,9 @@ private:
|
||||
QCompleter *autoCompleter = nullptr;
|
||||
QThread thread;
|
||||
WalletModel* m_last_wallet_model{nullptr};
|
||||
bool m_is_executing{false};
|
||||
QByteArray m_peer_widget_header_state;
|
||||
QByteArray m_banlist_widget_header_state;
|
||||
|
||||
/** Update UI with latest network info from model. */
|
||||
void updateNetworkState();
|
||||
|
@ -41,7 +41,7 @@ void TestRpcCommand(RPCConsole* console)
|
||||
QTest::keyClicks(lineEdit, "getblockchaininfo");
|
||||
QTest::keyClick(lineEdit, Qt::Key_Return);
|
||||
QVERIFY(mw_spy.wait(1000));
|
||||
QCOMPARE(mw_spy.count(), 2);
|
||||
QCOMPARE(mw_spy.count(), 4);
|
||||
QString output = messagesWidget->toPlainText();
|
||||
UniValue value;
|
||||
value.read(output.right(output.size() - output.indexOf("{")).toStdString());
|
||||
|
@ -201,7 +201,7 @@ void TestGUI(interfaces::Node& node)
|
||||
|
||||
QCOMPARE(uri.count("amount=0.00000001"), 2);
|
||||
QCOMPARE(receiveRequestDialog->QObject::findChild<QLabel*>("amount_tag")->text(), QString("Amount:"));
|
||||
QCOMPARE(receiveRequestDialog->QObject::findChild<QLabel*>("amount_content")->text(), QString("0.00000001 ") + BitcoinUnits::name(unit));
|
||||
QCOMPARE(receiveRequestDialog->QObject::findChild<QLabel*>("amount_content")->text(), QString::fromStdString("0.00000001 ") + BitcoinUnits::name(unit));
|
||||
|
||||
QCOMPARE(uri.count("label=TEST_LABEL_1"), 2);
|
||||
QCOMPARE(receiveRequestDialog->QObject::findChild<QLabel*>("label_tag")->text(), QString("Label:"));
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
#include <QLatin1String>
|
||||
|
||||
QString TransactionDesc::FormatTxStatus(const interfaces::WalletTx& wtx, const interfaces::WalletTxStatus& status, bool inMempool, int numBlocks)
|
||||
{
|
||||
if (!status.is_final)
|
||||
@ -44,19 +46,20 @@ QString TransactionDesc::FormatTxStatus(const interfaces::WalletTx& wtx, const i
|
||||
bool fChainLocked = status.is_chainlocked;
|
||||
|
||||
if (nDepth == 0) {
|
||||
strTxStatus = tr("0/unconfirmed, %1").arg((inMempool ? tr("in memory pool") : tr("not in memory pool"))) + (status.is_abandoned ? ", "+tr("abandoned") : "");
|
||||
const QString abandoned{status.is_abandoned ? QLatin1String(", ") + tr("abandoned") : QString()};
|
||||
strTxStatus = tr("0/unconfirmed, %1").arg((inMempool ? tr("in memory pool") : tr("not in memory pool"))) + abandoned;
|
||||
} else if (!fChainLocked && nDepth < 6) {
|
||||
strTxStatus = tr("%1/unconfirmed").arg(nDepth);
|
||||
} else {
|
||||
strTxStatus = tr("%1 confirmations").arg(nDepth);
|
||||
if (fChainLocked) {
|
||||
strTxStatus += ", " + tr("locked via ChainLocks");
|
||||
strTxStatus += QLatin1String(", ") + tr("locked via ChainLocks");
|
||||
return strTxStatus;
|
||||
}
|
||||
}
|
||||
|
||||
if (status.is_islocked) {
|
||||
strTxStatus += ", " + tr("verified via InstantSend");
|
||||
strTxStatus += QLatin1String(", ") + tr("verified via InstantSend");
|
||||
}
|
||||
|
||||
return strTxStatus;
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <QIcon>
|
||||
#include <QLatin1Char>
|
||||
#include <QLatin1String>
|
||||
#include <QList>
|
||||
#include <QMessageBox>
|
||||
|
||||
@ -466,9 +468,9 @@ QVariant TransactionTableModel::txAddressDecoration(const TransactionRecord *wtx
|
||||
QString TransactionTableModel::formatTxToAddress(const TransactionRecord *wtx, bool tooltip) const
|
||||
{
|
||||
QString watchAddress;
|
||||
if (tooltip) {
|
||||
if (tooltip && wtx->involvesWatchAddress) {
|
||||
// Mark transactions involving watch-only addresses by adding " (watch-only)"
|
||||
watchAddress = wtx->involvesWatchAddress ? QString(" (") + tr("watch-only") + QString(")") : "";
|
||||
watchAddress = QLatin1String(" (") + tr("watch-only") + QLatin1Char(')');
|
||||
}
|
||||
|
||||
switch(wtx->type)
|
||||
|
@ -7,14 +7,11 @@
|
||||
#include <fs.h>
|
||||
#include <node/ui_interface.h>
|
||||
#include <psbt.h>
|
||||
#include <qt/bitcoingui.h>
|
||||
#include <qt/createwalletdialog.h>
|
||||
#include <qt/governancelist.h>
|
||||
#include <qt/guiutil.h>
|
||||
#include <qt/masternodelist.h>
|
||||
#include <qt/overviewpage.h>
|
||||
#include <qt/psbtoperationsdialog.h>
|
||||
#include <qt/walletcontroller.h>
|
||||
#include <qt/walletmodel.h>
|
||||
#include <qt/walletview.h>
|
||||
#include <util/system.h>
|
||||
@ -30,9 +27,8 @@
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
WalletFrame::WalletFrame(BitcoinGUI* _gui)
|
||||
: QFrame(_gui),
|
||||
gui(_gui),
|
||||
WalletFrame::WalletFrame(QWidget* parent)
|
||||
: QFrame(parent),
|
||||
m_size_hint(OverviewPage{nullptr}.sizeHint())
|
||||
{
|
||||
// Leave HBox hook for adding a list view later
|
||||
@ -53,11 +49,7 @@ WalletFrame::WalletFrame(BitcoinGUI* _gui)
|
||||
|
||||
// A button for create wallet dialog
|
||||
QPushButton* create_wallet_button = new QPushButton(tr("Create a new wallet"), walletStack);
|
||||
connect(create_wallet_button, &QPushButton::clicked, [this] {
|
||||
auto activity = new CreateWalletActivity(gui->getWalletController(), this);
|
||||
connect(activity, &CreateWalletActivity::finished, activity, &QObject::deleteLater);
|
||||
activity->create();
|
||||
});
|
||||
connect(create_wallet_button, &QPushButton::clicked, this, &WalletFrame::createWalletButtonClicked);
|
||||
no_wallet_layout->addWidget(create_wallet_button, 0, Qt::AlignHCenter | Qt::AlignTop);
|
||||
no_wallet_group->setLayout(no_wallet_layout);
|
||||
|
||||
@ -86,17 +78,15 @@ void WalletFrame::setClientModel(ClientModel *_clientModel)
|
||||
}
|
||||
}
|
||||
|
||||
bool WalletFrame::addWallet(WalletModel *walletModel)
|
||||
bool WalletFrame::addWallet(WalletModel* walletModel, WalletView* walletView)
|
||||
{
|
||||
if (!gui || !clientModel || !walletModel) return false;
|
||||
if (!clientModel || !walletModel) return false;
|
||||
|
||||
if (mapWalletViews.count(walletModel) > 0) return false;
|
||||
|
||||
WalletView* walletView = new WalletView(this);
|
||||
walletView->setClientModel(clientModel);
|
||||
walletView->setWalletModel(walletModel);
|
||||
walletView->showOutOfSyncWarning(bOutOfSync);
|
||||
walletView->setPrivacy(gui->isPrivacyModeActivated());
|
||||
|
||||
WalletView* current_wallet_view = currentWalletView();
|
||||
if (current_wallet_view) {
|
||||
@ -108,17 +98,6 @@ bool WalletFrame::addWallet(WalletModel *walletModel)
|
||||
walletStack->addWidget(walletView);
|
||||
mapWalletViews[walletModel] = walletView;
|
||||
|
||||
connect(walletView, &WalletView::outOfSyncWarningClicked, this, &WalletFrame::outOfSyncWarningClicked);
|
||||
connect(walletView, &WalletView::transactionClicked, gui, &BitcoinGUI::gotoHistoryPage);
|
||||
connect(walletView, &WalletView::coinsSent, gui, &BitcoinGUI::gotoHistoryPage);
|
||||
connect(walletView, &WalletView::message, [this](const QString& title, const QString& message, unsigned int style) {
|
||||
gui->message(title, message, style);
|
||||
});
|
||||
connect(walletView, &WalletView::encryptionStatusChanged, gui, &BitcoinGUI::updateWalletStatus);
|
||||
connect(walletView, &WalletView::incomingTransaction, gui, &BitcoinGUI::incomingTransaction);
|
||||
connect(walletView, &WalletView::hdEnabledStatusChanged, gui, &BitcoinGUI::updateWalletStatus);
|
||||
connect(gui, &BitcoinGUI::setPrivacy, walletView, &WalletView::setPrivacy);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -364,8 +343,3 @@ WalletModel* WalletFrame::currentWalletModel() const
|
||||
WalletView* wallet_view = currentWalletView();
|
||||
return wallet_view ? wallet_view->getWalletModel() : nullptr;
|
||||
}
|
||||
|
||||
void WalletFrame::outOfSyncWarningClicked()
|
||||
{
|
||||
Q_EMIT requestedSyncWarningInfo();
|
||||
}
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include <QGroupBox>
|
||||
#include <QMap>
|
||||
|
||||
class BitcoinGUI;
|
||||
class ClientModel;
|
||||
class SendCoinsRecipient;
|
||||
class WalletModel;
|
||||
@ -33,12 +32,12 @@ class WalletFrame : public QFrame
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit WalletFrame(BitcoinGUI* _gui = nullptr);
|
||||
explicit WalletFrame(QWidget* parent);
|
||||
~WalletFrame();
|
||||
|
||||
void setClientModel(ClientModel *clientModel);
|
||||
|
||||
bool addWallet(WalletModel *walletModel);
|
||||
bool addWallet(WalletModel* walletModel, WalletView* walletView);
|
||||
void setCurrentWallet(WalletModel* wallet_model);
|
||||
void removeWallet(WalletModel* wallet_model);
|
||||
void removeAllWallets();
|
||||
@ -51,12 +50,11 @@ public:
|
||||
|
||||
Q_SIGNALS:
|
||||
void message(const QString& title, const QString& message, unsigned int style);
|
||||
/** Notify that the user has requested more information about the out-of-sync warning */
|
||||
void requestedSyncWarningInfo();
|
||||
|
||||
void createWalletButtonClicked();
|
||||
|
||||
private:
|
||||
QStackedWidget *walletStack;
|
||||
BitcoinGUI *gui;
|
||||
ClientModel *clientModel;
|
||||
QMap<WalletModel*, WalletView*> mapWalletViews;
|
||||
QGroupBox* no_wallet_group;
|
||||
@ -110,8 +108,6 @@ public Q_SLOTS:
|
||||
void usedSendingAddresses();
|
||||
/** Show used receiving addresses */
|
||||
void usedReceivingAddresses();
|
||||
/** Pass on signal over requested out-of-sync-warning information */
|
||||
void outOfSyncWarningClicked();
|
||||
};
|
||||
|
||||
#endif // BITCOIN_QT_WALLETFRAME_H
|
||||
|
@ -100,7 +100,7 @@ WalletView::WalletView(QWidget* parent) :
|
||||
connect(overviewPage, &OverviewPage::transactionClicked, this, &WalletView::transactionClicked);
|
||||
// Clicking on a transaction on the overview pre-selects the transaction on the transaction history page
|
||||
connect(overviewPage, &OverviewPage::transactionClicked, transactionView, qOverload<const QModelIndex&>(&TransactionView::focusTransaction));
|
||||
connect(overviewPage, &OverviewPage::outOfSyncWarningClicked, this, &WalletView::requestedSyncWarningInfo);
|
||||
connect(overviewPage, &OverviewPage::outOfSyncWarningClicked, this, &WalletView::outOfSyncWarningClicked);
|
||||
|
||||
connect(sendCoinsPage, &SendCoinsDialog::coinsSent, this, &WalletView::coinsSent);
|
||||
connect(coinJoinCoinsPage, &SendCoinsDialog::coinsSent, this, &WalletView::coinsSent);
|
||||
@ -408,11 +408,6 @@ void WalletView::showProgress(const QString &title, int nProgress)
|
||||
}
|
||||
}
|
||||
|
||||
void WalletView::requestedSyncWarningInfo()
|
||||
{
|
||||
Q_EMIT outOfSyncWarningClicked();
|
||||
}
|
||||
|
||||
/** Update wallet with the sum of the selected transactions */
|
||||
void WalletView::trxAmount(QString amount)
|
||||
{
|
||||
|
@ -122,10 +122,6 @@ public Q_SLOTS:
|
||||
/** Show progress dialog e.g. for rescan */
|
||||
void showProgress(const QString &title, int nProgress);
|
||||
|
||||
/** User has requested more information about the out of sync state */
|
||||
void requestedSyncWarningInfo();
|
||||
|
||||
|
||||
/** Update selected DASH amount from transactionview */
|
||||
void trxAmount(QString amount);
|
||||
Q_SIGNALS:
|
||||
|
@ -115,7 +115,7 @@ bool LoadWallets(interfaces::Chain& chain, interfaces::CoinJoin::Loader& coinjoi
|
||||
if (!database && status == DatabaseStatus::FAILED_NOT_FOUND) {
|
||||
continue;
|
||||
}
|
||||
chain.initMessage(_("Loading wallet...").translated);
|
||||
chain.initMessage(_("Loading wallet…").translated);
|
||||
std::shared_ptr<CWallet> pwallet = database ? CWallet::Create(&chain, &coinjoin_loader, name, std::move(database), options.create_flags, error_string, warnings) : nullptr;
|
||||
if (!warnings.empty()) chain.initWarning(Join(warnings, Untranslated("\n")));
|
||||
if (!pwallet) {
|
||||
|
@ -238,7 +238,7 @@ std::shared_ptr<CWallet> LoadWalletInternal(interfaces::Chain& chain, interfaces
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
chain.initMessage(_("Loading wallet...").translated);
|
||||
chain.initMessage(_("Loading wallet…").translated);
|
||||
std::shared_ptr<CWallet> wallet = CWallet::Create(&chain, &coinjoin_loader, name, std::move(database), options.create_flags, error, warnings);
|
||||
if (!wallet) {
|
||||
error = Untranslated("Wallet loading failed.") + Untranslated(" ") + error;
|
||||
@ -304,7 +304,7 @@ std::shared_ptr<CWallet> CreateWallet(interfaces::Chain& chain, interfaces::Coin
|
||||
}
|
||||
|
||||
// Make the wallet
|
||||
chain.initMessage(_("Loading wallet...").translated);
|
||||
chain.initMessage(_("Loading wallet…").translated);
|
||||
std::shared_ptr<CWallet> wallet = CWallet::Create(&chain, &coinjoin_loader, name, std::move(database), wallet_creation_flags, error, warnings);
|
||||
if (!wallet) {
|
||||
error = Untranslated("Wallet creation failed.") + Untranslated(" ") + error;
|
||||
|
@ -16,7 +16,6 @@ EXPECTED_CIRCULAR_DEPENDENCIES=(
|
||||
"index/coinstatsindex -> node/coinstats -> index/coinstatsindex"
|
||||
"policy/fees -> txmempool -> policy/fees"
|
||||
"qt/addresstablemodel -> qt/walletmodel -> qt/addresstablemodel"
|
||||
"qt/bitcoingui -> qt/walletframe -> qt/bitcoingui"
|
||||
"qt/recentrequeststablemodel -> qt/walletmodel -> qt/recentrequeststablemodel"
|
||||
"qt/transactiontablemodel -> qt/walletmodel -> qt/transactiontablemodel"
|
||||
"txmempool -> validation -> txmempool"
|
||||
|
Loading…
Reference in New Issue
Block a user