Port to declarative type registration

This commit is contained in:
Tobias Fella 2024-01-02 13:27:27 +00:00 committed by Bart De Vries
parent ae3cdc207a
commit ba9c302352
66 changed files with 307 additions and 235 deletions

View File

@ -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)

View File

@ -11,6 +11,7 @@
#include <memory>
#include <QObject>
#include <QQmlEngine>
#include <QString>
#include <QUrl>
@ -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<KMediaSession::MediaBackends> 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;

View File

@ -8,12 +8,15 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
#include <QSqlQuery>
#include <QString>
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));

View File

@ -8,6 +8,7 @@
#include <QHash>
#include <QObject>
#include <QQmlEngine>
#include <QString>
#include <QStringList>
@ -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;

View File

@ -9,6 +9,7 @@
#include <QDebug>
#include <QObject>
#include <QQmlEngine>
#include <QString>
#include <KFormat>
@ -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)

View File

@ -11,6 +11,7 @@
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QObject>
#include <QQmlEngine>
#include <QUrl>
#include <Syndication/Syndication>
@ -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);

View File

@ -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})

View File

@ -2,7 +2,7 @@
# SPDX-FileCopyrightText: 2022-2023 Bart De Vries <bart@mogwai.be>
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
)

View File

@ -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;

View File

@ -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

View File

@ -1,8 +0,0 @@
<!-- SPDX-FileCopyrightText: 2022-2023 Bart De Vries <bart@mogwai.be> -->
<!-- SPDX-License-Identifier: CC0-1.0 -->
<RCC>
<qresource prefix="/">
<file alias="main.qml">qml/main.qml</file>
</qresource>
</RCC>

View File

@ -12,6 +12,7 @@
#include <QList>
#include <QObject>
#include <QQmlEngine>
#include <QString>
#include <QUrl>
@ -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<KMediaSession::MediaBackends> availableBackends READ availableBackends CONSTANT)

View File

@ -9,12 +9,14 @@
#include "kmediasession_export.h"
#include <QObject>
#include <QQmlEngine>
#include <QString>
#include <QUrl>
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)

View File

@ -1,19 +0,0 @@
# SPDX-License-Identifier: BSD-2-Clause
# SPDX-FileCopyrightText: 2022-2023 Bart De Vries <bart@mogwai.be>
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)

View File

