diff --git a/doc/release-notes-6833.md b/doc/release-notes-6833.md new file mode 100644 index 0000000000000..23e50378905bd --- /dev/null +++ b/doc/release-notes-6833.md @@ -0,0 +1,15 @@ +GUI changes +----------- + +Configuration changes made in the Dash GUI (such as the pruning setting, +proxy settings, UPNP preferences) are now saved to `/settings.json` +file rather than to the Qt settings backend (windows registry or unix desktop +config files), so these settings will now apply to dashd, instead of being +ignored. + +Also, the interaction between GUI settings and `dash.conf` settings is +simplified. Settings from `dash.conf` are now displayed normally in the GUI +settings dialog, instead of in a separate warning message ("Options set in this +dialog are overridden by the configuration file: -setting=value"). And these +settings can now be edited because `settings.json` values take precedence over +`dash.conf` values. diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index f50ac4602bfb4..4372effd3e853 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -137,6 +137,7 @@ BITCOIN_QT_H = \ qt/proposalwizard.h \ qt/guiconstants.h \ qt/guiutil.h \ + qt/guiutil_font.h \ qt/initexecutor.h \ qt/intro.h \ qt/macdockiconhandler.h \ @@ -227,6 +228,7 @@ BITCOIN_QT_BASE_CPP = \ qt/clientmodel.cpp \ qt/csvmodelwriter.cpp \ qt/guiutil.cpp \ + qt/guiutil_font.cpp \ qt/initexecutor.cpp \ qt/intro.cpp \ qt/modaloverlay.cpp \ diff --git a/src/init.cpp b/src/init.cpp index 6a96d6dd4a9cc..b560a2eff90ce 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -426,7 +426,6 @@ void Shutdown(NodeContext& node) LogPrintf("%s: Unable to remove PID file: %s\n", __func__, fsbridge::get_filesystem_error_message(e)); } - node.args = nullptr; LogPrintf("%s: done\n", __func__); } diff --git a/src/interfaces/node.h b/src/interfaces/node.h index 3ea9b5da6450e..aff8f0044d2e9 100644 --- a/src/interfaces/node.h +++ b/src/interfaces/node.h @@ -5,13 +5,14 @@ #ifndef BITCOIN_INTERFACES_NODE_H #define BITCOIN_INTERFACES_NODE_H -#include // For CAmount -#include // For NodeId -#include // For banmap_t -#include // For Network -#include // For ConnectionDirection +#include // For CAmount +#include // For NodeId +#include // For banmap_t +#include // For Network +#include // For ConnectionDirection #include // For SecureString #include +#include // For util::SettingsValue #include #include @@ -193,6 +194,24 @@ class Node //! Return whether shutdown was requested. virtual bool shutdownRequested() = 0; + //! Return whether a particular setting in /settings.json is or + //! would be ignored because it is also specified in the command line. + virtual bool isSettingIgnored(const std::string& name) = 0; + + //! Return setting value from /settings.json or bitcoin.conf. + virtual util::SettingsValue getPersistentSetting(const std::string& name) = 0; + + //! Update a setting in /settings.json. + virtual void updateRwSetting(const std::string& name, const util::SettingsValue& value) = 0; + + //! Force a setting value to be applied, overriding any other configuration + //! source, but not being persisted. + virtual void forceSetting(const std::string& name, const util::SettingsValue& value) = 0; + + //! Clear all settings in /settings.json and store a backup of + //! previous settings in /settings.json.bak. + virtual void resetSettings() = 0; + //! Map port. virtual void mapPort(bool use_upnp, bool use_natpmp) = 0; diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp index bccb43aafe594..b269972d2cf1a 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -444,6 +444,46 @@ class NodeImpl : public Node } } bool shutdownRequested() override { return ShutdownRequested(); } + bool isSettingIgnored(const std::string& name) override + { + bool ignored = false; + gArgs.LockSettings([&](util::Settings& settings) { + if (auto* options = util::FindKey(settings.command_line_options, name)) { + ignored = !options->empty(); + } + }); + return ignored; + } + util::SettingsValue getPersistentSetting(const std::string& name) override { return gArgs.GetPersistentSetting(name); } + void updateRwSetting(const std::string& name, const util::SettingsValue& value) override + { + gArgs.LockSettings([&](util::Settings& settings) { + if (value.isNull()) { + settings.rw_settings.erase(name); + } else { + settings.rw_settings[name] = value; + } + }); + gArgs.WriteSettingsFile(); + } + void forceSetting(const std::string& name, const util::SettingsValue& value) override + { + gArgs.LockSettings([&](util::Settings& settings) { + if (value.isNull()) { + settings.forced_settings.erase(name); + } else { + settings.forced_settings[name] = value; + } + }); + } + void resetSettings() override + { + gArgs.WriteSettingsFile(/*errors=*/nullptr, /*backup=*/true); + gArgs.LockSettings([&](util::Settings& settings) { + settings.rw_settings.clear(); + }); + gArgs.WriteSettingsFile(); + } void mapPort(bool use_upnp, bool use_natpmp) override { StartMapPort(use_upnp, use_natpmp); } bool getProxy(Network net, Proxy& proxy_info) override { return GetProxy(net, proxy_info); } size_t getNodeCount(ConnectionDirection flags) override diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index 441531bb9207a..3b1f1df4ee763 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index d40a3deef6ebc..e1cc9e6a01559 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include diff --git a/src/qt/appearancewidget.cpp b/src/qt/appearancewidget.cpp index 2a26902d017aa..e5b5954a7f4c1 100644 --- a/src/qt/appearancewidget.cpp +++ b/src/qt/appearancewidget.cpp @@ -28,11 +28,9 @@ AppearanceWidget::AppearanceWidget(QWidget* parent) : ui->theme->addItem(entry, QVariant(entry)); } - GUIUtil::FontFamily fontSystem = GUIUtil::FontFamily::SystemDefault; - GUIUtil::FontFamily fontMontserrat = GUIUtil::FontFamily::Montserrat; - - ui->fontFamily->addItem(GUIUtil::fontFamilyToString(fontSystem), QVariant(static_cast(fontSystem))); - ui->fontFamily->addItem(GUIUtil::fontFamilyToString(fontMontserrat), QVariant(static_cast(fontMontserrat))); + for (const auto& [family, family_str, selectable] : GUIUtil::AVAILABLE_FONTS) { + if (selectable) ui->fontFamily->addItem(family_str, QVariant(static_cast(family))); + } updateWeightSlider(); diff --git a/src/qt/appearancewidget.h b/src/qt/appearancewidget.h index a1cd06e49b6b6..c3e62605d085e 100644 --- a/src/qt/appearancewidget.h +++ b/src/qt/appearancewidget.h @@ -8,6 +8,7 @@ #include #include +#include namespace Ui { class AppearanceWidget; diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index 3b9fd117ffe61..3e7fd9087d247 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index e78adbb798843..7faaca9e8c105 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -267,9 +268,26 @@ void BitcoinApplication::createPaymentServer() } #endif -void BitcoinApplication::createOptionsModel(bool resetSettings) +bool BitcoinApplication::createOptionsModel(bool resetSettings) { - optionsModel = new OptionsModel(this, resetSettings); + optionsModel = new OptionsModel(node(), this); + if (resetSettings) { + optionsModel->Reset(); + } + bilingual_str error; + if (!optionsModel->Init(error)) { + fs::path settings_path; + if (gArgs.GetSettingsPath(&settings_path)) { + error += Untranslated("\n"); + std::string quoted_path = strprintf("%s", fs::quoted(fs::PathToString(settings_path))); + error.original += strprintf("Settings file %s might be corrupt or invalid.", quoted_path); + error.translated += tr("Settings file %1 might be corrupt or invalid.").arg(QString::fromStdString(quoted_path)).toStdString(); + } + InitError(error); + QMessageBox::critical(nullptr, PACKAGE_NAME, QString::fromStdString(error.translated)); + return false; + } + return true; } void BitcoinApplication::createWindow(const NetworkStyle *networkStyle) @@ -295,7 +313,6 @@ void BitcoinApplication::createNode(interfaces::Init& init) { assert(!m_node); m_node = init.makeNode(); - if (optionsModel) optionsModel->setNode(*m_node); if (m_splash) m_splash->setNode(*m_node); } @@ -332,7 +349,7 @@ void BitcoinApplication::parameterSetup() void BitcoinApplication::InitPruneSetting(int64_t prune_MiB) { - optionsModel->SetPruneTargetGB(PruneMiBtoGB(prune_MiB), true); + optionsModel->SetPruneTargetGB(PruneMiBtoGB(prune_MiB)); } void BitcoinApplication::requestInitialize() @@ -488,10 +505,10 @@ 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("SystemDefault, Montserrat").arg(GUIUtil::fontFamilyToString(GUIUtil::getFontFamilyDefault())).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::getFontScaleDefault()).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::getFontWeightBoldDefault())).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::getFontWeightNormalDefault())).toStdString(), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); + argsman.AddArg("-font-family", QObject::tr("Set the font family. Possible values: %1. (default: %2)").arg("SystemDefault, Montserrat").arg(GUIUtil::fontFamilyToString(GUIUtil::g_font_defaults.family)).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::g_font_defaults.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::g_font_defaults.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::g_font_defaults.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); 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); @@ -670,12 +687,21 @@ int GuiMain(int argc, char* argv[]) QObject::tr("Error: Failed to load application fonts.")); return EXIT_FAILURE; } + + if (gArgs.GetBoolArg("-splash", DEFAULT_SPLASHSCREEN) && !gArgs.GetBoolArg("-min", false)) + app.createSplashScreen(networkStyle.data()); + + app.createNode(*init); + // Load GUI settings from QSettings - app.createOptionsModel(gArgs.GetBoolArg("-resetguisettings", false)); + if (!app.createOptionsModel(gArgs.GetBoolArg("-resetguisettings", false))) { + return EXIT_FAILURE; + } + // Validate/set font family if (gArgs.IsArgSet("-font-family")) { GUIUtil::FontFamily family; - QString strFamily = gArgs.GetArg("-font-family", GUIUtil::fontFamilyToString(GUIUtil::getFontFamilyDefault()).toStdString()).c_str(); + QString strFamily = gArgs.GetArg("-font-family", GUIUtil::fontFamilyToString(GUIUtil::g_font_defaults.family).toStdString()).c_str(); try { family = GUIUtil::fontFamilyFromString(strFamily); } catch (const std::exception& e) { @@ -762,11 +788,6 @@ int GuiMain(int argc, char* argv[]) app.InitPruneSetting(prune_MiB); } - if (gArgs.GetBoolArg("-splash", DEFAULT_SPLASHSCREEN) && !gArgs.GetBoolArg("-min", false)) - app.createSplashScreen(networkStyle.data()); - - app.createNode(*init); - int rv = EXIT_SUCCESS; try { diff --git a/src/qt/bitcoin.h b/src/qt/bitcoin.h index 7aa12efbc2fb3..0cf8ee03bcfcf 100644 --- a/src/qt/bitcoin.h +++ b/src/qt/bitcoin.h @@ -46,7 +46,7 @@ class BitcoinApplication: public QApplication /// parameter interaction/setup based on rules void parameterSetup(); /// Create options model - void createOptionsModel(bool resetSettings); + [[nodiscard]] bool createOptionsModel(bool resetSettings); /// Initialize prune setting void InitPruneSetting(int64_t prune_MiB); /// Create main window diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 08d0c6a16ca5c..bd2206f6a6ca0 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -888,6 +889,8 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel, interfaces::BlockAndH connect(optionsModel, &OptionsModel::coinJoinEnabledChanged, this, &BitcoinGUI::updateCoinJoinVisibility); } + + m_mask_values_action->setChecked(_clientModel->getOptionsModel()->getOption(OptionsModel::OptionID::MaskValues).toBool()); } else { if(trayIconMenu) { diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 593caf5ba252b..570ca199387d3 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui index d8f462c6e4b0c..09efc32fa040c 100644 --- a/src/qt/forms/optionsdialog.ui +++ b/src/qt/forms/optionsdialog.ui @@ -1055,6 +1055,118 @@ https://explore.transifex.com/dash/dash/ + + + + Monospaced font in the Overview tab: + + + + 18 + + + 18 + + + 18 + + + 18 + + + + + + + embedded "%1" + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 111.11111111 DASH + + + + + + + 909.09090909 DASH + + + + + + + + + + + Qt::Horizontal + + + + + + + + + closest matching "%1" + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 111.11111111 DASH + + + + + + + 909.09090909 DASH + + + + + + + + + + @@ -1100,7 +1212,7 @@ https://explore.transifex.com/dash/dash/ - Options set in this dialog are overridden by the command line or in the configuration file: + Options set in this dialog are overridden by the command line: Qt::PlainText diff --git a/src/qt/governancelist.cpp b/src/qt/governancelist.cpp index c68f6a7076d93..6bb9e7d72b215 100644 --- a/src/qt/governancelist.cpp +++ b/src/qt/governancelist.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include