diff --git a/CLAUDE.md b/CLAUDE.md index b43b9c667a3f..fcbe041c3326 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -63,6 +63,7 @@ make -C depends -j"$(( $(nproc) - 1 ))" | tail 5 --enable-werror # Build with parallel jobs (leaving one core free) +# NOTE: Individual object files cannot be built separately; always do a full build make -j"$(( $(nproc) - 1 ))" ``` diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 08132c0a3848..9a89ce889b46 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -501,7 +501,7 @@ 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-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(-50).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("-lang=", QObject::tr("Set language, for example \"de_DE\" (default: system locale)").toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); @@ -747,7 +747,7 @@ int GuiMain(int argc, char* argv[]) } // Validate/set font scale if (gArgs.IsArgSet("-font-scale")) { - const int nScaleMin = -100, nScaleMax = 100; + const int nScaleMin = -50, nScaleMax = 100; int nScale = gArgs.GetIntArg("-font-scale", GUIUtil::g_font_registry.GetFontScale()); if (nScale < nScaleMin || nScale > nScaleMax) { QMessageBox::critical(nullptr, PACKAGE_NAME, diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 8f6800b482ec..60f7a4a10ccf 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -71,6 +71,7 @@ #include #include +#include #include namespace { @@ -85,6 +86,10 @@ constexpr int GOV_CYCLE_FRAME_MS{STATUSBAR_ICON_CYCLE_MS / (GOV_CYCLE_FRAME_COUN // Per-frame interval for the spinner animation constexpr int SPINNER_FRAME_MS{STATUSBAR_ICON_CYCLE_MS / SPINNER_FRAMES}; + +constexpr int FONT_SCALE_MIN{-50}; +constexpr int FONT_SCALE_MAX{100}; +constexpr int FONT_SCALE_SHORTCUT_STEP{3}; } // anonymous namespace const std::string BitcoinGUI::DEFAULT_UIPLATFORM = @@ -517,12 +522,27 @@ void BitcoinGUI::createActions() m_mask_values_action->setStatusTip(tr("Mask the values in the Overview tab")); m_mask_values_action->setCheckable(true); + m_zoom_in_action = new QAction(tr("Zoom &In"), this); + m_zoom_in_action->setShortcuts({QKeySequence(QKeySequence::ZoomIn), QKeySequence(tr("Ctrl+="))}); + m_zoom_in_action->setStatusTip(tr("Increase the font size")); + + m_zoom_out_action = new QAction(tr("Zoom &Out"), this); + m_zoom_out_action->setShortcuts({QKeySequence(QKeySequence::ZoomOut), QKeySequence(tr("Ctrl+_"))}); + m_zoom_out_action->setStatusTip(tr("Decrease the font size")); + + m_zoom_reset_action = new QAction(tr("Reset &Zoom"), this); + m_zoom_reset_action->setShortcut(QKeySequence(tr("Ctrl+0"))); + m_zoom_reset_action->setStatusTip(tr("Reset the font size to default")); + connect(quitAction, &QAction::triggered, this, &BitcoinGUI::quitRequested); connect(aboutAction, &QAction::triggered, this, &BitcoinGUI::aboutClicked); connect(aboutQtAction, &QAction::triggered, qApp, QApplication::aboutQt); connect(optionsAction, &QAction::triggered, this, &BitcoinGUI::optionsClicked); connect(showHelpMessageAction, &QAction::triggered, this, &BitcoinGUI::showHelpMessageClicked); connect(showCoinJoinHelpAction, &QAction::triggered, this, &BitcoinGUI::showCoinJoinHelpClicked); + connect(m_zoom_in_action, &QAction::triggered, this, [this] { adjustFontScale(FONT_SCALE_SHORTCUT_STEP); }); + connect(m_zoom_out_action, &QAction::triggered, this, [this] { adjustFontScale(-FONT_SCALE_SHORTCUT_STEP); }); + connect(m_zoom_reset_action, &QAction::triggered, this, [this] { adjustFontScale(0); }); // Jump directly to tabs in RPC-console connect(openInfoAction, &QAction::triggered, this, &BitcoinGUI::showInfo); @@ -677,6 +697,11 @@ void BitcoinGUI::createMenuBar() } settings->addAction(optionsAction); + QMenu* view = appMenuBar->addMenu(tr("&View")); + view->addAction(m_zoom_in_action); + view->addAction(m_zoom_out_action); + view->addAction(m_zoom_reset_action); + QMenu* window_menu = appMenuBar->addMenu(tr("&Window")); QAction* minimize_action = window_menu->addAction(tr("&Minimize")); @@ -735,6 +760,31 @@ void BitcoinGUI::createMenuBar() help->addAction(aboutQtAction); } +void BitcoinGUI::adjustFontScale(int delta) +{ + if (clientModel && clientModel->getOptionsModel() && + clientModel->getOptionsModel()->isOptionOverridden("-font-scale")) { + return; + } + + const int current_scale{GUIUtil::g_font_registry.GetFontScale()}; + const int new_scale{delta == 0 + ? GUIUtil::FontRegistry::DEFAULT_FONT_SCALE + : std::clamp(current_scale + delta, FONT_SCALE_MIN, FONT_SCALE_MAX)}; + + if (new_scale == current_scale) { + return; + } + + GUIUtil::g_font_registry.SetFontScale(new_scale); + GUIUtil::updateFonts(); + updateWidth(); + + if (clientModel && clientModel->getOptionsModel()) { + clientModel->getOptionsModel()->setOption(OptionsModel::FontScale, new_scale); + } +} + void BitcoinGUI::createToolBars() { #ifdef ENABLE_WALLET diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 670ce48f084b..999789f4e24b 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -187,6 +187,9 @@ class BitcoinGUI : public QMainWindow QAction* m_close_all_wallets_action{nullptr}; QAction* m_wallet_selector_action = nullptr; QAction* m_mask_values_action{nullptr}; + QAction* m_zoom_in_action{nullptr}; + QAction* m_zoom_out_action{nullptr}; + QAction* m_zoom_reset_action{nullptr}; QComboBox* m_wallet_selector = nullptr; @@ -262,6 +265,9 @@ class BitcoinGUI : public QMainWindow /** Update UI with latest network info from model. */ void updateNetworkState(); + /** Apply a global font scale delta or reset when delta is 0. */ + void adjustFontScale(int delta); + /** Regenerate all pre-cached governance clock pixmaps (e.g. after a theme change). */ void refreshGovernanceCycleIcons(); diff --git a/src/qt/forms/appearancewidget.ui b/src/qt/forms/appearancewidget.ui index 955e94d21969..208d42259a21 100644 --- a/src/qt/forms/appearancewidget.ui +++ b/src/qt/forms/appearancewidget.ui @@ -183,10 +183,10 @@ - -30 + -50 - 30 + 100 10 diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 2b02ac80e1a4..340c44f187e6 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -302,9 +302,11 @@ void setupAppearance(QWidget* parent, OptionsModel* model) } } -void AddButtonShortcut(QAbstractButton* button, const QKeySequence& shortcut) +void AddButtonShortcut(QAbstractButton* button, const QKeySequence& shortcut, Qt::ShortcutContext context) { - QObject::connect(new QShortcut(shortcut, button), &QShortcut::activated, [button]() { button->animateClick(); }); + auto* sc = new QShortcut(shortcut, button); + sc->setContext(context); + QObject::connect(sc, &QShortcut::activated, [button]() { button->animateClick(); }); } bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out) diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 3a9b9240400a..3d0c1fcf084a 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -140,7 +140,7 @@ namespace GUIUtil * @param[in] button QAbstractButton to assign shortcut to * @param[in] shortcut QKeySequence to use as shortcut */ - void AddButtonShortcut(QAbstractButton* button, const QKeySequence& shortcut); + void AddButtonShortcut(QAbstractButton* button, const QKeySequence& shortcut, Qt::ShortcutContext context = Qt::WindowShortcut); // Parse "dash:" URI into recipient object, return true on successful parsing bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out); diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 1c5596baafb7..5a3ddf50781f 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -558,6 +558,17 @@ RPCConsole::RPCConsole(interfaces::Node& node, QWidget* parent, Qt::WindowFlags setButtonIcons(); + // Register console font-size shortcuts once (not in setButtonIcons which + // re-runs on theme changes and would create duplicate QShortcut objects). + //: Main shortcut to increase the RPC console font size. + GUIUtil::AddButtonShortcut(ui->fontBiggerButton, tr("Ctrl++"), Qt::WidgetWithChildrenShortcut); + //: Secondary shortcut to increase the RPC console font size. + GUIUtil::AddButtonShortcut(ui->fontBiggerButton, tr("Ctrl+="), Qt::WidgetWithChildrenShortcut); + //: Main shortcut to decrease the RPC console font size. + GUIUtil::AddButtonShortcut(ui->fontSmallerButton, tr("Ctrl+-"), Qt::WidgetWithChildrenShortcut); + //: Secondary shortcut to decrease the RPC console font size. + GUIUtil::AddButtonShortcut(ui->fontSmallerButton, tr("Ctrl+_"), Qt::WidgetWithChildrenShortcut); + // Install event filter for up and down arrow ui->lineEdit->installEventFilter(this); ui->lineEdit->setMaxLength(16 * 1024 * 1024); @@ -1031,8 +1042,8 @@ void RPCConsole::clear(bool keep_prompt) " without fully understanding the ramifications of a command.%8") .arg(PACKAGE_NAME, "" + ui->clearButton->shortcut().toString(QKeySequence::NativeText) + "", - "" + ui->fontBiggerButton->shortcut().toString(QKeySequence::NativeText) + "", - "" + ui->fontSmallerButton->shortcut().toString(QKeySequence::NativeText) + "", + "" + QKeySequence(tr("Ctrl++")).toString(QKeySequence::NativeText) + "", + "" + QKeySequence(tr("Ctrl+-")).toString(QKeySequence::NativeText) + "", "help", "help-console", "", @@ -1347,16 +1358,7 @@ void RPCConsole::setButtonIcons() GUIUtil::setIcon(ui->clearButton, "remove", GUIUtil::ThemedColor::RED, consoleButtonsSize); GUIUtil::setIcon(ui->fontBiggerButton, "fontbigger", GUIUtil::ThemedColor::BLUE, consoleButtonsSize); - //: Main shortcut to increase the RPC console font size. - ui->fontBiggerButton->setShortcut(tr("Ctrl++")); - //: Secondary shortcut to increase the RPC console font size. - GUIUtil::AddButtonShortcut(ui->fontBiggerButton, tr("Ctrl+=")); - GUIUtil::setIcon(ui->fontSmallerButton, "fontsmaller", GUIUtil::ThemedColor::BLUE, consoleButtonsSize); - //: Main shortcut to decrease the RPC console font size. - ui->fontSmallerButton->setShortcut(tr("Ctrl+-")); - //: Secondary shortcut to decrease the RPC console font size. - GUIUtil::AddButtonShortcut(ui->fontSmallerButton, tr("Ctrl+_")); } void RPCConsole::reloadThemedWidgets()