aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAqua-sama <aqua@iserlohn-fortress.net>2020-04-25 22:09:13 +0300
committerAqua-sama <aqua@iserlohn-fortress.net>2020-05-26 12:50:15 +0300
commit0492a063806b6d63e4f378908b809de104a24820 (patch)
tree2e285d0c9b5067dc9395bfb751fe84bb8ac2a5f4
parentlibwebengine (diff)
downloadsmolbote-0492a063806b6d63e4f378908b809de104a24820.tar.xz
Update ProfileEditor plugin
ProfileEditor: - add tests - disable read-only settings on otr profiles Add WebProfile::setHeaders and WebProfile::setCookies
-rw-r--r--include/smolbote/plugininterface.hpp18
-rw-r--r--meson.build3
-rw-r--r--plugins/ProfileEditor/ProfileEditor.json5
-rw-r--r--plugins/ProfileEditor/forms/newhttpheaderdialog.cpp32
-rw-r--r--plugins/ProfileEditor/forms/newhttpheaderdialog.h33
-rw-r--r--plugins/ProfileEditor/forms/newhttpheaderdialog.ui84
-rw-r--r--plugins/ProfileEditor/forms/newprofiledialog.cpp32
-rw-r--r--plugins/ProfileEditor/forms/newprofiledialog.h33
-rw-r--r--plugins/ProfileEditor/forms/newprofiledialog.ui81
-rw-r--r--plugins/ProfileEditor/forms/profilemanagerdialog.cpp30
-rw-r--r--plugins/ProfileEditor/forms/profilemanagerdialog.h18
-rw-r--r--plugins/ProfileEditor/forms/profilemanagerdialog.ui24
-rw-r--r--plugins/ProfileEditor/forms/profileview.cpp153
-rw-r--r--plugins/ProfileEditor/forms/profileview.h12
-rw-r--r--plugins/ProfileEditor/forms/profileview.ui535
-rw-r--r--plugins/ProfileEditor/forms/settingstable.cpp90
-rw-r--r--plugins/ProfileEditor/forms/settingstable.h31
-rw-r--r--plugins/ProfileEditor/meson.build17
-rw-r--r--plugins/ProfileEditor/profileeditorplugin.cpp36
-rw-r--r--plugins/ProfileEditor/profileeditorplugin.h7
-rw-r--r--plugins/ProfileEditor/test/main.cpp22
-rw-r--r--src/about/aboutdialog.ui5
-rw-r--r--src/about/aboutplugin.cpp60
-rw-r--r--src/about/aboutplugin.h3
-rw-r--r--src/about/aboutplugin.ui53
-rw-r--r--src/applicationmenu.cpp18
-rw-r--r--src/applicationmenu.h1
-rw-r--r--src/browser.cpp58
-rw-r--r--src/browser.h9
-rw-r--r--src/main.cpp14
-rw-r--r--src/webengine/meson.build2
-rw-r--r--src/webengine/test/profile.cpp145
-rw-r--r--src/webengine/webprofile.cpp18
-rw-r--r--src/webengine/webprofile.h62
-rw-r--r--src/webengine/webprofilemanager.cpp4
-rw-r--r--src/webengine/webprofilemanager.h2
36 files changed, 757 insertions, 993 deletions
diff --git a/include/smolbote/plugininterface.hpp b/include/smolbote/plugininterface.hpp
index 5fa4530..328cba5 100644
--- a/include/smolbote/plugininterface.hpp
+++ b/include/smolbote/plugininterface.hpp
@@ -9,14 +9,28 @@
#ifndef SMOLBOTE_PLUGIN_INTERFACE_HPP
#define SMOLBOTE_PLUGIN_INTERFACE_HPP
+#include <QDialog>
#include <QtPlugin>
+#include <QSettings>
+
+class QWebEngineProfile;
+class ProfileDialog : public QDialog
+{
+public:
+ ProfileDialog(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags())
+ : QDialog(parent, f)
+ {
+ }
+ virtual ~ProfileDialog() = default;
+ virtual int addProfile(const QString &id, const QString name, QWebEngineProfile *profile, QSettings *settings) = 0;
+ virtual void showProfile(int index) = 0;
+};
-class QDialog;
class PluginInterface
{
public:
virtual ~PluginInterface() = default;
- virtual QDialog *createWidget(QWidget *parent = nullptr) const = 0;
+ virtual QDialog *createWidget(QWidget *parent) const = 0;
};
#define PluginInterfaceIid "net.iserlohn-fortress.smolbote.PluginInterface"
diff --git a/meson.build b/meson.build
index 3cf7105..c180449 100644
--- a/meson.build
+++ b/meson.build
@@ -91,8 +91,7 @@ subdir('lang')
subdir('doc')
subdir('tools')
-#subdir('plugins/ConfigurationEditor')
-#subdir('plugins/ProfileEditor')
+subdir('plugins/ProfileEditor')
subdir('test/firefox-bookmarks-json-parser')
diff --git a/plugins/ProfileEditor/ProfileEditor.json b/plugins/ProfileEditor/ProfileEditor.json
index 8381e9a..afa0a1f 100644
--- a/plugins/ProfileEditor/ProfileEditor.json
+++ b/plugins/ProfileEditor/ProfileEditor.json
@@ -1,5 +1,6 @@
{
"name": "Profile Editor",
- "author": "Aqua-sama",
- "shortcut": "Ctrl+Shift+E"
+ "author": "aqua@",
+ "shortcut": "Ctrl+Shift+E",
+ "license": "GPL3"
}
diff --git a/plugins/ProfileEditor/forms/newhttpheaderdialog.cpp b/plugins/ProfileEditor/forms/newhttpheaderdialog.cpp
deleted file mode 100644
index 3978c4e..0000000
--- a/plugins/ProfileEditor/forms/newhttpheaderdialog.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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 "newhttpheaderdialog.h"
-#include "ui_newhttpheaderdialog.h"
-
-NewHttpHeaderDialog::NewHttpHeaderDialog(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::NewHttpHeaderDialog)
-{
- ui->setupUi(this);
-}
-
-NewHttpHeaderDialog::~NewHttpHeaderDialog()
-{
- delete ui;
-}
-
-QString NewHttpHeaderDialog::header() const
-{
- return ui->header->text();
-}
-
-QString NewHttpHeaderDialog::value() const
-{
- return ui->value->text();
-}
diff --git a/plugins/ProfileEditor/forms/newhttpheaderdialog.h b/plugins/ProfileEditor/forms/newhttpheaderdialog.h
deleted file mode 100644
index 53a2a80..0000000
--- a/plugins/ProfileEditor/forms/newhttpheaderdialog.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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 NEWHTTPHEADERDIALOG_H
-#define NEWHTTPHEADERDIALOG_H
-
-#include <QDialog>
-
-namespace Ui {
-class NewHttpHeaderDialog;
-}
-
-class NewHttpHeaderDialog : public QDialog
-{
- Q_OBJECT
-
-public:
- explicit NewHttpHeaderDialog(QWidget *parent = nullptr);
- ~NewHttpHeaderDialog();
-
- QString header() const;
- QString value() const;
-
-private:
- Ui::NewHttpHeaderDialog *ui;
-};
-
-#endif // NEWHTTPHEADERDIALOG_H
diff --git a/plugins/ProfileEditor/forms/newhttpheaderdialog.ui b/plugins/ProfileEditor/forms/newhttpheaderdialog.ui
deleted file mode 100644
index a457ba6..0000000
--- a/plugins/ProfileEditor/forms/newhttpheaderdialog.ui
+++ /dev/null
@@ -1,84 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>NewHttpHeaderDialog</class>
- <widget class="QDialog" name="NewHttpHeaderDialog">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>320</width>
- <height>108</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>Dialog</string>
- </property>
- <layout class="QFormLayout" name="formLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="header_label">
- <property name="text">
- <string>Header</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLineEdit" name="header"/>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="value_label">
- <property name="text">
- <string>Value</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLineEdit" name="value"/>
- </item>
- <item row="2" column="0" colspan="2">
- <widget class="QDialogButtonBox" name="buttonBox">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections>
- <connection>
- <sender>buttonBox</sender>
- <signal>accepted()</signal>
- <receiver>NewHttpHeaderDialog</receiver>
- <slot>accept()</slot>
- <hints>
- <hint type="sourcelabel">
- <x>248</x>
- <y>254</y>
- </hint>
- <hint type="destinationlabel">
- <x>157</x>
- <y>274</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>buttonBox</sender>
- <signal>rejected()</signal>
- <receiver>NewHttpHeaderDialog</receiver>
- <slot>reject()</slot>
- <hints>
- <hint type="sourcelabel">
- <x>316</x>
- <y>260</y>
- </hint>
- <hint type="destinationlabel">
- <x>286</x>
- <y>274</y>
- </hint>
- </hints>
- </connection>
- </connections>
-</ui>
diff --git a/plugins/ProfileEditor/forms/newprofiledialog.cpp b/plugins/ProfileEditor/forms/newprofiledialog.cpp
deleted file mode 100644
index 3ed61d8..0000000
--- a/plugins/ProfileEditor/forms/newprofiledialog.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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 "newprofiledialog.h"
-#include "ui_newprofiledialog.h"
-
-NewProfileDialog::NewProfileDialog(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::NewProfileDialog)
-{
- ui->setupUi(this);
-}
-
-NewProfileDialog::~NewProfileDialog()
-{
- delete ui;
-}
-
-const QString NewProfileDialog::getId() const
-{
- return ui->id_lineEdit->text();
-}
-
-bool NewProfileDialog::getOtr() const
-{
- return ui->offTheRecord->isChecked();
-}
diff --git a/plugins/ProfileEditor/forms/newprofiledialog.h b/plugins/ProfileEditor/forms/newprofiledialog.h
deleted file mode 100644
index dd9aa4e..0000000
--- a/plugins/ProfileEditor/forms/newprofiledialog.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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 NEWPROFILEDIALOG_H
-#define NEWPROFILEDIALOG_H
-
-#include <QDialog>
-
-namespace Ui {
-class NewProfileDialog;
-}
-
-class NewProfileDialog : public QDialog
-{
- Q_OBJECT
-
-public:
- explicit NewProfileDialog(QWidget *parent = nullptr);
- ~NewProfileDialog();
-
- const QString getId() const;
- bool getOtr() const;
-
-private:
- Ui::NewProfileDialog *ui;
-};
-
-#endif // NEWPROFILEDIALOG_H
diff --git a/plugins/ProfileEditor/forms/newprofiledialog.ui b/plugins/ProfileEditor/forms/newprofiledialog.ui
deleted file mode 100644
index 8b4888d..0000000
--- a/plugins/ProfileEditor/forms/newprofiledialog.ui
+++ /dev/null
@@ -1,81 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>NewProfileDialog</class>
- <widget class="QDialog" name="NewProfileDialog">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>320</width>
- <height>112</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>New Profile</string>
- </property>
- <layout class="QFormLayout" name="formLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="id_label">
- <property name="text">
- <string>ID</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLineEdit" name="id_lineEdit"/>
- </item>
- <item row="2" column="0" colspan="2">
- <widget class="QDialogButtonBox" name="buttonBox">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QCheckBox" name="offTheRecord">
- <property name="text">
- <string>Off the record</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections>
- <connection>
- <sender>buttonBox</sender>
- <signal>accepted()</signal>
- <receiver>NewProfileDialog</receiver>
- <slot>accept()</slot>
- <hints>
- <hint type="sourcelabel">
- <x>248</x>
- <y>254</y>
- </hint>
- <hint type="destinationlabel">
- <x>157</x>
- <y>274</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>buttonBox</sender>
- <signal>rejected()</signal>
- <receiver>NewProfileDialog</receiver>
- <slot>reject()</slot>
- <hints>
- <hint type="sourcelabel">
- <x>316</x>
- <y>260</y>
- </hint>
- <hint type="destinationlabel">
- <x>286</x>
- <y>274</y>
- </hint>
- </hints>
- </connection>
- </connections>
-</ui>
diff --git a/plugins/ProfileEditor/forms/profilemanagerdialog.cpp b/plugins/ProfileEditor/forms/profilemanagerdialog.cpp
index f5a17b1..6cbc806 100644
--- a/plugins/ProfileEditor/forms/profilemanagerdialog.cpp
+++ b/plugins/ProfileEditor/forms/profilemanagerdialog.cpp
@@ -10,15 +10,14 @@
#include "profileview.h"
#include <QDir>
#include <QPointer>
+#include "ui_profilemanagerdialog.h"
ProfileManagerDialog::ProfileManagerDialog(QWidget *parent)
- : QDialog(parent)
+ : ProfileDialog(parent)
, ui(new Ui::ProfileManagerDialog)
{
ui->setupUi(this);
-
- connect(ui->listWidget, &QListWidget::itemPressed, this, &ProfileManagerDialog::showProfile);
- showProfile(nullptr);
+ connect(ui->listWidget, &QListWidget::itemPressed, this, &ProfileManagerDialog::showItem);
}
ProfileManagerDialog::~ProfileManagerDialog()
@@ -26,17 +25,26 @@ ProfileManagerDialog::~ProfileManagerDialog()
delete ui;
}
-void ProfileManagerDialog::addProfile(const QString &id, Profile *profile)
+int ProfileManagerDialog::addProfile(const QString &id, const QString name, QWebEngineProfile *profile, QSettings *settings)
{
Q_CHECK_PTR(profile);
auto *item = new QListWidgetItem(id, ui->listWidget);
- auto pointer = QPointer<Profile>(profile);
- item->setData(Qt::UserRole, QVariant::fromValue(pointer));
+ item->setData(Qt::UserRole, name);
+ item->setData(Qt::UserRole+1, QVariant::fromValue(QPointer<QWebEngineProfile>(profile)));
+ item->setData(Qt::UserRole+2, QVariant::fromValue(QPointer<QSettings>(settings)));
+
+ return ui->listWidget->count() - 1;
+}
+
+void ProfileManagerDialog::showProfile(int index)
+{
+ auto *item = ui->listWidget->item(index);
+ showItem(item);
}
-void ProfileManagerDialog::showProfile(QListWidgetItem *item)
+void ProfileManagerDialog::showItem(QListWidgetItem *item)
{
// clear out groupbox layout
QLayoutItem *i;
@@ -51,8 +59,10 @@ void ProfileManagerDialog::showProfile(QListWidgetItem *item)
}
ui->groupBox->setVisible(true);
- auto profile = item->data(Qt::UserRole).value<QPointer<Profile>>();
- auto *v = new ProfileView(profile.data(), this);
+ const auto name = item->data(Qt::UserRole).value<QString>();
+ auto profile = item->data(Qt::UserRole+1).value<QPointer<QWebEngineProfile>>();
+ auto settings = item->data(Qt::UserRole+2).value<QPointer<QSettings>>();
+ auto *v = new ProfileView(name, profile.data(), settings.data(), this);
ui->groupBox->layout()->addWidget(v);
v->adjustSize();
}
diff --git a/plugins/ProfileEditor/forms/profilemanagerdialog.h b/plugins/ProfileEditor/forms/profilemanagerdialog.h
index fe91948..8dd307e 100644
--- a/plugins/ProfileEditor/forms/profilemanagerdialog.h
+++ b/plugins/ProfileEditor/forms/profilemanagerdialog.h
@@ -11,12 +11,15 @@
#include <QDialog>
#include <QVector>
-#include <profileinterface.h>
-#include "ui_profilemanagerdialog.h"
+#include <QWebEngineProfile>
+#include <smolbote/plugininterface.hpp>
+
+namespace Ui {
+ class ProfileManagerDialog;
+}
-class WebProfile;
class QListWidgetItem;
-class ProfileManagerDialog : public QDialog
+class ProfileManagerDialog : public ProfileDialog
{
Q_OBJECT
@@ -27,10 +30,9 @@ public:
~ProfileManagerDialog() override;
public slots:
- void addProfile(const QString &id, Profile *profile);
-
-private slots:
- void showProfile(QListWidgetItem *item);
+ int addProfile(const QString &id, const QString name, QWebEngineProfile *profile, QSettings *settings) override;
+ void showProfile(int index) override;
+ void showItem(QListWidgetItem *item);
private:
Ui::ProfileManagerDialog *ui;
diff --git a/plugins/ProfileEditor/forms/profilemanagerdialog.ui b/plugins/ProfileEditor/forms/profilemanagerdialog.ui
index f41b1b0..b715b86 100644
--- a/plugins/ProfileEditor/forms/profilemanagerdialog.ui
+++ b/plugins/ProfileEditor/forms/profilemanagerdialog.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>400</width>
- <height>300</height>
+ <width>918</width>
+ <height>600</height>
</rect>
</property>
<property name="windowTitle">
@@ -34,6 +34,12 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
+ <property name="minimumSize">
+ <size>
+ <width>640</width>
+ <height>0</height>
+ </size>
+ </property>
<layout class="QVBoxLayout" name="verticalLayout_2"/>
</widget>
</item>
@@ -42,20 +48,6 @@
<item>
<layout class="QHBoxLayout" name="buttons_horizontalLayout">
<item>
- <widget class="QPushButton" name="new_pushButton">
- <property name="text">
- <string>New</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="delete_pushButton">
- <property name="text">
- <string>Delete</string>
- </property>
- </widget>
- </item>
- <item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
diff --git a/plugins/ProfileEditor/forms/profileview.cpp b/plugins/ProfileEditor/forms/profileview.cpp
index 9a19cfc..992364c 100644
--- a/plugins/ProfileEditor/forms/profileview.cpp
+++ b/plugins/ProfileEditor/forms/profileview.cpp
@@ -1,29 +1,26 @@
/*
* 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
+ * location: https://neueland.iserlohn-fortress.net/cgit/smolbote
*
* SPDX-License-Identifier: GPL-3.0
*/
#include "profileview.h"
#include "ui_profileview.h"
-#include <profileinterface.h>
-#include <QWebEngineSettings>
-#include <QWebEngineCookieStore>
#include <QDateTime>
-#include "newhttpheaderdialog.h"
+#include <QWebEngineCookieStore>
+#include <QWebEngineSettings>
-inline void connectSetting(QCheckBox *checkBox, Profile *profile, QWebEngineSettings::WebAttribute attr)
+inline void connectSetting(QCheckBox *checkBox, QWebEngineProfile *profile, QWebEngineSettings::WebAttribute attr)
{
checkBox->setChecked(profile->settings()->testAttribute(attr));
QObject::connect(checkBox, &QCheckBox::clicked, [profile, attr](bool checked) {
profile->settings()->setAttribute(attr, checked);
- emit profile->attributeChanged(attr, checked);
});
}
-ProfileView::ProfileView(Profile *profile, QWidget *parent)
+ProfileView::ProfileView(const QString &name, QWebEngineProfile *profile, QSettings *settings, QWidget *parent)
: QWidget(parent)
, ui(new Ui::ProfileView)
{
@@ -32,52 +29,37 @@ ProfileView::ProfileView(Profile *profile, QWidget *parent)
ui->setupUi(this);
// general tab
- ui->name->setText(profile->name());
- connect(ui->name, &QLineEdit::editingFinished, profile, [=]() {
- profile->setName(ui->name->text());
- });
-
+ ui->name->setText(name);
ui->offTheRecord->setChecked(profile->isOffTheRecord());
- ui->homepage->setText(profile->homepage().toString());
- connect(ui->homepage, &QLineEdit::editingFinished, profile, [=]() {
- profile->setHomepage(QUrl::fromUserInput(ui->homepage->text()));
- });
-
- ui->newtab->setText(profile->newtab().toString());
- connect(ui->newtab, &QLineEdit::editingFinished, profile, [=]() {
- profile->setNewtab(QUrl::fromUserInput(ui->newtab->text()));
- });
-
- ui->search->setText(profile->search());
- connect(ui->search, &QLineEdit::editingFinished, profile, [=]() {
- profile->setSearch(ui->search->text());
- });
+ ui->settings_table->connect(settings);
// http tab
ui->userAgent->setPlainText(m_profile->httpUserAgent());
- connect(ui->userAgent, &QPlainTextEdit::textChanged, profile, [=]() {
+ connect(ui->userAgent, &QPlainTextEdit::textChanged, profile, [this, profile]() {
profile->setHttpUserAgent(ui->userAgent->toPlainText());
});
ui->acceptLanguage->setPlainText(m_profile->httpAcceptLanguage());
- connect(ui->acceptLanguage, &QPlainTextEdit::textChanged, profile, [=]() {
+ connect(ui->acceptLanguage, &QPlainTextEdit::textChanged, profile, [this, profile]() {
profile->setHttpAcceptLanguage(ui->acceptLanguage->toPlainText());
});
+ ui->headers_table->connect(settings, "headers");
+
ui->cacheType->setCurrentIndex(m_profile->httpCacheType());
- connect(ui->cacheType, QOverload<int>::of(&QComboBox::currentIndexChanged), profile, [=](int index) {
- profile->setHttpCacheType(index);
+ connect(ui->cacheType, QOverload<int>::of(&QComboBox::currentIndexChanged), profile, [profile](int index) {
+ profile->setHttpCacheType(static_cast<QWebEngineProfile::HttpCacheType>(index));
});
ui->cacheSize->setText(QString::number(m_profile->httpCacheMaximumSize()));
- connect(ui->cacheSize, &QLineEdit::textChanged, profile, [=](const QString &text) {
+ connect(ui->cacheSize, &QLineEdit::textChanged, profile, [profile](const QString &text) {
profile->setHttpCacheMaximumSize(text.toInt());
});
ui->cookiePolicy->setCurrentIndex(m_profile->persistentCookiesPolicy());
- connect(ui->cookiePolicy, QOverload<int>::of(&QComboBox::currentIndexChanged), profile, [=](int index) {
- profile->setPersistentCookiesPolicy(index);
+ connect(ui->cookiePolicy, QOverload<int>::of(&QComboBox::currentIndexChanged), profile, [profile](int index) {
+ profile->setPersistentCookiesPolicy(static_cast<QWebEngineProfile::PersistentCookiesPolicy>(index));
});
connect(ui->clearCache_pushButton, &QPushButton::clicked, profile, &QWebEngineProfile::clearHttpCache);
@@ -86,28 +68,13 @@ ProfileView::ProfileView(Profile *profile, QWidget *parent)
ui->storagePath_lineEdit->setText(m_profile->persistentStoragePath());
ui->cachePath_lineEdit->setText(m_profile->cachePath());
- // headers tab
- for(auto i = m_profile->headers().constBegin(); i != m_profile->headers().constEnd(); ++i) {
- //ui->httpHeaders->addItem();
- headerChanged(i.key(), i.value());
+ if(profile->isOffTheRecord()) {
+ ui->cacheType->setEnabled(false);
+ ui->cacheSize->setEnabled(false);
+ ui->storagePath_lineEdit->setEnabled(false);
+ ui->cachePath_lineEdit->setEnabled(false);
+ ui->cookiePolicy->setEnabled(false);
}
- connect(m_profile, &Profile::headerChanged, this, &ProfileView::headerChanged);
- connect(m_profile, &Profile::headerRemoved, this, &ProfileView::headerRemoved);
- connect(ui->headers_insert, &QPushButton::clicked, m_profile, [this]() {
- auto *dlg = new NewHttpHeaderDialog(this);
- if(dlg->exec() == QDialog::Accepted) {
- m_profile->setHttpHeader(dlg->header(), dlg->value());
- }
- delete dlg;
- });
- connect(ui->headers_delete, &QPushButton::clicked, m_profile, [this]() {
- for(auto &list : ui->httpHeaders->selectedRanges()) {
- for(int i = list.bottomRow(); i >= list.topRow(); --i) {
- m_profile->removeHttpHeader(ui->httpHeaders->item(i, 0)->text());
- }
- }
- });
-
// settings tab
connectSetting(ui->autoloadImages, m_profile, QWebEngineSettings::AutoLoadImages);
connectSetting(ui->autoloadIcons, m_profile, QWebEngineSettings::AutoLoadIconsForPage);
@@ -144,62 +111,39 @@ ProfileView::ProfileView(Profile *profile, QWidget *parent)
connectSetting(ui->printElementBackgrounds, m_profile, QWebEngineSettings::PrintElementBackgrounds);
// cookies tab
- loadCookies(profile->cookieStore());
- for(const auto &c : profile->cookies()) {
- cookieAdded(c);
+ for(const auto &data : profile->property("cookies").toList()) {
+ for(const auto &cookie : QNetworkCookie::parseCookies(data.toByteArray())) {
+ cookieAdded(cookie);
+ }
}
-}
-ProfileView::~ProfileView()
-{
- delete ui;
-}
+ connect(profile->cookieStore(), &QWebEngineCookieStore::cookieAdded, this, &ProfileView::cookieAdded);
+ connect(profile->cookieStore(), &QWebEngineCookieStore::cookieRemoved, this, &ProfileView::cookieRemoved);
-void ProfileView::loadCookies(QWebEngineCookieStore *store)
-{
- //
- connect(store, &QWebEngineCookieStore::cookieAdded, this, &ProfileView::cookieAdded);
- connect(store, &QWebEngineCookieStore::cookieRemoved, this, &ProfileView::cookieRemoved);
+ connect(ui->cookies_deleteSession, &QPushButton::clicked, profile->cookieStore(), &QWebEngineCookieStore::deleteSessionCookies);
+ connect(ui->cookies_deleteAll, &QPushButton::clicked, profile->cookieStore(), &QWebEngineCookieStore::deleteAllCookies);
- connect(ui->cookies_reload, &QPushButton::clicked, store, [=]() {
- ui->cookies->clearContents();
- ui->cookies->setRowCount(0);
- store->loadAllCookies();
- });
-
- connect(ui->cookies_delete, &QPushButton::clicked, store, [=]() {
+ connect(ui->cookies_delete, &QPushButton::clicked, [this, profile]() {
for(auto &list : ui->cookies->selectedRanges()) {
for(int i = list.bottomRow(); i >= list.topRow(); --i) {
auto cookie = ui->cookies->item(i, 0)->data(Qt::UserRole).value<QNetworkCookie>();
- store->deleteCookie(cookie);
+ profile->cookieStore()->deleteCookie(cookie);
}
}
});
- connect(ui->cookies_deleteSession, &QPushButton::clicked, store, &QWebEngineCookieStore::deleteSessionCookies);
- connect(ui->cookies_deleteAll, &QPushButton::clicked, store, &QWebEngineCookieStore::deleteAllCookies);
-}
-void ProfileView::headerChanged(const QString &name, const QString &value)
-{
- const auto items = ui->httpHeaders->findItems(name, Qt::MatchExactly);
- if(!items.isEmpty()) {
- QTableWidgetItem *valueItem = ui->httpHeaders->item(items.constFirst()->row(), 1);
- valueItem->setText(value);
- } else {
- // new header
- const int index = ui->httpHeaders->rowCount();
- ui->httpHeaders->setRowCount(index + 1);
- ui->httpHeaders->setItem(index, 0, new QTableWidgetItem(name));
- ui->httpHeaders->setItem(index, 1, new QTableWidgetItem(value));
- }
+ connect(ui->cookies_reload, &QPushButton::clicked, [this, profile]() {
+ ui->cookies->clearContents();
+ ui->cookies->setRowCount(0);
+ qDebug("loadAllCookies called!");
+ profile->cookieStore()->loadAllCookies();
+ });
+
}
-void ProfileView::headerRemoved(const QString& name)
+ProfileView::~ProfileView()
{
- const auto items = ui->httpHeaders->findItems(name, Qt::MatchExactly);
- if(!items.isEmpty()) {
- ui->httpHeaders->removeRow(items.constFirst()->row());
- }
+ delete ui;
}
void ProfileView::cookieAdded(const QNetworkCookie &cookie)
@@ -212,21 +156,24 @@ void ProfileView::cookieAdded(const QNetworkCookie &cookie)
ui->cookies->setItem(index, 0, item);
ui->cookies->setItem(index, 1, new QTableWidgetItem(cookie.domain()));
ui->cookies->setItem(index, 2, new QTableWidgetItem(cookie.path()));
- if(cookie.isSessionCookie())
+ if(cookie.isSessionCookie()) {
ui->cookies->setItem(index, 3, new QTableWidgetItem(tr("session")));
- else
+ } else {
ui->cookies->setItem(index, 3, new QTableWidgetItem(cookie.expirationDate().toString(Qt::RFC2822Date)));
+ }
}
void ProfileView::cookieRemoved(const QNetworkCookie &cookie)
{
+ qDebug("cookieRemoved called");
+
for(int i = 0; i < ui->cookies->rowCount(); ++i) {
auto *item = ui->cookies->item(i, 0);
- if(item->data(Qt::UserRole).value<QNetworkCookie>() == cookie) {
- //qDebug("removing cookie on row %i", i);
+ if(item->data(Qt::UserRole).value<QNetworkCookie>().hasSameIdentifier(cookie)) {
+ qDebug("removing cookie on row %i", i);
ui->cookies->removeRow(i);
- break;
+ return;
}
+ qDebug("cookie on row %i doesn't have the same identifier", i);
}
}
-
diff --git a/plugins/ProfileEditor/forms/profileview.h b/plugins/ProfileEditor/forms/profileview.h
index 7f3e738..9b4506a 100644
--- a/plugins/ProfileEditor/forms/profileview.h
+++ b/plugins/ProfileEditor/forms/profileview.h
@@ -12,13 +12,14 @@
#include <QWidget>
#include <QNetworkCookie>
#include <QWebEngineSettings>
+#include <QWebEngineProfile>
+#include <QSettings>
namespace Ui
{
class ProfileView;
}
-class Profile;
class QWebEngineCookieStore;
class QCheckBox;
@@ -27,21 +28,16 @@ class ProfileView : public QWidget
Q_OBJECT
public:
- explicit ProfileView(Profile *profile, QWidget *parent = nullptr);
+ explicit ProfileView(const QString &name, QWebEngineProfile *profile, QSettings *settings, QWidget *parent = nullptr);
~ProfileView() override;
private slots:
- void loadCookies(QWebEngineCookieStore *store);
-
- void headerChanged(const QString &name, const QString &value);
- void headerRemoved(const QString &name);
-
void cookieAdded(const QNetworkCookie &cookie);
void cookieRemoved(const QNetworkCookie &cookie);
private:
Ui::ProfileView *ui;
- Profile *m_profile;
+ QWebEngineProfile *m_profile;
};
#endif // PROFILEDIALOG_H
diff --git a/plugins/ProfileEditor/forms/profileview.ui b/plugins/ProfileEditor/forms/profileview.ui
index 630e53d..46e0a68 100644
--- a/plugins/ProfileEditor/forms/profileview.ui
+++ b/plugins/ProfileEditor/forms/profileview.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>640</width>
- <height>504</height>
+ <height>510</height>
</rect>
</property>
<property name="minimumSize">
@@ -19,7 +19,7 @@
<property name="windowTitle">
<string>Profile</string>
</property>
- <layout class="QVBoxLayout" name="verticalLayout">
+ <layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
@@ -29,76 +29,58 @@
<attribute name="title">
<string>General</string>
</attribute>
- <layout class="QFormLayout" name="formLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="name_label">
- <property name="text">
- <string>Name</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLineEdit" name="name"/>
- </item>
- <item row="1" column="1">
- <widget class="QCheckBox" name="offTheRecord">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Off-the-record</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLineEdit" name="configurationPath">
- <property name="enabled">
- <bool>false</bool>
- </property>
- </widget>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="name">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="offTheRecord">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Off-the-record</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
- <item row="2" column="0">
- <widget class="QLabel" name="configurationPath_label">
- <property name="text">
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
<string>Configuration</string>
</property>
- </widget>
- </item>
- <item row="4" column="0">
- <widget class="QLabel" name="homepage_label">
- <property name="text">
- <string>Homepage</string>
- </property>
- </widget>
- </item>
- <item row="5" column="0">
- <widget class="QLabel" name="newtab_label">
- <property name="text">
- <string>New tab page</string>
- </property>
- </widget>
- </item>
- <item row="6" column="0">
- <widget class="QLabel" name="search_label">
- <property name="text">
- <string>Search</string>
- </property>
- </widget>
- </item>
- <item row="5" column="1">
- <widget class="QLineEdit" name="newtab"/>
- </item>
- <item row="6" column="1">
- <widget class="QLineEdit" name="search"/>
- </item>
- <item row="4" column="1">
- <widget class="QLineEdit" name="homepage"/>
- </item>
- <item row="3" column="1">
- <widget class="Line" name="line_8">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
+ <property name="flat">
+ <bool>true</bool>
</property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="SettingsTable" name="settings_table">
+ <attribute name="horizontalHeaderStretchLastSection">
+ <bool>true</bool>
+ </attribute>
+ <attribute name="verticalHeaderVisible">
+ <bool>false</bool>
+ </attribute>
+ <column>
+ <property name="text">
+ <string>Key</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Value</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ </layout>
</widget>
</item>
</layout>
@@ -125,176 +107,150 @@
</property>
</widget>
</item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>Cache Type</string>
- </property>
+ <item row="1" column="1">
+ <widget class="QPlainTextEdit" name="acceptLanguage"/>
+ </item>
+ <item row="3" column="1">
+ <widget class="SettingsTable" name="headers_table">
+ <attribute name="horizontalHeaderStretchLastSection">
+ <bool>true</bool>
+ </attribute>
+ <attribute name="verticalHeaderVisible">
+ <bool>false</bool>
+ </attribute>
+ <column>
+ <property name="text">
+ <string>Key</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Value</string>
+ </property>
+ </column>
</widget>
</item>
<item row="3" column="0">
- <widget class="QLabel" name="label_6">
+ <widget class="QLabel" name="label_2">
<property name="text">
- <string>Cache Size</string>
+ <string>Headers</string>
</property>
</widget>
</item>
- <item row="1" column="1">
- <widget class="QPlainTextEdit" name="acceptLanguage"/>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="storageTab">
+ <attribute name="title">
+ <string>Storage</string>
+ </attribute>
+ <layout class="QFormLayout" name="formLayout_3">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Cache Type</string>
+ </property>
+ </widget>
</item>
- <item row="2" column="1">
- <widget class="QComboBox" name="cacheType">
+ <item row="0" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
- <property name="text">
- <string>Memory Cache</string>
- </property>
+ <widget class="QComboBox" name="cacheType">
+ <item>
+ <property name="text">
+ <string>Memory Cache</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Disk Cache</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Disabled</string>
+ </property>
+ </item>
+ </widget>
</item>
<item>
- <property name="text">
- <string>Disk Cache</string>
- </property>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
</item>
<item>
- <property name="text">
- <string>Disabled</string>
- </property>
+ <widget class="QPushButton" name="clearCache_pushButton">
+ <property name="text">
+ <string>Clear Cache</string>
+ </property>
+ </widget>
</item>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QLineEdit" name="cacheSize"/>
+ </layout>
</item>
- <item row="6" column="0">
- <widget class="QLabel" name="storagePath_label">
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_6">
<property name="text">
- <string>Storage Path</string>
+ <string>Cache Size</string>
</property>
</widget>
</item>
- <item row="6" column="1">
- <widget class="QLineEdit" name="storagePath_lineEdit">
- <property name="enabled">
- <bool>false</bool>
- </property>
- </widget>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="cacheSize"/>
</item>
- <item row="4" column="0">
+ <item row="2" column="0">
<widget class="QLabel" name="cachePath_label">
<property name="text">
<string>Cache Path</string>
</property>
</widget>
</item>
- <item row="4" column="1">
+ <item row="2" column="1">
<widget class="QLineEdit" name="cachePath_lineEdit">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
- <item row="5" column="1">
- <widget class="QPushButton" name="clearCache_pushButton">
+ <item row="3" column="0">
+ <widget class="QLabel" name="storagePath_label">
<property name="text">
- <string>Clear Cache</string>
+ <string>Storage Path</string>
</property>
</widget>
</item>
- <item row="7" column="0">
- <widget class="QLabel" name="cookiePolicy_label">
- <property name="text">
- <string>Cookies</string>
+ <item row="3" column="1">
+ <widget class="QLineEdit" name="storagePath_lineEdit">
+ <property name="enabled">
+ <bool>false</bool>
</property>
</widget>
</item>
- <item row="7" column="1">
- <widget class="QComboBox" name="cookiePolicy">
- <item>
- <property name="text">
- <string>No Persistent Cookies</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Allow Persistent Cookies</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Force Persistent Cookies</string>
- </property>
- </item>
- </widget>
- </item>
- <item row="8" column="1">
+ <item row="4" column="1">
<widget class="QPushButton" name="clearHistory_pushButton">
<property name="text">
<string>Clear History</string>
</property>
</widget>
</item>
- </layout>
- </widget>
- <widget class="QWidget" name="httpHeadersTab">
- <attribute name="title">
- <string>Headers</string>
- </attribute>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <item>
- <widget class="QTableWidget" name="httpHeaders">
- <attribute name="horizontalHeaderDefaultSectionSize">
- <number>200</number>
- </attribute>
- <attribute name="horizontalHeaderMinimumSectionSize">
- <number>100</number>
- </attribute>
- <attribute name="horizontalHeaderStretchLastSection">
- <bool>true</bool>
- </attribute>
- <attribute name="verticalHeaderVisible">
- <bool>false</bool>
- </attribute>
- <column>
- <property name="text">
- <string>Name</string>
- </property>
- </column>
- <column>
- <property name="text">
- <string>Value</string>
- </property>
- </column>
- </widget>
- </item>
- <item>
- <layout class="QVBoxLayout" name="verticalLayout_3">
- <item>
- <widget class="QPushButton" name="headers_insert">
- <property name="text">
- <string>Insert</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="headers_delete">
- <property name="text">
- <string>Delete</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer_2">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
+ <item row="5" column="1">
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
</item>
</layout>
</widget>
@@ -313,7 +269,7 @@
<rect>
<x>0</x>
<y>0</y>
- <width>584</width>
+ <width>273</width>
<height>797</height>
</rect>
</property>
@@ -559,94 +515,128 @@
<attribute name="title">
<string>Cookies</string>
</attribute>
- <layout class="QHBoxLayout" name="horizontalLayout">
+ <layout class="QVBoxLayout" name="verticalLayout_6">
<item>
- <widget class="QTableWidget" name="cookies">
- <property name="sizeAdjustPolicy">
- <enum>QAbstractScrollArea::AdjustToContents</enum>
- </property>
- <property name="editTriggers">
- <set>QAbstractItemView::NoEditTriggers</set>
- </property>
- <property name="selectionBehavior">
- <enum>QAbstractItemView::SelectRows</enum>
- </property>
- <property name="cornerButtonEnabled">
- <bool>false</bool>
- </property>
- <attribute name="horizontalHeaderHighlightSections">
- <bool>false</bool>
- </attribute>
- <attribute name="horizontalHeaderStretchLastSection">
- <bool>true</bool>
- </attribute>
- <attribute name="verticalHeaderVisible">
- <bool>false</bool>
- </attribute>
- <column>
- <property name="text">
- <string>Name</string>
- </property>
- </column>
- <column>
- <property name="text">
- <string>Domain</string>
- </property>
- </column>
- <column>
- <property name="text">
- <string>Path</string>
- </property>
- </column>
- <column>
- <property name="text">
- <string>Expires</string>
- </property>
- </column>
- </widget>
- </item>
- <item>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <widget class="QPushButton" name="cookies_reload">
+ <layout class="QFormLayout" name="formLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="cookiePolicy_label">
<property name="text">
- <string>Reload</string>
+ <string>Cookies</string>
</property>
</widget>
</item>
- <item>
- <widget class="QPushButton" name="cookies_delete">
- <property name="text">
- <string>Delete</string>
- </property>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="cookiePolicy">
+ <item>
+ <property name="text">
+ <string>No Persistent Cookies</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Allow Persistent Cookies</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Force Persistent Cookies</string>
+ </property>
+ </item>
</widget>
</item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
<item>
- <widget class="QPushButton" name="cookies_deleteSession">
- <property name="text">
- <string>Delete Session</string>
+ <widget class="QTableWidget" name="cookies">
+ <property name="sizeAdjustPolicy">
+ <enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="cookies_deleteAll">
- <property name="text">
- <string>Delete All</string>
+ <property name="editTriggers">
+ <set>QAbstractItemView::NoEditTriggers</set>
+ </property>
+ <property name="selectionBehavior">
+ <enum>QAbstractItemView::SelectRows</enum>
</property>
+ <property name="cornerButtonEnabled">
+ <bool>false</bool>
+ </property>
+ <attribute name="horizontalHeaderHighlightSections">
+ <bool>false</bool>
+ </attribute>
+ <attribute name="horizontalHeaderStretchLastSection">
+ <bool>true</bool>
+ </attribute>
+ <attribute name="verticalHeaderVisible">
+ <bool>false</bool>
+ </attribute>
+ <column>
+ <property name="text">
+ <string>Name</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Domain</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Path</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Expires</string>
+ </property>
+ </column>
</widget>
</item>
<item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QPushButton" name="cookies_reload">
+ <property name="text">
+ <string>Reload</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cookies_delete">
+ <property name="text">
+ <string>Delete</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cookies_deleteSession">
+ <property name="text">
+ <string>Delete Session</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cookies_deleteAll">
+ <property name="text">
+ <string>Delete All</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
</item>
</layout>
</item>
@@ -656,6 +646,13 @@
</item>
</layout>
</widget>
+ <customwidgets>
+ <customwidget>
+ <class>SettingsTable</class>
+ <extends>QTableWidget</extends>
+ <header>forms/settingstable.h</header>
+ </customwidget>
+ </customwidgets>
<resources/>
<connections/>
</ui>
diff --git a/plugins/ProfileEditor/forms/settingstable.cpp b/plugins/ProfileEditor/forms/settingstable.cpp
new file mode 100644
index 0000000..6cfe144
--- /dev/null
+++ b/plugins/ProfileEditor/forms/settingstable.cpp
@@ -0,0 +1,90 @@
+/*
+ * 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/cgit/smolbote
+ *
+ * SPDX-License-Identifier: GPL-3.0
+ */
+
+#include "settingstable.h"
+#include <QResizeEvent>
+#include <QSettings>
+#include <QToolButton>
+
+SettingsTable::SettingsTable(QWidget *parent)
+ : QTableWidget(parent)
+{
+ QObject::connect(this, &QTableWidget::currentCellChanged, [this](int currentRow, int currentColumn, int /*previousRow*/, int /*previousColumn*/) {
+ if(currentColumn == 0) {
+ const auto key = item(currentRow, currentColumn)->text();
+ m_selectedKey = key;
+ }
+ });
+
+ addBtn = new QToolButton(this);
+ addBtn->setText("Add");
+ removeBtn = new QToolButton(this);
+ removeBtn->setText("Remove");
+}
+
+void SettingsTable::connect(QSettings *settings, const QString &section)
+{
+ settings->beginGroup(section);
+ if(settings != nullptr) {
+ const auto keys = settings->childKeys();
+ setRowCount(keys.count());
+ for(int i = 0; i < keys.count(); ++i) {
+ setItem(i, 0, new QTableWidgetItem(keys[i]));
+ setItem(i, 1, new QTableWidgetItem(settings->value(keys[i]).toString()));
+ }
+ }
+ settings->endGroup();
+
+ QObject::connect(addBtn, &QToolButton::clicked, [this]() {
+ const auto row = rowCount();
+ setRowCount(row + 1);
+ setItem(row, 0, new QTableWidgetItem("key"));
+ setItem(row, 1, new QTableWidgetItem("value"));
+ });
+
+ QObject::connect(removeBtn, &QToolButton::clicked, [this, settings, section]() {
+ settings->beginGroup(section);
+
+ const int row = currentRow();
+ const auto key = item(row, 0)->text();
+
+ removeRow(row);
+ qDebug("remove key: %s", qUtf8Printable(key));
+ settings->remove(key);
+
+ settings->endGroup();
+ });
+
+ QObject::connect(this, &QTableWidget::cellChanged, [this, settings, section](int row, int column) {
+ // no value has been created yet
+ if(item(row, 1) == nullptr) {
+ return;
+ }
+
+ settings->beginGroup(section);
+
+ if(column == 0) {
+ qDebug("remove old key: %s", qUtf8Printable(m_selectedKey));
+ settings->remove(m_selectedKey);
+ }
+
+ const auto key = item(row, 0)->text();
+ const auto val = item(row, 1)->text();
+ qDebug("set: [%s]=[%s]", qUtf8Printable(key), qUtf8Printable(val));
+ settings->setValue(key, val);
+
+ settings->endGroup();
+ });
+}
+
+void SettingsTable::resizeEvent(QResizeEvent *event)
+{
+ QTableWidget::resizeEvent(event);
+ addBtn->move(width() - addBtn->width() - removeBtn->width(), 0);
+ removeBtn->move(width() - removeBtn->width(), 0);
+}
diff --git a/plugins/ProfileEditor/forms/settingstable.h b/plugins/ProfileEditor/forms/settingstable.h
new file mode 100644
index 0000000..80e76f0
--- /dev/null
+++ b/plugins/ProfileEditor/forms/settingstable.h
@@ -0,0 +1,31 @@
+/*
+ * 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/cgit/smolbote
+ *
+ * SPDX-License-Identifier: GPL-3.0
+ */
+
+#ifndef SETTINGS_TREE
+#define SETTINGS_TREE
+
+#include <QTableWidget>
+
+class QSettings;
+class QToolButton;
+class SettingsTable : public QTableWidget
+{
+public:
+ SettingsTable(QWidget *parent = nullptr);
+
+ void connect(QSettings *settings, const QString &section = QString());
+
+protected:
+ void resizeEvent(QResizeEvent *event);
+
+private:
+ QString m_selectedKey;
+ QToolButton *addBtn = nullptr, *removeBtn = nullptr;
+};
+
+#endif // SETTINGS_TREE
diff --git a/plugins/ProfileEditor/meson.build b/plugins/ProfileEditor/meson.build
index caa3a75..47a1c17 100644
--- a/plugins/ProfileEditor/meson.build
+++ b/plugins/ProfileEditor/meson.build
@@ -1,15 +1,14 @@
ProfileEditorPlugin_moc = mod_qt5.preprocess(
- include_directories: include,
- moc_headers: ['profileeditorplugin.h', 'forms/profilemanagerdialog.h', 'forms/profileview.h', 'forms/newprofiledialog.h', 'forms/newhttpheaderdialog.h'],
- ui_files: ['forms/profilemanagerdialog.ui', 'forms/profileview.ui', 'forms/newprofiledialog.ui', 'forms/newhttpheaderdialog.ui'],
- dependencies: dep_qt5
+ include_directories: plugininterfaces_include,
+ moc_headers: [ 'profileeditorplugin.h', 'forms/profilemanagerdialog.h', 'forms/profileview.h' ],
+ ui_files: [ 'forms/profilemanagerdialog.ui', 'forms/profileview.ui' ],
)
-ProfileEditorPlugin_lib = shared_library('ProfileEditorPlugin',
- [interfaces_moc, ProfileEditorPlugin_moc, 'profileeditorplugin.cpp', 'forms/profilemanagerdialog.cpp', 'forms/profileview.cpp', 'forms/newprofiledialog.cpp', 'forms/newhttpheaderdialog.cpp'],
- dependencies: dep_qt5,
- include_directories: include,
- install: true, install_dir: join_paths(get_option('libdir'), 'smolbote/plugins')
+ProfileEditorPlugin = shared_library('ProfileEditorPlugin',
+ [ ProfileEditorPlugin_moc, 'profileeditorplugin.cpp', 'forms/profilemanagerdialog.cpp', 'forms/profileview.cpp', 'forms/settingstable.cpp' ],
+ include_directories: plugininterfaces_include,
+ dependencies: [ dep_qt5 ],
+ install: true, install_dir: join_paths(get_option('libdir'), 'smolbote/plugins')
)
test('run', executable('ProfileEditor', 'test/main.cpp',
diff --git a/plugins/ProfileEditor/profileeditorplugin.cpp b/plugins/ProfileEditor/profileeditorplugin.cpp
index d480392..6d1fc6a 100644
--- a/plugins/ProfileEditor/profileeditorplugin.cpp
+++ b/plugins/ProfileEditor/profileeditorplugin.cpp
@@ -8,48 +8,12 @@
#include "profileeditorplugin.h"
#include "forms/profilemanagerdialog.h"
-#include "forms/newprofiledialog.h"
-
-QHash<QString, std::function<int()>> ProfileEditorPlugin::commands()
-{
- QHash<QString, std::function<int()>> hash;
-
- hash.insert("edit-profiles-ui", [this]() -> int {
- auto *dialog = createWidget(nullptr);
- return dialog->exec();
- });
- return hash;
-}
QDialog *ProfileEditorPlugin::createWidget(QWidget *parent) const
{
- auto *app = browser();
- Q_CHECK_PTR(app);
auto *widget = new ProfileManagerDialog(parent);
widget->setAttribute(Qt::WA_DeleteOnClose, true);
- for(const auto &pair : app->profileList()) {
- widget->addProfile(pair.first, pair.second);
- }
-
- connect(widget->ui->new_pushButton, &QPushButton::clicked, widget, [=]() {
- auto *newProfileDlg = new NewProfileDialog(widget);
- if(newProfileDlg->exec() == QDialog::Accepted) {
- const auto pair = app->loadProfile(newProfileDlg->getId(), newProfileDlg->getOtr());
- widget->addProfile(pair.first, pair.second);
- }
- delete newProfileDlg;
- });
-
- connect(widget->ui->delete_pushButton, &QPushButton::clicked, widget, [=]() {
- auto *item = widget->ui->listWidget->currentItem();
- if(item != nullptr) {
- // there is a selected widget
- const QString id = item->text();
- widget->showProfile(nullptr);
- app->removeProfile(id);
- }
- });
return widget;
}
diff --git a/plugins/ProfileEditor/profileeditorplugin.h b/plugins/ProfileEditor/profileeditorplugin.h
index a673436..13f6d90 100644
--- a/plugins/ProfileEditor/profileeditorplugin.h
+++ b/plugins/ProfileEditor/profileeditorplugin.h
@@ -9,7 +9,7 @@
#ifndef PROFILEEDITOR_PLUGIN_H
#define PROFILEEDITOR_PLUGIN_H
-#include <plugininterface.h>
+#include <smolbote/plugininterface.hpp>
class QDialog;
class ProfileEditorPlugin : public QObject, public PluginInterface
@@ -19,10 +19,7 @@ class ProfileEditorPlugin : public QObject, public PluginInterface
Q_INTERFACES(PluginInterface)
public:
- // PluginInterface
- QHash<QString, std::function<int()>> commands() override;
-
- // ProfileInterface
+ ~ProfileEditorPlugin() override = default;
QDialog *createWidget(QWidget *parent) const override;
};
diff --git a/plugins/ProfileEditor/test/main.cpp b/plugins/ProfileEditor/test/main.cpp
new file mode 100644
index 0000000..40b563c
--- /dev/null
+++ b/plugins/ProfileEditor/test/main.cpp
@@ -0,0 +1,22 @@
+#include <QApplication>
+#include "profileeditorplugin.h"
+#include <QDialog>
+#include <QTimer>
+#include <QWebEngineProfile>
+
+int main(int argc, char** argv)
+{
+ QApplication app(argc, argv);
+ ProfileEditorPlugin plugin;
+
+ auto *dlg = dynamic_cast<ProfileDialog*>(plugin.createWidget(nullptr));
+ const auto i = dlg->addProfile("id", "testing", new QWebEngineProfile, new QSettings(QString(), QSettings::IniFormat, &app));
+ dlg->show();
+
+ if(qEnvironmentVariableIsSet("autoclose")) {
+ dlg->showProfile(i);
+ QTimer::singleShot(200, dlg, &QDialog::accept);
+ }
+
+ return app.exec();
+}
diff --git a/src/about/aboutdialog.ui b/src/about/aboutdialog.ui
index 5b1c12a..036474c 100644
--- a/src/about/aboutdialog.ui
+++ b/src/about/aboutdialog.ui
@@ -134,11 +134,6 @@
</item>
</layout>
</widget>
- <widget class="QWidget" name="tab">
- <attribute name="title">
- <string>Plugins</string>
- </attribute>
- </widget>
</widget>
</item>
<item>
diff --git a/src/about/aboutplugin.cpp b/src/about/aboutplugin.cpp
index 92e55bb..a011b47 100644
--- a/src/about/aboutplugin.cpp
+++ b/src/about/aboutplugin.cpp
@@ -12,57 +12,12 @@
#include <QPluginLoader>
#include <QToolButton>
-QTreeWidgetItem *createItem(const QString &key, const QJsonValue &json, QTreeWidgetItem *parent)
-{
- auto *item = new QTreeWidgetItem(parent, { key, QLatin1String("---") });
-
- switch(json.type()) {
- case QJsonValue::Bool:
- item->setText(1, json.toBool() ? QLatin1String("true") : QLatin1String("false"));
- break;
-
- case QJsonValue::Double:
- item->setText(1, QString::number(json.toDouble()));
- break;
-
- case QJsonValue::String:
- item->setText(1, json.toString());
- break;
-
- case QJsonValue::Array:
- item->setText(1, QString());
- for(const auto &v : json.toArray()) {
- createItem(QString(), v, item);
- }
- break;
-
- case QJsonValue::Object:
- item->setText(1, QString());
- for(const QString &k : json.toObject().keys()) {
- createItem(k, json.toObject()[k], item);
- }
- break;
-
- case QJsonValue::Null:
- item->setText(1, QLatin1String("null"));
- break;
-
- case QJsonValue::Undefined:
- item->setText(1, QLatin1String("undefined"));
- break;
- }
-
- return item;
-}
-
AboutPluginDialog::AboutPluginDialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::AboutPluginDialog)
{
setAttribute(Qt::WA_DeleteOnClose, true);
ui->setupUi(this);
-
-
}
AboutPluginDialog::~AboutPluginDialog()
@@ -85,20 +40,17 @@ void AboutPluginDialog::add(QPluginLoader *loader)
auto *enable_btn = new QToolButton(this);
enable_btn->setCheckable(true);
enable_btn->setChecked(loader->isLoaded());
+ enable_btn->setText(loader->isLoaded() ? "loaded" : "unloaded");
ui->tableWidget->setCellWidget(index, 4, enable_btn);
- connect(enable_btn, &QToolButton::clicked, this, [ loader, enable_btn ](bool checked) {
+ connect(enable_btn, &QToolButton::clicked, this, [this, loader, enable_btn](bool checked) {
const bool success = checked ? loader->load() : loader->unload();
if(!success) {
enable_btn->setChecked(!checked);
- //ui->error->setText(loader->errorString());
+ ui->msg->setText(loader->errorString());
+ } else {
+ ui->msg->setText(checked ? "Plugin successfully loaded" : "Plugin successfully unloaded");
+ enable_btn->setText(checked ? "loaded" : "unloaded");
}
});
-
- for(const QString &key : metadata.keys()) {
- auto *i = createItem(key, metadata.value(key), nullptr);
- if(i != nullptr) {
- ui->details_treeWidget->insertTopLevelItem(0, i);
- }
- }
}
diff --git a/src/about/aboutplugin.h b/src/about/aboutplugin.h
index b01cc78..f9cd3d4 100644
--- a/src/about/aboutplugin.h
+++ b/src/about/aboutplugin.h
@@ -24,6 +24,9 @@ public:
explicit AboutPluginDialog(QWidget *parent = nullptr);
~AboutPluginDialog() override;
+signals:
+ void loadPlugin(const QString &path);
+
public slots:
void add(QPluginLoader *loader);
diff --git a/src/about/aboutplugin.ui b/src/about/aboutplugin.ui
index d4291e5..5f44886 100644
--- a/src/about/aboutplugin.ui
+++ b/src/about/aboutplugin.ui
@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
- <width>600</width>
+ <width>900</width>
<height>420</height>
</rect>
</property>
@@ -19,6 +19,9 @@
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
+ <attribute name="verticalHeaderVisible">
+ <bool>false</bool>
+ </attribute>
<column>
<property name="text">
<string>Name</string>
@@ -52,28 +55,32 @@
</widget>
</item>
<item>
- <widget class="QTreeWidget" name="details_treeWidget">
- <column>
- <property name="text">
- <string>Key</string>
- </property>
- </column>
- <column>
- <property name="text">
- <string>Value</string>
- </property>
- </column>
- </widget>
- </item>
- <item>
- <widget class="QDialogButtonBox" name="buttonBox">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="standardButtons">
- <set>QDialogButtonBox::Close</set>
- </property>
- </widget>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QToolButton" name="add_toolButton">
+ <property name="text">
+ <string>Add</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="msg">
+ <property name="text">
+ <string>text</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Close</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
</layout>
</widget>
diff --git a/src/applicationmenu.cpp b/src/applicationmenu.cpp
index b7acd57..dc888e7 100644
--- a/src/applicationmenu.cpp
+++ b/src/applicationmenu.cpp
@@ -13,10 +13,12 @@
#include "session/sessiondialog.h"
#include "smolbote/plugininterface.hpp"
#include <QPluginLoader>
+#include <spdlog/spdlog.h>
ApplicationMenu::ApplicationMenu(Browser *app, QWidget *parent)
: QMenu(parent)
{
+ m_app = app;
setTitle(qApp->applicationName());
Configuration conf;
@@ -57,11 +59,21 @@ void ApplicationMenu::addPlugin(QPluginLoader *plugin)
auto *action = addAction(metadata.value("name").toString());
action->setShortcut(QKeySequence::fromString(metadata.value("shortcut").toString()));
- connect(action, &QAction::triggered, this, [this, plugin]() {
+ connect(action, &QAction::triggered, [this, plugin]() {
if(plugin->isLoaded()) {
- if(const auto *interface = qobject_cast<PluginInterface *>(plugin->instance())) {
- interface->createWidget(this->parentWidget())->exec();
+ const auto *interface = qobject_cast<PluginInterface *>(plugin->instance());
+ auto *dlg = interface->createWidget(this->parentWidget());
+
+ if(auto *profileDlg = dynamic_cast<ProfileDialog*>(dlg)) {
+ WebProfileManager mgr;
+ mgr.walk([profileDlg](const QString &id, WebProfile *profile, QSettings *settings) {
+ profileDlg->addProfile(id, profile->name(), profile, settings);
+ });
}
+
+ dlg->exec();
+ } else {
+ spdlog::warn("Trying to run unloaded plugin!");
}
});
insertAction(bottom_pluginSeparator, action);
diff --git a/src/applicationmenu.h b/src/applicationmenu.h
index 7e1fe47..8b558e0 100644
--- a/src/applicationmenu.h
+++ b/src/applicationmenu.h
@@ -25,6 +25,7 @@ public slots:
void addPlugin(QPluginLoader *plugin);
private:
+ Browser *m_app = nullptr;
QAction *top_pluginSeparator = nullptr, *bottom_pluginSeparator = nullptr;
};
diff --git a/src/browser.cpp b/src/browser.cpp
index 2277e54..4f1e02e 100644
--- a/src/browser.cpp
+++ b/src/browser.cpp
@@ -92,10 +92,11 @@ void Browser::aboutPlugins()
dlg->exec();
}
-void Browser::loadPlugins(const QStringList &paths, const std::function<void(const QPluginLoader *)> &callback)
+bool Browser::loadPlugin(const QString &path)
{
- if(paths.isEmpty())
- return;
+ if(path.isEmpty()) {
+ return false;
+ }
Configuration conf;
const auto state = PluginLoader::signature_state(
@@ -103,23 +104,18 @@ void Browser::loadPlugins(const QStringList &paths, const std::function<void(con
conf.value<bool>("plugins.signature.checked").value(),
conf.value<bool>("plugins.signature.enforced").value());
- for(const auto &path : paths) {
- auto *loader = new PluginLoader(path, state, this);
- const bool loaded = loader->load();
-
- callback(loader);
-
- if(!loaded) {
- delete loader;
- } else {
- auto *info = new PluginInfo(loader);
- m_plugins.append(info);
+ auto *loader = new PluginLoader(path, state, this);
+ const bool loaded = loader->load();
- for(MainWindow *window : qAsConst(m_windows)) {
- addPluginTo(info, window);
- }
- }
+ if(!loaded) {
+ delete loader;
+ return false;
}
+ auto *info = new PluginInfo(loader);
+ m_plugins.append(info);
+
+ emit pluginAdded(loader);
+ return true;
}
void Browser::setup()
@@ -205,6 +201,7 @@ void Browser::open(const QVector<Session::MainWindow> &data, bool merge)
for(const auto &windowData : data) {
auto *menu = new ApplicationMenu(this);
+ connect(this, &Browser::pluginAdded, menu, &ApplicationMenu::addPlugin);
for(auto *info : qAsConst(m_plugins)) {
menu->addPlugin(info->loader);
}
@@ -219,28 +216,3 @@ void Browser::open(const QVector<Session::MainWindow> &data, bool merge)
});
}
}
-
-void Browser::addPluginTo(PluginInfo *info, MainWindow *window)
-{
- QPluginLoader *loader = info->loader;
- auto *pluginMenu = new QMenu(loader->metaData().value("MetaData").toObject().value("name").toString());
- //window->m_menuBar->insertPlugin(pluginMenu);
- info->menus.append(pluginMenu);
-
- auto *runAction = pluginMenu->addAction(tr("Run"));
- runAction->setShortcut(QKeySequence::fromString(loader->metaData().value("MetaData").toObject().value("shortcut").toString()));
-
- connect(runAction, &QAction::triggered, window, [loader, window]() {
- if(loader->isLoaded()) {
- const auto *interface = qobject_cast<PluginInterface *>(loader->instance());
- Q_CHECK_PTR(interface);
- interface->createWidget(window)->exec();
- }
- });
-
- auto *removeAction = pluginMenu->addAction(tr("Remove"));
- connect(removeAction, &QAction::triggered, this, [this, info]() {
- m_plugins.removeOne(info);
- delete info;
- });
-}
diff --git a/src/browser.h b/src/browser.h
index 74136f1..1964267 100644
--- a/src/browser.h
+++ b/src/browser.h
@@ -31,8 +31,6 @@ public:
explicit Browser(int &argc, char *argv[], bool allowSecondary = true);
~Browser() final;
- void loadPlugins(
- const QStringList &paths, const std::function<void(const QPluginLoader *)> &callback = [](const auto) {});
void setup();
const QVector<MainWindow *> windows() const
@@ -49,12 +47,18 @@ public:
return m_downloads.get();
}
+signals:
+ void pluginAdded(QPluginLoader *);
+
public slots:
void about();
void aboutPlugins();
+
void showWidget(QWidget *widget, MainWindow *where) const;
void open(const QVector<Session::MainWindow> &data, bool merge = true);
+ bool loadPlugin(const QString &path);
+
private:
struct PluginInfo {
explicit PluginInfo(QPluginLoader *l)
@@ -71,7 +75,6 @@ private:
QPluginLoader *loader;
QVector<QMenu *> menus;
};
- void addPluginTo(PluginInfo *info, MainWindow *window);
Q_DISABLE_COPY(Browser)
diff --git a/src/main.cpp b/src/main.cpp
index ca85b65..f0c1591 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -118,13 +118,13 @@ int main(int argc, char **argv)
}
// load plugins
- app.loadPlugins(Util::files(conf.value<QString>("plugins.path").value(), { "*.so", "*.dll" }),
- [](const auto *loader) {
- if(loader->isLoaded())
- spdlog::info("Loaded plugin [{}]", qUtf8Printable(loader->fileName()));
- else
- spdlog::warn("Loading plugin [{}] failed: {}", qUtf8Printable(loader->fileName()), qUtf8Printable(loader->errorString()));
- });
+ for(const QString &path : Util::files(conf.value<QString>("plugins.path").value(), { "*.so", "*.dll" })) {
+ if(app.loadPlugin(path)) {
+ spdlog::debug("Loaded plugin [{}]", qUtf8Printable(path));
+ } else {
+ spdlog::warn("Failed loading plugin [{}]", qUtf8Printable(path));
+ }
+ }
}
const auto profile = []() {
diff --git a/src/webengine/meson.build b/src/webengine/meson.build
index db7bdc5..47e4adf 100644
--- a/src/webengine/meson.build
+++ b/src/webengine/meson.build
@@ -5,7 +5,7 @@ webengine_moc = mod_qt5.preprocess(
dep_webengine = declare_dependency(
include_directories: [ '.', smolbote_include ],
- link_with: static_library('webengine', dependencies: dep_qt5,
+ link_with: static_library('webengine', dependencies: [ dep_qt5, dep_spdlog ],
include_directories: smolbote_include,
sources: [ 'webprofile.cpp', 'urlinterceptor.cpp', 'webprofilemanager.cpp', 'webpage.cpp', 'webview.cpp', 'webviewcontextmenu.cpp', webengine_moc ])
)
diff --git a/src/webengine/test/profile.cpp b/src/webengine/test/profile.cpp
index 7351f66..ae3a4e3 100644
--- a/src/webengine/test/profile.cpp
+++ b/src/webengine/test/profile.cpp
@@ -22,98 +22,99 @@ TEST_CASE("loading profile settings")
delete settings;
}
-SCENARIO("loading individual profiles")
+SCENARIO("profile properties")
{
- GIVEN("no profile preset")
- {
- const QString search = GENERATE(as<QString>{}, "https://search.url/t=%1", "https://duckduckgo.com/?q=%1&ia=web", "aaabbbccc");
- const QUrl homepage = GENERATE(as<QUrl>{}, "https://homepage.net", "about:blank", "aaabbbccc");
- const QUrl newtab = GENERATE(as<QUrl>{}, "https://newtab.net", "about:blank", "aaabbbccc");
+ const QString search{ "about:blank" };
+ const QUrl homepage{ "about:blank" };
+ const QUrl newtab{ "about:blank" };
+ const QString id{ "id" };
+
+ REQUIRE(qEnvironmentVariableIsSet("PROFILE"));
- const QString id{ "id" };
- auto *settings = WebProfile::load(QString(), search, homepage, newtab);
- auto *profile = WebProfile::load(id, settings, true);
+ // create an empty settings object
+ const QString settings_path = GENERATE(as<QString>{}, QString(), qgetenv("PROFILE"));
+ auto *settings = WebProfile::load(settings_path, search, homepage, newtab);
+ // create the actual profile
+ auto *profile = WebProfile::load(id, settings, true);
- REQUIRE(profile != nullptr);
+ REQUIRE(profile != nullptr);
+ REQUIRE(profile->isOffTheRecord());
+
+ WHEN("id constant")
+ {
REQUIRE(profile->getId() == id);
REQUIRE(profile->property("id").toString() == id);
- REQUIRE(profile->name() == id);
- REQUIRE(profile->search() == search);
- REQUIRE(profile->homepage() == homepage);
- REQUIRE(profile->newtab() == newtab);
-
- REQUIRE(profile->isOffTheRecord());
- delete settings;
- delete profile;
}
- GIVEN("an off-the-record profile preset")
+ WHEN("changing profile name")
{
- REQUIRE(qEnvironmentVariableIsSet("PROFILE"));
-
- const QString id{ "id" };
- auto *settings = WebProfile::load(qgetenv("PROFILE"), QString(), QUrl(), QUrl());
- auto *profile = WebProfile::load(id, settings, true);
-
- REQUIRE(profile != nullptr);
- REQUIRE(profile->getId() == id);
- REQUIRE(profile->isOffTheRecord());
-
- WHEN("created")
+ const QString name = GENERATE(as<QString>{}, "a", "bb", "ccc");
+ profile->setName(name);
+ THEN("the name changes")
{
- THEN("uses default values")
- {
- REQUIRE(profile->name() == "Test Profile");
- REQUIRE(profile->search() == "https://duckduckgo.com/?q=%1&ia=web");
- REQUIRE(profile->homepage() == QUrl("about:blank"));
- REQUIRE(profile->newtab() == QUrl("about:blank"));
- }
+ REQUIRE(profile->name() == name);
+ REQUIRE(settings->value("name").toString() == name);
}
-
- WHEN("changing profile name")
+ }
+ WHEN("changing search")
+ {
+ const QString search = GENERATE(as<QString>{}, "a", "bb", "ccc");
+ profile->setSearch(search);
+ THEN("the search url changes")
{
- const QString name = GENERATE(as<QString>{}, "a", "bb", "ccc");
- profile->setName(name);
- THEN("the name changes")
- {
- REQUIRE(profile->name() == name);
- REQUIRE(settings->value("name").toString() == name);
- }
+ REQUIRE(profile->search() == search);
+ REQUIRE(settings->value("search").toString() == search);
}
- WHEN("changing search url")
+ }
+ WHEN("changing homepage url")
+ {
+ const QUrl url = GENERATE(as<QUrl>{}, "a", "bb", "ccc");
+ profile->setHomepage(url);
+ THEN("homepage changes")
{
- const QString search = GENERATE(as<QString>{}, "a", "bb", "ccc");
- profile->setSearch(search);
- THEN("the search url changes")
- {
- REQUIRE(profile->search() == search);
- REQUIRE(settings->value("search").toString() == search);
- }
+ REQUIRE(profile->homepage() == url);
+ REQUIRE(settings->value("homepage").toUrl() == url);
}
- WHEN("changing homepage")
+ }
+ WHEN("changing newtab url")
+ {
+ const QUrl url = GENERATE(as<QUrl>{}, "a", "bb", "ccc");
+ profile->setNewtab(url);
+ THEN("newtab changes")
{
- const QUrl url = GENERATE(as<QUrl>{}, "a", "bb", "ccc");
- profile->setHomepage(url);
- THEN("homepage changes")
- {
- REQUIRE(profile->homepage() == url);
- REQUIRE(settings->value("homepage").toUrl() == url);
- }
+ REQUIRE(profile->newtab() == url);
+ REQUIRE(settings->value("newtab").toUrl() == url);
}
- WHEN("changing newtab")
+ }
+
+ WHEN("changing cookies")
+ {
+ auto list = profile->cookies();
+ REQUIRE(list.isEmpty());
+ list.append(QNetworkCookie("name", "value").toRawForm());
+ profile->setCookies(list);
+ THEN("new cookie list gets applied")
{
- const QUrl url = GENERATE(as<QUrl>{}, "a", "bb", "ccc");
- profile->setNewtab(url);
- THEN("newtab changes")
- {
- REQUIRE(profile->newtab() == url);
- REQUIRE(settings->value("newtab").toUrl() == url);
- }
+ // There is no event loop, so the signals cannot fire and update the cookie list
+ //REQUIRE(list == profile->cookies());
}
+ }
- delete settings;
- delete profile;
+ WHEN("changing headers")
+ {
+ QMap<QString, QVariant> headers;
+ headers.insert("Dnt", "1");
+ headers.insert("unknown", "pair");
+
+ profile->setHeaders(headers);
+ THEN("headers change")
+ {
+ REQUIRE(profile->headers() == headers);
+ }
}
+
+ delete settings;
+ delete profile;
}
int main(int argc, char **argv)
diff --git a/src/webengine/webprofile.cpp b/src/webengine/webprofile.cpp
index f0368c9..719ab34 100644
--- a/src/webengine/webprofile.cpp
+++ b/src/webengine/webprofile.cpp
@@ -7,11 +7,12 @@
*/
#include "webprofile.h"
+#include "urlinterceptor.h"
#include <QFileInfo>
#include <QSettings>
#include <QWebEngineCookieStore>
#include <QWebEngineSettings>
-#include "urlinterceptor.h"
+#include <spdlog/spdlog.h>
static WebProfile *s_profile = nullptr;
@@ -47,7 +48,7 @@ WebProfile *WebProfile::load(const QString &id, QSettings *settings, bool isOffT
{
WebProfile *profile = nullptr;
- if(isOffTheRecord || settings->value("otr", isOffTheRecord).toBool()) {
+ if(settings->value("otr", isOffTheRecord).toBool()) {
profile = new WebProfile(id, nullptr);
} else {
profile = new WebProfile(id, id, nullptr);
@@ -89,7 +90,8 @@ WebProfile *WebProfile::load(const QString &id, QSettings *settings, bool isOffT
{
// headers
settings->beginGroup("headers");
- for(const QString &key : settings->childKeys()) {
+ const auto keys = settings->childKeys();
+ for(const QString &key : keys) {
profile->setHttpHeader(key.toLatin1(), settings->value(key).toString().toLatin1());
}
settings->endGroup();
@@ -110,11 +112,14 @@ WebProfile::WebProfile(const QString &id, QObject *parent)
{
QWebEngineProfile::setUrlRequestInterceptor(new UrlRequestInterceptor(this));
connect(this->cookieStore(), &QWebEngineCookieStore::cookieAdded, this, [this](const QNetworkCookie &cookie) {
+ spdlog::debug("[{}]: +cookie {}", qUtf8Printable(m_name), qUtf8Printable(cookie.name()));
m_cookies.append(cookie);
});
connect(this->cookieStore(), &QWebEngineCookieStore::cookieRemoved, this, [this](const QNetworkCookie &cookie) {
- m_cookies.removeAll(cookie);
+ spdlog::debug("[{}]: -cookie {}", qUtf8Printable(m_name), qUtf8Printable(cookie.name()));
+ m_cookies.removeOne(cookie);
});
+ cookieStore()->loadAllCookies();
}
// default constructor
@@ -124,9 +129,12 @@ WebProfile::WebProfile(const QString &id, const QString &storageName, QObject *p
{
QWebEngineProfile::setUrlRequestInterceptor(new UrlRequestInterceptor(this));
connect(this->cookieStore(), &QWebEngineCookieStore::cookieAdded, this, [this](const QNetworkCookie &cookie) {
+ spdlog::debug("[{}]: +cookie {}", qUtf8Printable(m_name), qUtf8Printable(cookie.name()));
m_cookies.append(cookie);
});
connect(this->cookieStore(), &QWebEngineCookieStore::cookieRemoved, this, [this](const QNetworkCookie &cookie) {
- m_cookies.removeAll(cookie);
+ spdlog::debug("[{}]: -cookie {}", qUtf8Printable(m_name), qUtf8Printable(cookie.name()));
+ m_cookies.removeOne(cookie);
});
+ cookieStore()->loadAllCookies();
}
diff --git a/src/webengine/webprofile.h b/src/webengine/webprofile.h
index 180cc9d..0747638 100644
--- a/src/webengine/webprofile.h
+++ b/src/webengine/webprofile.h
@@ -11,13 +11,14 @@
#include <QMap>
#include <QNetworkCookie>
+#include <QSettings>
#include <QString>
#include <QUrl>
+#include <QVariant>
#include <QVector>
+#include <QWebEngineCookieStore>
#include <QWebEngineProfile>
#include <QWebEngineSettings>
-#include <QVariant>
-#include <QSettings>
class UrlRequestInterceptor;
class WebProfile : public QWebEngineProfile
@@ -44,6 +45,10 @@ class WebProfile : public QWebEngineProfile
Q_PROPERTY(bool spellCheckEnabled READ isSpellCheckEnabled WRITE setSpellCheckEnabled NOTIFY propertyChanged)
+ // more custom properties
+ Q_PROPERTY(QList<QVariant> cookies READ cookies WRITE setCookies NOTIFY cookiesChanged)
+ Q_PROPERTY(QMap<QString, QVariant> headers READ headers WRITE setHeaders NOTIFY headersChanged)
+
signals:
void nameChanged(const QString &name);
void searchChanged(const QString &url);
@@ -52,6 +57,9 @@ signals:
void propertyChanged(const QString &name, const QVariant &value);
void attributeChanged(QWebEngineSettings::WebAttribute attribute, bool value);
+
+ void cookiesChanged();
+ void headersChanged();
void headerChanged(const QString &name, const QString &value);
void headerRemoved(const QString &name);
@@ -60,9 +68,9 @@ public:
[[nodiscard]] static WebProfile *load(const QString &id, QSettings *settings, bool isOffTheRecord = true);
WebProfile(const WebProfile &) = delete;
- WebProfile& operator=(const WebProfile &) = delete;
+ WebProfile &operator=(const WebProfile &) = delete;
WebProfile(WebProfile &&) = delete;
- WebProfile& operator=(WebProfile &&) = delete;
+ WebProfile &operator=(WebProfile &&) = delete;
static WebProfile *defaultProfile();
static void setDefaultProfile(WebProfile *profile);
@@ -83,9 +91,13 @@ public:
emit nameChanged(name);
}
- [[nodiscard]] QVector<QNetworkCookie> cookies() const
+ [[nodiscard]] QList<QVariant> cookies() const
{
- return qAsConst(m_cookies);
+ QList<QVariant> r;
+ for(const auto &cookie : m_cookies) {
+ r.append(cookie.toRawForm());
+ }
+ return r;
}
[[nodiscard]] QString search() const
@@ -166,7 +178,16 @@ public:
emit headerRemoved(name);
}
}
-
+ [[nodiscard]] QMap<QString, QVariant> headers() const
+ {
+ QMap<QString, QVariant> r;
+ auto it = m_headers.constBegin();
+ while(it != m_headers.constEnd()) {
+ r.insert(QString(it.key()), QVariant(it.value()));
+ ++it;
+ }
+ return r;
+ }
void setSpellCheckEnabled(bool enable)
{
QWebEngineProfile::setSpellCheckEnabled(enable);
@@ -178,6 +199,29 @@ public:
m_filters.append(interceptor);
}
+public slots:
+ void setCookies(const QList<QVariant> &cookies)
+ {
+ auto *store = cookieStore();
+ store->deleteAllCookies();
+ for(const auto &data : cookies) {
+ for(const auto &cookie : QNetworkCookie::parseCookies(data.toByteArray())) {
+ store->setCookie(cookie);
+ }
+ }
+ emit cookiesChanged();
+ }
+ void setHeaders(const QMap<QString, QVariant> &headers)
+ {
+ m_headers.clear();
+ auto it = headers.constBegin();
+ while(it != headers.constEnd()) {
+ m_headers.insert(it.key().toLatin1(), it.value().toByteArray());
+ ++it;
+ }
+ emit headersChanged();
+ }
+
protected:
// off-the-record constructor
explicit WebProfile(const QString &id, QObject *parent = nullptr);
@@ -190,8 +234,8 @@ protected:
QUrl m_homepage = QUrl("about:blank");
QUrl m_newtab = QUrl("about:blank");
- QVector<QWebEngineUrlRequestInterceptor*> m_filters;
- QVector<QNetworkCookie> m_cookies;
+ QVector<QWebEngineUrlRequestInterceptor *> m_filters;
+ QList<QNetworkCookie> m_cookies;
QMap<QByteArray, QByteArray> m_headers;
};
diff --git a/src/webengine/webprofilemanager.cpp b/src/webengine/webprofilemanager.cpp
index 785251b..5cc83f8 100644
--- a/src/webengine/webprofilemanager.cpp
+++ b/src/webengine/webprofilemanager.cpp
@@ -56,7 +56,7 @@ QStringList WebProfileManager<true>::idList() const
}
template <>
-void WebProfileManager<false>::walk(std::function<void(const QString &id, WebProfile *profile, const QSettings *settings)> f) const
+void WebProfileManager<false>::walk(std::function<void(const QString &id, WebProfile *profile, QSettings *settings)> f) const
{
for(auto iter = profiles.begin(); iter != profiles.end(); ++iter) {
f(iter.key(), iter.value().ptr, iter.value().settings);
@@ -64,7 +64,7 @@ void WebProfileManager<false>::walk(std::function<void(const QString &id, WebPro
}
template <>
-void WebProfileManager<true>::walk(std::function<void(const QString &id, WebProfile *profile, const QSettings *settings)> f) const
+void WebProfileManager<true>::walk(std::function<void(const QString &id, WebProfile *profile, QSettings *settings)> f) const
{
s_instance->walk(f);
}
diff --git a/src/webengine/webprofilemanager.h b/src/webengine/webprofilemanager.h
index 22fb31c..91dcaf8 100644
--- a/src/webengine/webprofilemanager.h
+++ b/src/webengine/webprofilemanager.h
@@ -93,7 +93,7 @@ public:
return profiles.keys();
}
- callable_when(unconsumed) void walk(std::function<void(const QString &id, WebProfile *profile, const QSettings *settings)>) const;
+ callable_when(unconsumed) void walk(std::function<void(const QString &id, WebProfile *profile, QSettings *settings)>) const;
callable_when(unconsumed) void make_global();