diff --git a/CMakeLists.txt b/CMakeLists.txt index 70e5cbf..1ea714c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,59 +1,59 @@ cmake_minimum_required(VERSION 3.0) project(itinerary VERSION 0.0.1) find_package(ECM 5.38 REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} ${CMAKE_SOURCE_DIR}/cmake) include(KDECompilerSettings NO_POLICY_SCOPE) include(ECMAddTests) include(ECMGenerateHeaders) include(ECMQtDeclareLoggingCategory) include(ECMSetupVersion) include(FeatureSummary) include(KDEInstallDirs) include(KDECMakeSettings) include(GenerateExportHeader) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) ecm_setup_version(PROJECT VARIABLE_PREFIX ITINERARY VERSION_HEADER itinerary_version.h) # build-time dependencies find_package(Qt5 REQUIRED COMPONENTS Test Quick) +find_package(Qt5 OPTIONAL_COMPONENTS QuickCompiler) find_package(KF5 REQUIRED COMPONENTS I18n) find_package(KF5Contacts CONFIG REQUIRED) find_package(KPimPkPass CONFIG REQUIRED) find_package(KPimItinerary CONFIG REQUIRED) -find_package(QmlLint) set_package_properties(QmlLint PROPERTIES URL "https://qt.io" PURPOSE "Validate QML code.") find_package(SharedMimeInfo 1.0 REQUIRED) find_package(ZLIB REQUIRED) set_package_properties("ZLIB" PROPERTIES PURPOSE "Needed for retrieving weather forecast data.") include(ECMQMLModules) ecm_find_qmlmodule(org.kde.prison 1.0) ecm_find_qmlmodule(Qt.labs.platform 1.0) # 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) find_package(KF5 REQUIRED COMPONENTS DBusAddons) 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) install(FILES org_kde_itinerary.categories DESTINATION ${KDE_INSTALL_CONFDIR}) feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/cmake/FindQmlLint.cmake b/cmake/FindQmlLint.cmake deleted file mode 100644 index 5363da1..0000000 --- a/cmake/FindQmlLint.cmake +++ /dev/null @@ -1,62 +0,0 @@ -# Copyright (C) 2016-2018 Klarälvdalens Datakonsult AB, a KDAB Group company -# All rights reserved. -# -# Author: Volker Krause -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. The name of the author may not be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -find_program(QMLLINT_EXECUTABLE qmllint) -if (QMLLINT_EXECUTABLE AND NOT Qt5Core_VERSION VERSION_LESS 5.4) - if(NOT QMLLINT_IS_WORKING) - # Try to fix common problems on Debian-based distros -- they provide /usr/bin/qmllint, which is a symlink to - # /usr/lib/x86_64-linux-gnu/qt4/bin/qmllint (or the Qt5 version of it). The actual executable is part of different - # package, so might not even be installed => double-check whether qmllint is working by executing it - execute_process(COMMAND ${QMLLINT_EXECUTABLE} --version RESULT_VARIABLE _qmllint_result OUTPUT_QUIET ERROR_QUIET) - if (_qmllint_result EQUAL 0) - set(QMLLINT_IS_WORKING TRUE CACHE BOOL "Whether the found qmllint executable is actually usable" FORCE) - endif() - endif() - if(QMLLINT_IS_WORKING) - set(QmlLint_FOUND TRUE) - endif() -endif() - -# validate a list of qml files -function(qml_lint) - if (NOT QMLLINT_EXECUTABLE OR NOT QmlLint_FOUND) - return() - endif() - - foreach(_file ${ARGN}) - get_filename_component(_file_abs ${_file} ABSOLUTE) - string(REPLACE "/" "__" _target_name ${_file}) - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_target_name}.qmllint - COMMAND ${QMLLINT_EXECUTABLE} ${_file_abs} - COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/${_target_name}.qmllint - MAIN_DEPENDENCY ${_file_abs} - ) - add_custom_target(${_target_name}_qmllint ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${_target_name}.qmllint) - endforeach() -endfunction() diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index fc93e5e..dde8767 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -1,120 +1,98 @@ set(itinerary_srcs countryinformation.cpp pkpassmanager.cpp reservationmanager.cpp timelinemodel.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 KPim::Itinerary KPim::PkPass KF5::I18n Qt5::Network ) +if (Qt5QuickCompiler_FOUND) + qtquick_compiler_add_resources(qml_srcs qml.qrc) +else () + set(qml_srcs qml.qrc) +endif() + add_executable(itinerary-app main.cpp applicationcontroller.cpp countrymodel.cpp localizer.cpp pkpassimageprovider.cpp settings.cpp - qml.qrc + ${qml_srcs} ) target_include_directories(itinerary-app PRIVATE ${CMAKE_BINARY_DIR}) target_link_libraries(itinerary-app PRIVATE itinerary Qt5::Quick KF5::Contacts ) if (ANDROID) # explicitly add runtime dependencies and transitive link dependencies, # so androiddeployqt picks them up target_link_libraries(itinerary-app PRIVATE KF5::Archive KF5::Kirigami2 Qt5::AndroidExtras Qt5::Svg KF5::Prison OpenSSL::SSL ) kirigami_package_breeze_icons(ICONS document-open edit-delete go-next-symbolic map-symbolic 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-app PRIVATE KF5::DBusAddons Qt5::Positioning Qt5::Widgets ) set_target_properties(itinerary-app PROPERTIES OUTPUT_NAME "itinerary") endif() -qml_lint( - main.qml - BoardingPass.qml - BusDelegate.qml - BusPage.qml - CountryInfoDelegate.qml - DetailsPage.qml - FlightDelegate.qml - FlightPage.qml - HotelDelegate.qml - HotelPage.qml - ImportDialog.qml - PkPassPage.qml - PlaceDelegate.qml - RestaurantDelegate.qml - RestaurantPage.qml - SettingsPage.qml - TicketTokenDelegate.qml - TimelineDelegate.qml - TimelinePage.qml - TouristAttractionDelegate.qml - TrainDelegate.qml - TrainPage.qml - WeatherForecastDelegate.qml - - +android/ImportDialog.qml -) - install(TARGETS itinerary-app ${INSTALL_TARGETS_DEFAULT_ARGS}) if (NOT ANDROID) install(PROGRAMS org.kde.itinerary.desktop DESTINATION ${KDE_INSTALL_APPDIR}) endif() diff --git a/src/app/main.cpp b/src/app/main.cpp index 4f2a31c..7c69371 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -1,173 +1,173 @@ /* 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 "countryinformation.h" #include "countrymodel.h" #include "localizer.h" #include "pkpassmanager.h" #include "timelinemodel.h" #include "pkpassimageprovider.h" #include "reservationmanager.h" #include "settings.h" #include #include #include #include #include #ifndef Q_OS_ANDROID #include #endif #include #include #include #include #ifdef Q_OS_ANDROID #include #include #else #include #endif #include #include #include #include #include #include void handleViewIntent(ApplicationController *appController) { #ifdef Q_OS_ANDROID // handle opened files const auto activity = QtAndroid::androidActivity(); if (!activity.isValid()) return; const auto intent = activity.callObjectMethod("getIntent", "()Landroid/content/Intent;"); appController->importFromIntent(intent); #else Q_UNUSED(appController); #endif } #ifdef Q_OS_ANDROID Q_DECL_EXPORT #endif int main(int argc, char **argv) { QCoreApplication::setApplicationName(QStringLiteral("kde-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 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; resMgr.setPkPassManager(&passMgr); ApplicationController appController; appController.setReservationManager(&resMgr); appController.setPkPassManager(&passMgr); #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); for (const auto &file : parser.positionalArguments()) { appController.importLocalFile(QUrl::fromLocalFile(file)); } } 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); qmlRegisterUncreatableType("org.kde.pkpass", 1, 0, "Barcode", {}); qmlRegisterUncreatableType("org.kde.pkpass", 1, 0, "Field", {}); 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", {}); qmlRegisterUncreatableType("org.kde.itinerary", 1, 0, "TimelineModel", {}); qmlRegisterSingletonType("org.kde.itinerary", 1, 0, "Localizer", [](QQmlEngine*, QJSEngine*) -> QObject*{ return new Localizer; }); qmlRegisterType("org.kde.itinerary", 1, 0, "CountryModel"); 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"), &timelineModel); engine.rootContext()->setContextProperty(QStringLiteral("_appController"), &appController); engine.rootContext()->setContextProperty(QStringLiteral("_settings"), &settings); - engine.load(QStringLiteral(":/main.qml")); + engine.load(QStringLiteral("qrc:/main.qml")); for (const auto &file : parser.positionalArguments()) { appController.importLocalFile(QUrl::fromLocalFile(file)); } handleViewIntent(&appController); return app.exec(); }