From 0ca353fb03986cc11d6d31e54332b875ddd8c4e2 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Tue, 12 May 2026 21:51:44 +0700 Subject: [PATCH 01/16] refactor(qt): move setupAppearance helper inside qt/appearancewidget module --- src/qt/appearancewidget.cpp | 46 +++++++++++++++++++++++++ src/qt/appearancewidget.h | 7 ++-- src/qt/bitcoin.cpp | 3 +- src/qt/guiutil.cpp | 45 +----------------------- src/qt/guiutil.h | 4 --- test/lint/lint-circular-dependencies.py | 2 +- 6 files changed, 55 insertions(+), 52 deletions(-) diff --git a/src/qt/appearancewidget.cpp b/src/qt/appearancewidget.cpp index 0f5bdda5c96e..ca066a6cb8fe 100644 --- a/src/qt/appearancewidget.cpp +++ b/src/qt/appearancewidget.cpp @@ -9,14 +9,18 @@ #include #include +#include +#include #include #include #include #include +#include #include #include +#include #include #include @@ -299,3 +303,45 @@ void AppearanceWidget::updateWeightSlider(const bool fForce) updateFontWeightBold(nIndexBold, true); } } + +void AppearanceWidget::setupAppearance(QWidget* parent, OptionsModel* model) +{ + if (!QSettings().value("fAppearanceSetupDone", false).toBool()) { + // Create the dialog + QDialog dlg(parent); + dlg.setObjectName("AppearanceSetup"); + dlg.setWindowTitle(QObject::tr("Appearance Setup")); + dlg.setWindowIcon(QIcon(":icons/dash")); + // And the widgets we add to it + QLabel lblHeading(QObject::tr("Please choose your preferred settings for the appearance of %1").arg(PACKAGE_NAME), &dlg); + lblHeading.setObjectName("lblHeading"); + lblHeading.setWordWrap(true); + QLabel lblSubHeading(QObject::tr("This can also be adjusted later in the \"Appearance\" tab of the preferences."), &dlg); + lblSubHeading.setObjectName("lblSubHeading"); + lblSubHeading.setWordWrap(true); + AppearanceWidget appearance(&dlg); + appearance.setModel(model); + QFrame line(&dlg); + line.setFrameShape(QFrame::HLine); + QDialogButtonBox buttonBox(QDialogButtonBox::Save); + // Put them into a vbox and add the vbox to the dialog + QVBoxLayout layout; + layout.addWidget(&lblHeading); + layout.addWidget(&lblSubHeading); + layout.addWidget(&line); + layout.addWidget(&appearance); + layout.addWidget(&buttonBox); + dlg.setLayout(&layout); + // Adjust the headings + GUIUtil::setFont({&lblHeading}, {GUIUtil::FontWeight::Bold, 16}); + GUIUtil::setFont({&lblSubHeading}, {GUIUtil::FontWeight::Normal, 14, true}); + // Make sure the dialog closes and accepts the settings if save has been pressed + QObject::connect(&buttonBox, &QDialogButtonBox::accepted, [&]() { + QSettings().setValue("fAppearanceSetupDone", true); + appearance.accept(); + dlg.accept(); + }); + // And fire it! + dlg.exec(); + } +} diff --git a/src/qt/appearancewidget.h b/src/qt/appearancewidget.h index 3080a5f87e76..c91770fdade5 100644 --- a/src/qt/appearancewidget.h +++ b/src/qt/appearancewidget.h @@ -7,8 +7,6 @@ #include -#include -#include #include namespace Ui { @@ -56,6 +54,11 @@ private Q_SLOTS: OptionsModel::FontChoice prevMoneyFont{OptionsModel::FontChoiceAbstract::ApplicationFont}; void updateWeightSlider(bool fForce = false); + +public: + // Setup appearance settings if not done yet + static void setupAppearance(QWidget* parent, OptionsModel* model); + }; #endif // BITCOIN_QT_APPEARANCEWIDGET_H diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 08132c0a3848..989f04e731a6 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -439,7 +440,7 @@ void BitcoinApplication::initializeResult(bool success, interfaces::BlockAndHead Q_EMIT windowShown(window); // Let the users setup their preferred appearance if there are no settings for it defined yet. - GUIUtil::setupAppearance(window, clientModel->getOptionsModel()); + AppearanceWidget::setupAppearance(window, clientModel->getOptionsModel()); #ifdef ENABLE_WALLET // Now that initialization/startup is done, process any command-line diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 2b02ac80e1a4..3f00700cf393 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -5,7 +5,7 @@ #include -#include +#include #include #include #include @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include @@ -260,48 +259,6 @@ void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent, bool fAllow widget->setCheckValidator(new BitcoinAddressCheckValidator(parent)); } -void setupAppearance(QWidget* parent, OptionsModel* model) -{ - if (!QSettings().value("fAppearanceSetupDone", false).toBool()) { - // Create the dialog - QDialog dlg(parent); - dlg.setObjectName("AppearanceSetup"); - dlg.setWindowTitle(QObject::tr("Appearance Setup")); - dlg.setWindowIcon(QIcon(":icons/dash")); - // And the widgets we add to it - QLabel lblHeading(QObject::tr("Please choose your preferred settings for the appearance of %1").arg(PACKAGE_NAME), &dlg); - lblHeading.setObjectName("lblHeading"); - lblHeading.setWordWrap(true); - QLabel lblSubHeading(QObject::tr("This can also be adjusted later in the \"Appearance\" tab of the preferences."), &dlg); - lblSubHeading.setObjectName("lblSubHeading"); - lblSubHeading.setWordWrap(true); - AppearanceWidget appearance(&dlg); - appearance.setModel(model); - QFrame line(&dlg); - line.setFrameShape(QFrame::HLine); - QDialogButtonBox buttonBox(QDialogButtonBox::Save); - // Put them into a vbox and add the vbox to the dialog - QVBoxLayout layout; - layout.addWidget(&lblHeading); - layout.addWidget(&lblSubHeading); - layout.addWidget(&line); - layout.addWidget(&appearance); - layout.addWidget(&buttonBox); - dlg.setLayout(&layout); - // Adjust the headings - setFont({&lblHeading}, {GUIUtil::FontWeight::Bold, 16}); - setFont({&lblSubHeading}, {GUIUtil::FontWeight::Normal, 14, true}); - // Make sure the dialog closes and accepts the settings if save has been pressed - QObject::connect(&buttonBox, &QDialogButtonBox::accepted, [&]() { - QSettings().setValue("fAppearanceSetupDone", true); - appearance.accept(); - dlg.accept(); - }); - // And fire it! - dlg.exec(); - } -} - void AddButtonShortcut(QAbstractButton* button, const QKeySequence& shortcut) { QObject::connect(new QShortcut(shortcut, button), &QShortcut::activated, [button]() { button->animateClick(); }); diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 3a9b9240400a..d31b59ea3ab4 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -29,7 +29,6 @@ #include class QValidatedLineEdit; -class OptionsModel; class SendCoinsRecipient; namespace interfaces @@ -131,9 +130,6 @@ namespace GUIUtil // Set up widget for address void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent, bool fAllowURI = false); - // Setup appearance settings if not done yet - void setupAppearance(QWidget* parent, OptionsModel* model); - /** * Connects an additional shortcut to a QAbstractButton. Works around the * one shortcut limitation of the button's shortcut property. diff --git a/test/lint/lint-circular-dependencies.py b/test/lint/lint-circular-dependencies.py index cb3f4c80e89a..c1fe90a8c5dc 100755 --- a/test/lint/lint-circular-dependencies.py +++ b/test/lint/lint-circular-dependencies.py @@ -47,11 +47,11 @@ "masternode/payments -> validation -> masternode/payments", "net -> netmessagemaker -> net", "netaddress -> netbase -> netaddress", - "qt/appearancewidget -> qt/guiutil -> qt/appearancewidget", "qt/bitcoinaddressvalidator -> qt/guiutil -> qt/bitcoinaddressvalidator", "qt/bitcoingui -> qt/guiutil -> qt/bitcoingui", "qt/clientfeeds -> qt/clientmodel -> qt/clientfeeds", "qt/guiutil -> qt/qvalidatedlineedit -> qt/guiutil", + "qt/guiutil -> qt/guiutil_font -> qt/guiutil", "wallet/coinjoin -> wallet/receive -> wallet/coinjoin", ) From e68ad621240978a9fc5004190dde704c087afa90 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Fri, 15 May 2026 15:59:52 +0700 Subject: [PATCH 02/16] refactor: new helpers for font changes --- src/qt/guiutil_font.cpp | 38 ++++++++++++++++++++++++++++++++++++++ src/qt/guiutil_font.h | 16 ++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/src/qt/guiutil_font.cpp b/src/qt/guiutil_font.cpp index d7cd9c7895be..c7b5549985b2 100644 --- a/src/qt/guiutil_font.cpp +++ b/src/qt/guiutil_font.cpp @@ -337,6 +337,44 @@ int weightToArg(const QFont::Weight weight) return mapWeightArgs.second.find(weight)->second; } +bool isValidWeightArg(int arg) +{ + QFont::Weight weight; + return weightFromArg(arg, weight) && g_font_registry.IsValidWeight(weight); +} + +int currentWeightArg(FontWeight slot) +{ + return weightToArg(slot == FontWeight::Bold ? g_font_registry.GetWeightBold() + : g_font_registry.GetWeightNormal()); +} + +int defaultWeightArg(FontWeight slot) +{ + return weightToArg(slot == FontWeight::Bold ? g_font_registry.GetWeightBoldDefault() + : g_font_registry.GetWeightNormalDefault()); +} + +void setWeightFromArg(FontWeight slot, int arg) +{ + QFont::Weight weight; + if (!weightFromArg(arg, weight)) return; + if (slot == FontWeight::Bold) { + g_font_registry.SetWeightBold(weight); + } else { + g_font_registry.SetWeightNormal(weight); + } +} + +std::vector supportedWeightArgs() +{ + std::vector ret; + for (const auto& w : g_font_registry.GetSupportedWeights()) { + ret.push_back(weightToArg(w)); + } + return ret; +} + //! Internal helper to create a font with explicit weight (used for font detection) static QFont getFontWithWeight(const QString& font_name, QFont::Weight weight, double point_size) { diff --git a/src/qt/guiutil_font.h b/src/qt/guiutil_font.h index 3268c2169524..b4cd0358c4df 100644 --- a/src/qt/guiutil_font.h +++ b/src/qt/guiutil_font.h @@ -140,6 +140,22 @@ bool weightFromArg(int nArg, QFont::Weight& weight); /** Convert QFont::Weight to an arg value (0-8) */ int weightToArg(const QFont::Weight weight); +/* Weight operations expressed in caller-friendly arg ints (0..8). This is the + * format used by `-font-weight-*` CLI args and QSettings persistence. Callers + * that need slider positions (idx in 0..supportedWeightArgs().size()-1) build + * that bridge themselves from `supportedWeightArgs()`. */ + +/** True if `arg` (0..8) maps to a weight supported by the active font. */ +bool isValidWeightArg(int arg); +/** Current weight for `slot`, as arg int. */ +int currentWeightArg(FontWeight slot); +/** Default-best-match weight for `slot`, as arg int. Valid before loadFonts() too. */ +int defaultWeightArg(FontWeight slot); +/** Apply a weight from its arg int. No-op if `arg` is out of 0..8. */ +void setWeightFromArg(FontWeight slot, int arg); +/** Active font's supported weight args, in low-to-high order. */ +std::vector supportedWeightArgs(); + /** Load dash specific application fonts */ bool loadFonts(); From aa9cf24595c512f111f5e1df060fdaea6c7d9165 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Mon, 18 May 2026 03:17:31 +0700 Subject: [PATCH 03/16] refactor: unify qt settings and command line setting for weight --- src/qt/appearancewidget.cpp | 52 +++++++++++++++-------------- src/qt/appearancewidget.h | 5 +-- src/qt/bitcoin.cpp | 16 ++++----- src/qt/optionsmodel.cpp | 66 +++++++++++-------------------------- 4 files changed, 57 insertions(+), 82 deletions(-) diff --git a/src/qt/appearancewidget.cpp b/src/qt/appearancewidget.cpp index ca066a6cb8fe..1b837432d054 100644 --- a/src/qt/appearancewidget.cpp +++ b/src/qt/appearancewidget.cpp @@ -24,6 +24,9 @@ #include #include +#include +#include + int setFontChoice(QComboBox* cb, const OptionsModel::FontChoice& fc) { int i; @@ -82,8 +85,8 @@ AppearanceWidget::AppearanceWidget(QWidget* parent) : prevTheme{GUIUtil::getActiveTheme()}, prevScale{GUIUtil::g_font_registry.GetFontScale()}, prevFontFamily{GUIUtil::g_font_registry.GetFont()}, - prevWeightNormal{GUIUtil::g_font_registry.GetWeightNormal()}, - prevWeightBold{GUIUtil::g_font_registry.GetWeightBold()} + prevWeightNormalArg{GUIUtil::currentWeightArg(GUIUtil::FontWeight::Normal)}, + prevWeightBoldArg{GUIUtil::currentWeightArg(GUIUtil::FontWeight::Bold)} { ui->setupUi(this); @@ -139,11 +142,11 @@ AppearanceWidget::~AppearanceWidget() if (prevScale != GUIUtil::g_font_registry.GetFontScale()) { GUIUtil::g_font_registry.SetFontScale(prevScale); } - if (prevWeightNormal != GUIUtil::g_font_registry.GetWeightNormal()) { - GUIUtil::g_font_registry.SetWeightNormal(prevWeightNormal); + if (prevWeightNormalArg != GUIUtil::currentWeightArg(GUIUtil::FontWeight::Normal)) { + GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Normal, prevWeightNormalArg); } - if (prevWeightBold != GUIUtil::g_font_registry.GetWeightBold()) { - GUIUtil::g_font_registry.SetWeightBold(prevWeightBold); + if (prevWeightBoldArg != GUIUtil::currentWeightArg(GUIUtil::FontWeight::Bold)) { + GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Bold, prevWeightBoldArg); } // Restore monospace font if cancelled if (model) { @@ -198,18 +201,14 @@ void AppearanceWidget::setModel(OptionsModel* _model) if (is_overridden) { ui->fontWeightNormalSlider->setEnabled(false); } - if (const auto idx{GUIUtil::g_font_registry.WeightToIdx(GUIUtil::g_font_registry.GetWeightNormal())}; idx != -1) { - ui->fontWeightNormalSlider->setValue(idx); - } + ui->fontWeightNormalSlider->setValue(GUIUtil::currentWeightArg(GUIUtil::FontWeight::Normal)); } if (bool is_overridden{_model->isOptionOverridden("-font-weight-bold")}; is_overridden || override_family) { if (is_overridden) { ui->fontWeightBoldSlider->setEnabled(false); } - if (const auto idx{GUIUtil::g_font_registry.WeightToIdx(GUIUtil::g_font_registry.GetWeightBold())}; idx != -1) { - ui->fontWeightBoldSlider->setValue(idx); - } + ui->fontWeightBoldSlider->setValue(GUIUtil::currentWeightArg(GUIUtil::FontWeight::Bold)); } } @@ -252,9 +251,11 @@ void AppearanceWidget::updateFontWeightNormal(int nValue, bool fForce) if (nValue > ui->fontWeightBoldSlider->value() && !fForce) { nSliderValue = ui->fontWeightBoldSlider->value(); } + nSliderValue = std::ranges::min(GUIUtil::supportedWeightArgs(), {}, + [nSliderValue](int x) { return std::abs(x - nSliderValue); }); const QSignalBlocker blocker(ui->fontWeightNormalSlider); ui->fontWeightNormalSlider->setValue(nSliderValue); - GUIUtil::g_font_registry.SetWeightNormal(GUIUtil::g_font_registry.IdxToWeight(ui->fontWeightNormalSlider->value())); + GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Normal, nSliderValue); GUIUtil::setApplicationFont(); GUIUtil::updateFonts(); } @@ -265,9 +266,11 @@ void AppearanceWidget::updateFontWeightBold(int nValue, bool fForce) if (nValue < ui->fontWeightNormalSlider->value() && !fForce) { nSliderValue = ui->fontWeightNormalSlider->value(); } + nSliderValue = std::ranges::min(GUIUtil::supportedWeightArgs(), {}, + [nSliderValue](int x) { return std::abs(x - nSliderValue); }); const QSignalBlocker blocker(ui->fontWeightBoldSlider); ui->fontWeightBoldSlider->setValue(nSliderValue); - GUIUtil::g_font_registry.SetWeightBold(GUIUtil::g_font_registry.IdxToWeight(ui->fontWeightBoldSlider->value())); + GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Bold, nSliderValue); GUIUtil::setApplicationFont(); GUIUtil::updateFonts(); } @@ -287,20 +290,19 @@ void AppearanceWidget::updateMoneyFont(int index) void AppearanceWidget::updateWeightSlider(const bool fForce) { - int nMaximum = GUIUtil::g_font_registry.GetSupportedWeights().size() - 1; + const auto supported = GUIUtil::supportedWeightArgs(); + const int nMin = supported.front(); + const int nMax = supported.back(); - ui->fontWeightNormalSlider->setMinimum(0); - ui->fontWeightNormalSlider->setMaximum(nMaximum); + ui->fontWeightNormalSlider->setMinimum(nMin); + ui->fontWeightNormalSlider->setMaximum(nMax); - ui->fontWeightBoldSlider->setMinimum(0); - ui->fontWeightBoldSlider->setMaximum(nMaximum); + ui->fontWeightBoldSlider->setMinimum(nMin); + ui->fontWeightBoldSlider->setMaximum(nMax); - if (fForce || !GUIUtil::g_font_registry.IsValidWeight(prevWeightNormal) || !GUIUtil::g_font_registry.IsValidWeight(prevWeightBold)) { - int nIndexNormal = GUIUtil::g_font_registry.WeightToIdx(GUIUtil::g_font_registry.GetWeightNormalDefault()); - int nIndexBold = GUIUtil::g_font_registry.WeightToIdx(GUIUtil::g_font_registry.GetWeightBoldDefault()); - assert(nIndexNormal != -1 && nIndexBold != -1); - updateFontWeightNormal(nIndexNormal, true); - updateFontWeightBold(nIndexBold, true); + if (fForce || !GUIUtil::isValidWeightArg(prevWeightNormalArg) || !GUIUtil::isValidWeightArg(prevWeightBoldArg)) { + updateFontWeightNormal(GUIUtil::defaultWeightArg(GUIUtil::FontWeight::Normal), true); + updateFontWeightBold(GUIUtil::defaultWeightArg(GUIUtil::FontWeight::Bold), true); } } diff --git a/src/qt/appearancewidget.h b/src/qt/appearancewidget.h index c91770fdade5..2fa1f9b8b769 100644 --- a/src/qt/appearancewidget.h +++ b/src/qt/appearancewidget.h @@ -49,8 +49,9 @@ private Q_SLOTS: QString prevTheme; int prevScale; QString prevFontFamily; - QFont::Weight prevWeightNormal; - QFont::Weight prevWeightBold; + //! Snapshots stored as -font-weight-* arg ints (0..8), matching slider values. + int prevWeightNormalArg; + int prevWeightBoldArg; OptionsModel::FontChoice prevMoneyFont{OptionsModel::FontChoiceAbstract::ApplicationFont}; void updateWeightSlider(bool fForce = false); diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 989f04e731a6..084333049f54 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -503,8 +503,8 @@ static void SetupUIArgs(ArgsManager& argsman) argsman.AddArg("-custom-css-dir", "Set a directory which contains custom css files. Those will be used as stylesheets for the UI.", ArgsManager::ALLOW_ANY, OptionsCategory::GUI); argsman.AddArg("-font-family", QObject::tr("Set the font family. Possible values: %1. (default: %2)").arg(Join(GUIUtil::getFonts(/*selectable_only=*/true), ", ")).arg(GUIUtil::FontRegistry::DEFAULT_FONT).toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); argsman.AddArg("-font-scale", QObject::tr("Set a scale factor which gets applied to the base font size. Possible range %1 (smallest fonts) to %2 (largest fonts). (default: %3)").arg(-100).arg(100).arg(GUIUtil::FontRegistry::DEFAULT_FONT_SCALE).toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); - argsman.AddArg("-font-weight-bold", QObject::tr("Set the font weight for bold texts. Possible range %1 to %2 (default: %3)").arg(0).arg(8).arg(GUIUtil::weightToArg(GUIUtil::FontRegistry::TARGET_WEIGHT_BOLD)).toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); - argsman.AddArg("-font-weight-normal", QObject::tr("Set the font weight for normal texts. Possible range %1 to %2 (default: %3)").arg(0).arg(8).arg(GUIUtil::weightToArg(GUIUtil::FontRegistry::TARGET_WEIGHT_NORMAL)).toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); + argsman.AddArg("-font-weight-bold", QObject::tr("Set the font weight for bold texts. Possible range %1 to %2 (default: %3)").arg(0).arg(8).arg(GUIUtil::defaultWeightArg(GUIUtil::FontWeight::Bold)).toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); + argsman.AddArg("-font-weight-normal", QObject::tr("Set the font weight for normal texts. Possible range %1 to %2 (default: %3)").arg(0).arg(8).arg(GUIUtil::defaultWeightArg(GUIUtil::FontWeight::Normal)).toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); argsman.AddArg("-lang=", QObject::tr("Set language, for example \"de_DE\" (default: system locale)").toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); argsman.AddArg("-min", QObject::tr("Start minimized").toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); argsman.AddArg("-resetguisettings", QObject::tr("Reset all settings changed in the GUI").toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); @@ -728,23 +728,23 @@ int GuiMain(int argc, char* argv[]) } // Validate/set normal font weight if (gArgs.IsArgSet("-font-weight-normal")) { - QFont::Weight weight; - if (!GUIUtil::weightFromArg(gArgs.GetIntArg("-font-weight-normal", GUIUtil::weightToArg(GUIUtil::g_font_registry.GetWeightNormal())), weight)) { + const int arg = gArgs.GetIntArg("-font-weight-normal", GUIUtil::currentWeightArg(GUIUtil::FontWeight::Normal)); + if (!GUIUtil::isValidWeightArg(arg)) { QMessageBox::critical(nullptr, PACKAGE_NAME, QObject::tr("Error: Specified font-weight-normal invalid. Valid range %1 to %2.").arg(0).arg(8)); return EXIT_FAILURE; } - GUIUtil::g_font_registry.SetWeightNormal(weight); + GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Normal, arg); } // Validate/set bold font weight if (gArgs.IsArgSet("-font-weight-bold")) { - QFont::Weight weight; - if (!GUIUtil::weightFromArg(gArgs.GetIntArg("-font-weight-bold", GUIUtil::weightToArg(GUIUtil::g_font_registry.GetWeightBold())), weight)) { + const int arg = gArgs.GetIntArg("-font-weight-bold", GUIUtil::currentWeightArg(GUIUtil::FontWeight::Bold)); + if (!GUIUtil::isValidWeightArg(arg)) { QMessageBox::critical(nullptr, PACKAGE_NAME, QObject::tr("Error: Specified font-weight-bold invalid. Valid range %1 to %2.").arg(0).arg(8)); return EXIT_FAILURE; } - GUIUtil::g_font_registry.SetWeightBold(weight); + GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Bold, arg); } // Validate/set font scale if (gArgs.IsArgSet("-font-scale")) { diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 057751997f17..6f0e72d06aef 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -146,28 +146,6 @@ static int ParsePruneSizeGB(const QVariant& prune_size) return std::max(1, prune_size.toInt()); } -static int GetFallbackWeightIndex(bool is_bold) -{ - if (is_bold) { - // If the currently selected weight is not supported fallback to the second lightest weight for bold font - // or the lightest if there is only one. - return GUIUtil::g_font_registry.GetSupportedWeights().size() > 1 ? 1 : 0; - } else { - // If the currently selected weight is not supported fallback to the lightest weight for normal font. - return 0; - } -} - -static int WeightArgToIdx(bool is_bold, int weight_arg) -{ - if (QFont::Weight weight; GUIUtil::weightFromArg(weight_arg, weight)) { - if (int index = GUIUtil::g_font_registry.WeightToIdx(weight); index != -1) { - return index; - } - } - return GetFallbackWeightIndex(is_bold); -} - struct ProxySetting { bool is_set; QString ip; @@ -301,15 +279,16 @@ bool OptionsModel::Init(bilingual_str& error) const bool override_family{isOptionOverridden("-font-family")}; if (GUIUtil::fontsLoaded()) { // If font was overridden by CLI but weight wasn't, use the font's default weight - QFont::Weight weight{GUIUtil::g_font_registry.GetWeightNormalDefault()}; + const int default_arg = GUIUtil::defaultWeightArg(GUIUtil::FontWeight::Normal); + int arg = default_arg; if (!override_family || isOptionOverridden("-font-weight-normal")) { - const auto raw_weight{SettingToInt(node().getPersistentSetting("font-weight-normal"), GUIUtil::weightToArg(GUIUtil::FontRegistry::TARGET_WEIGHT_NORMAL))}; - if (!GUIUtil::weightFromArg(raw_weight, weight) || !GUIUtil::g_font_registry.IsValidWeight(weight)) { - weight = GUIUtil::g_font_registry.IdxToWeight(GetFallbackWeightIndex(/*is_bold=*/false)); - node().forceSetting("font-weight-normal", GUIUtil::weightToArg(weight)); + arg = SettingToInt(node().getPersistentSetting("font-weight-normal"), default_arg); + if (!GUIUtil::isValidWeightArg(arg)) { + arg = default_arg; + node().forceSetting("font-weight-normal", arg); } } - GUIUtil::g_font_registry.SetWeightNormal(weight); + GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Normal, arg); } // Font Weight (Bold) @@ -318,15 +297,16 @@ bool OptionsModel::Init(bilingual_str& error) } if (GUIUtil::fontsLoaded()) { // If font was overridden by CLI but weight wasn't, use the font's default weight - QFont::Weight weight{GUIUtil::g_font_registry.GetWeightBoldDefault()}; + const int default_arg = GUIUtil::defaultWeightArg(GUIUtil::FontWeight::Bold); + int arg = default_arg; if (!override_family || isOptionOverridden("-font-weight-bold")) { - const auto raw_weight{SettingToInt(node().getPersistentSetting("font-weight-bold"), GUIUtil::weightToArg(GUIUtil::FontRegistry::TARGET_WEIGHT_BOLD))}; - if (!GUIUtil::weightFromArg(raw_weight, weight) || !GUIUtil::g_font_registry.IsValidWeight(weight)) { - weight = GUIUtil::g_font_registry.IdxToWeight(GetFallbackWeightIndex(/*is_bold=*/true)); - node().forceSetting("font-weight-bold", GUIUtil::weightToArg(weight)); + arg = SettingToInt(node().getPersistentSetting("font-weight-bold"), default_arg); + if (!GUIUtil::isValidWeightArg(arg)) { + arg = default_arg; + node().forceSetting("font-weight-bold", arg); } } - GUIUtil::g_font_registry.SetWeightBold(weight); + GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Bold, arg); } // Apply font changes @@ -726,9 +706,9 @@ QVariant OptionsModel::getOption(OptionID option, const std::string& suffix) con case FontScale: return qlonglong(SettingToInt(setting(), GUIUtil::FontRegistry::DEFAULT_FONT_SCALE)); case FontWeightNormal: - return WeightArgToIdx(/*is_bold=*/false, SettingToInt(setting(), GUIUtil::g_font_registry.GetWeightNormalDefault())); + return qlonglong(SettingToInt(setting(), GUIUtil::defaultWeightArg(GUIUtil::FontWeight::Normal))); case FontWeightBold: - return WeightArgToIdx(/*is_bold=*/true, SettingToInt(setting(), GUIUtil::g_font_registry.GetWeightBoldDefault())); + return qlonglong(SettingToInt(setting(), GUIUtil::defaultWeightArg(GUIUtil::FontWeight::Bold))); case Language: return QString::fromStdString(SettingToString(setting(), "")); case FontForMoney: @@ -997,18 +977,12 @@ bool OptionsModel::setOption(OptionID option, const QVariant& value, const std:: update(value.toInt()); } break; - case FontWeightNormal: { - if (changed()) { - update(GUIUtil::weightToArg(GUIUtil::g_font_registry.IdxToWeight(value.toInt()))); - } - break; - } - case FontWeightBold: { + case FontWeightNormal: + case FontWeightBold: if (changed()) { - update(GUIUtil::weightToArg(GUIUtil::g_font_registry.IdxToWeight(value.toInt()))); + update(value.toInt()); } break; - } case Language: if (changed()) { update(value.toString().toStdString()); @@ -1200,8 +1174,6 @@ void OptionsModel::checkAndMigrate() ProxySetting parsed = ParseProxyString(value.toString()); setOption(ProxyIPTor, parsed.ip); setOption(ProxyPortTor, parsed.port); - } else if (option == FontWeightNormal || option == FontWeightBold) { - setOption(option, WeightArgToIdx(/*is_bold=*/option == FontWeightBold, value.toInt())); } else { setOption(option, value); } From 5961bb5bbc71527fbe1bba237bf3266e5004cfd6 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Mon, 18 May 2026 03:31:34 +0700 Subject: [PATCH 04/16] refactor: make couple weight functions anonymous --- src/qt/guiutil_font.cpp | 32 ++++++++++++++++---------------- src/qt/guiutil_font.h | 6 ------ 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/src/qt/guiutil_font.cpp b/src/qt/guiutil_font.cpp index c7b5549985b2..65dfbee119de 100644 --- a/src/qt/guiutil_font.cpp +++ b/src/qt/guiutil_font.cpp @@ -264,6 +264,22 @@ void setFontBodyHTML(QTextEdit* widget, const QString& src, double base_size) } } } + +bool weightFromArg(int nArg, QFont::Weight& weight) +{ + auto it = mapWeightArgs.first.find(nArg); + if (it == mapWeightArgs.first.end()) { + return false; + } + weight = it->second; + return true; +} + +int weightToArg(const QFont::Weight weight) +{ + assert(mapWeightArgs.second.count(weight)); + return mapWeightArgs.second.find(weight)->second; +} } // anonymous namespace namespace GUIUtil { @@ -321,22 +337,6 @@ bool FontRegistry::SetFont(const QString& font) return true; } -bool weightFromArg(int nArg, QFont::Weight& weight) -{ - auto it = mapWeightArgs.first.find(nArg); - if (it == mapWeightArgs.first.end()) { - return false; - } - weight = it->second; - return true; -} - -int weightToArg(const QFont::Weight weight) -{ - assert(mapWeightArgs.second.count(weight)); - return mapWeightArgs.second.find(weight)->second; -} - bool isValidWeightArg(int arg) { QFont::Weight weight; diff --git a/src/qt/guiutil_font.h b/src/qt/guiutil_font.h index b4cd0358c4df..febf1b9274ac 100644 --- a/src/qt/guiutil_font.h +++ b/src/qt/guiutil_font.h @@ -134,12 +134,6 @@ struct FontAttrib { ~FontAttrib(); }; -/** Convert weight value from args (0-8) to QFont::Weight */ -bool weightFromArg(int nArg, QFont::Weight& weight); - -/** Convert QFont::Weight to an arg value (0-8) */ -int weightToArg(const QFont::Weight weight); - /* Weight operations expressed in caller-friendly arg ints (0..8). This is the * format used by `-font-weight-*` CLI args and QSettings persistence. Callers * that need slider positions (idx in 0..supportedWeightArgs().size()-1) build From fb8da28e4f39689644546bc543079cc62d1f2eb0 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Mon, 18 May 2026 04:03:44 +0700 Subject: [PATCH 05/16] refactor: drop usages of g_font_registry to prefer static methods --- src/qt/appearancewidget.cpp | 20 ++++++++++---------- src/qt/bitcoin.cpp | 12 ++++++------ src/qt/guiutil_font.cpp | 15 +++++++++++++++ src/qt/guiutil_font.h | 22 +++++++++++++++++++--- src/qt/optionsmodel.cpp | 12 ++++++------ src/qt/overviewpage.cpp | 2 +- src/qt/proposalcreate.cpp | 2 +- 7 files changed, 58 insertions(+), 27 deletions(-) diff --git a/src/qt/appearancewidget.cpp b/src/qt/appearancewidget.cpp index 1b837432d054..88609c705043 100644 --- a/src/qt/appearancewidget.cpp +++ b/src/qt/appearancewidget.cpp @@ -83,8 +83,8 @@ AppearanceWidget::AppearanceWidget(QWidget* parent) : QWidget(parent), ui{new Ui::AppearanceWidget()}, prevTheme{GUIUtil::getActiveTheme()}, - prevScale{GUIUtil::g_font_registry.GetFontScale()}, - prevFontFamily{GUIUtil::g_font_registry.GetFont()}, + prevScale{GUIUtil::fontScale()}, + prevFontFamily{GUIUtil::activeFont()}, prevWeightNormalArg{GUIUtil::currentWeightArg(GUIUtil::FontWeight::Normal)}, prevWeightBoldArg{GUIUtil::currentWeightArg(GUIUtil::FontWeight::Bold)} { @@ -134,13 +134,13 @@ AppearanceWidget::~AppearanceWidget() if (prevTheme != GUIUtil::getActiveTheme()) { updateTheme(prevTheme); } - if (prevFontFamily != GUIUtil::g_font_registry.GetFont()) { - const bool setfont_ret{GUIUtil::g_font_registry.SetFont(prevFontFamily)}; + if (prevFontFamily != GUIUtil::activeFont()) { + const bool setfont_ret{GUIUtil::setActiveFont(prevFontFamily)}; assert(setfont_ret); GUIUtil::setApplicationFont(); } - if (prevScale != GUIUtil::g_font_registry.GetFontScale()) { - GUIUtil::g_font_registry.SetFontScale(prevScale); + if (prevScale != GUIUtil::fontScale()) { + GUIUtil::setFontScale(prevScale); } if (prevWeightNormalArg != GUIUtil::currentWeightArg(GUIUtil::FontWeight::Normal)) { GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Normal, prevWeightNormalArg); @@ -187,14 +187,14 @@ void AppearanceWidget::setModel(OptionsModel* _model) const bool override_family{_model->isOptionOverridden("-font-family")}; if (override_family) { ui->fontFamily->setEnabled(false); - if (const auto idx{ui->fontFamily->findText(GUIUtil::g_font_registry.GetFont())}; idx != -1) { + if (const auto idx{ui->fontFamily->findText(GUIUtil::activeFont())}; idx != -1) { ui->fontFamily->setCurrentIndex(idx); } } if (_model->isOptionOverridden("-font-scale")) { ui->fontScaleSlider->setEnabled(false); - ui->fontScaleSlider->setValue(GUIUtil::g_font_registry.GetFontScale()); + ui->fontScaleSlider->setValue(GUIUtil::fontScale()); } if (bool is_overridden{_model->isOptionOverridden("-font-weight-normal")}; is_overridden || override_family) { @@ -232,7 +232,7 @@ void AppearanceWidget::updateTheme(const QString& theme) void AppearanceWidget::updateFontFamily(int index) { - const bool setfont_ret{GUIUtil::g_font_registry.SetFont(GUIUtil::g_fonts_known[ui->fontFamily->itemData(index).toInt()].first)}; + const bool setfont_ret{GUIUtil::setActiveFont(GUIUtil::g_fonts_known[ui->fontFamily->itemData(index).toInt()].first)}; assert(setfont_ret); GUIUtil::setApplicationFont(); GUIUtil::updateFonts(); @@ -241,7 +241,7 @@ void AppearanceWidget::updateFontFamily(int index) void AppearanceWidget::updateFontScale(int nScale) { - GUIUtil::g_font_registry.SetFontScale(nScale); + GUIUtil::setFontScale(nScale); GUIUtil::updateFonts(); } diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 084333049f54..aead9091d954 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -501,8 +501,8 @@ static void SetupUIArgs(ArgsManager& argsman) { argsman.AddArg("-choosedatadir", strprintf(QObject::tr("Choose data directory on startup (default: %u)").toStdString(), DEFAULT_CHOOSE_DATADIR), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); argsman.AddArg("-custom-css-dir", "Set a directory which contains custom css files. Those will be used as stylesheets for the UI.", ArgsManager::ALLOW_ANY, OptionsCategory::GUI); - argsman.AddArg("-font-family", QObject::tr("Set the font family. Possible values: %1. (default: %2)").arg(Join(GUIUtil::getFonts(/*selectable_only=*/true), ", ")).arg(GUIUtil::FontRegistry::DEFAULT_FONT).toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); - argsman.AddArg("-font-scale", QObject::tr("Set a scale factor which gets applied to the base font size. Possible range %1 (smallest fonts) to %2 (largest fonts). (default: %3)").arg(-100).arg(100).arg(GUIUtil::FontRegistry::DEFAULT_FONT_SCALE).toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); + argsman.AddArg("-font-family", QObject::tr("Set the font family. Possible values: %1. (default: %2)").arg(Join(GUIUtil::getFonts(/*selectable_only=*/true), ", ")).arg(GUIUtil::defaultFontFamily()).toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); + argsman.AddArg("-font-scale", QObject::tr("Set a scale factor which gets applied to the base font size. Possible range %1 (smallest fonts) to %2 (largest fonts). (default: %3)").arg(-100).arg(100).arg(GUIUtil::defaultFontScale()).toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); argsman.AddArg("-font-weight-bold", QObject::tr("Set the font weight for bold texts. Possible range %1 to %2 (default: %3)").arg(0).arg(8).arg(GUIUtil::defaultWeightArg(GUIUtil::FontWeight::Bold)).toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); argsman.AddArg("-font-weight-normal", QObject::tr("Set the font weight for normal texts. Possible range %1 to %2 (default: %3)").arg(0).arg(8).arg(GUIUtil::defaultWeightArg(GUIUtil::FontWeight::Normal)).toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); argsman.AddArg("-lang=", QObject::tr("Set language, for example \"de_DE\" (default: system locale)").toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); @@ -720,8 +720,8 @@ int GuiMain(int argc, char* argv[]) // Validate/set font family if (gArgs.IsArgSet("-font-family")) { - QString family = gArgs.GetArg("-font-family", GUIUtil::FontRegistry::DEFAULT_FONT.toUtf8().toStdString()).c_str(); - if (!GUIUtil::g_font_registry.RegisterFont(family, /*selectable=*/true) || !GUIUtil::g_font_registry.SetFont(family)) { + QString family = gArgs.GetArg("-font-family", GUIUtil::defaultFontFamily().toStdString()).c_str(); + if (!GUIUtil::registerFont(family, /*selectable=*/true) || !GUIUtil::setActiveFont(family)) { QMessageBox::critical(nullptr, PACKAGE_NAME, QObject::tr("Error: Font \"%1\" could not be loaded.").arg(family)); return EXIT_FAILURE; } @@ -749,13 +749,13 @@ int GuiMain(int argc, char* argv[]) // Validate/set font scale if (gArgs.IsArgSet("-font-scale")) { const int nScaleMin = -100, nScaleMax = 100; - int nScale = gArgs.GetIntArg("-font-scale", GUIUtil::g_font_registry.GetFontScale()); + int nScale = gArgs.GetIntArg("-font-scale", GUIUtil::fontScale()); if (nScale < nScaleMin || nScale > nScaleMax) { QMessageBox::critical(nullptr, PACKAGE_NAME, QObject::tr("Error: Specified font-scale invalid. Valid range %1 to %2.").arg(nScaleMin).arg(nScaleMax)); return EXIT_FAILURE; } - GUIUtil::g_font_registry.SetFontScale(nScale); + GUIUtil::setFontScale(nScale); } // Apply font changes GUIUtil::updateFonts(); diff --git a/src/qt/guiutil_font.cpp b/src/qt/guiutil_font.cpp index 65dfbee119de..0083dd8fee42 100644 --- a/src/qt/guiutil_font.cpp +++ b/src/qt/guiutil_font.cpp @@ -337,6 +337,21 @@ bool FontRegistry::SetFont(const QString& font) return true; } +int defaultFontScale() { return FontRegistry::DEFAULT_FONT_SCALE; } +int defaultFontSize() { return FontRegistry::DEFAULT_FONT_SIZE; } +QString defaultFontFamily() { return FontRegistry::DEFAULT_FONT.toString(); } + +bool registerFont(const QString& font, bool selectable, bool skip_checks) +{ + return g_font_registry.RegisterFont(font, selectable, skip_checks); +} + +bool setActiveFont(const QString& font) { return g_font_registry.SetFont(font); } +QString activeFont() { return g_font_registry.GetFont(); } + +void setFontScale(int font_scale) { g_font_registry.SetFontScale(font_scale); } +int fontScale() { return g_font_registry.GetFontScale(); } + bool isValidWeightArg(int arg) { QFont::Weight weight; diff --git a/src/qt/guiutil_font.h b/src/qt/guiutil_font.h index febf1b9274ac..d871ba04b45e 100644 --- a/src/qt/guiutil_font.h +++ b/src/qt/guiutil_font.h @@ -134,10 +134,26 @@ struct FontAttrib { ~FontAttrib(); }; +/** Default values for the corresponding `-font-*` options (used in arg help + * text and as persistence fallbacks). */ +int defaultFontScale(); +int defaultFontSize(); +QString defaultFontFamily(); + +/** Register a font name as known. If selectable, it shows up in the appearance + * picker. `skip_checks` bypasses the QFontDatabase availability test — only + * legal right after QFontDatabase::addApplicationFont. */ +[[nodiscard]] bool registerFont(const QString& font, bool selectable, bool skip_checks = false); +/** Switch the active font family. The family must have been registered. */ +[[nodiscard]] bool setActiveFont(const QString& font); +/** Currently active font family. */ +QString activeFont(); + +void setFontScale(int font_scale); +int fontScale(); + /* Weight operations expressed in caller-friendly arg ints (0..8). This is the - * format used by `-font-weight-*` CLI args and QSettings persistence. Callers - * that need slider positions (idx in 0..supportedWeightArgs().size()-1) build - * that bridge themselves from `supportedWeightArgs()`. */ + * format used by `-font-weight-*` CLI args and QSettings persistence. */ /** True if `arg` (0..8) maps to a weight supported by the active font. */ bool isValidWeightArg(int arg); diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 6f0e72d06aef..cf50036a0002 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -257,8 +257,8 @@ bool OptionsModel::Init(bilingual_str& error) addOverriddenOption("-font-family"); } if (GUIUtil::fontsLoaded()) { - if (auto font_name = QString::fromStdString(SettingToString(node().getPersistentSetting("font-family"), GUIUtil::FontRegistry::DEFAULT_FONT.toUtf8().toStdString())); - GUIUtil::g_font_registry.RegisterFont(font_name, /*selectable=*/true) && GUIUtil::g_font_registry.SetFont(font_name)) { + if (auto font_name = QString::fromStdString(SettingToString(node().getPersistentSetting("font-family"), GUIUtil::defaultFontFamily().toStdString())); + GUIUtil::registerFont(font_name, /*selectable=*/true) && GUIUtil::setActiveFont(font_name)) { GUIUtil::setApplicationFont(); } } @@ -268,7 +268,7 @@ bool OptionsModel::Init(bilingual_str& error) addOverriddenOption("-font-scale"); } if (GUIUtil::fontsLoaded()) { - GUIUtil::g_font_registry.SetFontScale(SettingToInt(node().getPersistentSetting("font-scale"), GUIUtil::FontRegistry::DEFAULT_FONT_SCALE)); + GUIUtil::setFontScale(SettingToInt(node().getPersistentSetting("font-scale"), GUIUtil::defaultFontScale())); } // Font Weight (Normal) @@ -541,7 +541,7 @@ QFont OptionsModel::getFontForChoice(const FontChoice& fc) if (std::holds_alternative(fc)) { switch (std::get(fc)) { case FontChoiceAbstract::ApplicationFont: - f.setFamily(GUIUtil::g_font_registry.GetFont()); + f.setFamily(GUIUtil::activeFont()); break; case FontChoiceAbstract::EmbeddedFont: f = GUIUtil::fixedPitchFont(true); @@ -702,9 +702,9 @@ QVariant OptionsModel::getOption(OptionID option, const std::string& suffix) con case Theme: return settings.value("theme"); case FontFamily: - return QString::fromStdString(SettingToString(setting(), GUIUtil::FontRegistry::DEFAULT_FONT.toUtf8().toStdString())); + return QString::fromStdString(SettingToString(setting(), GUIUtil::defaultFontFamily().toStdString())); case FontScale: - return qlonglong(SettingToInt(setting(), GUIUtil::FontRegistry::DEFAULT_FONT_SCALE)); + return qlonglong(SettingToInt(setting(), GUIUtil::defaultFontScale())); case FontWeightNormal: return qlonglong(SettingToInt(setting(), GUIUtil::defaultWeightArg(GUIUtil::FontWeight::Normal))); case FontWeightBold: diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 7f11fde0f9a8..2bd8d38cdc05 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -63,7 +63,7 @@ class TxViewDelegate : public QAbstractItemDelegate QRect rectBottomHalf(mainRect.left() + xspace, mainRect.top() + ypad + halfheight + 5, mainRect.width() - xspace, halfheight); QRect rectBounding; QColor colorForeground; - constexpr auto initial_size{GUIUtil::FontRegistry::DEFAULT_FONT_SIZE}; + const auto initial_size{GUIUtil::defaultFontSize()}; // Grab model indexes for desired data from TransactionTableModel QModelIndex indexDate = index.sibling(index.row(), TransactionTableModel::Date); diff --git a/src/qt/proposalcreate.cpp b/src/qt/proposalcreate.cpp index 322e9ef475e0..b309b51317bd 100644 --- a/src/qt/proposalcreate.cpp +++ b/src/qt/proposalcreate.cpp @@ -39,7 +39,7 @@ ProposalCreate::ProposalCreate(WalletModel* walletModel, QWidget* parent) : m_ui->setupUi(this); m_ui->labelError->setStyleSheet(GUIUtil::getThemedStyleQString(GUIUtil::ThemedStyle::TS_ERROR)); m_ui->labelTotalValue->setFont( - GUIUtil::getScaledFont(GUIUtil::FontRegistry::DEFAULT_FONT_SIZE, /*bold=*/true, /*multiplier=*/1.05)); + GUIUtil::getScaledFont(GUIUtil::defaultFontSize(), /*bold=*/true, /*multiplier=*/1.05)); // Allow payment amount field to stretch horizontally if (auto* lineEdit = m_ui->paymentAmount->findChild()) { From 25759c614f404ef6b1127c2648427387f217e69c Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Mon, 18 May 2026 13:25:19 +0700 Subject: [PATCH 06/16] refactor: drop usages of g_fonts_known from header and qt widgets --- src/qt/appearancewidget.cpp | 7 ++++--- src/qt/guiutil_font.cpp | 1 + src/qt/guiutil_font.h | 2 ++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/qt/appearancewidget.cpp b/src/qt/appearancewidget.cpp index 88609c705043..bcdc2b47c603 100644 --- a/src/qt/appearancewidget.cpp +++ b/src/qt/appearancewidget.cpp @@ -94,8 +94,9 @@ AppearanceWidget::AppearanceWidget(QWidget* parent) : ui->theme->addItem(entry, QVariant(entry)); } - for (size_t idx{0}; idx < GUIUtil::g_fonts_known.size(); idx++) { - const auto& [font, selectable] = GUIUtil::g_fonts_known[idx]; + const auto& known = GUIUtil::knownFonts(); + for (size_t idx{0}; idx < known.size(); idx++) { + const auto& [font, selectable] = known[idx]; if (selectable) { ui->fontFamily->addItem(font, QVariant((uint16_t)idx)); } } @@ -232,7 +233,7 @@ void AppearanceWidget::updateTheme(const QString& theme) void AppearanceWidget::updateFontFamily(int index) { - const bool setfont_ret{GUIUtil::setActiveFont(GUIUtil::g_fonts_known[ui->fontFamily->itemData(index).toInt()].first)}; + const bool setfont_ret{GUIUtil::setActiveFont(GUIUtil::knownFonts()[ui->fontFamily->itemData(index).toInt()].first)}; assert(setfont_ret); GUIUtil::setApplicationFont(); GUIUtil::updateFonts(); diff --git a/src/qt/guiutil_font.cpp b/src/qt/guiutil_font.cpp index 0083dd8fee42..a6de926a6e22 100644 --- a/src/qt/guiutil_font.cpp +++ b/src/qt/guiutil_font.cpp @@ -348,6 +348,7 @@ bool registerFont(const QString& font, bool selectable, bool skip_checks) bool setActiveFont(const QString& font) { return g_font_registry.SetFont(font); } QString activeFont() { return g_font_registry.GetFont(); } +const std::vector>& knownFonts() { return g_fonts_known; } void setFontScale(int font_scale) { g_font_registry.SetFontScale(font_scale); } int fontScale() { return g_font_registry.GetFontScale(); } diff --git a/src/qt/guiutil_font.h b/src/qt/guiutil_font.h index d871ba04b45e..237356ddb259 100644 --- a/src/qt/guiutil_font.h +++ b/src/qt/guiutil_font.h @@ -148,6 +148,8 @@ QString defaultFontFamily(); [[nodiscard]] bool setActiveFont(const QString& font); /** Currently active font family. */ QString activeFont(); +/** Known fonts and their "selectable in UI" flag, in registration order. */ +const std::vector>& knownFonts(); void setFontScale(int font_scale); int fontScale(); From 635480d8e45710b9e5554dfc23264c6239e71522 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Mon, 18 May 2026 13:34:30 +0700 Subject: [PATCH 07/16] refactor: move private implementation of g_font_registry to anonymous namespace --- src/qt/guiutil_font.cpp | 416 +++++++++++++++++++++++++--------------- src/qt/guiutil_font.h | 110 +---------- 2 files changed, 264 insertions(+), 262 deletions(-) diff --git a/src/qt/guiutil_font.cpp b/src/qt/guiutil_font.cpp index a6de926a6e22..f90fe09d91c8 100644 --- a/src/qt/guiutil_font.cpp +++ b/src/qt/guiutil_font.cpp @@ -17,9 +17,11 @@ #include #include #include +#include #include #include #include +#include #include #include @@ -28,6 +30,113 @@ #include namespace { +// TODO: Switch to QUtf8StringView when we switch to Qt 6 +constexpr QStringView MONTSERRAT_FONT_STR{u"Montserrat"}; +constexpr QStringView OS_FONT_STR{u"SystemDefault"}; +constexpr QStringView OS_MONO_FONT_STR{u"SystemMonospace"}; +constexpr QStringView ROBOTO_MONO_FONT_STR{u"Roboto Mono"}; + +constexpr int DEFAULT_FONT_SCALE{0}; +constexpr int DEFAULT_FONT_SIZE{12}; +constexpr QStringView DEFAULT_FONT{OS_FONT_STR}; +constexpr QFont::Weight TARGET_WEIGHT_BOLD{QFont::Medium}; +constexpr QFont::Weight TARGET_WEIGHT_NORMAL{ +#ifdef Q_OS_MACOS + QFont::ExtraLight +#else + QFont::Light +#endif // Q_OS_MACOS +}; + +//! Per-font weight cache (defaults + user-selected bold/normal + supported list). +struct FontInfo { + QFont::Weight m_bold; + QFont::Weight m_bold_default; + QFont::Weight m_normal; + QFont::Weight m_normal_default; + std::vector m_supported_weights; + + FontInfo() = delete; + explicit FontInfo(const QString& font_name); + ~FontInfo(); + +private: + QFont::Weight GetBestMatch(const QString& font_name, QFont::Weight target); + void CalcDefaultWeights(const QString& font_name); + void CalcSupportedWeights(const QString& font_name); +}; + +//! Global font state (active family, scale, per-font cache). File-private — +//! external callers go through the free-function API in qt/guiutil_font.h. +class FontRegistry { +public: + [[nodiscard]] bool RegisterFont(const QString& font, bool selectable, bool skip_checks = false); + + bool IsValidWeight(const QFont::Weight& weight) const { return WeightToIdx(weight) != -1; } + int WeightToIdx(const QFont::Weight& weight) const; + QFont::Weight IdxToWeight(int index) const; + + [[nodiscard]] bool SetFont(const QString& font); + void SetFontScale(int font_scale) { m_font_scale = font_scale; } + void SetWeightBold(const QFont::Weight& bold) + { + assert(m_weights.count(m_font)); + m_weights.at(m_font).m_bold = bold; + } + void SetWeightNormal(const QFont::Weight& normal) + { + assert(m_weights.count(m_font)); + m_weights.at(m_font).m_normal = normal; + } + + double GetScaledFontSize(double size) const { return std::round(size * (1 + (m_font_scale * m_scale_steps)) * 4) / 4.0; } + QString GetFont() const { return m_font; } + int GetFontScale() const { return m_font_scale; } + int GetFontSize() const { return m_font_size; } + QFont::Weight GetWeightBold() const + { + if (auto it = m_weights.find(m_font); it != m_weights.end()) { return it->second.m_bold; } + return TARGET_WEIGHT_BOLD; + } + QFont::Weight GetWeightNormal() const + { + if (auto it = m_weights.find(m_font); it != m_weights.end()) { return it->second.m_normal; } + return TARGET_WEIGHT_NORMAL; + } + QFont::Weight GetWeightBoldDefault() const + { + if (auto it = m_weights.find(m_font); it != m_weights.end()) { return it->second.m_bold_default; } + return TARGET_WEIGHT_BOLD; + } + QFont::Weight GetWeightNormalDefault() const + { + if (auto it = m_weights.find(m_font); it != m_weights.end()) { return it->second.m_normal_default; } + return TARGET_WEIGHT_NORMAL; + } + std::vector GetSupportedWeights() const + { + if (auto it = m_weights.find(m_font); it != m_weights.end()) { return it->second.m_supported_weights; } + return {TARGET_WEIGHT_NORMAL, TARGET_WEIGHT_BOLD}; + } + +private: + double m_scale_steps{0.01}; + QString m_font{DEFAULT_FONT.toUtf8()}; + int m_font_scale{DEFAULT_FONT_SCALE}; + int m_font_size{DEFAULT_FONT_SIZE}; + std::map m_weights; +}; + +FontRegistry g_font_registry; + +//! Fonts known by the client +std::vector> g_fonts_known{ + {MONTSERRAT_FONT_STR.toUtf8(), true}, + {OS_FONT_STR.toUtf8(), true}, + {OS_MONO_FONT_STR.toUtf8(), false}, + {ROBOTO_MONO_FONT_STR.toUtf8(), false}, +}; + //! Instance of font database shared among calls std::unique_ptr g_font_db{nullptr}; @@ -127,6 +236,22 @@ QString qstrprintf(const std::string& fmt, const Args&... args) return QString::fromStdString(tfm::format(fmt, args...)); } +bool weightFromArg(int nArg, QFont::Weight& weight) +{ + auto it = mapWeightArgs.first.find(nArg); + if (it == mapWeightArgs.first.end()) { + return false; + } + weight = it->second; + return true; +} + +int weightToArg(const QFont::Weight weight) +{ + assert(mapWeightArgs.second.count(weight)); + return mapWeightArgs.second.find(weight)->second; +} + //! Returns a properly weighted QFont object with the selected font QFont getFont(const GUIUtil::FontAttrib& font_attrib) { @@ -137,9 +262,9 @@ QFont getFont(const GUIUtil::FontAttrib& font_attrib) // Resolve weight from FontWeight type const QFont::Weight weight = (font_attrib.m_weight_type == GUIUtil::FontWeight::Bold) - ? GUIUtil::g_font_registry.GetWeightBold() : GUIUtil::g_font_registry.GetWeightNormal(); + ? g_font_registry.GetWeightBold() : g_font_registry.GetWeightNormal(); - if (font_attrib.m_font == GUIUtil::MONTSERRAT_FONT_STR) { + if (font_attrib.m_font == MONTSERRAT_FONT_STR) { assert(mapMontserrat.count(weight)); #ifdef Q_OS_MACOS font.setFamily(font_attrib.m_font); @@ -161,20 +286,20 @@ QFont getFont(const GUIUtil::FontAttrib& font_attrib) font.setFamily(qstrprintf("%s %s", font_attrib.m_font.toStdString(), mapMontserrat.at(weight).first)); } #endif // Q_OS_MACOS - } else if (font_attrib.m_font == GUIUtil::OS_FONT_STR) { + } else if (font_attrib.m_font == OS_FONT_STR) { font.setFamily(g_default_font->family()); - } else if (font_attrib.m_font == GUIUtil::OS_MONO_FONT_STR) { + } else if (font_attrib.m_font == OS_MONO_FONT_STR) { font.setFamily(QFontDatabase::systemFont(QFontDatabase::FixedFont).family()); } else { font.setFamily(font_attrib.m_font); } - if (font_attrib.m_font == GUIUtil::ROBOTO_MONO_FONT_STR || font_attrib.m_font == GUIUtil::OS_MONO_FONT_STR) { + if (font_attrib.m_font == ROBOTO_MONO_FONT_STR || font_attrib.m_font == OS_MONO_FONT_STR) { font.setStyleHint(QFont::Monospace); } #ifdef Q_OS_MACOS - if (font_attrib.m_font != GUIUtil::MONTSERRAT_FONT_STR) + if (font_attrib.m_font != MONTSERRAT_FONT_STR) #endif // Q_OS_MACOS { font.setWeight(weight); @@ -182,7 +307,7 @@ QFont getFont(const GUIUtil::FontAttrib& font_attrib) } if (font_attrib.m_point_size != -1) { - font.setPointSizeF(GUIUtil::g_font_registry.GetScaledFontSize(font_attrib.m_point_size)); + font.setPointSizeF(g_font_registry.GetScaledFontSize(font_attrib.m_point_size)); } if (gArgs.GetBoolArg("-debug-ui", false)) { @@ -257,7 +382,7 @@ void setFontBodyHTML(QTextEdit* widget, const QString& src, double base_size) } #endif // Q_OS_MACOS if (scale_add > 0) { - fmt.setFontPointSize(GUIUtil::g_font_registry.GetScaledFontSize(base_size * (1 + scale_add))); + fmt.setFontPointSize(g_font_registry.GetScaledFontSize(base_size * (1 + scale_add))); } cursor.mergeCharFormat(fmt); } @@ -265,134 +390,8 @@ void setFontBodyHTML(QTextEdit* widget, const QString& src, double base_size) } } -bool weightFromArg(int nArg, QFont::Weight& weight) -{ - auto it = mapWeightArgs.first.find(nArg); - if (it == mapWeightArgs.first.end()) { - return false; - } - weight = it->second; - return true; -} - -int weightToArg(const QFont::Weight weight) -{ - assert(mapWeightArgs.second.count(weight)); - return mapWeightArgs.second.find(weight)->second; -} -} // anonymous namespace - -namespace GUIUtil { -//! Fonts known by the client -std::vector> g_fonts_known{ - {MONTSERRAT_FONT_STR.toUtf8(), true}, - {OS_FONT_STR.toUtf8(), true}, - {OS_MONO_FONT_STR.toUtf8(), false}, - {ROBOTO_MONO_FONT_STR.toUtf8(), false}, -}; - -FontRegistry g_font_registry; - -FontInfo::FontInfo(const QString& font_name) -{ - CalcSupportedWeights(font_name); - CalcDefaultWeights(font_name); - m_bold = m_bold_default; - m_normal = m_normal_default; -} - -FontInfo::~FontInfo() = default; - -bool FontRegistry::RegisterFont(const QString& font, bool selectable, bool skip_checks) -{ - const auto font_strs{getFonts(/*selectable_only=*/false)}; - auto font_it{std::find(font_strs.begin(), font_strs.end(), font)}; - if (m_weights.count(font)) { - // Font's already registered - assert(font_it != font_strs.end()); - // Overwrite selectable flag - g_fonts_known.at(std::distance(font_strs.begin(), font_it)).second = selectable; - return true; - } - if (!skip_checks) { - if (!g_font_db) { g_font_db = std::make_unique(); } - if (!g_font_db->families().contains(font, Qt::CaseInsensitive)) { - // Font doesn't exist - return false; - } - } - m_weights.emplace(font, FontInfo(font)); - if (font_it == font_strs.end()) { - g_fonts_known.emplace_back(font, selectable); - } - return true; -} - -bool FontRegistry::SetFont(const QString& font) -{ - if (!m_weights.count(font)) { - return false; - } - m_font = font; - return true; -} - -int defaultFontScale() { return FontRegistry::DEFAULT_FONT_SCALE; } -int defaultFontSize() { return FontRegistry::DEFAULT_FONT_SIZE; } -QString defaultFontFamily() { return FontRegistry::DEFAULT_FONT.toString(); } - -bool registerFont(const QString& font, bool selectable, bool skip_checks) -{ - return g_font_registry.RegisterFont(font, selectable, skip_checks); -} - -bool setActiveFont(const QString& font) { return g_font_registry.SetFont(font); } -QString activeFont() { return g_font_registry.GetFont(); } -const std::vector>& knownFonts() { return g_fonts_known; } - -void setFontScale(int font_scale) { g_font_registry.SetFontScale(font_scale); } -int fontScale() { return g_font_registry.GetFontScale(); } - -bool isValidWeightArg(int arg) -{ - QFont::Weight weight; - return weightFromArg(arg, weight) && g_font_registry.IsValidWeight(weight); -} - -int currentWeightArg(FontWeight slot) -{ - return weightToArg(slot == FontWeight::Bold ? g_font_registry.GetWeightBold() - : g_font_registry.GetWeightNormal()); -} - -int defaultWeightArg(FontWeight slot) -{ - return weightToArg(slot == FontWeight::Bold ? g_font_registry.GetWeightBoldDefault() - : g_font_registry.GetWeightNormalDefault()); -} - -void setWeightFromArg(FontWeight slot, int arg) -{ - QFont::Weight weight; - if (!weightFromArg(arg, weight)) return; - if (slot == FontWeight::Bold) { - g_font_registry.SetWeightBold(weight); - } else { - g_font_registry.SetWeightNormal(weight); - } -} - -std::vector supportedWeightArgs() -{ - std::vector ret; - for (const auto& w : g_font_registry.GetSupportedWeights()) { - ret.push_back(weightToArg(w)); - } - return ret; -} - //! Internal helper to create a font with explicit weight (used for font detection) -static QFont getFontWithWeight(const QString& font_name, QFont::Weight weight, double point_size) +QFont getFontWithWeight(const QString& font_name, QFont::Weight weight, double point_size) { QFont font; if (font_name == MONTSERRAT_FONT_STR) { @@ -423,11 +422,21 @@ static QFont getFontWithWeight(const QString& font_name, QFont::Weight weight, d return font; } +FontInfo::FontInfo(const QString& font_name) +{ + CalcSupportedWeights(font_name); + CalcDefaultWeights(font_name); + m_bold = m_bold_default; + m_normal = m_normal_default; +} + +FontInfo::~FontInfo() = default; + void FontInfo::CalcSupportedWeights(const QString& font_name) { auto getTestWidth = [](const QString& font_name, QFont::Weight weight) -> int { - QFont font = getFontWithWeight(font_name, weight, FontRegistry::DEFAULT_FONT_SIZE); - return TextWidth(QFontMetrics(font), ("Check the width of this text to see if the weight change has an impact!")); + QFont font = getFontWithWeight(font_name, weight, DEFAULT_FONT_SIZE); + return GUIUtil::TextWidth(QFontMetrics(font), ("Check the width of this text to see if the weight change has an impact!")); }; QFont::Weight prevWeight = vecWeightConsider.front(); bool isFirst = true; @@ -469,8 +478,8 @@ void FontInfo::CalcDefaultWeights(const QString& font_name) { assert(!m_supported_weights.empty()); - m_normal_default = GetBestMatch(font_name, FontRegistry::TARGET_WEIGHT_NORMAL); - m_bold_default = GetBestMatch(font_name, FontRegistry::TARGET_WEIGHT_BOLD); + m_normal_default = GetBestMatch(font_name, TARGET_WEIGHT_NORMAL); + m_bold_default = GetBestMatch(font_name, TARGET_WEIGHT_BOLD); if (m_normal_default == m_bold_default) { // If the results are the same use the next possible weight for bold font auto it = std::find(m_supported_weights.begin(), m_supported_weights.end(), m_normal_default); @@ -480,6 +489,61 @@ void FontInfo::CalcDefaultWeights(const QString& font_name) } } +bool FontRegistry::RegisterFont(const QString& font, bool selectable, bool skip_checks) +{ + const auto font_strs{GUIUtil::getFonts(/*selectable_only=*/false)}; + auto font_it{std::find(font_strs.begin(), font_strs.end(), font)}; + if (m_weights.count(font)) { + // Font's already registered + assert(font_it != font_strs.end()); + // Overwrite selectable flag + g_fonts_known.at(std::distance(font_strs.begin(), font_it)).second = selectable; + return true; + } + if (!skip_checks) { + if (!g_font_db) { g_font_db = std::make_unique(); } + if (!g_font_db->families().contains(font, Qt::CaseInsensitive)) { + // Font doesn't exist + return false; + } + } + m_weights.emplace(font, FontInfo(font)); + if (font_it == font_strs.end()) { + g_fonts_known.emplace_back(font, selectable); + } + return true; +} + +bool FontRegistry::SetFont(const QString& font) +{ + if (!m_weights.count(font)) { + return false; + } + m_font = font; + return true; +} + +QFont::Weight FontRegistry::IdxToWeight(int index) const +{ + const auto vecWeights = GetSupportedWeights(); + assert(vecWeights.size() > uint64_t(index)); + return vecWeights.at(index); +} + +int FontRegistry::WeightToIdx(const QFont::Weight& weight) const +{ + const auto vecWeights = GetSupportedWeights(); + for (uint64_t index = 0; index < vecWeights.size(); ++index) { + if (weight == vecWeights.at(index)) { + return index; + } + } + return -1; +} +} // anonymous namespace + +namespace GUIUtil { + FontAttrib::FontAttrib(QString font, FontWeight weight_type, double point_size, bool is_italic) : m_font{font}, m_weight_type{weight_type}, @@ -498,6 +562,60 @@ FontAttrib::FontAttrib(FontWeight weight_type, double point_size, bool is_italic FontAttrib::~FontAttrib() = default; +int defaultFontScale() { return DEFAULT_FONT_SCALE; } +int defaultFontSize() { return DEFAULT_FONT_SIZE; } +QString defaultFontFamily() { return DEFAULT_FONT.toString(); } + +bool registerFont(const QString& font, bool selectable, bool skip_checks) +{ + return g_font_registry.RegisterFont(font, selectable, skip_checks); +} + +bool setActiveFont(const QString& font) { return g_font_registry.SetFont(font); } +QString activeFont() { return g_font_registry.GetFont(); } +const std::vector>& knownFonts() { return g_fonts_known; } + +void setFontScale(int font_scale) { g_font_registry.SetFontScale(font_scale); } +int fontScale() { return g_font_registry.GetFontScale(); } + +bool isValidWeightArg(int arg) +{ + QFont::Weight weight; + return weightFromArg(arg, weight) && g_font_registry.IsValidWeight(weight); +} + +int currentWeightArg(FontWeight slot) +{ + return weightToArg(slot == FontWeight::Bold ? g_font_registry.GetWeightBold() + : g_font_registry.GetWeightNormal()); +} + +int defaultWeightArg(FontWeight slot) +{ + return weightToArg(slot == FontWeight::Bold ? g_font_registry.GetWeightBoldDefault() + : g_font_registry.GetWeightNormalDefault()); +} + +void setWeightFromArg(FontWeight slot, int arg) +{ + QFont::Weight weight; + if (!weightFromArg(arg, weight)) return; + if (slot == FontWeight::Bold) { + g_font_registry.SetWeightBold(weight); + } else { + g_font_registry.SetWeightNormal(weight); + } +} + +std::vector supportedWeightArgs() +{ + std::vector ret; + for (const auto& w : g_font_registry.GetSupportedWeights()) { + ret.push_back(weightToArg(w)); + } + return ret; +} + bool loadFonts() { // Before any font changes store the applications default font to use it as SystemDefault. @@ -717,24 +835,6 @@ QFont getScaledFont(double baseSize, bool bold, double multiplier) }); } -QFont::Weight FontRegistry::IdxToWeight(int index) const -{ - const auto vecWeights = GetSupportedWeights(); - assert(vecWeights.size() > uint64_t(index)); - return vecWeights.at(index); -} - -int FontRegistry::WeightToIdx(const QFont::Weight& weight) const -{ - const auto vecWeights = GetSupportedWeights(); - for (uint64_t index = 0; index < vecWeights.size(); ++index) { - if (weight == vecWeights.at(index)) { - return index; - } - } - return -1; -} - QFont fixedPitchFont(bool use_embedded_font) { return getFont({ @@ -746,7 +846,7 @@ QFont fixedPitchFont(bool use_embedded_font) void registerWidget(QTextEdit* widget, const QString& html) { if (!widget) return; - double base_size{FontRegistry::DEFAULT_FONT_SIZE}; + double base_size{DEFAULT_FONT_SIZE}; auto it{mapTextEditStyleUpdates.find(widget)}; if (it != mapTextEditStyleUpdates.end()) { // Widget already registered, preserve stored base_size and update HTML diff --git a/src/qt/guiutil_font.h b/src/qt/guiutil_font.h index 237356ddb259..b45d9060be67 100644 --- a/src/qt/guiutil_font.h +++ b/src/qt/guiutil_font.h @@ -7,121 +7,23 @@ #include #include -#include -#include -#include -#include #include -#include +#include #include -namespace GUIUtil { -// TODO: Switch to QUtf8StringView when we switch to Qt 6 -constexpr QStringView MONTSERRAT_FONT_STR{u"Montserrat"}; -constexpr QStringView OS_FONT_STR{u"SystemDefault"}; -constexpr QStringView OS_MONO_FONT_STR{u"SystemMonospace"}; -constexpr QStringView ROBOTO_MONO_FONT_STR{u"Roboto Mono"}; +QT_BEGIN_NAMESPACE +class QTextEdit; +class QWidget; +QT_END_NAMESPACE -extern std::vector> g_fonts_known; +namespace GUIUtil { enum class FontWeight : uint8_t { Normal, Bold, }; -struct FontInfo { - QFont::Weight m_bold; - QFont::Weight m_bold_default; - QFont::Weight m_normal; - QFont::Weight m_normal_default; - std::vector m_supported_weights; - - FontInfo() = delete; - explicit FontInfo(const QString& font_name); - ~FontInfo(); - -private: - QFont::Weight GetBestMatch(const QString& font_name, QFont::Weight target); - void CalcDefaultWeights(const QString& font_name); - void CalcSupportedWeights(const QString& font_name); -}; - -class FontRegistry { -public: - static constexpr int DEFAULT_FONT_SCALE{0}; - static constexpr int DEFAULT_FONT_SIZE{12}; - static constexpr QStringView DEFAULT_FONT{OS_FONT_STR}; - static constexpr QFont::Weight TARGET_WEIGHT_BOLD{QFont::Medium}; - static constexpr QFont::Weight TARGET_WEIGHT_NORMAL{ -#ifdef Q_OS_MACOS - QFont::ExtraLight -#else - QFont::Light -#endif // Q_OS_MACOS - }; - -public: - [[nodiscard]] bool RegisterFont(const QString& font, bool selectable, bool skip_checks = false); - - bool IsValidWeight(const QFont::Weight& weight) const { return WeightToIdx(weight) != -1; } - int WeightToIdx(const QFont::Weight& weight) const; - QFont::Weight IdxToWeight(int index) const; - - [[nodiscard]] bool SetFont(const QString& font); - void SetFontScale(int font_scale) { m_font_scale = font_scale; } - void SetWeightBold(const QFont::Weight& bold) - { - assert(m_weights.count(m_font)); - m_weights.at(m_font).m_bold = bold; - } - void SetWeightNormal(const QFont::Weight& normal) - { - assert(m_weights.count(m_font)); - m_weights.at(m_font).m_normal = normal; - } - - double GetScaleSteps() const { return m_scale_steps; } - double GetScaledFontSize(double size) const { return std::round(size * (1 + (m_font_scale * m_scale_steps)) * 4) / 4.0; } - QString GetFont() const { return m_font; } - int GetFontScale() const { return m_font_scale; } - int GetFontSize() const { return m_font_size; } - QFont::Weight GetWeightBold() const - { - if (auto it = m_weights.find(m_font); it != m_weights.end()) { return it->second.m_bold; } - return TARGET_WEIGHT_BOLD; - } - QFont::Weight GetWeightNormal() const - { - if (auto it = m_weights.find(m_font); it != m_weights.end()) { return it->second.m_normal; } - return TARGET_WEIGHT_NORMAL; - } - QFont::Weight GetWeightBoldDefault() const - { - if (auto it = m_weights.find(m_font); it != m_weights.end()) { return it->second.m_bold_default; } - return TARGET_WEIGHT_BOLD; - } - QFont::Weight GetWeightNormalDefault() const - { - if (auto it = m_weights.find(m_font); it != m_weights.end()) { return it->second.m_normal_default; } - return TARGET_WEIGHT_NORMAL; - } - std::vector GetSupportedWeights() const - { - if (auto it = m_weights.find(m_font); it != m_weights.end()) { return it->second.m_supported_weights; } - return {TARGET_WEIGHT_NORMAL, TARGET_WEIGHT_BOLD}; - } - -private: - double m_scale_steps{0.01}; - QString m_font{DEFAULT_FONT.toUtf8()}; - int m_font_scale{DEFAULT_FONT_SCALE}; - int m_font_size{DEFAULT_FONT_SIZE}; - std::map m_weights; -}; - -extern FontRegistry g_font_registry; - struct FontAttrib { QString m_font; FontWeight m_weight_type; From 99a22771e98be2a93c0f3dc902b29d1e9f0a7323 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Mon, 18 May 2026 13:36:39 +0700 Subject: [PATCH 08/16] refactor: removed unused helpers to convert weight<->idx --- src/qt/guiutil_font.cpp | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/src/qt/guiutil_font.cpp b/src/qt/guiutil_font.cpp index f90fe09d91c8..e2c41d2e9c17 100644 --- a/src/qt/guiutil_font.cpp +++ b/src/qt/guiutil_font.cpp @@ -72,9 +72,7 @@ class FontRegistry { public: [[nodiscard]] bool RegisterFont(const QString& font, bool selectable, bool skip_checks = false); - bool IsValidWeight(const QFont::Weight& weight) const { return WeightToIdx(weight) != -1; } - int WeightToIdx(const QFont::Weight& weight) const; - QFont::Weight IdxToWeight(int index) const; + bool IsValidWeight(const QFont::Weight& weight) const; [[nodiscard]] bool SetFont(const QString& font); void SetFontScale(int font_scale) { m_font_scale = font_scale; } @@ -523,22 +521,10 @@ bool FontRegistry::SetFont(const QString& font) return true; } -QFont::Weight FontRegistry::IdxToWeight(int index) const +bool FontRegistry::IsValidWeight(const QFont::Weight& weight) const { - const auto vecWeights = GetSupportedWeights(); - assert(vecWeights.size() > uint64_t(index)); - return vecWeights.at(index); -} - -int FontRegistry::WeightToIdx(const QFont::Weight& weight) const -{ - const auto vecWeights = GetSupportedWeights(); - for (uint64_t index = 0; index < vecWeights.size(); ++index) { - if (weight == vecWeights.at(index)) { - return index; - } - } - return -1; + const auto supported = GetSupportedWeights(); + return std::find(supported.begin(), supported.end(), weight) != supported.end(); } } // anonymous namespace From fdffbf9c4da49343cd745dd819eaa6c3b7a31d8c Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Mon, 18 May 2026 17:29:59 +0700 Subject: [PATCH 09/16] refactor: simplify paired calls of GUIUtil::registerFont and GUIUtil::setActiveFont --- src/qt/bitcoin.cpp | 10 +++++++--- src/qt/guiutil_font.cpp | 33 +++++++++++++-------------------- src/qt/guiutil_font.h | 13 ++++--------- src/qt/optionsmodel.cpp | 7 +++---- 4 files changed, 27 insertions(+), 36 deletions(-) diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index aead9091d954..0e2b7812f350 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -501,7 +501,11 @@ static void SetupUIArgs(ArgsManager& argsman) { argsman.AddArg("-choosedatadir", strprintf(QObject::tr("Choose data directory on startup (default: %u)").toStdString(), DEFAULT_CHOOSE_DATADIR), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); argsman.AddArg("-custom-css-dir", "Set a directory which contains custom css files. Those will be used as stylesheets for the UI.", ArgsManager::ALLOW_ANY, OptionsCategory::GUI); - argsman.AddArg("-font-family", QObject::tr("Set the font family. Possible values: %1. (default: %2)").arg(Join(GUIUtil::getFonts(/*selectable_only=*/true), ", ")).arg(GUIUtil::defaultFontFamily()).toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); + std::vector selectable_fonts; + for (const auto& [name, selectable] : GUIUtil::knownFonts()) { + if (selectable) selectable_fonts.push_back(name); + } + argsman.AddArg("-font-family", QObject::tr("Set the font family. Possible values: %1. (default: %2)").arg(Join(selectable_fonts, ", ")).arg(GUIUtil::defaultFontFamily()).toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); argsman.AddArg("-font-scale", QObject::tr("Set a scale factor which gets applied to the base font size. Possible range %1 (smallest fonts) to %2 (largest fonts). (default: %3)").arg(-100).arg(100).arg(GUIUtil::defaultFontScale()).toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); argsman.AddArg("-font-weight-bold", QObject::tr("Set the font weight for bold texts. Possible range %1 to %2 (default: %3)").arg(0).arg(8).arg(GUIUtil::defaultWeightArg(GUIUtil::FontWeight::Bold)).toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); argsman.AddArg("-font-weight-normal", QObject::tr("Set the font weight for normal texts. Possible range %1 to %2 (default: %3)").arg(0).arg(8).arg(GUIUtil::defaultWeightArg(GUIUtil::FontWeight::Normal)).toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); @@ -720,8 +724,8 @@ int GuiMain(int argc, char* argv[]) // Validate/set font family if (gArgs.IsArgSet("-font-family")) { - QString family = gArgs.GetArg("-font-family", GUIUtil::defaultFontFamily().toStdString()).c_str(); - if (!GUIUtil::registerFont(family, /*selectable=*/true) || !GUIUtil::setActiveFont(family)) { + const QString family = QString::fromStdString(gArgs.GetArg("-font-family", "")); + if (!GUIUtil::setActiveFont(family)) { QMessageBox::critical(nullptr, PACKAGE_NAME, QObject::tr("Error: Font \"%1\" could not be loaded.").arg(family)); return EXIT_FAILURE; } diff --git a/src/qt/guiutil_font.cpp b/src/qt/guiutil_font.cpp index e2c41d2e9c17..78479015ba1e 100644 --- a/src/qt/guiutil_font.cpp +++ b/src/qt/guiutil_font.cpp @@ -489,13 +489,12 @@ void FontInfo::CalcDefaultWeights(const QString& font_name) bool FontRegistry::RegisterFont(const QString& font, bool selectable, bool skip_checks) { - const auto font_strs{GUIUtil::getFonts(/*selectable_only=*/false)}; - auto font_it{std::find(font_strs.begin(), font_strs.end(), font)}; + auto font_it = std::find_if(g_fonts_known.begin(), g_fonts_known.end(), + [&](const auto& p) { return p.first == font; }); if (m_weights.count(font)) { - // Font's already registered - assert(font_it != font_strs.end()); - // Overwrite selectable flag - g_fonts_known.at(std::distance(font_strs.begin(), font_it)).second = selectable; + // Font's already registered — overwrite selectable flag + assert(font_it != g_fonts_known.end()); + font_it->second = selectable; return true; } if (!skip_checks) { @@ -506,7 +505,7 @@ bool FontRegistry::RegisterFont(const QString& font, bool selectable, bool skip_ } } m_weights.emplace(font, FontInfo(font)); - if (font_it == font_strs.end()) { + if (font_it == g_fonts_known.end()) { g_fonts_known.emplace_back(font, selectable); } return true; @@ -552,12 +551,15 @@ int defaultFontScale() { return DEFAULT_FONT_SCALE; } int defaultFontSize() { return DEFAULT_FONT_SIZE; } QString defaultFontFamily() { return DEFAULT_FONT.toString(); } -bool registerFont(const QString& font, bool selectable, bool skip_checks) +bool setActiveFont(const QString& font_name) { - return g_font_registry.RegisterFont(font, selectable, skip_checks); + if (!fontsLoaded()) return false; + const QString name = font_name.isEmpty() ? defaultFontFamily() : font_name; + if (!g_font_registry.RegisterFont(name, /*selectable=*/true)) return false; + if (!g_font_registry.SetFont(name)) return false; + setApplicationFont(); + return true; } - -bool setActiveFont(const QString& font) { return g_font_registry.SetFont(font); } QString activeFont() { return g_font_registry.GetFont(); } const std::vector>& knownFonts() { return g_fonts_known; } @@ -794,15 +796,6 @@ void updateFonts() } } -std::vector getFonts(bool selectable_only) -{ - std::vector ret; - for (const auto& [font, selectable] : g_fonts_known) { - if (selectable || !selectable_only) { ret.emplace_back(font); } - } - return ret; -} - QFont getFontBold() { return getFont({FontWeight::Bold}); diff --git a/src/qt/guiutil_font.h b/src/qt/guiutil_font.h index b45d9060be67..f82f310d68c8 100644 --- a/src/qt/guiutil_font.h +++ b/src/qt/guiutil_font.h @@ -42,12 +42,10 @@ int defaultFontScale(); int defaultFontSize(); QString defaultFontFamily(); -/** Register a font name as known. If selectable, it shows up in the appearance - * picker. `skip_checks` bypasses the QFontDatabase availability test — only - * legal right after QFontDatabase::addApplicationFont. */ -[[nodiscard]] bool registerFont(const QString& font, bool selectable, bool skip_checks = false); -/** Switch the active font family. The family must have been registered. */ -[[nodiscard]] bool setActiveFont(const QString& font); +/** Switch the active font family. Registers `font_name` if not yet known and + * applies the new font to qApp. Empty `font_name` means "use defaultFontFamily()". + * No-op if loadFonts() hasn't completed. Returns true on success. */ +bool setActiveFont(const QString& font_name = {}); /** Currently active font family. */ QString activeFont(); /** Known fonts and their "selectable in UI" flag, in registration order. */ @@ -91,9 +89,6 @@ void setFont(const std::vector& vecWidgets, const FontAttrib& font_att GUIUtil::setFont */ void updateFonts(); -/** Get list of all selectable fonts */ -std::vector getFonts(bool selectable_only); - /** Get the default bold QFont */ QFont getFontBold(); diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index cf50036a0002..b8dcdb2e5697 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -257,10 +257,9 @@ bool OptionsModel::Init(bilingual_str& error) addOverriddenOption("-font-family"); } if (GUIUtil::fontsLoaded()) { - if (auto font_name = QString::fromStdString(SettingToString(node().getPersistentSetting("font-family"), GUIUtil::defaultFontFamily().toStdString())); - GUIUtil::registerFont(font_name, /*selectable=*/true) && GUIUtil::setActiveFont(font_name)) { - GUIUtil::setApplicationFont(); - } + const QString font_name = QString::fromStdString( + SettingToString(node().getPersistentSetting("font-family"), "")); + GUIUtil::setActiveFont(font_name); } // Font Scale From cae89c0df2468eaa4746d55dfdb7dd70011b85cf Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Mon, 18 May 2026 18:11:04 +0700 Subject: [PATCH 10/16] refactor: rename registerWidget to setStyledHtml --- src/qt/descriptiondialog.cpp | 2 +- src/qt/guiutil_font.cpp | 2 +- src/qt/guiutil_font.h | 6 ++++-- src/qt/proposalresume.cpp | 4 ++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/qt/descriptiondialog.cpp b/src/qt/descriptiondialog.cpp index 164939d3f284..87b03441672b 100644 --- a/src/qt/descriptiondialog.cpp +++ b/src/qt/descriptiondialog.cpp @@ -16,7 +16,7 @@ DescriptionDialog::DescriptionDialog(const QString& title, const QString& html, { ui->setupUi(this); setWindowTitle(title); - GUIUtil::registerWidget(ui->detailText, html); + GUIUtil::setStyledHtml(ui->detailText, html); GUIUtil::updateFonts(); GUIUtil::handleCloseWindowShortcut(this); } diff --git a/src/qt/guiutil_font.cpp b/src/qt/guiutil_font.cpp index 78479015ba1e..68248f6d2a6b 100644 --- a/src/qt/guiutil_font.cpp +++ b/src/qt/guiutil_font.cpp @@ -822,7 +822,7 @@ QFont fixedPitchFont(bool use_embedded_font) }); } -void registerWidget(QTextEdit* widget, const QString& html) +void setStyledHtml(QTextEdit* widget, const QString& html) { if (!widget) return; double base_size{DEFAULT_FONT_SIZE}; diff --git a/src/qt/guiutil_font.h b/src/qt/guiutil_font.h index f82f310d68c8..e1f2de8b6c09 100644 --- a/src/qt/guiutil_font.h +++ b/src/qt/guiutil_font.h @@ -74,8 +74,10 @@ bool loadFonts(); /** Check if the fonts have been loaded successfully */ bool fontsLoaded(); -/** Register a QTextEdit for font styling. Applies immediately and updates when fonts change. */ -void registerWidget(QTextEdit* widget, const QString& html); +/** Set HTML content on a QTextEdit with font-aware styling. Captures the + * widget's base point size on first call so re-application on font/theme + * changes preserves it. Subsequent calls update the HTML. */ +void setStyledHtml(QTextEdit* widget, const QString& html); /** Set an application wide default font, depends on the selected theme */ void setApplicationFont(); diff --git a/src/qt/proposalresume.cpp b/src/qt/proposalresume.cpp index 6b1fcd641563..bdebb1883233 100644 --- a/src/qt/proposalresume.cpp +++ b/src/qt/proposalresume.cpp @@ -163,7 +163,7 @@ void ProposalResume::addProposal(const Governance::Object& proposal) entry.description->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); entry.description->setTextInteractionFlags(Qt::NoTextInteraction); entry.description->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); - GUIUtil::registerWidget(entry.description, formatProposalHtml(proposal, -1)); + GUIUtil::setStyledHtml(entry.description, formatProposalHtml(proposal, -1)); // Create "Broadcast" action entry.broadcast_btn = new QPushButton(tr("Broadcast"), entry.container); @@ -259,7 +259,7 @@ void ProposalResume::refreshConfirmations() const int confs = queryConfirmations(entry.proposal.collateralHash); if (confs != entry.collateral_confs) { entry.collateral_confs = confs; - GUIUtil::registerWidget(entry.description, formatProposalHtml(entry.proposal, confs)); + GUIUtil::setStyledHtml(entry.description, formatProposalHtml(entry.proposal, confs)); entry.broadcast_btn->setEnabled(confs >= m_relay_confs); } if (confs < m_relay_confs) { From 8963dcec4a5d0c067ddcefe5269a328fbc25f9e7 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Mon, 18 May 2026 22:19:51 +0700 Subject: [PATCH 11/16] refactor: collapse usages of GUIUtil::isValidWeightArg --- src/qt/appearancewidget.cpp | 2 +- src/qt/bitcoin.cpp | 6 ++---- src/qt/guiutil_font.cpp | 11 +++-------- src/qt/guiutil_font.h | 8 ++++---- src/qt/optionsmodel.cpp | 28 ++++++++++++---------------- 5 files changed, 22 insertions(+), 33 deletions(-) diff --git a/src/qt/appearancewidget.cpp b/src/qt/appearancewidget.cpp index bcdc2b47c603..95200ead7367 100644 --- a/src/qt/appearancewidget.cpp +++ b/src/qt/appearancewidget.cpp @@ -301,7 +301,7 @@ void AppearanceWidget::updateWeightSlider(const bool fForce) ui->fontWeightBoldSlider->setMinimum(nMin); ui->fontWeightBoldSlider->setMaximum(nMax); - if (fForce || !GUIUtil::isValidWeightArg(prevWeightNormalArg) || !GUIUtil::isValidWeightArg(prevWeightBoldArg)) { + if (fForce) { updateFontWeightNormal(GUIUtil::defaultWeightArg(GUIUtil::FontWeight::Normal), true); updateFontWeightBold(GUIUtil::defaultWeightArg(GUIUtil::FontWeight::Bold), true); } diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 0e2b7812f350..75780d39e381 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -733,22 +733,20 @@ int GuiMain(int argc, char* argv[]) // Validate/set normal font weight if (gArgs.IsArgSet("-font-weight-normal")) { const int arg = gArgs.GetIntArg("-font-weight-normal", GUIUtil::currentWeightArg(GUIUtil::FontWeight::Normal)); - if (!GUIUtil::isValidWeightArg(arg)) { + if (!GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Normal, arg)) { QMessageBox::critical(nullptr, PACKAGE_NAME, QObject::tr("Error: Specified font-weight-normal invalid. Valid range %1 to %2.").arg(0).arg(8)); return EXIT_FAILURE; } - GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Normal, arg); } // Validate/set bold font weight if (gArgs.IsArgSet("-font-weight-bold")) { const int arg = gArgs.GetIntArg("-font-weight-bold", GUIUtil::currentWeightArg(GUIUtil::FontWeight::Bold)); - if (!GUIUtil::isValidWeightArg(arg)) { + if (!GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Bold, arg)) { QMessageBox::critical(nullptr, PACKAGE_NAME, QObject::tr("Error: Specified font-weight-bold invalid. Valid range %1 to %2.").arg(0).arg(8)); return EXIT_FAILURE; } - GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Bold, arg); } // Validate/set font scale if (gArgs.IsArgSet("-font-scale")) { diff --git a/src/qt/guiutil_font.cpp b/src/qt/guiutil_font.cpp index 68248f6d2a6b..7cd0cf1d6624 100644 --- a/src/qt/guiutil_font.cpp +++ b/src/qt/guiutil_font.cpp @@ -566,12 +566,6 @@ const std::vector>& knownFonts() { return g_fonts_known void setFontScale(int font_scale) { g_font_registry.SetFontScale(font_scale); } int fontScale() { return g_font_registry.GetFontScale(); } -bool isValidWeightArg(int arg) -{ - QFont::Weight weight; - return weightFromArg(arg, weight) && g_font_registry.IsValidWeight(weight); -} - int currentWeightArg(FontWeight slot) { return weightToArg(slot == FontWeight::Bold ? g_font_registry.GetWeightBold() @@ -584,15 +578,16 @@ int defaultWeightArg(FontWeight slot) : g_font_registry.GetWeightNormalDefault()); } -void setWeightFromArg(FontWeight slot, int arg) +bool setWeightFromArg(FontWeight slot, int arg) { QFont::Weight weight; - if (!weightFromArg(arg, weight)) return; + if (!weightFromArg(arg, weight) || !g_font_registry.IsValidWeight(weight)) return false; if (slot == FontWeight::Bold) { g_font_registry.SetWeightBold(weight); } else { g_font_registry.SetWeightNormal(weight); } + return true; } std::vector supportedWeightArgs() diff --git a/src/qt/guiutil_font.h b/src/qt/guiutil_font.h index e1f2de8b6c09..0eb81c6712e8 100644 --- a/src/qt/guiutil_font.h +++ b/src/qt/guiutil_font.h @@ -57,14 +57,14 @@ int fontScale(); /* Weight operations expressed in caller-friendly arg ints (0..8). This is the * format used by `-font-weight-*` CLI args and QSettings persistence. */ -/** True if `arg` (0..8) maps to a weight supported by the active font. */ -bool isValidWeightArg(int arg); /** Current weight for `slot`, as arg int. */ int currentWeightArg(FontWeight slot); /** Default-best-match weight for `slot`, as arg int. Valid before loadFonts() too. */ int defaultWeightArg(FontWeight slot); -/** Apply a weight from its arg int. No-op if `arg` is out of 0..8. */ -void setWeightFromArg(FontWeight slot, int arg); +/** Apply a weight from its arg int. Returns true on success; false if `arg` is + * out of 0..8 or maps to a weight not supported by the active font (no change + * to state in that case). */ +bool setWeightFromArg(FontWeight slot, int arg); /** Active font's supported weight args, in low-to-high order. */ std::vector supportedWeightArgs(); diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index b8dcdb2e5697..bce5a514e617 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -279,15 +279,13 @@ bool OptionsModel::Init(bilingual_str& error) if (GUIUtil::fontsLoaded()) { // If font was overridden by CLI but weight wasn't, use the font's default weight const int default_arg = GUIUtil::defaultWeightArg(GUIUtil::FontWeight::Normal); - int arg = default_arg; - if (!override_family || isOptionOverridden("-font-weight-normal")) { - arg = SettingToInt(node().getPersistentSetting("font-weight-normal"), default_arg); - if (!GUIUtil::isValidWeightArg(arg)) { - arg = default_arg; - node().forceSetting("font-weight-normal", arg); - } + const int arg = (!override_family || isOptionOverridden("-font-weight-normal")) + ? SettingToInt(node().getPersistentSetting("font-weight-normal"), default_arg) + : default_arg; + if (!GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Normal, arg)) { + node().forceSetting("font-weight-normal", default_arg); + GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Normal, default_arg); } - GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Normal, arg); } // Font Weight (Bold) @@ -297,15 +295,13 @@ bool OptionsModel::Init(bilingual_str& error) if (GUIUtil::fontsLoaded()) { // If font was overridden by CLI but weight wasn't, use the font's default weight const int default_arg = GUIUtil::defaultWeightArg(GUIUtil::FontWeight::Bold); - int arg = default_arg; - if (!override_family || isOptionOverridden("-font-weight-bold")) { - arg = SettingToInt(node().getPersistentSetting("font-weight-bold"), default_arg); - if (!GUIUtil::isValidWeightArg(arg)) { - arg = default_arg; - node().forceSetting("font-weight-bold", arg); - } + const int arg = (!override_family || isOptionOverridden("-font-weight-bold")) + ? SettingToInt(node().getPersistentSetting("font-weight-bold"), default_arg) + : default_arg; + if (!GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Bold, arg)) { + node().forceSetting("font-weight-bold", default_arg); + GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Bold, default_arg); } - GUIUtil::setWeightFromArg(GUIUtil::FontWeight::Bold, arg); } // Apply font changes From 6d15b1220949e3b1bcc4440c3d7973acecc33fa7 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Mon, 18 May 2026 22:56:06 +0700 Subject: [PATCH 12/16] refactor: hide FontAttrib as a part of private implementation --- src/qt/appearancewidget.cpp | 4 +-- src/qt/askpassphrasedialog.cpp | 2 +- src/qt/bitcoingui.cpp | 4 +-- src/qt/coincontroldialog.cpp | 2 +- src/qt/guiutil_font.cpp | 43 ++++++++++++++---------------- src/qt/guiutil_font.h | 21 ++++----------- src/qt/informationwidget.cpp | 2 +- src/qt/masternodelist.cpp | 2 +- src/qt/modaloverlay.cpp | 2 +- src/qt/networkwidget.cpp | 2 +- src/qt/optionsdialog.cpp | 6 ++--- src/qt/overviewpage.cpp | 10 +++---- src/qt/proposalinfo.cpp | 2 +- src/qt/proposallist.cpp | 2 +- src/qt/qrdialog.cpp | 2 +- src/qt/receivecoinsdialog.cpp | 4 +-- src/qt/rpcconsole.cpp | 6 ++--- src/qt/sendcoinsdialog.cpp | 6 ++--- src/qt/sendcoinsentry.cpp | 2 +- src/qt/signverifymessagedialog.cpp | 10 +++---- src/qt/walletview.cpp | 2 +- 21 files changed, 61 insertions(+), 75 deletions(-) diff --git a/src/qt/appearancewidget.cpp b/src/qt/appearancewidget.cpp index 95200ead7367..c0234bc795c3 100644 --- a/src/qt/appearancewidget.cpp +++ b/src/qt/appearancewidget.cpp @@ -336,8 +336,8 @@ void AppearanceWidget::setupAppearance(QWidget* parent, OptionsModel* model) layout.addWidget(&buttonBox); dlg.setLayout(&layout); // Adjust the headings - GUIUtil::setFont({&lblHeading}, {GUIUtil::FontWeight::Bold, 16}); - GUIUtil::setFont({&lblSubHeading}, {GUIUtil::FontWeight::Normal, 14, true}); + GUIUtil::setFont({&lblHeading}, GUIUtil::FontWeight::Bold, 16); + GUIUtil::setFont({&lblSubHeading}, GUIUtil::FontWeight::Normal, 14, true); // Make sure the dialog closes and accepts the settings if save has been pressed QObject::connect(&buttonBox, &QDialogButtonBox::accepted, [&]() { QSettings().setValue("fAppearanceSetupDone", true); diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index e79a97e33afd..d15abdd71273 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -29,7 +29,7 @@ AskPassphraseDialog::AskPassphraseDialog(Mode _mode, QWidget *parent, SecureStri { ui->setupUi(this); - GUIUtil::setFont({ui->capsLabel}, {GUIUtil::FontWeight::Bold}); + GUIUtil::setFont({ui->capsLabel}, GUIUtil::FontWeight::Bold); GUIUtil::updateFonts(); diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 8f6800b482ec..6c1446f75e5f 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -795,7 +795,7 @@ void BitcoinGUI::createToolBars() connect(tabGroup, qOverload(&QButtonGroup::buttonToggled), this, &BitcoinGUI::highlightTabButton); for (auto button : tabGroup->buttons()) { - GUIUtil::setFont({button}, {GUIUtil::FontWeight::Normal, 16}); + GUIUtil::setFont({button}, GUIUtil::FontWeight::Normal, 16); button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); button->setToolTip(button->statusTip()); button->setCheckable(true); @@ -1305,7 +1305,7 @@ void BitcoinGUI::openClicked() void BitcoinGUI::highlightTabButton(QAbstractButton *button, bool checked) { - GUIUtil::setFont({button}, {checked ? GUIUtil::FontWeight::Bold : GUIUtil::FontWeight::Normal, 16}); + GUIUtil::setFont({button}, checked ? GUIUtil::FontWeight::Bold : GUIUtil::FontWeight::Normal, 16); GUIUtil::updateFonts(); } diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 74e6167ac8aa..d86bdbd1ce40 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -67,7 +67,7 @@ CoinControlDialog::CoinControlDialog(CCoinControl& coin_control, WalletModel* _m ui->labelCoinControlFeeText, ui->labelCoinControlAfterFeeText, ui->labelCoinControlChangeText - }, {GUIUtil::FontWeight::Bold}); + }, GUIUtil::FontWeight::Bold); GUIUtil::updateFonts(); diff --git a/src/qt/guiutil_font.cpp b/src/qt/guiutil_font.cpp index 7cd0cf1d6624..90c6512c2378 100644 --- a/src/qt/guiutil_font.cpp +++ b/src/qt/guiutil_font.cpp @@ -48,6 +48,14 @@ constexpr QFont::Weight TARGET_WEIGHT_NORMAL{ #endif // Q_OS_MACOS }; +//! Per-widget styling request — what setFont() captures into mapFontUpdates. +struct FontAttrib { + QString m_font; + GUIUtil::FontWeight m_weight_type; + double m_point_size{-1}; + bool m_is_italic{false}; +}; + //! Per-font weight cache (defaults + user-selected bold/normal + supported list). struct FontInfo { QFont::Weight m_bold; @@ -149,7 +157,7 @@ std::map mapClassFontUpdates{ }; //! Contains all widgets and its font attributes (weight, italic, size) with font changes due to GUIUtil::setFont -std::map, GUIUtil::FontAttrib> mapFontUpdates; +std::map, FontAttrib> mapFontUpdates; //! Contains QTextEdit widgets with the original base font size and HTML struct TextEditStyleData { @@ -251,7 +259,7 @@ int weightToArg(const QFont::Weight weight) } //! Returns a properly weighted QFont object with the selected font -QFont getFont(const GUIUtil::FontAttrib& font_attrib) +QFont getFont(const FontAttrib& font_attrib) { QFont font; if (!GUIUtil::fontsLoaded()) { @@ -529,24 +537,6 @@ bool FontRegistry::IsValidWeight(const QFont::Weight& weight) const namespace GUIUtil { -FontAttrib::FontAttrib(QString font, FontWeight weight_type, double point_size, bool is_italic) : - m_font{font}, - m_weight_type{weight_type}, - m_point_size{point_size}, - m_is_italic{is_italic} -{ -} - -FontAttrib::FontAttrib(FontWeight weight_type, double point_size, bool is_italic) : - m_font{g_font_registry.GetFont()}, - m_weight_type{weight_type}, - m_point_size{point_size}, - m_is_italic{is_italic} -{ -} - -FontAttrib::~FontAttrib() = default; - int defaultFontScale() { return DEFAULT_FONT_SCALE; } int defaultFontSize() { return DEFAULT_FONT_SIZE; } QString defaultFontFamily() { return DEFAULT_FONT.toString(); } @@ -693,8 +683,9 @@ void setApplicationFont() util::to_string(qApp->font().exactMatch())); } -void setFont(const std::vector& vecWidgets, const FontAttrib& font_attrib) +void setFont(const std::vector& vecWidgets, const QString& font, FontWeight weight, double point_size, bool is_italic) { + const FontAttrib font_attrib{font, weight, point_size, is_italic}; for (auto it : vecWidgets) { auto itFontUpdate = mapFontUpdates.emplace(std::make_pair(it, font_attrib)); if (!itFontUpdate.second) { @@ -703,6 +694,11 @@ void setFont(const std::vector& vecWidgets, const FontAttrib& font_att } } +void setFont(const std::vector& vecWidgets, FontWeight weight, double point_size, bool is_italic) +{ + setFont(vecWidgets, g_font_registry.GetFont(), weight, point_size, is_italic); +} + void updateFonts() { // Fonts need to be loaded by GUIUtil::loadFonts(), if not just return. @@ -793,17 +789,18 @@ void updateFonts() QFont getFontBold() { - return getFont({FontWeight::Bold}); + return getFont({g_font_registry.GetFont(), FontWeight::Bold}); } QFont getFontNormal() { - return getFont({FontWeight::Normal}); + return getFont({g_font_registry.GetFont(), FontWeight::Normal}); } QFont getScaledFont(double baseSize, bool bold, double multiplier) { return getFont({ + g_font_registry.GetFont(), bold ? FontWeight::Bold : FontWeight::Normal, baseSize * multiplier }); diff --git a/src/qt/guiutil_font.h b/src/qt/guiutil_font.h index 0eb81c6712e8..95d0f4486c5d 100644 --- a/src/qt/guiutil_font.h +++ b/src/qt/guiutil_font.h @@ -24,18 +24,6 @@ enum class FontWeight : uint8_t { Bold, }; -struct FontAttrib { - QString m_font; - FontWeight m_weight_type; - double m_point_size{-1}; - bool m_is_italic{false}; - - FontAttrib(QString font, FontWeight weight_type, double point_size = -1, bool is_italic = false); - // cppcheck-suppress noExplicitConstructor - FontAttrib(FontWeight weight_type, double point_size = -1, bool is_italic = false); - ~FontAttrib(); -}; - /** Default values for the corresponding `-font-*` options (used in arg help * text and as persistence fallbacks). */ int defaultFontScale(); @@ -82,10 +70,11 @@ void setStyledHtml(QTextEdit* widget, const QString& html); /** Set an application wide default font, depends on the selected theme */ void setApplicationFont(); -/** Workaround to set correct font styles in all themes since there is a bug in macOS which leads to - issues loading variations of montserrat in css it also keeps track of the set fonts to update on - theme changes. */ -void setFont(const std::vector& vecWidgets, const FontAttrib& font_attrib); +/** Register `widgets` to receive the given font attributes on the next updateFonts() pass. + * Uses the currently active font family. */ +void setFont(const std::vector& widgets, FontWeight weight, double point_size = -1, bool is_italic = false); +/** Same as above, but with an explicit font family. */ +void setFont(const std::vector& widgets, const QString& font, FontWeight weight, double point_size = -1, bool is_italic = false); /** Update the font of all widgets where a custom font has been set with GUIUtil::setFont */ diff --git a/src/qt/informationwidget.cpp b/src/qt/informationwidget.cpp index d0c9e9bc9ece..de39049bb2b1 100644 --- a/src/qt/informationwidget.cpp +++ b/src/qt/informationwidget.cpp @@ -28,7 +28,7 @@ InformationWidget::InformationWidget(QWidget* parent) : ui->label_10, ui->labelMempoolTitle, ui->labelNetwork}, - {GUIUtil::FontWeight::Bold, 16}); + GUIUtil::FontWeight::Bold, 16); for (auto* element : {ui->label_10, ui->labelNetwork, ui->labelMempoolTitle}) { element->setContentsMargins(0, 10, 0, 0); diff --git a/src/qt/masternodelist.cpp b/src/qt/masternodelist.cpp index 4305752f8bba..ad957ee8388e 100644 --- a/src/qt/masternodelist.cpp +++ b/src/qt/masternodelist.cpp @@ -88,7 +88,7 @@ MasternodeList::MasternodeList(QWidget* parent) : { ui->setupUi(this); - GUIUtil::setFont({ui->label_count, ui->countLabel}, {GUIUtil::FontWeight::Bold, 14}); + GUIUtil::setFont({ui->label_count, ui->countLabel}, GUIUtil::FontWeight::Bold, 14); // Set up proxy model m_proxy_model->setSourceModel(m_model); diff --git a/src/qt/modaloverlay.cpp b/src/qt/modaloverlay.cpp index 154cb60f4cee..2db1515f117f 100644 --- a/src/qt/modaloverlay.cpp +++ b/src/qt/modaloverlay.cpp @@ -25,7 +25,7 @@ ModalOverlay::ModalOverlay(bool enable_wallet, QWidget* parent) ui->labelSyncDone, ui->labelProgressIncrease, ui->labelEstimatedTimeLeft, - }, {GUIUtil::FontWeight::Bold}); + }, GUIUtil::FontWeight::Bold); ui->warningIcon->setPixmap(GUIUtil::getIcon("warning", GUIUtil::ThemedColor::ORANGE).pixmap(48, 48)); diff --git a/src/qt/networkwidget.cpp b/src/qt/networkwidget.cpp index 790057764d51..248d03d815dd 100644 --- a/src/qt/networkwidget.cpp +++ b/src/qt/networkwidget.cpp @@ -43,7 +43,7 @@ NetworkWidget::NetworkWidget(QWidget* parent) : ui->labelInstantSend, ui->labelMasternodes, ui->labelQuorums}, - {GUIUtil::FontWeight::Bold, 16}); + GUIUtil::FontWeight::Bold, 16); for (auto* element : {ui->labelInstantSend, ui->labelMasternodes, ui->labelChainLocks}) { element->setContentsMargins(0, 10, 0, 0); diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 39c71a1649ac..659dc82ff624 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -46,7 +46,7 @@ OptionsDialog::OptionsDialog(QWidget* parent, bool enableWallet) { ui->setupUi(this); - GUIUtil::setFont({ui->statusLabel}, {GUIUtil::FontWeight::Bold, 16}); + GUIUtil::setFont({ui->statusLabel}, GUIUtil::FontWeight::Bold, 16); GUIUtil::updateFonts(); @@ -417,8 +417,8 @@ void OptionsDialog::showPage(int index) } } - GUIUtil::setFont({btnActive}, {GUIUtil::FontWeight::Bold, 16}); - GUIUtil::setFont(vecNormal, {GUIUtil::FontWeight::Normal, 16}); + GUIUtil::setFont({btnActive}, GUIUtil::FontWeight::Bold, 16); + GUIUtil::setFont(vecNormal, GUIUtil::FontWeight::Normal, 16); GUIUtil::updateFonts(); ui->stackedWidgetOptions->setCurrentIndex(index); diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 2bd8d38cdc05..319891b99037 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -150,16 +150,16 @@ OverviewPage::OverviewPage(QWidget* parent) : GUIUtil::setFont({ui->label_4, ui->label_5, ui->labelCoinJoinHeader - }, {GUIUtil::FontWeight::Bold, 16}); + }, GUIUtil::FontWeight::Bold, 16); - GUIUtil::setFont({ui->labelTotalText}, {GUIUtil::FontWeight::Bold, 14}); + GUIUtil::setFont({ui->labelTotalText}, GUIUtil::FontWeight::Bold, 14); GUIUtil::setFont({ui->labelBalanceText, ui->labelPendingText, ui->labelImmatureText, ui->labelWatchonly, ui->labelSpendable - }, {GUIUtil::FontWeight::Bold}); + }, GUIUtil::FontWeight::Bold); GUIUtil::updateFonts(); @@ -380,7 +380,7 @@ void OverviewPage::setMonospacedFont(const QFont& f) GUIUtil::setFont({ ui->labelTotal, ui->labelWatchTotal, - }, {f.family(), GUIUtil::FontWeight::Bold, 14}); + }, f.family(), GUIUtil::FontWeight::Bold, 14); GUIUtil::setFont({ ui->labelAmountRounds, @@ -392,7 +392,7 @@ void OverviewPage::setMonospacedFont(const QFont& f) ui->labelWatchAvailable, ui->labelWatchPending, ui->labelWatchImmature, - }, {f.family(), GUIUtil::FontWeight::Bold}); + }, f.family(), GUIUtil::FontWeight::Bold); GUIUtil::updateFonts(); } diff --git a/src/qt/proposalinfo.cpp b/src/qt/proposalinfo.cpp index daa8e211ba81..47c44ac3da82 100644 --- a/src/qt/proposalinfo.cpp +++ b/src/qt/proposalinfo.cpp @@ -55,7 +55,7 @@ ProposalInfo::ProposalInfo(QWidget* parent) : ui->labelNode, ui->labelParticipation, ui->labelProposals}, - {GUIUtil::FontWeight::Bold, 16}); + GUIUtil::FontWeight::Bold, 16); for (auto* element : {ui->labelNode, ui->labelParticipation, ui->labelProposals}) { element->setContentsMargins(0, 10, 0, 0); diff --git a/src/qt/proposallist.cpp b/src/qt/proposallist.cpp index 27241a021726..16a1f8e9950a 100644 --- a/src/qt/proposallist.cpp +++ b/src/qt/proposallist.cpp @@ -58,7 +58,7 @@ ProposalList::ProposalList(QWidget* parent) : ui->setupUi(this); GUIUtil::setFont({ui->label_count_2, ui->countLabel}, - {GUIUtil::FontWeight::Bold, 14}); + GUIUtil::FontWeight::Bold, 14); ui->govTableView->setContextMenuPolicy(Qt::CustomContextMenu); ui->govTableView->setModel(proposalModelProxy); diff --git a/src/qt/qrdialog.cpp b/src/qt/qrdialog.cpp index 4c94c389fce3..1a89e2e4a390 100644 --- a/src/qt/qrdialog.cpp +++ b/src/qt/qrdialog.cpp @@ -21,7 +21,7 @@ QRDialog::QRDialog(QWidget *parent) : { ui->setupUi(this); - GUIUtil::setFont({ui->labelQRCodeTitle}, {GUIUtil::FontWeight::Bold, 16}); + GUIUtil::setFont({ui->labelQRCodeTitle}, GUIUtil::FontWeight::Bold, 16); GUIUtil::updateFonts(); diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index bf4d9d8322c7..70496bcd769b 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -22,10 +22,10 @@ ReceiveCoinsDialog::ReceiveCoinsDialog(QWidget* parent) : { ui->setupUi(this); - GUIUtil::setFont({ui->label_6}, {GUIUtil::FontWeight::Bold, 16}); + GUIUtil::setFont({ui->label_6}, GUIUtil::FontWeight::Bold, 16); GUIUtil::setFont({ui->label, ui->label_2, - ui->label_3}, {GUIUtil::FontWeight::Normal, 15}); + ui->label_3}, GUIUtil::FontWeight::Normal, 15); GUIUtil::updateFonts(); // context menu diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 1c5596baafb7..11fa2c265f64 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -489,7 +489,7 @@ RPCConsole::RPCConsole(interfaces::Node& node, QWidget* parent, Qt::WindowFlags GUIUtil::setFont({ui->peerHeading, ui->label_repair_header, ui->banHeading - }, {GUIUtil::FontWeight::Bold, 16}); + }, GUIUtil::FontWeight::Bold, 16); GUIUtil::updateFonts(); @@ -1073,8 +1073,8 @@ void RPCConsole::showPage(int index) } } - GUIUtil::setFont({btnActive}, {GUIUtil::FontWeight::Bold, 16}); - GUIUtil::setFont(vecNormal, {GUIUtil::FontWeight::Normal, 16}); + GUIUtil::setFont({btnActive}, GUIUtil::FontWeight::Bold, 16); + GUIUtil::setFont(vecNormal, GUIUtil::FontWeight::Normal, 16); GUIUtil::updateFonts(); ui->stackedWidgetRPC->setCurrentIndex(index); diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index c09783e2ab08..c9819de0dd17 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -77,14 +77,14 @@ SendCoinsDialog::SendCoinsDialog(bool _fCoinJoin, QWidget* parent) : ui->labelCoinControlChangeText, ui->labelFeeHeadline, ui->fallbackFeeWarningLabel - }, {GUIUtil::FontWeight::Bold}); + }, GUIUtil::FontWeight::Bold); GUIUtil::setFont({ui->labelBalance, ui->labelBalanceName, - }, {GUIUtil::FontWeight::Bold, 14}); + }, GUIUtil::FontWeight::Bold, 14); GUIUtil::setFont({ui->labelCoinControlFeatures - }, {GUIUtil::FontWeight::Bold, 16}); + }, GUIUtil::FontWeight::Bold, 16); ui->checkBoxCoinControlChange->setEnabled(!_fCoinJoin); GUIUtil::setupAddressWidget(ui->lineEditCoinControlChange, this); diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index b22f950ec090..077a9febc3c5 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -36,7 +36,7 @@ SendCoinsEntry::SendCoinsEntry(QWidget* parent) : GUIUtil::setFont({ui->payToLabel, ui->labellLabel, ui->amountLabel, - ui->messageLabel}, {GUIUtil::FontWeight::Normal, 15}); + ui->messageLabel}, GUIUtil::FontWeight::Normal, 15); GUIUtil::updateFonts(); diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index 78f9776a0646..e2856413d681 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -52,9 +52,9 @@ SignVerifyMessageDialog::SignVerifyMessageDialog(QWidget* parent) : ui->messageIn_VM->installEventFilter(this); ui->signatureIn_VM->installEventFilter(this); - GUIUtil::setFont({ui->signatureOut_SM, ui->signatureIn_VM}, {GUIUtil::FontWeight::Normal, 11, true}); - GUIUtil::setFont({ui->signatureLabel_SM}, {GUIUtil::FontWeight::Bold, 16}); - GUIUtil::setFont({ui->statusLabel_SM, ui->statusLabel_VM}, {GUIUtil::FontWeight::Bold}); + GUIUtil::setFont({ui->signatureOut_SM, ui->signatureIn_VM}, GUIUtil::FontWeight::Normal, 11, true); + GUIUtil::setFont({ui->signatureLabel_SM}, GUIUtil::FontWeight::Bold, 16); + GUIUtil::setFont({ui->statusLabel_SM, ui->statusLabel_VM}, GUIUtil::FontWeight::Bold); GUIUtil::updateFonts(); @@ -110,8 +110,8 @@ void SignVerifyMessageDialog::showPage(int index) } } - GUIUtil::setFont({btnActive}, {GUIUtil::FontWeight::Bold, 16}); - GUIUtil::setFont(vecNormal, {GUIUtil::FontWeight::Normal, 16}); + GUIUtil::setFont({btnActive}, GUIUtil::FontWeight::Bold, 16); + GUIUtil::setFont(vecNormal, GUIUtil::FontWeight::Normal, 16); GUIUtil::updateFonts(); ui->stackedWidgetSig->setCurrentIndex(index); diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 11c85d1b615e..9a389acd4e0b 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -69,7 +69,7 @@ WalletView::WalletView(WalletModel* wallet_model, QWidget* parent) GUIUtil::setFont({transactionSumLabel, transactionSum, - }, {GUIUtil::FontWeight::Bold, 14}); + }, GUIUtil::FontWeight::Bold, 14); GUIUtil::updateFonts(); hbox_buttons->addWidget(transactionSum); From 50c0ff14c189d5fc196339509c2a12e69eebddc0 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Mon, 18 May 2026 23:09:09 +0700 Subject: [PATCH 13/16] refactor: drop include QFont from guiutil_font.h --- src/qt/guiutil_font.cpp | 1 + src/qt/guiutil_font.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qt/guiutil_font.cpp b/src/qt/guiutil_font.cpp index 90c6512c2378..629f3cad7b1c 100644 --- a/src/qt/guiutil_font.cpp +++ b/src/qt/guiutil_font.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include #include diff --git a/src/qt/guiutil_font.h b/src/qt/guiutil_font.h index 95d0f4486c5d..28fc59612f45 100644 --- a/src/qt/guiutil_font.h +++ b/src/qt/guiutil_font.h @@ -5,7 +5,6 @@ #ifndef BITCOIN_QT_GUIUTIL_FONT_H #define BITCOIN_QT_GUIUTIL_FONT_H -#include #include #include @@ -13,6 +12,7 @@ #include QT_BEGIN_NAMESPACE +class QFont; class QTextEdit; class QWidget; QT_END_NAMESPACE From 945bf8de3767e50109b633e79c4a1651f7c1868d Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Mon, 18 May 2026 23:36:49 +0700 Subject: [PATCH 14/16] refactor: drop LoadFont that is super-seeded by multiple rich dash core helpers --- src/qt/bitcoin.cpp | 1 - src/qt/guiutil.cpp | 7 ------- src/qt/guiutil.h | 5 ----- src/qt/guiutil_font.cpp | 2 ++ 4 files changed, 2 insertions(+), 13 deletions(-) diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 75780d39e381..441135aed5a8 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -551,7 +551,6 @@ int GuiMain(int argc, char* argv[]) #endif BitcoinApplication app; - GUIUtil::LoadFont(QStringLiteral(":/fonts/monospace")); /// 2. Parse command-line options. We do this after qt in order to show an error if there are problems parsing these // Command-line options take precedence: diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 3f00700cf393..a06e07ee37db 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include @@ -432,12 +431,6 @@ bool hasEntryData(const QAbstractItemView *view, int column, int role) return !selection.at(0).data(role).toString().isEmpty(); } -void LoadFont(const QString& file_name) -{ - const int id = QFontDatabase::addApplicationFont(file_name); - assert(id != -1); -} - QString getDefaultDataDirectory() { return PathToQString(GetDefaultDataDir()); diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index d31b59ea3ab4..1446e81dabda 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -178,11 +178,6 @@ namespace GUIUtil void setClipboard(const QString& str); - /** - * Loads the font from the file specified by file_name, aborts if it fails. - */ - void LoadFont(const QString& file_name); - /** * Determine default data directory for operating system. */ diff --git a/src/qt/guiutil_font.cpp b/src/qt/guiutil_font.cpp index 629f3cad7b1c..fd4d85b79f71 100644 --- a/src/qt/guiutil_font.cpp +++ b/src/qt/guiutil_font.cpp @@ -601,6 +601,8 @@ bool loadFonts() qDebug() << qstrprintf("%s: %s loaded with id %d", __func__, font_name.toStdString(), vecFontIds.back()); }; + // Import the embedded Roboto Mono used by fixedPitchFont(use_embedded_font=true) + importFont(":fonts/monospace"); // Import the italic Montserrat variant as it doesn't map to a weight importFont(qstrprintf(":fonts/%s-Italic", MONTSERRAT_FONT_STR.toUtf8().toStdString())); // Import the rest of Montserrat variants From 7517f7b7e86b17daf7404d373f2dd03bd85b8644 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Mon, 18 May 2026 23:53:08 +0700 Subject: [PATCH 15/16] refactor: inline header qt/guiutil_font.h to guiutil.h Co-authored-by: UdjinM6 --- src/Makefile.qt.include | 1 - src/qt/addressbookpage.cpp | 1 - src/qt/addresstablemodel.cpp | 1 - src/qt/appearancewidget.cpp | 1 - src/qt/askpassphrasedialog.cpp | 1 - src/qt/bitcoin.cpp | 1 - src/qt/bitcoingui.cpp | 1 - src/qt/coincontroldialog.cpp | 1 - src/qt/descriptiondialog.cpp | 1 - src/qt/guiutil.cpp | 2 +- src/qt/guiutil.h | 61 ++++++++++++++++ src/qt/guiutil_font.cpp | 6 +- src/qt/guiutil_font.h | 96 ------------------------- src/qt/informationwidget.cpp | 1 - src/qt/masternodelist.cpp | 1 - src/qt/modaloverlay.cpp | 1 - src/qt/networkwidget.cpp | 1 - src/qt/openuridialog.cpp | 1 - src/qt/optionsdialog.cpp | 1 - src/qt/optionsmodel.cpp | 1 - src/qt/overviewpage.cpp | 1 - src/qt/proposalcreate.cpp | 4 +- src/qt/proposalinfo.cpp | 1 - src/qt/proposallist.cpp | 1 - src/qt/proposalmodel.cpp | 6 +- src/qt/proposalresume.cpp | 2 +- src/qt/qrdialog.cpp | 1 - src/qt/qrimagewidget.cpp | 1 - src/qt/receivecoinsdialog.cpp | 1 - src/qt/receiverequestdialog.cpp | 1 - src/qt/rpcconsole.cpp | 1 - src/qt/sendcoinsdialog.cpp | 1 - src/qt/sendcoinsentry.cpp | 1 - src/qt/signverifymessagedialog.cpp | 1 - src/qt/splashscreen.cpp | 1 - src/qt/test/apptests.cpp | 2 +- src/qt/trafficgraphwidget.cpp | 1 - src/qt/utilitydialog.cpp | 1 - src/qt/walletview.cpp | 1 - test/lint/lint-circular-dependencies.py | 1 - 40 files changed, 69 insertions(+), 142 deletions(-) delete mode 100644 src/qt/guiutil_font.h diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 04652688dbef..16296207eca1 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -151,7 +151,6 @@ BITCOIN_QT_H = \ qt/donutchart.h \ qt/editaddressdialog.h \ qt/guiconstants.h \ - qt/guiutil_font.h \ qt/guiutil.h \ qt/informationwidget.h \ qt/initexecutor.h \ diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index 5ffc72846032..1f8d62191325 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index f13723d560fc..12a13e1458ca 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -6,7 +6,6 @@ #include #include -#include #include #include diff --git a/src/qt/appearancewidget.cpp b/src/qt/appearancewidget.cpp index c0234bc795c3..7cba5922dccd 100644 --- a/src/qt/appearancewidget.cpp +++ b/src/qt/appearancewidget.cpp @@ -10,7 +10,6 @@ #include #include -#include #include #include diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index d15abdd71273..ffdc26c12dfc 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 441135aed5a8..578cb564a4fe 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 6c1446f75e5f..622d302341b9 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index d86bdbd1ce40..487693a498a3 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include diff --git a/src/qt/descriptiondialog.cpp b/src/qt/descriptiondialog.cpp index 87b03441672b..4665727a1a6a 100644 --- a/src/qt/descriptiondialog.cpp +++ b/src/qt/descriptiondialog.cpp @@ -6,7 +6,6 @@ #include #include -#include #include diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index a06e07ee37db..b705fe3cab72 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -5,7 +5,6 @@ #include -#include #include #include #include @@ -43,6 +42,7 @@ #include #include #include +#include #include #include #include diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 1446e81dabda..88dfd1354681 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -25,8 +25,10 @@ #include #include +#include #include #include +#include class QValidatedLineEdit; class SendCoinsRecipient; @@ -49,6 +51,7 @@ class QLineEdit; class QMenu; class QPoint; class QProgressDialog; +class QTextEdit; class QUrl; class QWidget; QT_END_NAMESPACE @@ -127,6 +130,9 @@ namespace GUIUtil QString dateTimeStr(const QDateTime &datetime); QString dateTimeStr(qint64 nTime); + // Return a monospace font + QFont fixedPitchFont(bool use_embedded_font = false); + // Set up widget for address void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent, bool fAllowURI = false); @@ -178,6 +184,61 @@ namespace GUIUtil void setClipboard(const QString& str); + enum class FontWeight : uint8_t { + Normal, + Bold, + }; + + /** Load Dash-specific application fonts. Returns false if any failed to load. */ + bool loadFonts(); + /** True once loadFonts() has completed successfully. */ + bool fontsLoaded(); + /** Set the application-wide default font (depends on active font/theme). */ + void setApplicationFont(); + + /** Defaults for the `-font-*` CLI options (used in arg help and as persistence fallbacks). */ + int defaultFontScale(); + int defaultFontSize(); + QString defaultFontFamily(); + + /** Switch the active font family. Registers `font_name` if unknown and applies it to qApp. + * Empty `font_name` means "use defaultFontFamily()". No-op if loadFonts() hasn't run. */ + bool setActiveFont(const QString& font_name = {}); + QString activeFont(); + /** Known fonts and their "selectable in UI" flag, in registration order. */ + const std::vector>& knownFonts(); + + void setFontScale(int font_scale); + int fontScale(); + + /* Weight operations expressed as caller-friendly arg ints 0..8 -- the format used by + * `-font-weight-*` CLI args and QSettings persistence. */ + int currentWeightArg(FontWeight slot); + /** Default-best-match weight for `slot`. Valid before loadFonts() too. */ + int defaultWeightArg(FontWeight slot); + /** Apply a weight. Returns false if `arg` is out of 0..8 or unsupported by the active + * font (no state change in that case). */ + bool setWeightFromArg(FontWeight slot, int arg); + /** Active font's supported weight args, low-to-high. */ + std::vector supportedWeightArgs(); + + /** Register `widgets` to receive the given font attributes on the next updateFonts() pass. + * Uses the currently active font family unless one is given explicitly. */ + void setFont(const std::vector& widgets, FontWeight weight, double point_size = -1, bool is_italic = false); + void setFont(const std::vector& widgets, const QString& font, FontWeight weight, double point_size = -1, bool is_italic = false); + /** Re-apply fonts to all widgets previously registered via setFont(). */ + void updateFonts(); + + /** Get the default bold / normal QFont. */ + QFont getFontBold(); + QFont getFontNormal(); + /** Get a scaled font with the given base size, weight, and optional multiplier. */ + QFont getScaledFont(double baseSize, bool bold, double multiplier = 1); + + /** Set HTML content on a QTextEdit with font-aware styling. Captures the widget's base + * point size on first call so re-application on font/theme changes preserves it. */ + void setStyledHtml(QTextEdit* widget, const QString& html); + /** * Determine default data directory for operating system. */ diff --git a/src/qt/guiutil_font.cpp b/src/qt/guiutil_font.cpp index fd4d85b79f71..966c0ecd1f36 100644 --- a/src/qt/guiutil_font.cpp +++ b/src/qt/guiutil_font.cpp @@ -2,7 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include +#include #include @@ -10,8 +10,6 @@ #include #include -#include - #include #include #include @@ -76,7 +74,7 @@ struct FontInfo { }; //! Global font state (active family, scale, per-font cache). File-private — -//! external callers go through the free-function API in qt/guiutil_font.h. +//! external callers go through the free-function API in qt/guiutil.h. class FontRegistry { public: [[nodiscard]] bool RegisterFont(const QString& font, bool selectable, bool skip_checks = false); diff --git a/src/qt/guiutil_font.h b/src/qt/guiutil_font.h deleted file mode 100644 index 28fc59612f45..000000000000 --- a/src/qt/guiutil_font.h +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) 2014-2025 The Dash 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_GUIUTIL_FONT_H -#define BITCOIN_QT_GUIUTIL_FONT_H - -#include - -#include -#include -#include - -QT_BEGIN_NAMESPACE -class QFont; -class QTextEdit; -class QWidget; -QT_END_NAMESPACE - -namespace GUIUtil { - -enum class FontWeight : uint8_t { - Normal, - Bold, -}; - -/** Default values for the corresponding `-font-*` options (used in arg help - * text and as persistence fallbacks). */ -int defaultFontScale(); -int defaultFontSize(); -QString defaultFontFamily(); - -/** Switch the active font family. Registers `font_name` if not yet known and - * applies the new font to qApp. Empty `font_name` means "use defaultFontFamily()". - * No-op if loadFonts() hasn't completed. Returns true on success. */ -bool setActiveFont(const QString& font_name = {}); -/** Currently active font family. */ -QString activeFont(); -/** Known fonts and their "selectable in UI" flag, in registration order. */ -const std::vector>& knownFonts(); - -void setFontScale(int font_scale); -int fontScale(); - -/* Weight operations expressed in caller-friendly arg ints (0..8). This is the - * format used by `-font-weight-*` CLI args and QSettings persistence. */ - -/** Current weight for `slot`, as arg int. */ -int currentWeightArg(FontWeight slot); -/** Default-best-match weight for `slot`, as arg int. Valid before loadFonts() too. */ -int defaultWeightArg(FontWeight slot); -/** Apply a weight from its arg int. Returns true on success; false if `arg` is - * out of 0..8 or maps to a weight not supported by the active font (no change - * to state in that case). */ -bool setWeightFromArg(FontWeight slot, int arg); -/** Active font's supported weight args, in low-to-high order. */ -std::vector supportedWeightArgs(); - -/** Load dash specific application fonts */ -bool loadFonts(); - -/** Check if the fonts have been loaded successfully */ -bool fontsLoaded(); - -/** Set HTML content on a QTextEdit with font-aware styling. Captures the - * widget's base point size on first call so re-application on font/theme - * changes preserves it. Subsequent calls update the HTML. */ -void setStyledHtml(QTextEdit* widget, const QString& html); - -/** Set an application wide default font, depends on the selected theme */ -void setApplicationFont(); - -/** Register `widgets` to receive the given font attributes on the next updateFonts() pass. - * Uses the currently active font family. */ -void setFont(const std::vector& widgets, FontWeight weight, double point_size = -1, bool is_italic = false); -/** Same as above, but with an explicit font family. */ -void setFont(const std::vector& widgets, const QString& font, FontWeight weight, double point_size = -1, bool is_italic = false); - -/** Update the font of all widgets where a custom font has been set with - GUIUtil::setFont */ -void updateFonts(); - -/** Get the default bold QFont */ -QFont getFontBold(); - -/** Get the default normal QFont */ -QFont getFontNormal(); - -/** Get a scaled font with the specified base size, weight, and optional multiplier. */ -QFont getScaledFont(double baseSize, bool bold, double multiplier = 1); - -/** (Bitcoin) Return a monospace font */ -QFont fixedPitchFont(bool use_embedded_font = false); -} // namespace GUIUtil - -#endif // BITCOIN_QT_GUIUTIL_FONT_H diff --git a/src/qt/informationwidget.cpp b/src/qt/informationwidget.cpp index de39049bb2b1..1d26c30922a5 100644 --- a/src/qt/informationwidget.cpp +++ b/src/qt/informationwidget.cpp @@ -11,7 +11,6 @@ #include #include -#include #include diff --git a/src/qt/masternodelist.cpp b/src/qt/masternodelist.cpp index ad957ee8388e..2ba9e46a78dc 100644 --- a/src/qt/masternodelist.cpp +++ b/src/qt/masternodelist.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include diff --git a/src/qt/modaloverlay.cpp b/src/qt/modaloverlay.cpp index 2db1515f117f..dc4c6a1a0bcb 100644 --- a/src/qt/modaloverlay.cpp +++ b/src/qt/modaloverlay.cpp @@ -7,7 +7,6 @@ #include #include -#include #include #include diff --git a/src/qt/networkwidget.cpp b/src/qt/networkwidget.cpp index 248d03d815dd..58912161610b 100644 --- a/src/qt/networkwidget.cpp +++ b/src/qt/networkwidget.cpp @@ -10,7 +10,6 @@ #include #include -#include #include #include diff --git a/src/qt/openuridialog.cpp b/src/qt/openuridialog.cpp index afd2e6e0807c..324241ce86ae 100644 --- a/src/qt/openuridialog.cpp +++ b/src/qt/openuridialog.cpp @@ -7,7 +7,6 @@ #include #include -#include #include #include diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 659dc82ff624..76d0e5934bae 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index bce5a514e617..3ab17fc63eb8 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 319891b99037..bc3846dd25b7 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include diff --git a/src/qt/proposalcreate.cpp b/src/qt/proposalcreate.cpp index b309b51317bd..0d0597bd7b6c 100644 --- a/src/qt/proposalcreate.cpp +++ b/src/qt/proposalcreate.cpp @@ -11,11 +11,9 @@ #include #include -#include -#include - #include #include +#include #include #include #include diff --git a/src/qt/proposalinfo.cpp b/src/qt/proposalinfo.cpp index 47c44ac3da82..510471ed9159 100644 --- a/src/qt/proposalinfo.cpp +++ b/src/qt/proposalinfo.cpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include diff --git a/src/qt/proposallist.cpp b/src/qt/proposallist.cpp index 16a1f8e9950a..03b0f9e618b0 100644 --- a/src/qt/proposallist.cpp +++ b/src/qt/proposallist.cpp @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/src/qt/proposalmodel.cpp b/src/qt/proposalmodel.cpp index 8580075cc021..ace256893cd6 100644 --- a/src/qt/proposalmodel.cpp +++ b/src/qt/proposalmodel.cpp @@ -8,14 +8,12 @@ #include #include -#include +#include +#include #include #include -#include -#include - #include #include diff --git a/src/qt/proposalresume.cpp b/src/qt/proposalresume.cpp index bdebb1883233..0acb321de757 100644 --- a/src/qt/proposalresume.cpp +++ b/src/qt/proposalresume.cpp @@ -7,7 +7,7 @@ #include -#include +#include #include #include diff --git a/src/qt/qrdialog.cpp b/src/qt/qrdialog.cpp index 1a89e2e4a390..28c2db1f0c9b 100644 --- a/src/qt/qrdialog.cpp +++ b/src/qt/qrdialog.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #include #if defined(HAVE_CONFIG_H) diff --git a/src/qt/qrimagewidget.cpp b/src/qt/qrimagewidget.cpp index 3d937bf7f680..cbe15a1c5c16 100644 --- a/src/qt/qrimagewidget.cpp +++ b/src/qt/qrimagewidget.cpp @@ -5,7 +5,6 @@ #include #include -#include #include #include diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index 70496bcd769b..0401dca9229c 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -7,7 +7,6 @@ #include #include -#include #include #include #include diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index dee027526167..942090e9d383 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -7,7 +7,6 @@ #include #include -#include #include #include #include diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 11fa2c265f64..395fd669abb1 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index c9819de0dd17..db2a304b2410 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index 077a9febc3c5..0b3f1548ccbf 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index e2856413d681..e1bdb63275cd 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -8,7 +8,6 @@ #include #include -#include #include #include diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index d7039def9ea8..32a24535553b 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/src/qt/test/apptests.cpp b/src/qt/test/apptests.cpp index 9b97b2bad89e..30d6223cb21a 100644 --- a/src/qt/test/apptests.cpp +++ b/src/qt/test/apptests.cpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/qt/trafficgraphwidget.cpp b/src/qt/trafficgraphwidget.cpp index c88bf1c9513b..1c204448d5cd 100644 --- a/src/qt/trafficgraphwidget.cpp +++ b/src/qt/trafficgraphwidget.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 27eb09a270cf..0b1d55ac9cdf 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 9a389acd4e0b..face06ba7ade 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include diff --git a/test/lint/lint-circular-dependencies.py b/test/lint/lint-circular-dependencies.py index c1fe90a8c5dc..31a3d54842a1 100755 --- a/test/lint/lint-circular-dependencies.py +++ b/test/lint/lint-circular-dependencies.py @@ -51,7 +51,6 @@ "qt/bitcoingui -> qt/guiutil -> qt/bitcoingui", "qt/clientfeeds -> qt/clientmodel -> qt/clientfeeds", "qt/guiutil -> qt/qvalidatedlineedit -> qt/guiutil", - "qt/guiutil -> qt/guiutil_font -> qt/guiutil", "wallet/coinjoin -> wallet/receive -> wallet/coinjoin", ) From d4badd119a3ff7bed70caf4762516d87d2f0d395 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Tue, 19 May 2026 14:44:08 +0700 Subject: [PATCH 16/16] refactor: replace BitcoinGUI::DEFAULT_UIPLATFORM to GUIUtil::defaultUIPlatform It helps to break circular dependency over qt/guiutil --- src/qt/bitcoin.cpp | 4 ++-- src/qt/bitcoingui.cpp | 10 ---------- src/qt/bitcoingui.h | 2 -- src/qt/guiutil.cpp | 14 ++++++++++++-- src/qt/guiutil.h | 4 ++++ test/lint/lint-circular-dependencies.py | 1 - 6 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 578cb564a4fe..1adb129f5bb8 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -412,7 +412,7 @@ void BitcoinApplication::initializeResult(bool success, interfaces::BlockAndHead m_splash = nullptr; // Log this only after AppInitMain finishes, as then logging setup is guaranteed complete - qInfo() << "Platform customization:" << gArgs.GetArg("-uiplatform", BitcoinGUI::DEFAULT_UIPLATFORM).c_str(); + qInfo() << "Platform customization:" << gArgs.GetArg("-uiplatform", GUIUtil::defaultUIPlatform()).c_str(); clientModel = new ClientModel(node(), optionsModel); window->setClientModel(clientModel, &tip_info); @@ -512,7 +512,7 @@ static void SetupUIArgs(ArgsManager& argsman) argsman.AddArg("-min", QObject::tr("Start minimized").toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); argsman.AddArg("-resetguisettings", QObject::tr("Reset all settings changed in the GUI").toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); argsman.AddArg("-splash", strprintf(QObject::tr("Show splash screen on startup (default: %u)").toStdString(), DEFAULT_SPLASHSCREEN), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); - argsman.AddArg("-uiplatform", strprintf("Select platform to customize UI for (one of windows, macosx, other; default: %s)", BitcoinGUI::DEFAULT_UIPLATFORM), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::GUI); + argsman.AddArg("-uiplatform", strprintf("Select platform to customize UI for (one of windows, macosx, other; default: %s)", GUIUtil::defaultUIPlatform()), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::GUI); argsman.AddArg("-debug-ui", "Updates the UI's stylesheets in realtime with changes made to the css files in -custom-css-dir and forces some widgets to show up which are usually only visible under certain circumstances. (default: 0)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::GUI); argsman.AddArg("-windowtitle=", _("Sets a window title which is appended to \"Dash Core - \"").translated, ArgsManager::ALLOW_ANY, OptionsCategory::GUI); } diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 622d302341b9..4c581111961a 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -86,16 +86,6 @@ constexpr int GOV_CYCLE_FRAME_MS{STATUSBAR_ICON_CYCLE_MS / (GOV_CYCLE_FRAME_COUN constexpr int SPINNER_FRAME_MS{STATUSBAR_ICON_CYCLE_MS / SPINNER_FRAMES}; } // anonymous namespace -const std::string BitcoinGUI::DEFAULT_UIPLATFORM = -#if defined(Q_OS_MACOS) - "macosx" -#elif defined(Q_OS_WIN) - "windows" -#else - "other" -#endif - ; - BitcoinGUI::BitcoinGUI(interfaces::Node& node, const NetworkStyle* networkStyle, QWidget* parent) : QMainWindow(parent), m_node(node), diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 670ce48f084b..333ef538d412 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -74,8 +74,6 @@ class BitcoinGUI : public QMainWindow Q_OBJECT public: - static const std::string DEFAULT_UIPLATFORM; - explicit BitcoinGUI(interfaces::Node& node, const NetworkStyle* networkStyle, QWidget* parent = nullptr); ~BitcoinGUI(); diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index b705fe3cab72..af5210ce36c0 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -6,7 +6,6 @@ #include #include -#include #include #include #include @@ -164,6 +163,17 @@ static const std::map themedDarkStyles = { { ThemedStyle::TS_SECONDARY, "color:#aaa;" }, }; +std::string defaultUIPlatform() +{ +#if defined(Q_OS_MACOS) + return "macosx"; +#elif defined(Q_OS_WIN) + return "windows"; +#else + return "other"; +#endif +} + QColor getThemedQColor(ThemedColor color) { QString theme = QSettings().value("theme", "").toString(); @@ -876,7 +886,7 @@ void loadStyleSheet(bool fForceUpdate) return false; } - std::string platformName = gArgs.GetArg("-uiplatform", BitcoinGUI::DEFAULT_UIPLATFORM); + std::string platformName = gArgs.GetArg("-uiplatform", defaultUIPlatform()); stylesheet = std::make_unique(); for (const auto& file : vecFiles) { diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 88dfd1354681..33db7b82c511 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -60,6 +61,9 @@ QT_END_NAMESPACE */ namespace GUIUtil { + /** Default value for the `-uiplatform` arg ("macosx" / "windows" / "other"). */ + std::string defaultUIPlatform(); + /* Enumeration of possible "colors" */ enum class ThemedColor { /* Transaction list -- TX status decoration - default color */ diff --git a/test/lint/lint-circular-dependencies.py b/test/lint/lint-circular-dependencies.py index 31a3d54842a1..76367c2ddb07 100755 --- a/test/lint/lint-circular-dependencies.py +++ b/test/lint/lint-circular-dependencies.py @@ -48,7 +48,6 @@ "net -> netmessagemaker -> net", "netaddress -> netbase -> netaddress", "qt/bitcoinaddressvalidator -> qt/guiutil -> qt/bitcoinaddressvalidator", - "qt/bitcoingui -> qt/guiutil -> qt/bitcoingui", "qt/clientfeeds -> qt/clientmodel -> qt/clientfeeds", "qt/guiutil -> qt/qvalidatedlineedit -> qt/guiutil", "wallet/coinjoin -> wallet/receive -> wallet/coinjoin",