Skip to content

Commit

Permalink
Merge #6111: backport: bitcoin-core/gui#154, #176, #221, #248, #251 -…
Browse files Browse the repository at this point in the history
… qt improvements and related fixes

2917c33 partial Merge bitcoin-core/gui#205: Save/restore TransactionView and recentRequestsView tables column sizes (Konstantin Akimov)
e5c2c03 Merge bitcoin-core/gui#154: qt: Support macOS Dark mode (MarcoFalke)
29a98c7 Merge bitcoin-core/gui#251: Improve URI/file handling message (MarcoFalke)
48d66fd 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)
63b1800 Merge bitcoin-core/gui#221: qt, refactor: rpcconsole translatable string fixes and improvements (MarcoFalke)
0d1faa2 fix: removed maximum width of transaction list on overview page (Konstantin Akimov)
458384a Merge bitcoin-core/gui#176: Fix TxViewDelegate layout (MarcoFalke)
d670240 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 2917c33 (CI failure is unrelated)
  PastaPastaPasta:
    light-ACK 2917c33

Tree-SHA512: b84c7e254562d86da30515d05572587edd1b451d988bbcfe16b8874f13d6b581910bed9008a7f8a408aae9181faa86703463fd508711e6e09b299be232ba3f48
  • Loading branch information
PastaPastaPasta committed Jul 23, 2024
2 parents ef2ad76 + 2917c33 commit f708101
Show file tree
Hide file tree
Showing 14 changed files with 196 additions and 56 deletions.
4 changes: 4 additions & 0 deletions doc/release-notes-154.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Compatibility
==============

Dash Core change appearance when macOS "dark mode" is activated.
3 changes: 0 additions & 3 deletions share/qt/Info.plist.in
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,6 @@
<key>NSHighResolutionCapable</key>
<string>True</string>

<key>NSRequiresAquaSystemAppearance</key>
<string>True</string>

<key>NSHumanReadableCopyright</key>
<string>Copyright © 2009-@COPYRIGHT_YEAR@ The Bitcoin Core developers, 2014-@COPYRIGHT_YEAR@ @COPYRIGHT_HOLDERS_FINAL@</string>
<key>LSApplicationCategoryType</key>
Expand Down
2 changes: 2 additions & 0 deletions src/Makefile.qt.include
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ QT_MOC_CPP = \
qt/moc_transactiondesc.cpp \
qt/moc_transactiondescdialog.cpp \
qt/moc_transactionfilterproxy.cpp \
qt/moc_transactionoverviewwidget.cpp \
qt/moc_transactiontablemodel.cpp \
qt/moc_transactionview.cpp \
qt/moc_utilitydialog.cpp \
Expand Down Expand Up @@ -164,6 +165,7 @@ BITCOIN_QT_H = \
qt/transactiondesc.h \
qt/transactiondescdialog.h \
qt/transactionfilterproxy.h \
qt/transactionoverviewwidget.h \
qt/transactionrecord.h \
qt/transactiontablemodel.h \
qt/transactionview.h \
Expand Down
62 changes: 60 additions & 2 deletions src/qt/forms/overviewpage.ui
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,23 @@
</widget>
</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>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
Expand Down Expand Up @@ -560,6 +576,19 @@
</item>
</layout>
</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>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
Expand Down Expand Up @@ -609,7 +638,7 @@
</layout>
</item>
<item>
<widget class="QListView" name="listTransactions">
<widget class="TransactionOverviewWidget" name="listTransactions">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
Expand All @@ -619,20 +648,49 @@
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<property name="uniformItemSizes">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</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>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>TransactionOverviewWidget</class>
<extends>QListView</extends>
<header>qt/transactionoverviewwidget.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
12 changes: 6 additions & 6 deletions src/qt/guiutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1785,14 +1785,14 @@ QString formatNiceTimeOffset(qint64 secs)

