Merge #6111: backport: bitcoin-core/gui#154, #176, #221, #248, #251 - qt improvements and related fixes

2917c33206 partial Merge bitcoin-core/gui#205: Save/restore TransactionView and recentRequestsView tables column sizes (Konstantin Akimov)
e5c2c03984 Merge bitcoin-core/gui#154: qt: Support macOS Dark mode (MarcoFalke)
29a98c7826 Merge bitcoin-core/gui#251: Improve URI/file handling message (MarcoFalke)
48d66fd1ab Merge bitcoin-core/gui#248: Fix: For values of "Bytes transferred" and "Bytes/s" with 1000-based prefix names use 1000-based divisor instead of 1024-based (MarcoFalke)
63b18006a3 Merge bitcoin-core/gui#221: qt, refactor: rpcconsole translatable string fixes and improvements (MarcoFalke)
0d1faa203e fix: removed maximum width of transaction list on overview page (Konstantin Akimov)
458384ab93 Merge bitcoin-core/gui#176: Fix TxViewDelegate layout (MarcoFalke)
d670240d13 Revert "fix: remove stretching from Overview page when it's not needed" (Konstantin Akimov)

Pull request description:

  ## Issue being fixed or feature implemented
  Backports of QT related improvements from bitcoin v22

  ## What was done?
  See commits for list of backports.
  Changes related to improved behavior of columns while resizing for Transactions List and Recent Requests is dropped due to low performance and buggy behaviour. bitcoin-core/gui#205 and bitcoin-core/gui#229 are DNM due to incompatibility with our table view.
  It reverts also #5992 as better fix is found (see css changes).

  ## How Has This Been Tested?
  Run qt app, try to resize main view with overview page.

  ## 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 ACK 2917c33206 (CI failure is unrelated)
  PastaPastaPasta:
    light-ACK 2917c33206

Tree-SHA512: b84c7e254562d86da30515d05572587edd1b451d988bbcfe16b8874f13d6b581910bed9008a7f8a408aae9181faa86703463fd508711e6e09b299be232ba3f48
This commit is contained in:
pasta 2024-07-23 14:16:25 -05:00
commit f708101978
No known key found for this signature in database
GPG Key ID: 52527BEDABE87984
14 changed files with 196 additions and 56 deletions

4
doc/release-notes-154.md Normal file
View File

@ -0,0 +1,4 @@
Compatibility
==============
Dash Core change appearance when macOS "dark mode" is activated.

View File

@ -56,9 +56,6 @@
<key>NSHighResolutionCapable</key> <key>NSHighResolutionCapable</key>
<string>True</string> <string>True</string>
<key>NSRequiresAquaSystemAppearance</key>
<string>True</string>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>
<string>Copyright © 2009-@COPYRIGHT_YEAR@ The Bitcoin Core developers, 2014-@COPYRIGHT_YEAR@ @COPYRIGHT_HOLDERS_FINAL@</string> <string>Copyright © 2009-@COPYRIGHT_YEAR@ The Bitcoin Core developers, 2014-@COPYRIGHT_YEAR@ @COPYRIGHT_HOLDERS_FINAL@</string>
<key>LSApplicationCategoryType</key> <key>LSApplicationCategoryType</key>

View File

@ -87,6 +87,7 @@ QT_MOC_CPP = \
qt/moc_transactiondesc.cpp \ qt/moc_transactiondesc.cpp \
qt/moc_transactiondescdialog.cpp \ qt/moc_transactiondescdialog.cpp \
qt/moc_transactionfilterproxy.cpp \ qt/moc_transactionfilterproxy.cpp \
qt/moc_transactionoverviewwidget.cpp \
qt/moc_transactiontablemodel.cpp \ qt/moc_transactiontablemodel.cpp \
qt/moc_transactionview.cpp \ qt/moc_transactionview.cpp \
qt/moc_utilitydialog.cpp \ qt/moc_utilitydialog.cpp \
@ -164,6 +165,7 @@ BITCOIN_QT_H = \
qt/transactiondesc.h \ qt/transactiondesc.h \
qt/transactiondescdialog.h \ qt/transactiondescdialog.h \
qt/transactionfilterproxy.h \ qt/transactionfilterproxy.h \
qt/transactionoverviewwidget.h \
qt/transactionrecord.h \ qt/transactionrecord.h \
qt/transactiontablemodel.h \ qt/transactiontablemodel.h \
qt/transactionview.h \ qt/transactionview.h \

