File indexing completed on 2025-02-02 05:02:31

0001 /*
0002     SPDX-FileCopyrightText: 2018 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "config-itinerary.h"
0008 #include "itinerary_version.h"
0009 #include "logging.h"
0010 
0011 #include "applicationcontroller.h"
0012 #include "calendarimportmodel.h"
0013 #include "countrysubdivisionmodel.h"
0014 #include "clipboard.h"
0015 #include "developmentmodecontroller.h"
0016 #include "documentmanager.h"
0017 #include "documentsmodel.h"
0018 #include "factory.h"
0019 #include "favoritelocationmodel.h"
0020 #include "genericpkpass.h"
0021 #include "healthcertificatemanager.h"
0022 #include "journeysectionmodel.h"
0023 #include "kdeconnect.h"
0024 #include "livedatamanager.h"
0025 #include "localizer.h"
0026 #include "locationinformation.h"
0027 #include "mapdownloadmanager.h"
0028 #include "matrixcontroller.h"
0029 #include "navigationcontroller.h"
0030 #include "notificationconfigcontroller.h"
0031 #include "onlineticketimporter.h"
0032 #include "passmanager.h"
0033 #include "pkpassmanager.h"
0034 #include "permissionmanager.h"
0035 #include "pkpassimageprovider.h"
0036 #include "publictransport.h"
0037 #include "reservationmanager.h"
0038 #include "settings.h"
0039 #include "statisticsmodel.h"
0040 #include "statisticstimerangemodel.h"
0041 #include "tickettokenmodel.h"
0042 #include "timelinedelegatecontroller.h"
0043 #include "timelinemodel.h"
0044 #include "timelinesectiondelegatecontroller.h"
0045 #include "transferdelegatecontroller.h"
0046 #include "transfermanager.h"
0047 #include "tripgroupinfoprovider.h"
0048 #include "tripgroupmanager.h"
0049 #include "tripgroupproxymodel.h"
0050 #include "unitconversion.h"
0051 #include "util.h"
0052 #include "weatherforecastmodel.h"
0053 
0054 #if HAVE_MATRIX
0055 #include "matrix/matrixroomsmodel.h"
0056 #include "matrix/matrixbeacon.h"
0057 #endif
0058 
0059 #include "weatherforecastmanager.h"
0060 
0061 #include "calendarlistmodel.h"
0062 #include "calendarpluginloader.h"
0063 
0064 #include <KItinerary/CountryDb>
0065 #include <KItinerary/JsonLdDocument>
0066 #include <KItinerary/PriceUtil>
0067 #include <KItinerary/Ticket>
0068 
0069 #include <KPkPass/Field>
0070 #include <KPkPass/Barcode>
0071 #include <KPkPass/BoardingPass>
0072 
0073 #ifndef Q_OS_ANDROID
0074 #include <KDBusService>
0075 #include <KWindowSystem>
0076 #endif
0077 
0078 #include <KLocalizedContext>
0079 #include <KLocalizedString>
0080 
0081 #include <KAboutData>
0082 #if HAVE_KCRASH
0083 #include <KCrash>
0084 #endif
0085 #include <KContacts/AddressFormat>
0086 
0087 #include <QQuickStyle>
0088 #include <QQmlApplicationEngine>
0089 #include <QQmlContext>
0090 
0091 #ifdef Q_OS_ANDROID
0092 #include "kandroidextras/activity.h"
0093 #include "kandroidextras/intent.h"
0094 #else
0095 #include <QApplication>
0096 #endif
0097 
0098 #include <QCommandLineParser>
0099 #include <QDebug>
0100 #include <QDir>
0101 #include <QGuiApplication>
0102 #include <QIcon>
0103 #include <QNetworkAccessManager>
0104 #include <QStandardPaths>
0105 #include <QWindow>
0106 
0107 #if !HAVE_MATRIX
0108 class MatrixBeaconStub : public QObject
0109 {
0110     Q_OBJECT
0111     Q_PROPERTY(QVariant connection MEMBER m_connection)
0112     QVariant m_connection;
0113 };
0114 #endif
0115 
0116 void registerKContactsTypes()
0117 {
0118     // ### this should move into a real QML plugin for KContacts
0119     qmlRegisterUncreatableMetaObject(KContacts::staticMetaObject, "org.kde.contacts", 1, 0, "KContacts", {});
0120     qmlRegisterSingletonType("org.kde.contacts", 1, 0, "AddressFormatRepository", [](QQmlEngine *, QJSEngine *jsEngine) -> QJSValue {
0121         return jsEngine->toScriptValue(KContacts::AddressFormatRepository());
0122     });
0123     qRegisterMetaType<KContacts::AddressFormat>();
0124     qRegisterMetaType<KContacts::AddressFormatElement>();
0125     qRegisterMetaType<KContacts::AddressFormatRepository>();
0126     qRegisterMetaType<KContacts::AddressFormatPreference>();
0127     qRegisterMetaType<KContacts::AddressFormatScriptPreference>();
0128 }
0129 
0130 void registerKCalendarCoreTypes()
0131 {
0132     // ### this should move into a QML plugin of KCalendarCore
0133     qmlRegisterUncreatableMetaObject(KCalendarCore::staticMetaObject, "internal.org.kde.kcalendarcore", 1, 0, "KCalendarCore", {});
0134     qmlRegisterType<KCalendarCoreExtras::CalendarListModel>("internal.org.kde.kcalendarcore", 1, 0, "CalendarListModel");
0135     qmlRegisterSingletonType("internal.org.kde.kcalendarcore", 1, 0, "CalendarPluginLoader", [](QQmlEngine *, QJSEngine *jsEngine) -> QJSValue {
0136         return jsEngine->toScriptValue(KCalendarCoreExtras::CalendarPluginLoader());
0137     });
0138 }
0139 
0140 void registerKPkPassTypes()
0141 {
0142     qmlRegisterUncreatableMetaObject(KPkPass::Barcode::staticMetaObject, "org.kde.pkpass", 1, 0, "Barcode", {});
0143     qmlRegisterUncreatableMetaObject(KPkPass::Field::staticMetaObject, "org.kde.pkpass", 1, 0, "Field", {});
0144     qmlRegisterUncreatableType<KPkPass::Pass>("org.kde.pkpass", 1, 0, "Pass", {});
0145     qmlRegisterUncreatableType<KPkPass::BoardingPass>("org.kde.pkpass", 1, 0, "BoardingPass", {});
0146 }
0147 
0148 void registerKItineraryTypes()
0149 {
0150     qRegisterMetaType<KItinerary::KnowledgeDb::DrivingSide>();
0151     qmlRegisterUncreatableMetaObject(KItinerary::Ticket::staticMetaObject, "org.kde.kitinerary", 1, 0, "Ticket", {});
0152     qmlRegisterUncreatableMetaObject(KItinerary::KnowledgeDb::staticMetaObject, "org.kde.kitinerary", 1, 0, "KnowledgeDb", {});
0153     qmlRegisterSingletonType("org.kde.itinerary", 1, 0, "PriceUtil", [](QQmlEngine*, QJSEngine *engine) -> QJSValue {
0154         return engine->toScriptValue(KItinerary::PriceUtil());
0155     });
0156 }
0157 
0158 void registerApplicationTypes()
0159 {
0160     qRegisterMetaType<ReservationManager*>();
0161     qRegisterMetaType<Transfer::Alignment>();
0162     qRegisterMetaType<TripGroupManager*>();
0163     qRegisterMetaType<WeatherForecast>();
0164     qRegisterMetaType<Permission::Permission>();
0165     qRegisterMetaType<HealthCertificateManager*>();
0166 
0167     qmlRegisterUncreatableMetaObject(LocationInformation::staticMetaObject, "org.kde.itinerary", 1, 0, "LocationInformation", {});
0168     qmlRegisterUncreatableMetaObject(StatisticsItem::staticMetaObject, "org.kde.itinerary", 1, 0, "StatisticsItem", {});
0169     qmlRegisterUncreatableMetaObject(TimelineElement::staticMetaObject, "org.kde.itinerary", 1, 0, "TimelineElement", {});
0170     qmlRegisterUncreatableType<TimelineModel>("org.kde.itinerary", 1, 0, "TimelineModel", {});
0171     qmlRegisterUncreatableMetaObject(Transfer::staticMetaObject, "org.kde.itinerary", 1, 0, "Transfer", {});
0172 
0173     qmlRegisterUncreatableMetaObject(Permission::staticMetaObject, "org.kde.itinerary", 1, 0, "Permission", {});
0174 #if HAVE_MATRIX
0175     qmlRegisterUncreatableMetaObject(MatrixRoomsModel::staticMetaObject, "org.kde.itinerary", 1, 0, "MatrixRoomsModel", {});
0176 #endif
0177 
0178     qmlRegisterType<CalendarImportModel>("org.kde.itinerary", 1, 0, "CalendarImportModel");
0179     qmlRegisterType<CountrySubdivisionModel>("org.kde.itinerary", 1, 0, "CountrySubdivisionModel");
0180     qmlRegisterType<DocumentsModel>("org.kde.itinerary", 1, 0, "DocumentsModel");
0181     qmlRegisterType<JourneySectionModel>("org.kde.itinerary", 1, 0, "JourneySectionModel");
0182     qmlRegisterType<KDEConnectDeviceModel>("org.kde.itinerary", 1, 0, "KDEConnectDeviceModel");
0183     qmlRegisterType<StatisticsModel>("org.kde.itinerary", 1, 0, "StatisticsModel");
0184     qmlRegisterType<StatisticsTimeRangeModel>("org.kde.itinerary", 1, 0, "StatisticsTimeRangeModel");
0185     qmlRegisterType<TicketTokenModel>("org.kde.itinerary", 1, 0, "TicketTokenModel");
0186     qmlRegisterType<TimelineDelegateController>("org.kde.itinerary", 1, 0, "TimelineDelegateController");
0187     qmlRegisterType<TimelineSectionDelegateController>("org.kde.itinerary", 1, 0, "TimelineSectionDelegateController");
0188     qmlRegisterType<TransferDelegateController>("org.kde.itinerary", 1, 0, "TransferDelegateController");
0189     qmlRegisterType<WeatherForecastModel>("org.kde.itinerary", 1, 0, "WeatherForecastModel");
0190 #if HAVE_MATRIX
0191     qmlRegisterType<MatrixBeacon>("org.kde.itinerary", 1, 0, "MatrixBeacon");
0192 #else
0193     qmlRegisterType<MatrixBeaconStub>("org.kde.itinerary", 1, 0, "MatrixBeacon");
0194 #endif
0195     qmlRegisterType<OnlineTicketImporter>("org.kde.itinerary", 1, 0, "OnlineTicketImporter");
0196 
0197     qmlRegisterSingletonType("org.kde.itinerary", 1, 0, "About", [](QQmlEngine *engine, QJSEngine *) -> QJSValue {
0198         return engine->toScriptValue(KAboutData::applicationData());
0199     });
0200 
0201     qmlRegisterSingletonType<Clipboard>("org.kde.itinerary", 1, 0, "Clipboard", [](QQmlEngine *, QJSEngine *) -> QObject * {
0202         return new Clipboard;
0203     });
0204 }
0205 
0206 // for registering QML singletons only
0207 static ReservationManager *s_reservationManager = nullptr;
0208 static DocumentManager *s_documentManager = nullptr;
0209 static FavoriteLocationModel *s_favoriteLocationModel = nullptr;
0210 static PkPassManager *s_pkPassManager = nullptr;
0211 static Settings *s_settings = nullptr;
0212 static TransferManager *s_tranferManager = nullptr;
0213 static TripGroupManager *s_tripGroupManager = nullptr;
0214 static LiveDataManager *s_liveDataMnager = nullptr;
0215 static WeatherForecastManager *s_weatherForecastManager = nullptr;
0216 static TimelineModel *s_timelineModel = nullptr;
0217 static TripGroupInfoProvider s_tripGroupInfoProvider;
0218 static TripGroupProxyModel *s_tripGroupProxyModel = nullptr;
0219 static MapDownloadManager *s_mapDownloadManager = nullptr;
0220 static PassManager *s_passManager = nullptr;
0221 static MatrixController *s_matrixController = nullptr;
0222 
0223 #define REGISTER_SINGLETON_INSTANCE(Class, Instance) \
0224     qmlRegisterSingletonInstance<Class>("org.kde.itinerary", 1, 0, #Class, Instance);
0225 
0226 #define REGISTER_SINGLETON_GADGET_INSTANCE(Class, Instance) \
0227     qmlRegisterSingletonType("org.kde.itinerary", 1, 0, #Class, [](QQmlEngine *engine, QJSEngine*) -> QJSValue { \
0228         return engine->toScriptValue(Instance); \
0229     });
0230 
0231 #define REGISTER_SINGLETON_GADGET_FACTORY(Class) \
0232     qmlRegisterSingletonType("org.kde.itinerary", 1, 0, #Class, [](QQmlEngine*, QJSEngine *engine) -> QJSValue { \
0233         return engine->toScriptValue(Class()); \
0234     });
0235 
0236 void registerApplicationSingletons()
0237 {
0238     REGISTER_SINGLETON_INSTANCE(ApplicationController, ApplicationController::instance())
0239     REGISTER_SINGLETON_INSTANCE(ReservationManager, s_reservationManager)
0240     REGISTER_SINGLETON_INSTANCE(DocumentManager, s_documentManager)
0241     REGISTER_SINGLETON_INSTANCE(FavoriteLocationModel, s_favoriteLocationModel)
0242     REGISTER_SINGLETON_INSTANCE(PkPassManager, s_pkPassManager)
0243     REGISTER_SINGLETON_INSTANCE(Settings, s_settings)
0244     REGISTER_SINGLETON_INSTANCE(TransferManager, s_tranferManager)
0245     REGISTER_SINGLETON_INSTANCE(TripGroupManager, s_tripGroupManager)
0246     REGISTER_SINGLETON_INSTANCE(LiveDataManager, s_liveDataMnager)
0247     REGISTER_SINGLETON_INSTANCE(WeatherForecastManager, s_weatherForecastManager)
0248     REGISTER_SINGLETON_INSTANCE(TimelineModel, s_timelineModel)
0249     REGISTER_SINGLETON_INSTANCE(TripGroupProxyModel, s_tripGroupProxyModel)
0250     REGISTER_SINGLETON_INSTANCE(MapDownloadManager, s_mapDownloadManager)
0251     REGISTER_SINGLETON_INSTANCE(PassManager, s_passManager)
0252     REGISTER_SINGLETON_INSTANCE(MatrixController, s_matrixController);
0253 
0254     REGISTER_SINGLETON_GADGET_INSTANCE(TripGroupInfoProvider, s_tripGroupInfoProvider)
0255 
0256     REGISTER_SINGLETON_GADGET_FACTORY(DevelopmentModeController)
0257     REGISTER_SINGLETON_GADGET_FACTORY(Factory)
0258     REGISTER_SINGLETON_GADGET_FACTORY(Localizer)
0259     REGISTER_SINGLETON_GADGET_FACTORY(NavigationController)
0260     REGISTER_SINGLETON_GADGET_FACTORY(NotificationConfigController)
0261     REGISTER_SINGLETON_GADGET_FACTORY(PermissionManager)
0262     REGISTER_SINGLETON_GADGET_FACTORY(PublicTransport)
0263     REGISTER_SINGLETON_GADGET_FACTORY(UnitConversion)
0264     REGISTER_SINGLETON_GADGET_FACTORY(Util)
0265 }
0266 
0267 #undef REGISTER_SINGLETON_INSTANCE
0268 #undef REGISTER_SINGLETON_GADGET_INSTANCE
0269 #undef REGISTER_SINGLETON_GADGET_FACTORY
0270 
0271 static QNetworkAccessManager *namFactory()
0272 {
0273     static QNetworkAccessManager *s_nam = nullptr;
0274     if (!s_nam) {
0275         s_nam = new QNetworkAccessManager(QCoreApplication::instance());
0276         s_nam->setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
0277         s_nam->setStrictTransportSecurityEnabled(true);
0278         s_nam->enableStrictTransportSecurityStore(true, QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QLatin1StringView("/hsts/"));
0279     }
0280     return s_nam;
0281 }
0282 
0283 void handleCommandLineArguments(ApplicationController *appController, const QStringList &args, bool isTemporary, const QString &page)
0284 {
0285     for (const auto &file : args) {
0286         const auto localUrl = QUrl::fromLocalFile(file);
0287         if (QFile::exists(localUrl.toLocalFile())) {
0288             appController->importFromUrl(localUrl);
0289             if (isTemporary) {
0290                 QFile::remove(localUrl.toLocalFile());
0291             }
0292         } else {
0293             appController->importFromUrl(QUrl::fromUserInput(file));
0294         }
0295     }
0296 
0297     if (!page.isEmpty()) {
0298         appController->requestOpenPage(page);
0299     }
0300 }
0301 
0302 #ifdef Q_OS_ANDROID
0303 Q_DECL_EXPORT
0304 #endif
0305 int main(int argc, char **argv)
0306 {
0307     QCoreApplication::setApplicationName(QStringLiteral("itinerary"));
0308     QCoreApplication::setOrganizationName(QStringLiteral("KDE"));
0309     QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org"));
0310     QCoreApplication::setApplicationVersion(QStringLiteral(ITINERARY_VERSION_STRING));
0311 #ifdef Q_OS_ANDROID
0312     QGuiApplication app(argc, argv);
0313     QQuickStyle::setStyle(QStringLiteral("org.kde.breeze"));
0314 #else
0315     QIcon::setFallbackThemeName(QStringLiteral("breeze"));
0316     QApplication app(argc, argv); // for native file dialogs
0317 
0318     // Default to org.kde.desktop style unless the user forces another style
0319     if (qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE")) {
0320         QQuickStyle::setStyle(QStringLiteral("org.kde.desktop"));
0321     }
0322 #endif
0323     QGuiApplication::setApplicationDisplayName(i18n("KDE Itinerary"));
0324     QGuiApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("org.kde.itinerary")));
0325 
0326     auto aboutData = KAboutData::applicationData();
0327     aboutData.setBugAddress("submit@bugs.kde.org");
0328     aboutData.setProductName("KDE Itinerary/general"); // Bugzilla product/component name
0329     aboutData.setLicense(KAboutLicense::LGPL_V2, KAboutLicense::OrLaterVersions);
0330     aboutData.setHomepage(QStringLiteral("https://apps.kde.org/itinerary"));
0331     aboutData.setShortDescription(i18n("Digital Travel Assistant"));
0332     aboutData.setCopyrightStatement(i18n("Copyright © The KDE Community"));
0333     aboutData.setDesktopFileName(QStringLiteral("org.kde.itinerary"));
0334     KAboutData::setApplicationData(aboutData);
0335 
0336     QCommandLineParser parser;
0337     QCommandLineOption isTemporaryOpt(QStringLiteral("tempfile"), QStringLiteral("Input file is a temporary file and will be deleted after importing."));
0338     parser.addOption(isTemporaryOpt);
0339     QCommandLineOption pageOpt(QStringLiteral("page"), i18n("Open Itinerary on the given page"), QStringLiteral("page"));
0340     parser.addOption(pageOpt);
0341     QCommandLineOption selfTestOpt(QStringLiteral("self-test"), QStringLiteral("internal, for automated testing"));
0342     parser.addOption(selfTestOpt);
0343     aboutData.setupCommandLine(&parser);
0344     parser.addPositionalArgument(QStringLiteral("file"), i18n("Files or URLs to import."));
0345     parser.process(app);
0346     aboutData.processCommandLine(&parser);
0347 #if HAVE_KCRASH
0348     KCrash::initialize();
0349 #endif
0350 
0351 #ifndef Q_OS_ANDROID
0352     KDBusService service(KDBusService::Unique);
0353 #endif
0354 
0355     Settings settings;
0356     s_settings = &settings;
0357 
0358     PkPassManager pkPassMgr;
0359     pkPassMgr.setNetworkAccessManagerFactory(namFactory);
0360     s_pkPassManager = &pkPassMgr;
0361 
0362     ReservationManager resMgr;
0363     s_reservationManager = &resMgr;
0364 
0365     DocumentManager docMgr;
0366     s_documentManager = &docMgr;
0367 
0368     FavoriteLocationModel favLocModel;
0369     s_favoriteLocationModel = &favLocModel;
0370 
0371     TripGroupManager tripGroupMgr;
0372     tripGroupMgr.setReservationManager(&resMgr);
0373     s_tripGroupManager = &tripGroupMgr;
0374 
0375     LiveDataManager liveDataMgr;
0376     liveDataMgr.setPkPassManager(&pkPassMgr);
0377     liveDataMgr.setReservationManager(&resMgr);
0378     liveDataMgr.setPollingEnabled(settings.queryLiveData());
0379     liveDataMgr.setShowNotificationsOnLockScreen(settings.showNotificationOnLockScreen());
0380     QObject::connect(&settings, &Settings::queryLiveDataChanged, &liveDataMgr, &LiveDataManager::setPollingEnabled);
0381     QObject::connect(&settings, &Settings::showNotificationOnLockScreenChanged, &liveDataMgr, &LiveDataManager::setShowNotificationsOnLockScreen);
0382     s_liveDataMnager = &liveDataMgr;
0383 
0384     WeatherForecastManager weatherForecastMgr;
0385     weatherForecastMgr.setAllowNetworkAccess(settings.weatherForecastEnabled());
0386     QObject::connect(&settings, &Settings::weatherForecastEnabledChanged, &weatherForecastMgr, &WeatherForecastManager::setAllowNetworkAccess);
0387     s_weatherForecastManager = &weatherForecastMgr;
0388 
0389     TransferManager transferManager;
0390     transferManager.setReservationManager(&resMgr);
0391     transferManager.setTripGroupManager(&tripGroupMgr);
0392     transferManager.setFavoriteLocationModel(&favLocModel);
0393     transferManager.setLiveDataManager(&liveDataMgr);
0394     transferManager.setAutoAddTransfers(settings.autoAddTransfers());
0395     transferManager.setAutoFillTransfers(settings.autoFillTransfers());
0396     QObject::connect(&settings, &Settings::autoAddTransfersChanged, &transferManager, &TransferManager::setAutoAddTransfers);
0397     QObject::connect(&settings, &Settings::autoFillTransfersChanged, &transferManager, &TransferManager::setAutoFillTransfers);
0398     s_tranferManager = &transferManager;
0399 
0400     tripGroupMgr.setTransferManager(&transferManager);
0401 
0402     TimelineModel timelineModel;
0403     timelineModel.setHomeCountryIsoCode(settings.homeCountryIsoCode());
0404     timelineModel.setReservationManager(&resMgr);
0405     timelineModel.setWeatherForecastManager(&weatherForecastMgr);
0406     timelineModel.setTransferManager(&transferManager);
0407     timelineModel.setTripGroupManager(&tripGroupMgr);
0408     QObject::connect(&settings, &Settings::homeCountryIsoCodeChanged, &timelineModel, &TimelineModel::setHomeCountryIsoCode);
0409     s_timelineModel = &timelineModel;
0410 
0411     TripGroupProxyModel tripGroupProxy;
0412     tripGroupProxy.setSourceModel(&timelineModel);
0413     s_tripGroupProxyModel = &tripGroupProxy;
0414 
0415     s_tripGroupInfoProvider.setReservationManager(&resMgr);
0416     s_tripGroupInfoProvider.setWeatherForecastManager(&weatherForecastMgr);
0417 
0418     MapDownloadManager mapDownloadMgr;
0419     mapDownloadMgr.setReservationManager(&resMgr);
0420     mapDownloadMgr.setAutomaticDownloadEnabled(s_settings->preloadMapData());
0421     QObject::connect(s_settings, &Settings::preloadMapDataChanged, &mapDownloadMgr, &MapDownloadManager::setAutomaticDownloadEnabled);
0422     s_mapDownloadManager = &mapDownloadMgr;
0423 
0424     KItinerary::JsonLdDocument::registerType<GenericPkPass>();
0425     PassManager passMgr;
0426     s_passManager = &passMgr;
0427 
0428     MatrixController matrixController;
0429     s_matrixController = &matrixController;
0430 
0431     ApplicationController appController;
0432     appController.setNetworkAccessManagerFactory(namFactory);
0433     appController.setReservationManager(&resMgr);
0434     appController.setPkPassManager(&pkPassMgr);
0435     appController.setDocumentManager(&docMgr);
0436     appController.setFavoriteLocationModel(&favLocModel);
0437     appController.setTransferManager(&transferManager);
0438     appController.setLiveDataManager(&liveDataMgr);
0439     appController.setTripGroupManager(&tripGroupMgr);
0440     appController.setPassManager(&passMgr);
0441 #ifndef Q_OS_ANDROID
0442     QObject::connect(&service, &KDBusService::activateRequested, [&](const QStringList &args, const QString &workingDir) {
0443         qCDebug(Log) << "remote activation" << args << workingDir;
0444         if (!args.isEmpty()) {
0445             QDir::setCurrent(workingDir);
0446             parser.parse(args);
0447             handleCommandLineArguments(&appController, parser.positionalArguments(), parser.isSet(isTemporaryOpt), parser.value(pageOpt));
0448         }
0449         if (!QGuiApplication::allWindows().isEmpty()) {
0450             QWindow *window = QGuiApplication::allWindows().at(0);
0451             KWindowSystem::updateStartupId(window);
0452             KWindowSystem::activateWindow(window);
0453         }
0454     });
0455 #endif
0456 
0457     OnlineTicketImporter::setNetworkAccessManagerFactory(namFactory);
0458 
0459     registerKContactsTypes();
0460     registerKCalendarCoreTypes();
0461     registerKPkPassTypes();
0462     registerKItineraryTypes();
0463     registerApplicationTypes();
0464     registerApplicationSingletons();
0465 
0466     QQmlApplicationEngine engine;
0467     engine.addImageProvider(QStringLiteral("org.kde.pkpass"), new PkPassImageProvider(&pkPassMgr));
0468     auto l10nContext = new KLocalizedContext(&engine);
0469     l10nContext->setTranslationDomain(QStringLiteral(TRANSLATION_DOMAIN));
0470     engine.rootContext()->setContextObject(l10nContext);
0471     engine.load(QStringLiteral("qrc:/qt/qml/org/kde/itinerary/main.qml"));
0472 
0473     // Exit on QML load error.
0474     if (engine.rootObjects().isEmpty()) {
0475         return 1;
0476     }
0477 
0478     handleCommandLineArguments(&appController, parser.positionalArguments(), parser.isSet(isTemporaryOpt), parser.value(pageOpt));
0479 
0480 #ifdef Q_OS_ANDROID
0481     using namespace KAndroidExtras;
0482     appController.importFromIntent(Activity::getIntent());
0483 #endif
0484 
0485     if (parser.isSet(selfTestOpt)) {
0486         QTimer::singleShot(std::chrono::milliseconds(250), &app, &QCoreApplication::quit);
0487     }
0488 
0489     return app.exec();
0490 }
0491 
0492 #include "main.moc"