File indexing completed on 2024-04-21 04:58:00

0001 /* This file is part of the KDE project
0002     SPDX-FileCopyrightText: 2001 Carsten Pfeiffer <pfeiffer@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "settingsplugin.h"
0008 
0009 #include <kwidgetsaddons_version.h>
0010 #include <kconfig.h>
0011 #include <KLocalizedString>
0012 #include <kmessagebox.h>
0013 #include <QMenu>
0014 #include <kprotocolmanager.h>
0015 #include <kpluginfactory.h>
0016 #include <KPluginMetaData>
0017 #include <ktoggleaction.h>
0018 #include <kactioncollection.h>
0019 #include <kselectaction.h>
0020 #include <kactionmenu.h>
0021 
0022 #include <kparts/part.h>
0023 #include <kparts/readonlypart.h>
0024 #include <KConfigGroup>
0025 
0026 #include <QDBusConnection>
0027 #include <QDBusInterface>
0028 #include <QDBusMessage>
0029 #include <QDBusReply>
0030 #include <QNetworkProxy>
0031 
0032 #include <htmlextension.h>
0033 #include <htmlsettingsinterface.h>
0034 
0035 K_PLUGIN_CLASS_WITH_JSON(SettingsPlugin, "khtmlsettingsplugin.json")
0036 
0037 SettingsPlugin::SettingsPlugin(QObject *parent,
0038                                const KPluginMetaData& metaData,
0039                                const QVariantList &)
0040     : KonqParts::Plugin(parent), mConfig(nullptr)
0041 {
0042     setMetaData(metaData);
0043     KActionMenu *menu = new KActionMenu(QIcon::fromTheme(QStringLiteral("configure")), i18n("HTML Settings"), actionCollection());
0044     actionCollection()->addAction(QStringLiteral("action menu"), menu);
0045     menu->setPopupMode(QToolButton::InstantPopup);
0046 
0047     KToggleAction *action = actionCollection()->add<KToggleAction>(QStringLiteral("javascript"));
0048     action->setText(i18n("Java&Script"));
0049     connect(action, SIGNAL(triggered(bool)), SLOT(toggleJavascript(bool)));
0050     menu->addAction(action);
0051 
0052     action = actionCollection()->add<KToggleAction>(QStringLiteral("java"));
0053     action->setText(i18n("&Java"));
0054     connect(action, SIGNAL(triggered(bool)), SLOT(toggleJava(bool)));
0055     menu->addAction(action);
0056 
0057     action = actionCollection()->add<KToggleAction>(QStringLiteral("cookies"));
0058     action->setText(i18n("&Cookies"));
0059     connect(action, SIGNAL(triggered(bool)), SLOT(toggleCookies(bool)));
0060     menu->addAction(action);
0061 
0062     action = actionCollection()->add<KToggleAction>(QStringLiteral("plugins"));
0063     action->setText(i18n("&Plugins"));
0064     connect(action, SIGNAL(triggered(bool)), SLOT(togglePlugins(bool)));
0065     menu->addAction(action);
0066 
0067     action = actionCollection()->add<KToggleAction>(QStringLiteral("imageloading"));
0068     action->setText(i18n("Autoload &Images"));
0069     connect(action, SIGNAL(triggered(bool)), SLOT(toggleImageLoading(bool)));
0070     menu->addAction(action);
0071 
0072     //menu->addAction( new KSeparatorAction(actionCollection()) );
0073 
0074     action = actionCollection()->add<KToggleAction>(QStringLiteral("useproxy"));
0075     action->setText(i18n("Enable Pro&xy"));
0076     connect(action, SIGNAL(triggered(bool)), SLOT(toggleProxy(bool)));
0077     menu->addAction(action);
0078 
0079     action = actionCollection()->add<KToggleAction>(QStringLiteral("usecache"));
0080     action->setText(i18n("Enable Cac&he"));
0081     connect(action, SIGNAL(triggered(bool)), SLOT(toggleCache(bool)));
0082     menu->addAction(action);
0083 
0084     KSelectAction *sAction = actionCollection()->add<KSelectAction>(QStringLiteral("cachepolicy"));
0085     sAction->setText(i18n("Cache Po&licy"));
0086     QStringList policies;
0087     policies += i18n("&Keep Cache in Sync");
0088     policies += i18n("&Use Cache if Possible");
0089     policies += i18n("&Offline Browsing Mode");
0090     sAction->setItems(policies);
0091     connect(sAction, &KSelectAction::indexTriggered, this, &SettingsPlugin::cachePolicyChanged);
0092 
0093     menu->addAction(sAction);
0094 
0095     connect(menu->menu(), SIGNAL(aboutToShow()), SLOT(showPopup()));
0096 }
0097 
0098 SettingsPlugin::~SettingsPlugin()
0099 {
0100     delete mConfig;
0101 }
0102 
0103 static HtmlSettingsInterface *settingsInterfaceFor(QObject *obj)
0104 {
0105     HtmlExtension *extension = HtmlExtension::childObject(obj);
0106     return qobject_cast< HtmlSettingsInterface *>(extension);
0107 }
0108 
0109 void SettingsPlugin::showPopup()
0110 {
0111     if (!mConfig) {
0112         mConfig = new KConfig(QStringLiteral("settingspluginrc"), KConfig::NoGlobals);
0113     }
0114 
0115     KParts::ReadOnlyPart *part = qobject_cast<KParts::ReadOnlyPart *>(parent());
0116 
0117     KProtocolManager::reparseConfiguration();
0118     const bool cookies = cookiesEnabled(part->url().url());
0119     actionCollection()->action(QStringLiteral("cookies"))->setChecked(cookies);
0120 #if QT_VERSION_MAJOR < 6
0121     actionCollection()->action(QStringLiteral("useproxy"))->setChecked(KProtocolManager::useProxy());
0122 #else
0123     actionCollection()->action(QStringLiteral("useproxy"))->setChecked(QNetworkProxy::applicationProxy().type() != QNetworkProxy::NoProxy);
0124 #endif
0125 
0126 // TODO KF6: check whether there's a way to implement cache settings directly using QtWebEngine settings. Also, check whether
0127 // these settings are actually applied to WebEnginePart
0128 #if QT_VERSION_MAJOR < 6
0129     actionCollection()->action(QStringLiteral("usecache"))->setChecked(KProtocolManager::useCache());
0130 #endif
0131 
0132     HtmlSettingsInterface *settings = settingsInterfaceFor(part);
0133     if (settings) {
0134         actionCollection()->action(QStringLiteral("java"))->setChecked(settings->htmlSettingsProperty(HtmlSettingsInterface::JavaEnabled).toBool());
0135         actionCollection()->action(QStringLiteral("javascript"))->setChecked(settings->htmlSettingsProperty(HtmlSettingsInterface::JavascriptEnabled).toBool());
0136         actionCollection()->action(QStringLiteral("plugins"))->setChecked(settings->htmlSettingsProperty(HtmlSettingsInterface::PluginsEnabled).toBool());
0137         actionCollection()->action(QStringLiteral("imageloading"))->setChecked(settings->htmlSettingsProperty(HtmlSettingsInterface::AutoLoadImages).toBool());
0138     }
0139 
0140 #if QT_VERSION_MAJOR < 6
0141     KIO::CacheControl cc = KProtocolManager::cacheControl();
0142     switch (cc) {
0143     case KIO::CC_Verify:
0144         static_cast<KSelectAction *>(actionCollection()->action(QStringLiteral("cachepolicy")))->setCurrentItem(0);
0145         break;
0146     case KIO::CC_CacheOnly:
0147         static_cast<KSelectAction *>(actionCollection()->action(QStringLiteral("cachepolicy")))->setCurrentItem(2);
0148         break;
0149     case KIO::CC_Cache:
0150         static_cast<KSelectAction *>(actionCollection()->action(QStringLiteral("cachepolicy")))->setCurrentItem(1);
0151         break;
0152     case KIO::CC_Reload: // nothing for now
0153     case KIO::CC_Refresh:
0154     default:
0155         break;
0156     }
0157 #endif
0158 }
0159 
0160 void SettingsPlugin::toggleJava(bool checked)
0161 {
0162     HtmlSettingsInterface *settings = settingsInterfaceFor(parent());
0163     if (settings) {
0164         settings->setHtmlSettingsProperty(HtmlSettingsInterface::JavaEnabled, checked);
0165     }
0166 }
0167 
0168 void SettingsPlugin::toggleJavascript(bool checked)
0169 {
0170     HtmlSettingsInterface *settings = settingsInterfaceFor(parent());
0171     if (settings) {
0172         settings->setHtmlSettingsProperty(HtmlSettingsInterface::JavascriptEnabled, checked);
0173     }
0174 }
0175 
0176 void SettingsPlugin::toggleCookies(bool checked)
0177 {
0178     KParts::ReadOnlyPart *part = qobject_cast<KParts::ReadOnlyPart *>(parent());
0179     if (part) {
0180         const QString advice((checked ? QStringLiteral("Accept") : QStringLiteral("Reject")));
0181 
0182         // TODO generate interface from the installed org.kde.KCookieServer.xml file
0183         // but not until 4.3 is released, since 4.2 had "void setDomainAdvice"
0184         // while 4.3 has "bool setDomainAdvice".
0185 
0186         QDBusInterface kded(QStringLiteral("org.kde.kded5"),
0187                             QStringLiteral("/modules/kcookiejar"),
0188                             QStringLiteral("org.kde.KCookieServer"));
0189         QDBusReply<void> reply = kded.call(QStringLiteral("setDomainAdvice"), part->url().url(), advice);
0190 
0191         if (!reply.isValid())
0192             KMessageBox::error(part->widget(),
0193                                i18n("The cookie setting could not be changed, because the "
0194                                     "cookie daemon could not be contacted."),
0195                                i18nc("@title:window", "Cookie Settings Unavailable"));
0196     }
0197 }
0198 
0199 void SettingsPlugin::togglePlugins(bool checked)
0200 {
0201     HtmlSettingsInterface *settings = settingsInterfaceFor(parent());
0202     if (settings) {
0203         settings->setHtmlSettingsProperty(HtmlSettingsInterface::PluginsEnabled, checked);
0204     }
0205 }
0206 
0207 void SettingsPlugin::toggleImageLoading(bool checked)
0208 {
0209     HtmlSettingsInterface *settings = settingsInterfaceFor(parent());
0210     if (settings) {
0211         settings->setHtmlSettingsProperty(HtmlSettingsInterface::AutoLoadImages, checked);
0212     }
0213 }
0214 
0215 bool SettingsPlugin::cookiesEnabled(const QString &url)
0216 {
0217     QDBusInterface kded(QStringLiteral("org.kde.kded5"),
0218                         QStringLiteral("/modules/kcookiejar"),
0219                         QStringLiteral("org.kde.KCookieServer"));
0220     QDBusReply<QString> reply = kded.call(QStringLiteral("getDomainAdvice"), url);
0221 
0222     bool enabled = false;
0223 
0224     if (reply.isValid()) {
0225         QString advice = reply;
0226         enabled = (advice == QLatin1String("Accept"));
0227         if (!enabled && advice == QLatin1String("Dunno")) {
0228             // TODO, check the global setting via dcop
0229             KConfig _kc(QStringLiteral("kcookiejarrc"), KConfig::NoGlobals);
0230             KConfigGroup kc(&_kc, "Cookie Policy");
0231             enabled = (kc.readEntry("CookieGlobalAdvice", "Reject") == QLatin1String("Accept"));
0232         }
0233     }
0234 
0235     return enabled;
0236 }
0237 
0238 //
0239 // sync with kcontrol/kio/ksaveioconfig.* !
0240 //
0241 
0242 void SettingsPlugin::toggleProxy(bool checked)
0243 {
0244     KConfigGroup grp(mConfig, QString());
0245     int type;
0246 
0247     if (checked) {
0248         //According with kioextras/kcms/ksaveioconfig.h, 1 is ManualProxy
0249         type = grp.readEntry("SavedProxyType", 1);
0250     } else {
0251         grp.writeEntry("SavedProxyType",proxyType());
0252         //According with kioextras/kcms/ksaveioconfig.h, 1 is NoProxy
0253         type = 0;
0254     }
0255 
0256     KConfig _config(QStringLiteral("kioslaverc"), KConfig::NoGlobals);
0257     KConfigGroup config(&_config, "Proxy Settings");
0258     config.writeEntry("ProxyType", type);
0259 
0260     actionCollection()->action(QStringLiteral("useproxy"))->setChecked(checked);
0261     updateIOSlaves();
0262 }
0263 
0264 void SettingsPlugin::toggleCache(bool checked)
0265 {
0266     KConfig config(QStringLiteral("kio_httprc"), KConfig::NoGlobals);
0267     KConfigGroup grp(&config, QString());
0268     grp.writeEntry("UseCache", checked);
0269     actionCollection()->action(QStringLiteral("usecache"))->setChecked(checked);
0270 
0271     updateIOSlaves();
0272 }
0273 
0274 void SettingsPlugin::cachePolicyChanged(int p)
0275 {
0276     QString policy;
0277 
0278     switch (p) {
0279     case 0:
0280         policy = KIO::getCacheControlString(KIO::CC_Verify);
0281         break;
0282     case 1:
0283         policy = KIO::getCacheControlString(KIO::CC_Cache);
0284         break;
0285     case 2:
0286         policy = KIO::getCacheControlString(KIO::CC_CacheOnly);
0287         break;
0288     };
0289 
0290     if (!policy.isEmpty()) {
0291         KConfig config(QStringLiteral("kio_httprc"), KConfig::NoGlobals);
0292         KConfigGroup grp(&config, QString());
0293         grp.writeEntry("cache", policy);
0294 
0295         updateIOSlaves();
0296     }
0297 }
0298 
0299 void SettingsPlugin::updateIOSlaves()
0300 {
0301     QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/KIO/Scheduler"),
0302                            QStringLiteral("org.kde.KIO.Scheduler"),
0303                            QStringLiteral("reparseSlaveConfiguration"));
0304     message << QString();
0305     QDBusConnection::sessionBus().send(message);
0306 }
0307 
0308 int SettingsPlugin::proxyType()
0309 {
0310 #if QT_VERSION_MAJOR < 6
0311     return KProtocolManager::proxyType();
0312 #else
0313     return KConfig(QStringLiteral("kioslaverc"), KConfig::NoGlobals).group("Proxy Settings").readEntry("ProxyType", 0);
0314 #endif
0315 }
0316 
0317 #include "settingsplugin.moc"