View File

@ -37,7 +37,23 @@
</widget> </widget>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0"> <layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0,1,0,1">
<item>
<spacer name="horizontalSpacerLeft">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="verticalLayout_2">
<item> <item>
@ -560,6 +576,19 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<spacer name="horizontalSpacerCenter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="verticalLayout_3">
<item> <item>
@ -609,7 +638,7 @@
</layout> </layout>
</item> </item>
<item> <item>
<widget class="QListView" name="listTransactions"> <widget class="TransactionOverviewWidget" name="listTransactions">
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::NoFrame</enum> <enum>QFrame::NoFrame</enum>
</property> </property>
@ -619,9 +648,15 @@
<property name="horizontalScrollBarPolicy"> <property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum> <enum>Qt::ScrollBarAlwaysOff</enum>
</property> </property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<property name="selectionMode"> <property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum> <enum>QAbstractItemView::NoSelection</enum>
</property> </property>
<property name="uniformItemSizes">
<bool>true</bool>
</property>
</widget> </widget>
</item> </item>
</layout> </layout>
@ -629,10 +664,33 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<spacer name="horizontalSpacerRight">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout> </layout>
</item> </item>
</layout> </layout>
</widget> </widget>
<customwidgets>
<customwidget>
<class>TransactionOverviewWidget</class>
<extends>QListView</extends>
<header>qt/transactionoverviewwidget.h</header>
</customwidget>
</customwidgets>
<resources/> <resources/>
<connections/> <connections/>
</ui> </ui>

View File

