File indexing completed on 2024-05-12 16:21:30
0001 /** 0002 * SPDX-FileCopyrightText: 2020 Tobias Fella <tobias.fella@kde.org> 0003 * SPDX-FileCopyrightText: 2021 Bart De Vries <bart@mogwai.be> 0004 * 0005 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0006 */ 0007 0008 #include <QCommandLineOption> 0009 #include <QCommandLineParser> 0010 #include <QIcon> 0011 #include <QLoggingCategory> 0012 #include <QQmlApplicationEngine> 0013 #include <QQmlContext> 0014 #include <QQuickStyle> 0015 #include <QQuickView> 0016 #include <QString> 0017 #include <QStringList> 0018 #include <QSysInfo> 0019 #include <QVariant> 0020 0021 #ifdef Q_OS_ANDROID 0022 #include <QGuiApplication> 0023 #else 0024 #include <QApplication> 0025 #endif 0026 0027 #include <KAboutData> 0028 #include <KLocalizedContext> 0029 #include <KLocalizedString> 0030 0031 #ifdef Q_OS_ANDROID 0032 #include "androidlogging.h" 0033 #endif 0034 #include "audiomanager.h" 0035 #include "author.h" 0036 #include "database.h" 0037 #include "datamanager.h" 0038 #include "entry.h" 0039 #include "feed.h" 0040 #include "fetcher.h" 0041 #include "kasts-version.h" 0042 #include "models/abstractepisodemodel.h" 0043 #include "models/abstractepisodeproxymodel.h" 0044 #include "models/chaptermodel.h" 0045 #include "models/downloadmodel.h" 0046 #include "models/entriesproxymodel.h" 0047 #include "models/episodeproxymodel.h" 0048 #include "models/errorlogmodel.h" 0049 #include "models/feedsproxymodel.h" 0050 #include "models/podcastsearchmodel.h" 0051 #include "models/queuemodel.h" 0052 #include "networkconnectionmanager.h" 0053 #include "settingsmanager.h" 0054 #include "storagemanager.h" 0055 #include "sync/sync.h" 0056 #include "sync/syncutils.h" 0057 #include "systrayicon.h" 0058 0059 #ifdef Q_OS_WINDOWS 0060 #include <windows.h> 0061 #endif 0062 0063 #ifdef Q_OS_ANDROID 0064 Q_DECL_EXPORT 0065 #endif 0066 0067 int main(int argc, char *argv[]) 0068 { 0069 if (QSysInfo::currentCpuArchitecture().contains(QStringLiteral("arm")) && qEnvironmentVariableIsEmpty("QT_ENABLE_GLYPH_CACHE_WORKAROUND")) { 0070 qputenv("QT_ENABLE_GLYPH_CACHE_WORKAROUND", "1"); 0071 } 0072 0073 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0074 QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); 0075 QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 0076 #endif 0077 0078 #ifdef Q_OS_ANDROID 0079 QGuiApplication app(argc, argv); 0080 qInstallMessageHandler(myMessageHandler); 0081 QLoggingCategory::setFilterRules(QStringLiteral("org.kde.*=true")); 0082 QQuickStyle::setStyle(QStringLiteral("org.kde.breeze")); 0083 #else 0084 QApplication app(argc, argv); 0085 if (qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE")) { 0086 QQuickStyle::setStyle(QStringLiteral("org.kde.desktop")); 0087 } 0088 #endif 0089 0090 #ifdef Q_OS_WINDOWS 0091 if (AttachConsole(ATTACH_PARENT_PROCESS)) { 0092 freopen("CONOUT$", "w", stdout); 0093 freopen("CONOUT$", "w", stderr); 0094 } 0095 0096 QApplication::setStyle(QStringLiteral("breeze")); 0097 auto font = app.font(); 0098 font.setPointSize(10); 0099 app.setFont(font); 0100 #endif 0101 0102 QIcon::setFallbackSearchPaths(QIcon::fallbackSearchPaths() << QStringLiteral(":custom-icons")); 0103 0104 QCoreApplication::setOrganizationName(QStringLiteral("KDE")); 0105 QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org")); 0106 QCoreApplication::setApplicationName(QStringLiteral("Kasts")); 0107 0108 QQmlApplicationEngine engine; 0109 engine.rootContext()->setContextObject(new KLocalizedContext(&engine)); 0110 KLocalizedString::setApplicationDomain("kasts"); 0111 0112 QCommandLineParser parser; 0113 parser.setApplicationDescription(i18n("Podcast Application")); 0114 QCommandLineOption addFeedOption(QStringList() << QStringLiteral("a") << QStringLiteral("add"), 0115 i18n("Adds a new podcast to subscriptions."), 0116 i18n("Podcast URL"), 0117 QStringLiteral("none")); 0118 parser.addOption(addFeedOption); 0119 0120 KAboutData about(QStringLiteral("kasts"), 0121 i18n("Kasts"), 0122 QStringLiteral(KASTS_VERSION_STRING), 0123 i18n("Podcast Player"), 0124 KAboutLicense::GPL, 0125 i18n("© 2020–2023 KDE Community")); 0126 about.addAuthor(i18n("Tobias Fella"), QString(), QStringLiteral("tobias.fella@kde.org"), QStringLiteral("https://tobiasfella.de")); 0127 about.addAuthor(i18n("Bart De Vries"), QString(), QStringLiteral("bart@mogwai.be")); 0128 about.setProgramLogo(QVariant(QIcon(QStringLiteral(":/logo.svg")))); 0129 KAboutData::setApplicationData(about); 0130 0131 about.setupCommandLine(&parser); 0132 parser.process(app); 0133 QString feedURL = parser.value(addFeedOption); 0134 if (feedURL != QStringLiteral("none")) { 0135 Database::instance(); 0136 DataManager::instance().addFeed(feedURL); 0137 } 0138 about.processCommandLine(&parser); 0139 0140 qmlRegisterType<FeedsProxyModel>("org.kde.kasts", 1, 0, "FeedsProxyModel"); 0141 qmlRegisterType<QueueModel>("org.kde.kasts", 1, 0, "QueueModel"); 0142 qmlRegisterType<EpisodeProxyModel>("org.kde.kasts", 1, 0, "EpisodeProxyModel"); 0143 qmlRegisterType<PodcastSearchModel>("org.kde.kasts", 1, 0, "PodcastSearchModel"); 0144 qmlRegisterType<ChapterModel>("org.kde.kasts", 1, 0, "ChapterModel"); 0145 0146 qmlRegisterUncreatableType<AbstractEpisodeProxyModel>("org.kde.kasts", 1, 0, "AbstractEpisodeProxyModel", QStringLiteral("Only for enums")); 0147 qmlRegisterUncreatableType<EntriesProxyModel>("org.kde.kasts", 1, 0, "EntriesProxyModel", QStringLiteral("Get from Feed")); 0148 qmlRegisterUncreatableType<Enclosure>("org.kde.kasts", 1, 0, "Enclosure", QStringLiteral("Only for enums")); 0149 qmlRegisterUncreatableType<AbstractEpisodeModel>("org.kde.kasts", 1, 0, "AbstractEpisodeModel", QStringLiteral("Only for enums")); 0150 qmlRegisterUncreatableType<FeedsModel>("org.kde.kasts", 1, 0, "FeedsModel", QStringLiteral("Only for enums")); 0151 0152 qmlRegisterSingletonType("org.kde.kasts", 1, 0, "About", [](QQmlEngine *engine, QJSEngine *) -> QJSValue { 0153 return engine->toScriptValue(KAboutData::applicationData()); 0154 }); 0155 qmlRegisterSingletonInstance("org.kde.kasts", 1, 0, "Database", &Database::instance()); 0156 qmlRegisterSingletonInstance("org.kde.kasts", 1, 0, "NetworkConnectionManager", &NetworkConnectionManager::instance()); 0157 qmlRegisterSingletonInstance("org.kde.kasts", 1, 0, "Fetcher", &Fetcher::instance()); 0158 qmlRegisterSingletonInstance("org.kde.kasts", 1, 0, "DataManager", &DataManager::instance()); 0159 qmlRegisterSingletonInstance("org.kde.kasts", 1, 0, "SettingsManager", SettingsManager::self()); 0160 qmlRegisterSingletonInstance("org.kde.kasts", 1, 0, "DownloadModel", &DownloadModel::instance()); 0161 qmlRegisterSingletonInstance("org.kde.kasts", 1, 0, "ErrorLogModel", &ErrorLogModel::instance()); 0162 qmlRegisterSingletonInstance("org.kde.kasts", 1, 0, "AudioManager", &AudioManager::instance()); 0163 qmlRegisterSingletonInstance("org.kde.kasts", 1, 0, "StorageManager", &StorageManager::instance()); 0164 qmlRegisterSingletonInstance("org.kde.kasts", 1, 0, "Sync", &Sync::instance()); 0165 qmlRegisterSingletonInstance("org.kde.kasts", 1, 0, "SystrayIcon", &SystrayIcon::instance()); 0166 0167 qmlRegisterUncreatableMetaObject(SyncUtils::staticMetaObject, "org.kde.kasts", 1, 0, "SyncUtils", QStringLiteral("Error: only enums and structs")); 0168 0169 qRegisterMetaType<Entry *>("const Entry*"); // "hack" to make qml understand Entry* 0170 qRegisterMetaType<Feed *>("const Feed*"); // "hack" to make qml understand Feed* 0171 qRegisterMetaType<QVector<SyncUtils::Device>>("QVector<SyncUtils::Device>"); // "hack" to make qml understand QVector of SyncUtils::Device 0172 0173 // Make sure that settings are saved before the application exits 0174 QObject::connect(&app, &QCoreApplication::aboutToQuit, SettingsManager::self(), &SettingsManager::save); 0175 0176 engine.load(QUrl(QStringLiteral("qrc:///main.qml"))); 0177 0178 if (engine.rootObjects().isEmpty()) { 0179 return -1; 0180 } 0181 0182 return app.exec(); 0183 }