@ -1,30 +0,0 @@
/**
* SPDX-FileCopyrightText: 2022-2023 Bart De Vries <bart@mogwai.be>
*
* SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include <QQmlContext>
#include <QQmlEngine>
#include <QQmlExtensionPlugin>
#include <kmediasession.h>
#include <metadata.h>
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<KMediaSession>("org.kde.kmediasession", 1, 0, "KMediaSession");
qmlRegisterType<MetaData>("org.kde.kmediasession", 1, 0, "MetaData");
qRegisterMetaType<KMediaSession::MediaBackends>("KMediaSession::MediaBackends");
qRegisterMetaType<QList<KMediaSession::MediaBackends>>("QList<KMediaSession::MediaBackends>");
}
#include "kmediasession-qmlplugin.moc"

View File

@ -1,3 +0,0 @@
module org.kde.kmediasession
plugin kmediasession-qmlplugin
classname KMediaSessionQmlPlugin

View File

@ -1,2 +0,0 @@
SPDX-License-Identifier: BSD-2-Clause
SPDX-FileCopyrightText: 2022-2023 Bart De Vries <bart@mogwai.be>

View File

@ -120,62 +120,30 @@ int main(int argc, char *argv[])
i18n("© 20202023 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<FeedsProxyModel>("org.kde.kasts", 1, 0, "FeedsProxyModel");
qmlRegisterType<QueueModel>("org.kde.kasts", 1, 0, "QueueModel");
qmlRegisterType<EpisodeProxyModel>("org.kde.kasts", 1, 0, "EpisodeProxyModel");
qmlRegisterType<PodcastSearchModel>("org.kde.kasts", 1, 0, "PodcastSearchModel");
qmlRegisterType<ChapterModel>("org.kde.kasts", 1, 0, "ChapterModel");
qmlRegisterSingletonInstance("org.kde.kasts.settings", 1, 0, "SettingsManager", SettingsManager::self());
qmlRegisterUncreatableType<AbstractEpisodeProxyModel>("org.kde.kasts", 1, 0, "AbstractEpisodeProxyModel", QStringLiteral("Only for enums"));
qmlRegisterUncreatableType<EntriesProxyModel>("org.kde.kasts", 1, 0, "EntriesProxyModel", QStringLiteral("Get from Feed"));
qmlRegisterUncreatableType<Enclosure>("org.kde.kasts", 1, 0, "Enclosure", QStringLiteral("Only for enums"));
qmlRegisterUncreatableType<AbstractEpisodeModel>("org.kde.kasts", 1, 0, "AbstractEpisodeModel", QStringLiteral("Only for enums"));
qmlRegisterUncreatableType<FeedsModel>("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<ColorSchemer>("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<Entry *>("const Entry*"); // "hack" to make qml understand Entry*
qRegisterMetaType<Feed *>("const Feed*"); // "hack" to make qml understand Feed*
qRegisterMetaType<QVector<SyncUtils::Device>>("QVector<SyncUtils::Device>"); // "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;

View File

@ -10,10 +10,13 @@
#include <QByteArray>
#include <QHash>
#include <QObject>
#include <QQmlEngine>
class AbstractEpisodeModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("")
public:
enum Roles {

View File

@ -7,6 +7,7 @@
#pragma once
#include <QItemSelection>
#include <QQmlEngine>
#include <QSortFilterProxyModel>
#include <QString>
@ -17,6 +18,8 @@ class Entry;
class AbstractEpisodeProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("")
public:
enum FilterType {

View File

@ -8,6 +8,7 @@
#include <KFormat>
#include <QAbstractListModel>
#include <QQmlEngine>
#include <mpegfile.h>
@ -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)

View File

@ -10,6 +10,7 @@
#include <QHash>
#include <QItemSelection>
#include <QObject>
#include <QQmlEngine>
#include <QVariant>
#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<int, QByteArray> roleNames() const override;

View File

@ -8,6 +8,7 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
#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)

View File

@ -7,6 +7,7 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
#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);

View File

@ -10,6 +10,7 @@
#include <QDateTime>
#include <QHash>
#include <QObject>
#include <QQmlEngine>
#include <QVariant>
#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<int, QByteArray> roleNames() const override;

View File

@ -9,6 +9,7 @@
#include <QAbstractListModel>
#include <QHash>
#include <QQmlEngine>
#include <QSqlTableModel>
#include <QUrl>
@ -17,6 +18,8 @@
class FeedsModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("")
public:
enum Roles {

View File

@ -8,6 +8,7 @@
#include <QItemSelection>
#include <QModelIndex>
#include <QQmlEngine>
#include <QSortFilterProxyModel>
#include <QString>
@ -18,6 +19,7 @@ class Entry;
class FeedsProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
QML_ELEMENT
public:
enum SortType {

View File

@ -10,6 +10,7 @@
#include <QHash>
#include <QJsonObject>
#include <QObject>
#include <QQmlEngine>
#include <QVariant>
#include "feed.h"
@ -18,6 +19,8 @@
class PodcastSearchModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
public:
enum Roles {
Id = Qt::UserRole,

View File

@ -9,6 +9,7 @@
#include <QItemSelection>
#include <QModelIndex>
#include <QObject>
#include <QQmlEngine>
#include <QString>
#include <QVariant>
@ -18,6 +19,7 @@
class QueueModel : public AbstractEpisodeModel
{
Q_OBJECT
QML_ELEMENT
public:
Q_PROPERTY(int timeLeft READ timeLeft NOTIFY timeLeftChanged)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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();
}

View File

@ -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,

View File

@ -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

View File

@ -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")

View File

@ -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)});
}
}

View File

@ -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,
});
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -13,6 +13,8 @@ import org.kde.kirigamiaddons.formcard as FormCard
import org.kde.kasts
import ".."
FormCard.FormCardPage {
title: i18nc("@title", "Error Log")

View File

@ -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

View File

@ -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

View File

@ -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"
}
]
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,7 +0,0 @@
<!-- SPDX-FileCopyrightText: 2023 Bart De Vries <bart@mogwai.be> -->
<!-- SPDX-License-Identifier: CC0-1.0 -->
<RCC>
<qresource prefix="/">
<file alias="StorageDirDialog.qml">qml/Settings/StorageDirDialogFlatpak.qml</file>
</qresource>
</RCC>

View File

@ -1,7 +0,0 @@
<!-- SPDX-FileCopyrightText: 2023 Bart De Vries <bart@mogwai.be> -->
<!-- SPDX-License-Identifier: CC0-1.0 -->
<RCC>
<qresource prefix="/">
<file alias="StorageDirDialog.qml">qml/Settings/StorageDirDialog.qml</file>
</qresource>
</RCC>

View File

@ -1,54 +0,0 @@
<!-- SPDX-FileCopyrightText: 2020 Tobias Fella <tobias.fella@kde.org> -->
<!-- SPDX-FileCopyrightText: 2021-2023 Bart De Vries <bart@mogwai.be> -->
<!-- SPDX-License-Identifier: CC0-1.0 -->
<RCC>
<qresource prefix="/">
<file alias="main.qml">qml/main.qml</file>
<file alias="FeedListPage.qml">qml/FeedListPage.qml</file>
<file alias="EntryPage.qml">qml/EntryPage.qml</file>
<file alias="AboutPage.qml">qml/Settings/AboutPage.qml</file>
<file alias="FeedDetailsPage.qml">qml/FeedDetailsPage.qml</file>
<file alias="AddFeedSheet.qml">qml/AddFeedSheet.qml</file>
<file alias="FeedListDelegate.qml">qml/FeedListDelegate.qml</file>
<file alias="MinimizedPlayerControls.qml">qml/Mobile/MinimizedPlayerControls.qml</file>
<file alias="MobilePlayerControls.qml">qml/Mobile/MobilePlayerControls.qml</file>
<file alias="VolumeSlider.qml">qml/VolumeSlider.qml</file>
<file alias="FooterBar.qml">qml/Mobile/FooterBar.qml</file>
<file alias="BottomToolbar.qml">qml/Mobile/BottomToolbar.qml</file>
<file alias="QueuePage.qml">qml/QueuePage.qml</file>
<file alias="EpisodeListPage.qml">qml/EpisodeListPage.qml</file>
<file alias="DownloadListPage.qml">qml/DownloadListPage.qml</file>
<file alias="ErrorList.qml">qml/ErrorList.qml</file>
<file alias="ErrorListOverlay.qml">qml/ErrorListOverlay.qml</file>
<file alias="GenericHeader.qml">qml/GenericHeader.qml</file>
<file alias="GenericEntryDelegate.qml">qml/GenericEntryDelegate.qml</file>
<file alias="GenericEntryListView.qml">qml/GenericEntryListView.qml</file>
<file alias="DiscoverPage.qml">qml/DiscoverPage.qml</file>
<file alias="ImageWithFallback.qml">qml/ImageWithFallback.qml</file>
<file alias="UpdateNotification.qml">qml/UpdateNotification.qml</file>
<file alias="HeaderBar.qml">qml/Desktop/HeaderBar.qml</file>
<file alias="DesktopPlayerControls.qml">qml/Desktop/DesktopPlayerControls.qml</file>
<file alias="PlaybackRateMenu.qml">qml/PlaybackRateMenu.qml</file>
<file alias="PlaybackRateCustomizerDialog.qml">qml/PlaybackRateCustomizerDialog.qml</file>
<file alias="ErrorNotification.qml">qml/ErrorNotification.qml</file>
<file alias="ConnectionCheckAction.qml">qml/ConnectionCheckAction.qml</file>
<file alias="ChapterListDelegate.qml">qml/ChapterListDelegate.qml</file>
<file alias="SyncPasswordOverlay.qml">qml/SyncPasswordOverlay.qml</file>
<file alias="SettingsPage.qml">qml/Settings/SettingsPage.qml</file>
<file alias="GeneralSettingsPage.qml">qml/Settings/GeneralSettingsPage.qml</file>
<file alias="NetworkSettingsPage.qml">qml/Settings/NetworkSettingsPage.qml</file>
<file alias="StorageSettingsPage.qml">qml/Settings/StorageSettingsPage.qml</file>
<file alias="SynchronizationSettingsPage.qml">qml/Settings/SynchronizationSettingsPage.qml</file>
<file alias="ErrorListPage.qml">qml/Settings/ErrorListPage.qml</file>
<file alias="SleepTimerDialog.qml">qml/SleepTimerDialog.qml</file>
<file alias="FullScreenImage.qml">qml/FullScreenImage.qml</file>
<file alias="GlobalSearchField.qml">qml/GlobalSearchField.qml</file>
<file alias="SearchBar.qml">qml/SearchBar.qml</file>
<file alias="FilterInlineMessage.qml">qml/FilterInlineMessage.qml</file>
<file alias="KastsGlobalDrawer.qml">qml/KastsGlobalDrawer.qml</file>
<file alias="logo.svg">../kasts.svg</file>
<file alias="kasts-tray-light.svg">../icons/kasts-tray-light.svg</file>
<file alias="kasts-tray-dark.svg">../icons/kasts-tray-dark.svg</file>
<file alias="custom-icons/media-playback-cloud.svg">../icons/media-playback-cloud.svg</file>
</qresource>
</RCC>

View File

@ -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);

View File

@ -8,6 +8,7 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
#include <KFormat>
@ -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;

View File

@ -7,11 +7,13 @@
#pragma once
#include <QMetaType>
#include <QQmlEngine>
#include <QString>
namespace SyncUtils
{
Q_NAMESPACE
QML_ELEMENT
// constants
const QString subscriptionTimestampLabel = QStringLiteral("syncsubscriptions");

View File

@ -7,6 +7,7 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
#include <QtQml>
class QAbstractItemModel;

View File

@ -7,10 +7,13 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
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;

View File

@ -8,6 +8,7 @@
#include <QFile>
#include <QObject>
#include <QQmlEngine>
#include <QString>
#include <QUrl>
@ -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;

View File

@ -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

View File

@ -7,6 +7,7 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
#ifndef Q_OS_ANDROID
#include <QSystemTrayIcon>
#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;