diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui
index 6be47e94feb..99fb2387723 100644
--- a/src/qt/forms/optionsdialog.ui
+++ b/src/qt/forms/optionsdialog.ui
@@ -772,104 +772,29 @@
-
-
-
- Monospaced font in the Overview tab:
-
-
-
-
-
-
-
-
-
- embedded "%1"
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
-
-
-
- 111.11111111 BTC
-
-
-
- -
-
-
- 909.09090909 BTC
-
-
-
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- -
-
-
-
-
-
- closest matching "%1"
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
-
-
-
- 111.11111111 BTC
-
-
-
- -
-
-
- 909.09090909 BTC
-
-
-
-
-
-
-
-
-
+
+ -
+
+
+ Font in the Overview tab:
+
+
+ moneyFont
+
+
+
+ -
+
+
+ -
+
+
+ 111.11111111 BTC
+909.09090909 BTC
+
+
+
+
-
diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp
index 6dec4b2e42e..b10c0740831 100644
--- a/src/qt/optionsdialog.cpp
+++ b/src/qt/optionsdialog.cpp
@@ -23,14 +23,70 @@
#include
+#include
#include
#include
+#include
#include
#include
#include
#include
#include
+int setFontChoice(QComboBox* cb, const OptionsModel::FontChoice& fc)
+{
+ int i;
+ for (i = cb->count(); --i >= 0; ) {
+ QVariant item_data = cb->itemData(i);
+ if (!item_data.canConvert()) continue;
+ if (item_data.value() == fc) {
+ break;
+ }
+ }
+ if (i == -1) {
+ // New item needed
+ QFont chosen_font = OptionsModel::getFontForChoice(fc);
+ QSignalBlocker block_currentindexchanged_signal(cb); // avoid triggering QFontDialog
+ cb->insertItem(0, QFontInfo(chosen_font).family(), QVariant::fromValue(fc));
+ i = 0;
+ }
+
+ cb->setCurrentIndex(i);
+ return i;
+}
+
+void setupFontOptions(QComboBox* cb, QLabel* preview)
+{
+ QFont embedded_font{GUIUtil::fixedPitchFont(true)};
+ QFont system_font{GUIUtil::fixedPitchFont(false)};
+ cb->addItem(QObject::tr("Embedded \"%1\"").arg(QFontInfo(embedded_font).family()), QVariant::fromValue(OptionsModel::FontChoice{OptionsModel::FontChoiceAbstract::EmbeddedFont}));
+ cb->addItem(QObject::tr("Default system font \"%1\"").arg(QFontInfo(system_font).family()), QVariant::fromValue(OptionsModel::FontChoice{OptionsModel::FontChoiceAbstract::BestSystemFont}));
+ cb->addItem(QObject::tr("Custom…"));
+
+ const auto& on_font_choice_changed = [cb, preview](int index) {
+ static int previous_index = -1;
+ QVariant item_data = cb->itemData(index);
+ QFont f;
+ if (item_data.canConvert()) {
+ f = OptionsModel::getFontForChoice(item_data.value());
+ } else {
+ bool ok;
+ f = QFontDialog::getFont(&ok, GUIUtil::fixedPitchFont(false), cb->parentWidget());
+ if (!ok) {
+ cb->setCurrentIndex(previous_index);
+ return;
+ }
+ index = setFontChoice(cb, OptionsModel::FontChoice{f});
+ }
+ if (preview) {
+ preview->setFont(f);
+ }
+ previous_index = index;
+ };
+ QObject::connect(cb, QOverload::of(&QComboBox::currentIndexChanged), on_font_choice_changed);
+ on_font_choice_changed(cb->currentIndex());
+}
+
OptionsDialog::OptionsDialog(QWidget* parent, bool enableWallet)
: QDialog(parent, GUIUtil::dialog_flags),
ui(new Ui::OptionsDialog)
@@ -148,19 +204,7 @@ OptionsDialog::OptionsDialog(QWidget* parent, bool enableWallet)
ui->minimizeToTray->setEnabled(false);
}
- QFont embedded_font{GUIUtil::fixedPitchFont(true)};
- ui->embeddedFont_radioButton->setText(ui->embeddedFont_radioButton->text().arg(QFontInfo(embedded_font).family()));
- embedded_font.setWeight(QFont::Bold);
- ui->embeddedFont_label_1->setFont(embedded_font);
- ui->embeddedFont_label_9->setFont(embedded_font);
-
- QFont system_font{GUIUtil::fixedPitchFont(false)};
- ui->systemFont_radioButton->setText(ui->systemFont_radioButton->text().arg(QFontInfo(system_font).family()));
- system_font.setWeight(QFont::Bold);
- ui->systemFont_label_1->setFont(system_font);
- ui->systemFont_label_9->setFont(system_font);
- // Checking the embeddedFont_radioButton automatically unchecks the systemFont_radioButton.
- ui->systemFont_radioButton->setChecked(true);
+ setupFontOptions(ui->moneyFont, ui->moneyFont_preview);
GUIUtil::handleCloseWindowShortcut(this);
}
@@ -198,6 +242,9 @@ void OptionsDialog::setModel(OptionsModel *_model)
setMapper();
mapper->toFirst();
+ const auto& font_for_money = _model->data(_model->index(OptionsModel::FontForMoney, 0), Qt::EditRole).value();
+ setFontChoice(ui->moneyFont, font_for_money);
+
updateDefaultProxyNets();
}
@@ -275,7 +322,6 @@ void OptionsDialog::setMapper()
mapper->addMapping(ui->lang, OptionsModel::Language);
mapper->addMapping(ui->unit, OptionsModel::DisplayUnit);
mapper->addMapping(ui->thirdPartyTxUrls, OptionsModel::ThirdPartyTxUrls);
- mapper->addMapping(ui->embeddedFont_radioButton, OptionsModel::UseEmbeddedMonospacedFont);
}
void OptionsDialog::setOkButtonState(bool fState)
@@ -337,6 +383,8 @@ void OptionsDialog::on_openBitcoinConfButton_clicked()
void OptionsDialog::on_okButton_clicked()
{
+ model->setData(model->index(OptionsModel::FontForMoney, 0), ui->moneyFont->itemData(ui->moneyFont->currentIndex()));
+
mapper->submit();
accept();
updateDefaultProxyNets();
diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp
index bee8fafddc2..2937b800196 100644
--- a/src/qt/optionsmodel.cpp
+++ b/src/qt/optionsmodel.cpp
@@ -118,6 +118,37 @@ struct ProxySetting {
static ProxySetting ParseProxyString(const std::string& proxy);
static std::string ProxyString(bool is_set, QString ip, QString port);
+static const QLatin1String fontchoice_str_embedded{"embedded"};
+static const QLatin1String fontchoice_str_best_system{"best_system"};
+static const QString fontchoice_str_custom_prefix{QStringLiteral("custom, ")};
+
+QString OptionsModel::FontChoiceToString(const OptionsModel::FontChoice& f)
+{
+ if (std::holds_alternative(f)) {
+ if (f == UseBestSystemFont) {
+ return fontchoice_str_best_system;
+ } else {
+ return fontchoice_str_embedded;
+ }
+ }
+ return fontchoice_str_custom_prefix + std::get(f).toString();
+}
+
+OptionsModel::FontChoice OptionsModel::FontChoiceFromString(const QString& s)
+{
+ if (s == fontchoice_str_best_system) {
+ return FontChoiceAbstract::BestSystemFont;
+ } else if (s == fontchoice_str_embedded) {
+ return FontChoiceAbstract::EmbeddedFont;
+ } else if (s.startsWith(fontchoice_str_custom_prefix)) {
+ QFont f;
+ f.fromString(s.mid(fontchoice_str_custom_prefix.size()));
+ return f;
+ } else {
+ return FontChoiceAbstract::EmbeddedFont; // default
+ }
+}
+
OptionsModel::OptionsModel(interfaces::Node& node, QObject *parent) :
QAbstractListModel(parent), m_node{node}
{
@@ -215,11 +246,16 @@ bool OptionsModel::Init(bilingual_str& error)
#endif
// Display
- if (!settings.contains("UseEmbeddedMonospacedFont")) {
- settings.setValue("UseEmbeddedMonospacedFont", "true");
+ if (settings.contains("FontForMoney")) {
+ m_font_money = FontChoiceFromString(settings.value("FontForMoney").toString());
+ } else if (settings.contains("UseEmbeddedMonospacedFont")) {
+ if (settings.value("UseEmbeddedMonospacedFont").toBool()) {
+ m_font_money = FontChoiceAbstract::EmbeddedFont;
+ } else {
+ m_font_money = FontChoiceAbstract::BestSystemFont;
+ }
}
- m_use_embedded_monospaced_font = settings.value("UseEmbeddedMonospacedFont").toBool();
- Q_EMIT useEmbeddedMonospacedFontChanged(m_use_embedded_monospaced_font);
+ Q_EMIT fontForMoneyChanged(getFontForMoney());
m_mask_values = settings.value("mask_values", false).toBool();
@@ -427,8 +463,8 @@ QVariant OptionsModel::getOption(OptionID option, const std::string& suffix) con
return strThirdPartyTxUrls;
case Language:
return QString::fromStdString(SettingToString(setting(), ""));
- case UseEmbeddedMonospacedFont:
- return m_use_embedded_monospaced_font;
+ case FontForMoney:
+ return QVariant::fromValue(m_font_money);
case CoinControlFeatures:
return fCoinControlFeatures;
case EnablePSBTControls:
@@ -454,6 +490,23 @@ QVariant OptionsModel::getOption(OptionID option, const std::string& suffix) con
}
}
+QFont OptionsModel::getFontForChoice(const FontChoice& fc)
+{
+ QFont f;
+ if (std::holds_alternative(fc)) {
+ f = GUIUtil::fixedPitchFont(fc != UseBestSystemFont);
+ f.setWeight(QFont::Bold);
+ } else {
+ f = std::get(fc);
+ }
+ return f;
+}
+
+QFont OptionsModel::getFontForMoney() const
+{
+ return getFontForChoice(m_font_money);
+}
+
bool OptionsModel::setOption(OptionID option, const QVariant& value, const std::string& suffix)
{
auto changed = [&] { return value.isValid() && value != getOption(option, suffix); };
@@ -586,11 +639,15 @@ bool OptionsModel::setOption(OptionID option, const QVariant& value, const std::
setRestartRequired(true);
}
break;
- case UseEmbeddedMonospacedFont:
- m_use_embedded_monospaced_font = value.toBool();
- settings.setValue("UseEmbeddedMonospacedFont", m_use_embedded_monospaced_font);
- Q_EMIT useEmbeddedMonospacedFontChanged(m_use_embedded_monospaced_font);
+ case FontForMoney:
+ {
+ const auto& new_font = value.value();
+ if (m_font_money == new_font) break;
+ settings.setValue("FontForMoney", FontChoiceToString(new_font));
+ m_font_money = new_font;
+ Q_EMIT fontForMoneyChanged(getFontForMoney());
break;
+ }
case CoinControlFeatures:
fCoinControlFeatures = value.toBool();
settings.setValue("fCoinControlFeatures", fCoinControlFeatures);
diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h
index f28a1087ba5..b5ea6c783e4 100644
--- a/src/qt/optionsmodel.h
+++ b/src/qt/optionsmodel.h
@@ -10,8 +10,10 @@
#include
#include
+#include
#include
+#include
struct bilingual_str;
namespace interfaces {
@@ -60,7 +62,7 @@ class OptionsModel : public QAbstractListModel
DisplayUnit, // BitcoinUnit
ThirdPartyTxUrls, // QString
Language, // QString
- UseEmbeddedMonospacedFont, // bool
+ FontForMoney, // FontChoice
CoinControlFeatures, // bool
SubFeeFromAmount, // bool
ThreadsScriptVerif, // int
@@ -76,6 +78,14 @@ class OptionsModel : public QAbstractListModel
OptionIDRowCount,
};
+ enum class FontChoiceAbstract {
+ EmbeddedFont,
+ BestSystemFont,
+ };
+ typedef std::variant FontChoice;
+ static inline const FontChoice UseBestSystemFont{FontChoiceAbstract::BestSystemFont};
+ static QFont getFontForChoice(const FontChoice& fc);
+
bool Init(bilingual_str& error);
void Reset();
@@ -93,7 +103,7 @@ class OptionsModel : public QAbstractListModel
bool getMinimizeOnClose() const { return fMinimizeOnClose; }
BitcoinUnit getDisplayUnit() const { return m_display_bitcoin_unit; }
QString getThirdPartyTxUrls() const { return strThirdPartyTxUrls; }
- bool getUseEmbeddedMonospacedFont() const { return m_use_embedded_monospaced_font; }
+ QFont getFontForMoney() const;
bool getCoinControlFeatures() const { return fCoinControlFeatures; }
bool getSubFeeFromAmount() const { return m_sub_fee_from_amount; }
bool getEnablePSBTControls() const { return m_enable_psbt_controls; }
@@ -120,7 +130,7 @@ class OptionsModel : public QAbstractListModel
QString language;
BitcoinUnit m_display_bitcoin_unit;
QString strThirdPartyTxUrls;
- bool m_use_embedded_monospaced_font;
+ FontChoice m_font_money{FontChoiceAbstract::EmbeddedFont};
bool fCoinControlFeatures;
bool m_sub_fee_from_amount;
bool m_enable_psbt_controls;
@@ -129,6 +139,9 @@ class OptionsModel : public QAbstractListModel
/* settings that were overridden by command-line */
QString strOverriddenByCommandLine;
+ static QString FontChoiceToString(const OptionsModel::FontChoice&);
+ static FontChoice FontChoiceFromString(const QString&);
+
// Add option to list of GUI options overridden through command line/config file
void addOverriddenOption(const std::string &option);
@@ -139,7 +152,9 @@ class OptionsModel : public QAbstractListModel
void displayUnitChanged(BitcoinUnit unit);
void coinControlFeaturesChanged(bool);
void showTrayIconChanged(bool);
- void useEmbeddedMonospacedFontChanged(bool);
+ void fontForMoneyChanged(const QFont&);
};
+Q_DECLARE_METATYPE(OptionsModel::FontChoice)
+
#endif // BITCOIN_QT_OPTIONSMODEL_H
diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp
index 0f00d167f76..7d584920822 100644
--- a/src/qt/overviewpage.cpp
+++ b/src/qt/overviewpage.cpp
@@ -250,8 +250,8 @@ void OverviewPage::setClientModel(ClientModel *model)
connect(model, &ClientModel::alertsChanged, this, &OverviewPage::updateAlerts);
updateAlerts(model->getStatusBarWarnings());
- connect(model->getOptionsModel(), &OptionsModel::useEmbeddedMonospacedFontChanged, this, &OverviewPage::setMonospacedFont);
- setMonospacedFont(model->getOptionsModel()->getUseEmbeddedMonospacedFont());
+ connect(model->getOptionsModel(), &OptionsModel::fontForMoneyChanged, this, &OverviewPage::setMonospacedFont);
+ setMonospacedFont(clientModel->getOptionsModel()->getFontForMoney());
}
}
@@ -340,10 +340,8 @@ void OverviewPage::showOutOfSyncWarning(bool fShow)
ui->labelTransactionsStatus->setVisible(fShow);
}
-void OverviewPage::setMonospacedFont(bool use_embedded_font)
+void OverviewPage::setMonospacedFont(const QFont& f)
{
- QFont f = GUIUtil::fixedPitchFont(use_embedded_font);
- f.setWeight(QFont::Bold);
ui->labelBalance->setFont(f);
ui->labelUnconfirmed->setFont(f);
ui->labelImmature->setFont(f);
diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h
index 5c487ee1162..fc7a99f319a 100644
--- a/src/qt/overviewpage.h
+++ b/src/qt/overviewpage.h
@@ -65,7 +65,7 @@ private Q_SLOTS:
void handleTransactionClicked(const QModelIndex &index);
void updateAlerts(const QString &warnings);
void updateWatchOnlyLabels(bool showWatchOnly);
- void setMonospacedFont(bool use_embedded_font);
+ void setMonospacedFont(const QFont&);
};
#endif // BITCOIN_QT_OVERVIEWPAGE_H