File indexing completed on 2024-05-19 05:38:05
0001 /* 0002 SPDX-FileCopyrightText: 1997 Mark Donohoe 0003 SPDX-FileCopyrightText: 1999 Lars Knoll 0004 SPDX-FileCopyrightText: 2000 Rik Hemsley 0005 SPDX-FileCopyrightText: 2015 Antonis Tsiapaliokas <antonis.tsiapaliokas@kde.org> 0006 SPDX-FileCopyrightText: 2017 Marco Martin <mart@kde.org> 0007 SPDX-FileCopyrightText: 2019 Benjamin Port <benjamin.port@enioka.com> 0008 0009 Ported to kcontrol2: 0010 SPDX-FileCopyrightText: Geert Jansen 0011 0012 SPDX-License-Identifier: LGPL-2.0-or-later 0013 */ 0014 0015 #include "fonts.h" 0016 0017 #include <QApplication> 0018 #include <QDBusConnection> 0019 #include <QDBusMessage> 0020 #include <QFontDatabase> 0021 #include <QProcess> 0022 #include <QQmlEngine> 0023 #include <QQuickItem> 0024 #include <QQuickView> 0025 #include <QWindow> 0026 0027 #include <KAcceleratorManager> 0028 #include <KConfig> 0029 #include <KConfigGroup> 0030 #include <KFontChooserDialog> 0031 #include <KLocalizedString> 0032 #include <KPluginFactory> 0033 #include <KWindowSystem> 0034 0035 #include "../kcms-common_p.h" 0036 #include "krdb.h" 0037 #include "kxftconfig.h" 0038 #include "previewimageprovider.h" 0039 0040 #include "fontsdata.h" 0041 0042 /**** DLL Interface ****/ 0043 K_PLUGIN_FACTORY_WITH_JSON(KFontsFactory, "kcm_fonts.json", registerPlugin<KFonts>(); registerPlugin<FontsData>();) 0044 0045 /**** KFonts ****/ 0046 0047 KFonts::KFonts(QObject *parent, const KPluginMetaData &metaData) 0048 : KQuickManagedConfigModule(parent, metaData) 0049 , m_data(new FontsData(this)) 0050 , m_subPixelOptionsModel(new QStandardItemModel(this)) 0051 , m_hintingOptionsModel(new QStandardItemModel(this)) 0052 { 0053 qmlRegisterAnonymousType<QStandardItemModel>("QStandardItemModel", 1); 0054 qmlRegisterAnonymousType<FontsSettings>("FontsSettings", 1); 0055 qmlRegisterAnonymousType<FontsAASettings>("FontsAASettings", 1); 0056 0057 setButtons(Apply | Default | Help); 0058 0059 for (KXftConfig::SubPixel::Type t : 0060 {KXftConfig::SubPixel::None, KXftConfig::SubPixel::Rgb, KXftConfig::SubPixel::Bgr, KXftConfig::SubPixel::Vrgb, KXftConfig::SubPixel::Vbgr}) { 0061 auto item = new QStandardItem(KXftConfig::description(t)); 0062 m_subPixelOptionsModel->appendRow(item); 0063 } 0064 0065 for (KXftConfig::Hint::Style s : {KXftConfig::Hint::None, KXftConfig::Hint::Slight, KXftConfig::Hint::Medium, KXftConfig::Hint::Full}) { 0066 auto item = new QStandardItem(KXftConfig::description(s)); 0067 m_hintingOptionsModel->appendRow(item); 0068 } 0069 connect(fontsAASettings(), &FontsAASettings::hintingChanged, this, &KFonts::hintingCurrentIndexChanged); 0070 connect(fontsAASettings(), &FontsAASettings::subPixelChanged, this, &KFonts::subPixelCurrentIndexChanged); 0071 } 0072 0073 KFonts::~KFonts() 0074 { 0075 } 0076 0077 FontsSettings *KFonts::fontsSettings() const 0078 { 0079 return m_data->fontsSettings(); 0080 } 0081 0082 FontsAASettings *KFonts::fontsAASettings() const 0083 { 0084 return m_data->fontsAASettings(); 0085 } 0086 0087 QAbstractItemModel *KFonts::subPixelOptionsModel() const 0088 { 0089 return m_subPixelOptionsModel; 0090 } 0091 0092 QAbstractItemModel *KFonts::hintingOptionsModel() const 0093 { 0094 return m_hintingOptionsModel; 0095 } 0096 0097 void KFonts::load() 0098 { 0099 // first load all the settings 0100 KQuickManagedConfigModule::load(); 0101 0102 // Load preview 0103 // NOTE: This needs to be done AFTER AA settings is loaded 0104 // otherwise AA settings will be reset in process of loading 0105 // previews 0106 engine()->addImageProvider("preview", new PreviewImageProvider(fontsSettings()->font())); 0107 0108 // KCM expect save state to be false at this point (can be true because if a font setting loaded 0109 // from the config isn't available on the system, font substitution may take place) 0110 setNeedsSave(false); 0111 } 0112 0113 void KFonts::save() 0114 { 0115 #if HAVE_X11 0116 bool forceFontDPIChanged = false; 0117 0118 if (KWindowSystem::isPlatformX11()) { 0119 auto dpiItem = fontsAASettings()->findItem("forceFontDPI"); 0120 auto antiAliasingItem = fontsAASettings()->findItem("antiAliasing"); 0121 Q_ASSERT(dpiItem && antiAliasingItem); 0122 if (dpiItem->isSaveNeeded() || antiAliasingItem->isSaveNeeded()) { 0123 emit aliasingChangeApplied(); 0124 } 0125 0126 forceFontDPIChanged = dpiItem->isSaveNeeded(); 0127 } 0128 #endif 0129 0130 KQuickManagedConfigModule::save(); 0131 0132 #if HAVE_X11 0133 // if the setting is reset in the module, remove the dpi value, 0134 // otherwise don't explicitly remove it and leave any possible system-wide value 0135 if (fontsAASettings()->forceFontDPI() == 0 && forceFontDPIChanged && KWindowSystem::isPlatformX11()) { 0136 QProcess proc; 0137 proc.setProcessChannelMode(QProcess::ForwardedChannels); 0138 proc.start("xrdb", 0139 QStringList() << "-quiet" 0140 << "-remove" 0141 << "-nocpp"); 0142 if (proc.waitForStarted()) { 0143 proc.write(QByteArray("Xft.dpi\n")); 0144 proc.closeWriteChannel(); 0145 proc.waitForFinished(); 0146 } 0147 } 0148 QApplication::processEvents(); 0149 #endif 0150 0151 // Notify the world about the font changes 0152 if (qEnvironmentVariableIsSet("KDE_FULL_SESSION")) { 0153 QDBusMessage message = QDBusMessage::createSignal("/KDEPlatformTheme", "org.kde.KDEPlatformTheme", "refreshFonts"); 0154 QDBusConnection::sessionBus().send(message); 0155 } 0156 0157 runRdb(KRdbExportXftSettings | KRdbExportGtkTheme); 0158 } 0159 0160 void KFonts::adjustFont(const QFont &font, const QString &category) 0161 { 0162 QFont selFont = font; 0163 int ret = KFontChooserDialog::getFont(selFont, KFontChooser::NoDisplayFlags); 0164 0165 if (ret == QDialog::Accepted) { 0166 if (category == QLatin1String("font")) { 0167 fontsSettings()->setFont(selFont); 0168 } else if (category == QLatin1String("menuFont")) { 0169 fontsSettings()->setMenuFont(selFont); 0170 } else if (category == QLatin1String("toolBarFont")) { 0171 fontsSettings()->setToolBarFont(selFont); 0172 } else if (category == QLatin1String("activeFont")) { 0173 fontsSettings()->setActiveFont(selFont); 0174 } else if (category == QLatin1String("smallestReadableFont")) { 0175 fontsSettings()->setSmallestReadableFont(selFont); 0176 } else if (category == QLatin1String("fixed")) { 0177 fontsSettings()->setFixed(selFont); 0178 } 0179 } 0180 Q_EMIT fontsHaveChanged(); 0181 } 0182 0183 void KFonts::adjustAllFonts() 0184 { 0185 QFont font = fontsSettings()->font(); 0186 KFontChooser::FontDiffFlags fontDiffFlags; 0187 int ret = KFontChooserDialog::getFontDiff(font, fontDiffFlags, KFontChooser::NoDisplayFlags); 0188 0189 if (ret == QDialog::Accepted && fontDiffFlags) { 0190 fontsSettings()->setFont(applyFontDiff(fontsSettings()->font(), font, fontDiffFlags)); 0191 fontsSettings()->setMenuFont(applyFontDiff(fontsSettings()->menuFont(), font, fontDiffFlags)); 0192 fontsSettings()->setToolBarFont(applyFontDiff(fontsSettings()->toolBarFont(), font, fontDiffFlags)); 0193 fontsSettings()->setActiveFont(applyFontDiff(fontsSettings()->activeFont(), font, fontDiffFlags)); 0194 0195 QFont smallestFont = font; 0196 // Make the small font 2 points smaller than the general font, but only 0197 // if the general font is 9pt or higher or else the small font would be 0198 // borderline unreadable. Assume that if the user is making the font 0199 // tiny, they want a tiny font everywhere. 0200 const int generalFontPointSize = font.pointSize(); 0201 if (generalFontPointSize >= 9) { 0202 smallestFont.setPointSize(generalFontPointSize - 2); 0203 } 0204 fontsSettings()->setSmallestReadableFont(applyFontDiff(fontsSettings()->smallestReadableFont(), smallestFont, fontDiffFlags)); 0205 0206 const QFont adjustedFont = applyFontDiff(fontsSettings()->fixed(), font, fontDiffFlags); 0207 if (QFontInfo(adjustedFont).fixedPitch()) { 0208 fontsSettings()->setFixed(adjustedFont); 0209 } 0210 } 0211 } 0212 0213 QFont KFonts::applyFontDiff(const QFont &fnt, const QFont &newFont, int fontDiffFlags) 0214 { 0215 QFont font(fnt); 0216 0217 if (fontDiffFlags & KFontChooser::FontDiffSize) { 0218 font.setPointSizeF(newFont.pointSizeF()); 0219 } 0220 if ((fontDiffFlags & KFontChooser::FontDiffFamily)) { 0221 font.setFamily(newFont.family()); 0222 } 0223 if (fontDiffFlags & KFontChooser::FontDiffStyle) { 0224 font.setWeight(newFont.weight()); 0225 font.setStyle(newFont.style()); 0226 font.setUnderline(newFont.underline()); 0227 font.setStyleName(newFont.styleName()); 0228 } 0229 0230 return font; 0231 } 0232 0233 int KFonts::subPixelCurrentIndex() const 0234 { 0235 return fontsAASettings()->subPixel() - KXftConfig::SubPixel::None; 0236 } 0237 0238 void KFonts::setSubPixelCurrentIndex(int idx) 0239 { 0240 fontsAASettings()->setSubPixel(static_cast<KXftConfig::SubPixel::Type>(KXftConfig::SubPixel::None + idx)); 0241 } 0242 0243 int KFonts::hintingCurrentIndex() const 0244 { 0245 return fontsAASettings()->hinting() - KXftConfig::Hint::None; 0246 } 0247 0248 void KFonts::setHintingCurrentIndex(int idx) 0249 { 0250 fontsAASettings()->setHinting(static_cast<KXftConfig::Hint::Style>(KXftConfig::Hint::None + idx)); 0251 } 0252 0253 #include "fonts.moc"