File indexing completed on 2024-05-05 05:00:07

0001 #include "appearance.h"
0002 #include "../../src/htmldefaults.h"
0003 
0004 #include "kcmcss.h"
0005 
0006 #include <QFormLayout>
0007 #include <QDBusMessage>
0008 #include <QDBusConnection>
0009 #include <QGroupBox>
0010 #include <QFontComboBox>
0011 #include <QFontDatabase>
0012 #include <QSpinBox>
0013 #include <QTabWidget>
0014 
0015 #include <kcharsets.h>
0016 #include <ksharedconfig.h>
0017 #include <KLocalizedString>
0018 #include <KConfigGroup>
0019 
0020 static const char *const animationValues[] = {"Enabled", "Disabled", "LoopOnce"};
0021 enum AnimationsType { AnimationsAlways = 0, AnimationsNever = 1, AnimationsLoopOnce = 2 };
0022 
0023 static const char *const smoothScrollingValues[] = {"Enabled", "Disabled", "WhenEfficient"};
0024 enum SmoothScrollingType { SmoothScrollingAlways = 0, SmoothScrollingNever = 1, SmoothScrollingWhenEfficient = 2 };
0025 
0026 enum UnderlineLinkType { UnderlineAlways = 0, UnderlineNever = 1, UnderlineHover = 2 };
0027 
0028 KAppearanceOptions::KAppearanceOptions(QObject *parent, const KPluginMetaData &md, const QVariantList &)
0029     : KCModule(parent, md), m_groupname(QStringLiteral("HTML Settings")),
0030       fSize(10), fMinSize(HTML_DEFAULT_MIN_FONT_SIZE)
0031 
0032 {
0033     QVBoxLayout *l = new QVBoxLayout(widget());
0034     QTabWidget *tabWidget = new QTabWidget(widget());
0035     l->addWidget(tabWidget);
0036     QWidget *mainTab = new QWidget(widget());
0037     QWidget *fontsTab = new QWidget(widget());
0038     cssConfig = new CSSConfig(widget());
0039     tabWidget->addTab(mainTab, i18nc("@title:tab", "General"));
0040     tabWidget->addTab(fontsTab, i18nc("@title:tab", "Fonts"));
0041     tabWidget->addTab(cssConfig, i18nc("@title:tab", "Stylesheets"));
0042 
0043 #if QT_VERSION_MAJOR < 6
0044     connect(cssConfig, &CSSConfig::changed, this, &KAppearanceOptions::markAsChanged);
0045 #else
0046     connect(cssConfig, &CSSConfig::changed, this, [this](){setNeedsSave(true);});
0047 #endif
0048 
0049     l = new QVBoxLayout(mainTab);
0050 
0051     //Images
0052     QGroupBox *box = new QGroupBox(i18n("Images"), mainTab);
0053     l->addWidget(box);
0054     QFormLayout *fl = new QFormLayout(box);
0055 
0056     m_pAutoLoadImagesCheckBox = new QCheckBox(i18n("A&utomatically load images"), widget());
0057     m_pAutoLoadImagesCheckBox->setToolTip(i18n("<html>If this box is checked, Konqueror will"
0058                                                " automatically load any images that are embedded in a web page."
0059                                                " Otherwise, it will display placeholders for the images, and"
0060                                                " you can then manually load the images by clicking on the image"
0061                                                " button.<br />Unless you have a very slow network connection, you"
0062                                                " will probably want to check this box to enhance your browsing"
0063                                                " experience.</html>"));
0064     connect(m_pAutoLoadImagesCheckBox, &QAbstractButton::toggled, this, &KAppearanceOptions::markAsChanged);
0065     fl->addRow(m_pAutoLoadImagesCheckBox);
0066 
0067     m_pUnfinishedImageFrameCheckBox = new QCheckBox(i18n("Dra&w frame around not completely loaded images"), widget());
0068     m_pUnfinishedImageFrameCheckBox->setToolTip(i18n("<html>If this box is checked, Konqueror will draw"
0069                                                      " a frame as a placeholder around images embedded in a web page that are"
0070                                                      " not yet fully loaded.<br />You will probably want to check this box to"
0071                                                      " enhance your browsing experience, especially if have a slow network"
0072                                                      " connection.</html>"));
0073     connect(m_pUnfinishedImageFrameCheckBox, &QAbstractButton::toggled, this, &KAppearanceOptions::markAsChanged);
0074     fl->addRow(m_pUnfinishedImageFrameCheckBox);
0075 
0076     m_pAnimationsCombo = new QComboBox(widget());
0077     m_pAnimationsCombo->setEditable(false);
0078     m_pAnimationsCombo->insertItem(AnimationsAlways, i18nc("animations", "Enabled"));
0079     m_pAnimationsCombo->insertItem(AnimationsNever, i18nc("animations", "Disabled"));
0080     m_pAnimationsCombo->insertItem(AnimationsLoopOnce, i18n("Show Only Once"));
0081     m_pAnimationsCombo->setToolTip(i18n("<html>Controls how Konqueror shows animated images:<br />"
0082                                         "<ul><li><b>Enabled</b>: Show all animations completely.</li>"
0083                                         "<li><b>Disabled</b>: Never show animations, show the starting image only.</li>"
0084                                         "<li><b>Show only once</b>: Show all animations completely but do not repeat them.</li></ul></html>"));
0085     connect(m_pAnimationsCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &KAppearanceOptions::markAsChanged);
0086     fl->addRow(i18n("A&nimations:"), m_pAnimationsCombo);
0087 
0088     //Other
0089     box = new QGroupBox(i18nc("@title:group", "Miscellaneous"), mainTab);
0090     l->addWidget(box);
0091     fl = new QFormLayout(box);
0092     m_pUnderlineCombo = new QComboBox(widget());
0093     m_pUnderlineCombo->setEditable(false);
0094     m_pUnderlineCombo->insertItem(UnderlineAlways, i18nc("underline", "Enabled"));
0095     m_pUnderlineCombo->insertItem(UnderlineNever, i18nc("underline", "Disabled"));
0096     m_pUnderlineCombo->insertItem(UnderlineHover, i18n("Only on Hover"));
0097     fl->addRow(i18n("Und&erline links:"), m_pUnderlineCombo);
0098 
0099     m_pUnderlineCombo->setToolTip(i18n(
0100                                       "<html>Controls how Konqueror handles underlining hyperlinks:<br />"
0101                                       "<ul><li><b>Enabled</b>: Always underline links</li>"
0102                                       "<li><b>Disabled</b>: Never underline links</li>"
0103                                       "<li><b>Only on Hover</b>: Underline when the mouse is moved over the link</li>"
0104                                       "</ul><br /><i>Note: The site's CSS definitions can override this value.</i></html>"));
0105     connect(m_pUnderlineCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &KAppearanceOptions::markAsChanged);
0106 
0107     m_pSmoothScrollingCombo = new QComboBox(widget());
0108     m_pSmoothScrollingCombo->setEditable(false);
0109     m_pSmoothScrollingCombo->insertItem(SmoothScrollingWhenEfficient, i18n("When Efficient"));
0110     m_pSmoothScrollingCombo->insertItem(SmoothScrollingAlways, i18nc("smooth scrolling", "Always"));
0111     m_pSmoothScrollingCombo->insertItem(SmoothScrollingNever, i18nc("soft scrolling", "Never"));
0112     fl->addRow(i18n("S&mooth scrolling:"), m_pSmoothScrollingCombo);
0113     m_pSmoothScrollingCombo->setToolTip(i18n(
0114                                             "<html>Determines whether Konqueror should use smooth steps to scroll HTML pages, or whole steps:<br />"
0115                                             "<ul><li><b>Always</b>: Always use smooth steps when scrolling.</li>"
0116                                             "<li><b>Never</b>: Never use smooth scrolling, scroll with whole steps instead.</li>"
0117                                             "<li><b>When Efficient</b>: Only use smooth scrolling on pages where it can be achieved with moderate usage of system resources.</li></ul></html>"));
0118     connect(m_pSmoothScrollingCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &KAppearanceOptions::markAsChanged);
0119 
0120     l->addStretch(5);
0121 
0122     m_pConfig = KSharedConfig::openConfig(QStringLiteral("konquerorrc"), KConfig::NoGlobals);
0123 
0124     QString empty;
0125     //initialise fonts list otherwise it crashs
0126     while (fonts.count() < 7) {
0127         fonts.append(empty);
0128     }
0129 
0130     QVBoxLayout *lay = new QVBoxLayout(fontsTab);
0131 
0132     QGroupBox *gb = new QGroupBox(i18n("Font Si&ze"));
0133     lay->addWidget(gb);
0134     fl = new QFormLayout(gb);
0135     gb->setToolTip(i18n("This is the relative font size Konqueror uses to display web sites."));
0136 
0137     m_minSize = new QSpinBox;
0138     m_minSize->setValue(fMinSize);
0139     fl->addRow(i18n("M&inimum font size:"), m_minSize);
0140     m_minSize->setRange(2, 30);
0141     connect(m_minSize, QOverload<int>::of(&QSpinBox::valueChanged), this, &KAppearanceOptions::slotMinimumFontSize);
0142     connect(m_minSize, QOverload<int>::of(&QSpinBox::valueChanged), this, &KAppearanceOptions::markAsChanged);
0143     m_minSize->setToolTip("<qt>" + i18n("Konqueror will never display text smaller than "
0144                                         "this size,<br />overriding any other settings.") + "</qt>");
0145 
0146     m_MedSize = new QSpinBox(m_minSize);
0147     m_MedSize->setValue(fSize);
0148     fl->addRow(i18n("&Medium font size:"), m_MedSize);
0149     m_MedSize->setRange(2, 30);
0150     connect(m_MedSize, QOverload<int>::of(&QSpinBox::valueChanged), this, &KAppearanceOptions::slotFontSize);
0151     connect(m_MedSize, QOverload<int>::of(&QSpinBox::valueChanged), this, &KAppearanceOptions::markAsChanged);
0152     m_MedSize->setToolTip(
0153         i18n("This is the relative font size Konqueror uses "
0154              "to display web sites."));
0155 
0156     box = new QGroupBox(/*i18n("Font Families")*/);
0157     lay->addWidget(box);
0158     fl = new QFormLayout(box);
0159 
0160     m_pFonts[0] = new QFontComboBox(fontsTab);
0161     fl->addRow(i18n("S&tandard font:"), m_pFonts[0]);
0162     m_pFonts[0]->setToolTip(i18n("This is the font used to display normal text in a web page."));
0163     connect(m_pFonts[0], &QFontComboBox::currentFontChanged, this, &KAppearanceOptions::slotStandardFont);
0164 
0165     m_pFonts[1] = new QFontComboBox(fontsTab);
0166     fl->addRow(i18n("&Fixed font:"), m_pFonts[1]);
0167     m_pFonts[1]->setToolTip(i18n("This is the font used to display fixed-width (i.e. non-proportional) text."));
0168     connect(m_pFonts[1], &QFontComboBox::currentFontChanged, this, &KAppearanceOptions::slotFixedFont);
0169 
0170     m_pFonts[2] = new QFontComboBox(widget());
0171     fl->addRow(i18n("S&erif font:"),  m_pFonts[2]);
0172     m_pFonts[2]->setToolTip(i18n("This is the font used to display text that is marked up as serif."));
0173     connect(m_pFonts[2], &QFontComboBox::currentFontChanged, this, &KAppearanceOptions::slotSerifFont);
0174 
0175     m_pFonts[3] = new QFontComboBox(widget());
0176     fl->addRow(i18n("Sa&ns serif font:"),  m_pFonts[3]);
0177     m_pFonts[3]->setToolTip(i18n("This is the font used to display text that is marked up as sans-serif."));
0178     connect(m_pFonts[3], &QFontComboBox::currentFontChanged, this, &KAppearanceOptions::slotSansSerifFont);
0179 
0180     m_pFonts[4] = new QFontComboBox(widget());
0181     fl->addRow(i18n("C&ursive font:"),  m_pFonts[4]);
0182     m_pFonts[4]->setToolTip(i18n("This is the font used to display text that is marked up as italic."));
0183     connect(m_pFonts[4], &QFontComboBox::currentFontChanged, this, &KAppearanceOptions::slotCursiveFont);
0184 
0185     m_pFonts[5] = new QFontComboBox(widget());
0186     fl->addRow(i18n("Fantas&y font:"), m_pFonts[5]);
0187     m_pFonts[5]->setToolTip(i18n("This is the font used to display text that is marked up as a fantasy font."));
0188     connect(m_pFonts[5], &QFontComboBox::currentFontChanged, this, &KAppearanceOptions::slotFantasyFont);
0189 
0190     for (int i = 0; i < 6; ++i)
0191         connect(m_pFonts[i], &QFontComboBox::currentFontChanged, this, &KAppearanceOptions::markAsChanged);
0192 
0193     m_pFontSizeAdjust = new QSpinBox(widget());
0194     m_pFontSizeAdjust->setRange(-5, 5);
0195     m_pFontSizeAdjust->setSingleStep(1);
0196     fl->addRow(i18n("Font &size adjustment for this encoding:"), m_pFontSizeAdjust);
0197 
0198     connect(m_pFontSizeAdjust, QOverload<int>::of(&QSpinBox::valueChanged), this, &KAppearanceOptions::slotFontSizeAdjust);
0199     connect(m_pFontSizeAdjust, QOverload<int>::of(&QSpinBox::valueChanged), this, &KAppearanceOptions::markAsChanged);
0200 
0201     m_pEncoding = new QComboBox(widget());
0202     m_pEncoding->setEditable(false);
0203     encodings = KCharsets::charsets()->availableEncodingNames();
0204     encodings.prepend(i18n("Use Language Encoding"));
0205     m_pEncoding->addItems(encodings);
0206     fl->addRow(i18n("Default encoding:"), m_pEncoding);
0207 
0208     m_pEncoding->setToolTip(i18n("Select the default encoding to be used; normally, you will be fine with 'Use language encoding' "
0209                                  "and should not have to change this."));
0210 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
0211     connect(m_pEncoding, QOverload<int>::of(&QComboBox::activated), this, [this](int n){slotEncoding(m_pEncoding->itemText(n));});
0212     connect(m_pEncoding, QOverload<int>::of(&QComboBox::activated), this, &KAppearanceOptions::markAsChanged);
0213 #else
0214     connect(m_pEncoding, &QComboBox::textActivated, this, &KAppearanceOptions::slotEncoding);
0215     connect(m_pEncoding, &QComboBox::textActivated, this, &KAppearanceOptions::markAsChanged);
0216 #endif
0217 
0218     lay->addStretch(5);
0219 }
0220 
0221 KAppearanceOptions::~KAppearanceOptions()
0222 {
0223 }
0224 
0225 void KAppearanceOptions::slotFontSize(int i)
0226 {
0227     fSize = i;
0228     if (fSize < fMinSize) {
0229         m_minSize->setValue(fSize);
0230         fMinSize = fSize;
0231     }
0232 }
0233 
0234 void KAppearanceOptions::slotMinimumFontSize(int i)
0235 {
0236     fMinSize = i;
0237     if (fMinSize > fSize) {
0238         m_MedSize->setValue(fMinSize);
0239         fSize = fMinSize;
0240     }
0241 }
0242 
0243 void KAppearanceOptions::slotStandardFont(const QFont &n)
0244 {
0245     fonts[0] = n.family();
0246 }
0247 
0248 void KAppearanceOptions::slotFixedFont(const QFont &n)
0249 {
0250     fonts[1] = n.family();
0251 }
0252 
0253 void KAppearanceOptions::slotSerifFont(const QFont &n)
0254 {
0255     fonts[2] = n.family();
0256 }
0257 
0258 void KAppearanceOptions::slotSansSerifFont(const QFont &n)
0259 {
0260     fonts[3] = n.family();
0261 }
0262 
0263 void KAppearanceOptions::slotCursiveFont(const QFont &n)
0264 {
0265     fonts[4] = n.family();
0266 }
0267 
0268 void KAppearanceOptions::slotFantasyFont(const QFont &n)
0269 {
0270     fonts[5] = n.family();
0271 }
0272 
0273 void KAppearanceOptions::slotFontSizeAdjust(int value)
0274 {
0275     fonts[6] = QString::number(value);
0276 }
0277 
0278 void KAppearanceOptions::slotEncoding(const QString &n)
0279 {
0280     encodingName = n;
0281 }
0282 
0283 static int stringToIndex(const char *const *possibleValues, int possibleValuesCount, int defaultValue, const QString &value)
0284 {
0285     int i = possibleValuesCount;
0286     while (--i >= 0)
0287         if (possibleValues[i] == value) {
0288             break;
0289         }
0290     if (i == -1) {
0291         i = defaultValue;
0292     }
0293     return i;
0294 }
0295 
0296 void KAppearanceOptions::load()
0297 {
0298     KConfigGroup khtmlrc(KSharedConfig::openConfig(QStringLiteral("khtmlrc"), KConfig::NoGlobals), "");
0299     KConfigGroup cg(m_pConfig, "");
0300 #define SET_GROUP(x) cg = KConfigGroup(m_pConfig,x); khtmlrc = KConfigGroup(KSharedConfig::openConfig("khtmlrc", KConfig::NoGlobals),x)
0301 #define READ_NUM(x,y) cg.readEntry(x, khtmlrc.readEntry(x, y))
0302 #define READ_LIST(x) cg.readEntry(x, khtmlrc.readEntry(x, QStringList() ))
0303 #define READ_BOOL(x,y) cg.readEntry(x, khtmlrc.readEntry(x, y))
0304 #define READ_ENTRYNODEFAULT(x) cg.readEntry(x, khtmlrc.readEntry(x))
0305 
0306     SET_GROUP(m_groupname);
0307     fSize = READ_NUM("MediumFontSize", 12);
0308     fMinSize = READ_NUM("MinimumFontSize", HTML_DEFAULT_MIN_FONT_SIZE);
0309     if (fSize < fMinSize) {
0310         fSize = fMinSize;
0311     }
0312 
0313     defaultFonts = QStringList();
0314     defaultFonts.append(QFontDatabase::systemFont(QFontDatabase::GeneralFont).family());
0315     defaultFonts.append(QFontDatabase::systemFont(QFontDatabase::FixedFont).family());
0316     defaultFonts.append(HTML_DEFAULT_VIEW_SERIF_FONT);
0317     defaultFonts.append(HTML_DEFAULT_VIEW_SANSSERIF_FONT);
0318     defaultFonts.append(HTML_DEFAULT_VIEW_CURSIVE_FONT);
0319     defaultFonts.append(HTML_DEFAULT_VIEW_FANTASY_FONT);
0320     defaultFonts.append(QStringLiteral("0"));   // default font size adjustment
0321 
0322     if (cg.hasKey("Fonts")) {
0323         fonts = cg.readEntry("Fonts", QStringList());
0324     } else {
0325         fonts = khtmlrc.readEntry("Fonts", QStringList());
0326     }
0327     while (fonts.count() < 7) {
0328         fonts.append(QString());
0329     }
0330 
0331     encodingName = READ_ENTRYNODEFAULT("DefaultEncoding"); //TODO move
0332 
0333     m_pAutoLoadImagesCheckBox->setChecked(READ_BOOL("AutoLoadImages", true));
0334     m_pUnfinishedImageFrameCheckBox->setChecked(READ_BOOL("UnfinishedImageFrame", true));
0335 
0336     m_pAnimationsCombo->setCurrentIndex(stringToIndex(animationValues,      sizeof(animationValues) / sizeof(char *),      /*default*/2, READ_ENTRYNODEFAULT("ShowAnimations")));
0337     m_pSmoothScrollingCombo->setCurrentIndex(stringToIndex(smoothScrollingValues, sizeof(smoothScrollingValues) / sizeof(char *),/*default*/2, READ_ENTRYNODEFAULT("SmoothScrolling")));
0338     // we use two keys for link underlining so that this config file
0339     // is backwards compatible with KDE 2.0.  the HoverLink setting
0340     // has precedence over the UnderlineLinks setting
0341     if (READ_BOOL("HoverLinks", true)) {
0342         m_pUnderlineCombo->setCurrentIndex(UnderlineHover);
0343     } else {
0344         m_pUnderlineCombo->setCurrentIndex(READ_BOOL("UnderlineLinks", true) ? UnderlineAlways : UnderlineNever);
0345     }
0346 
0347     cssConfig->load();
0348 
0349     updateGUI();
0350     KCModule::load();
0351 }
0352 
0353 void KAppearanceOptions::defaults()
0354 {
0355     bool old = m_pConfig->readDefaults();
0356     m_pConfig->setReadDefaults(true);
0357     load();
0358     m_pConfig->setReadDefaults(old);
0359 
0360     cssConfig->defaults();
0361     setNeedsSave(true);
0362 #if QT_VERSION_MAJOR > 5
0363     setRepresentsDefaults(true);
0364 #endif
0365 }
0366 
0367 void KAppearanceOptions::updateGUI()
0368 {
0369     //qCDebug(KONQUEROR_LOG) << "KAppearanceOptions::updateGUI " << charset;
0370     for (int f = 0; f < 6; f++) {
0371         QString ff = fonts[f];
0372         if (ff.isEmpty()) {
0373             ff = defaultFonts[f];
0374         }
0375         m_pFonts[f]->setCurrentFont(ff);
0376     }
0377 
0378     int i = 0;
0379     QStringList::const_iterator end = encodings.constEnd();
0380     for (QStringList::const_iterator it = encodings.constBegin(); it != end; ++it, ++i)
0381         if (encodingName == *it) {
0382             m_pEncoding->setCurrentIndex(i);
0383         }
0384     if (encodingName.isEmpty()) {
0385         m_pEncoding->setCurrentIndex(0);
0386     }
0387     m_pFontSizeAdjust->setValue(fonts[6].toInt());
0388     m_MedSize->blockSignals(true);
0389     m_MedSize->setValue(fSize);
0390     m_MedSize->blockSignals(false);
0391     m_minSize->blockSignals(true);
0392     m_minSize->setValue(fMinSize);
0393     m_minSize->blockSignals(false);
0394 }
0395 
0396 void KAppearanceOptions::save()
0397 {
0398     KConfigGroup cg(m_pConfig, m_groupname);
0399     cg.writeEntry("MediumFontSize", fSize);
0400     cg.writeEntry("MinimumFontSize", fMinSize);
0401     cg.writeEntry("Fonts", fonts);
0402 
0403     //TODO move to behaviour
0404     // If the user chose "Use language encoding", write an empty string
0405     if (encodingName == i18n("Use Language Encoding")) {
0406         encodingName = QLatin1String("");
0407     }
0408     cg.writeEntry("DefaultEncoding", encodingName);
0409 
0410     //Images
0411     cg.writeEntry("AutoLoadImages", m_pAutoLoadImagesCheckBox->isChecked());
0412     cg.writeEntry("UnfinishedImageFrame", m_pUnfinishedImageFrameCheckBox->isChecked());
0413     cg.writeEntry("ShowAnimations", animationValues[m_pAnimationsCombo->currentIndex()]);
0414     cg.writeEntry("UnderlineLinks", m_pUnderlineCombo->currentIndex() == UnderlineAlways);
0415     cg.writeEntry("HoverLinks", m_pUnderlineCombo->currentIndex() == UnderlineHover);
0416     cg.writeEntry("SmoothScrolling", smoothScrollingValues[m_pSmoothScrollingCombo->currentIndex()]);
0417 
0418     cssConfig->save();
0419 
0420     cg.sync();
0421     // Send signal to all konqueror instances
0422     QDBusMessage message =
0423         QDBusMessage::createSignal(QStringLiteral("/KonqMain"), QStringLiteral("org.kde.Konqueror.Main"), QStringLiteral("reparseConfiguration"));
0424     QDBusConnection::sessionBus().send(message);
0425 
0426     KCModule::save();
0427 }
0428