diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8e2ed046..20b2cf96 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -51,7 +51,79 @@ add_executable(kasts sync/gpodder/uploadsubscriptionrequest.cpp sync/gpodder/episodeactionrequest.cpp sync/gpodder/uploadepisodeactionrequest.cpp - resources.qrc +) + +# define custom resource paths +set_source_files_properties(../kasts.svg PROPERTIES + QT_RESOURCE_ALIAS icons/kasts.svg +) +set_source_files_properties(../icons/media-playback-cloud.svg PROPERTIES + QT_RESOURCE_ALIAS icons/media-playback-cloud.svg +) +set_source_files_properties(../icons/kasts-tray-light.svg PROPERTIES + QT_RESOURCE_ALIAS icons/kasts-tray-light.svg +) +set_source_files_properties(../icons/kasts-tray-dark.svg PROPERTIES + QT_RESOURCE_ALIAS icons/kasts-tray-dark.svg +) + +# add icons needed by c++ +qt_add_resources(kasts "icons" + FILES + ../kasts.svg + ../icons/kasts-tray-light.svg + ../icons/kasts-tray-dark.svg +) + +qt_policy(SET QTP0001 NEW) +qt_add_qml_module(kasts URI org.kde.kasts + QML_FILES + qml/Main.qml + qml/FeedListPage.qml + qml/EntryPage.qml + qml/Settings/AboutPage.qml + qml/FeedDetailsPage.qml + qml/AddFeedSheet.qml + qml/FeedListDelegate.qml + qml/Mobile/MinimizedPlayerControls.qml + qml/Mobile/MobilePlayerControls.qml + qml/VolumeSlider.qml + qml/Mobile/FooterBar.qml + qml/Mobile/BottomToolbar.qml + qml/QueuePage.qml + qml/EpisodeListPage.qml + qml/DownloadListPage.qml + qml/ErrorList.qml + qml/ErrorListOverlay.qml + qml/GenericHeader.qml + qml/GenericEntryDelegate.qml + qml/GenericEntryListView.qml + qml/DiscoverPage.qml + qml/ImageWithFallback.qml + qml/UpdateNotification.qml + qml/KastsGlobalDrawer.qml + qml/Desktop/HeaderBar.qml + qml/Desktop/DesktopPlayerControls.qml + qml/PlaybackRateMenu.qml + qml/PlaybackRateCustomizerDialog.qml + qml/ErrorNotification.qml + qml/ConnectionCheckAction.qml + qml/ChapterListDelegate.qml + qml/SyncPasswordOverlay.qml + qml/Settings/SettingsPage.qml + qml/Settings/GeneralSettingsPage.qml + qml/Settings/NetworkSettingsPage.qml + qml/Settings/StorageSettingsPage.qml + qml/Settings/SynchronizationSettingsPage.qml + qml/Settings/ErrorListPage.qml + qml/SleepTimerDialog.qml + qml/FullScreenImage.qml + qml/GlobalSearchField.qml + qml/SearchBar.qml + qml/FilterInlineMessage.qml + RESOURCES + ../icons/media-playback-cloud.svg + ../kasts.svg ) ecm_qt_declare_logging_category(kasts @@ -143,9 +215,18 @@ if(ANDROID) endif() if(KASTS_FLATPAK) - target_sources(kasts PRIVATE resources-flatpak.qrc) + set_source_files_properties(qml/Settings/StorageDirDialogFlatpak.qml PROPERTIES + QT_RESOURCE_ALIAS qml/Settings/StorageDirDialog.qml + ) + qt_target_qml_sources(kasts + QML_FILES + qml/Settings/StorageDirDialogFlatpak.qml + ) else() - target_sources(kasts PRIVATE resources-non-flatpak.qrc) + qt_target_qml_sources(kasts + QML_FILES + qml/Settings/StorageDirDialog.qml + ) endif() ecm_add_app_icon(kasts ICONS ${kasts_ICONS_PNG} @@ -159,7 +240,7 @@ ecm_add_app_icon(kasts ICONS ${kasts_ICONS_PNG} kconfig_add_kcfg_files(kasts settingsmanager.kcfgc GENERATE_MOC) -target_include_directories(kasts PRIVATE ${CMAKE_BINARY_DIR}) +target_include_directories(kasts PRIVATE ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/models ${CMAKE_CURRENT_SOURCE_DIR}/utils ${CMAKE_CURRENT_SOURCE_DIR}/sync) target_link_libraries(kasts PRIVATE Qt::Core Qt::Qml Qt::Quick Qt::QuickControls2 Qt::Sql Qt::Svg Qt::Xml Qt::Network KF6::Kirigami KF6::Syndication KF6::CoreAddons KF6::ConfigGui KF6::I18n Taglib::Taglib ${QTKEYCHAIN_LIBRARIES} KF6::ThreadWeaver KF6::ColorScheme KMediaSession) if(KASTS_FLATPAK) diff --git a/src/audiomanager.h b/src/audiomanager.h index e4cf050d..c87e6514 100644 --- a/src/audiomanager.h +++ b/src/audiomanager.h @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -24,6 +25,8 @@ class AudioManagerPrivate; class AudioManager : public QObject { Q_OBJECT + QML_ELEMENT + QML_SINGLETON Q_PROPERTY(KMediaSession::MediaBackends currentBackend READ currentBackend WRITE setCurrentBackend NOTIFY currentBackendChanged) Q_PROPERTY(QList availableBackends READ availableBackends CONSTANT) @@ -56,6 +59,11 @@ public: static AudioManager _instance; return _instance; } + static AudioManager *create(QQmlEngine *engine, QJSEngine *) + { + engine->setObjectOwnership(&instance(), QQmlEngine::CppOwnership); + return &instance(); + } ~AudioManager() override; diff --git a/src/database.h b/src/database.h index b00bf358..d6096414 100644 --- a/src/database.h +++ b/src/database.h @@ -8,12 +8,15 @@ #pragma once #include +#include #include #include class Database : public QObject { Q_OBJECT + QML_ELEMENT + QML_SINGLETON public: static Database &instance() @@ -21,6 +24,11 @@ public: static Database _instance; return _instance; } + static Database *create(QQmlEngine *engine, QJSEngine *) + { + engine->setObjectOwnership(&instance(), QQmlEngine::CppOwnership); + return &instance(); + } static void openDatabase(const QString &connectionName = QLatin1String(QSqlDatabase::defaultConnection)); static void closeDatabase(const QString &connectionName = QLatin1String(QSqlDatabase::defaultConnection)); diff --git a/src/datamanager.h b/src/datamanager.h index 47e7ee84..439f560e 100644 --- a/src/datamanager.h +++ b/src/datamanager.h @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -20,13 +21,19 @@ class Feed; class DataManager : public QObject { Q_OBJECT - + QML_ELEMENT + QML_SINGLETON public: static DataManager &instance() { static DataManager _instance; return _instance; } + static DataManager *create(QQmlEngine *engine, QJSEngine *) + { + engine->setObjectOwnership(&instance(), QQmlEngine::CppOwnership); + return &instance(); + } Feed *getFeed(const int index) const; Q_INVOKABLE Feed *getFeed(const QString &feedurl) const; diff --git a/src/enclosure.h b/src/enclosure.h index e3ba8667..5814c0cc 100644 --- a/src/enclosure.h +++ b/src/enclosure.h @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -20,6 +21,8 @@ class Entry; class Enclosure : public QObject { Q_OBJECT + QML_ELEMENT + QML_UNCREATABLE("") Q_PROPERTY(qint64 size READ size WRITE setSize NOTIFY sizeChanged) Q_PROPERTY(QString formattedSize READ formattedSize NOTIFY sizeChanged) diff --git a/src/fetcher.h b/src/fetcher.h index fb6df36d..76b7988b 100644 --- a/src/fetcher.h +++ b/src/fetcher.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -20,6 +21,8 @@ class Fetcher : public QObject { Q_OBJECT + QML_ELEMENT + QML_SINGLETON Q_PROPERTY(int updateProgress MEMBER m_updateProgress NOTIFY updateProgressChanged) Q_PROPERTY(int updateTotal MEMBER m_updateTotal NOTIFY updateTotalChanged) @@ -31,6 +34,11 @@ public: static Fetcher _instance; return _instance; } + static Fetcher *create(QQmlEngine *engine, QJSEngine *) + { + engine->setObjectOwnership(&instance(), QQmlEngine::CppOwnership); + return &instance(); + } Q_INVOKABLE void fetch(const QString &url); Q_INVOKABLE void fetch(const QStringList &urls); diff --git a/src/kmediasession/CMakeLists.txt b/src/kmediasession/CMakeLists.txt index c7807d8d..854701cd 100644 --- a/src/kmediasession/CMakeLists.txt +++ b/src/kmediasession/CMakeLists.txt @@ -27,9 +27,7 @@ endif() ######################################### -add_subdirectory(qml) - -set(kmediasession_srcs +add_library(KMediaSession kmediasession.cpp metadata.cpp mediabackends/abstractmediabackend.h @@ -38,35 +36,40 @@ set(kmediasession_srcs mpris2/mpris2.cpp ) -ecm_qt_declare_logging_category(kmediasession_srcs +qt_policy(SET QTP0001 NEW) +qt_add_qml_module(KMediaSession URI org.kde.kmediasession + OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/org/kde/kmediasession +) + +ecm_qt_declare_logging_category(KMediaSession HEADER "kmediasessionlogging.h" IDENTIFIER "KMediaSessionLog" CATEGORY_NAME "org.kde.kmediasession.kmediasession" DEFAULT_SEVERITY Info ) -ecm_qt_declare_logging_category(kmediasession_srcs +ecm_qt_declare_logging_category(KMediaSession HEADER "powermanagementinterfacelogging.h" IDENTIFIER "KMediaSessionPowerManagementInterface" CATEGORY_NAME "org.kde.kmediasession.powermanagementinterface" DEFAULT_SEVERITY Info ) -ecm_qt_declare_logging_category(kmediasession_srcs +ecm_qt_declare_logging_category(KMediaSession HEADER "qtmediabackendlogging.h" IDENTIFIER "QtMediaBackendLog" CATEGORY_NAME "org.kde.kmediasession.qtmediabackend" DEFAULT_SEVERITY Info ) -ecm_qt_declare_logging_category(kmediasession_srcs +ecm_qt_declare_logging_category(KMediaSession HEADER "mpris2logging.h" IDENTIFIER "Mpris2Log" CATEGORY_NAME "org.kde.kmediasession.mpris2" DEFAULT_SEVERITY Info ) -ecm_qt_declare_logging_category(kmediasession_srcs +ecm_qt_declare_logging_category(KMediaSession HEADER "metadatalogging.h" IDENTIFIER "MetaDataLog" CATEGORY_NAME "org.kde.kmediasession.metadata" @@ -74,51 +77,51 @@ ecm_qt_declare_logging_category(kmediasession_srcs ) if(ANDROID) - list(APPEND kmediasession_srcs - androidlogging.h - ) + target_sources(KMediaSession PRIVATE androidlogging.h) else() - list(APPEND kmediasession_srcs + set(KMediaSession_dbus_srcs "") + qt_add_dbus_interface(KMediaSession_dbus_srcs dbus-interfaces/org.freedesktop.PowerManagement.Inhibit.xml inhibitinterface) + qt_add_dbus_interface(KMediaSession_dbus_srcs dbus-interfaces/org.gnome.SessionManager.xml gnomesessioninterface) + target_sources(KMediaSession PRIVATE mpris2/mediaplayer2.cpp mpris2/mediaplayer2player.cpp + ${KMediaSession_dbus_srcs} ) - qt_add_dbus_interface(kmediasession_srcs dbus-interfaces/org.freedesktop.PowerManagement.Inhibit.xml inhibitinterface) - qt_add_dbus_interface(kmediasession_srcs dbus-interfaces/org.gnome.SessionManager.xml gnomesessioninterface) endif() if (LIBVLC_FOUND) - ecm_qt_declare_logging_category(kmediasession_srcs + ecm_qt_declare_logging_category(KMediaSession HEADER "vlcmediabackendlogging.h" IDENTIFIER "VlcMediaBackendLog" CATEGORY_NAME "org.kde.kmediasession.vlcmediabackend" DEFAULT_SEVERITY Info ) - ecm_qt_declare_logging_category(kmediasession_srcs + ecm_qt_declare_logging_category(KMediaSession HEADER "vlcsignalslogging.h" IDENTIFIER "VlcSignalsLog" CATEGORY_NAME "org.kde.kmediasession.vlcsignals" DEFAULT_SEVERITY Info ) - list(APPEND kmediasession_srcs + target_sources(KMediaSession PRIVATE mediabackends/vlcmediabackend.cpp ) set(HAVE_LIBVLC ON) endif() if (GSTREAMER_FOUND) - ecm_qt_declare_logging_category(kmediasession_srcs + ecm_qt_declare_logging_category(KMediaSession HEADER "gstmediabackendlogging.h" IDENTIFIER "GstMediaBackendLog" CATEGORY_NAME "org.kde.kmediasession.gstmediabackend" DEFAULT_SEVERITY Info ) - ecm_qt_declare_logging_category(kmediasession_srcs + ecm_qt_declare_logging_category(KMediaSession HEADER "gstsignalslogging.h" IDENTIFIER "GstSignalsLog" CATEGORY_NAME "org.kde.kmediasession.gstsignals" DEFAULT_SEVERITY Info ) - list(APPEND kmediasession_srcs + target_sources(KMediaSession PRIVATE mediabackends/gstmediabackend.cpp ) set(HAVE_GST ON) @@ -126,7 +129,6 @@ endif() configure_file(config-kmediasession.h.in ${CMAKE_CURRENT_BINARY_DIR}/config-kmediasession.h) -add_library(KMediaSession ${kmediasession_srcs}) generate_export_header(KMediaSession BASE_NAME KMediaSession) target_include_directories(KMediaSession PUBLIC ${CMAKE_BINARY_DIR}) diff --git a/src/kmediasession/example-app/CMakeLists.txt b/src/kmediasession/example-app/CMakeLists.txt index 247ba4d9..b87baac4 100644 --- a/src/kmediasession/example-app/CMakeLists.txt +++ b/src/kmediasession/example-app/CMakeLists.txt @@ -2,7 +2,7 @@ # SPDX-FileCopyrightText: 2022-2023 Bart De Vries find_package(Qt6 ${QT_MIN_VERSION} REQUIRED NO_MODULE COMPONENTS Core Qml Gui Multimedia) -find_package(KF6 ${KF_MIN_VERSION} REQUIRED COMPONENTS CoreAddons I18n) +find_package(KF6 ${KF_MIN_VERSION} REQUIRED COMPONENTS CoreAddons Kirigami I18n) if (NOT ANDROID) find_package(Qt6 ${QT_MIN_VERSION} REQUIRED COMPONENTS DBus Widgets) @@ -10,13 +10,20 @@ endif() ########################################################### -add_executable(kmediasession-example main.cpp resources.qrc) +add_executable(kmediasession-example main.cpp) + +qt_policy(SET QTP0001 NEW) +qt_add_qml_module(kmediasession-example URI org.kde.kmediasession-example + QML_FILES + qml/Main.qml +) target_link_libraries(kmediasession-example PRIVATE Qt::Core Qt::Qml Qt::Gui KF6::CoreAddons + KF6::Kirigami KF6::I18n KMediaSession ) diff --git a/src/kmediasession/example-app/main.cpp b/src/kmediasession/example-app/main.cpp index ccec0e5c..f301e9ab 100644 --- a/src/kmediasession/example-app/main.cpp +++ b/src/kmediasession/example-app/main.cpp @@ -40,7 +40,7 @@ int main(int argc, char *argv[]) engine.rootContext()->setContextObject(new KLocalizedContext(&engine)); KLocalizedString::setApplicationDomain("kmediasession-example"); - engine.load(QUrl(QStringLiteral("qrc:///main.qml"))); + engine.loadFromModule("org.kde.kmediasession-example", "Main"); if (engine.rootObjects().isEmpty()) { return -1; diff --git a/src/kmediasession/example-app/qml/main.qml b/src/kmediasession/example-app/qml/Main.qml similarity index 96% rename from src/kmediasession/example-app/qml/main.qml rename to src/kmediasession/example-app/qml/Main.qml index bce58f3e..8bb8bbe4 100644 --- a/src/kmediasession/example-app/qml/main.qml +++ b/src/kmediasession/example-app/qml/Main.qml @@ -4,15 +4,15 @@ * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL */ -import QtQuick 2.15 -import QtQuick.Controls 2.15 as Controls -import QtQuick.Layouts 1.15 -import QtMultimedia 5.15 -import Qt.labs.platform 1.1 +import QtQuick +import QtQuick.Controls as Controls +import QtQuick.Layouts +import QtMultimedia +import Qt.labs.platform -import org.kde.kirigami 2.15 as Kirigami +import org.kde.kirigami as Kirigami -import org.kde.kmediasession 1.0 +import org.kde.kmediasession Kirigami.ApplicationWindow { id: root diff --git a/src/kmediasession/example-app/resources.qrc b/src/kmediasession/example-app/resources.qrc deleted file mode 100644 index 8e44f9a0..00000000 --- a/src/kmediasession/example-app/resources.qrc +++ /dev/null @@ -1,8 +0,0 @@ - - - - - qml/main.qml - - - diff --git a/src/kmediasession/kmediasession.h b/src/kmediasession/kmediasession.h index 924803c3..5681125b 100644 --- a/src/kmediasession/kmediasession.h +++ b/src/kmediasession/kmediasession.h @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -22,6 +23,7 @@ class KMediaSessionPrivate; class KMEDIASESSION_EXPORT KMediaSession : public QObject { Q_OBJECT + QML_ELEMENT Q_PROPERTY(KMediaSession::MediaBackends currentBackend READ currentBackend WRITE setCurrentBackend NOTIFY currentBackendChanged) Q_PROPERTY(QList availableBackends READ availableBackends CONSTANT) diff --git a/src/kmediasession/metadata.h b/src/kmediasession/metadata.h index 24a902fe..315464d6 100644 --- a/src/kmediasession/metadata.h +++ b/src/kmediasession/metadata.h @@ -9,12 +9,14 @@ #include "kmediasession_export.h" #include +#include #include #include class KMEDIASESSION_EXPORT MetaData : public QObject { Q_OBJECT + QML_ELEMENT Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged) Q_PROPERTY(QString artist READ artist WRITE setArtist NOTIFY artistChanged) diff --git a/src/kmediasession/qml/CMakeLists.txt b/src/kmediasession/qml/CMakeLists.txt deleted file mode 100644 index cfb5b787..00000000 --- a/src/kmediasession/qml/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -# SPDX-License-Identifier: BSD-2-Clause -# SPDX-FileCopyrightText: 2022-2023 Bart De Vries - -add_library(kmediasession-qmlplugin kmediasession-qmlplugin.cpp) -target_link_libraries(kmediasession-qmlplugin - Qt::Qml - KMediaSession -) - -# make examples work without installation -if (NOT CMAKE_VERSION VERSION_LESS 3.14) - set_property(TARGET kmediasession-qmlplugin PROPERTY LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/org/kde/kmediasession) - file(CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/qmldir ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/org/kde/kmediasession/qmldir COPY_ON_ERROR SYMBOLIC) -else() - message(WARNING "CMake is too old, cannot setup QML plugins to work without installation") -endif() - -install(TARGETS kmediasession-qmlplugin DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/kmediasession) -install(FILES qmldir DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/kmediasession) diff --git a/src/kmediasession/qml/kmediasession-qmlplugin.cpp b/src/kmediasession/qml/kmediasession-qmlplugin.cpp deleted file mode 100644 index 79c43018..00000000 --- a/src/kmediasession/qml/kmediasession-qmlplugin.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/** - * SPDX-FileCopyrightText: 2022-2023 Bart De Vries - * - * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL - */ - -#include -#include -#include - -#include -#include - -class KMediaSessionQmlPlugin : public QQmlExtensionPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") - void registerTypes(const char *uri) override; -}; - -void KMediaSessionQmlPlugin::registerTypes(const char *) -{ - qmlRegisterType("org.kde.kmediasession", 1, 0, "KMediaSession"); - qmlRegisterType("org.kde.kmediasession", 1, 0, "MetaData"); - - qRegisterMetaType("KMediaSession::MediaBackends"); - qRegisterMetaType>("QList"); -} - -#include "kmediasession-qmlplugin.moc" diff --git a/src/kmediasession/qml/qmldir b/src/kmediasession/qml/qmldir deleted file mode 100644 index a02095c1..00000000 --- a/src/kmediasession/qml/qmldir +++ /dev/null @@ -1,3 +0,0 @@ -module org.kde.kmediasession -plugin kmediasession-qmlplugin -classname KMediaSessionQmlPlugin diff --git a/src/kmediasession/qml/qmldir.license b/src/kmediasession/qml/qmldir.license deleted file mode 100644 index b4a767d8..00000000 --- a/src/kmediasession/qml/qmldir.license +++ /dev/null @@ -1,2 +0,0 @@ -SPDX-License-Identifier: BSD-2-Clause -SPDX-FileCopyrightText: 2022-2023 Bart De Vries diff --git a/src/main.cpp b/src/main.cpp index 730161ca..40a78f85 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -120,62 +120,30 @@ int main(int argc, char *argv[]) i18n("© 2020–2023 KDE Community")); about.addAuthor(i18n("Tobias Fella"), QString(), QStringLiteral("tobias.fella@kde.org"), QStringLiteral("https://tobiasfella.de")); about.addAuthor(i18n("Bart De Vries"), QString(), QStringLiteral("bart@mogwai.be")); - about.setProgramLogo(QVariant(QIcon(QStringLiteral(":/logo.svg")))); KAboutData::setApplicationData(about); about.setupCommandLine(&parser); parser.process(app); QString feedURL = parser.value(addFeedOption); + Database::instance(); if (feedURL != QStringLiteral("none")) { - Database::instance(); DataManager::instance().addFeed(feedURL); } about.processCommandLine(&parser); - qmlRegisterType("org.kde.kasts", 1, 0, "FeedsProxyModel"); - qmlRegisterType("org.kde.kasts", 1, 0, "QueueModel"); - qmlRegisterType("org.kde.kasts", 1, 0, "EpisodeProxyModel"); - qmlRegisterType("org.kde.kasts", 1, 0, "PodcastSearchModel"); - qmlRegisterType("org.kde.kasts", 1, 0, "ChapterModel"); + qmlRegisterSingletonInstance("org.kde.kasts.settings", 1, 0, "SettingsManager", SettingsManager::self()); - qmlRegisterUncreatableType("org.kde.kasts", 1, 0, "AbstractEpisodeProxyModel", QStringLiteral("Only for enums")); - qmlRegisterUncreatableType("org.kde.kasts", 1, 0, "EntriesProxyModel", QStringLiteral("Get from Feed")); - qmlRegisterUncreatableType("org.kde.kasts", 1, 0, "Enclosure", QStringLiteral("Only for enums")); - qmlRegisterUncreatableType("org.kde.kasts", 1, 0, "AbstractEpisodeModel", QStringLiteral("Only for enums")); - qmlRegisterUncreatableType("org.kde.kasts", 1, 0, "FeedsModel", QStringLiteral("Only for enums")); - - qmlRegisterSingletonType("org.kde.kasts", 1, 0, "About", [](QQmlEngine *engine, QJSEngine *) -> QJSValue { - return engine->toScriptValue(KAboutData::applicationData()); - }); - qmlRegisterSingletonInstance("org.kde.kasts", 1, 0, "Database", &Database::instance()); - qmlRegisterSingletonInstance("org.kde.kasts", 1, 0, "NetworkConnectionManager", &NetworkConnectionManager::instance()); - qmlRegisterSingletonInstance("org.kde.kasts", 1, 0, "Fetcher", &Fetcher::instance()); - qmlRegisterSingletonInstance("org.kde.kasts", 1, 0, "DataManager", &DataManager::instance()); - qmlRegisterSingletonInstance("org.kde.kasts", 1, 0, "SettingsManager", SettingsManager::self()); - qmlRegisterSingletonInstance("org.kde.kasts", 1, 0, "DownloadModel", &DownloadModel::instance()); - qmlRegisterSingletonInstance("org.kde.kasts", 1, 0, "ErrorLogModel", &ErrorLogModel::instance()); - qmlRegisterSingletonInstance("org.kde.kasts", 1, 0, "AudioManager", &AudioManager::instance()); - 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")); - - qRegisterMetaType("const Entry*"); // "hack" to make qml understand Entry* - qRegisterMetaType("const Feed*"); // "hack" to make qml understand Feed* - qRegisterMetaType>("QVector"); // "hack" to make qml understand QVector of SyncUtils::Device - // Workaround to don't get the app to silently quit when minimized to tray app.setQuitLockEnabled(false); // Make sure that settings are saved before the application exits QObject::connect(&app, &QCoreApplication::aboutToQuit, SettingsManager::self(), &SettingsManager::save); - engine.load(QUrl(QStringLiteral("qrc:///main.qml"))); + engine.loadFromModule("org.kde.kasts", "Main"); if (engine.rootObjects().isEmpty()) { return -1; diff --git a/src/models/abstractepisodemodel.h b/src/models/abstractepisodemodel.h index 21f4db94..0b1850b2 100644 --- a/src/models/abstractepisodemodel.h +++ b/src/models/abstractepisodemodel.h @@ -10,10 +10,13 @@ #include #include #include +#include class AbstractEpisodeModel : public QAbstractListModel { Q_OBJECT + QML_ELEMENT + QML_UNCREATABLE("") public: enum Roles { diff --git a/src/models/abstractepisodeproxymodel.h b/src/models/abstractepisodeproxymodel.h index 1873b7fa..f123c5d9 100644 --- a/src/models/abstractepisodeproxymodel.h +++ b/src/models/abstractepisodeproxymodel.h @@ -7,6 +7,7 @@ #pragma once #include +#include #include #include @@ -17,6 +18,8 @@ class Entry; class AbstractEpisodeProxyModel : public QSortFilterProxyModel { Q_OBJECT + QML_ELEMENT + QML_UNCREATABLE("") public: enum FilterType { diff --git a/src/models/chaptermodel.h b/src/models/chaptermodel.h index 0ab48195..fb6f1836 100644 --- a/src/models/chaptermodel.h +++ b/src/models/chaptermodel.h @@ -8,6 +8,7 @@ #include #include +#include #include @@ -17,6 +18,7 @@ class ChapterModel : public QAbstractListModel { Q_OBJECT + QML_ELEMENT Q_PROPERTY(Entry *entry READ entry WRITE setEntry NOTIFY entryChanged) Q_PROPERTY(Chapter *currentChapter READ currentChapter NOTIFY currentChapterChanged) diff --git a/src/models/downloadmodel.h b/src/models/downloadmodel.h index a8315053..16720d6a 100644 --- a/src/models/downloadmodel.h +++ b/src/models/downloadmodel.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "enclosure.h" @@ -18,6 +19,8 @@ class DownloadModel : public QAbstractListModel { Q_OBJECT + QML_ELEMENT + QML_SINGLETON public: static DownloadModel &instance() @@ -25,6 +28,11 @@ public: static DownloadModel _instance; return _instance; } + static DownloadModel *create(QQmlEngine *engine, QJSEngine *) + { + engine->setObjectOwnership(&instance(), QQmlEngine::CppOwnership); + return &instance(); + } QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QHash roleNames() const override; diff --git a/src/models/entriesproxymodel.h b/src/models/entriesproxymodel.h index 0d916081..6da91873 100644 --- a/src/models/entriesproxymodel.h +++ b/src/models/entriesproxymodel.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include "models/abstractepisodeproxymodel.h" #include "models/entriesmodel.h" @@ -17,6 +18,8 @@ class Feed; class EntriesProxyModel : public AbstractEpisodeProxyModel { Q_OBJECT + QML_ELEMENT + QML_UNCREATABLE("") Q_PROPERTY(Feed *feed READ feed CONSTANT) diff --git a/src/models/episodeproxymodel.h b/src/models/episodeproxymodel.h index 512599fc..9eefe9db 100644 --- a/src/models/episodeproxymodel.h +++ b/src/models/episodeproxymodel.h @@ -7,6 +7,7 @@ #pragma once #include +#include #include "models/abstractepisodeproxymodel.h" #include "models/episodemodel.h" @@ -14,6 +15,7 @@ class EpisodeProxyModel : public AbstractEpisodeProxyModel { Q_OBJECT + QML_ELEMENT public: explicit EpisodeProxyModel(QObject *parent = nullptr); diff --git a/src/models/errorlogmodel.h b/src/models/errorlogmodel.h index b76d096e..9cce5426 100644 --- a/src/models/errorlogmodel.h +++ b/src/models/errorlogmodel.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "error.h" @@ -17,6 +18,8 @@ class ErrorLogModel : public QAbstractListModel { Q_OBJECT + QML_ELEMENT + QML_SINGLETON public: static ErrorLogModel &instance() @@ -24,6 +27,11 @@ public: static ErrorLogModel _instance; return _instance; } + static ErrorLogModel *create(QQmlEngine *engine, QJSEngine *) + { + engine->setObjectOwnership(&instance(), QQmlEngine::CppOwnership); + return &instance(); + } QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QHash roleNames() const override; diff --git a/src/models/feedsmodel.h b/src/models/feedsmodel.h index f8bbe3cb..71030ff6 100644 --- a/src/models/feedsmodel.h +++ b/src/models/feedsmodel.h @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -17,6 +18,8 @@ class FeedsModel : public QAbstractListModel { Q_OBJECT + QML_ELEMENT + QML_UNCREATABLE("") public: enum Roles { diff --git a/src/models/feedsproxymodel.h b/src/models/feedsproxymodel.h index 4c20bd79..b27ee853 100644 --- a/src/models/feedsproxymodel.h +++ b/src/models/feedsproxymodel.h @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -18,6 +19,7 @@ class Entry; class FeedsProxyModel : public QSortFilterProxyModel { Q_OBJECT + QML_ELEMENT public: enum SortType { diff --git a/src/models/podcastsearchmodel.h b/src/models/podcastsearchmodel.h index 9bd4fc2c..aae4424d 100644 --- a/src/models/podcastsearchmodel.h +++ b/src/models/podcastsearchmodel.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "feed.h" @@ -18,6 +19,8 @@ class PodcastSearchModel : public QAbstractListModel { Q_OBJECT + QML_ELEMENT + public: enum Roles { Id = Qt::UserRole, diff --git a/src/models/queuemodel.h b/src/models/queuemodel.h index 951092fe..bfa13ffa 100644 --- a/src/models/queuemodel.h +++ b/src/models/queuemodel.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -18,6 +19,7 @@ class QueueModel : public AbstractEpisodeModel { Q_OBJECT + QML_ELEMENT public: Q_PROPERTY(int timeLeft READ timeLeft NOTIFY timeLeftChanged) diff --git a/src/qml/ChapterListDelegate.qml b/src/qml/ChapterListDelegate.qml index a9f24a57..52e2448a 100644 --- a/src/qml/ChapterListDelegate.qml +++ b/src/qml/ChapterListDelegate.qml @@ -14,7 +14,7 @@ import org.kde.kirigamiaddons.delegates as AddonDelegates import org.kde.kmediasession import org.kde.kasts - +import org.kde.kasts.settings AddonDelegates.RoundedItemDelegate { id: root diff --git a/src/qml/ConnectionCheckAction.qml b/src/qml/ConnectionCheckAction.qml index 9f4a182e..e27e1df1 100644 --- a/src/qml/ConnectionCheckAction.qml +++ b/src/qml/ConnectionCheckAction.qml @@ -12,6 +12,7 @@ import org.kde.kirigami as Kirigami import org.kde.kirigamiaddons.delegates as Delegates import org.kde.kasts +import org.kde.kasts.settings Kirigami.Dialog { id: overlay diff --git a/src/qml/Desktop/DesktopPlayerControls.qml b/src/qml/Desktop/DesktopPlayerControls.qml index 90c1de60..2e7ed4de 100644 --- a/src/qml/Desktop/DesktopPlayerControls.qml +++ b/src/qml/Desktop/DesktopPlayerControls.qml @@ -13,6 +13,9 @@ import org.kde.kirigami as Kirigami import org.kde.kmediasession import org.kde.kasts +import org.kde.kasts.settings + +import ".." FocusScope { id: desktopPlayerControls diff --git a/src/qml/Desktop/HeaderBar.qml b/src/qml/Desktop/HeaderBar.qml index a173dc21..ae1d9855 100644 --- a/src/qml/Desktop/HeaderBar.qml +++ b/src/qml/Desktop/HeaderBar.qml @@ -16,6 +16,8 @@ import org.kde.kmediasession import org.kde.kasts +import ".." + FocusScope { id: headerBar height: headerMetaData.implicitHeight + desktopPlayerControls.implicitHeight @@ -30,7 +32,7 @@ FocusScope { function openEntry() { if (AudioManager.entry) { pushPage("QueuePage"); - pageStack.push("qrc:/EntryPage.qml", {"entry": AudioManager.entry}); + pageStack.push("qrc:/qt/qml/org/kde/kasts/qml/EntryPage.qml", {"entry": AudioManager.entry}); pageStack.get(0).lastEntry = AudioManager.entry.id; var model = pageStack.get(0).queueList.model; for (var i = 0; i < model.rowCount(); i++) { @@ -47,7 +49,7 @@ FocusScope { function openFeed() { if (AudioManager.entry) { pushPage("FeedListPage"); - pageStack.push("qrc:/FeedDetailsPage.qml", {"feed": AudioManager.entry.feed}); + pageStack.push("qrc:/qt/qml/org/kde/kasts/qml/FeedDetailsPage.qml", {"feed": AudioManager.entry.feed}); } } @@ -57,7 +59,7 @@ FocusScope { "description": Qt.binding(function() { return headerMetaData.title }), "loader": Qt.binding(function() { return fullScreenImageLoader}) }; - fullScreenImageLoader.setSource("qrc:/FullScreenImage.qml", options); + fullScreenImageLoader.setSource("qrc:/qt/qml/org/kde/kasts/qml/FullScreenImage.qml", options); fullScreenImageLoader.active = true; fullScreenImageLoader.item.open(); } diff --git a/src/qml/DiscoverPage.qml b/src/qml/DiscoverPage.qml index 8c781767..1a728415 100644 --- a/src/qml/DiscoverPage.qml +++ b/src/qml/DiscoverPage.qml @@ -99,7 +99,7 @@ Kirigami.ScrollablePage { Keys.onReturnPressed: clicked() onClicked: { - pageStack.push("qrc:/FeedDetailsPage.qml", { + pageStack.push("qrc:/qt/qml/org/kde/kasts/qml/FeedDetailsPage.qml", { feed: subscribeAction.enabled ? listItem.model : DataManager.getFeed(listItem.url), isSubscribed: !subscribeAction.enabled, subscribeAction: subscribeAction, diff --git a/src/qml/EntryPage.qml b/src/qml/EntryPage.qml index 277cb309..ffb8eccb 100644 --- a/src/qml/EntryPage.qml +++ b/src/qml/EntryPage.qml @@ -13,6 +13,7 @@ import org.kde.kirigami as Kirigami import org.kde.kmediasession import org.kde.kasts +import org.kde.kasts.settings Kirigami.ScrollablePage { id: page @@ -26,7 +27,7 @@ Kirigami.ScrollablePage { function openPodcast() { pushPage("FeedListPage"); lastFeed = entry.feed.url; - pageStack.push("qrc:/FeedDetailsPage.qml", {"feed": entry.feed}); + pageStack.push("qrc:/qt/qml/org/kde/kasts/qml/FeedDetailsPage.qml", {"feed": entry.feed}); } // This function is needed to close the EntryPage if it is opened over the diff --git a/src/qml/FeedListDelegate.qml b/src/qml/FeedListDelegate.qml index ed35d6b4..6cfdcab9 100644 --- a/src/qml/FeedListDelegate.qml +++ b/src/qml/FeedListDelegate.qml @@ -215,7 +215,7 @@ Controls.ItemDelegate { lastFeed = feed.url if (pageStack.depth > 1) pageStack.pop(); - pageStack.push("qrc:/FeedDetailsPage.qml", {"feed": feed}) + pageStack.push("qrc:/qt/qml/org/kde/kasts/qml/FeedDetailsPage.qml", {"feed": feed}) } Controls.ToolTip.visible: hovered @@ -234,7 +234,7 @@ Controls.ItemDelegate { onTriggered: { while (pageStack.depth > 1) pageStack.pop() - pageStack.push("qrc:/FeedDetailsPage.qml", {"feed": feed}); + pageStack.push("qrc:/qt/qml/org/kde/kasts/qml/FeedDetailsPage.qml", {"feed": feed}); } icon.name: "documentinfo" text: i18n("Podcast Details") diff --git a/src/qml/FeedListPage.qml b/src/qml/FeedListPage.qml index deb0718e..af2f8ad4 100644 --- a/src/qml/FeedListPage.qml +++ b/src/qml/FeedListPage.qml @@ -41,7 +41,7 @@ Kirigami.ScrollablePage { text: i18nc("@action:intoolbar Open the podcast discover page", "Discover") icon.name: "search" onTriggered: { - applicationWindow().pageStack.push("qrc:/DiscoverPage.qml"); + applicationWindow().pageStack.push("qrc:/qt/qml/org/kde/kasts/qml/DiscoverPage.qml"); } }, Kirigami.Action { @@ -231,7 +231,7 @@ Kirigami.ScrollablePage { // not using pushPage here in order to open the sync page // directly pageStack.layers.clear() - pageStack.pushDialogLayer("qrc:/SettingsPage.qml", { + pageStack.pushDialogLayer("qrc:/qt/qml/org/kde/kasts/qml/Settings/SettingsPage.qml", { defaultPage: "Synchronization" }, { title: i18n("Settings"), }) @@ -414,7 +414,7 @@ Kirigami.ScrollablePage { onTriggered: { while(pageStack.depth > 1) pageStack.pop(); - pageStack.push("qrc:/FeedDetailsPage.qml", {"feed": feedList.selectionForContextMenu[0].model.data(feedList.selectionForContextMenu[0], FeedsModel.FeedRole)}); + pageStack.push("qrc:/qt/qml/org/kde/kasts/qml/FeedDetailsPage.qml", {"feed": feedList.selectionForContextMenu[0].model.data(feedList.selectionForContextMenu[0], FeedsModel.FeedRole)}); } } diff --git a/src/qml/GenericEntryDelegate.qml b/src/qml/GenericEntryDelegate.qml index 4682be82..7c5099ca 100644 --- a/src/qml/GenericEntryDelegate.qml +++ b/src/qml/GenericEntryDelegate.qml @@ -14,6 +14,7 @@ import org.kde.kirigamiaddons.delegates as AddonDelegates import org.kde.kmediasession import org.kde.kasts +import org.kde.kasts.settings AddonDelegates.RoundedItemDelegate { id: listItem @@ -90,7 +91,7 @@ AddonDelegates.RoundedItemDelegate { pageStack.pop(); } - pageStack.push("qrc:/EntryPage.qml", { + pageStack.push("qrc:/qt/qml/org/kde/kasts/qml/EntryPage.qml", { entry: entry, }); } diff --git a/src/qml/GenericHeader.qml b/src/qml/GenericHeader.qml index ef77f087..e9e743a4 100644 --- a/src/qml/GenericHeader.qml +++ b/src/qml/GenericHeader.qml @@ -74,7 +74,7 @@ Item { anchors.fill: parent cursorShape: Qt.PointingHandCursor onClicked: { - fullScreenImageLoader.setSource("qrc:/FullScreenImage.qml", { + fullScreenImageLoader.setSource("qrc:/qt/qml/org/kde/kasts/qml/FullScreenImage.qml", { "image": root.image, "description": root.title, "loader": fullScreenImageLoader diff --git a/src/qml/GlobalSearchField.qml b/src/qml/GlobalSearchField.qml index 6a193de3..ca9ba408 100644 --- a/src/qml/GlobalSearchField.qml +++ b/src/qml/GlobalSearchField.qml @@ -43,7 +43,7 @@ Addons.SearchPopupField { function openEntry(entry) { pushPage("EpisodeListPage"); - pageStack.push("qrc:/EntryPage.qml", {"entry": entry}); + pageStack.push("qrc:/qt/qml/org/kde/kasts/qml/EntryPage.qml", {"entry": entry}); // Find the index of the entry on the EpisodeListPage and scroll to it var episodeModel = pageStack.get(0).episodeList.model diff --git a/src/qml/ImageWithFallback.qml b/src/qml/ImageWithFallback.qml index a133001e..cfb867fb 100644 --- a/src/qml/ImageWithFallback.qml +++ b/src/qml/ImageWithFallback.qml @@ -13,6 +13,7 @@ import QtQuick.Window import org.kde.kirigami as Kirigami import org.kde.kasts +import org.kde.kasts.settings Item { id: root diff --git a/src/qml/main.qml b/src/qml/Main.qml similarity index 93% rename from src/qml/main.qml rename to src/qml/Main.qml index 31893650..9f393be4 100644 --- a/src/qml/main.qml +++ b/src/qml/Main.qml @@ -14,6 +14,11 @@ import QtCore import org.kde.kirigami as Kirigami import org.kde.kasts +import org.kde.kasts.settings + +import "Desktop" +import "Mobile" + Kirigami.ApplicationWindow { id: kastsMainWindow @@ -49,22 +54,22 @@ Kirigami.ApplicationWindow { function getPage(page) { switch (page) { - case "QueuePage": return "qrc:/QueuePage.qml"; - case "EpisodeListPage": return "qrc:/EpisodeListPage.qml"; - case "DiscoverPage": return "qrc:/DiscoverPage.qml"; - case "FeedListPage": return "qrc:/FeedListPage.qml"; - case "DownloadListPage": return "qrc:/DownloadListPage.qml"; - case "SettingsPage": return "qrc:/Settings/SettingsPage.qml"; + case "QueuePage": return "qrc:/qt/qml/org/kde/kasts/qml/QueuePage.qml"; + case "EpisodeListPage": return "qrc:/qt/qml/org/kde/kasts/qml/EpisodeListPage.qml"; + case "DiscoverPage": return "qrc:/qt/qml/org/kde/kasts/qml/DiscoverPage.qml"; + case "FeedListPage": return "qrc:/qt/qml/org/kde/kasts/qml/FeedListPage.qml"; + case "DownloadListPage": return "qrc:/qt/qml/org/kde/kasts/qml/DownloadListPage.qml"; + case "SettingsPage": return "qrc:/qt/qml/org/kde/kasts/qml/Settings/SettingsPage.qml"; default: { currentPage = "FeedListPage"; - return "qrc:/FeedListPage.qml"; + return "qrc:/qt/qml/org/kde/kasts/qml/FeedListPage.qml"; } } } function pushPage(page) { if (page === "SettingsPage") { pageStack.layers.clear() - pageStack.pushDialogLayer("qrc:/SettingsPage.qml", {}, { + pageStack.pushDialogLayer("qrc:/qt/qml/org/kde/kasts/qml/Settings/SettingsPage.qml", {}, { title: i18n("Settings") }) } else { diff --git a/src/qml/Mobile/MinimizedPlayerControls.qml b/src/qml/Mobile/MinimizedPlayerControls.qml index 7d7790fb..8004aa6d 100644 --- a/src/qml/Mobile/MinimizedPlayerControls.qml +++ b/src/qml/Mobile/MinimizedPlayerControls.qml @@ -14,6 +14,8 @@ import org.kde.kmediasession import org.kde.kasts +import ".." + Item { property int miniplayerheight: Kirigami.Units.gridUnit * 3 property int progressbarheight: Kirigami.Units.gridUnit / 6 diff --git a/src/qml/Mobile/MobilePlayerControls.qml b/src/qml/Mobile/MobilePlayerControls.qml index ad2cf0a3..348fafa7 100644 --- a/src/qml/Mobile/MobilePlayerControls.qml +++ b/src/qml/Mobile/MobilePlayerControls.qml @@ -14,6 +14,9 @@ import org.kde.kirigami as Kirigami import org.kde.kmediasession import org.kde.kasts +import org.kde.kasts.settings + +import ".." Kirigami.Page { id: playerControls diff --git a/src/qml/PlaybackRateCustomizerDialog.qml b/src/qml/PlaybackRateCustomizerDialog.qml index c24f46bd..b6612bfc 100644 --- a/src/qml/PlaybackRateCustomizerDialog.qml +++ b/src/qml/PlaybackRateCustomizerDialog.qml @@ -10,6 +10,7 @@ import QtQuick.Layouts import org.kde.kirigami as Kirigami import org.kde.kasts +import org.kde.kasts.settings Kirigami.Dialog { id: customizeRatesDialog diff --git a/src/qml/PlaybackRateMenu.qml b/src/qml/PlaybackRateMenu.qml index a5c8f463..671eaea8 100644 --- a/src/qml/PlaybackRateMenu.qml +++ b/src/qml/PlaybackRateMenu.qml @@ -10,6 +10,7 @@ import QtQuick.Layouts import org.kde.kirigami as Kirigami import org.kde.kasts +import org.kde.kasts.settings Controls.Menu { id: playbackRateMenu diff --git a/src/qml/Settings/AboutPage.qml b/src/qml/Settings/AboutPage.qml index 8cd273b3..b3feb96d 100644 --- a/src/qml/Settings/AboutPage.qml +++ b/src/qml/Settings/AboutPage.qml @@ -8,6 +8,7 @@ import QtQuick import QtQuick.Controls as Controls import QtQuick.Layouts +import org.kde.coreaddons import org.kde.kirigami as Kirigami import org.kde.kirigamiaddons.formcard as FormCard @@ -15,5 +16,5 @@ import org.kde.kasts FormCard.AboutPage { title: i18n("About") - aboutData: About + aboutData: AboutData } diff --git a/src/qml/Settings/ErrorListPage.qml b/src/qml/Settings/ErrorListPage.qml index 0d5bdee9..fded6b4c 100644 --- a/src/qml/Settings/ErrorListPage.qml +++ b/src/qml/Settings/ErrorListPage.qml @@ -13,6 +13,8 @@ import org.kde.kirigamiaddons.formcard as FormCard import org.kde.kasts +import ".." + FormCard.FormCardPage { title: i18nc("@title", "Error Log") diff --git a/src/qml/Settings/GeneralSettingsPage.qml b/src/qml/Settings/GeneralSettingsPage.qml index 1a9c83db..e574aac7 100644 --- a/src/qml/Settings/GeneralSettingsPage.qml +++ b/src/qml/Settings/GeneralSettingsPage.qml @@ -14,6 +14,7 @@ import org.kde.kirigamiaddons.formcard as FormCard import org.kde.kmediasession import org.kde.kasts +import org.kde.kasts.settings FormCard.FormCardPage { id: root diff --git a/src/qml/Settings/NetworkSettingsPage.qml b/src/qml/Settings/NetworkSettingsPage.qml index f1dc75e6..91309428 100644 --- a/src/qml/Settings/NetworkSettingsPage.qml +++ b/src/qml/Settings/NetworkSettingsPage.qml @@ -13,6 +13,7 @@ import org.kde.kirigami as Kirigami import org.kde.kirigamiaddons.formcard as FormCard import org.kde.kasts +import org.kde.kasts.settings FormCard.FormCardPage { id: root diff --git a/src/qml/Settings/SettingsPage.qml b/src/qml/Settings/SettingsPage.qml index bde417aa..0ccf09d4 100644 --- a/src/qml/Settings/SettingsPage.qml +++ b/src/qml/Settings/SettingsPage.qml @@ -16,38 +16,38 @@ KirigamiSettings.CategorizedSettings { KirigamiSettings.SettingAction { text: i18n("General") actionName: "General" - icon.name: ":/logo.svg" - page: "qrc:/GeneralSettingsPage.qml" + icon.name: "kasts" + page: "qrc:/qt/qml/org/kde/kasts/qml/Settings/GeneralSettingsPage.qml" }, KirigamiSettings.SettingAction { text: i18n("Storage") actionName: "Storage" icon.name: "drive-harddisk-symbolic" - page: "qrc:/StorageSettingsPage.qml" + page: "qrc:/qt/qml/org/kde/kasts/qml/Settings/StorageSettingsPage.qml" }, KirigamiSettings.SettingAction { text: i18n("Network") actionName: "Network" icon.name: "network-connect" - page: "qrc:/NetworkSettingsPage.qml" + page: "qrc:/qt/qml/org/kde/kasts/qml/Settings/NetworkSettingsPage.qml" }, KirigamiSettings.SettingAction { text: i18n("Synchronization") actionName: "Synchronization" icon.name: "state-sync" - page: "qrc:/SynchronizationSettingsPage.qml" + page: "qrc:/qt/qml/org/kde/kasts/qml/Settings/SynchronizationSettingsPage.qml" }, KirigamiSettings.SettingAction { text: i18n("Error Log") actionName: "Error Log" icon.name: "error" - page: "qrc:/ErrorListPage.qml" + page: "qrc:/qt/qml/org/kde/kasts/qml/Settings/ErrorListPage.qml" }, KirigamiSettings.SettingAction { text: i18n("About") actionName: "About" icon.name: "documentinfo" - page: "qrc:/AboutPage.qml" + page: "qrc:/qt/qml/org/kde/kasts/qml/Settings/AboutPage.qml" } ] } diff --git a/src/qml/Settings/StorageSettingsPage.qml b/src/qml/Settings/StorageSettingsPage.qml index 774e340e..c4e53916 100644 --- a/src/qml/Settings/StorageSettingsPage.qml +++ b/src/qml/Settings/StorageSettingsPage.qml @@ -13,6 +13,7 @@ import org.kde.kirigami as Kirigami import org.kde.kirigamiaddons.formcard as FormCard import org.kde.kasts +import org.kde.kasts.settings FormCard.FormCardPage { id: root diff --git a/src/qml/Settings/SynchronizationSettingsPage.qml b/src/qml/Settings/SynchronizationSettingsPage.qml index 632098b5..14031ecb 100644 --- a/src/qml/Settings/SynchronizationSettingsPage.qml +++ b/src/qml/Settings/SynchronizationSettingsPage.qml @@ -14,6 +14,9 @@ import org.kde.kirigamiaddons.delegates as Delegates import org.kde.kirigamiaddons.formcard as FormCard import org.kde.kasts +import org.kde.kasts.settings + +import ".." Kirigami.ScrollablePage { id: root diff --git a/src/qml/SleepTimerDialog.qml b/src/qml/SleepTimerDialog.qml index b2e7ac26..9967f211 100644 --- a/src/qml/SleepTimerDialog.qml +++ b/src/qml/SleepTimerDialog.qml @@ -10,6 +10,7 @@ import QtQuick.Layouts import org.kde.kirigami as Kirigami import org.kde.kasts +import org.kde.kasts.settings Kirigami.Dialog { id: sleepTimerDialog diff --git a/src/qml/SyncPasswordOverlay.qml b/src/qml/SyncPasswordOverlay.qml index a2fc2056..8c50ff1f 100644 --- a/src/qml/SyncPasswordOverlay.qml +++ b/src/qml/SyncPasswordOverlay.qml @@ -11,6 +11,7 @@ import QtQuick.Layouts import org.kde.kirigami as Kirigami import org.kde.kasts +import org.kde.kasts.settings Kirigami.Dialog { id: syncPasswordOverlay diff --git a/src/resources-flatpak.qrc b/src/resources-flatpak.qrc deleted file mode 100755 index f74862dc..00000000 --- a/src/resources-flatpak.qrc +++ /dev/null @@ -1,7 +0,0 @@ - - - - - qml/Settings/StorageDirDialogFlatpak.qml - - diff --git a/src/resources-non-flatpak.qrc b/src/resources-non-flatpak.qrc deleted file mode 100755 index 6b8476ec..00000000 --- a/src/resources-non-flatpak.qrc +++ /dev/null @@ -1,7 +0,0 @@ - - - - - qml/Settings/StorageDirDialog.qml - - diff --git a/src/resources.qrc b/src/resources.qrc deleted file mode 100755 index fe598d1d..00000000 --- a/src/resources.qrc +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - qml/main.qml - qml/FeedListPage.qml - qml/EntryPage.qml - qml/Settings/AboutPage.qml - qml/FeedDetailsPage.qml - qml/AddFeedSheet.qml - qml/FeedListDelegate.qml - qml/Mobile/MinimizedPlayerControls.qml - qml/Mobile/MobilePlayerControls.qml - qml/VolumeSlider.qml - qml/Mobile/FooterBar.qml - qml/Mobile/BottomToolbar.qml - qml/QueuePage.qml - qml/EpisodeListPage.qml - qml/DownloadListPage.qml - qml/ErrorList.qml - qml/ErrorListOverlay.qml - qml/GenericHeader.qml - qml/GenericEntryDelegate.qml - qml/GenericEntryListView.qml - qml/DiscoverPage.qml - qml/ImageWithFallback.qml - qml/UpdateNotification.qml - qml/Desktop/HeaderBar.qml - qml/Desktop/DesktopPlayerControls.qml - qml/PlaybackRateMenu.qml - qml/PlaybackRateCustomizerDialog.qml - qml/ErrorNotification.qml - qml/ConnectionCheckAction.qml - qml/ChapterListDelegate.qml - qml/SyncPasswordOverlay.qml - qml/Settings/SettingsPage.qml - qml/Settings/GeneralSettingsPage.qml - qml/Settings/NetworkSettingsPage.qml - qml/Settings/StorageSettingsPage.qml - qml/Settings/SynchronizationSettingsPage.qml - qml/Settings/ErrorListPage.qml - qml/SleepTimerDialog.qml - qml/FullScreenImage.qml - qml/GlobalSearchField.qml - qml/SearchBar.qml - qml/FilterInlineMessage.qml - qml/KastsGlobalDrawer.qml - ../kasts.svg - ../icons/kasts-tray-light.svg - ../icons/kasts-tray-dark.svg - ../icons/media-playback-cloud.svg - - diff --git a/src/sync/sync.cpp b/src/sync/sync.cpp index 9c2026e8..3755f62a 100644 --- a/src/sync/sync.cpp +++ b/src/sync/sync.cpp @@ -95,7 +95,7 @@ void Sync::retrieveCredentialsFromConfig() // Now that we have all credentials we can do the initial sync if // it's enabled in the config. If it's not enabled, then we handle - // the automatic refresh through main.qml + // the automatic refresh through Main.qml if (NetworkConnectionManager::instance().feedUpdatesAllowed()) { if (SettingsManager::self()->refreshOnStartup() && SettingsManager::self()->syncWhenUpdatingFeeds()) { doRegularSync(true); diff --git a/src/sync/sync.h b/src/sync/sync.h index 93debedb..ed0e3e94 100644 --- a/src/sync/sync.h +++ b/src/sync/sync.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include @@ -25,6 +26,8 @@ class GPodder; class Sync : public QObject { Q_OBJECT + QML_ELEMENT + QML_SINGLETON Q_PROPERTY(bool syncEnabled READ syncEnabled WRITE setSyncEnabled NOTIFY syncEnabledChanged) Q_PROPERTY(QString username READ username NOTIFY credentialsChanged) @@ -51,6 +54,11 @@ public: static Sync _instance; return _instance; } + static Sync *create(QQmlEngine *engine, QJSEngine *) + { + engine->setObjectOwnership(&instance(), QQmlEngine::CppOwnership); + return &instance(); + } bool syncEnabled() const; QString username() const; diff --git a/src/sync/syncutils.h b/src/sync/syncutils.h index 4c5f550b..b2ecd07a 100644 --- a/src/sync/syncutils.h +++ b/src/sync/syncutils.h @@ -7,11 +7,13 @@ #pragma once #include +#include #include namespace SyncUtils { Q_NAMESPACE +QML_ELEMENT // constants const QString subscriptionTimestampLabel = QStringLiteral("syncsubscriptions"); diff --git a/src/utils/colorschemer.h b/src/utils/colorschemer.h index 596fbcfe..c5307b1f 100644 --- a/src/utils/colorschemer.h +++ b/src/utils/colorschemer.h @@ -7,6 +7,7 @@ #pragma once #include +#include #include class QAbstractItemModel; diff --git a/src/utils/networkconnectionmanager.h b/src/utils/networkconnectionmanager.h index 13a039a1..6aff3ca6 100644 --- a/src/utils/networkconnectionmanager.h +++ b/src/utils/networkconnectionmanager.h @@ -7,10 +7,13 @@ #pragma once #include +#include class NetworkConnectionManager : public QObject { Q_OBJECT + QML_ELEMENT + QML_SINGLETON Q_PROPERTY(bool networkReachable READ networkReachable NOTIFY networkReachableChanged) Q_PROPERTY(bool feedUpdatesAllowed READ feedUpdatesAllowed NOTIFY feedUpdatesAllowedChanged) @@ -24,6 +27,11 @@ public: static NetworkConnectionManager _instance; return _instance; } + static NetworkConnectionManager *create(QQmlEngine *engine, QJSEngine *) + { + engine->setObjectOwnership(&instance(), QQmlEngine::CppOwnership); + return &instance(); + } [[nodiscard]] bool networkReachable() const; [[nodiscard]] bool feedUpdatesAllowed() const; diff --git a/src/utils/storagemanager.h b/src/utils/storagemanager.h index 0dd3f02d..c91a6a30 100644 --- a/src/utils/storagemanager.h +++ b/src/utils/storagemanager.h @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -18,6 +19,8 @@ class StorageManager : public QObject { Q_OBJECT + QML_ELEMENT + QML_SINGLETON Q_PROPERTY(int storageMoveProgress MEMBER m_storageMoveProgress NOTIFY storageMoveProgressChanged) Q_PROPERTY(int storageMoveTotal MEMBER m_storageMoveTotal NOTIFY storageMoveTotalChanged) @@ -33,6 +36,11 @@ public: static StorageManager _instance; return _instance; } + static StorageManager *create(QQmlEngine *engine, QJSEngine *) + { + engine->setObjectOwnership(&instance(), QQmlEngine::CppOwnership); + return &instance(); + } static const int maxFilenameLength = 200; diff --git a/src/utils/systrayicon.cpp b/src/utils/systrayicon.cpp index da28ebe2..ffa49fe7 100644 --- a/src/utils/systrayicon.cpp +++ b/src/utils/systrayicon.cpp @@ -148,13 +148,13 @@ void SystrayIcon::setIconColor(SystrayIcon::IconColor iconColor) // do not specify svg-extension; icon will not be visible due to [QTBUG-53550] switch (iconColor) { case SystrayIcon::IconColor::Colorful: - setIcon(QIcon(QStringLiteral(":/logo"))); + setIcon(QIcon(QStringLiteral(":/icons/kasts"))); break; case SystrayIcon::IconColor::Light: - setIcon(QIcon(QStringLiteral(":/kasts-tray-light"))); + setIcon(QIcon(QStringLiteral(":/icons/kasts-tray-light"))); break; case SystrayIcon::IconColor::Dark: - setIcon(QIcon(QStringLiteral(":/kasts-tray-dark"))); + setIcon(QIcon(QStringLiteral(":/icons/kasts-tray-dark"))); break; } #endif diff --git a/src/utils/systrayicon.h b/src/utils/systrayicon.h index a2006ff2..92ec0c16 100644 --- a/src/utils/systrayicon.h +++ b/src/utils/systrayicon.h @@ -7,6 +7,7 @@ #pragma once #include +#include #ifndef Q_OS_ANDROID #include #endif @@ -19,6 +20,8 @@ class SystrayIcon #endif { Q_OBJECT + QML_ELEMENT + QML_SINGLETON public: enum IconColor { @@ -35,6 +38,11 @@ public: static SystrayIcon _instance; return _instance; } + static SystrayIcon *create(QQmlEngine *engine, QJSEngine *) + { + engine->setObjectOwnership(&instance(), QQmlEngine::CppOwnership); + return &instance(); + } [[nodiscard]] bool available() const;