summaryrefslogtreecommitdiff
path: root/src/settings
diff options
context:
space:
mode:
Diffstat (limited to 'src/settings')
-rw-r--r--src/settings/CMakeLists.txt13
-rw-r--r--src/settings/settings.cpp51
-rw-r--r--src/settings/settings.hpp14
-rw-r--r--src/settings/settings.qrc (renamed from src/settings/test/test_settings.qrc)2
-rw-r--r--src/settings/settingsdialog.cpp16
-rw-r--r--src/settings/settingswidget.cpp42
-rw-r--r--src/settings/settingswidgets.hpp6
-rw-r--r--src/settings/test/rekonqrc37
-rw-r--r--src/settings/test/settings_mock.hpp3
-rw-r--r--src/settings/test/test_settings.cpp82
-rw-r--r--src/settings/test/test_settingsdialog.cpp9
11 files changed, 146 insertions, 129 deletions
diff --git a/src/settings/CMakeLists.txt b/src/settings/CMakeLists.txt
index 712fd57a..38a35cf6 100644
--- a/src/settings/CMakeLists.txt
+++ b/src/settings/CMakeLists.txt
@@ -15,11 +15,20 @@ add_custom_command(OUTPUT shortcutssettingswidget.cpp DEPENDS ${PROJECT_SOURCE_D
--group=Shortcuts --output=shortcutssettingswidget.cpp
${PROJECT_SOURCE_DIR}/src/rekonq.kcfg)
+# generate rekonqrc
+execute_process(
+ COMMAND python3 ${PROJECT_SOURCE_DIR}/scripts/rekonf.py --group=all --output=rekonqrc ${PROJECT_SOURCE_DIR}/src/rekonq.kcfg
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ #OUTPUT rekonqrc
+ #DEPENDS ${PROJECT_SOURCE_DIR}/scripts/rekonf.py ${PROJECT_SOURCE_DIR}/src/rekonq.kcfg
+)
+
add_library(settings STATIC
${PROJECT_SOURCE_DIR}/include/rsettings.hpp settings.cpp settings.hpp
settingsdialog.cpp settingsdialog.h settingsdialog.ui
settingswidgets.hpp settingswidget.cpp helpers.hpp
generalsettingswidget.cpp appearancesettingswidget.cpp networksettingswidget.cpp shortcutssettingswidget.cpp
+ settings.qrc rekonqrc
)
target_link_libraries(settings PUBLIC Qt6::Widgets)
@@ -27,7 +36,7 @@ IF(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
add_executable(test_settingsdialog test/test_settingsdialog.cpp test/settings_mock.hpp)
target_link_libraries(test_settingsdialog GTest::gmock settings)
- add_executable(test_settings test/test_settings.cpp test/test_settings.qrc test/settings_mock.hpp)
+ add_executable(test_settings test/test_settings.cpp test/settings_mock.hpp)
target_link_libraries(test_settings PRIVATE GTest::gtest GTest::gmock settings)
- gtest_discover_tests(test_settings EXTRA_ARGS rekonqrc)
+ gtest_discover_tests(test_settings)
endif()
diff --git a/src/settings/settings.cpp b/src/settings/settings.cpp
index 190bc977..d7216b2e 100644
--- a/src/settings/settings.cpp
+++ b/src/settings/settings.cpp
@@ -8,23 +8,66 @@
* ============================================================ */
#include "settings.hpp"
+#include "../rekonq.hpp"
+#include "helpers.hpp"
+#include <QDir>
#include <QSettings>
+#include <QStandardPaths>
+
+QString Settings::path()
+{
+ return QDir(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)).filePath("rekonqrc");
+}
Settings::Settings(const QString &path, QObject *parent) : RekonqSettings(parent)
{
d = new QSettings(path, QSettings::IniFormat, this);
+ b = new QSettings(":/settings/rekonqrc", QSettings::IniFormat, this);
}
-void Settings::beginGroup(const QString &prefix) { d->beginGroup(prefix); }
+Settings::~Settings()
+{
+ delete d;
+ delete b;
+}
-void Settings::endGroup() { d->endGroup(); }
+void Settings::beginGroup(const QString &prefix)
+{
+ d->beginGroup(prefix);
+ b->beginGroup(prefix);
+}
+
+void Settings::endGroup()
+{
+ d->endGroup();
+ b->endGroup();
+}
void Settings::setValue(const QString &key, const QVariant &value)
{
- d->setValue(key, value);
+ if (value == b->value(key)) d->remove(key);
+ else
+ d->setValue(key, value);
emit changed(key, value);
}
-QVariant Settings::value(const QString &key, const QVariant &defaultValue) const { return d->value(key, defaultValue); }
+void Settings::resetValue(const QString &key) { d->remove(key); }
+
+QVariant Settings::value(const QString &key) const
+{
+ auto v = d->value(key);
+ if (v.isValid()) return v;
+
+ if (key == QL1S("standardFontFamily")) return getFont(QFont::System).family();
+ if (key == QL1S("fixedFontFamily")) return getFont(QFont::Monospace).family();
+ if (key == QL1S("serifFontFamily")) return getFont(QFont::Times).family();
+ if (key == QL1S("sansSerifFontFamily")) return getFont(QFont::Helvetica).family();
+ if (key == QL1S("cursiveFontFamily")) return getFont(QFont::Cursive).family();
+ if (key == QL1S("fantasyFontFamily")) return getFont(QFont::Fantasy).family();
+
+ v = b->value(key);
+ Q_ASSERT_X(v.isValid(), __PRETTY_FUNCTION__, qUtf8Printable(key));
+ return v;
+}
QString Settings::filePath() const { return d->fileName(); }
diff --git a/src/settings/settings.hpp b/src/settings/settings.hpp
index 713ce38d..8d413985 100644
--- a/src/settings/settings.hpp
+++ b/src/settings/settings.hpp
@@ -12,22 +12,28 @@
#include <rsettings.hpp>
class QSettings;
-class Settings final : public RekonqSettings {
+class Settings : public RekonqSettings {
Q_OBJECT
public:
+ [[nodiscard]] static QString path();
+
explicit Settings(const QString &settingsPath, QObject *parent = nullptr);
- ~Settings() override = default;
+ ~Settings() override;
void beginGroup(const QString &prefix) override;
void endGroup() override;
void setValue(const QString &key, const QVariant &value) override;
- [[nodiscard]] QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const override;
+ void resetValue(const QString &key) override;
+ [[nodiscard]] QVariant value(const QString &key) const override;
[[nodiscard]] QString filePath() const override;
+protected:
+ QSettings *d;
+ QSettings *b;
+
private:
Q_DISABLE_COPY_MOVE(Settings)
- QSettings *d;
};
diff --git a/src/settings/test/test_settings.qrc b/src/settings/settings.qrc
index 16e74fef..71e19674 100644
--- a/src/settings/test/test_settings.qrc
+++ b/src/settings/settings.qrc
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='utf-8' standalone='yes'?>
<!DOCTYPE RCC>
<RCC version="1.0">
- <qresource prefix="/">
+ <qresource prefix="/settings">
<file alias="rekonqrc">rekonqrc</file>
</qresource>
</RCC>
diff --git a/src/settings/settingsdialog.cpp b/src/settings/settingsdialog.cpp
index 68fa7a26..66a47140 100644
--- a/src/settings/settingsdialog.cpp
+++ b/src/settings/settingsdialog.cpp
@@ -23,7 +23,7 @@ SettingsDialog::SettingsDialog(RekonqSettings *settings, QWidget *parent) : QDia
restoreDefaultsBtn = ui->buttonBox->button(QDialogButtonBox::RestoreDefaults);
Q_CHECK_PTR(restoreDefaultsBtn);
- if (!settings->value("FirstRun", true).toBool()) saveBtn->setEnabled(false);
+ if (!settings->value("FirstRun").toBool()) saveBtn->setEnabled(false);
addPage(new GeneralSettingsWidget(settings, this));
addPage(new AppearanceSettingsWidget(settings, this));
@@ -32,16 +32,14 @@ SettingsDialog::SettingsDialog(RekonqSettings *settings, QWidget *parent) : QDia
connect(ui->listWidget, &QListWidget::currentRowChanged, ui->stackedWidget, &QStackedWidget::setCurrentIndex);
- connect(restoreDefaultsBtn, &QPushButton::clicked, this, [this]() {
- for (auto *w : ui->stackedWidget->findChildren<SettingsWidget *>(QString(), Qt::FindDirectChildrenOnly)) {
- w->reset();
- }
+ connect(restoreDefaultsBtn, &QPushButton::clicked, this, [this, settings]() {
+ for (auto *w : ui->stackedWidget->findChildren<SettingsWidget *>(QString(), Qt::FindDirectChildrenOnly)) w->reset();
+ settings->setValue("FirstRun", false);
+ close();
});
connect(this, &QDialog::accepted, this, [this]() {
- for (auto *w : ui->stackedWidget->findChildren<SettingsWidget *>(QString(), Qt::FindDirectChildrenOnly)) {
- w->save();
- }
+ for (auto *w : ui->stackedWidget->findChildren<SettingsWidget *>(QString(), Qt::FindDirectChildrenOnly)) w->save();
});
}
@@ -54,4 +52,4 @@ void SettingsDialog::addPage(SettingsWidget *page)
ui->stackedWidget->addWidget(page);
connect(page, &SettingsWidget::changed, this, [this]() { saveBtn->setEnabled(true); });
-} \ No newline at end of file
+}
diff --git a/src/settings/settingswidget.cpp b/src/settings/settingswidget.cpp
index b5a2432c..60f2bf62 100644
--- a/src/settings/settingswidget.cpp
+++ b/src/settings/settingswidget.cpp
@@ -37,45 +37,3 @@ void SettingsWidget::save()
if (objectName() != QLatin1String("General")) m_settings->endGroup();
}
-
-void SettingsWidget::reset()
-{
- if (objectName() != QLatin1String("General")) m_settings->beginGroup(objectName());
-
- // Int
- for (auto *spinbox : findChildren<QSpinBox *>(QString(), Qt::FindDirectChildrenOnly)) {
- const auto value = spinbox->property("defaultValue");
- spinbox->setValue(value.toInt());
- m_settings->setValue(spinbox->objectName(), value);
- }
-
- // Bool
- for (auto *checkbox : findChildren<QCheckBox *>(QString(), Qt::FindDirectChildrenOnly)) {
- const auto value = checkbox->property("defaultValue");
- checkbox->setChecked(value.toBool());
- m_settings->setValue(checkbox->objectName(), value);
- }
-
- // String
- for (auto *lineedit : findChildren<QLineEdit *>(QString(), Qt::FindDirectChildrenOnly)) {
- const auto value = lineedit->property("defaultValue");
- lineedit->setText(value.toString());
- m_settings->setValue(lineedit->objectName(), value);
- }
-
- // Font
- for (auto *font : findChildren<QFontComboBox *>(QString(), Qt::FindDirectChildrenOnly)) {
- const auto value = font->property("defaultValue");
- font->setFont(QFont(value.toString()));
- m_settings->setValue(font->objectName(), value);
- }
-
- // Shortcut
- for (auto *shortcut : findChildren<QKeySequenceEdit *>(QString(), Qt::FindDirectChildrenOnly)) {
- const auto value = shortcut->property("defaultValue");
- shortcut->setKeySequence(value.toString());
- m_settings->setValue(shortcut->objectName(), value);
- }
-
- if (objectName() != QLatin1String("General")) m_settings->endGroup();
-} \ No newline at end of file
diff --git a/src/settings/settingswidgets.hpp b/src/settings/settingswidgets.hpp
index cb08b591..532a5683 100644
--- a/src/settings/settingswidgets.hpp
+++ b/src/settings/settingswidgets.hpp
@@ -27,7 +27,7 @@ signals:
public slots:
void save();
- void reset();
+ virtual void reset() = 0;
protected:
RekonqSettings *m_settings;
@@ -38,6 +38,7 @@ class GeneralSettingsWidget final : public SettingsWidget {
public:
explicit GeneralSettingsWidget(RekonqSettings *, QWidget *parent = nullptr);
~GeneralSettingsWidget() override = default;
+ void reset() override;
};
class AppearanceSettingsWidget final : public SettingsWidget {
@@ -45,6 +46,7 @@ class AppearanceSettingsWidget final : public SettingsWidget {
public:
explicit AppearanceSettingsWidget(RekonqSettings *, QWidget *parent = nullptr);
~AppearanceSettingsWidget() override = default;
+ void reset() override;
};
class NetworkSettingsWidget final : public SettingsWidget {
@@ -52,6 +54,7 @@ class NetworkSettingsWidget final : public SettingsWidget {
public:
explicit NetworkSettingsWidget(RekonqSettings *, QWidget *parent = nullptr);
~NetworkSettingsWidget() override = default;
+ void reset() override;
};
class ShortcutsSettingsWidget final : public SettingsWidget {
@@ -59,4 +62,5 @@ class ShortcutsSettingsWidget final : public SettingsWidget {
public:
explicit ShortcutsSettingsWidget(RekonqSettings *, QWidget *parent = nullptr);
~ShortcutsSettingsWidget() override = default;
+ void reset() override;
};
diff --git a/src/settings/test/rekonqrc b/src/settings/test/rekonqrc
deleted file mode 100644
index fe67194c..00000000
--- a/src/settings/test/rekonqrc
+++ /dev/null
@@ -1,37 +0,0 @@
-[General]
-FirstRun=true
-lang=TODO: change type to StringList
-homepage=about:blank
-newtab=about:blank
-searchUrl=https://duckduckgo.com/?q=%1
-pluginPath=TODO: change type to Path
-
-[Network]
-downloadPath=TODO: change type to Path
-downloadPathAsk=true
-userAgent=TODO
-
-[Appearance]
-IconTheme=tabler
-defaultFontSize=16
-minFontSize=7
-defaultEncoding=ISO 8859-1
-defaultZoom=10
-
-[Shortcuts]
-actionShowSidebar=Ctrl+B
-actionShowSearchBar=Ctrl+F
-actionSettings=Ctrl+S
-actionQuit=Ctrl+Q
-actionNewTab=Ctrl+T
-actionCloseTab=Ctrl+W
-actionSwitchTabLeft=Ctrl+Left
-actionSwitchTabRight=Ctrl+Right
-actionFocusAddressBar=F6
-actionBack=Alt+Left
-actionForward=Alt+Right
-actionRefresh=F5
-actionReload=Ctrl+F5
-actionOpen=Ctrl+O
-actionBookmark=Ctrl+D
-
diff --git a/src/settings/test/settings_mock.hpp b/src/settings/test/settings_mock.hpp
index bc3fbc2f..bf0e137a 100644
--- a/src/settings/test/settings_mock.hpp
+++ b/src/settings/test/settings_mock.hpp
@@ -21,7 +21,8 @@ public:
MOCK_METHOD(void, endGroup, (), (override));
MOCK_METHOD(void, setValue, (const QString &, const QVariant &), (override));
- MOCK_METHOD(QVariant, value, (const QString &, const QVariant &), (const, override));
+ MOCK_METHOD(void, resetValue, (const QString &), (override));
+ MOCK_METHOD(QVariant, value, (const QString &), (const, override));
MOCK_METHOD(QString, filePath, (), (const, override));
};
diff --git a/src/settings/test/test_settings.cpp b/src/settings/test/test_settings.cpp
index 6efc64c3..a797a224 100644
--- a/src/settings/test/test_settings.cpp
+++ b/src/settings/test/test_settings.cpp
@@ -7,9 +7,10 @@
#include <QApplication>
#include <QDialogButtonBox>
-#include <QDir>
+#include <QFile>
#include <QLineEdit>
#include <QPushButton>
+#include <QSettings>
#include <QStandardPaths>
#include <gtest/gtest.h>
@@ -19,9 +20,10 @@
#include "../settingsdialog.h"
#include "settings_mock.hpp"
-using ::testing::_;
+using ::testing::_; // NOLINT(bugprone-reserved-identifier)
using ::testing::AtLeast;
using ::testing::ContainerEq;
+using ::testing::Return;
using ::testing::ReturnArg;
MATCHER_P(QStringEq, a, "")
@@ -32,7 +34,7 @@ MATCHER_P(QStringEq, a, "")
MATCHER_P(QVariantEq, a, "")
{
*result_listener << "where the arg is " << qUtf8Printable(arg.toString());
- return arg.toString().compare(a) == 0;
+ return arg == QVariant(a);
}
TEST(settings, getFont)
@@ -46,15 +48,30 @@ TEST(settings, getFont)
TEST(settings, settingsPath)
{
- const auto path = QDir(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)).filePath("rekonqrc");
+ const auto path = Settings::path();
EXPECT_FALSE(path.isEmpty());
EXPECT_TRUE(path.endsWith("rekonqrc"));
+
+ QFile defaultSettingsPath(":/settings/rekonqrc");
+ EXPECT_TRUE(defaultSettingsPath.exists());
}
+class TestSettings : public Settings {
+public:
+ TestSettings(const QString &path = QString()) : Settings(path, nullptr){};
+ ~TestSettings() override = default;
+
+ [[nodiscard]] auto groups() const { return d->childGroups(); }
+ [[nodiscard]] auto keys() const { return d->childKeys(); }
+};
+
TEST(settings, Settings)
{
- Settings settings(":rekonqrc");
- EXPECT_THAT(settings.filePath(), QStringEq(":rekonqrc"));
+ TestSettings settings;
+ EXPECT_TRUE(settings.filePath().isEmpty());
+
+ EXPECT_TRUE(settings.groups().isEmpty());
+ EXPECT_TRUE(settings.keys().isEmpty());
const auto FirstRun = settings.value("FirstRun");
EXPECT_TRUE(FirstRun.isValid());
@@ -63,6 +80,9 @@ TEST(settings, Settings)
settings.setValue("FirstRun", false);
EXPECT_FALSE(settings.value("FirstRun").toBool());
+ EXPECT_TRUE(settings.groups().isEmpty());
+ EXPECT_EQ(settings.keys().count(), 1);
+
settings.beginGroup("Network");
const auto downloadPathAsk = settings.value("downloadPathAsk");
EXPECT_TRUE(downloadPathAsk.isValid());
@@ -72,9 +92,12 @@ TEST(settings, Settings)
const auto searchUrl = settings.value("searchUrl");
EXPECT_TRUE(searchUrl.isValid());
EXPECT_EQ(searchUrl.toString(), QString("https://duckduckgo.com/?q=%1"));
+
+ EXPECT_TRUE(settings.groups().isEmpty());
+ EXPECT_EQ(settings.keys().count(), 1);
}
-TEST(settings, SettingsDialog)
+TEST(settings, SettingsDialog_mock)
{
constexpr unsigned n_settings = 36; // there are 36 settings in total
MockSettings mockSettings;
@@ -82,16 +105,20 @@ TEST(settings, SettingsDialog)
// beginGroup/endGroup are called twice: during the ctor and when accepted
EXPECT_CALL(mockSettings, beginGroup).Times(3 * 4);
EXPECT_CALL(mockSettings, endGroup).Times(3 * 4);
- EXPECT_CALL(mockSettings, value).Times(n_settings * 2).WillRepeatedly(ReturnArg<1>());
- // 1 setting is hidden and won't be set by the dialog
- // save and reset will both call setValue on all non-hidden settings
- EXPECT_CALL(mockSettings, setValue(_, _)).Times(n_settings * 2 - 3);
+ EXPECT_CALL(mockSettings, value).Times(n_settings * 2 - 2).WillRepeatedly(ReturnArg<0>());
+ EXPECT_CALL(mockSettings, value(QStringEq("homepage"))).Times(2).WillRepeatedly(Return(QVariant("about:blank")));
+ // expect accept to call setValue on all non-hidden settings
+ EXPECT_CALL(mockSettings, setValue(_, _)).Times(n_settings - 2);
EXPECT_CALL(mockSettings, setValue(QStringEq("homepage"), QVariantEq("https://kde.org")));
+ EXPECT_CALL(mockSettings, setValue(QStringEq("FirstRun"), QVariantEq(false)));
+ // expect resetBtn to call resetValue on all non-hidden settings
+ EXPECT_CALL(mockSettings, resetValue).Times(n_settings - 1);
// change setting
{
SettingsDialog dlg(&mockSettings);
auto *homepage = dlg.findChild<QLineEdit *>("homepage");
+ ASSERT_FALSE(homepage == nullptr);
EXPECT_TRUE(homepage->text() == QLatin1String("about:blank")) << qUtf8Printable(homepage->text());
homepage->setText("https://kde.org");
dlg.accept();
@@ -101,24 +128,37 @@ TEST(settings, SettingsDialog)
{
SettingsDialog dlg(&mockSettings);
auto *resetBtn = dlg.findChild<QDialogButtonBox *>()->button(QDialogButtonBox::RestoreDefaults);
- EXPECT_FALSE(resetBtn == nullptr);
+ ASSERT_FALSE(resetBtn == nullptr);
resetBtn->click();
}
}
+TEST(settings, SettingsDialog)
+{
+ const auto path = Settings::path();
+ ASSERT_FALSE(QFile::exists(path));
+
+ {
+ Settings settings(path);
+ EXPECT_TRUE(settings.value("FirstRun").toBool());
+
+ SettingsDialog dlg(&settings);
+ auto *resetBtn = dlg.findChild<QDialogButtonBox *>()->button(QDialogButtonBox::RestoreDefaults);
+ ASSERT_FALSE(resetBtn == nullptr);
+ resetBtn->click();
+ }
+
+ ASSERT_TRUE(QFile::exists(path));
+ ASSERT_TRUE(QFile::remove(path));
+}
+
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
+ Q_INIT_RESOURCE(settings);
- // handling fonts requires a QGuiApplication
- // The proper platform name needs to be added to the argument list before the QGuiApplication constructor is called
- // This needs to be done here for gtest_discover_tests to work
- QList<char *> args;
- for (int i = 0; i < argc; ++i) args.append(argv[i]);
- args.append({"-platform", "offscreen"});
- int args_count = args.count();
-
- QApplication app(args_count, args.data());
+ QApplication app(argc, argv);
+ QStandardPaths::setTestModeEnabled(true);
return RUN_ALL_TESTS();
}
diff --git a/src/settings/test/test_settingsdialog.cpp b/src/settings/test/test_settingsdialog.cpp
index a50cf307..a89ec82d 100644
--- a/src/settings/test/test_settingsdialog.cpp
+++ b/src/settings/test/test_settingsdialog.cpp
@@ -5,20 +5,15 @@
* Copyright (C) 2022 aqua <aqua@iserlohn-fortress.net>
* ============================================================ */
+#include "../settings.hpp"
#include "../settingsdialog.h"
-#include "settings_mock.hpp"
#include <QApplication>
-using ::testing::AtLeast;
-using ::testing::NiceMock;
-using ::testing::ReturnArg;
-
int main(int argc, char **argv)
{
QApplication app(argc, argv);
- NiceMock<MockSettings> settings;
- EXPECT_CALL(settings, value).WillRepeatedly(ReturnArg<1>());
+ Settings settings(Settings::path());
SettingsDialog dlg(&settings);
dlg.show();