diff --git a/kcms/fonts/fonts.cpp b/kcms/fonts/fonts.cpp index 4dfe9da66..64b0adabc 100644 --- a/kcms/fonts/fonts.cpp +++ b/kcms/fonts/fonts.cpp @@ -1,735 +1,668 @@ /* Copyright 1997 Mark Donohoe Copyright 1999 Lars Knoll Copyright 2000 Rik Hemsley Copyright 2015 Antonis Tsiapaliokas Copyright 2017 Marco Martin Ported to kcontrol2 by Geert Jansen. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "fonts.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../krdb/krdb.h" /**** DLL Interface ****/ K_PLUGIN_FACTORY_WITH_JSON(KFontsFactory, "kcm_fonts.json", registerPlugin();) //from KFontRequester // Determine if the font with given properties is available on the system, // otherwise find and return the best fitting combination. static QFont nearestExistingFont(const QFont &font) { QFontDatabase dbase; // Initialize font data accoring to given font object. QString family = font.family(); QString style = dbase.styleString(font); qreal size = font.pointSizeF(); // Check if the family exists. const QStringList families = dbase.families(); if (!families.contains(family)) { // Chose another family. family = QFontInfo(font).family(); // the nearest match if (!families.contains(family)) { family = families.count() ? families.at(0) : QStringLiteral("fixed"); } } // Check if the family has the requested style. // Easiest by piping it through font selection in the database. QString retStyle = dbase.styleString(dbase.font(family, style, 10)); style = retStyle; // Check if the family has the requested size. // Only for bitmap fonts. if (!dbase.isSmoothlyScalable(family, style)) { QList sizes = dbase.smoothSizes(family, style); if (!sizes.contains(size)) { // Find nearest available size. int mindiff = 1000; int refsize = size; Q_FOREACH (int lsize, sizes) { int diff = qAbs(refsize - lsize); if (mindiff > diff) { mindiff = diff; size = lsize; } } } } // Select the font with confirmed properties. QFont result = dbase.font(family, style, int(size)); if (dbase.isSmoothlyScalable(family, style) && result.pointSize() == floor(size)) { result.setPointSizeF(size); } return result; } /**** FontAASettings ****/ #if defined(HAVE_FONTCONFIG) && defined (HAVE_X11) FontAASettings::FontAASettings(QObject *parent) : QObject(parent) , m_subPixelOptionsModel(new QStandardItemModel(this)) , m_hintingOptionsModel(new QStandardItemModel(this)) - , m_subPixel(QString("System default")) - , m_hinting(QString("System default")) { for (int t = KXftConfig::SubPixel::NotSet; t <= KXftConfig::SubPixel::Vbgr; ++t) { QStandardItem *item = new QStandardItem(i18n(KXftConfig::description((KXftConfig::SubPixel::Type)t).toUtf8())); m_subPixelOptionsModel->appendRow(item); } for (int s = KXftConfig::Hint::NotSet; s <= KXftConfig::Hint::Full; ++s) { QStandardItem * item = new QStandardItem(i18n(KXftConfig::description((KXftConfig::Hint::Style)s).toUtf8())); m_hintingOptionsModel->appendRow(item); } } void FontAASettings::load() { double from, to; KXftConfig xft; if (xft.getExcludeRange(from, to)) { m_excludeFrom = from; m_excludeTo = to; - m_exclude = true; + setExclude(true); } else { m_excludeFrom = 8; m_excludeTo = 15; - m_exclude = false; + setExclude(false); } excludeToChanged(); excludeFromChanged(); KXftConfig::SubPixel::Type spType; - xft.getSubPixelType(spType); - m_subPixel = KXftConfig::description(spType); + + setSubPixelCurrentIndex(spType); KXftConfig::Hint::Style hStyle; if (!xft.getHintStyle(hStyle) || KXftConfig::Hint::NotSet == hStyle) { KConfig kglobals("kdeglobals", KConfig::NoGlobals); hStyle = KXftConfig::Hint::NotSet; xft.setHintStyle(hStyle); KConfigGroup(&kglobals, "General").writeEntry("XftHintStyle", KXftConfig::toStr(hStyle)); kglobals.sync(); runRdb(KRdbExportXftSettings | KRdbExportGtkTheme); - } else { - m_hinting = KXftConfig::description(hStyle); } + setHintingCurrentIndex(hStyle); + KConfig _cfgfonts("kcmfonts"); KConfigGroup cfgfonts(&_cfgfonts, "General"); int dpicfg; if (KWindowSystem::isPlatformWayland()) { dpicfg = cfgfonts.readEntry("forceFontDPIWayland", 0); } else { dpicfg = cfgfonts.readEntry("forceFontDPI", 0); } if (dpicfg <= 0) { m_dpiOriginal = 0; } else { m_dpiOriginal = dpicfg; }; setDpi(dpicfg); + KSharedConfig::Ptr config = KSharedConfig::openConfig("kdeglobals"); + KConfigGroup cg(config, "General"); + if (cfgfonts.readEntry("dontChangeAASettings", true)) { setAntiAliasing(1); //AASystem - } else if (xft.aliasingEnabled()) { + } else if (cg.readEntry("XftAntialias", true)) { setAntiAliasing(0); //AAEnabled } else { setAntiAliasing(2); //AADisabled } m_antiAliasingOriginal = m_antiAliasing; } bool FontAASettings::save(KXftConfig::AntiAliasing::State aaState) { KXftConfig xft; KConfig kglobals("kdeglobals", KConfig::NoGlobals); KConfigGroup grp(&kglobals, "General"); xft.setAntiAliasing(aaState); if (m_exclude) { xft.setExcludeRange(m_excludeFrom, m_excludeTo); } else { xft.setExcludeRange(0, 0); } - KXftConfig::SubPixel::Type spType(getSubPixelType()); + KXftConfig::SubPixel::Type spType = (KXftConfig::SubPixel::Type)m_subPixelCurrentIndex; xft.setSubPixelType(spType); grp.writeEntry("XftSubPixel", KXftConfig::toStr(spType)); - if (KXftConfig::AntiAliasing::NotSet == aaState) { + if (aaState == KXftConfig::AntiAliasing::NotSet) { grp.revertToDefault("XftAntialias"); } else { grp.writeEntry("XftAntialias", aaState == KXftConfig::AntiAliasing::Enabled); } bool mod = false; - KXftConfig::Hint::Style hStyle(getHintStyle()); + KXftConfig::Hint::Style hStyle = (KXftConfig::Hint::Style)m_hintingCurrentIndex; xft.setHintStyle(hStyle); QString hs(KXftConfig::toStr(hStyle)); if (hs != grp.readEntry("XftHintStyle")) { if (KXftConfig::Hint::NotSet == hStyle) { grp.revertToDefault("XftHintStyle"); } else { grp.writeEntry("XftHintStyle", hs); } } mod = true; kglobals.sync(); if (!mod) { mod = xft.changed(); } xft.apply(); KConfig _cfgfonts("kcmfonts"); KConfigGroup cfgfonts(&_cfgfonts, "General"); if (KWindowSystem::isPlatformWayland()) { cfgfonts.writeEntry("forceFontDPIWayland", m_dpi); } else { cfgfonts.writeEntry("forceFontDPI", m_dpi); } cfgfonts.sync(); #if HAVE_X11 // if the setting is reset in the module, remove the dpi value, // otherwise don't explicitly remove it and leave any possible system-wide value if (m_dpi == 0 && m_dpiOriginal != 0 && !KWindowSystem::isPlatformWayland()) { QProcess proc; proc.setProcessChannelMode(QProcess::ForwardedChannels); proc.start("xrdb", QStringList() << "-quiet" << "-remove" << "-nocpp"); if (proc.waitForStarted()) { proc.write(QByteArray("Xft.dpi\n")); proc.closeWriteChannel(); proc.waitForFinished(); } } #endif QApplication::processEvents(); // Process font change ourselves // Don't overwrite global settings unless explicitly asked for - e.g. the system // fontconfig setup may be much more complex than this module can provide. // TODO: With AASystem the changes already made by this module should be reverted somehow. #if defined(HAVE_FONTCONFIG) && defined (HAVE_X11) if (mod || (m_antiAliasing != m_antiAliasingOriginal) || m_dpi != m_dpiOriginal) { KMessageBox::information(0, i18n( "

