diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui index 99fb2387723..6c7061e25bf 100644 --- a/src/qt/forms/optionsdialog.ui +++ b/src/qt/forms/optionsdialog.ui @@ -796,6 +796,31 @@ + + + + + + Font in QR Codes: + + + qrFont + + + + + + + + + + 1NS17iag9jJgT… +bc1p2q3rvn3gp… + + + + + diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index a87bef796c3..db7a4cc281e 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -205,6 +205,12 @@ OptionsDialog::OptionsDialog(QWidget* parent, bool enableWallet) } setupFontOptions(ui->moneyFont, ui->moneyFont_preview); + setupFontOptions(ui->qrFont, ui->qrFont_preview); +#ifndef USE_QRCODE + ui->qrFontLabel->setVisible(false); + ui->qrFont->setVisible(false); + ui->qrFont_preview->setVisible(false); +#endif GUIUtil::handleCloseWindowShortcut(this); } @@ -245,6 +251,9 @@ void OptionsDialog::setModel(OptionsModel *_model) const auto& font_for_money = _model->data(_model->index(OptionsModel::FontForMoney, 0), Qt::EditRole).value(); setFontChoice(ui->moneyFont, font_for_money); + const auto& font_for_qrcodes = _model->data(_model->index(OptionsModel::FontForQRCodes, 0), Qt::EditRole).value(); + setFontChoice(ui->qrFont, font_for_qrcodes); + updateDefaultProxyNets(); } @@ -384,6 +393,7 @@ void OptionsDialog::on_openBitcoinConfButton_clicked() void OptionsDialog::on_okButton_clicked() { model->setData(model->index(OptionsModel::FontForMoney, 0), ui->moneyFont->itemData(ui->moneyFont->currentIndex())); + model->setData(model->index(OptionsModel::FontForQRCodes, 0), ui->qrFont->itemData(ui->qrFont->currentIndex())); mapper->submit(); accept(); diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index d816a72ca36..fa370d476cc 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -258,6 +258,11 @@ bool OptionsModel::Init(bilingual_str& error) } Q_EMIT fontForMoneyChanged(getFontForMoney()); + if (settings.contains("FontForQRCodes")) { + m_font_qrcodes = FontChoiceFromString(settings.value("FontForQRCodes").toString()); + } + Q_EMIT fontForQRCodesChanged(getFontChoiceForQRCodes()); + m_mask_values = settings.value("mask_values", false).toBool(); return true; @@ -466,6 +471,8 @@ QVariant OptionsModel::getOption(OptionID option, const std::string& suffix) con return QString::fromStdString(SettingToString(setting(), "")); case FontForMoney: return QVariant::fromValue(m_font_money); + case FontForQRCodes: + return QVariant::fromValue(m_font_qrcodes); case CoinControlFeatures: return fCoinControlFeatures; case EnablePSBTControls: @@ -649,6 +656,15 @@ bool OptionsModel::setOption(OptionID option, const QVariant& value, const std:: Q_EMIT fontForMoneyChanged(getFontForMoney()); break; } + case FontForQRCodes: + { + const auto& new_font = value.value(); + if (m_font_qrcodes == new_font) break; + settings.setValue("FontForQRCodes", FontChoiceToString(new_font)); + m_font_qrcodes = new_font; + Q_EMIT fontForQRCodesChanged(new_font); + break; + } case CoinControlFeatures: fCoinControlFeatures = value.toBool(); settings.setValue("fCoinControlFeatures", fCoinControlFeatures); diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index b5ea6c783e4..6f8c55d0bb0 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -63,6 +63,7 @@ class OptionsModel : public QAbstractListModel ThirdPartyTxUrls, // QString Language, // QString FontForMoney, // FontChoice + FontForQRCodes, // FontChoice CoinControlFeatures, // bool SubFeeFromAmount, // bool ThreadsScriptVerif, // int @@ -104,6 +105,7 @@ class OptionsModel : public QAbstractListModel BitcoinUnit getDisplayUnit() const { return m_display_bitcoin_unit; } QString getThirdPartyTxUrls() const { return strThirdPartyTxUrls; } QFont getFontForMoney() const; + FontChoice getFontChoiceForQRCodes() const { return m_font_qrcodes; } bool getCoinControlFeatures() const { return fCoinControlFeatures; } bool getSubFeeFromAmount() const { return m_sub_fee_from_amount; } bool getEnablePSBTControls() const { return m_enable_psbt_controls; } @@ -131,6 +133,7 @@ class OptionsModel : public QAbstractListModel BitcoinUnit m_display_bitcoin_unit; QString strThirdPartyTxUrls; FontChoice m_font_money{FontChoiceAbstract::EmbeddedFont}; + FontChoice m_font_qrcodes{FontChoiceAbstract::EmbeddedFont}; bool fCoinControlFeatures; bool m_sub_fee_from_amount; bool m_enable_psbt_controls; @@ -153,6 +156,7 @@ class OptionsModel : public QAbstractListModel void coinControlFeaturesChanged(bool); void showTrayIconChanged(bool); void fontForMoneyChanged(const QFont&); + void fontForQRCodesChanged(const FontChoice&); }; Q_DECLARE_METATYPE(OptionsModel::FontChoice) diff --git a/src/qt/qrimagewidget.cpp b/src/qt/qrimagewidget.cpp index 00f928b3557..ad87fe9807a 100644 --- a/src/qt/qrimagewidget.cpp +++ b/src/qt/qrimagewidget.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -31,7 +32,7 @@ QRImageWidget::QRImageWidget(QWidget* parent) contextMenu->addAction(tr("&Copy Image"), this, &QRImageWidget::copyImage); } -bool QRImageWidget::setQR(const QString& data, const QString& text) +bool QRImageWidget::setQR(const QString& data, const QString& text, const OptionsModel::FontChoice& fontchoice) { #ifdef USE_QRCODE setText(""); @@ -72,11 +73,22 @@ bool QRImageWidget::setQR(const QString& data, const QString& text) QRect paddedRect = qrAddrImage.rect(); paddedRect.setHeight(QR_IMAGE_SIZE + QR_IMAGE_TEXT_MARGIN); - QFont font = GUIUtil::fixedPitchFont(); - font.setStretch(QFont::SemiCondensed); - font.setLetterSpacing(QFont::AbsoluteSpacing, 1); - const qreal font_size = GUIUtil::calculateIdealFontSize(paddedRect.width() - 2 * QR_IMAGE_TEXT_MARGIN, text, font); - font.setPointSizeF(font_size); + QFont font; + + // Determine font to use + if (std::holds_alternative(fontchoice)) { + font = GUIUtil::fixedPitchFont(fontchoice != OptionsModel::UseBestSystemFont); + font.setWeight(QFont::Bold); + font.setStretch(QFont::SemiCondensed); + font.setLetterSpacing(QFont::AbsoluteSpacing, 1); + + const auto qr_image_width = paddedRect.width(); + const int max_text_width = qr_image_width - (2 * QR_IMAGE_TEXT_MARGIN); + const qreal font_size = GUIUtil::calculateIdealFontSize(max_text_width, text, font); + font.setPointSizeF(font_size); + } else { + font = std::get(fontchoice); + } painter.setFont(font); painter.drawText(paddedRect, Qt::AlignBottom | Qt::AlignCenter, text); @@ -92,6 +104,11 @@ bool QRImageWidget::setQR(const QString& data, const QString& text) #endif } +bool QRImageWidget::setQR(const QString& data) +{ + return setQR(data, "", OptionsModel::FontChoiceAbstract::EmbeddedFont); +} + QImage QRImageWidget::exportImage() { return GUIUtil::GetImage(this); diff --git a/src/qt/qrimagewidget.h b/src/qt/qrimagewidget.h index d9ca2b899fb..b71659b1a5c 100644 --- a/src/qt/qrimagewidget.h +++ b/src/qt/qrimagewidget.h @@ -5,6 +5,8 @@ #ifndef BITCOIN_QT_QRIMAGEWIDGET_H #define BITCOIN_QT_QRIMAGEWIDGET_H +#include + #include #include @@ -29,7 +31,8 @@ class QRImageWidget : public QLabel public: explicit QRImageWidget(QWidget *parent = nullptr); - bool setQR(const QString& data, const QString& text = ""); + bool setQR(const QString& data); + bool setQR(const QString& data, const QString& text, const OptionsModel::FontChoice& fontchoice); QImage exportImage(); public Q_SLOTS: diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index 3453857f985..c7fed910335 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -49,8 +49,11 @@ void ReceiveRequestDialog::setInfo(const SendCoinsRecipient &_info) QString uri = GUIUtil::formatBitcoinURI(info); #ifdef USE_QRCODE - if (ui->qr_code->setQR(uri, info.address)) { + if (ui->qr_code->setQR(uri, info.address, model->getOptionsModel()->getFontChoiceForQRCodes())) { connect(ui->btnSaveAs, &QPushButton::clicked, ui->qr_code, &QRImageWidget::saveImage); + connect(model->getOptionsModel(), &OptionsModel::fontForQRCodesChanged, this, [&](const OptionsModel::FontChoice& fontchoice){ + ui->qr_code->setQR(uri, info.address, fontchoice); + }); } else { ui->btnSaveAs->setEnabled(false); }