diff --git a/.kde-ci.yml b/.kde-ci.yml index 34411e35..98fb09c5 100644 --- a/.kde-ci.yml +++ b/.kde-ci.yml @@ -11,6 +11,7 @@ Dependencies: 'frameworks/ki18n': '@latest-kf6' 'frameworks/kconfig': '@latest-kf6' 'frameworks/threadweaver': '@latest-kf6' + 'frameworks/kcolorscheme': '@latest-kf6' 'libraries/kirigami-addons': '@latest-kf6' 'third-party/qtkeychain': '@latest' diff --git a/CMakeLists.txt b/CMakeLists.txt index 4153209a..825e4ac1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,7 +51,7 @@ ecm_set_disabled_deprecation_versions( ) find_package(Qt6 ${QT_MIN_VERSION} REQUIRED NO_MODULE COMPONENTS Core Quick Test Gui QuickControls2 Sql Svg Xml Network) -find_package(KF6 ${KF_MIN_VERSION} REQUIRED COMPONENTS I18n CoreAddons Kirigami2 Syndication Config ThreadWeaver) +find_package(KF6 ${KF_MIN_VERSION} REQUIRED COMPONENTS I18n CoreAddons Kirigami2 Syndication Config ThreadWeaver ColorScheme) find_package(Taglib REQUIRED) find_package(Qt6Keychain) diff --git a/README.md b/README.md index 93d2ff9a..648cc3bd 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ Note: When using versions of Kasts built from git-master, it's possible that the - TagLib - QtKeychain - ThreadWeaver + - KColorScheme - libVLC (optional, recommended) - GStreamer (optional) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 214a81d2..725a66ea 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -23,6 +23,7 @@ set(kasts_srcs utils/fetchfeedsjob.cpp utils/systrayicon.cpp utils/networkconnectionmanager.cpp + utils/colorschemer.cpp models/abstractepisodemodel.cpp models/abstractepisodeproxymodel.cpp models/chaptermodel.cpp @@ -168,7 +169,7 @@ add_executable(kasts ${kasts_srcs}) kconfig_add_kcfg_files(kasts settingsmanager.kcfgc GENERATE_MOC) target_include_directories(kasts PRIVATE ${CMAKE_BINARY_DIR}) -target_link_libraries(kasts PRIVATE Qt::Core Qt::Qml Qt::Quick Qt::QuickControls2 Qt::Sql Qt::Svg Qt::Xml Qt::Network KF6::Kirigami2 KF6::Syndication KF6::CoreAddons KF6::ConfigGui KF6::I18n Taglib::Taglib ${QTKEYCHAIN_LIBRARIES} KF6::ThreadWeaver KMediaSession) +target_link_libraries(kasts PRIVATE Qt::Core Qt::Qml Qt::Quick Qt::QuickControls2 Qt::Sql Qt::Svg Qt::Xml Qt::Network KF6::Kirigami2 KF6::Syndication KF6::CoreAddons KF6::ConfigGui KF6::I18n Taglib::Taglib ${QTKEYCHAIN_LIBRARIES} KF6::ThreadWeaver KF6::ColorScheme KMediaSession) if(KASTS_FLATPAK) target_compile_definitions(kasts PUBLIC KASTS_FLATPAK) diff --git a/src/main.cpp b/src/main.cpp index 61b29378..5d27e43e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -52,6 +52,7 @@ #include "settingsmanager.h" #include "sync/sync.h" #include "sync/syncutils.h" +#include "utils/colorschemer.h" #include "utils/networkconnectionmanager.h" #include "utils/storagemanager.h" #include "utils/systrayicon.h" @@ -158,6 +159,10 @@ int main(int argc, char *argv[]) qmlRegisterSingletonInstance("org.kde.kasts", 1, 0, "StorageManager", &StorageManager::instance()); qmlRegisterSingletonInstance("org.kde.kasts", 1, 0, "Sync", &Sync::instance()); qmlRegisterSingletonInstance("org.kde.kasts", 1, 0, "SystrayIcon", &SystrayIcon::instance()); + qmlRegisterSingletonInstance("org.kde.kasts", 1, 0, "ColorSchemer", &ColorSchemer::instance()); + if (SettingsManager::self()->colorScheme().isEmpty()) { + ColorSchemer::instance().apply(SettingsManager::self()->colorScheme()); + } qmlRegisterUncreatableMetaObject(SyncUtils::staticMetaObject, "org.kde.kasts", 1, 0, "SyncUtils", QStringLiteral("Error: only enums and structs")); diff --git a/src/qml/Settings/GeneralSettingsPage.qml b/src/qml/Settings/GeneralSettingsPage.qml index f337ac35..1a9c83db 100644 --- a/src/qml/Settings/GeneralSettingsPage.qml +++ b/src/qml/Settings/GeneralSettingsPage.qml @@ -26,6 +26,23 @@ FormCard.FormCardPage { FormCard.FormCard { Layout.fillWidth: true + FormCard.FormComboBoxDelegate { + Layout.fillWidth: true + id: colorTheme + text: i18n("Color theme") + textRole: "display" + valueRole: "display" + model: ColorSchemer.model + Component.onCompleted: currentIndex = ColorSchemer.indexForScheme(SettingsManager.colorScheme); + onCurrentValueChanged: { + ColorSchemer.apply(currentIndex); + SettingsManager.colorScheme = ColorSchemer.nameForIndex(currentIndex); + SettingsManager.save(); + } + } + + FormCard.FormDelegateSeparator {} + FormCard.FormCheckDelegate { id: alwaysShowFeedTitles text: i18n("Always show podcast titles in subscription view") diff --git a/src/settingsmanager.kcfg b/src/settingsmanager.kcfg index 565f99db..7f126e21 100644 --- a/src/settingsmanager.kcfg +++ b/src/settingsmanager.kcfg @@ -5,6 +5,9 @@ http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" > + + + false diff --git a/src/utils/colorschemer.cpp b/src/utils/colorschemer.cpp new file mode 100644 index 00000000..9a808116 --- /dev/null +++ b/src/utils/colorschemer.cpp @@ -0,0 +1,51 @@ +/** + * SPDX-FileCopyrightText: 2021 Carl Schwan + * SPDX-FileCopyrightText: 2023 Bart De Vries + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#include +#include + +#include "colorschemer.h" + +ColorSchemer::ColorSchemer(QObject *parent) + : QObject(parent) + , c(new KColorSchemeManager(this)) +{ +} + +ColorSchemer &ColorSchemer::instance() +{ + static ColorSchemer colorSchemer; + return colorSchemer; +} + +QAbstractItemModel *ColorSchemer::model() const +{ + return c->model(); +} + +void ColorSchemer::apply(int idx) +{ + c->activateScheme(c->model()->index(idx, 0)); +} + +void ColorSchemer::apply(const QString &name) +{ + c->activateScheme(c->indexForScheme(name)); +} + +int ColorSchemer::indexForScheme(const QString &name) const +{ + auto index = c->indexForScheme(name).row(); + if (index == -1) { + index = 0; + } + return index; +} + +QString ColorSchemer::nameForIndex(int index) const +{ + return c->model()->data(c->model()->index(index, 0), Qt::DisplayRole).toString(); +} diff --git a/src/utils/colorschemer.h b/src/utils/colorschemer.h new file mode 100644 index 00000000..596fbcfe --- /dev/null +++ b/src/utils/colorschemer.h @@ -0,0 +1,43 @@ +/** + * SPDX-FileCopyrightText: 2021 Carl Schwan + * SPDX-FileCopyrightText: 2023 Bart De Vries + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#pragma once + +#include +#include + +class QAbstractItemModel; +class KColorSchemeManager; + +class ColorSchemer : public QObject +{ + Q_OBJECT + QML_ELEMENT + QML_SINGLETON + + Q_PROPERTY(QAbstractItemModel *model READ model CONSTANT) + +public: + static ColorSchemer *create(QQmlEngine *, QJSEngine *) + { + auto inst = &instance(); + QJSEngine::setObjectOwnership(inst, QJSEngine::ObjectOwnership::CppOwnership); + return inst; + } + + explicit ColorSchemer(QObject *parent = nullptr); + + static ColorSchemer &instance(); + + QAbstractItemModel *model() const; + Q_INVOKABLE void apply(int idx); + Q_INVOKABLE void apply(const QString &name); + Q_INVOKABLE int indexForScheme(const QString &name) const; + Q_INVOKABLE QString nameForIndex(int index) const; + +private: + KColorSchemeManager *c; +};