Some changes such as anti-aliasing or DPI will only affect newly started applications.

" ), i18n("Font Settings Changed"), "FontSettingsChanged"); m_antiAliasingOriginal = m_antiAliasing; m_dpiOriginal = m_dpi; } #else #if HAVE_X11 if (m_dpi != m_dpiOriginal) { KMessageBox::information(0, i18n( "

Some changes such as DPI will only affect newly started applications.

" ), i18n("Font Settings Changed"), "FontSettingsChanged"); m_dpiOriginal = m_dpi; } #endif #endif return mod; } void FontAASettings::defaults() { setExcludeTo(15); setExcludeFrom(8); setAntiAliasing(1); m_antiAliasingOriginal = m_antiAliasing; setDpi(96); - setSubPixel(KXftConfig::description(KXftConfig::SubPixel::NotSet)); - setHinting(KXftConfig::description(KXftConfig::Hint::NotSet)); -} - -int FontAASettings::getIndexSubPixel(KXftConfig::SubPixel::Type spType) const -{ - int pos = -1; - int index; - - for (index = 0; index < m_subPixelOptionsModel->rowCount(); ++index) { - QStandardItem *item = m_subPixelOptionsModel->item(index); - if (item->text() == i18n(KXftConfig::description(spType).toUtf8())) { - pos = index; - break; - } - } - - return pos; -} - -KXftConfig::SubPixel::Type FontAASettings::getSubPixelType() -{ - int t; - - for (t = KXftConfig::SubPixel::NotSet; t <= KXftConfig::SubPixel::Vbgr; ++t){ - if (m_subPixel == i18n(KXftConfig::description((KXftConfig::SubPixel::Type)t).toUtf8())) { - return (KXftConfig::SubPixel::Type)t; - } - } - return KXftConfig::SubPixel::NotSet; -} - -int FontAASettings::getIndexHint(KXftConfig::Hint::Style hStyle) const -{ - int pos = -1; - int index; - - for (index = 0; index < m_hintingOptionsModel->rowCount(); ++index) { - QStandardItem *item = m_hintingOptionsModel->item(index); - if (item->text() == i18n(KXftConfig::description(hStyle).toUtf8())) { - pos = index; - break; - } - } - - return pos; -} - -KXftConfig::Hint::Style FontAASettings::getHintStyle() -{ - int s; - - for (s = KXftConfig::Hint::NotSet; s <= KXftConfig::Hint::Full; ++s){ - if (m_hinting == i18n(KXftConfig::description((KXftConfig::Hint::Style)s).toUtf8())) { - return (KXftConfig::Hint::Style)s; - } - } - - return KXftConfig::Hint::Medium; + setSubPixelCurrentIndex(KXftConfig::SubPixel::NotSet); + setHintingCurrentIndex(KXftConfig::Hint::NotSet); } #endif -void FontAASettings::setSubPixel(const QString &subPixel) -{ - - if (m_subPixel == subPixel) { - return; - } - - m_subPixel = subPixel; - emit subPixelChanged(); -} - -QString FontAASettings::subPixel() const -{ - return m_subPixel; -} - -void FontAASettings::setHinting(const QString &hinting) -{ - if (m_hinting == hinting) { - return; - } - - m_hinting = hinting; - emit hintingChanged(); -} - -QString FontAASettings::hinting() const -{ - return m_hinting; -} - void FontAASettings::setExclude(bool exclude) { if (exclude == m_exclude) { return; } m_exclude = exclude; emit excludeChanged(); } bool FontAASettings::exclude() const { return m_exclude; } void FontAASettings::setExcludeTo(const int &excludeTo) { if (m_excludeTo == excludeTo) { return; } m_excludeTo = excludeTo; emit excludeToChanged(); } int FontAASettings::excludeTo() const { return m_excludeTo; } void FontAASettings::setExcludeFrom(const int &excludeTo) { if (m_excludeFrom == excludeTo) { return; } m_excludeFrom = excludeTo; emit excludeToChanged(); } int FontAASettings::excludeFrom() const { return m_excludeFrom; } void FontAASettings::setAntiAliasing(const int &antiAliasing) { if (m_antiAliasing == antiAliasing) { return; } m_antiAliasing = antiAliasing; emit aliasingChanged(); } int FontAASettings::antiAliasing() const { return m_antiAliasing; } void FontAASettings::setDpi(const int &dpi) { if (m_dpi == dpi) { return; } m_dpi = dpi; emit dpiChanged(); } int FontAASettings::dpi() const { return m_dpi; } +void FontAASettings::setSubPixelCurrentIndex(int idx) +{ + if (m_subPixelCurrentIndex == idx) { + return; + } + + m_subPixelCurrentIndex = idx; + emit subPixelCurrentIndexChanged(); +} + int FontAASettings::subPixelCurrentIndex() { - return getSubPixelType(); + return m_subPixelCurrentIndex; +} + +void FontAASettings::setHintingCurrentIndex(int idx) +{ + if (m_hintingCurrentIndex == idx) { + return; + } + + m_hintingCurrentIndex = idx; + emit hintingCurrentIndexChanged(); } int FontAASettings::hintingCurrentIndex() { - return getHintStyle(); + return m_hintingCurrentIndex; } /**** KFonts ****/ KFonts::KFonts(QObject *parent, const QVariantList &args) : KQuickAddons::ConfigModule(parent, args) , m_fontAASettings(new FontAASettings(this)) { qApp->setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); KAboutData* about = new KAboutData("kcm_fonts", i18n("Configure Fonts"), "0.1", QString(), KAboutLicense::LGPL); about->addAuthor(i18n("Antonis Tsiapaliokas"), QString(), "antonis.tsiapaliokas@kde.org"); setAboutData(about); qmlRegisterType(); setButtons(Apply | Default); auto updateState = [this]() { setNeedsSave(true); }; - connect(m_fontAASettings, &FontAASettings::subPixelChanged, this, updateState); - connect(m_fontAASettings, &FontAASettings::hintingChanged, this, updateState); + connect(m_fontAASettings, &FontAASettings::subPixelCurrentIndexChanged, this, updateState); + connect(m_fontAASettings, &FontAASettings::hintingCurrentIndexChanged, this, updateState); connect(m_fontAASettings, &FontAASettings::excludeToChanged, this, updateState); connect(m_fontAASettings, &FontAASettings::antiAliasingChanged, this, updateState); connect(m_fontAASettings, &FontAASettings::aliasingChanged, this, updateState); connect(m_fontAASettings, &FontAASettings::dpiChanged, this, updateState); } KFonts::~KFonts() { } void KFonts::defaults() { #ifdef Q_OS_MAC setGeneralFont(QFont("Lucida Grande", 13)); setMenuFont(QFont("Lucida Grande", 13)); setFixedWidthFont(QFont("Monaco", 10)); setToolbarFont(QFont("Lucida Grande", 11)); setSmallFont(QFont("Lucida Grande", 9)); setWindowTitleFont(QFont("Lucida Grande", 14)); #else setGeneralFont(QFont("Noto Sans", 10)); setMenuFont(QFont("Noto Sans", 10)); setFixedWidthFont(QFont("Hack", 9)); setToolbarFont(QFont("Noto Sans", 10)); setSmallFont(QFont("Noto Sans", 8)); setWindowTitleFont(QFont("Noto Sans", 10)); #endif m_fontAASettings->defaults(); } void KFonts::load() { KSharedConfig::Ptr config = KSharedConfig::openConfig("kdeglobals"); KConfigGroup cg(config, "General"); QFont font; font = nearestExistingFont(cg.readEntry("font", m_defaultFont)); setGeneralFont(font); font = nearestExistingFont(cg.readEntry("fixed", m_defaultFont)); setFixedWidthFont(font); font = nearestExistingFont(cg.readEntry("smallestReadableFont", m_defaultFont)); setSmallFont(font); font = nearestExistingFont(cg.readEntry("toolBarFont", m_defaultFont)); setToolbarFont(font); font = nearestExistingFont(cg.readEntry("menuFont", m_defaultFont)); setMenuFont(font); cg = KConfigGroup(config, "WM"); font = nearestExistingFont(cg.readEntry("activeFont", m_defaultFont)); setWindowTitleFont(font); m_fontAASettings->load(); setNeedsSave(false); } void KFonts::save() { KSharedConfig::Ptr config = KSharedConfig::openConfig("kdeglobals"); KConfigGroup cg(config, "General"); cg.writeEntry("font", m_generalFont.toString()); cg.writeEntry("fixed", m_fixedWidthFont.toString()); cg.writeEntry("smallestReadableFont", m_smallFont.toString()); cg.writeEntry("toolBarFont", m_toolbarFont.toString()); cg.writeEntry("menuFont", m_menuFont.toString()); cg.sync(); cg = KConfigGroup(config, "WM"); cg.writeEntry("activeFont", m_windowTitleFont.toString()); cg.sync(); KConfig _cfgfonts("kcmfonts"); KConfigGroup cfgfonts(&_cfgfonts, "General"); FontAASettings::AASetting aaSetting = (FontAASettings::AASetting)m_fontAASettings->antiAliasing(); cfgfonts.writeEntry("dontChangeAASettings", aaSetting == FontAASettings::AASystem); if (aaSetting == FontAASettings::AAEnabled) { m_fontAASettings->save(KXftConfig::AntiAliasing::Enabled); } else if (aaSetting == FontAASettings::AADisabled) { m_fontAASettings->save(KXftConfig::AntiAliasing::Disabled); } else { m_fontAASettings->save(KXftConfig::AntiAliasing::NotSet); } KGlobalSettings::self()->emitChange(KGlobalSettings::FontChanged); runRdb(KRdbExportXftSettings | KRdbExportGtkTheme); emit fontsHaveChanged(); setNeedsSave(false); } void KFonts::setGeneralFont(const QFont &font) { if (m_generalFont == font) { return; } m_generalFont = font; emit generalFontChanged(); setNeedsSave(true); } QFont KFonts::generalFont() const { return m_generalFont; } void KFonts::setFixedWidthFont(const QFont &font) { if (m_fixedWidthFont == font) { return; } m_fixedWidthFont = font; emit fixedWidthFontChanged(); setNeedsSave(true); } QFont KFonts::fixedWidthFont() const { return m_fixedWidthFont; } void KFonts::setSmallFont(const QFont &font) { if (m_smallFont == font) { return; } m_smallFont = font; emit smallFontChanged(); setNeedsSave(true); } QFont KFonts::smallFont() const { return m_smallFont; } void KFonts::setToolbarFont(const QFont &font) { if (m_toolbarFont == font) { return; } m_toolbarFont = font; emit toolbarFontChanged(); setNeedsSave(true); } QFont KFonts::toolbarFont() const { return m_toolbarFont; } void KFonts::setMenuFont(const QFont &font) { if (m_menuFont == font) { return; } m_menuFont = font; emit menuFontChanged(); setNeedsSave(true); } QFont KFonts::menuFont() const { return m_menuFont; } void KFonts::setWindowTitleFont(const QFont &font) { if (m_windowTitleFont == font) { return; } m_windowTitleFont = font; emit windowTitleFontChanged(); setNeedsSave(true); } QFont KFonts::windowTitleFont() const { return m_windowTitleFont; } void KFonts::adjustAllFonts() { QFont font = m_generalFont; KFontChooser::FontDiffFlags fontDiffFlags = 0; int ret = KFontDialog::getFontDiff(font, fontDiffFlags, KFontChooser::NoDisplayFlags); if (ret == KDialog::Accepted && fontDiffFlags) { setGeneralFont(applyFontDiff(m_generalFont, font, fontDiffFlags)); setMenuFont(applyFontDiff(m_menuFont, font, fontDiffFlags)); { const QFont adjustedFont = applyFontDiff(m_fixedWidthFont, font, fontDiffFlags); if (QFontInfo(adjustedFont).fixedPitch()) { setFixedWidthFont(adjustedFont); } } setToolbarFont(applyFontDiff(m_toolbarFont, font, fontDiffFlags)); setSmallFont(applyFontDiff(m_smallFont, font, fontDiffFlags)); setWindowTitleFont(applyFontDiff(m_windowTitleFont, font, fontDiffFlags)); } } QFont KFonts::applyFontDiff(const QFont &fnt, const QFont &newFont, int fontDiffFlags) { QFont font(fnt); if (fontDiffFlags & KFontChooser::FontDiffSize) { font.setPointSizeF(newFont.pointSizeF()); } if ((fontDiffFlags & KFontChooser::FontDiffFamily)) { font.setFamily(newFont.family()); } if (fontDiffFlags & KFontChooser::FontDiffStyle) { font.setWeight(newFont.weight()); font.setStyle(newFont.style()); font.setUnderline(newFont.underline()); font.setStyleName(newFont.styleName()); } return font; } #include "fonts.moc" diff --git a/kcms/fonts/fonts.h b/kcms/fonts/fonts.h index 79c90bb30..d770b4375 100644 --- a/kcms/fonts/fonts.h +++ b/kcms/fonts/fonts.h @@ -1,188 +1,181 @@ /* Copyright 1997 Mark Donohoe Copyright 1999 Lars Knoll Copyright 2000 Rik Hemsley Copyright 2015 Antonis Tsiapaliokas Copyright 2017 Marco Martin Ported to kcontrol2 by Geert Jansen. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef FONTS_H #define FONTS_H #include #include #include #include #include "kxftconfig.h" class FontAASettings : public QObject { Q_OBJECT Q_PROPERTY(QAbstractItemModel *subPixelOptionsModel READ subPixelOptionsModel CONSTANT) + Q_PROPERTY(int subPixelCurrentIndex READ subPixelCurrentIndex WRITE setSubPixelCurrentIndex NOTIFY subPixelCurrentIndexChanged); Q_PROPERTY(QAbstractItemModel *hintingOptionsModel READ hintingOptionsModel CONSTANT) - Q_PROPERTY(QString subPixel READ subPixel WRITE setSubPixel NOTIFY subPixelChanged) - Q_PROPERTY(QString hinting READ hinting WRITE setHinting NOTIFY hintingChanged) + Q_PROPERTY(int hintingCurrentIndex READ hintingCurrentIndex WRITE setHintingCurrentIndex NOTIFY hintingCurrentIndexChanged); + Q_PROPERTY(bool exclude READ exclude WRITE setExclude NOTIFY excludeChanged) Q_PROPERTY(int excludeTo READ excludeTo WRITE setExcludeTo NOTIFY excludeToChanged) Q_PROPERTY(int excludeFrom READ excludeFrom WRITE setExcludeFrom NOTIFY excludeFromChanged) Q_PROPERTY(int antiAliasing READ antiAliasing WRITE setAntiAliasing NOTIFY aliasingChanged) Q_PROPERTY(int dpi READ dpi WRITE setDpi NOTIFY dpiChanged) public: enum AASetting { AAEnabled, AASystem, AADisabled }; #if defined(HAVE_FONTCONFIG) && defined (HAVE_X11) FontAASettings(QObject *parent); bool save(KXftConfig::AntiAliasing::State aaState); void load(); void defaults(); - int getIndexSubPixel(KXftConfig::SubPixel::Type spType) const; - KXftConfig::SubPixel::Type getSubPixelType(); - int getIndexHint(KXftConfig::Hint::Style hStyle) const; - KXftConfig::Hint::Style getHintStyle(); void setAntiAliasingState(KXftConfig::AntiAliasing::State aaState); QAbstractItemModel* subPixelOptionsModel() { return m_subPixelOptionsModel; } QAbstractItemModel* hintingOptionsModel() { return m_hintingOptionsModel; } - void setSubPixel(const QString &subPixel); - QString subPixel() const; - - void setHinting(const QString &hinting); - QString hinting() const; - void setExclude(bool exclude); bool exclude() const; void setExcludeTo(const int &excludeTo); int excludeTo() const; void setExcludeFrom(const int &excludeTo); int excludeFrom() const; void setAntiAliasing(const int& antiAliasing); int antiAliasing() const; void setDpi(const int &dpi); int dpi() const; - Q_INVOKABLE int subPixelCurrentIndex(); - Q_INVOKABLE int hintingCurrentIndex(); + int subPixelCurrentIndex(); + void setSubPixelCurrentIndex(int idx); + int hintingCurrentIndex(); + void setHintingCurrentIndex(int idx); #endif Q_SIGNALS: - void subPixelChanged(); - void hintingChanged(); void excludeChanged(); void excludeToChanged(); void excludeFromChanged(); void antiAliasingChanged(); void aliasingChanged(); void dpiChanged(); + void subPixelCurrentIndexChanged(); + void hintingCurrentIndexChanged(); #if defined(HAVE_FONTCONFIG) && defined (HAVE_X11) private: - QString m_subPixel; - QString m_hinting; int m_excludeTo; int m_excludeFrom; int m_antiAliasing; int m_antiAliasingOriginal; int m_dpi; int m_dpiOriginal; + int m_subPixelCurrentIndex = 0; + int m_hintingCurrentIndex = 0; QStandardItemModel *m_subPixelOptionsModel; QStandardItemModel *m_hintingOptionsModel; bool m_exclude = false; #endif }; /** * The Desktop/fonts tab in kcontrol. */ class KFonts : public KQuickAddons::ConfigModule { Q_OBJECT Q_PROPERTY(QFont generalFont READ generalFont WRITE setGeneralFont NOTIFY generalFontChanged) Q_PROPERTY(QFont fixedWidthFont READ fixedWidthFont WRITE setFixedWidthFont NOTIFY fixedWidthFontChanged) Q_PROPERTY(QFont smallFont READ smallFont WRITE setSmallFont NOTIFY smallFontChanged) Q_PROPERTY(QFont toolbarFont READ toolbarFont WRITE setToolbarFont NOTIFY toolbarFontChanged) Q_PROPERTY(QFont menuFont READ menuFont WRITE setMenuFont NOTIFY menuFontChanged) Q_PROPERTY(QFont windowTitleFont READ windowTitleFont WRITE setWindowTitleFont NOTIFY windowTitleFontChanged) Q_PROPERTY(QObject *fontAASettings READ fontAASettings CONSTANT) public: KFonts(QObject *parent, const QVariantList &); ~KFonts(); void setGeneralFont(const QFont &font); QFont generalFont() const; void setFixedWidthFont(const QFont &font); QFont fixedWidthFont() const; void setSmallFont(const QFont &font); QFont smallFont() const; void setToolbarFont(const QFont &font); QFont toolbarFont() const; void setMenuFont(const QFont &font); QFont menuFont() const; void setWindowTitleFont(const QFont &font); QFont windowTitleFont() const; QObject* fontAASettings() { return m_fontAASettings; } public Q_SLOTS: void load(); void save(); void defaults(); Q_INVOKABLE void adjustAllFonts(); Q_SIGNALS: void fontsHaveChanged(); void generalFontChanged(); void fixedWidthFontChanged(); void smallFontChanged(); void toolbarFontChanged(); void menuFontChanged(); void windowTitleFontChanged(); private: QFont applyFontDiff(const QFont &fnt, const QFont &newFont, int fontDiffFlags); QFont m_defaultFont; QFont m_generalFont; QFont m_fixedWidthFont; QFont m_smallFont; QFont m_toolbarFont; QFont m_menuFont; QFont m_windowTitleFont; FontAASettings *m_fontAASettings; }; #endif diff --git a/kcms/fonts/kxftconfig.cpp b/kcms/fonts/kxftconfig.cpp index 2cc3a1bb0..6bdeab84f 100644 --- a/kcms/fonts/kxftconfig.cpp +++ b/kcms/fonts/kxftconfig.cpp @@ -1,835 +1,837 @@ /* Copyright (c) 2002 Craig Drummond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kxftconfig.h" #ifdef HAVE_FONTCONFIG #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; static int point2Pixel(double point) { return (int)(((point * QX11Info::appDpiY()) / 72.0) + 0.5); } static int pixel2Point(double pixel) { return (int)(((pixel * 72.0) / (double)QX11Info::appDpiY()) + 0.5); } static bool equal(double d1, double d2) { return (fabs(d1 - d2) < 0.0001); } static QString dirSyntax(const QString &d) { if (!d.isNull()) { QString ds(d); ds.replace("//", "/"); int slashPos = ds.lastIndexOf('/'); if (slashPos != (((int)ds.length()) - 1)) { ds.append('/'); } return ds; } return d; } static bool check(const QString &path, unsigned int fmt, bool checkW = false) { KDE_struct_stat info; QByteArray pathC(QFile::encodeName(path)); return 0 == KDE_lstat(pathC, &info) && (info.st_mode & S_IFMT) == fmt && (!checkW || 0 ==::access(pathC, W_OK)); } inline bool fExists(const QString &p) { return check(p, S_IFREG, false); } inline bool dWritable(const QString &p) { return check(p, S_IFDIR, true); } static QString getDir(const QString &f) { QString d(f); int slashPos = d.lastIndexOf('/'); if (-1 != slashPos) { d.remove(slashPos + 1, d.length()); } return dirSyntax(d); } static time_t getTimeStamp(const QString &item) { KDE_struct_stat info; return !item.isNull() && 0 == KDE_lstat(QFile::encodeName(item), &info) ? info.st_mtime : 0; } // // Obtain location of config file to use. QString getConfigFile() { FcStrList *list = FcConfigGetConfigFiles(FcConfigGetCurrent()); QStringList files; FcChar8 *file; QString home(dirSyntax(QDir::homePath())); while ((file = FcStrListNext(list))) { QString f((const char *)file); if (fExists(f) && 0 == f.indexOf(home)) { files.append(f); } } FcStrListDone(list); // // Go through list of files, looking for the preferred one... if (files.count()) { QStringList::const_iterator it(files.begin()), end(files.end()); for (; it != end; ++it) if (-1 != (*it).indexOf(QRegExp("/\\.?fonts\\.conf$"))) { return *it; } return files.front(); // Just return the 1st one... } else { // Hmmm... no known files? if (FcGetVersion() >= 21000) { QString targetPath(KGlobal::dirs()->localxdgconfdir() + "fontconfig"); QDir target(targetPath); if (!target.exists()) { target.mkpath(targetPath); } return targetPath + "/fonts.conf"; } else { return home + "/.fonts.conf"; } } } static QString getEntry(QDomElement element, const char *type, unsigned int numAttributes, ...) { if (numAttributes == element.attributes().length()) { va_list args; unsigned int arg; bool ok = true; va_start(args, numAttributes); for (arg = 0; arg < numAttributes && ok; ++arg) { const char *attr = va_arg(args, const char *); const char *val = va_arg(args, const char *); if (!attr || !val || val != element.attribute(attr)) { ok = false; } } va_end(args); if (ok) { QDomNode n = element.firstChild(); if (!n.isNull()) { QDomElement e = n.toElement(); if (!e.isNull() && type == e.tagName()) { return e.text(); } } } } return QString(); } static KXftConfig::SubPixel::Type strToType(const char *str) { if (0 == strcmp(str, "rgb")) { return KXftConfig::SubPixel::Rgb; } else if (0 == strcmp(str, "bgr")) { return KXftConfig::SubPixel::Bgr; } else if (0 == strcmp(str, "vrgb")) { return KXftConfig::SubPixel::Vrgb; } else if (0 == strcmp(str, "vbgr")) { return KXftConfig::SubPixel::Vbgr; } else if (0 == strcmp(str, "none")) { return KXftConfig::SubPixel::None; } else { return KXftConfig::SubPixel::NotSet; } } static KXftConfig::Hint::Style strToStyle(const char *str) { if (0 == strcmp(str, "hintslight")) { return KXftConfig::Hint::Slight; } else if (0 == strcmp(str, "hintmedium")) { return KXftConfig::Hint::Medium; } else if (0 == strcmp(str, "hintfull")) { return KXftConfig::Hint::Full; } else { return KXftConfig::Hint::None; } } KXftConfig::KXftConfig() : m_doc("fontconfig") , m_file(getConfigFile()) { kDebug(1208) << "Using fontconfig file:" << m_file; reset(); } KXftConfig::~KXftConfig() { } bool KXftConfig::reset() { bool ok = false; m_madeChanges = false; m_hint.reset(); m_hinting.reset(); m_excludeRange.reset(); m_excludePixelRange.reset(); m_subPixel.reset(); m_antiAliasing.reset(); QFile f(m_file); if (f.open(QIODevice::ReadOnly)) { m_time = getTimeStamp(m_file); ok = true; m_doc.clear(); if (m_doc.setContent(&f)) { readContents(); } f.close(); } else { ok = !fExists(m_file) && dWritable(getDir(m_file)); } if (m_doc.documentElement().isNull()) { m_doc.appendChild(m_doc.createElement("fontconfig")); } if (ok) { // // Check exclude range values - i.e. size and pixel size... // If "size" range is set, ensure "pixelsize" matches... if (!equal(0, m_excludeRange.from) || !equal(0, m_excludeRange.to)) { double pFrom = (double)point2Pixel(m_excludeRange.from), pTo = (double)point2Pixel(m_excludeRange.to); if (!equal(pFrom, m_excludePixelRange.from) || !equal(pTo, m_excludePixelRange.to)) { m_excludePixelRange.from = pFrom; m_excludePixelRange.to = pTo; m_madeChanges = true; } } else if (!equal(0, m_excludePixelRange.from) || !equal(0, m_excludePixelRange.to)) { // "pixelsize" set, but not "size" !!! m_excludeRange.from = (int)pixel2Point(m_excludePixelRange.from); m_excludeRange.to = (int)pixel2Point(m_excludePixelRange.to); m_madeChanges = true; } } return ok; } bool KXftConfig::apply() { bool ok = true; if (m_madeChanges) { // // Check if file has been written since we last read it. If it has, then re-read and add any // of our changes... if (fExists(m_file) && getTimeStamp(m_file) != m_time) { KXftConfig newConfig; newConfig.setExcludeRange(m_excludeRange.from, m_excludeRange.to); newConfig.setSubPixelType(m_subPixel.type); newConfig.setHintStyle(m_hint.style); newConfig.setAntiAliasing(m_antiAliasing.state); ok = newConfig.changed() ? newConfig.apply() : true; if (ok) { reset(); } else { m_time = getTimeStamp(m_file); } } else { // Ensure these are always equal... m_excludePixelRange.from = (int)point2Pixel(m_excludeRange.from); m_excludePixelRange.to = (int)point2Pixel(m_excludeRange.to); FcAtomic *atomic = FcAtomicCreate((const unsigned char *)(QFile::encodeName(m_file).data())); ok = false; if (atomic) { if (FcAtomicLock(atomic)) { FILE *f = fopen((char *)FcAtomicNewFile(atomic), "w"); if (f) { applySubPixelType(); applyHintStyle(); applyAntiAliasing(); applyExcludeRange(false); applyExcludeRange(true); // // Check document syntax... static const char qtXmlHeader[] = ""; static const char xmlHeader[] = ""; static const char qtDocTypeLine[] = ""; static const char docTypeLine[] = ""; QString str(m_doc.toString()); int idx; if (0 != str.indexOf("= 0 || to >= 0) && foundFalse) { m_excludeRange.from = from < to ? from : to; m_excludeRange.to = from < to ? to : from; m_excludeRange.node = n; } else if ((pixelFrom >= 0 || pixelTo >= 0) && foundFalse) { m_excludePixelRange.from = pixelFrom < pixelTo ? pixelFrom : pixelTo; m_excludePixelRange.to = pixelFrom < pixelTo ? pixelTo : pixelFrom; m_excludePixelRange.node = n; } } break; default: break; } } } n = n.nextSibling(); } } void KXftConfig::applySubPixelType() { if (SubPixel::NotSet == m_subPixel.type) { if (!m_subPixel.node.isNull()) { m_doc.documentElement().removeChild(m_subPixel.node); m_subPixel.node.clear(); } } else { QDomElement matchNode = m_doc.createElement("match"); QDomElement typeNode = m_doc.createElement("const"); QDomElement editNode = m_doc.createElement("edit"); QDomText typeText = m_doc.createTextNode(toStr(m_subPixel.type)); matchNode.setAttribute("target", "font"); editNode.setAttribute("mode", "assign"); editNode.setAttribute("name", "rgba"); editNode.appendChild(typeNode); typeNode.appendChild(typeText); matchNode.appendChild(editNode); if (m_subPixel.node.isNull()) { m_doc.documentElement().appendChild(matchNode); } else { m_doc.documentElement().replaceChild(matchNode, m_subPixel.node); } m_subPixel.node = matchNode; } } void KXftConfig::applyHintStyle() { applyHinting(); if (Hint::NotSet == m_hint.style) { if (!m_hint.node.isNull()) { m_doc.documentElement().removeChild(m_hint.node); m_hint.node.clear(); } if (!m_hinting.node.isNull()) { m_doc.documentElement().removeChild(m_hinting.node); m_hinting.node.clear(); } } else { QDomElement matchNode = m_doc.createElement("match"), typeNode = m_doc.createElement("const"), editNode = m_doc.createElement("edit"); QDomText typeText = m_doc.createTextNode(toStr(m_hint.style)); matchNode.setAttribute("target", "font"); editNode.setAttribute("mode", "assign"); editNode.setAttribute("name", "hintstyle"); editNode.appendChild(typeNode); typeNode.appendChild(typeText); matchNode.appendChild(editNode); if (m_hint.node.isNull()) { m_doc.documentElement().appendChild(matchNode); } else { m_doc.documentElement().replaceChild(matchNode, m_hint.node); } m_hint.node = matchNode; } } void KXftConfig::applyHinting() { QDomElement matchNode = m_doc.createElement("match"), typeNode = m_doc.createElement("bool"), editNode = m_doc.createElement("edit"); QDomText typeText = m_doc.createTextNode(m_hinting.set ? "true" : "false"); matchNode.setAttribute("target", "font"); editNode.setAttribute("mode", "assign"); editNode.setAttribute("name", "hinting"); editNode.appendChild(typeNode); typeNode.appendChild(typeText); matchNode.appendChild(editNode); if (m_hinting.node.isNull()) { m_doc.documentElement().appendChild(matchNode); } else { m_doc.documentElement().replaceChild(matchNode, m_hinting.node); } m_hinting.node = matchNode; } void KXftConfig::applyExcludeRange(bool pixel) { Exclude &range = pixel ? m_excludePixelRange : m_excludeRange; if (equal(range.from, 0) && equal(range.to, 0)) { if (!range.node.isNull()) { m_doc.documentElement().removeChild(range.node); range.node.clear(); } } else { QString fromString, toString; fromString.setNum(range.from); toString.setNum(range.to); QDomElement matchNode = m_doc.createElement("match"), fromTestNode = m_doc.createElement("test"), fromNode = m_doc.createElement("double"), toTestNode = m_doc.createElement("test"), toNode = m_doc.createElement("double"), editNode = m_doc.createElement("edit"), boolNode = m_doc.createElement("bool"); QDomText fromText = m_doc.createTextNode(fromString), toText = m_doc.createTextNode(toString), boolText = m_doc.createTextNode("false"); matchNode.setAttribute("target", "font"); // CPD: Is target "font" or "pattern" ???? fromTestNode.setAttribute("qual", "any"); fromTestNode.setAttribute("name", pixel ? "pixelsize" : "size"); fromTestNode.setAttribute("compare", "more_eq"); fromTestNode.appendChild(fromNode); fromNode.appendChild(fromText); toTestNode.setAttribute("qual", "any"); toTestNode.setAttribute("name", pixel ? "pixelsize" : "size"); toTestNode.setAttribute("compare", "less_eq"); toTestNode.appendChild(toNode); toNode.appendChild(toText); editNode.setAttribute("mode", "assign"); editNode.setAttribute("name", "antialias"); editNode.appendChild(boolNode); boolNode.appendChild(boolText); matchNode.appendChild(fromTestNode); matchNode.appendChild(toTestNode); matchNode.appendChild(editNode); if (!m_antiAliasing.node.isNull()) { m_doc.documentElement().removeChild(range.node); } m_doc.documentElement().appendChild(matchNode); range.node = matchNode; } } KXftConfig::AntiAliasing::State KXftConfig::getAntiAliasing() const { return m_antiAliasing.state; } void KXftConfig::setAntiAliasing(AntiAliasing::State state) { if (state != m_antiAliasing.state) { m_antiAliasing.state = state; m_madeChanges = true; } } void KXftConfig::applyAntiAliasing() { if (AntiAliasing::NotSet == m_antiAliasing.state) { if (!m_antiAliasing.node.isNull()) { m_doc.documentElement().removeChild(m_antiAliasing.node); m_antiAliasing.node.clear(); } } else { QDomElement matchNode = m_doc.createElement("match"); QDomElement typeNode = m_doc.createElement("bool"); QDomElement editNode = m_doc.createElement("edit"); QDomText typeText = m_doc.createTextNode(m_antiAliasing.state == AntiAliasing::Enabled ? "true" : "false"); matchNode.setAttribute("target", "font"); editNode.setAttribute("mode", "assign"); editNode.setAttribute("name", "antialias"); editNode.appendChild(typeNode); typeNode.appendChild(typeText); matchNode.appendChild(editNode); if (!m_antiAliasing.node.isNull()) { m_doc.documentElement().removeChild(m_antiAliasing.node); } m_doc.documentElement().appendChild(matchNode); m_antiAliasing.node = matchNode; } } // KXftConfig only parses one config file, user's .fonts.conf usually. // If that one doesn't exist, then KXftConfig doesn't know if antialiasing // is enabled or not. So try to find out the default value from the default font. // Maybe there's a better way *shrug*. bool KXftConfig::aliasingEnabled() { FcPattern *pattern = FcPatternCreate(); FcConfigSubstitute(0, pattern, FcMatchPattern); FcDefaultSubstitute(pattern); FcResult result; FcPattern *f = FcFontMatch(0, pattern, &result); FcBool antialiased = FcTrue; FcPatternGetBool(f, FC_ANTIALIAS, 0, &antialiased); FcPatternDestroy(f); FcPatternDestroy(pattern); return antialiased == FcTrue; } #endif diff --git a/kcms/fonts/package/contents/ui/main.qml b/kcms/fonts/package/contents/ui/main.qml index b997e1f84..61b306810 100644 --- a/kcms/fonts/package/contents/ui/main.qml +++ b/kcms/fonts/package/contents/ui/main.qml @@ -1,194 +1,196 @@ /* Copyright (c) 2015 Antonis Tsiapaliokas Copyright (c) 2017 Marco Martin This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.1 import QtQuick.Layouts 1.1 import QtQuick.Controls 2.0 as QtControls import QtQuick.Dialogs 1.2 as QtDialogs import org.kde.kirigami 2.3 as Kirigami import org.kde.kcm 1.0 Kirigami.ScrollablePage { id: root ConfigModule.quickHelp: i18n("Fonts") Kirigami.FormLayout { id: formLayout readonly property int maxImplicitWidth: Math.max(adjustAllFontsButton.implicitWidth, Math.max(antiAliasingComboBox.implicitWidth, Math.max(excludeField.implicitWidth, Math.max(subPixelCombo.implicitWidth, hintingCombo.implicitWidth)))) QtControls.Button { id: adjustAllFontsButton Layout.preferredWidth: formLayout.maxImplicitWidth text: i18n("&Adjust All Fonts...") onClicked: kcm.adjustAllFonts(); } FontWidget { label: i18n("General:") category: "generalFont" font: kcm.generalFont } FontWidget { label: i18n("Fixed width:") category: "fixedWidthFont" font: kcm.fixedWidthFont } FontWidget { label: i18n("Small:") category: "smallFont" font: kcm.smallFont } FontWidget { label: i18n("Toolbar:") category: "toolbarFont" font: kcm.toolbarFont } FontWidget { label: i18n("Menu:") category: "menuFont" font: kcm.menuFont } FontWidget { label: i18n("Window title:") category: "windowTitleFont" font: kcm.windowTitleFont } Kirigami.Separator { Kirigami.FormData.isSection: true } QtControls.ComboBox { id: antiAliasingComboBox Layout.preferredWidth: formLayout.maxImplicitWidth Kirigami.FormData.label: i18n("Use anti-aliasing:") model: [i18n("Enabled"), i18n("System Settings"), i18n("Disabled")] currentIndex: kcm.fontAASettings.antiAliasing onCurrentIndexChanged: kcm.fontAASettings.antiAliasing = antiAliasingComboBox.currentIndex } QtControls.CheckBox { id: excludeCheckBox checked: kcm.fontAASettings.exclude onCheckedChanged: kcm.fontAASettings.exclude = checked; text: i18n("Exclude range from anti-aliasing") Layout.fillWidth: true enabled: antiAliasingComboBox.currentIndex == 0 } RowLayout { id: excludeField Layout.preferredWidth: formLayout.maxImplicitWidth enabled: antiAliasingComboBox.currentIndex == 0 QtControls.SpinBox { id: excludeFromSpinBox stepSize: 1 onValueChanged: kcm.fontAASettings.excludeFrom = value textFromValue: function(value, locale) { return i18n("%1 pt", value)} enabled: excludeCheckBox.checked } QtControls.Label { Layout.fillWidth: true horizontalAlignment: Text.AlignHCenter text: i18n("to") } QtControls.SpinBox { id: excludeToSpinBox stepSize: 1 onValueChanged: kcm.fontAASettings.excludeTo = value textFromValue: function(value, locale) { return i18n("%1 pt", value)} enabled: excludeCheckBox.checked } Connections { target: kcm.fontAASettings onExcludeFromChanged: excludeFromSpinBox.value = kcm.fontAASettings.excludeFrom; onExcludeToChanged: excludeToSpinBox.value = kcm.fontAASettings.excludeTo; } } QtControls.ComboBox { id: subPixelCombo Layout.preferredWidth: formLayout.maxImplicitWidth Kirigami.FormData.label: i18n("Sub-pixel rendering type:") - currentIndex: kcm.fontAASettings.subPixelCurrentIndex() + currentIndex: kcm.fontAASettings.subPixelCurrentIndex + onCurrentIndexChanged: kcm.fontAASettings.subPixelCurrentIndex = currentIndex; model: kcm.fontAASettings.subPixelOptionsModel textRole: "display" enabled: antiAliasingComboBox.currentIndex == 0 } QtControls.ComboBox { id: hintingCombo Layout.preferredWidth: formLayout.maxImplicitWidth Kirigami.FormData.label: i18n("Hinting style:") - currentIndex: kcm.fontAASettings.hintingCurrentIndex() + currentIndex: kcm.fontAASettings.hintingCurrentIndex + onCurrentTextChanged: kcm.fontAASettings.hintingCurrentIndex = currentIndex; model: kcm.fontAASettings.hintingOptionsModel textRole: "display" enabled: antiAliasingComboBox.currentIndex == 0 } RowLayout { QtControls.CheckBox { id: dpiCheckBox checked: dpiSpinBox.value != 96 text: i18n("Force Fonts DPI:") onCheckedChanged: { if (!dpiCheckBox.checked) { dpiSpinBox.enabled = false; kcm.fontAASettings.dpi = 0; } else { dpiSpinBox.enabled = true; } } } QtControls.SpinBox { id: dpiSpinBox stepSize: 24 enabled: dpiCheckBox.checked value: kcm.fontAASettings.dpi onValueChanged: kcm.fontAASettings.dpi = dpiSpinBox.value to: 1000 from: 96 } } } QtDialogs.FontDialog { id: fontDialog title: "Choose a font" property string currentCategory property bool adjustAllFonts: false onAccepted: { if (adjustAllFonts) { kcm.adjustAllFonts(font); } else { kcm[currentCategory] = font; } } } }