diff --git a/kcms/fonts/fonts.cpp b/kcms/fonts/fonts.cpp index 382492e10..a353de0b5 100644 --- a/kcms/fonts/fonts.cpp +++ b/kcms/fonts/fonts.cpp @@ -1,779 +1,772 @@ /* 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" #include "previewimageprovider.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 according 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) && HAVE_X11 FontAASettings::FontAASettings(QObject *parent) : QObject(parent) , m_state() , m_originalState() , m_subPixelOptionsModel(new QStandardItemModel(this)) , m_hintingOptionsModel(new QStandardItemModel(this)) { m_state.subPixel = KXftConfig::SubPixel::None; for (int t = KXftConfig::SubPixel::None; t <= KXftConfig::SubPixel::Vbgr; ++t) { QStandardItem *item = new QStandardItem(KXftConfig::description((KXftConfig::SubPixel::Type)t)); m_subPixelOptionsModel->appendRow(item); } m_state.hinting = KXftConfig::Hint::None; for (int s = KXftConfig::Hint::None; s <= KXftConfig::Hint::Full; ++s) { QStandardItem * item = new QStandardItem(KXftConfig::description((KXftConfig::Hint::Style)s)); m_hintingOptionsModel->appendRow(item); } } void FontAASettings::load() { double from, to; KXftConfig xft; if (xft.getExcludeRange(from, to)) { m_state.excludeFrom = from; m_state.excludeTo = to; setExclude(true); } else { m_state.excludeFrom = 8; m_state.excludeTo = 15; setExclude(false); } m_originalState.exclude = m_state.exclude; m_originalState.excludeFrom = m_state.excludeFrom; m_originalState.excludeTo = m_state.excludeTo; excludeToChanged(); excludeFromChanged(); KXftConfig::SubPixel::Type spType; if (!xft.getSubPixelType(spType) || KXftConfig::SubPixel::NotSet == spType) { spType = KXftConfig::SubPixel::Rgb; } setSubPixel(spType); m_originalState.subPixel = spType; m_state.subPixelHasLocalConfig = xft.subPixelTypeHasLocalConfig(); KXftConfig::Hint::Style hStyle; if (!xft.getHintStyle(hStyle) || KXftConfig::Hint::NotSet == hStyle) { hStyle = KXftConfig::Hint::Slight; } setHinting(hStyle); m_originalState.hinting = hStyle; m_state.hintingHasLocalConfig = xft.hintStyleHasLocalConfig(); 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_originalState.dpi = 0; } else { m_originalState.dpi = dpicfg; }; setDpi(dpicfg); KSharedConfig::Ptr config = KSharedConfig::openConfig("kdeglobals"); KConfigGroup cg(config, "General"); if (cfgfonts.readEntry("dontChangeAASettings", true)) { setAntiAliasing(true); //AASystem m_state.antiAliasingHasLocalConfig = false; } else if (cg.readEntry("XftAntialias", true)) { setAntiAliasing(true); //AAEnabled m_state.antiAliasingHasLocalConfig = xft.antiAliasingHasLocalConfig(); } else { setAntiAliasing(false); //AADisabled m_state.antiAliasingHasLocalConfig = xft.antiAliasingHasLocalConfig(); } m_originalState.antiAliasing = m_state.antiAliasing; m_originalState.antiAliasingHasLocalConfig = m_state.antiAliasingHasLocalConfig; } bool FontAASettings::save(KXftConfig::AntiAliasing::State aaState) { KXftConfig xft; KConfig kglobals("kdeglobals", KConfig::NoGlobals); KConfigGroup grp(&kglobals, "General"); xft.setAntiAliasing(aaState); if (m_state.exclude) { xft.setExcludeRange(m_state.excludeFrom, m_state.excludeTo); } else { xft.setExcludeRange(0, 0); } KXftConfig::SubPixel::Type spType = (KXftConfig::SubPixel::Type)m_state.subPixel; if (subPixelNeedsSave()) { xft.setSubPixelType(spType); } else { xft.setSubPixelType(KXftConfig::SubPixel::NotSet); } grp.writeEntry("XftSubPixel", KXftConfig::toStr(spType)); if (aaState == KXftConfig::AntiAliasing::NotSet) { grp.revertToDefault("XftAntialias"); } else { grp.writeEntry("XftAntialias", aaState == KXftConfig::AntiAliasing::Enabled); } bool mod = false; KXftConfig::Hint::Style hStyle = (KXftConfig::Hint::Style)m_state.hinting; if (hintingNeedsSave()) { xft.setHintStyle(hStyle); } else { xft.setHintStyle(KXftConfig::Hint::NotSet); } 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_state.dpi); } else { cfgfonts.writeEntry("forceFontDPI", m_state.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_state.dpi == 0 && m_originalState.dpi != 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_state.antiAliasing != m_originalState.antiAliasing) || m_state.dpi != m_originalState.dpi) { - KMessageBox::information(nullptr, - i18n( - "

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

" - ), i18n("Font Settings Changed"), "FontSettingsChanged"); m_originalState.antiAliasing = m_state.antiAliasing; m_originalState.dpi = m_state.dpi; + emit aliasingChangeApplied(); } #else #if HAVE_X11 if (m_state.dpi != m_originalState.dpi) { - KMessageBox::information(0, - i18n( - "

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

" - ), i18n("Font Settings Changed"), "FontSettingsChanged"); m_originalState.dpi = m_state.dpi; } #endif #endif m_originalState.exclude = m_state.exclude; m_originalState.excludeTo = m_state.excludeTo; m_originalState.excludeFrom = m_state.excludeFrom; - + m_originalState.subPixel = m_state.subPixel; m_originalState.hinting = m_state.hinting; return mod; } void FontAASettings::defaults() { setExcludeTo(15); setExcludeFrom(8); setAntiAliasing(true); m_originalState.antiAliasing = m_state.antiAliasing; m_state.antiAliasingHasLocalConfig = false; setDpi(0); setSubPixel(KXftConfig::SubPixel::Rgb); m_state.subPixelHasLocalConfig = false; setHinting(KXftConfig::Hint::Slight); m_state.hintingHasLocalConfig = false; } #endif void FontAASettings::setExclude(bool exclude) { if (exclude == m_state.exclude) { return; } m_state.exclude = exclude; emit excludeChanged(); } bool FontAASettings::exclude() const { return m_state.exclude; } void FontAASettings::setExcludeTo(const int &excludeTo) { if (m_state.excludeTo == excludeTo) { return; } m_state.excludeTo = excludeTo; emit excludeToChanged(); } int FontAASettings::excludeTo() const { return m_state.excludeTo; } void FontAASettings::setExcludeFrom(const int &excludeTo) { if (m_state.excludeFrom == excludeTo) { return; } m_state.excludeFrom = excludeTo; emit excludeToChanged(); } int FontAASettings::excludeFrom() const { return m_state.excludeFrom; } void FontAASettings::setAntiAliasing(bool antiAliasing) { if (m_state.antiAliasing == antiAliasing) { return; } m_state.antiAliasing = antiAliasing; emit aliasingChanged(); } bool FontAASettings::antiAliasing() const { return m_state.antiAliasing; } bool FontAASettings::antiAliasingNeedsSave() const { return m_state.antiAliasingHasLocalConfig || (m_state.antiAliasing != m_originalState.antiAliasing); } bool FontAASettings::subPixelNeedsSave() const { return m_state.subPixelHasLocalConfig || (m_state.subPixel != m_originalState.subPixel); } bool FontAASettings::hintingNeedsSave() const { return m_state.hintingHasLocalConfig || (m_state.hinting != m_originalState.hinting); } void FontAASettings::setDpi(const int &dpi) { if (m_state.dpi == dpi) { return; } m_state.dpi = dpi; emit dpiChanged(); } int FontAASettings::dpi() const { return m_state.dpi; } void FontAASettings::setSubPixel(int idx) { if (m_state.subPixel == idx) { return; } m_state.subPixel = idx; emit subPixelCurrentIndexChanged(); } void FontAASettings::setSubPixelCurrentIndex(int idx) { setSubPixel(KXftConfig::SubPixel::None + idx); } int FontAASettings::subPixelCurrentIndex() { return m_state.subPixel - KXftConfig::SubPixel::None; } void FontAASettings::setHinting(int idx) { if (m_state.hinting == idx) { return; } m_state.hinting = idx; emit hintingCurrentIndexChanged(); } void FontAASettings::setHintingCurrentIndex(int idx) { setHinting(KXftConfig::Hint::None + idx); } int FontAASettings::hintingCurrentIndex() { return m_state.hinting - KXftConfig::Hint::None; } bool FontAASettings::needsSave() const { return m_state != m_originalState; } /**** 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("Fonts"), "0.1", QString(), KAboutLicense::LGPL); about->addAuthor(i18n("Antonis Tsiapaliokas"), QString(), "antonis.tsiapaliokas@kde.org"); setAboutData(about); qmlRegisterType(); setButtons(Apply | Default | Help); auto updateState = [this]() { setNeedsSave(m_fontAASettings->needsSave()); }; connect(m_fontAASettings, &FontAASettings::subPixelCurrentIndexChanged, this, updateState); connect(m_fontAASettings, &FontAASettings::hintingCurrentIndexChanged, this, updateState); connect(m_fontAASettings, &FontAASettings::excludeChanged, this, updateState); connect(m_fontAASettings, &FontAASettings::excludeFromChanged, 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"); m_generalFont = m_generalFontOriginal = nearestExistingFont(cg.readEntry("font", m_defaultFont)); m_fixedWidthFont = m_fixedWidthFontOriginal = nearestExistingFont(cg.readEntry("fixed", QFont("Hack", 9))); m_smallFont = m_smallFontOriginal = nearestExistingFont(cg.readEntry("smallestReadableFont", m_defaultFont)); m_toolbarFont = m_toolbarFontOriginal = nearestExistingFont(cg.readEntry("toolBarFont", m_defaultFont)); m_menuFont = m_menuFontOriginal = nearestExistingFont(cg.readEntry("menuFont", m_defaultFont)); cg = KConfigGroup(config, "WM"); m_windowTitleFont = m_windowTitleFontOriginal = nearestExistingFont(cg.readEntry("activeFont", m_defaultFont)); engine()->addImageProvider("preview", new PreviewImageProvider(generalFont())); - + emit generalFontChanged(); emit fixedWidthFontChanged(); emit smallFontChanged(); emit toolbarFontChanged(); emit menuFontChanged(); emit windowTitleFontChanged(); 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(); m_defaultFontOriginal = m_defaultFont; m_generalFontOriginal = m_generalFont; m_fixedWidthFontOriginal = m_fixedWidthFont; m_smallFontOriginal = m_smallFont; m_toolbarFontOriginal = m_toolbarFont; m_menuFontOriginal = m_menuFont; m_windowTitleFontOriginal = m_windowTitleFont; KConfig _cfgfonts("kcmfonts"); KConfigGroup cfgfonts(&_cfgfonts, "General"); FontAASettings::AASetting aaSetting = FontAASettings::AASystem; if (m_fontAASettings->antiAliasingNeedsSave()) { aaSetting = m_fontAASettings->antiAliasing() ? FontAASettings::AAEnabled : FontAASettings::AADisabled; } 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::updateNeedsSave() { setNeedsSave(m_defaultFontOriginal != m_defaultFont || m_generalFontOriginal != m_generalFont || m_fixedWidthFontOriginal != m_fixedWidthFont || m_smallFontOriginal != m_smallFont || m_toolbarFontOriginal != m_toolbarFont || m_menuFontOriginal != m_menuFont || m_windowTitleFontOriginal != m_windowTitleFont || m_fontAASettings->needsSave()); } void KFonts::setGeneralFont(const QFont &font) { if (m_generalFont == font) { return; } m_generalFont = font; emit generalFontChanged(); updateNeedsSave(); } QFont KFonts::generalFont() const { return m_generalFont; } void KFonts::setFixedWidthFont(const QFont &font) { if (m_fixedWidthFont == font) { return; } m_fixedWidthFont = font; emit fixedWidthFontChanged(); updateNeedsSave(); } QFont KFonts::fixedWidthFont() const { return m_fixedWidthFont; } void KFonts::setSmallFont(const QFont &font) { if (m_smallFont == font) { return; } m_smallFont = font; emit smallFontChanged(); updateNeedsSave(); } QFont KFonts::smallFont() const { return m_smallFont; } void KFonts::setToolbarFont(const QFont &font) { if (m_toolbarFont == font) { return; } m_toolbarFont = font; emit toolbarFontChanged(); updateNeedsSave(); } QFont KFonts::toolbarFont() const { return m_toolbarFont; } void KFonts::setMenuFont(const QFont &font) { if (m_menuFont == font) { return; } m_menuFont = font; emit menuFontChanged(); updateNeedsSave(); } QFont KFonts::menuFont() const { return m_menuFont; } void KFonts::setWindowTitleFont(const QFont &font) { if (m_windowTitleFont == font) { return; } m_windowTitleFont = font; emit windowTitleFontChanged(); updateNeedsSave(); } QFont KFonts::windowTitleFont() const { return m_windowTitleFont; } void KFonts::adjustAllFonts() { QFont font = m_generalFont; KFontChooser::FontDiffFlags fontDiffFlags; 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; } bool FontAASettings::State::operator==(const State& other) const { if ( exclude != other.exclude || antiAliasing != other.antiAliasing || dpi != other.dpi || subPixel != other.subPixel || hinting != other.hinting ) { return false; } if (exclude && (excludeFrom != other.excludeFrom || excludeTo != other.excludeTo)) { return false; } return true; } bool FontAASettings::State::operator!=(const State& other) const { return !(*this == other); } #include "fonts.moc" diff --git a/kcms/fonts/fonts.h b/kcms/fonts/fonts.h index d660eae11..e1595af11 100644 --- a/kcms/fonts/fonts.h +++ b/kcms/fonts/fonts.h @@ -1,208 +1,209 @@ /* 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(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(bool antiAliasing READ antiAliasing WRITE setAntiAliasing NOTIFY aliasingChanged) Q_PROPERTY(int dpi READ dpi WRITE setDpi NOTIFY dpiChanged) struct State { bool exclude; int excludeFrom; int excludeTo; int antiAliasing; bool antiAliasingHasLocalConfig; bool subPixelHasLocalConfig; bool hintingHasLocalConfig; int dpi; int subPixel; int hinting; bool operator==(const State& other) const; bool operator!=(const State& other) const; }; public: enum AASetting { AAEnabled, AASystem, AADisabled }; #if defined(HAVE_FONTCONFIG) && HAVE_X11 FontAASettings(QObject *parent); bool save(KXftConfig::AntiAliasing::State aaState); void load(); void defaults(); void setAntiAliasingState(KXftConfig::AntiAliasing::State aaState); QAbstractItemModel* subPixelOptionsModel() { return m_subPixelOptionsModel; } QAbstractItemModel* hintingOptionsModel() { return m_hintingOptionsModel; } 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(bool antiAliasing); bool antiAliasing() const; bool antiAliasingNeedsSave() const; bool subPixelNeedsSave() const; bool hintingNeedsSave() const; void setDpi(const int &dpi); int dpi() const; int subPixelCurrentIndex(); void setSubPixelCurrentIndex(int idx); void setSubPixel(int idx); int hintingCurrentIndex(); void setHintingCurrentIndex(int idx); void setHinting(int idx); bool needsSave() const; #endif Q_SIGNALS: void excludeChanged(); void excludeToChanged(); void excludeFromChanged(); void antiAliasingChanged(); + void aliasingChangeApplied(); void aliasingChanged(); void dpiChanged(); void subPixelCurrentIndexChanged(); void hintingCurrentIndexChanged(); #if defined(HAVE_FONTCONFIG) && HAVE_X11 private: State m_state; State m_originalState; QStandardItemModel *m_subPixelOptionsModel; QStandardItemModel *m_hintingOptionsModel; #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() override; 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() override; void save() override; void defaults() override; Q_INVOKABLE void adjustAllFonts(); Q_SIGNALS: void fontsHaveChanged(); void generalFontChanged(); void fixedWidthFontChanged(); void smallFontChanged(); void toolbarFontChanged(); void menuFontChanged(); void windowTitleFontChanged(); private: void updateNeedsSave(); 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; QFont m_defaultFontOriginal; QFont m_generalFontOriginal; QFont m_fixedWidthFontOriginal; QFont m_smallFontOriginal; QFont m_toolbarFontOriginal; QFont m_menuFontOriginal; QFont m_windowTitleFontOriginal; FontAASettings *m_fontAASettings; }; #endif diff --git a/kcms/fonts/package/contents/ui/main.qml b/kcms/fonts/package/contents/ui/main.qml index 0819b0351..ed68a95e0 100644 --- a/kcms/fonts/package/contents/ui/main.qml +++ b/kcms/fonts/package/contents/ui/main.qml @@ -1,242 +1,256 @@ /* 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.kirigami 2.4 as Kirigami import org.kde.kcm 1.1 as KCM KCM.SimpleKCM { id: root KCM.ConfigModule.quickHelp: i18n("This module lets you configure the system fonts.") - Kirigami.FormLayout { - id: formLayout - readonly property int maxImplicitWidth: Math.max(adjustAllFontsButton.implicitWidth, excludeField.implicitWidth, subPixelCombo.implicitWidth, hintingCombo.implicitWidth) + ColumnLayout { - QtControls.Button { - id: adjustAllFontsButton - Layout.preferredWidth: formLayout.maxImplicitWidth - icon.name: "font-select-symbolic" - text: i18n("&Adjust All Fonts...") + Kirigami.InlineMessage { + id: antiAliasingMessage + Layout.fillWidth: true + showCloseButton: true + text: i18n("Some changes such as anti-aliasing or DPI will only affect newly started applications.") - onClicked: kcm.adjustAllFonts(); + Connections { + target: kcm.fontAASettings + onAliasingChangeApplied: antiAliasingMessage.visible = true + } } - FontWidget { - id: generalFontWidget - 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 - } + Kirigami.FormLayout { + id: formLayout + readonly property int maxImplicitWidth: Math.max(adjustAllFontsButton.implicitWidth, excludeField.implicitWidth, subPixelCombo.implicitWidth, hintingCombo.implicitWidth) - QtControls.CheckBox { - id: antiAliasingCheckBox - checked: kcm.fontAASettings.antiAliasing - onCheckedChanged: kcm.fontAASettings.antiAliasing = checked - Kirigami.FormData.label: i18n("Anti-Aliasing:") - text: i18n("Enable") - Layout.fillWidth: true - } + QtControls.Button { + id: adjustAllFontsButton + Layout.preferredWidth: formLayout.maxImplicitWidth + icon.name: "font-select-symbolic" + text: i18n("&Adjust All Fonts...") - QtControls.CheckBox { - id: excludeCheckBox - checked: kcm.fontAASettings.exclude - onCheckedChanged: kcm.fontAASettings.exclude = checked; - text: i18n("Exclude range from anti-aliasing") - Layout.fillWidth: true - enabled: antiAliasingCheckBox.checked - } + onClicked: kcm.adjustAllFonts(); + } - RowLayout { - id: excludeField - Layout.preferredWidth: formLayout.maxImplicitWidth - enabled: antiAliasingCheckBox.checked - QtControls.SpinBox { - id: excludeFromSpinBox - stepSize: 1 - onValueChanged: kcm.fontAASettings.excludeFrom = value - textFromValue: function(value, locale) { return i18n("%1 pt", value)} - enabled: excludeCheckBox.checked + FontWidget { + id: generalFontWidget + 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 } - QtControls.Label { - Layout.fillWidth: true - horizontalAlignment: Text.AlignHCenter - text: i18n("to") - enabled: excludeCheckBox.checked + Kirigami.Separator { + Kirigami.FormData.isSection: true } - QtControls.SpinBox { - id: excludeToSpinBox - stepSize: 1 - onValueChanged: kcm.fontAASettings.excludeTo = value - textFromValue: function(value, locale) { return i18n("%1 pt", value)} - enabled: excludeCheckBox.checked + QtControls.CheckBox { + id: antiAliasingCheckBox + checked: kcm.fontAASettings.antiAliasing + onCheckedChanged: kcm.fontAASettings.antiAliasing = checked + Kirigami.FormData.label: i18n("Anti-Aliasing:") + text: i18n("Enable") + Layout.fillWidth: true } - Connections { - target: kcm.fontAASettings - onExcludeFromChanged: excludeFromSpinBox.value = kcm.fontAASettings.excludeFrom; - onExcludeToChanged: excludeToSpinBox.value = kcm.fontAASettings.excludeTo; + + QtControls.CheckBox { + id: excludeCheckBox + checked: kcm.fontAASettings.exclude + onCheckedChanged: kcm.fontAASettings.exclude = checked; + text: i18n("Exclude range from anti-aliasing") + Layout.fillWidth: true + enabled: antiAliasingCheckBox.checked } - } - QtControls.ComboBox { - id: subPixelCombo - Layout.preferredWidth: formLayout.maxImplicitWidth - Kirigami.FormData.label: i18nc("Used as a noun, and precedes a combobox full of options", "Sub-pixel rendering:") - currentIndex: kcm.fontAASettings.subPixelCurrentIndex - onCurrentIndexChanged: kcm.fontAASettings.subPixelCurrentIndex = currentIndex; - model: kcm.fontAASettings.subPixelOptionsModel - textRole: "display" - enabled: antiAliasingCheckBox.checked - popup.height: popup.implicitHeight - delegate: QtControls.ItemDelegate { - id: subPixelDelegate - onWidthChanged: { - subPixelCombo.popup.width = Math.max(subPixelCombo.popup.width, width) + RowLayout { + id: excludeField + Layout.preferredWidth: formLayout.maxImplicitWidth + enabled: antiAliasingCheckBox.checked + QtControls.SpinBox { + id: excludeFromSpinBox + stepSize: 1 + onValueChanged: kcm.fontAASettings.excludeFrom = value + textFromValue: function(value, locale) { return i18n("%1 pt", value)} + enabled: excludeCheckBox.checked } - contentItem: ColumnLayout { - id: subPixelLayout - Kirigami.Heading { - id: subPixelComboText - text: model.display - level: 5 + + QtControls.Label { + Layout.fillWidth: true + horizontalAlignment: Text.AlignHCenter + text: i18n("to") + enabled: excludeCheckBox.checked + } + + 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: i18nc("Used as a noun, and precedes a combobox full of options", "Sub-pixel rendering:") + currentIndex: kcm.fontAASettings.subPixelCurrentIndex + onCurrentIndexChanged: kcm.fontAASettings.subPixelCurrentIndex = currentIndex; + model: kcm.fontAASettings.subPixelOptionsModel + textRole: "display" + enabled: antiAliasingCheckBox.checked + popup.height: popup.implicitHeight + delegate: QtControls.ItemDelegate { + id: subPixelDelegate + onWidthChanged: { + subPixelCombo.popup.width = Math.max(subPixelCombo.popup.width, width) } - Image { - id: subPixelComboImage - source: "image://preview/" + model.index + "_" + kcm.fontAASettings.hintingCurrentIndex + ".png" - // Setting sourceSize here is necessary as a workaround for QTBUG-38127 - // - // With this bug, images requested from a QQuickImageProvider have an incorrect scale with devicePixelRatio != 1 when sourceSize is not set. - // - // TODO: Check if QTBUG-38127 is fixed and remove the next two lines. - sourceSize.width: 1 - sourceSize.height: 1 + contentItem: ColumnLayout { + id: subPixelLayout + Kirigami.Heading { + id: subPixelComboText + text: model.display + level: 5 + } + Image { + id: subPixelComboImage + source: "image://preview/" + model.index + "_" + kcm.fontAASettings.hintingCurrentIndex + ".png" + // Setting sourceSize here is necessary as a workaround for QTBUG-38127 + // + // With this bug, images requested from a QQuickImageProvider have an incorrect scale with devicePixelRatio != 1 when sourceSize is not set. + // + // TODO: Check if QTBUG-38127 is fixed and remove the next two lines. + sourceSize.width: 1 + sourceSize.height: 1 + } } } } - } - QtControls.ComboBox { - id: hintingCombo - Layout.preferredWidth: formLayout.maxImplicitWidth - Kirigami.FormData.label: i18nc("Used as a noun, and precedes a combobox full of options", "Hinting:") - currentIndex: kcm.fontAASettings.hintingCurrentIndex - onCurrentTextChanged: kcm.fontAASettings.hintingCurrentIndex = currentIndex; - model: kcm.fontAASettings.hintingOptionsModel - textRole: "display" - enabled: antiAliasingCheckBox.checked - popup.height: popup.implicitHeight - delegate: QtControls.ItemDelegate { - id: hintingDelegate - onWidthChanged: { - hintingCombo.popup.width = Math.max(hintingCombo.popup.width, width) - } - contentItem: ColumnLayout { - id: hintingLayout - Kirigami.Heading { - id: hintingComboText - text: model.display - level: 5 + QtControls.ComboBox { + id: hintingCombo + Layout.preferredWidth: formLayout.maxImplicitWidth + Kirigami.FormData.label: i18nc("Used as a noun, and precedes a combobox full of options", "Hinting:") + currentIndex: kcm.fontAASettings.hintingCurrentIndex + onCurrentTextChanged: kcm.fontAASettings.hintingCurrentIndex = currentIndex; + model: kcm.fontAASettings.hintingOptionsModel + textRole: "display" + enabled: antiAliasingCheckBox.checked + popup.height: popup.implicitHeight + delegate: QtControls.ItemDelegate { + id: hintingDelegate + onWidthChanged: { + hintingCombo.popup.width = Math.max(hintingCombo.popup.width, width) } - Image { - id: hintingComboImage - source: "image://preview/" + kcm.fontAASettings.subPixelCurrentIndex + "_" + model.index + ".png" - // Setting sourceSize here is necessary as a workaround for QTBUG-38127 - // - // With this bug, images requested from a QQuickImageProvider have an incorrect scale with devicePixelRatio != 1 when sourceSize is not set. - // - // TODO: Check if QTBUG-38127 is fixed and remove the next two lines. - sourceSize.width: 1 - sourceSize.height: 1 + contentItem: ColumnLayout { + id: hintingLayout + Kirigami.Heading { + id: hintingComboText + text: model.display + level: 5 + } + Image { + id: hintingComboImage + source: "image://preview/" + kcm.fontAASettings.subPixelCurrentIndex + "_" + model.index + ".png" + // Setting sourceSize here is necessary as a workaround for QTBUG-38127 + // + // With this bug, images requested from a QQuickImageProvider have an incorrect scale with devicePixelRatio != 1 when sourceSize is not set. + // + // TODO: Check if QTBUG-38127 is fixed and remove the next two lines. + sourceSize.width: 1 + sourceSize.height: 1 + } } } } - } - RowLayout { - QtControls.CheckBox { - id: dpiCheckBox - checked: kcm.fontAASettings.dpi !== 0 - text: i18n("Force font DPI:") - onClicked: kcm.fontAASettings.dpi = (checked ? dpiSpinBox.value : 0) - } - - QtControls.SpinBox { - id: dpiSpinBox - stepSize: 24 - editable: true - enabled: dpiCheckBox.checked - value: kcm.fontAASettings.dpi !== 0 ? kcm.fontAASettings.dpi : 96 - onValueModified: kcm.fontAASettings.dpi = value - to: 1000 - from: 1 + RowLayout { + QtControls.CheckBox { + id: dpiCheckBox + checked: kcm.fontAASettings.dpi !== 0 + text: i18n("Force font DPI:") + onClicked: kcm.fontAASettings.dpi = (checked ? dpiSpinBox.value : 0) + } + + QtControls.SpinBox { + id: dpiSpinBox + stepSize: 24 + editable: true + enabled: dpiCheckBox.checked + value: kcm.fontAASettings.dpi !== 0 ? kcm.fontAASettings.dpi : 96 + onValueModified: kcm.fontAASettings.dpi = value + to: 1000 + from: 1 + } } - } - QtDialogs.FontDialog { - id: fontDialog - title: i18n("Select Font") - modality: Qt.WindowModal - property string currentCategory - property bool adjustAllFonts: false - onAccepted: { - if (adjustAllFonts) { - kcm.adjustAllFonts(font); - } else { - kcm[currentCategory] = font; + QtDialogs.FontDialog { + id: fontDialog + title: i18n("Select Font") + modality: Qt.WindowModal + property string currentCategory + property bool adjustAllFonts: false + onAccepted: { + if (adjustAllFonts) { + kcm.adjustAllFonts(font); + } else { + kcm[currentCategory] = font; + } } } } } } -