QString formatBytes(uint64_t bytes)
{
if(bytes < 1024)
if (bytes < 1'000)
return QObject::tr("%1 B").arg(bytes);
if(bytes < 1024 * 1024)
return QObject::tr("%1 KB").arg(bytes / 1024);
if(bytes < 1024 * 1024 * 1024)
return QObject::tr("%1 MB").arg(bytes / 1024 / 1024);
if (bytes < 1'000'000)
return QObject::tr("%1 kB").arg(bytes / 1'000);
if (bytes < 1'000'000'000)
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) {
Expand Down
28 changes: 24 additions & 4 deletions src/qt/overviewpage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@
#include <qt/guiutil.h>
#include <qt/optionsmodel.h>
#include <qt/transactionfilterproxy.h>
#include <qt/transactionoverviewwidget.h>
#include <qt/transactiontablemodel.h>
#include <qt/utilitydialog.h>
#include <qt/walletmodel.h>

#include <coinjoin/options.h>
#include <interfaces/coinjoin.h>

#include <algorithm>
#include <map>
#include <cmath>

#include <QAbstractItemDelegate>
Expand All @@ -42,7 +45,7 @@ class TxViewDelegate : public QAbstractItemDelegate
explicit TxViewDelegate(QObject* parent = nullptr) :
QAbstractItemDelegate(), unit(BitcoinUnits::DASH)
{

connect(this, &TxViewDelegate::width_changed, this, &TxViewDelegate::sizeHintChanged);
}

inline void paint(QPainter *painter, const QStyleOptionViewItem &option,
Expand Down Expand Up @@ -83,7 +86,8 @@ class TxViewDelegate : public QAbstractItemDelegate
qint64 nAmount = index.data(TransactionTableModel::AmountRole).toLongLong();
QString strAmount = BitcoinUnits::floorWithUnit(unit, nAmount, true, BitcoinUnits::SeparatorStyle::ALWAYS);
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)
// Content: Address/label, Optional Watchonly indicator
Expand All @@ -93,6 +97,7 @@ class TxViewDelegate : public QAbstractItemDelegate
QString address = indexAddress.data(Qt::DisplayRole).toString();
painter->setPen(colorForeground);
painter->drawText(rectBottomHalf, Qt::AlignLeft | Qt::AlignVCenter, address, &rectBounding);
int address_rect_min_width = rectBounding.width();
// Optional Watchonly indicator
if (index.data(TransactionTableModel::WatchonlyRole).toBool())
{
Expand All @@ -101,17 +106,32 @@ class TxViewDelegate : public QAbstractItemDelegate
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();
}

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;

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>

OverviewPage::OverviewPage(QWidget* parent) :
Expand Down Expand Up @@ -151,7 +171,7 @@ OverviewPage::OverviewPage(QWidget* parent) :
// Note: minimum height of listTransactions will be set later in updateAdvancedCJUI() to reflect actual settings
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
ui->labelWalletStatus->setText("(" + tr("out of sync") + ")");
Expand Down
8 changes: 4 additions & 4 deletions src/qt/paymentserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,8 @@ void PaymentServer::handleURIOrFile(const QString& s)
if (!IsValidDestination(dest)) {
if (uri.hasQueryItem("r")) { // payment request
Q_EMIT message(tr("URI handling"),
tr("Cannot process payment request as BIP70 is no longer supported.")+
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."),
tr("Cannot process payment request as BIP70 is no longer supported.\n"
"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);
} else {
Q_EMIT message(tr("URI handling"), QString::fromStdString(error_msg),
Expand All @@ -262,8 +262,8 @@ void PaymentServer::handleURIOrFile(const QString& s)
if (QFile::exists(s)) // payment request file
{
Q_EMIT message(tr("Payment request file handling"),
tr("Cannot process payment request as BIP70 is no longer supported.")+
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."),
tr("Cannot process payment request as BIP70 is no longer supported.\n"
"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);
}
}
Expand Down
1 change: 0 additions & 1 deletion src/qt/res/css/general.css
Original file line number Diff line number Diff line change
Expand Up @@ -1544,7 +1544,6 @@ QWidget .QFrame#frame_2 .QLabel#labelTransactionsStatus { /* Recent Transactions

QWidget .QFrame#frame_2 QListView { /* Transaction List */
background: #00000000;
max-width: 430px;
margin-right: 10px;
}

Expand Down
46 changes: 23 additions & 23 deletions src/qt/rpcconsole.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>"};
ui->peerConnectionTypeLabel->setToolTip(ui->peerConnectionTypeLabel->toolTip().arg(list));
const QString hb_list{"<ul><li>\""
+ tr("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>\""
+ tr("No") + "\"" + tr("no high bandwidth relay selected") + "</li></ul>"};
+ ts.to + "\"" + tr("we selected the peer for high bandwidth relay") + "</li><li>\""
+ ts.from + "\"" + tr("the peer selected us for high bandwidth relay") + "</li><li>\""
+ ts.no + "\"" + tr("no high bandwidth relay selected") + "</li></ul>"};
ui->peerHighBandwidthLabel->setToolTip(ui->peerHighBandwidthLabel->toolTip().arg(hb_list));
ui->dataDir->setToolTip(ui->dataDir->toolTip().arg(QString(nonbreaking_hyphen) + "datadir"));
ui->blocksDir->setToolTip(ui->blocksDir->toolTip().arg(QString(nonbreaking_hyphen) + "blocksdir"));
Expand Down Expand Up @@ -707,10 +707,10 @@ void RPCConsole::setClientModel(ClientModel *model, int bestblock_height, int64_

// create peer table context menu actions
QAction* disconnectAction = new QAction(tr("&Disconnect"), this);
QAction* banAction1h = new QAction(tr("Ban for") + " " + tr("1 &hour"), this);
QAction* banAction24h = new QAction(tr("Ban for") + " " + tr("1 &day"), this);
QAction* banAction7d = new QAction(tr("Ban for") + " " + tr("1 &week"), this);
QAction* banAction365d = new QAction(tr("Ban for") + " " + tr("1 &year"), this);
QAction* banAction1h = new QAction(ts.ban_for + " " + tr("1 &hour"), this);
QAction* banAction24h = new QAction(ts.ban_for + " " + tr("1 &day"), this);
QAction* banAction7d = new QAction(ts.ban_for + " " + tr("1 &week"), this);
QAction* banAction365d = new QAction(ts.ban_for + " " + tr("1 &year"), this);

// create peer table context menu
peersTableContextMenu = new QMenu(this);
Expand Down Expand Up @@ -1301,9 +1301,9 @@ void RPCConsole::updateDetailWidget()
ui->peerLastBlock->setText(TimeDurationField(time_now, stats->nodeStats.m_last_block_time));
ui->peerLastTx->setText(TimeDurationField(time_now, stats->nodeStats.m_last_tx_time));
QString bip152_hb_settings;
if (stats->nodeStats.m_bip152_highbandwidth_to) bip152_hb_settings += "To";
if (stats->nodeStats.m_bip152_highbandwidth_from) bip152_hb_settings += (bip152_hb_settings == "" ? "From" : "/From");
if (bip152_hb_settings == "") bip152_hb_settings = "No";
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.isEmpty() ? ts.from : QLatin1Char('/') + ts.from);
if (bip152_hb_settings.isEmpty()) bip152_hb_settings = ts.no;
ui->peerHighBandwidth->setText(bip152_hb_settings);
ui->peerLastSend->setText(TimeDurationField(time_now, stats->nodeStats.m_last_send));
ui->peerLastRecv->setText(TimeDurationField(time_now, stats->nodeStats.m_last_recv));
Expand All @@ -1317,19 +1317,19 @@ void RPCConsole::updateDetailWidget()
ui->peerConnectionType->setText(GUIUtil::ConnectionTypeToQString(stats->nodeStats.m_conn_type, /* prepend_direction */ true));
ui->peerNetwork->setText(GUIUtil::NetworkToQString(stats->nodeStats.m_network));
if (stats->nodeStats.m_permissionFlags == NetPermissionFlags::None) {
ui->peerPermissions->setText(tr("N/A"));
ui->peerPermissions->setText(ts.na);
} else {
QStringList permissions;
for (const auto& permission : NetPermissions::ToStrings(stats->nodeStats.m_permissionFlags)) {
permissions.append(QString::fromStdString(permission));
}
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);
if (dmn == nullptr) {
ui->peerNodeType->setText(tr("Regular"));
ui->peerPoSeScore->setText(tr("N/A"));
ui->peerPoSeScore->setText(ts.na);
} else {
if (stats->nodeStats.verifiedProRegTxHash.IsNull()) {
ui->peerNodeType->setText(tr("Masternode"));
Expand All @@ -1343,23 +1343,23 @@ void RPCConsole::updateDetailWidget()
// nodeStateStats couldn't be fetched.
if (stats->fNodeStateStatsAvailable) {
// 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));
else
ui->peerSyncHeight->setText(tr("Unknown"));

} else {
ui->peerSyncHeight->setText(ts.unknown);
}
// 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));
else
ui->peerCommonHeight->setText(tr("Unknown"));

} else {
ui->peerCommonHeight->setText(ts.unknown);
}
ui->peerHeight->setText(QString::number(stats->nodeStateStats.m_starting_height));
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->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();
Expand Down
5 changes: 5 additions & 0 deletions src/qt/rpcconsole.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,11 @@ public Q_SLOTS:
void handleRestart(QStringList args);

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 setTrafficGraphRange(TrafficGraphData::GraphRange range);
/** Build parameter list for restart */
Expand Down
2 changes: 1 addition & 1 deletion src/qt/trafficgraphwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ void TrafficGraphWidget::paintEvent(QPaintEvent *)
float val = pow(10.0f, base);
float val2 = val;

const QString units = tr("KB/s");
const QString units = tr("kB/s");
const float yMarginText = 2.0;

// draw lines
Expand Down
Loading

0 comments on commit f708101

Please sign in to comment.