diff options
author | Aqua-sama <aqua@iserlohn-fortress.net> | 2019-11-04 21:55:20 +0200 |
---|---|---|
committer | Aqua-sama <aqua@iserlohn-fortress.net> | 2019-11-04 21:55:20 +0200 |
commit | d631875b20244cb8eb0523c88cc838808e9ff4b0 (patch) | |
tree | 254afb4e16ac0a7db059eb4f568eb5f9c3e92c1d /src/webengine | |
parent | Fix gcc compile errors and warnings (diff) | |
download | smolbote-d631875b20244cb8eb0523c88cc838808e9ff4b0.tar.xz |
Move lib/webprofile into src/webengine
Diffstat (limited to 'src/webengine')
-rw-r--r-- | src/webengine/webprofile.cpp | 147 | ||||
-rw-r--r-- | src/webengine/webprofile.h | 94 | ||||
-rw-r--r-- | src/webengine/webprofilemanager.cpp | 149 | ||||
-rw-r--r-- | src/webengine/webprofilemanager.h | 84 |
4 files changed, 474 insertions, 0 deletions
diff --git a/src/webengine/webprofile.cpp b/src/webengine/webprofile.cpp new file mode 100644 index 0000000..843b78e --- /dev/null +++ b/src/webengine/webprofile.cpp @@ -0,0 +1,147 @@ +/* + * This file is part of smolbote. It's copyrighted by the contributors recorded + * in the version control history of the file, available from its original + * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#include "webprofile.h" +#include <QFileInfo> +#include <QSettings> +#include <QWebEngineCookieStore> +#include <QWebEngineSettings> + +WebProfile *WebProfile::profile = nullptr; + +WebProfile::WebProfile(const QString &name, QObject *parent) + : Profile(parent) +{ + m_name = name; + + connect(this->cookieStore(), &QWebEngineCookieStore::cookieAdded, this, [this](const QNetworkCookie &cookie) { + m_cookies.append(cookie); + }); + connect(this->cookieStore(), &QWebEngineCookieStore::cookieRemoved, this, [this](const QNetworkCookie &cookie) { + m_cookies.removeAll(cookie); + }); +} + +WebProfile::WebProfile(const QString &storageName, const QString &name, QObject *parent) + : Profile(storageName, parent) +{ + m_name = name; + + connect(this->cookieStore(), &QWebEngineCookieStore::cookieAdded, this, [this](const QNetworkCookie &cookie) { + m_cookies.append(cookie); + }); + connect(this->cookieStore(), &QWebEngineCookieStore::cookieRemoved, this, [this](const QNetworkCookie &cookie) { + m_cookies.removeAll(cookie); + }); +} + +const QString WebProfile::name() const +{ + return m_name; +} + +void WebProfile::setName(const QString &name) +{ + m_name = name; + emit nameChanged(name); +} + +QString WebProfile::search() const +{ + return m_search; +} + +void WebProfile::setSearch(const QString &url) +{ + m_search = url; + emit searchChanged(m_search); +} + +QUrl WebProfile::homepage() const +{ + return m_homepage; +} + +void WebProfile::setHomepage(const QUrl &url) +{ + m_homepage = url; + emit homepageChanged(m_homepage); +} + +QUrl WebProfile::newtab() const +{ + return m_newtab; +} + +void WebProfile::setNewtab(const QUrl &url) +{ + m_newtab = url; + emit newtabChanged(m_newtab); +} + +void WebProfile::setCachePath(const QString &path) +{ + QWebEngineProfile::setCachePath(path); + emit propertyChanged("cachePath", path); +} + +void WebProfile::setPersistentStoragePath(const QString &path) +{ + QWebEngineProfile::setPersistentStoragePath(path); + emit propertyChanged("persistentStoragePath", path); +} + +void WebProfile::setPersistentCookiesPolicy(int policy) +{ + QWebEngineProfile::setPersistentCookiesPolicy(static_cast<QWebEngineProfile::PersistentCookiesPolicy>(policy)); + emit propertyChanged("persistentCookiesPolicy", policy); +} + +void WebProfile::setHttpAcceptLanguage(const QString &httpAcceptLanguage) +{ + QWebEngineProfile::setHttpAcceptLanguage(httpAcceptLanguage); + emit propertyChanged("httpAcceptLanguage", httpAcceptLanguage); +} + +void WebProfile::setHttpCacheMaximumSize(int maxSize) +{ + QWebEngineProfile::setHttpCacheMaximumSize(maxSize); + emit propertyChanged("httpCacheMaximumSize", maxSize); +} + +void WebProfile::setHttpCacheType(int type) +{ + QWebEngineProfile::setHttpCacheType(static_cast<QWebEngineProfile::HttpCacheType>(type)); + emit propertyChanged("httpCacheType", type); +} + +void WebProfile::setHttpUserAgent(const QString &userAgent) +{ + QWebEngineProfile::setHttpUserAgent(userAgent); + emit propertyChanged("httpUserAgent", userAgent); +} + +void WebProfile::setHttpHeader(const QString &name, const QString &value) +{ + m_headers[name.toLatin1()] = value.toLatin1(); + emit headerChanged(name, value); +} + +void WebProfile::removeHttpHeader(const QString &name) +{ + if(m_headers.contains(name.toLatin1())) { + m_headers.remove(name.toLatin1()); + emit headerRemoved(name); + } +} + +void WebProfile::setSpellCheckEnabled(bool enable) +{ + QWebEngineProfile::setSpellCheckEnabled(enable); + emit propertyChanged("spellCheckEnabed", enable); +} diff --git a/src/webengine/webprofile.h b/src/webengine/webprofile.h new file mode 100644 index 0000000..37e3419 --- /dev/null +++ b/src/webengine/webprofile.h @@ -0,0 +1,94 @@ +/* + * This file is part of smolbote. It's copyrighted by the contributors recorded + * in the version control history of the file, available from its original + * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#ifndef SMOLBOTE_WEBENGINEPROFILE_H +#define SMOLBOTE_WEBENGINEPROFILE_H + +#include <QHash> +#include <QMap> +#include <QNetworkCookie> +#include <QString> +#include <QUrl> +#include <QVector> +#include <QWebEngineProfile> +#include <QWebEngineSettings> +#include <profileinterface.h> + +class WebProfile : public Profile +{ + Q_OBJECT + +public: + // off-the-record constructor + explicit WebProfile(const QString &name, QObject *parent = nullptr); + // default constructor + explicit WebProfile(const QString &storageName, const QString &name, QObject *parent = nullptr); + + ~WebProfile() = default; + + static void setDefaultProfile(WebProfile *profile) + { + Q_CHECK_PTR(profile); + WebProfile::profile = profile; + } + static WebProfile *defaultProfile() + { + Q_CHECK_PTR(WebProfile::profile); + return WebProfile::profile; + } + + const QString name() const; + void setName(const QString &name); + + const QVector<QNetworkCookie> cookies() const + { + return qAsConst(m_cookies); + } + const QMap<QByteArray, QByteArray> headers() const + { + return qAsConst(m_headers); + } + + // search url + QString search() const; + void setSearch(const QString &url); + + // homepage url + QUrl homepage() const; + void setHomepage(const QUrl &url); + + // new tab url + QUrl newtab() const; + void setNewtab(const QUrl &url); + + void setCachePath(const QString &path); + void setPersistentStoragePath(const QString &path); + void setPersistentCookiesPolicy(int policy); + + void setHttpAcceptLanguage(const QString &httpAcceptLanguage); + void setHttpCacheMaximumSize(int maxSize); + void setHttpCacheType(int type); + void setHttpUserAgent(const QString &userAgent); + void setHttpHeader(const QString &name, const QString &value); + void removeHttpHeader(const QString &name); + + void setSpellCheckEnabled(bool enable); + +private: + static WebProfile *profile; + + QString m_name; + QString m_search = QString("about:blank"); + QUrl m_homepage = QUrl("about:blank"); + QUrl m_newtab = QUrl("about:blank"); + + QVector<QNetworkCookie> m_cookies; + QMap<QByteArray, QByteArray> m_headers; +}; + +#endif // SMOLBOTE_WEBENGINEPROFILE_H diff --git a/src/webengine/webprofilemanager.cpp b/src/webengine/webprofilemanager.cpp new file mode 100644 index 0000000..3f3d5ba --- /dev/null +++ b/src/webengine/webprofilemanager.cpp @@ -0,0 +1,149 @@ +/* + * This file is part of smolbote. It's copyrighted by the contributors recorded + * in the version control history of the file, available from its original + * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#include "webprofilemanager.h" +#include "webprofile.h" +#include <QFileInfo> +#include <QWebEngineSettings> +#include "configuration.h" + +WebProfileManager::WebProfileManager(QObject *parent) + : QObject(parent) +{ +} + +WebProfileManager::~WebProfileManager() +{ + for(Profile p : profiles) { + if(p.selfDestruct && p.settings != nullptr) { + if(!p.ptr->isOffTheRecord()) { + if(!p.ptr->persistentStoragePath().isEmpty()) + QDir(p.ptr->persistentStoragePath()).removeRecursively(); + if(!p.ptr->cachePath().isEmpty()) + QDir(p.ptr->cachePath()).removeRecursively(); + } + const QString filename = p.settings->fileName(); + delete p.settings; + QFile::remove(filename); + } else if(p.settings != nullptr) { + p.settings->sync(); + delete p.settings; + } + } +} + +WebProfile *WebProfileManager::profile(const QString &id, const QString &path, bool isOffTheRecord) +{ + // Check if profile exists + if(profiles.contains(id)) + return profiles.value(id).ptr; + + Configuration conf; + Profile profile; + + if(!path.isEmpty()) + profile.settings = new QSettings(path, QSettings::IniFormat); + + // QWebEngineCore cleans up profiles automatically, so no need to set parent + profile.ptr = [id, isOffTheRecord, profile]() { + if(profile.value("otr", isOffTheRecord).toBool()) + return new WebProfile(/* name */ profile.value("name", id).toString(), /* parent */ nullptr); + else + return new WebProfile(/* storageName */ id, /* name */ profile.value("name", id).toString(), /* parent */ nullptr); + }(); + if(profile.settings != nullptr) + profile.settings->setParent(profile.ptr); + + connect(profile.ptr, &WebProfile::nameChanged, profile.settings, [profile](const QString &name) { + profile.settings->setValue("name", name); + }); + + profile.ptr->setSearch(profile.value("search", conf.value<QString>("profile.search").value()).toString()); + connect(profile.ptr, &WebProfile::searchChanged, profile.settings, [profile](const QString &url) { + profile.settings->setValue("search", url); + }); + + profile.ptr->setHomepage(profile.value("homepage", conf.value<QString>("profile.homepage").value()).toUrl()); + connect(profile.ptr, &WebProfile::homepageChanged, profile.settings, [profile](const QUrl &url) { + profile.settings->setValue("homepage", url); + }); + + profile.ptr->setNewtab(profile.value("newtab", conf.value<QString>("profile.newtab").value()).toUrl()); + connect(profile.ptr, &WebProfile::newtabChanged, profile.settings, [profile](const QUrl &url) { + profile.settings->setValue("newtab", url); + }); + + if(profile.settings != nullptr) { + profile.settings->beginGroup("properties"); + { + const auto keys = profile.settings->childKeys(); + for(const QString &key : keys) { + profile.ptr->setProperty(qUtf8Printable(key), profile.settings->value(key)); + } + } + profile.settings->endGroup(); // properties + connect(profile.ptr, &WebProfile::propertyChanged, [profile](const QString &property, const QVariant &value) { + profile.settings->setValue("properties/" + property, value); + }); + + profile.settings->beginGroup("attributes"); + { + const auto keys = profile.settings->childKeys(); + auto *settings = profile.ptr->settings(); + for(const QString &key : keys) { + auto attribute = static_cast<QWebEngineSettings::WebAttribute>(key.toInt()); + settings->setAttribute(attribute, profile.settings->value(key).toBool()); + } + } + profile.settings->endGroup(); + connect(profile.ptr, &WebProfile::attributeChanged, [profile](const QWebEngineSettings::WebAttribute attr, const bool value) { + profile.settings->setValue("attributes/" + QString::number(attr), value); + }); + + // headers + profile.settings->beginGroup("headers"); + for(const QString &key : profile.settings->childKeys()) { + profile.ptr->setHttpHeader(key.toLatin1(), profile.settings->value(key).toString().toLatin1()); + } + profile.settings->endGroup(); + connect(profile.ptr, &WebProfile::headerChanged, [profile](const QString &name, const QString &value) { + profile.settings->setValue("headers/" + name, value); + }); + connect(profile.ptr, &WebProfile::headerRemoved, [profile](const QString &name) { + profile.settings->remove("headers/" + name); + }); + + } // profile.settings != nullptr + + profiles[id] = profile; + return profile.ptr; +} + +void WebProfileManager::deleteProfile(const QString &id) +{ + if(profiles.contains(id)) { + profiles[id].selfDestruct = true; + } +} + +void WebProfileManager::profileMenu(QMenu *menu, const std::function<void(WebProfile *)> &callback, WebProfile *current, bool checkable) const +{ + auto *group = new QActionGroup(menu); + connect(menu, &QMenu::aboutToHide, group, &QActionGroup::deleteLater); + + for(const auto &profile : profiles) { + auto *action = menu->addAction(profile.ptr->name(), profile.ptr, [profile, callback]() { + callback(profile.ptr); + }); + action->setCheckable(checkable); + if(profile.ptr == current) + action->setChecked(true); + group->addAction(action); + } +} + diff --git a/src/webengine/webprofilemanager.h b/src/webengine/webprofilemanager.h new file mode 100644 index 0000000..3e82936 --- /dev/null +++ b/src/webengine/webprofilemanager.h @@ -0,0 +1,84 @@ +/* + * This file is part of smolbote. It's copyrighted by the contributors recorded + * in the version control history of the file, available from its original + * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#ifndef SMOLBOTE_WEBPROFILEMANAGER_H +#define SMOLBOTE_WEBPROFILEMANAGER_H + +#include "webprofile.h" +#include <QDir> +#include <QFile> +#include <QMap> +#include <QMenu> +#include <QObject> +#include <QSettings> +#include <functional> + +struct ProfileDefault_t +{ + QString search; + QString homepage; + QString newtab; +}; + +class WebProfileManager : public QObject +{ + Q_OBJECT +public: + explicit WebProfileManager(QObject *parent); + ~WebProfileManager(); + + /** Create a profile with specified id + * param id The profile ID + * param path The path to the profile settings + * param isOffTheRecord Off-the-record toggle + * return WebProfile* The profile, or nullptr if one could not be created + */ + WebProfile *profile(const QString &id, const QString &path = QString(), bool isOffTheRecord = true); + + /** Set a profile for deletion + * param id The profile ID + * return void + */ + void deleteProfile(const QString &id); + + void profileMenu(QMenu *menu, const std::function<void(WebProfile *)> &callback, WebProfile *current = nullptr, bool checkable = false) const; + + const QStringList idList() const + { + return profiles.keys(); + } + QString id(WebProfile *profile) const + { + QMapIterator<QString, Profile> i(profiles); + while(i.hasNext()) { + i.next(); + if(i.value().ptr == profile) + return i.key(); + } + return QString(); + } + +private: + struct Profile { + WebProfile *ptr = nullptr; + QSettings *settings = nullptr; + bool selfDestruct = false; + + QVariant value(const QString &key, const QVariant &defaultValue) const + { + if(settings == nullptr) + return defaultValue; + else + return settings->value(key, defaultValue); + } + }; + + QMap<QString, Profile> profiles; +}; + +#endif // SMOLBOTE_PROFILEMANAGER_H |