@ -1785,14 +1785,14 @@ QString formatNiceTimeOffset(qint64 secs)
QString formatBytes(uint64_t bytes) QString formatBytes(uint64_t bytes)
{ {
if(bytes < 1024) if (bytes < 1'000)
return QObject::tr("%1 B").arg(bytes); return QObject::tr("%1 B").arg(bytes);
if(bytes < 1024 * 1024) if (bytes < 1'000'000)
return QObject::tr("%1 KB").arg(bytes / 1024); return QObject::tr("%1 kB").arg(bytes / 1'000);
if(bytes < 1024 * 1024 * 1024) if (bytes < 1'000'000'000)
return QObject::tr("%1 MB").arg(bytes / 1024 / 1024); return QObject::tr("%1 MB").arg(bytes / 1'000'000);
return QObject::tr("%1 GB").arg(bytes / 1024 / 1024 / 1024); return QObject::tr("%1 GB").arg(bytes / 1'000'000'000);
} }
qreal calculateIdealFontSize(int width, const QString& text, QFont font, qreal minPointSize, qreal font_size) { qreal calculateIdealFontSize(int width, const QString& text, QFont font, qreal minPointSize, qreal font_size) {

View File

@ -11,6 +11,7 @@
#include <qt/guiutil.h> #include <qt/guiutil.h>
#include <qt/optionsmodel.h> #include <qt/optionsmodel.h>
#include <qt/transactionfilterproxy.h> #include <qt/transactionfilterproxy.h>
#include <qt/transactionoverviewwidget.h>
#include <qt/transactiontablemodel.h> #include <qt/transactiontablemodel.h>
#include <qt/utilitydialog.h> #include <qt/utilitydialog.h>
#include <qt/walletmodel.h> #include <qt/walletmodel.h>
@ -18,6 +19,8 @@
#include <coinjoin/options.h> #include <coinjoin/options.h>
#include <interfaces/coinjoin.h> #include <interfaces/coinjoin.h>
#include <algorithm>
#include <map>
#include <cmath> #include <cmath>
#include <QAbstractItemDelegate> #include <QAbstractItemDelegate>
@ -42,7 +45,7 @@ public:
explicit TxViewDelegate(QObject* parent = nullptr) : explicit TxViewDelegate(QObject* parent = nullptr) :
QAbstractItemDelegate(), unit(BitcoinUnits::DASH) QAbstractItemDelegate(), unit(BitcoinUnits::DASH)
{ {
connect(this, &TxViewDelegate::width_changed, this, &TxViewDelegate::sizeHintChanged);
} }
inline void paint(QPainter *painter, const QStyleOptionViewItem &option, inline void paint(QPainter *painter, const QStyleOptionViewItem &option,
@ -83,7 +86,8 @@ public:
qint64 nAmount = index.data(TransactionTableModel::AmountRole).toLongLong(); qint64 nAmount = index.data(TransactionTableModel::AmountRole).toLongLong();
QString strAmount = BitcoinUnits::floorWithUnit(unit, nAmount, true, BitcoinUnits::SeparatorStyle::ALWAYS); QString strAmount = BitcoinUnits::floorWithUnit(unit, nAmount, true, BitcoinUnits::SeparatorStyle::ALWAYS);
painter->setPen(colorForeground); painter->setPen(colorForeground);
painter->drawText(rectTopHalf, Qt::AlignRight | Qt::AlignVCenter, strAmount); QRect amount_bounding_rect;
painter->drawText(rectTopHalf, Qt::AlignRight | Qt::AlignVCenter, strAmount, &amount_bounding_rect);
// Draw second line (with the initial font) // Draw second line (with the initial font)
// Content: Address/label, Optional Watchonly indicator // Content: Address/label, Optional Watchonly indicator
@ -93,6 +97,7 @@ public:
QString address = indexAddress.data(Qt::DisplayRole).toString(); QString address = indexAddress.data(Qt::DisplayRole).toString();
painter->setPen(colorForeground); painter->setPen(colorForeground);
painter->drawText(rectBottomHalf, Qt::AlignLeft | Qt::AlignVCenter, address, &rectBounding); painter->drawText(rectBottomHalf, Qt::AlignLeft | Qt::AlignVCenter, address, &rectBounding);
int address_rect_min_width = rectBounding.width();
// Optional Watchonly indicator // Optional Watchonly indicator
if (index.data(TransactionTableModel::WatchonlyRole).toBool()) if (index.data(TransactionTableModel::WatchonlyRole).toBool())
{ {
@ -101,17 +106,32 @@ public:
iconWatchonly.paint(painter, rectWatchonly); iconWatchonly.paint(painter, rectWatchonly);
} }
const int minimum_width = std::max(address_rect_min_width, amount_bounding_rect.width() /*+ date_bounding_rect.width() */);
const auto search = m_minimum_width.find(index.row());
if (search == m_minimum_width.end() || search->second != minimum_width) {
m_minimum_width[index.row()] = minimum_width;
Q_EMIT width_changed(index);
}
painter->restore(); painter->restore();
} }
inline QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override inline QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
{ {
return QSize(ITEM_HEIGHT, ITEM_HEIGHT); const auto search = m_minimum_width.find(index.row());
const int minimum_text_width = search == m_minimum_width.end() ? 0 : search->second;
return {ITEM_HEIGHT + 8 + minimum_text_width, ITEM_HEIGHT};
} }
int unit; int unit;
Q_SIGNALS:
//! An intermediate signal for emitting from the `paint() const` member function.
void width_changed(const QModelIndex& index) const;
private:
mutable std::map<int, int> m_minimum_width;
}; };
#include <qt/overviewpage.moc> #include <qt/overviewpage.moc>
OverviewPage::OverviewPage(QWidget* parent) : OverviewPage::OverviewPage(QWidget* parent) :
@ -151,7 +171,7 @@ OverviewPage::OverviewPage(QWidget* parent) :
// Note: minimum height of listTransactions will be set later in updateAdvancedCJUI() to reflect actual settings // Note: minimum height of listTransactions will be set later in updateAdvancedCJUI() to reflect actual settings
ui->listTransactions->setAttribute(Qt::WA_MacShowFocusRect, false); ui->listTransactions->setAttribute(Qt::WA_MacShowFocusRect, false);
connect(ui->listTransactions, &QListView::clicked, this, &OverviewPage::handleTransactionClicked); connect(ui->listTransactions, &TransactionOverviewWidget::clicked, this, &OverviewPage::handleTransactionClicked);
// init "out of sync" warning labels // init "out of sync" warning labels
ui->labelWalletStatus->setText("(" + tr("out of sync") + ")"); ui->labelWalletStatus->setText("(" + tr("out of sync") + ")");

View File

@ -239,8 +239,8 @@ void PaymentServer::handleURIOrFile(const QString& s)
if (!IsValidDestination(dest)) { if (!IsValidDestination(dest)) {
if (uri.hasQueryItem("r")) { // payment request if (uri.hasQueryItem("r")) { // payment request
Q_EMIT message(tr("URI handling"), Q_EMIT message(tr("URI handling"),
tr("Cannot process payment request as BIP70 is no longer supported.")+ tr("Cannot process payment request as BIP70 is no longer supported.\n"
tr("Due to discontinued support, you should request the merchant to provide you with a BIP21 compatible URI or use a wallet that does continue to support BIP70."), "Due to discontinued support, you should request the merchant to provide you with a BIP21 compatible URI or use a wallet that does continue to support BIP70."),
CClientUIInterface::ICON_WARNING); CClientUIInterface::ICON_WARNING);
} else { } else {
Q_EMIT message(tr("URI handling"), QString::fromStdString(error_msg), Q_EMIT message(tr("URI handling"), QString::fromStdString(error_msg),
@ -262,8 +262,8 @@ void PaymentServer::handleURIOrFile(const QString& s)
if (QFile::exists(s)) // payment request file if (QFile::exists(s)) // payment request file
{ {
Q_EMIT message(tr("Payment request file handling"), Q_EMIT message(tr("Payment request file handling"),
tr("Cannot process payment request as BIP70 is no longer supported.")+ tr("Cannot process payment request as BIP70 is no longer supported.\n"
tr("Due to discontinued support, you should request the merchant to provide you with a BIP21 compatible URI or use a wallet that does continue to support BIP70."), "Due to discontinued support, you should request the merchant to provide you with a BIP21 compatible URI or use a wallet that does continue to support BIP70."),
CClientUIInterface::ICON_WARNING); CClientUIInterface::ICON_WARNING);
} }
} }

View File

@ -1544,7 +1544,6 @@ QWidget .QFrame#frame_2 .QLabel#labelTransactionsStatus { /* Recent Transactions
QWidget .QFrame#frame_2 QListView { /* Transaction List */ QWidget .QFrame#frame_2 QListView { /* Transaction List */
background: #00000000; background: #00000000;
max-width: 430px;
margin-right: 10px; margin-right: 10px;
} }

View File

@ -531,9 +531,9 @@ RPCConsole::RPCConsole(interfaces::Node& node, QWidget* parent, Qt::WindowFlags
const QString list{"<ul><li>" + Join(CONNECTION_TYPE_DOC, QString("</li><li>")) + "</li></ul>"}; const QString list{"<ul><li>" + Join(CONNECTION_TYPE_DOC, QString("</li><li>")) + "</li></ul>"};
ui->peerConnectionTypeLabel->setToolTip(ui->peerConnectionTypeLabel->toolTip().arg(list)); ui->peerConnectionTypeLabel->setToolTip(ui->peerConnectionTypeLabel->toolTip().arg(list));
const QString hb_list{"<ul><li>\"" const QString hb_list{"<ul><li>\""
+ tr("To") + "\" " + tr("we selected the peer for high bandwidth relay") + "</li><li>\"" + ts.to + "\" " + tr("we selected the peer for high bandwidth relay") + "</li><li>\""
+ tr("From") + "\" " + tr("the peer selected us for high bandwidth relay") + "</li><li>\"" + ts.from + "\" " + tr("the peer selected us for high bandwidth relay") + "</li><li>\""
+ tr("No") + "\" " + tr("no high bandwidth relay selected") + "</li></ul>"}; + ts.no + "\" " + tr("no high bandwidth relay selected") + "</li></ul>"};
ui->peerHighBandwidthLabel->setToolTip(ui->peerHighBandwidthLabel->toolTip().arg(hb_list)); ui->peerHighBandwidthLabel->setToolTip(ui->peerHighBandwidthLabel->toolTip().arg(hb_list));
ui->dataDir->setToolTip(ui->dataDir->toolTip().arg(QString(nonbreaking_hyphen) + "datadir")); ui->dataDir->setToolTip(ui->dataDir->toolTip().arg(QString(nonbreaking_hyphen) + "datadir"));
ui->blocksDir->setToolTip(ui->blocksDir->toolTip().arg(QString(nonbreaking_hyphen) + "blocksdir")); ui->blocksDir->setToolTip(ui->blocksDir->toolTip().arg(QString(nonbreaking_hyphen) + "blocksdir"));
@ -707,10 +707,10 @@ void RPCConsole::setClientModel(ClientModel *model, int bestblock_height, int64_
// create peer table context menu actions // create peer table context menu actions
QAction* disconnectAction = new QAction(tr("&Disconnect"), this); QAction* disconnectAction = new QAction(tr("&Disconnect"), this);
QAction* banAction1h = new QAction(tr("Ban for") + " " + tr("1 &hour"), this); QAction* banAction1h = new QAction(ts.ban_for + " " + tr("1 &hour"), this);
QAction* banAction24h = new QAction(tr("Ban for") + " " + tr("1 &day"), this); QAction* banAction24h = new QAction(ts.ban_for + " " + tr("1 &day"), this);
QAction* banAction7d = new QAction(tr("Ban for") + " " + tr("1 &week"), this); QAction* banAction7d = new QAction(ts.ban_for + " " + tr("1 &week"), this);
QAction* banAction365d = new QAction(tr("Ban for") + " " + tr("1 &year"), this); QAction* banAction365d = new QAction(ts.ban_for + " " + tr("1 &year"), this);
// create peer table context menu // create peer table context menu
peersTableContextMenu = new QMenu(this); peersTableContextMenu = new QMenu(this);
@ -1301,9 +1301,9 @@ void RPCConsole::updateDetailWidget()
ui->peerLastBlock->setText(TimeDurationField(time_now, stats->nodeStats.m_last_block_time)); ui->peerLastBlock->setText(TimeDurationField(time_now, stats->nodeStats.m_last_block_time));
ui->peerLastTx->setText(TimeDurationField(time_now, stats->nodeStats.m_last_tx_time)); ui->peerLastTx->setText(TimeDurationField(time_now, stats->nodeStats.m_last_tx_time));
QString bip152_hb_settings; QString bip152_hb_settings;
if (stats->nodeStats.m_bip152_highbandwidth_to) bip152_hb_settings += "To"; if (stats->nodeStats.m_bip152_highbandwidth_to) bip152_hb_settings = ts.to;
if (stats->nodeStats.m_bip152_highbandwidth_from) bip152_hb_settings += (bip152_hb_settings == "" ? "From" : "/From"); if (stats->nodeStats.m_bip152_highbandwidth_from) bip152_hb_settings += (bip152_hb_settings.isEmpty() ? ts.from : QLatin1Char('/') + ts.from);
if (bip152_hb_settings == "") bip152_hb_settings = "No"; if (bip152_hb_settings.isEmpty()) bip152_hb_settings = ts.no;
ui->peerHighBandwidth->setText(bip152_hb_settings); ui->peerHighBandwidth->setText(bip152_hb_settings);
ui->peerLastSend->setText(TimeDurationField(time_now, stats->nodeStats.m_last_send)); ui->peerLastSend->setText(TimeDurationField(time_now, stats->nodeStats.m_last_send));
ui->peerLastRecv->setText(TimeDurationField(time_now, stats->nodeStats.m_last_recv)); ui->peerLastRecv->setText(TimeDurationField(time_now, stats->nodeStats.m_last_recv));
@ -1317,7 +1317,7 @@ void RPCConsole::updateDetailWidget()
ui->peerConnectionType->setText(GUIUtil::ConnectionTypeToQString(stats->nodeStats.m_conn_type, /* prepend_direction */ true)); ui->peerConnectionType->setText(GUIUtil::ConnectionTypeToQString(stats->nodeStats.m_conn_type, /* prepend_direction */ true));
ui->peerNetwork->setText(GUIUtil::NetworkToQString(stats->nodeStats.m_network)); ui->peerNetwork->setText(GUIUtil::NetworkToQString(stats->nodeStats.m_network));
if (stats->nodeStats.m_permissionFlags == NetPermissionFlags::None) { if (stats->nodeStats.m_permissionFlags == NetPermissionFlags::None) {
ui->peerPermissions->setText(tr("N/A")); ui->peerPermissions->setText(ts.na);
} else { } else {
QStringList permissions; QStringList permissions;
for (const auto& permission : NetPermissions::ToStrings(stats->nodeStats.m_permissionFlags)) { for (const auto& permission : NetPermissions::ToStrings(stats->nodeStats.m_permissionFlags)) {
@ -1325,11 +1325,11 @@ void RPCConsole::updateDetailWidget()
} }
ui->peerPermissions->setText(permissions.join(" & ")); ui->peerPermissions->setText(permissions.join(" & "));
} }
ui->peerMappedAS->setText(stats->nodeStats.m_mapped_as != 0 ? QString::number(stats->nodeStats.m_mapped_as) : tr("N/A")); ui->peerMappedAS->setText(stats->nodeStats.m_mapped_as != 0 ? QString::number(stats->nodeStats.m_mapped_as) : ts.na);
auto dmn = clientModel->getMasternodeList().first.GetMNByService(stats->nodeStats.addr); auto dmn = clientModel->getMasternodeList().first.GetMNByService(stats->nodeStats.addr);
if (dmn == nullptr) { if (dmn == nullptr) {
ui->peerNodeType->setText(tr("Regular")); ui->peerNodeType->setText(tr("Regular"));
ui->peerPoSeScore->setText(tr("N/A")); ui->peerPoSeScore->setText(ts.na);
} else { } else {
if (stats->nodeStats.verifiedProRegTxHash.IsNull()) { if (stats->nodeStats.verifiedProRegTxHash.IsNull()) {
ui->peerNodeType->setText(tr("Masternode")); ui->peerNodeType->setText(tr("Masternode"));
@ -1343,23 +1343,23 @@ void RPCConsole::updateDetailWidget()
// nodeStateStats couldn't be fetched. // nodeStateStats couldn't be fetched.
if (stats->fNodeStateStatsAvailable) { if (stats->fNodeStateStatsAvailable) {
// Sync height is init to -1 // Sync height is init to -1
if (stats->nodeStateStats.nSyncHeight > -1) if (stats->nodeStateStats.nSyncHeight > -1) {
ui->peerSyncHeight->setText(QString("%1").arg(stats->nodeStateStats.nSyncHeight)); ui->peerSyncHeight->setText(QString("%1").arg(stats->nodeStateStats.nSyncHeight));
else } else {
ui->peerSyncHeight->setText(tr("Unknown")); ui->peerSyncHeight->setText(ts.unknown);
}
// Common height is init to -1 // Common height is init to -1
if (stats->nodeStateStats.nCommonHeight > -1) if (stats->nodeStateStats.nCommonHeight > -1) {
ui->peerCommonHeight->setText(QString("%1").arg(stats->nodeStateStats.nCommonHeight)); ui->peerCommonHeight->setText(QString("%1").arg(stats->nodeStateStats.nCommonHeight));
else } else {
ui->peerCommonHeight->setText(tr("Unknown")); ui->peerCommonHeight->setText(ts.unknown);
}
ui->peerHeight->setText(QString::number(stats->nodeStateStats.m_starting_height)); ui->peerHeight->setText(QString::number(stats->nodeStateStats.m_starting_height));
ui->peerPingWait->setText(GUIUtil::formatPingTime(stats->nodeStateStats.m_ping_wait)); ui->peerPingWait->setText(GUIUtil::formatPingTime(stats->nodeStateStats.m_ping_wait));
ui->peerAddrRelayEnabled->setText(stats->nodeStateStats.m_addr_relay_enabled ? "Yes" : "No"); ui->peerAddrRelayEnabled->setText(stats->nodeStateStats.m_addr_relay_enabled ? ts.yes : ts.no);
ui->peerAddrProcessed->setText(QString::number(stats->nodeStateStats.m_addr_processed)); ui->peerAddrProcessed->setText(QString::number(stats->nodeStateStats.m_addr_processed));
ui->peerAddrRateLimited->setText(QString::number(stats->nodeStateStats.m_addr_rate_limited)); ui->peerAddrRateLimited->setText(QString::number(stats->nodeStateStats.m_addr_rate_limited));
ui->peerRelayTxes->setText(stats->nodeStateStats.m_relay_txs ? "Yes" : "No"); ui->peerRelayTxes->setText(stats->nodeStateStats.m_relay_txs ? ts.yes : ts.no);
} }
ui->peersTabRightPanel->show(); ui->peersTabRightPanel->show();

View File

@ -154,6 +154,11 @@ Q_SIGNALS:
void handleRestart(QStringList args); void handleRestart(QStringList args);
private: private:
struct TranslatedStrings {
const QString yes{tr("Yes")}, no{tr("No")}, to{tr("To")}, from{tr("From")},
ban_for{tr("Ban for")}, na{tr("N/A")}, unknown{tr("Unknown")};
} const ts;
void startExecutor(); void startExecutor();
void setTrafficGraphRange(TrafficGraphData::GraphRange range); void setTrafficGraphRange(TrafficGraphData::GraphRange range);
/** Build parameter list for restart */ /** Build parameter list for restart */

View File

@ -98,7 +98,7 @@ void TrafficGraphWidget::paintEvent(QPaintEvent *)
float val = pow(10.0f, base); float val = pow(10.0f, base);
float val2 = val; float val2 = val;
const QString units = tr("KB/s"); const QString units = tr("kB/s");
const float yMarginText = 2.0; const float yMarginText = 2.0;
// draw lines // draw lines

View File

@ -0,0 +1,41 @@
// Copyright (c) 2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_TRANSACTIONOVERVIEWWIDGET_H
#define BITCOIN_QT_TRANSACTIONOVERVIEWWIDGET_H
#include <qt/transactiontablemodel.h>
#include <QListView>
#include <QSize>
#include <QSizePolicy>
QT_BEGIN_NAMESPACE
class QShowEvent;
class QWidget;
QT_END_NAMESPACE
class TransactionOverviewWidget : public QListView
{
Q_OBJECT
public:
explicit TransactionOverviewWidget(QWidget* parent = nullptr) : QListView(parent) {}
QSize sizeHint() const override
{
return {sizeHintForColumn(TransactionTableModel::ToAddress), QListView::sizeHint().height()};
}
protected:
void showEvent(QShowEvent* event) override
{
Q_UNUSED(event);
QSizePolicy sp = sizePolicy();
sp.setHorizontalPolicy(QSizePolicy::Minimum);
setSizePolicy(sp);
}
};
#endif // BITCOIN_QT_TRANSACTIONOVERVIEWWIDGET_H

View File

@ -126,24 +126,23 @@ TransactionView::TransactionView(QWidget* parent) :
vlayout->setContentsMargins(0,0,0,0); vlayout->setContentsMargins(0,0,0,0);
vlayout->setSpacing(0); vlayout->setSpacing(0);
QTableView *view = new QTableView(this); transactionView = new QTableView(this);
vlayout->addLayout(hlayout); vlayout->addLayout(hlayout);
vlayout->addWidget(createDateRangeWidget()); vlayout->addWidget(createDateRangeWidget());
vlayout->addWidget(view); vlayout->addWidget(transactionView);
vlayout->setSpacing(0); vlayout->setSpacing(0);
#ifndef Q_OS_MAC #ifndef Q_OS_MAC
int width = view->verticalScrollBar()->sizeHint().width(); int width = transactionView->verticalScrollBar()->sizeHint().width();
// Cover scroll bar width with spacing // Cover scroll bar width with spacing
hlayout->addSpacing(width); hlayout->addSpacing(width);
// Always show scroll bar // Always show scroll bar
view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); transactionView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
#endif #endif
view->setTabKeyNavigation(false); transactionView->setTabKeyNavigation(false);
view->setContextMenuPolicy(Qt::CustomContextMenu); transactionView->setContextMenuPolicy(Qt::CustomContextMenu);
view->installEventFilter(this); transactionView->installEventFilter(this);
transactionView = view;
transactionView->setObjectName("transactionView"); transactionView->setObjectName("transactionView");
// Actions // Actions
@ -185,9 +184,9 @@ TransactionView::TransactionView(QWidget* parent) :
connect(search_widget, &QLineEdit::textChanged, prefix_typing_delay, static_cast<void (QTimer::*)()>(&QTimer::start)); connect(search_widget, &QLineEdit::textChanged, prefix_typing_delay, static_cast<void (QTimer::*)()>(&QTimer::start));
connect(prefix_typing_delay, &QTimer::timeout, this, &TransactionView::changedSearch); connect(prefix_typing_delay, &QTimer::timeout, this, &TransactionView::changedSearch);
connect(view, &QTableView::doubleClicked, this, &TransactionView::doubleClicked); connect(transactionView, &QTableView::doubleClicked, this, &TransactionView::doubleClicked);
connect(view, &QTableView::clicked, this, &TransactionView::computeSum); connect(transactionView, &QTableView::clicked, this, &TransactionView::computeSum);
connect(view, &QTableView::customContextMenuRequested, this, &TransactionView::contextualMenu); connect(transactionView, &QTableView::customContextMenuRequested, this, &TransactionView::contextualMenu);
connect(abandonAction, &QAction::triggered, this, &TransactionView::abandonTx); connect(abandonAction, &QAction::triggered, this, &TransactionView::abandonTx);
connect(resendAction, &QAction::triggered, this, &TransactionView::resendTx); connect(resendAction, &QAction::triggered, this, &TransactionView::resendTx);

View File

@ -123,9 +123,24 @@ void WalletFrame::setCurrentWallet(WalletModel* wallet_model)
{ {
if (mapWalletViews.count(wallet_model) == 0) return; if (mapWalletViews.count(wallet_model) == 0) return;
// Stop the effect of hidden widgets on the size hint of the shown one in QStackedWidget.
WalletView* view_about_to_hide = currentWalletView();
if (view_about_to_hide) {
QSizePolicy sp = view_about_to_hide->sizePolicy();
sp.setHorizontalPolicy(QSizePolicy::Ignored);
view_about_to_hide->setSizePolicy(sp);
}
WalletView *walletView = mapWalletViews.value(wallet_model); WalletView *walletView = mapWalletViews.value(wallet_model);
walletStack->setCurrentWidget(walletView);
assert(walletView); assert(walletView);
// Set or restore the default QSizePolicy which could be set to QSizePolicy::Ignored previously.
QSizePolicy sp = walletView->sizePolicy();
sp.setHorizontalPolicy(QSizePolicy::Preferred);
walletView->setSizePolicy(sp);
walletView->updateGeometry();
walletStack->setCurrentWidget(walletView);
walletView->updateEncryptionStatus(); walletView->updateEncryptionStatus();
} }