diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f4a388..5454dda 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,67 +1,72 @@ cmake_minimum_required(VERSION 3.0) project(itinerary VERSION 0.0.1) find_package(ECM 5.59 REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} ${CMAKE_SOURCE_DIR}/cmake) include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) include(ECMAddTests) include(ECMGenerateHeaders) include(ECMQtDeclareLoggingCategory) include(ECMSetupVersion) include(FeatureSummary) include(KDEInstallDirs) include(KDECMakeSettings) include(GenerateExportHeader) set(CMAKE_CXX_STANDARD 14) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) ecm_setup_version(PROJECT VARIABLE_PREFIX ITINERARY VERSION_HEADER itinerary_version.h) +set(QT_MIN_VERSION 5.11) +if (ANDROID) + set(QT_MIN_VERSION 5.13) # for content: support and lambda activity result receiver support +endif() + # build-time dependencies -find_package(Qt5 5.10 REQUIRED COMPONENTS Test Quick) +find_package(Qt5 ${QT_MIN_VERSION} REQUIRED COMPONENTS Test Quick) find_package(Qt5 CONFIG QUIET OPTIONAL_COMPONENTS QuickCompiler) find_package(KF5 REQUIRED COMPONENTS I18n CoreAddons) find_package(KF5Holidays 5.49.0 CONFIG QUIET) find_package(KF5Notifications 5.49.0 CONFIG QUIET) find_package(KF5Contacts CONFIG REQUIRED) find_package(KPimPkPass CONFIG REQUIRED) -find_package(KPimItinerary 5.9.40 CONFIG REQUIRED) +find_package(KPimItinerary 5.12.0 CONFIG REQUIRED) find_package(KPublicTransport CONFIG REQUIRED) find_package(SharedMimeInfo 1.0 REQUIRED) find_package(ZLIB REQUIRED) set_package_properties("ZLIB" PROPERTIES PURPOSE "Needed for retrieving weather forecast data.") set_package_properties(KF5Solid PROPERTIES TYPE OPTIONAL TYPE RUNTIME PURPOSE "Used for controlling the screen brightness.") include(ECMQMLModules) ecm_find_qmlmodule(org.kde.prison 1.0) if (NOT ANDROID) ecm_find_qmlmodule(Qt.labs.platform 1.0) endif() # runtime dependencies are build-time dependencies on Android if (ANDROID) find_package(Qt5 REQUIRED COMPONENTS AndroidExtras Svg) find_package(KF5 REQUIRED COMPONENTS Archive Kirigami2 Prison) if (NOT DEFINED BREEZEICONS_DIR AND EXISTS ${CMAKE_SOURCE_DIR}/../breeze-icons) set(BREEZEICONS_DIR ${CMAKE_SOURCE_DIR}/../breeze-icons) endif() find_package(OpenSSL REQUIRED) else() find_package(Qt5 REQUIRED COMPONENTS Widgets Positioning DBus) find_package(KF5 REQUIRED COMPONENTS DBusAddons) find_package(KF5 COMPONENTS Solid) endif() add_definitions(-DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII -DQT_NO_URL_CAST_FROM_STRING) add_definitions(-DQT_NO_NARROWING_CONVERSIONS_IN_CONNECT) add_definitions(-DQT_USE_QSTRINGBUILDER) add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x060000) add_subdirectory(src) add_subdirectory(autotests) add_subdirectory(tests) install(FILES org_kde_itinerary.categories DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR}) feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index ea6f8da..f1d964d 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -1,159 +1,158 @@ if (TARGET KF5::Notifications) SET(HAVE_NOTIFICATIONS TRUE) endif() configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config-itinerary.h.in ${CMAKE_CURRENT_BINARY_DIR}/config-itinerary.h) set(itinerary_srcs applicationcontroller.cpp countryinformation.cpp documentmanager.cpp livedatamanager.cpp navigationcontroller.cpp pkpassmanager.cpp pkpassimageprovider.cpp publictransport.cpp reservationmanager.cpp timelinedelegatecontroller.cpp timelinemodel.cpp tripgroup.cpp tripgroupinfoprovider.cpp tripgroupmanager.cpp tripgroupproxymodel.cpp util.cpp ) ecm_qt_declare_logging_category(itinerary_srcs HEADER logging.h IDENTIFIER Log CATEGORY_NAME org.kde.itinerary ) add_library(itinerary STATIC ${itinerary_srcs}) target_link_libraries(itinerary PUBLIC itinerary-weather KPublicTransport KPim::Itinerary KPim::PkPass KF5::I18n KF5::CoreAddons Qt5::Network Qt5::Quick ) if (TARGET KF5::Notifications) target_link_libraries(itinerary PUBLIC KF5::Notifications) endif() if (Qt5QuickCompiler_FOUND) qtquick_compiler_add_resources(qml_srcs qml.qrc) else () set(qml_srcs qml.qrc) endif() set(itinerary_app_srcs main.cpp countrymodel.cpp documentsmodel.cpp localizer.cpp settings.cpp tickettokenmodel.cpp weatherforecastmodel.cpp ${qml_srcs} brightnessmanager.cpp lockmanager.cpp ) if (ANDROID) list(APPEND itinerary_app_srcs androidbrightnessbackend.cpp - androidcontentfileengine.cpp androidlockbackend.cpp ) else() list(APPEND itinerary_app_srcs solidbrightnessbackend.cpp solidlockbackend.cpp ) qt5_add_dbus_interface(itinerary_app_srcs org.kde.Solid.PowerManagement.Actions.BrightnessControl.xml brightnesscontroldbusinterface) qt5_add_dbus_interface(itinerary_app_srcs org.freedesktop.ScreenSaver.xml screensaverdbusinterface) endif() add_executable(itinerary-app ${itinerary_app_srcs}) target_include_directories(itinerary-app PRIVATE ${CMAKE_BINARY_DIR}) target_link_libraries(itinerary-app PRIVATE itinerary KF5::Contacts ) if (ANDROID) target_include_directories(itinerary-app PRIVATE ${Qt5Core_PRIVATE_INCLUDE_DIRS}) # explicitly add runtime dependencies and transitive link dependencies, # so androiddeployqt picks them up target_link_libraries(itinerary PUBLIC Qt5::AndroidExtras KAndroidExtras) target_link_libraries(itinerary-app PRIVATE KF5::Archive KF5::Kirigami2 Qt5::Svg KF5::Prison OpenSSL::SSL ) kirigami_package_breeze_icons(ICONS application-pdf checkmark clock dialog-cancel document-edit document-open document-save documentinfo edit-delete edit-download edit-paste export-symbolic folder-documents-symbolic go-down-symbolic go-home go-next-symbolic go-up-symbolic help-about list-add map-symbolic meeting-attending question settings-configure view-calendar-day view-refresh weather-clear weather-clear-night weather-few-clouds weather-few-clouds-night weather-clouds weather-clouds-night weather-showers-day weather-showers-night weather-showers-scattered-day weather-showers-scattered-night weather-snow-scattered-day weather-snow-scattered-night weather-storm-day weather-storm-night weather-many-clouds weather-fog weather-showers weather-showers-scattered weather-hail weather-snow weather-snow-scattered weather-storm ) else () target_link_libraries(itinerary PRIVATE Qt5::Positioning Qt5::DBus) target_link_libraries(itinerary-app PRIVATE KF5::DBusAddons Qt5::Widgets ) set_target_properties(itinerary-app PROPERTIES OUTPUT_NAME "itinerary") endif() install(TARGETS itinerary-app ${INSTALL_TARGETS_DEFAULT_ARGS}) if (NOT ANDROID) install(PROGRAMS org.kde.itinerary.desktop DESTINATION ${KDE_INSTALL_APPDIR}) endif() install(FILES org.kde.itinerary.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR}) diff --git a/src/app/androidcontentfileengine.cpp b/src/app/androidcontentfileengine.cpp deleted file mode 100644 index e075f1b..0000000 --- a/src/app/androidcontentfileengine.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 Volker Krause -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "androidcontentfileengine.h" - -#include -#include - -#include - -AndroidContentFileEngine::AndroidContentFileEngine(const QString &fileName) - : QFSFileEngine(fileName) -{ -} - -bool AndroidContentFileEngine::open(QIODevice::OpenMode openMode) -{ - QString openModeStr; - if (openMode & QFileDevice::ReadOnly) { - openModeStr += QLatin1Char('r'); - } - if (openMode & QFileDevice::WriteOnly) { - openModeStr += QLatin1Char('w'); - } - if (openMode & QFileDevice::Truncate) { - openModeStr += QLatin1Char('t'); - } else if (openMode & QFileDevice::Append) { - openModeStr += QLatin1Char('a'); - } - - const auto fd = QJNIObjectPrivate::callStaticMethod("org/kde/itinerary/ContentFileEngine", - "openFdForContentUri", - "(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)I", - QtAndroidPrivate::context(), - QJNIObjectPrivate::fromString(fileName(DefaultName)).object(), - QJNIObjectPrivate::fromString(openModeStr).object()); - - if (fd < 0) { - return false; - } - - return QFSFileEngine::open(openMode, fd, QFile::AutoCloseHandle); -} - - -AndroidContentFileEngineHandler::AndroidContentFileEngineHandler() = default; -AndroidContentFileEngineHandler::~AndroidContentFileEngineHandler() = default; - -QAbstractFileEngine* AndroidContentFileEngineHandler::create(const QString &fileName) const -{ - if (!fileName.startsWith(QLatin1String("content"))) { - return nullptr; - } - - return new AndroidContentFileEngine(fileName); -} diff --git a/src/app/androidcontentfileengine.h b/src/app/androidcontentfileengine.h deleted file mode 100644 index db3def0..0000000 --- a/src/app/androidcontentfileengine.h +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 Volker Krause -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ANDROIDCONTENTFILEENGINE_H -#define ANDROIDCONTENTFILEENGINE_H - -#include - -class AndroidContentFileEngine : public QFSFileEngine -{ -public: - AndroidContentFileEngine(const QString &fileName); - bool open(QIODevice::OpenMode openMode) override; -}; - -class AndroidContentFileEngineHandler : public QAbstractFileEngineHandler -{ -public: - AndroidContentFileEngineHandler(); - ~AndroidContentFileEngineHandler(); - QAbstractFileEngine *create(const QString &fileName) const override; -}; - -#endif // ANDROIDCONTENTFILEENGINE_H diff --git a/src/app/main.cpp b/src/app/main.cpp index e94c934..a17645c 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -1,246 +1,244 @@ /* Copyright (C) 2018 Volker Krause This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "itinerary_version.h" #include "logging.h" #include "applicationcontroller.h" #include "brightnessmanager.h" #include "countryinformation.h" #include "countrymodel.h" #include "documentmanager.h" #include "documentsmodel.h" #include "livedatamanager.h" #include "localizer.h" #include "lockmanager.h" #include "navigationcontroller.h" #include "pkpassmanager.h" #include "timelinemodel.h" #include "pkpassimageprovider.h" #include "publictransport.h" #include "reservationmanager.h" #include "settings.h" #include "tickettokenmodel.h" #include "tripgroupinfoprovider.h" #include "tripgroupmanager.h" #include "tripgroupproxymodel.h" #include "util.h" #include "timelinedelegatecontroller.h" #include "weatherforecastmodel.h" #include #include #include #include #include #include #include #ifndef Q_OS_ANDROID #include #endif #include #include #include #include #ifdef Q_OS_ANDROID #include #include -#include "androidcontentfileengine.h" #include #include #else #include #endif #include #include #include #include #include #include void handleViewIntent(ApplicationController *appController) { #ifdef Q_OS_ANDROID // handle opened files using namespace KAndroidExtras; appController->importFromUrl(Activity::getIntent().getData()); #else Q_UNUSED(appController); #endif } void handlePositionalArguments(ApplicationController *appController, const QStringList &args) { for (const auto &file : args) { const auto localUrl = QUrl::fromLocalFile(file); if (QFile::exists(localUrl.toLocalFile())) appController->importFromUrl(localUrl); else appController->importFromUrl(QUrl::fromUserInput(file)); } } #ifdef Q_OS_ANDROID Q_DECL_EXPORT #endif int main(int argc, char **argv) { QCoreApplication::setApplicationName(QStringLiteral("itinerary")); QCoreApplication::setOrganizationName(QStringLiteral("KDE")); QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org")); QCoreApplication::setApplicationVersion(QStringLiteral(ITINERARY_VERSION_STRING)); QGuiApplication::setApplicationDisplayName(i18n("KDE Itinerary")); QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); #ifdef Q_OS_ANDROID - AndroidContentFileEngineHandler fsEngineHandler; QGuiApplication app(argc, argv); #else QApplication app(argc, argv); // for native file dialogs #endif QGuiApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("map-globe"))); QCommandLineParser parser; parser.addHelpOption(); parser.addVersionOption(); parser.addPositionalArgument(QStringLiteral("file"), i18n("PkPass or JSON-LD file to import.")); parser.process(app); #ifndef Q_OS_ANDROID KDBusService service(KDBusService::Unique); #endif Settings settings; PkPassManager passMgr; ReservationManager resMgr; DocumentManager docMgr; resMgr.setPkPassManager(&passMgr); TripGroupManager tripGroupMgr; tripGroupMgr.setReservationManager(&resMgr); ApplicationController appController; appController.setReservationManager(&resMgr); appController.setPkPassManager(&passMgr); appController.setDocumentManager(&docMgr); BrightnessManager brightnessManager; LockManager lockManager; KPublicTransport::Manager ptMgr; ptMgr.setAllowInsecureBackends(settings.allowInsecureServices()); QObject::connect(&settings, &Settings::allowInsecureServicesChanged, [&ptMgr](bool insec) { ptMgr.setAllowInsecureBackends(insec); }); LiveDataManager liveDataMgr; liveDataMgr.setPublicTransportManager(&ptMgr); liveDataMgr.setPkPassManager(&passMgr); liveDataMgr.setReservationManager(&resMgr); liveDataMgr.setPollingEnabled(settings.queryLiveData()); QObject::connect(&settings, &Settings::queryLiveDataChanged, &liveDataMgr, &LiveDataManager::setPollingEnabled); #ifndef Q_OS_ANDROID QObject::connect(&service, &KDBusService::activateRequested, [&parser, &appController](const QStringList &args, const QString &workingDir) { qCDebug(Log) << "remote activation" << args << workingDir; if (!args.isEmpty()) { QDir::setCurrent(workingDir); parser.parse(args); handlePositionalArguments(&appController, parser.positionalArguments()); } if (!QGuiApplication::allWindows().isEmpty()) { QGuiApplication::allWindows().at(0)->requestActivate(); } }); #endif TimelineModel timelineModel; timelineModel.setHomeCountryIsoCode(settings.homeCountryIsoCode()); timelineModel.setReservationManager(&resMgr); QObject::connect(&settings, &Settings::homeCountryIsoCodeChanged, &timelineModel, &TimelineModel::setHomeCountryIsoCode); WeatherForecastManager weatherForecastMgr; weatherForecastMgr.setAllowNetworkAccess(settings.weatherForecastEnabled()); QObject::connect(&settings, &Settings::weatherForecastEnabledChanged, &weatherForecastMgr, &WeatherForecastManager::setAllowNetworkAccess); timelineModel.setWeatherForecastManager(&weatherForecastMgr); timelineModel.setTripGroupManager(&tripGroupMgr); TripGroupProxyModel tripGroupProxy; tripGroupProxy.setSourceModel(&timelineModel); TripGroupInfoProvider tripGroupInfoProvider; tripGroupInfoProvider.setReservationManager(&resMgr); tripGroupInfoProvider.setWeatherForecastManager(&weatherForecastMgr); qmlRegisterUncreatableType("org.kde.pkpass", 1, 0, "Barcode", {}); qmlRegisterUncreatableType("org.kde.pkpass", 1, 0, "Field", {}); qmlRegisterUncreatableType("org.kde.pkpass", 1, 0, "Pass", {}); qmlRegisterUncreatableType("org.kde.pkpass", 1, 0, "BoardingPass", {}); qRegisterMetaType(); qmlRegisterUncreatableType("org.kde.kitinerary", 1, 0, "Ticket", {}); qmlRegisterUncreatableMetaObject(KItinerary::KnowledgeDb::staticMetaObject, "org.kde.kitinerary", 1, 0, "KnowledgeDb", {}); qmlRegisterUncreatableType("org.kde.itinerary", 1, 0, "CountryInformation", {}); qmlRegisterType("org.kde.itinerary", 1, 0, "CountryModel"); qmlRegisterType("org.kde.itinerary", 1, 0, "DocumentsModel"); qmlRegisterSingletonType("org.kde.itinerary", 1, 0, "Localizer", [](QQmlEngine*, QJSEngine *engine) -> QJSValue { return engine->toScriptValue(Localizer()); }); qmlRegisterType("org.kde.itinerary", 1, 0, "TicketTokenModel"); qmlRegisterUncreatableType("org.kde.itinerary", 1, 0, "TimelineModel", {}); qmlRegisterType("org.kde.itinerary", 1, 0, "TimelineDelegateController"); qmlRegisterSingletonType("org.kde.itinerary", 1, 0, "Util", [](QQmlEngine*, QJSEngine*) -> QObject*{ return new Util; }); qmlRegisterType("org.kde.itinerary", 1, 0, "WeatherForecastModel"); qmlRegisterSingletonType("org.kde.itinerary", 1, 0, "PublicTransport", [](QQmlEngine*, QJSEngine *engine) -> QJSValue { return engine->toScriptValue(PublicTransport()); }); qmlRegisterSingletonType("org.kde.itinerary", 1, 0, "NavigationController", [](QQmlEngine*, QJSEngine *engine) -> QJSValue { return engine->toScriptValue(NavigationController()); }); qmlRegisterSingletonType("org.kde.itinerary", 1, 0, "DocumentManager", [](QQmlEngine *engine, QJSEngine*) -> QObject* { engine->setObjectOwnership(DocumentManager::instance(), QQmlEngine::CppOwnership); return DocumentManager::instance(); }); QQmlApplicationEngine engine; engine.addImageProvider(QStringLiteral("org.kde.pkpass"), new PkPassImageProvider(&passMgr)); engine.rootContext()->setContextObject(new KLocalizedContext(&engine)); engine.rootContext()->setContextProperty(QStringLiteral("_pkpassManager"), &passMgr); engine.rootContext()->setContextProperty(QStringLiteral("_reservationManager"), &resMgr); engine.rootContext()->setContextProperty(QStringLiteral("_timelineModel"), &tripGroupProxy); engine.rootContext()->setContextProperty(QStringLiteral("_appController"), &appController); engine.rootContext()->setContextProperty(QStringLiteral("_settings"), &settings); engine.rootContext()->setContextProperty(QStringLiteral("_weatherForecastManager"), &weatherForecastMgr); engine.rootContext()->setContextProperty(QStringLiteral("_brightnessManager"), &brightnessManager); engine.rootContext()->setContextProperty(QStringLiteral("_lockManager"), &lockManager); engine.rootContext()->setContextProperty(QStringLiteral("_liveDataManager"), &liveDataMgr); engine.rootContext()->setContextProperty(QStringLiteral("_tripGroupInfoProvider"), QVariant::fromValue(tripGroupInfoProvider)); engine.load(QStringLiteral("qrc:/main.qml")); handlePositionalArguments(&appController, parser.positionalArguments()); handleViewIntent(&appController); return app.exec(); }