diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ea05eb58..dd13e4c2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,389 +1,389 @@ cmake_minimum_required(VERSION 2.8.12) # Set minimum OS X target set(CMAKE_OSX_DEPLOYMENT_TARGET 10.9) project(marble) #################################################### # CMake Settings SET(CMAKE_COLOR_MAKEFILE ON) # SET(CMAKE_SKIP_RPATH ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) # Let CMake find the correct library dir instead of # relying on the obsolete LIB_SUFFIX parameter include(GNUInstallDirs) # Taken from KDECompilerSettings.cmake: # Pick sensible versions of the C and C++ standards. # Note that MSVC does not have equivalent flags; the features are either # supported or they are not. if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") # We use the C89 standard because that is what is common to all our # compilers (in particular, MSVC 2010 does not support C99) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=iso9899:1990") endif() if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel" AND NOT WIN32) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") endif() # Default to hidden visibility for symbols set(CMAKE_C_VISIBILITY_PRESET hidden) set(CMAKE_CXX_VISIBILITY_PRESET hidden) set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) if (POLICY CMP0063) cmake_policy(SET CMP0063 NEW) endif() # RPATH/RUNPATH settings if (UNIX) # Add CMAKE_INSTALL_FULL_LIBDIR to the RPATH to be used when installing, # but only if it isn't a standard system directory. list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_FULL_LIBDIR}" isSystemLibDir) list(FIND CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_FULL_LIBDIR}" isSystemCxxLibDir) list(FIND CMAKE_C_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_FULL_LIBDIR}" isSystemCLibDir) if("${isSystemLibDir}" STREQUAL "-1" AND "${isSystemCxxLibDir}" STREQUAL "-1" AND "${isSystemCLibDir}" STREQUAL "-1") set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_FULL_LIBDIR}") endif() # Add directories which are in the linker search path (but outside the project) # to the RPATH to be used when installing set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) # no libs or plugins are designed to be used from the build dir, so directly link with install rpath set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) endif (UNIX) #################################################### # Where to look first for cmake modules, # before ${CMAKE_ROOT}/Modules/ is checked set ( CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/cmake_find_rules ${CMAKE_CURRENT_SOURCE_DIR}/cmake_scripts ${CMAKE_MODULE_PATH} ) # add cmake macros include(GenerateExportHeader) include( MarbleMacros ) #################################################### # Generate the tiles with the tilecreator at compile time # if this option is set, srtm.jpg will not be installed but the generated tiles instead option(MOBILE "Create a Marble version optimized for handheld devices") #################################################### # Build a D-Bus interface for the Marble widget # This is disabled by default for all win32, apple and Android if(WIN32 OR APPLE OR CMAKE_SYSTEM_NAME STREQUAL Android) option(BUILD_WITH_DBUS "Build the D-Bus interface for the Marble widget" OFF) else() option(BUILD_WITH_DBUS "Build the D-Bus interface for the Marble widget" ON) endif() ####################################################### # Specific options for building for different platforms if(CMAKE_SYSTEM_NAME STREQUAL Android) add_definitions(-DANDROID) endif() ####################################################### # Find Qt dependencies if(CMAKE_SYSTEM_NAME STREQUAL Android) set(REQUIRED_QT_VERSION 5.7.0) # TODO: still needed with ECM toolchain? SET(QT_QMAKE_EXECUTABLE "$ENV{Qt5_android}/bin/qmake") else() set(REQUIRED_QT_VERSION 5.3.0) endif() find_package(Qt5 ${REQUIRED_QT_VERSION} REQUIRED COMPONENTS Core Xml Network Test Widgets Svg Sql Concurrent Quick PrintSupport ) if(CMAKE_SYSTEM_NAME STREQUAL Android) find_package(Qt5 ${REQUIRED_QT_VERSION} REQUIRED COMPONENTS Positioning Multimedia ) set ( MARBLE_NO_WEBKITWIDGETS TRUE ) else() find_package(Qt5 ${REQUIRED_QT_VERSION} COMPONENTS - WebKit - WebKitWidgets + WebEngine + WebEngineWidgets ) - if ( NOT Qt5WebKitWidgets_FOUND ) + if ( NOT Qt5WebEngineWidgets_FOUND ) set ( MARBLE_NO_WEBKITWIDGETS TRUE ) endif() endif() if (BUILD_WITH_DBUS) find_package(Qt5 ${REQUIRED_QT_VERSION} COMPONENTS DBus) if (NOT Qt5DBus_FOUND) set(MARBLE_NO_DBUS TRUE) endif() else() set(MARBLE_NO_DBUS TRUE) endif() SET(CMAKE_AUTOMOC TRUE) # Use M_PI under Windows if( WIN32 ) add_definitions( -D_USE_MATH_DEFINES ) endif( WIN32 ) #################################################### # build unit tests INCLUDE (CTest) ENABLE_TESTING() option( BUILD_MARBLE_TESTS "Build unit tests" ON ) add_feature_info("Unit tests" BUILD_MARBLE_TESTS "Build unit tests. Toggle with BUILD_MARBLE_TESTS=YES/NO. 'make test' will run all.") if( BUILD_MARBLE_TESTS ) # SET (TEST_DATA_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/tests/test_data") #where unit test binaries should be installed to and run from # SET (MARBLE_TEST_DIR ${CMAKE_CURRENT_BINARY_DIR}/tests) endif( BUILD_MARBLE_TESTS ) #################################################### set (PEDANTIC FALSE CACHE BOOL "Determines if we should compile with -Wall -Werror.") set (WITH_DESIGNER_PLUGIN TRUE CACHE BOOL "Build plugins for Qt Designer") add_feature_info("Qt Designer plugins" WITH_DESIGNER_PLUGIN "Marble widget support in Qt Designer. Toggle with WITH_DESIGNER_PLUGIN=YES/NO") set(EXEC_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX} CACHE PATH "Base directory for executables and libraries" FORCE) if (NOT QT_PLUGINS_DIR) set(QT_PLUGINS_DIR ${CMAKE_INSTALL_LIBDIR}/plugins) endif() #################################################### # Detect default for the user configurable MARBLE_DATA_PATH option if(WIN32) set(data_dir data) set(locale_dir "${data_dir}/locale") set(plugin_dir plugins) elseif(APPLE) # needed for finding bundle path in e.g. katlasdir.h FIND_LIBRARY(APP_SERVICES_LIBRARY ApplicationServices ) MARK_AS_ADVANCED (APP_SERVICES_LIBRARY) SET(MAC_EXTRA_LIBS ${APP_SERVICES_LIBRARY}) # for Mac OS X, everything is put inside an application bundle SET (CMAKE_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}/) # path for library references SET (CMAKE_INSTALL_NAME_DIR @executable_path/lib) # install the Info.plist file install(FILES src/mac/Info.plist DESTINATION ${CMAKE_INSTALL_PREFIX}/Marble.app/Contents) #SET (lib_dir ${CMAKE_INSTALL_PREFIX}/Marble.app/Contents/MacOS/lib) SET (data_dir ${CMAKE_INSTALL_PREFIX}/Marble.app/Contents/MacOS/resources/data) set(locale_dir "${data_dir}/locale") SET (plugin_dir ${CMAKE_INSTALL_PREFIX}/Marble.app/Contents/MacOS/resources/plugins) elseif(CMAKE_SYSTEM_NAME STREQUAL Android) set(plugin_dir "${CMAKE_INSTALL_PREFIX}/assets/plugins") set(data_dir "${CMAKE_INSTALL_PREFIX}/assets/data") set(locale_dir "${data_dir}/locale") else() # Linux / bsd etc... set(data_dir ${CMAKE_INSTALL_FULL_DATAROOTDIR}/marble/data) set(locale_dir "${CMAKE_INSTALL_FULL_DATAROOTDIR}/locale") set(plugin_dir ${CMAKE_INSTALL_FULL_LIBDIR}/marble/plugins) endif() if(NOT ICON_INSTALL_DIR) set(ICON_INSTALL_DIR ${CMAKE_INSTALL_FULL_DATAROOTDIR}/icons) endif(NOT ICON_INSTALL_DIR) if(NOT APPS_INSTALL_DIR) set(APPS_INSTALL_DIR ${CMAKE_INSTALL_FULL_DATAROOTDIR}/applications) endif(NOT APPS_INSTALL_DIR) if(NOT INCLUDE_INSTALL_DIR) set(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include") endif() if (NOT MARBLE_DATA_PATH) set (MARBLE_DATA_PATH ${data_dir}) endif (NOT MARBLE_DATA_PATH) if (NOT MARBLE_PLUGIN_PATH) set (MARBLE_PLUGIN_PATH ${plugin_dir}) endif (NOT MARBLE_PLUGIN_PATH) if (NOT MARBLE_DATA_INSTALL_PATH) set (MARBLE_DATA_INSTALL_PATH ${MARBLE_DATA_PATH}) endif (NOT MARBLE_DATA_INSTALL_PATH) if (NOT MARBLE_PLUGIN_INSTALL_PATH) set (MARBLE_PLUGIN_INSTALL_PATH ${MARBLE_PLUGIN_PATH}) endif (NOT MARBLE_PLUGIN_INSTALL_PATH) #MESSAGE( STATUS, "MARBLE_PLUGIN_INSTALL_PATH: ${MARBLE_PLUGIN_INSTALL_PATH}" ) if(WIN32) set (STATIC_BUILD FALSE CACHE BOOL "Link to static Qt libs (win32 only)?") endif(WIN32) add_definitions( -DQT_USE_QSTRINGBUILDER -DQT_NO_SIGNALS_SLOTS_KEYWORDS -DQT_NO_URL_CAST_FROM_STRING -DQT_NO_CAST_TO_ASCII -DQT_NO_CAST_FROM_BYTEARRAY -DQT_STRICT_ITERATORS -DQT_DISABLE_DEPRECATED_BEFORE=0x050700 ) #################################################### # Options for static build if(STATIC_BUILD) add_definitions(-DSTATIC_BUILD=1) endif(STATIC_BUILD) ############################################################# if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_C_COMPILER MATCHES "icc") # Its good programming practice to build with no warnings... add_definitions( -Wall -Wextra -Wundef -Wnon-virtual-dtor -Woverloaded-virtual -Wno-long-long -Wchar-subscripts -Wcast-align -Wpointer-arith -Wformat-security ) # In pedantic mode, treat warnings as errors if (PEDANTIC) add_definitions( -Werror ) endif (PEDANTIC) endif (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_C_COMPILER MATCHES "icc") ############################################################# # Add a compiler def so that we can conditionally compile # code in debug mode only (e.g. extra console messages) IF (CMAKE_BUILD_TYPE MATCHES Debug) IF(NOT MINGW) ADD_DEFINITIONS(-DDEBUG) ELSE(NOT MINGW) REMOVE_DEFINITIONS( -DQT_NO_DEBUG ) ENDIF(NOT MINGW) ENDIF (CMAKE_BUILD_TYPE MATCHES Debug) #################################################### # on Win32 set the debug postfix if(WIN32) # distinguish between debug and release plugin SET(CMAKE_DEBUG_POSTFIX "d") endif(WIN32) #################################################### #################################################### # Add global ECM & KF5 settings set(REQUIRED_ECM_VERSION 1.7.0) set(KDE_INSTALL_DIRS_NO_DEPRECATED TRUE) set(KDE_SKIP_UNINSTALL_TARGET ON CACHE BOOL "KDE uninstall target must be disabled") set(REQUIRED_KF5_VERSION 5.7.0) #################################################### # Add the include directories include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/projections ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/geodata ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/geodata/data ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/geodata/graphicsitem ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/geodata/handlers/dgml ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/geodata/parser ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/geodata/writer ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/geodata/scene ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/graphicsview ${CMAKE_CURRENT_BINARY_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/src/lib/marble ) #################################################### # Descend into subdirectories add_subdirectory(doc) add_subdirectory(src) add_subdirectory(data) include(DistTarget) add_subdirectory(tests) option(BUILD_MARBLE_TOOLS "Build various tools related to Marble" OFF) add_feature_info("Marble tools" BUILD_MARBLE_TOOLS "Build various Marble tools for e.g. file format conversion. Toggle with BUILD_MARBLE_TOOLS=YES/NO.") if(BUILD_MARBLE_TOOLS) add_subdirectory(tools) endif() option(BUILD_MARBLE_EXAMPLES "Build C++ examples showing how to use the Marble library" OFF) add_feature_info("Marble library C++ examples" BUILD_MARBLE_EXAMPLES "Build C++ examples showing how to use the Marble library. Toggle with BUILD_MARBLE_EXAMPLES=YES/NO.") if(BUILD_MARBLE_EXAMPLES) add_subdirectory(examples/cpp) endif() #################################################### # Handle translation catalogs of KDE Application release tarball of marble # (for custom bundle translation handling see data/lang/README) # KDE Application release tarballs have the respective po files added on tarball creation, # which are otherwise stored and edited separately on the KDE svn servers. # Toplevel subdir "poqm/" holds all the po files which should be processed and installed as qm files marble_install_po_files_as_qm(poqm) # Toplevel subdir "po/" holds all the po files which should be processed and installed as mo files # Those are used by app and plugin code building against KI18n. # So the respective macro ki18n_install can be used. # Likewise, it contains the translated user documentation, which is handled by kdoctools_install. # Just, the macros are not available here in the toplevel CMakeLists.txt file. # As a temporary hack (your task to improve it, dear reader :) ) the macros # are called only from src/apps/marble-kde/CMakeLists.txt. # That should catch 99.9 % cases of builds from released tarball, where all the # KF5-dependant apps and plugins will be built and installed together. # Currently these are: # src/apps/marble-kde # src/plasmarunner # src/plasma/applets/worldclock # src/plasma/wallpapers/worldmap # # Let releaseme know about this: # SKIP_PO_INSTALL #################################################### # Install extra files install(FILES LICENSE.txt DESTINATION ${MARBLE_DATA_INSTALL_PATH}) ############################################################ # Uninstall stuff CONFIGURE_FILE( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") include(MarbleCPackOptions) marble_feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES) diff --git a/src/apps/behaim/CMakeLists.txt b/src/apps/behaim/CMakeLists.txt index b8ad26c43..bbed8a9dc 100644 --- a/src/apps/behaim/CMakeLists.txt +++ b/src/apps/behaim/CMakeLists.txt @@ -1,77 +1,79 @@ set(marble_SRCS main.cpp) qt5_add_resources(marble_QRCS MarbleBehaim.qrc) include_directories(${CMAKE_CURRENT_BINARY_DIR}) if (CMAKE_SYSTEM_NAME STREQUAL Android) set(TARGET MarbleBehaim) find_package(Qt5 ${REQUIRED_QT_VERSION} REQUIRED COMPONENTS AndroidExtras) add_library (${TARGET} SHARED ${marble_SRCS} ${marble_QRCS}) # while not directly linked, need to be listed here to have deployqt pick up those libs target_link_libraries ( ${TARGET} marblewidget astro Qt5::Concurrent Qt5::Xml Qt5::Widgets Qt5::PrintSupport Qt5::Network Qt5::Sql Qt5::Svg Qt5::Positioning Qt5::AndroidExtras Qt5::Multimedia + Qt5::WebEngineWidgets + Qt5::WebEngine ) else() set(TARGET marble-behaim) add_executable (${TARGET} ${marble_SRCS} ${marble_QRCS}) endif() target_link_libraries ( ${TARGET} marbledeclarative ) FILE(GLOB QML_FILES *.qml) add_custom_target(marble-behaim_resources ALL SOURCES ${QML_FILES} package/AndroidManifest.xml) if (CMAKE_SYSTEM_NAME STREQUAL Android) install(DIRECTORY "../../../data/android/" DESTINATION "${CMAKE_INSTALL_PREFIX}/res") set(ABSOLUTE_INSTALL_PATH "${CMAKE_INSTALL_PREFIX}") if(NOT IS_ABSOLUTE "${ABSOLUTE_INSTALL_PATH}") set(ABSOLUTE_INSTALL_PATH "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_PREFIX}") endif() get_filename_component(ABSOLUTE_INSTALL_PATH "${ABSOLUTE_INSTALL_PATH}" ABSOLUTE) get_filename_component(QT_ANDROID_QT_ROOT "${Qt5Core_DIR}/../../.." ABSOLUTE) set(ANDROID_SDK_ROOT $ENV{ANDROID_SDK_ROOT}) set(ANDROID_NDK_ROOT $ENV{ANDROID_NDK_ROOT}) set(QT_ANDROID_APP_PATH "${ABSOLUTE_INSTALL_PATH}/libs/${ANDROID_ABI}/libMarbleBehaim.so") set(QT_ANDROID_APP_EXTRA_LIBS "${ABSOLUTE_INSTALL_PATH}/lib/libastro.so,${ABSOLUTE_INSTALL_PATH}/lib/libmarblewidget-qt5.so,${ABSOLUTE_INSTALL_PATH}/lib/libmarbledeclarative.so") set(QML_ROOT_PATH "${ABSOLUTE_INSTALL_PATH}/") set(QT_ANDROID_APP_EXTRA_PLUGINS "${ABSOLUTE_INSTALL_PATH}//share,${ABSOLUTE_INSTALL_PATH}//lib/qml") set(QT_ANDROID_APP_PACKAGE_SOURCE_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/package") set(QT_ANDROID_APP_PACKAGE_NAME "org.kde.marble.behaim") set(QT_ANDROID_APP_NAME "Marble Globe: Behaim's Erdapfel") configure_file(package/deploy-behaim.json.in ${CMAKE_CURRENT_BINARY_DIR}/deploy-behaim.json @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/deploy-behaim.json DESTINATION "${CMAKE_INSTALL_PREFIX}/share") install(TARGETS ${TARGET} LIBRARY DESTINATION libs/${ANDROID_ABI}) if (TARGET create-apk-MarbleBehaim) set(PACKAGE_DIR "${CMAKE_BINARY_DIR}/MarbleBehaim_projects/") set_target_properties(create-apk-MarbleBehaim PROPERTIES ANDROID_APK_DIR "${PACKAGE_DIR}") add_custom_target(marblebehaim-move-metadata ALL COMMAND cmake -E echo "Moving MarbleBehaim shared Android resources" COMMAND cmake -E remove_directory "${PACKAGE_DIR}" COMMAND cmake -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/package" "${PACKAGE_DIR}" COMMAND cmake -E copy_directory "${CMAKE_SOURCE_DIR}/data/android/" "${PACKAGE_DIR}/res" ) add_dependencies(create-apk-MarbleBehaim marblebehaim-move-metadata) endif() else() if(MARBLE_INSTALL_ANDROID_APPS) install(TARGETS ${TARGET} RUNTIME DESTINATION bin) endif() endif() diff --git a/src/apps/marble-maps/CMakeLists.txt b/src/apps/marble-maps/CMakeLists.txt index 14be2c0f2..a52818ca6 100644 --- a/src/apps/marble-maps/CMakeLists.txt +++ b/src/apps/marble-maps/CMakeLists.txt @@ -1,84 +1,86 @@ set(marble_SRCS main.cpp MarbleMaps.cpp TextToSpeechClient.cpp) qt5_add_resources(marble_QRCS MarbleMaps.qrc) include_directories(${CMAKE_CURRENT_BINARY_DIR}) if (CMAKE_SYSTEM_NAME STREQUAL Android) set(TARGET Marble) find_package(Qt5 ${REQUIRED_QT_VERSION} REQUIRED COMPONENTS AndroidExtras QuickControls2 ) add_library (${TARGET} SHARED ${marble_SRCS} ${marble_QRCS}) # while not directly linked, need to be listed here to have deployqt pick up those libs target_link_libraries ( ${TARGET} marblewidget astro Qt5::Concurrent Qt5::Xml Qt5::Widgets Qt5::PrintSupport Qt5::Network Qt5::Sql Qt5::Svg Qt5::Positioning Qt5::AndroidExtras Qt5::Multimedia Qt5::QuickControls2 + Qt5::WebEngineWidgets + Qt5::WebEngine ) else() set(TARGET marble-maps) add_executable (${TARGET} ${marble_SRCS} ${marble_QRCS}) endif() target_link_libraries ( ${TARGET} marbledeclarative ) FILE(GLOB QML_FILES *.qml) add_custom_target(marble-maps_resources ALL SOURCES ${QML_FILES} package/AndroidManifest.xml) if (CMAKE_SYSTEM_NAME STREQUAL Android) install(DIRECTORY "../../../data/android/" DESTINATION "${CMAKE_INSTALL_PREFIX}/res") set(ABSOLUTE_INSTALL_PATH "${CMAKE_INSTALL_PREFIX}") if(NOT IS_ABSOLUTE "${ABSOLUTE_INSTALL_PATH}") set(ABSOLUTE_INSTALL_PATH "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_PREFIX}") endif() get_filename_component(ABSOLUTE_INSTALL_PATH "${ABSOLUTE_INSTALL_PATH}" ABSOLUTE) get_filename_component(QT_ANDROID_QT_ROOT "${Qt5Core_DIR}/../../.." ABSOLUTE) set(ANDROID_SDK_ROOT $ENV{ANDROID_SDK_ROOT}) set(ANDROID_NDK_ROOT $ENV{ANDROID_NDK_ROOT}) set(QT_ANDROID_APP_PATH "${ABSOLUTE_INSTALL_PATH}/libs/${ANDROID_ABI}/libMarble.so") set(QT_ANDROID_APP_EXTRA_LIBS "${ABSOLUTE_INSTALL_PATH}/lib/libastro.so,${ABSOLUTE_INSTALL_PATH}/lib/libmarblewidget-qt5.so,${ABSOLUTE_INSTALL_PATH}/lib/libmarbledeclarative.so") set(QT_ANDROID_APP_PACKAGE_SOURCE_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/package") set(QT_ANDROID_APP_PACKAGE_NAME "org.kde.marble.maps") set(QT_ANDROID_APP_NAME "Marble Maps") set(QT_ANDROID_APP_EXTRA_PLUGINS "${ABSOLUTE_INSTALL_PATH}//share,${ABSOLUTE_INSTALL_PATH}//lib/qml") configure_file(package/deploy-marble-maps.json.in ${CMAKE_CURRENT_BINARY_DIR}/deploy-marble-maps.json @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/deploy-marble-maps.json DESTINATION "${CMAKE_INSTALL_PREFIX}/share") install(TARGETS ${TARGET} LIBRARY DESTINATION libs/${ANDROID_ABI}) if (TARGET create-apk-Marble) set(PACKAGE_DIR "${CMAKE_BINARY_DIR}/Marble_projects/") set_target_properties(create-apk-Marble PROPERTIES ANDROID_APK_DIR "${PACKAGE_DIR}") add_custom_target(marble-move-metadata ALL COMMAND cmake -E echo "Moving Marble shared Android resources" COMMAND cmake -E remove_directory "${PACKAGE_DIR}" COMMAND cmake -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/package" "${PACKAGE_DIR}" COMMAND cmake -E copy_directory "${CMAKE_SOURCE_DIR}/data/android/" "${PACKAGE_DIR}/res" ) add_dependencies(create-apk-Marble marble-move-metadata) endif() else() if(MARBLE_INSTALL_ANDROID_APPS) if(APPS_INSTALL_DIR) install(PROGRAMS org.kde.marble.maps.desktop DESTINATION ${APPS_INSTALL_DIR}) endif(APPS_INSTALL_DIR) install(TARGETS ${TARGET} RUNTIME DESTINATION bin) endif() endif() diff --git a/src/lib/marble/CMakeLists.txt b/src/lib/marble/CMakeLists.txt index 3f1afa7e0..64d0ceca4 100644 --- a/src/lib/marble/CMakeLists.txt +++ b/src/lib/marble/CMakeLists.txt @@ -1,748 +1,749 @@ PROJECT(marblewidget) macro_optional_find_package(Phonon4Qt5 QUIET) marble_set_package_properties( Phonon4Qt5 PROPERTIES DESCRIPTION "Qt-based audio library" URL "https://phonon.kde.org/" PURPOSE "Support for playback of soundcue elements" TYPE OPTIONAL ) if(Phonon4Qt5_FOUND) set(HAVE_PHONON TRUE) endif() CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/config-phonon.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-phonon.h) INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/projections ${CMAKE_CURRENT_SOURCE_DIR}/routing ${CMAKE_CURRENT_SOURCE_DIR}/geodata ${CMAKE_CURRENT_SOURCE_DIR}/geodata/data ${CMAKE_CURRENT_SOURCE_DIR}/geodata/graphicsitem ${CMAKE_CURRENT_SOURCE_DIR}/geodata/scene ${CMAKE_CURRENT_SOURCE_DIR}/geodata/handlers ${CMAKE_CURRENT_SOURCE_DIR}/geodata/handlers/kml ${CMAKE_CURRENT_SOURCE_DIR}/geodata/handlers/dgml ${CMAKE_CURRENT_SOURCE_DIR}/geodata/parser ${CMAKE_CURRENT_SOURCE_DIR}/graphicsview ${CMAKE_CURRENT_SOURCE_DIR}/layers ${CMAKE_CURRENT_SOURCE_DIR}/osm ${CMAKE_CURRENT_SOURCE_DIR}/cloudsync ${CMAKE_SOURCE_DIR}/src/lib/astro ${ZLIB_INCLUDE_DIRS} ) INCLUDE(geodata/CMakeLists.txt) INCLUDE(graphicsview/CMakeLists.txt) INCLUDE(layers/CMakeLists.txt) INCLUDE(osm/CMakeLists.txt) set(MARBLE_LIB_VERSION_MAJOR "0") set(MARBLE_LIB_VERSION_MINOR "28") set(MARBLE_LIB_VERSION_PATCH "0") set(MARBLE_LIB_VERSION "${MARBLE_LIB_VERSION_MAJOR}.${MARBLE_LIB_VERSION_MINOR}.${MARBLE_LIB_VERSION_PATCH}") set(MARBLE_ABI_VERSION "28") ########### next target ############### if(MARBLE_NO_WEBKITWIDGETS) add_definitions(-DMARBLE_NO_WEBKITWIDGETS) endif() set(marblewidget_SRCS ${geodata_SRCS} ${graphicsview_SRCS} ${layers_SRCS} ${osm_SRCS} blendings/Blending.cpp blendings/BlendingAlgorithms.cpp blendings/BlendingFactory.cpp blendings/SunLightBlending.cpp DownloadRegion.cpp DownloadRegionDialog.cpp LatLonBoxWidget.cpp MarbleWidget.cpp MarbleAbstractPresenter.cpp MarbleModel.cpp MarbleMap.cpp MarbleColors.cpp MapViewWidget.cpp CelestialSortFilterProxyModel.cpp FileViewWidget.cpp TourWidget.cpp FlyToEditWidget.cpp TourControlEditWidget.cpp WaitEditWidget.cpp SoundCueEditWidget.cpp RemoveItemEditWidget.cpp TourItemDelegate.cpp MapViewItemDelegate.cpp TourPlayback.cpp LegendWidget.cpp PlaybackItem.cpp PlaybackAnimatedUpdateItem.cpp PlaybackFlyToItem.cpp PlaybackSoundCueItem.cpp PlaybackTourControlItem.cpp PlaybackWaitItem.cpp SerialTrack.cpp SoundTrack.cpp AnimatedUpdateTrack.cpp CurrentLocationWidget.cpp MarbleNavigator.cpp MarbleLegendBrowser.cpp MarbleAboutDialog.cpp MarbleInputHandler.cpp MarbleWidgetInputHandler.cpp MarbleWidgetPopupMenu.cpp MarblePlacemarkModel.cpp GeoDataTreeModel.cpp GeoUriParser.cpp kdescendantsproxymodel.cpp BranchFilterProxyModel.cpp TreeViewDecoratorModel.cpp MarbleDebug.cpp Tile.cpp TextureTile.cpp TileCoordsPyramid.cpp TileLevelRangeWidget.cpp TileLoader.cpp QtMarbleConfigDialog.cpp ClipPainter.cpp DownloadPolicy.cpp DownloadQueueSet.cpp GeoPainter.cpp HttpDownloadManager.cpp HttpJob.cpp RemoteIconLoader.cpp LayerManager.cpp PluginManager.cpp TimeControlWidget.cpp AbstractFloatItem.cpp PopupItem.cpp MarbleGlobal.cpp MarbleDirs.cpp MarbleLocale.cpp MarblePhysics.cpp TileCreatorDialog.cpp MapThemeManager.cpp ViewportParams.cpp ViewParams.cpp projections/AbstractProjection.cpp projections/CylindricalProjection.cpp projections/AzimuthalProjection.cpp projections/SphericalProjection.cpp projections/EquirectProjection.cpp projections/MercatorProjection.cpp projections/GnomonicProjection.cpp projections/StereographicProjection.cpp projections/LambertAzimuthalProjection.cpp projections/AzimuthalEquidistantProjection.cpp projections/VerticalPerspectiveProjection.cpp VisiblePlacemark.cpp PlacemarkLayout.cpp Planet.cpp PlanetFactory.cpp Quaternion.cpp TextureColorizer.cpp TextureMapperInterface.cpp ScanlineTextureMapperContext.cpp SphericalScanlineTextureMapper.cpp EquirectScanlineTextureMapper.cpp MercatorScanlineTextureMapper.cpp TileScalingTextureMapper.cpp GenericScanlineTextureMapper.cpp VectorTileModel.cpp DiscCache.cpp ServerLayout.cpp StoragePolicy.cpp CacheStoragePolicy.cpp FileStoragePolicy.cpp FileStorageWatcher.cpp StackedTile.cpp TileId.cpp StackedTileLoader.cpp TileLoaderHelper.cpp TileCreator.cpp #jsonparser.cpp FileLoader.cpp FileManager.cpp PositionTracking.cpp DataMigration.cpp ImageF.cpp MovieCapture.cpp MovieCaptureDialog.cpp TourCaptureDialog.cpp EditPlacemarkDialog.cpp AddLinkDialog.cpp FormattedTextWidget.cpp AbstractDataPlugin.cpp AbstractDataPluginModel.cpp AbstractDataPluginItem.cpp AbstractWorkerThread.cpp PluginInterface.cpp DialogConfigurationInterface.cpp LayerInterface.cpp RenderState.cpp RenderPlugin.cpp RenderPluginInterface.cpp PositionProviderPlugin.cpp PositionProviderPluginInterface.cpp PlacemarkPositionProviderPlugin.cpp RouteSimulationPositionProviderPlugin.cpp MarblePluginSettingsWidget.cpp RenderPluginModel.cpp PluginAboutDialog.cpp PluginItemDelegate.cpp SunLocator.cpp MarbleClock.cpp SunControlWidget.cpp MergedLayerDecorator.cpp MathHelper.cpp LatLonEdit.cpp PlacemarkEditHeader.cpp MapThemeSortFilterProxyModel.cpp TemplateDocument.cpp routing/AlternativeRoutesModel.cpp routing/Maneuver.cpp routing/Route.cpp routing/RouteRequest.cpp routing/RouteSegment.cpp routing/RoutingModel.cpp routing/RoutingProfile.cpp routing/RoutingManager.cpp routing/RoutingLayer.cpp routing/RoutingInputWidget.cpp routing/RoutingWidget.cpp routing/RoutingProfilesWidget.cpp routing/RoutingProfilesModel.cpp routing/RoutingProfileSettingsDialog.cpp routing/SpeakersModel.cpp routing/VoiceNavigationModel.cpp routing/instructions/InstructionTransformation.cpp routing/instructions/RoutingInstruction.cpp routing/instructions/RoutingPoint.cpp routing/instructions/RoutingWaypoint.cpp routing/instructions/WaypointParser.cpp ParsingRunnerManager.cpp ReverseGeocodingRunnerManager.cpp RoutingRunnerManager.cpp SearchRunnerManager.cpp AutoNavigation.cpp SearchRunnerPlugin.cpp ReverseGeocodingRunnerPlugin.cpp RoutingRunnerPlugin.cpp ParseRunnerPlugin.cpp SearchRunner.cpp ReverseGeocodingRunner.cpp RoutingRunner.cpp ParsingRunner.cpp RunnerTask.cpp BookmarkManager.cpp EditBookmarkDialog.cpp BookmarkManagerDialog.cpp NewBookmarkFolderDialog.cpp PrintOptionsWidget.cpp ExternalEditorDialog.cpp GoToDialog.cpp MapWizard.cpp MapThemeDownloadDialog.cpp GeoGraphicsScene.cpp ElevationModel.cpp MarbleLineEdit.cpp SearchInputWidget.cpp SearchWidget.cpp kineticmodel.cpp NewstuffModel.cpp MarbleZip.cpp OsmcSymbol.cpp StyleBuilder.cpp cloudsync/CloudSyncManager.cpp cloudsync/RouteSyncManager.cpp cloudsync/OwncloudSyncBackend.cpp cloudsync/CloudRouteModel.cpp cloudsync/CloudRoutesDialog.cpp cloudsync/RouteItem.cpp cloudsync/RouteItemDelegate.cpp cloudsync/BookmarkSyncManager.cpp cloudsync/MergeItem.cpp cloudsync/ConflictDialog.cpp ) if (MARBLE_NO_WEBKITWIDGETS) LIST(APPEND marblewidget_SRCS NullMarbleWebView.cpp NullTinyWebBrowser.cpp ) else() LIST(APPEND marblewidget_SRCS MarbleWebView.cpp TinyWebBrowser.cpp ) endif() if (NOT MARBLE_NO_DBUS) LIST(APPEND marblewidget_SRCS MarbleDBusInterface.cpp ) endif() set (marblewidget_UI ${osm_UIS} LatLonBoxWidget.ui MapViewWidget.ui CurrentLocationWidget.ui FileViewWidget.ui TourWidget.ui MarbleNavigator.ui MarbleCacheSettingsWidget.ui MarbleViewSettingsWidget.ui MarbleNavigationSettingsWidget.ui TimeControlWidget.ui MarbleTimeSettingsWidget.ui MarblePluginSettingsWidget.ui TileCreatorDialog.ui TileLevelRangeWidget.ui MarbleAboutDialog.ui SunControlWidget.ui LatLonEdit.ui PlacemarkEditHeader.ui routing/RoutingWidget.ui DataMigrationWidget.ui EditBookmarkDialog.ui BookmarkManagerDialog.ui NewBookmarkFolderDialog.ui PrintOptions.ui ExternalEditor.ui GoToDialog.ui routing/RoutingSettingsWidget.ui routing/RoutingProfileSettingsDialog.ui MapWizard.ui MapThemeDownloadDialog.ui cloudsync/CloudRoutesDialog.ui MarbleCloudSyncSettingsWidget.ui MovieCaptureDialog.ui TourCaptureDialog.ui EditPlacemarkDialog.ui AddLinkDialog.ui FormattedTextWidget.ui ElevationWidget.ui ) if (MARBLE_NO_WEBKITWIDGETS) LIST(APPEND marblewidget_UI NullLegendWidget.ui NullWebPopupWidget.ui ) else() LIST(APPEND marblewidget_UI LegendWidget.ui WebPopupWidget.ui ) endif() # FIXME: cleaner approach of src/lib/marblwidget/MarbleControlBox.* vs. marble.qrc qt_add_resources(marblewidget_SRCS libmarble.qrc ../../apps/marble-ui/marble.qrc) qt_wrap_ui(marblewidget_SRCS ${marblewidget_UI}) add_library(marblewidget SHARED ${marblewidget_SRCS} ${SOURCES_UI_HDRS}) generate_export_header(marblewidget BASE_NAME marble) # TODO: use PUBLIC/PRIVATE everywhere instead of LINK_PUBLIC/LINK_PRIVATE # once SailfishOS has cmake >= 2.8.12 # link with libastro target_link_libraries(marblewidget LINK_PRIVATE astro) # link against zlib target_link_libraries(marblewidget LINK_PRIVATE ${ZLIB_LIBRARIES}) # link with release version of Qt libs target_link_libraries(marblewidget LINK_PUBLIC Qt5::Xml Qt5::Gui Qt5::Widgets Qt5::Network LINK_PRIVATE Qt5::Svg Qt5::PrintSupport Qt5::Concurrent ) if (NOT MARBLE_NO_WEBKITWIDGETS) target_link_libraries(marblewidget LINK_PUBLIC - Qt5::WebKitWidgets + Qt5::WebEngineWidgets + Qt5::WebEngine ) endif () if (NOT MARBLE_NO_DBUS) target_link_libraries(marblewidget LINK_PRIVATE Qt5::DBus ) endif () if (Phonon4Qt5_FOUND) target_link_libraries(marblewidget LINK_PRIVATE Phonon::phonon4qt5 ) endif() if (APPLE) # TODO: PUBLIC or can be PRIVATE? #defined in top level makefile target_link_libraries(marblewidget LINK_PUBLIC ${MAC_EXTRA_LIBS} ) endif (APPLE) # TODO: still supported? if (CMAKE_SYSTEM_NAME MATCHES "SunOS") target_link_libraries(marblewidget LINK_PUBLIC m) endif (CMAKE_SYSTEM_NAME MATCHES "SunOS") if(WIN32) # TODO: PUBLIC or can be PRIVATE? target_link_libraries(marblewidget LINK_PUBLIC ws2_32 imm32 winmm) endif(WIN32) set_target_properties(marblewidget PROPERTIES EXPORT_NAME "Marble" OUTPUT_NAME marblewidget-qt5 COMPILE_FLAGS "-DKML_LAZY_IMP" ) if (NOT (CMAKE_SYSTEM_NAME STREQUAL Android)) set_target_properties(marblewidget PROPERTIES VERSION ${MARBLE_LIB_VERSION} SOVERSION ${MARBLE_ABI_VERSION} ) endif() target_include_directories(marblewidget INTERFACE "$" ) # choose the correct target install library path if(WIN32) install(TARGETS marblewidget EXPORT MarbleTargets RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX} ARCHIVE DESTINATION lib) elseif(APPLE) install(TARGETS marblewidget LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/Marble.app/Contents/MacOS/lib) else() install(TARGETS marblewidget EXPORT MarbleTargets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() ########### install headers & cmake config files ############### if (APPLE) # TODO: find how to install & deploy library, headers and config files as bundle for development return() endif() if (MARBLE_NO_WEBKITWIDGETS) set(marble_WebKit NullMarbleWebView.h NullTinyWebBrowser.h ) else() set(marble_WebKit MarbleWebView.h TinyWebBrowser.h ) endif() install( FILES ${CMAKE_CURRENT_BINARY_DIR}/marble_export.h ${graphicsview_HDRS} ${marble_WebKit} AutoNavigation.h BookmarkManager.h DownloadRegion.h DownloadRegionDialog.h LatLonBoxWidget.h MarbleWidget.h MarbleMap.h MarbleModel.h MapViewWidget.h CelestialSortFilterProxyModel.h LegendWidget.h FileViewWidget.h TourWidget.h FlyToEditWidget.h TourControlEditWidget.h WaitEditWidget.h SoundCueEditWidget.h RemoveItemEditWidget.h TourItemDelegate.h MapViewItemDelegate.h TourPlayback.h CurrentLocationWidget.h MarbleNavigator.h AbstractFloatItem.h MapThemeManager.h MarbleAboutDialog.h MarbleInputHandler.h MarbleWidgetInputHandler.h MarbleWidgetPopupMenu.h TileId.h TileCoordsPyramid.h TileLevelRangeWidget.h QtMarbleConfigDialog.h MarbleMath.h MarbleColors.h MarbleGlobal.h MarbleLocale.h MarbleDebug.h MarbleDirs.h GeoPainter.h HttpDownloadManager.h TileCreatorDialog.h ViewportParams.h projections/AbstractProjection.h PositionTracking.h Quaternion.h SunLocator.h ClipPainter.h GeoGraphicsScene.h GeoDataTreeModel.h geodata/data/GeoDataAbstractView.h geodata/data/GeoDataAccuracy.h geodata/data/GeoDataBalloonStyle.h geodata/data/GeoDataColorStyle.h geodata/data/GeoDataContainer.h geodata/data/GeoDataCoordinates.h geodata/data/GeoDataDocument.h geodata/data/GeoDataFeature.h geodata/data/GeoDataFolder.h geodata/data/GeoDataGeometry.h geodata/data/GeoDataGroundOverlay.h geodata/data/GeoDataHotSpot.h geodata/data/GeoDataIconStyle.h geodata/data/GeoDataItemIcon.h geodata/data/GeoDataLabelStyle.h geodata/data/GeoDataLatLonAltBox.h geodata/data/GeoDataLatLonBox.h geodata/data/GeoDataLatLonQuad.h geodata/data/GeoDataLinearRing.h geodata/data/GeoDataLineString.h geodata/data/GeoDataLineStyle.h geodata/data/GeoDataListStyle.h geodata/data/GeoDataLod.h geodata/data/GeoDataLookAt.h geodata/data/GeoDataOverlay.h geodata/data/GeoDataMultiGeometry.h geodata/data/GeoDataObject.h geodata/data/GeoDataPlacemark.h geodata/data/GeoDataPoint.h geodata/data/GeoDataPolygon.h geodata/data/GeoDataPolyStyle.h geodata/data/GeoDataRegion.h geodata/data/GeoDataRelation.h geodata/data/GeoDataSnippet.h geodata/data/GeoDataStyle.h geodata/data/GeoDataStyleMap.h geodata/data/GeoDataStyleSelector.h geodata/data/GeoDataTrack.h geodata/data/GeoDataTimeSpan.h geodata/data/GeoDataTimeStamp.h geodata/data/GeoDataTimePrimitive.h geodata/data/Serializable.h geodata/geodata_export.h geodata/parser/GeoDocument.h geodata/parser/GeoDataTypes.h geodata/writer/GeoWriter.h routing/RoutingWidget.h routing/RoutingManager.h TileCreator.h PluginManager.h PluginInterface.h DialogConfigurationInterface.h PositionProviderPlugin.h PositionProviderPluginInterface.h RenderPlugin.h RenderPluginInterface.h ParsingRunnerManager.h ReverseGeocodingRunnerManager.h RoutingRunnerManager.h SearchRunnerManager.h ParsingRunner.h SearchRunner.h ReverseGeocodingRunner.h RoutingRunner.h SearchRunnerPlugin.h ReverseGeocodingRunnerPlugin.h RoutingRunnerPlugin.h ParseRunnerPlugin.h LayerInterface.h RenderState.h PluginAboutDialog.h Planet.h PlanetFactory.h EditPlacemarkDialog.h AddLinkDialog.h FormattedTextWidget.h AbstractDataPlugin.h AbstractDataPluginModel.h AbstractDataPluginItem.h AbstractWorkerThread.h LatLonEdit.h PlacemarkEditHeader.h MapWizard.h MapThemeDownloadDialog.h ElevationModel.h routing/AlternativeRoutesModel.h routing/Route.h routing/Maneuver.h routing/RouteRequest.h routing/RouteSegment.h routing/RoutingManager.h routing/RoutingModel.h routing/RoutingProfile.h OsmcSymbol.h DESTINATION ${INCLUDE_INSTALL_DIR}/marble ) ########### CMake Config files ############### include(CMakePackageConfigHelpers) set(MARBLE_CMAKECONFIGNAME Marble) set(MARBLE_INSTALL_CMAKECONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${MARBLE_CMAKECONFIGNAME}) configure_package_config_file(MarbleConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${MARBLE_CMAKECONFIGNAME}Config.cmake INSTALL_DESTINATION ${MARBLE_INSTALL_CMAKECONFIGDIR} ) write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/${MARBLE_CMAKECONFIGNAME}ConfigVersion.cmake VERSION ${MARBLE_LIB_VERSION} COMPATIBILITY SameMajorVersion ) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${MARBLE_CMAKECONFIGNAME}Config.cmake ${CMAKE_CURRENT_BINARY_DIR}/${MARBLE_CMAKECONFIGNAME}ConfigVersion.cmake DESTINATION ${MARBLE_INSTALL_CMAKECONFIGDIR} ) install( EXPORT MarbleTargets FILE ${MARBLE_CMAKECONFIGNAME}Targets.cmake DESTINATION ${MARBLE_INSTALL_CMAKECONFIGDIR} ) ########### Qt Pri file ############### # Where the pri file is installed is defined by the following rules, with decreasing priority: # * MARBLE_PRI_INSTALL_USE_QT_SYS_PATHS=TRUE: # pri file will be installed with the dirs of the Qt installation used # * MARBLE_PRI_INSTALL_DIR=some-relative-or-absolute-path # if set will be used as given # * installation prefix = Qt installation prefix: # pri file will be installed with the dirs of the Qt installation used # * otherwise: # pri file will be installed in mkspecs/modules in the installation prefix get_target_property(PRI_LIB_NAME marblewidget OUTPUT_NAME) set(PRI_ABS_INCLUDE_INSTALL_DIR "${INCLUDE_INSTALL_DIR}") if(NOT IS_ABSOLUTE "${PRI_ABS_INCLUDE_INSTALL_DIR}") set(PRI_ABS_INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${PRI_ABS_INCLUDE_INSTALL_DIR}") endif() set(PRI_ABS_LIB_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}") if(NOT IS_ABSOLUTE "${PRI_ABS_LIB_INSTALL_DIR}") set(PRI_ABS_LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${PRI_ABS_LIB_INSTALL_DIR}") endif() set(PRI_DEPS "xml gui widgets network") if (NOT MARBLE_NO_WEBKITWIDGETS) set(PRI_DEPS "${PRI_DEPS} webkitwidgets") endif() file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/qt_Marble.pri CONTENT "QT.Marble.VERSION = ${MARBLE_LIB_VERSION} QT.Marble.MAJOR_VERSION = ${MARBLE_LIB_VERSION_MAJOR} QT.Marble.MINOR_VERSION = ${MARBLE_LIB_VERSION_MINOR} QT.Marble.PATCH_VERSION = ${MARBLE_LIB_VERSION_PATCH} QT.Marble.name = ${PRI_LIB_NAME} QT.Marble.defines = QT.Marble.includes = ${PRI_ABS_INCLUDE_INSTALL_DIR} QT.Marble.private_includes = QT.Marble.libs = ${PRI_ABS_LIB_INSTALL_DIR} QT.Marble.depends = ${PRI_DEPS} " ) # detect which folder the pri file should be installed into get_target_property(QMAKE_EXECUTABLE Qt5::qmake LOCATION) function(query_qmake result_variable qt_variable) execute_process( COMMAND ${QMAKE_EXECUTABLE} -query "${qt_variable}" RESULT_VARIABLE return_code OUTPUT_VARIABLE output ) if(return_code EQUAL 0) string(STRIP "${output}" output) file(TO_CMAKE_PATH "${output}" output_path) set(${result_variable} "${output_path}" PARENT_SCOPE) else() message(WARNING "Failed call: ${QMAKE_EXECUTABLE} -query \"${qt_variable}\"") message(FATAL_ERROR "QMake call failed: ${return_code}") endif() endfunction() # if going to be installed into same prefix as Qt, then also use same folder set(IS_SHARED_INSTALL_PREFIX FALSE) if(NOT DEFINED MARBLE_PRI_INSTALL_USE_QT_SYS_PATHS) query_qmake(qt_install_prefix_dir QT_INSTALL_PREFIX) if(qt_install_prefix_dir STREQUAL "${CMAKE_INSTALL_PREFIX}") set(IS_SHARED_INSTALL_PREFIX TRUE) endif() endif() if(MARBLE_PRI_INSTALL_USE_QT_SYS_PATHS OR IS_SHARED_INSTALL_PREFIX) query_qmake(qt_host_data_dir QT_HOST_DATA) set(PRI_INSTALL_DIR ${qt_host_data_dir}/mkspecs/modules) else() set(PRI_INSTALL_DIR mkspecs/modules) endif() set(MARBLE_PRI_INSTALL_DIR "${PRI_INSTALL_DIR}" CACHE PATH "The directory where the Marble pri file will be installed to.") install(FILES ${CMAKE_CURRENT_BINARY_DIR}/qt_Marble.pri DESTINATION ${MARBLE_PRI_INSTALL_DIR} ) diff --git a/src/lib/marble/LegendWidget.cpp b/src/lib/marble/LegendWidget.cpp index c6949aebb..8f9c237f2 100644 --- a/src/lib/marble/LegendWidget.cpp +++ b/src/lib/marble/LegendWidget.cpp @@ -1,67 +1,65 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2010 Bastian Holst // // Self #include "LegendWidget.h" // Marble #include "MarbleModel.h" using namespace Marble; // Ui #ifdef MARBLE_NO_WEBKITWIDGETS #include "ui_NullLegendWidget.h" #else #include "ui_LegendWidget.h" #endif -#include "MarbleLegendBrowser.h" - namespace Marble { class LegendWidgetPrivate : public Ui::LegendWidget { public: LegendWidgetPrivate(); }; LegendWidgetPrivate::LegendWidgetPrivate() { } LegendWidget::LegendWidget( QWidget *parent, Qt::WindowFlags f ) : QWidget( parent, f ), d( new LegendWidgetPrivate ) { d->setupUi( this ); layout()->setMargin( 0 ); connect( d->m_marbleLegendBrowser, SIGNAL(tourLinkClicked(QString)), this, SIGNAL(tourLinkClicked(QString)) ); } LegendWidget::~LegendWidget() { delete d; } void LegendWidget::setMarbleModel( MarbleModel *model ) { // Initialize the MarbleLegendBrowser d->m_marbleLegendBrowser->setMarbleModel( model ); // connect signals for the Legend connect( d->m_marbleLegendBrowser, SIGNAL(toggledShowProperty(QString,bool)), this, SIGNAL(propertyValueChanged(QString,bool)) ); } } #include "moc_LegendWidget.cpp" diff --git a/src/lib/marble/LegendWidget.ui b/src/lib/marble/LegendWidget.ui index 5a41ffdcb..14c763350 100644 --- a/src/lib/marble/LegendWidget.ui +++ b/src/lib/marble/LegendWidget.ui @@ -1,37 +1,37 @@ LegendWidget 0 0 187 332 Legend about:blank MarbleLegendBrowser - QWebView + QWebEngineView
MarbleLegendBrowser.h
diff --git a/src/lib/marble/MarbleLegendBrowser.cpp b/src/lib/marble/MarbleLegendBrowser.cpp index c06fe9a87..d5a4a8794 100644 --- a/src/lib/marble/MarbleLegendBrowser.cpp +++ b/src/lib/marble/MarbleLegendBrowser.cpp @@ -1,396 +1,390 @@ // // This file is part of the Marble Project. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2006-2007 Torsten Rahn // Copyright 2007 Inge Wallin // Copyright 2012 Illya Kovalevskyy // Copyright 2013 Yazeed Zoabi // #include "MarbleLegendBrowser.h" #include #include #include #include #include #include #include #include #ifndef MARBLE_NO_WEBKITWIDGETS -#include -#include +#include +#include +#include "MarbleWebView.h" #endif #include #include "GeoSceneDocument.h" #include "GeoSceneHead.h" #include "GeoSceneLegend.h" #include "GeoSceneSection.h" #include "GeoSceneIcon.h" #include "GeoSceneItem.h" #include "GeoSceneProperty.h" #include "GeoSceneSettings.h" #include "MarbleModel.h" #include "MarbleDebug.h" #include "TemplateDocument.h" #include "MarbleDirs.h" namespace Marble { class MarbleLegendBrowserPrivate { public: - MarbleModel *m_marbleModel; + MarbleModel *m_marbleModel; QMap m_checkBoxMap; QMap m_symbolMap; QString m_currentThemeId; + MarbleJsWrapper *m_jsWrapper; }; // ================================================================ MarbleLegendBrowser::MarbleLegendBrowser( QWidget *parent ) : MarbleWebView( parent ), d( new MarbleLegendBrowserPrivate ) { d->m_marbleModel = nullptr; - -#ifndef MARBLE_NO_WEBKITWIDGETS - QWebFrame *frame = page()->mainFrame(); - connect(frame, SIGNAL(javaScriptWindowObjectCleared()), - this, SLOT(injectCheckBoxChecker())); - page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks ); - connect( this, SIGNAL(linkClicked(QUrl)), this, SLOT(openLinkExternally(QUrl)) ); -#endif + d->m_jsWrapper = new MarbleJsWrapper(this); } MarbleLegendBrowser::~MarbleLegendBrowser() { delete d; } void MarbleLegendBrowser::setMarbleModel( MarbleModel *marbleModel ) { // We need this to be able to get to the MapTheme. d->m_marbleModel = marbleModel; if ( d->m_marbleModel ) { connect ( d->m_marbleModel, SIGNAL(themeChanged(QString)), this, SLOT(initTheme()) ); } } QSize MarbleLegendBrowser::sizeHint() const { - return QSize( 180, 320 ); + return QSize( 320, 320 ); } void MarbleLegendBrowser::initTheme() { // Check for a theme specific legend.html first if ( d->m_marbleModel != nullptr && d->m_marbleModel->mapTheme() != nullptr ) { const GeoSceneDocument *currentMapTheme = d->m_marbleModel->mapTheme(); d->m_checkBoxMap.clear(); for ( const GeoSceneProperty *property: currentMapTheme->settings()->allProperties() ) { if ( property->available() ) { d->m_checkBoxMap[ property->name() ] = property->value(); } } disconnect ( currentMapTheme, SIGNAL(valueChanged(QString,bool)), nullptr, nullptr ); connect ( currentMapTheme, SIGNAL(valueChanged(QString,bool)), this, SLOT(setCheckedProperty(QString,bool)) ); } if ( isVisible() ) { loadLegend(); } } void MarbleLegendBrowser::loadLegend() { if (!d->m_marbleModel) { return; } #ifndef MARBLE_NO_WEBKITWIDGETS if (d->m_currentThemeId != d->m_marbleModel->mapThemeId()) { d->m_currentThemeId = d->m_marbleModel->mapThemeId(); } else { return; } // Read the html string. QString legendPath; // Check for a theme specific legend.html first if (d->m_marbleModel->mapTheme() != nullptr ) { const GeoSceneDocument *currentMapTheme = d->m_marbleModel->mapTheme(); legendPath = MarbleDirs::path(QLatin1String("maps/") + currentMapTheme->head()->target() + QLatin1Char('/') + currentMapTheme->head()->theme() + QLatin1String("/legend.html")); } if ( legendPath.isEmpty() ) { legendPath = MarbleDirs::path(QStringLiteral("legend.html")); } QString finalHtml = readHtml( QUrl::fromLocalFile( legendPath ) ); TemplateDocument doc(finalHtml); finalHtml = doc.finalText(); + injectWebChannel(finalHtml); reverseSupportCheckboxes(finalHtml); // Generate some parts of the html from the MapTheme tag. const QString sectionsHtml = generateSectionsHtml(); // And then create the final html from these two parts. finalHtml.replace( QString( "" ), sectionsHtml ); translateHtml( finalHtml ); QUrl baseUrl = QUrl::fromLocalFile( legendPath ); // Set the html string in the QTextBrowser. - setHtml(finalHtml, baseUrl); + MarbleWebPage * page = new MarbleWebPage(this); + connect( page, SIGNAL(linkClicked(QUrl)), this, SLOT(openLinkExternally(QUrl)) ); + page->setHtml(finalHtml, baseUrl); + setPage(page); - QTextDocument *document = new QTextDocument(page()->mainFrame()->toHtml()); - d->m_marbleModel->setLegend( document ); -#endif -} + QWebChannel *channel = new QWebChannel(page); + channel->registerObject(QStringLiteral("Marble"), d->m_jsWrapper); + page->setWebChannel(channel); -void MarbleLegendBrowser::injectCheckBoxChecker() -{ -#ifndef MARBLE_NO_WEBKITWIDGETS - QWebFrame *frame = page()->mainFrame(); - frame->addToJavaScriptWindowObject( "Marble", this ); + if ( d->m_marbleModel ) { + page->toHtml([=]( QString document ) { + d->m_marbleModel->setLegend( new QTextDocument(document) ); + }); + } #endif } void MarbleLegendBrowser::openLinkExternally( const QUrl &url ) { if (url.scheme() == QLatin1String("tour")) { emit tourLinkClicked(QLatin1String("maps/") + url.host() + url.path()); } else { QDesktopServices::openUrl( url ); } } bool MarbleLegendBrowser::event( QEvent * event ) { // "Delayed initialization": legend gets created only if ( event->type() == QEvent::Show ) { + setVisible(true); loadLegend(); return true; } return MarbleWebView::event( event ); } QString MarbleLegendBrowser::readHtml( const QUrl & name ) { QString html; QFile data( name.toLocalFile() ); if ( data.open( QFile::ReadOnly ) ) { QTextStream in( &data ); html = in.readAll(); data.close(); } return html; } void MarbleLegendBrowser::translateHtml( QString & html ) { // must match string extraction in Messages.sh - // TODO: html.remove also changes html, is that intended? - QString s = html.remove(0, html.indexOf(QLatin1String(""))); + QString s = html; QRegExp rx( "\\s]+))?)+\\s*|\\s*)/?>" ); rx.setMinimal( true ); s.replace( rx, "\n" ); s.replace( QRegExp( "\\s*\n\\s*" ), "\n" ); const QStringList words = s.split(QLatin1Char('\n'), QString::SkipEmptyParts); QStringList::const_iterator i = words.constBegin(); QStringList::const_iterator const end = words.constEnd(); for (; i != end; ++i ) html.replace(*i, QCoreApplication::translate("Legends", (*i).toUtf8().constData())); } +void MarbleLegendBrowser::injectWebChannel(QString &html) +{ + QString webChannelCode = ""; + webChannelCode += "" + ""; + html.replace("", webChannelCode); +} + void MarbleLegendBrowser::reverseSupportCheckboxes(QString &html) { const QString old = ""; QString checked; if (d->m_checkBoxMap["cities"]) checked = "checked"; const QString repair = QLatin1String( - ""); html.replace(old, repair); } QString MarbleLegendBrowser::generateSectionsHtml() { // Generate HTML to include into legend.html here. QString customLegendString; if ( d->m_marbleModel == nullptr || d->m_marbleModel->mapTheme() == nullptr ) return QString(); const GeoSceneDocument *currentMapTheme = d->m_marbleModel->mapTheme(); d->m_symbolMap.clear(); /* Okay, if you are reading it now, be ready for hell! * We can't optimize this part of Legend Browser, but we will * do it, anyway. It's complicated a lot, the most important * thing is to understand everything. */ for ( const GeoSceneSection *section: currentMapTheme->legend()->sections() ) { // Each section is divided into the "well" // Well is like a block of data with rounded corners customLegendString += QLatin1String("
"); const QString heading = QCoreApplication::translate("DGML", section->heading().toUtf8().constData()); QString checkBoxString; if (section->checkable()) { // If it's needed to make a checkbox here, we will QString const checked = d->m_checkBoxMap[section->connectTo()] ? "checked" : ""; /* Important comment: * We inject Marble object into JavaScript of each legend html file * This is only one way to handle checkbox changes we see, so * Marble.setCheckedProperty is a function that does it */ if(!section->radio().isEmpty()) { checkBoxString = QLatin1String( ""); } else { checkBoxString = QLatin1String( ""); } customLegendString += checkBoxString; } else { customLegendString += QLatin1String("

") + heading + QLatin1String("

"); } for (const GeoSceneItem *item: section->items()) { // checkbox for item QString checkBoxString; if (item->checkable()) { QString const checked = d->m_checkBoxMap[item->connectTo()] ? "checked" : ""; checkBoxString = QLatin1String( "connectTo() + QLatin1String("\" />"); } // pixmap and text QString src; QString styleDiv; int pixmapWidth = 24; int pixmapHeight = 12; if (!item->icon()->pixmap().isEmpty()) { QString path = MarbleDirs::path( item->icon()->pixmap() ); const QPixmap oncePixmap(path); pixmapWidth = oncePixmap.width(); pixmapHeight = oncePixmap.height(); src = QUrl::fromLocalFile( path ).toString(); styleDiv = QLatin1String("width: ") + QString::number(pixmapWidth) + QLatin1String("px; height: ") + QString::number(pixmapHeight) + QLatin1String("px;"); + } else { + // Workaround for rendered border around empty images in webkit + src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"; } // NOTICE. There are some pixmaps without image, so we should // create just a plain rectangle with set color - else if (item->icon()->color().isValid()) { + if (QColor(item->icon()->color()).isValid()) { const QColor color = item->icon()->color(); styleDiv = QLatin1String("width: ") + QString::number(pixmapWidth) + QLatin1String("px; height: ") + QString::number(pixmapHeight) + QLatin1String("px; background-color: ") + color.name() + QLatin1Char(';'); } + styleDiv += " position: relative; top: -3px;"; const QString text = QCoreApplication::translate("DGML", item->text().toUtf8().constData()); QString html = QLatin1String( "
" " " "
"); customLegendString += html; } customLegendString += QLatin1String("
"); //
} return customLegendString; } void MarbleLegendBrowser::setCheckedProperty( const QString& name, bool checked ) { -#ifndef MARBLE_NO_WEBKITWIDGETS - QWebElement box = page()->mainFrame()->findFirstElement(QLatin1String("input[name=") + name + QLatin1Char(']')); - if (!box.isNull()) { - if (checked != d->m_checkBoxMap[name]) { - d->m_checkBoxMap[name] = checked; - emit toggledShowProperty( name, checked ); - } + if (checked != d->m_checkBoxMap[name]) { + d->m_checkBoxMap[name] = checked; + emit toggledShowProperty( name, checked ); } - - update(); -#endif } void MarbleLegendBrowser::setRadioCheckedProperty( const QString& value, const QString& name , bool checked ) { -#ifndef MARBLE_NO_WEBKITWIDGETS - QWebElement box = page()->mainFrame()->findFirstElement(QLatin1String("input[value=") + value + QLatin1Char(']')); - QWebElementCollection boxes = page()->mainFrame()->findAllElements(QLatin1String("input[name=") + name + QLatin1Char(']')); - QString currentValue; - for(int i=0; im_checkBoxMap[currentValue]=false; - emit toggledShowProperty( currentValue, false ); - } - if (!box.isNull()) { - if (checked != d->m_checkBoxMap[value]) { - d->m_checkBoxMap[value] = checked; - emit toggledShowProperty( value, checked ); - } - } - - update(); -#endif + Q_UNUSED(value) + if (checked != d->m_checkBoxMap[name]) { + d->m_checkBoxMap[name] = checked; + emit toggledShowProperty( name, checked ); + } } } #include "moc_MarbleLegendBrowser.cpp" diff --git a/src/lib/marble/MarbleLegendBrowser.h b/src/lib/marble/MarbleLegendBrowser.h index b77b03566..6f568e9b2 100644 --- a/src/lib/marble/MarbleLegendBrowser.h +++ b/src/lib/marble/MarbleLegendBrowser.h @@ -1,80 +1,97 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2006-2007 Torsten Rahn // Copyright 2007 Inge Wallin // Copyright 2013 Yazeed Zoabi // // // The Legend Browser displays the legend // #ifndef MARBLE_MARBLELEGENDBROWSER_H #define MARBLE_MARBLELEGENDBROWSER_H #ifdef MARBLE_NO_WEBKITWIDGETS #include "NullMarbleWebView.h" #else #include "MarbleWebView.h" #endif #include "marble_export.h" class QEvent; class QUrl; class QString; namespace Marble { class MarbleModel; class MarbleLegendBrowserPrivate; class MARBLE_EXPORT MarbleLegendBrowser : public MarbleWebView { Q_OBJECT public: explicit MarbleLegendBrowser( QWidget* parent ); ~MarbleLegendBrowser() override; void setMarbleModel( MarbleModel *marbleModel ); QSize sizeHint() const override; - public Q_SLOTS: - void setCheckedProperty( const QString& name, bool checked ); - void setRadioCheckedProperty( const QString& value,const QString& name, bool checked ); - - Q_SIGNALS: void toggledShowProperty( const QString&, bool ); void tourLinkClicked( const QString &url ); + public Q_SLOTS: + void setCheckedProperty( const QString& name, bool checked ); + void setRadioCheckedProperty( const QString& value,const QString& name, bool checked ); + private Q_SLOTS: void initTheme(); void loadLegend(); - void injectCheckBoxChecker(); void openLinkExternally( const QUrl &url ); protected: bool event( QEvent * event ) override; static QString readHtml(const QUrl &name); QString generateSectionsHtml(); static void translateHtml(QString &html); private: + void injectWebChannel( QString &html ); void reverseSupportCheckboxes( QString &html ); - private: Q_DISABLE_COPY( MarbleLegendBrowser ) MarbleLegendBrowserPrivate * const d; }; +class MarbleJsWrapper : public QObject +{ + Q_OBJECT +public: + explicit MarbleJsWrapper( MarbleLegendBrowser* parent ) : m_parent(parent) {} + +public Q_SLOTS: + void setCheckedProperty( const QString& name, bool checked ) + { + m_parent->setCheckedProperty(name, checked); + } + void setRadioCheckedProperty( const QString& value,const QString& name, bool checked ) + { + m_parent->setRadioCheckedProperty(value, name, checked); + } +private: + MarbleLegendBrowser * m_parent; +}; + } #endif diff --git a/src/lib/marble/MarbleWebView.cpp b/src/lib/marble/MarbleWebView.cpp index 16ec4ea9a..a4982f054 100644 --- a/src/lib/marble/MarbleWebView.cpp +++ b/src/lib/marble/MarbleWebView.cpp @@ -1,58 +1,58 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2012 Illya Kovalevskyy // #include "MarbleWebView.h" #include #include #include #include #include MarbleWebView::MarbleWebView(QWidget *parent) : - QWebView(parent), + QWebEngineView(parent), m_contextMenu(new QMenu(this)), m_copyAction(new QAction(this)) { m_copyAction->setText(tr("Copy")); m_copyAction->setIcon(QIcon(QStringLiteral(":/icons/edit-copy.png"))); m_copyAction->setIconVisibleInMenu(true); m_copyAction->setToolTip(tr("Copy selected content")); connect(m_copyAction, SIGNAL(triggered()), this, SLOT(copySelectedText())); m_contextMenu->addAction(m_copyAction); setContextMenuPolicy(Qt::DefaultContextMenu); } void MarbleWebView::contextMenuEvent(QContextMenuEvent *event) { m_copyAction->setEnabled(!selectedText().isEmpty()); m_contextMenu->exec(event->globalPos()); } void MarbleWebView::copySelectedText() { const QString text = selectedText(); if (!text.isEmpty()) { QClipboard *clipboard = QApplication::clipboard(); clipboard->setText(text); } } void MarbleWebView::keyPressEvent(QKeyEvent *event) { if(event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_C) { copySelectedText(); return; } - QWebView::keyPressEvent(event); + QWebEngineView::keyPressEvent(event); } #include "moc_MarbleWebView.cpp" diff --git a/src/lib/marble/MarbleWebView.h b/src/lib/marble/MarbleWebView.h index 8c84b7ba8..7ae71fc9f 100644 --- a/src/lib/marble/MarbleWebView.h +++ b/src/lib/marble/MarbleWebView.h @@ -1,36 +1,57 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2012 Illya Kovalevskyy // #ifndef MARBLEWEBVIEW_H #define MARBLEWEBVIEW_H -#include +#include +#include +#include #include "marble_export.h" -class MARBLE_EXPORT MarbleWebView : public QWebView +class MARBLE_EXPORT MarbleWebPage : public QWebEnginePage +{ + Q_OBJECT +public: + explicit MarbleWebPage(QObject *parent = nullptr) : QWebEnginePage(parent){} + +Q_SIGNALS: + void linkClicked(const QUrl & url); +protected: + bool acceptNavigationRequest(const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame) override { + Q_UNUSED(isMainFrame) + if (type == QWebEnginePage::NavigationTypeLinkClicked) { + emit linkClicked(url); + return false; + } + return true; + } +}; + +class MARBLE_EXPORT MarbleWebView : public QWebEngineView { Q_OBJECT public: explicit MarbleWebView(QWidget *parent = nullptr); protected: void contextMenuEvent(QContextMenuEvent *event) override; void keyPressEvent(QKeyEvent *event) override; private Q_SLOTS: void copySelectedText(); private: QMenu *m_contextMenu; QAction *m_copyAction; }; #endif // MARBLEWEBVIEW_H diff --git a/src/lib/marble/PopupItem.cpp b/src/lib/marble/PopupItem.cpp index 2415f8873..16b694913 100644 --- a/src/lib/marble/PopupItem.cpp +++ b/src/lib/marble/PopupItem.cpp @@ -1,416 +1,417 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2012 Torsten Rahn // Copyright 2013 Mohammed Nafees // Copyright 2012 Dennis Nienhüser // Copyright 2012 Illya Kovalevskyy // #include "PopupItem.h" #include "MarbleWidget.h" #ifdef MARBLE_NO_WEBKITWIDGETS #include "NullMarbleWebView.h" #else -#include -#include +#include +#include +#include #include "MarbleWebView.h" #endif +#include #include #include #include #include #include #include #include #include #include namespace Marble { PopupItem::PopupItem( QObject* parent ) : QObject( parent ), BillboardGraphicsItem(), - m_widget( new QWidget ), + m_widget( new QWidget() ), m_textColor( QColor(Qt::black) ), m_backColor( QColor(Qt::white) ), m_needMouseRelease(false) { - setCacheMode( ItemCoordinateCache ); +// setCacheMode( ItemCoordinateCache ); setVisible( false ); setSize( QSizeF( 300.0, 320.0 ) ); m_ui.setupUi( m_widget ); - m_ui.goBackButton->setVisible( false ); connect( m_ui.goBackButton, SIGNAL(clicked()), this, SLOT(goBack()) ); #ifdef QT_NO_PRINTER m_ui.printButton->setVisible( false ); #else m_ui.printButton->setVisible( true ); connect( m_ui.printButton, SIGNAL(clicked()), this, SLOT(printContent()) ); #endif + m_widget->setVisible(true); + m_widget->setAttribute(Qt::WA_DontShowOnScreen); m_widget->setAttribute( Qt::WA_NoSystemBackground, true ); QPalette palette = m_ui.webView->palette(); palette.setBrush(QPalette::Base, Qt::transparent); - m_ui.webView->setPalette(palette); #ifndef MARBLE_NO_WEBKITWIDGETS - m_ui.webView->page()->setPalette(palette); - m_ui.webView->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks); + m_ui.webView->setPalette(palette); + m_ui.webView->page()->settings()->setAttribute(QWebEngineSettings::LocalContentCanAccessFileUrls, true); + m_ui.webView->page()->settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true); #endif m_ui.webView->setAttribute(Qt::WA_OpaquePaintEvent, false); m_ui.webView->setUrl( QUrl( "about:blank" ) ); connect( m_ui.hideButton, SIGNAL(clicked()), this, SIGNAL(hide()) ); #ifndef MARBLE_NO_WEBKITWIDGETS - connect( m_ui.webView, SIGNAL(titleChanged(QString)), m_ui.titleText, SLOT(setText(QString)) ); - connect( m_ui.webView, SIGNAL(urlChanged(QUrl)), this, SLOT(updateBackButton()) ); + connect( m_ui.webView->page(), SIGNAL(titleChanged(QString)), m_ui.titleText, SLOT(setText(QString)) ); + connect( m_ui.webView->page(), SIGNAL(urlChanged(QUrl)), this, SLOT(updateBackButton()) ); // Update the popupitem on changes while loading the webpage - connect( m_ui.webView->page(), SIGNAL(repaintRequested(QRect)), this, SLOT(requestUpdate()) ); - connect(m_ui.webView->page(), SIGNAL(linkClicked(QUrl)), this, SLOT(openUrl(QUrl))); + connect(m_ui.webView, SIGNAL(loadFinished(bool)), this, SLOT(requestUpdate())); #endif } PopupItem::~PopupItem() { delete m_widget; } bool PopupItem::isPrintButtonVisible() const { return m_ui.printButton->isVisible(); } void PopupItem::setPrintButtonVisible( bool display ) { m_ui.printButton->setVisible( display ); } void PopupItem::setUrl( const QUrl &url ) { m_ui.webView->setUrl( url ); - setVisible( true ); QPalette palette = m_ui.webView->palette(); palette.setBrush(QPalette::Base, Qt::transparent); - m_ui.webView->setPalette(palette); #ifndef MARBLE_NO_WEBKITWIDGETS - m_ui.webView->page()->setPalette(palette); + m_ui.webView->setPalette(palette); #endif m_ui.webView->setAttribute(Qt::WA_OpaquePaintEvent, false); requestUpdate(); } void PopupItem::setContent( const QString &html, const QUrl &baseUrl ) { m_content = html; m_baseUrl = baseUrl; #ifndef MARBLE_NO_WEBKITWIDGETS m_ui.webView->setHtml( html, baseUrl ); #endif requestUpdate(); } void PopupItem::setTextColor(const QColor &color) { if(color.isValid() && m_ui.titleText != nullptr) { m_textColor = color; QPalette palette(m_ui.titleText->palette()); palette.setColor(QPalette::WindowText, m_textColor); m_ui.titleText->setPalette(palette); requestUpdate(); } } void PopupItem::setBackgroundColor(const QColor &color) { if(color.isValid()) { m_backColor = color; QPixmapCache::remove( "marble/webpopup/webpopup2" ); QPixmapCache::remove( "marble/webpopup/arrow2_topleft" ); QPixmapCache::remove( "marble/webpopup/arrow2_bottomleft" ); QPixmapCache::remove( "marble/webpopup/arrow2_topright" ); QPixmapCache::remove( "marble/webpopup/arrow2_bottomright" ); requestUpdate(); } } void PopupItem::colorize( QImage &img, const QColor &col ) { if (img.depth() <= 8) return; int pixels = img.width()*img.height(); unsigned int *data = (unsigned int *) img.bits(); for (int i=0; i < pixels; ++i) { int val = qGray(data[i]); data[i] = qRgba(col.red()*val/255,col.green()*val/255, col.blue()*val/255, qAlpha(data[i])); } } void PopupItem::paint( QPainter *painter ) { QRect popupRect; QPixmap image = pixmap("marble/webpopup/arrow2_vertical_topright"); if ( alignment() & Qt::AlignRight ) { popupRect.setRect( image.width() - 13, -10, size().width() - ( image.width() - 3 ), size().height() ); qDrawBorderPixmap(painter, popupRect, QMargins( 20, 20, 20, 20 ), pixmap("marble/webpopup/webpopup2")); if ( alignment() & Qt::AlignTop ) { image = pixmap("marble/webpopup/arrow2_bottomleft"); painter->drawPixmap( 0, size().height() - image.height(), image ); } else if ( alignment() & Qt::AlignBottom ) { image = pixmap("marble/webpopup/arrow2_topleft"); painter->drawPixmap( 0, 0, image ); } else { // for no horizontal align value and Qt::AlignVCenter image = pixmap("marble/webpopup/arrow2_topleft"); painter->drawPixmap( 0, size().height() / 2, image ); } - m_widget->render( painter, QPoint( image.width() - 3, 0 ), QRegion() ); + m_widget->render( painter, QPoint( image.width() - 3, 0 ) ); } else if ( alignment() & Qt::AlignLeft ) { popupRect.setRect( -10, -10, size().width() - ( image.width() - 3 ), size().height() ); qDrawBorderPixmap(painter, popupRect, QMargins( 20, 20, 20, 20 ), pixmap("marble/webpopup/webpopup2")); if ( alignment() & Qt::AlignTop ) { image = pixmap("marble/webpopup/arrow2_bottomright"); painter->drawPixmap( size().width() - image.width(), size().height() - image.height(), image ); } else if ( alignment() & Qt::AlignBottom ) { image = pixmap("marble/webpopup/arrow2_topright"); painter->drawPixmap( size().width() - image.width(), 0, image ); } else { // for no horizontal align value and Qt::AlignVCenter image = pixmap("marble/webpopup/arrow2_topright"); painter->drawPixmap( size().width() - image.width(), size().height() / 2 - image.height() / 2 + 23, image ); } m_widget->render( painter, QPoint( 5, 0 ), QRegion() ); } else if ( alignment() & Qt::AlignHCenter ) { if ( alignment() & Qt::AlignTop ) { image = pixmap("marble/webpopup/arrow2_vertical_bottomright"); popupRect.setRect( -10, -10, size().width(), size().height() - image.height() + 3 ); qDrawBorderPixmap(painter, popupRect, QMargins( 20, 20, 20, 20 ), pixmap("marble/webpopup/webpopup2")); painter->drawPixmap( size().width() / 2 - image.width(), size().height() - image.height(), image ); m_widget->render( painter, QPoint( 0, 0 ), QRegion() ); } else if ( alignment() & Qt::AlignBottom ) { image = pixmap("marble/webpopup/arrow2_vertical_topleft"); popupRect.setRect( -10, image.height() - 13, size().width(), size().height() - image.height() + 3 ); qDrawBorderPixmap(painter, popupRect, QMargins( 20, 20, 20, 20 ), pixmap("marble/webpopup/webpopup2")); painter->drawPixmap( size().width() / 2, 0, image ); m_widget->render( painter, QPoint( 5, image.height() - 7 ), QRegion() ); } else { // for no horizontal align value and Qt::AlignVCenter popupRect.setRect( -10, -10, size().width(), size().height()); qDrawBorderPixmap(painter, popupRect, QMargins( 20, 20, 20, 20 ), pixmap("marble/webpopup/webpopup2")); m_widget->render( painter, QPoint( 0, 0 ), QRegion() ); } } m_widget->setFixedSize( popupRect.width() - 20, popupRect.height() - 20 ); } bool PopupItem::eventFilter( QObject *object, QEvent *e ) { MarbleWidget *widget = dynamic_cast ( object ); if ( !widget ) { return BillboardGraphicsItem::eventFilter( object, e ); } if ( e->type() == QEvent::ContextMenu) { QApplication::sendEvent( m_ui.webView, e ); return BillboardGraphicsItem::eventFilter( object, e ); } if ( e->type() == QEvent::KeyPress ) { QApplication::sendEvent( m_ui.webView, e ); return BillboardGraphicsItem::eventFilter( object, e ); } if ( e->type() == QEvent::MouseButtonDblClick || e->type() == QEvent::MouseMove || e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonRelease ) { // Mouse events are forwarded to the underlying widget QMouseEvent *event = static_cast ( e ); QPoint shiftedPos = event->pos(); QWidget* child = transform( shiftedPos ); bool const forcedMouseRelease = m_needMouseRelease && e->type() == QEvent::MouseButtonRelease; if ( child || forcedMouseRelease ) { if ( !m_needMouseRelease && e->type() == QEvent::MouseButtonPress ) { m_needMouseRelease = true; } else if ( forcedMouseRelease ) { m_needMouseRelease = false; } if ( !child ) { child = m_ui.webView; } QMouseEvent shiftedEvent = QMouseEvent( e->type(), shiftedPos, event->globalPos(), event->button(), event->buttons(), event->modifiers() ); if ( QApplication::sendEvent( child, &shiftedEvent ) ) { widget->setCursor( child->cursor() ); emit repaintNeeded(); return true; } } } else if ( e->type() == QEvent::Wheel ) { // Wheel events are forwarded to the underlying widget QWheelEvent *event = static_cast ( e ); QPoint shiftedPos = event->pos(); QWidget* child = transform( shiftedPos ); if ( child ) { QWheelEvent shiftedEvent = QWheelEvent( shiftedPos, event->globalPos(), event->delta(), event->buttons(), event->modifiers() ); if ( QApplication::sendEvent( child, &shiftedEvent ) ) { widget->setCursor( child->cursor() ); emit repaintNeeded(); return true; } } } return BillboardGraphicsItem::eventFilter( object, e ); } QWidget* PopupItem::transform( QPoint &point ) const { /* * Fixes for mouse events to trigger when the web popup * is shifted in accordance with the horizontal alignment */ if ( alignment() & Qt::AlignRight ) point -= QPoint( 117, 0 ); else if ( alignment() & Qt::AlignLeft ) point -= QPoint( 5, 0 ); else if ( alignment() & Qt::AlignHCenter ) { if ( alignment() & Qt::AlignTop ) { point -= QPoint( 0, 0 ); } else if ( alignment() & Qt::AlignBottom ) { point-= QPoint( 5, 57 ); } else { point -= QPoint( 0, 0 ); } } const QVector widgetPositions = positions(); QVector::const_iterator it = widgetPositions.constBegin(); for( ; it != widgetPositions.constEnd(); ++it ) { if ( QRectF( *it, size() ).contains( point ) ) { point -= it->toPoint(); QWidget* child = m_widget->childAt( point ); if ( child ) { point -= child->pos(); } return child; } } return nullptr; } void PopupItem::clearHistory() { m_content.clear(); m_ui.webView->setUrl( QUrl( "about:blank" ) ); #ifndef MARBLE_NO_WEBKITWIDGETS m_ui.webView->history()->clear(); #endif } void PopupItem::requestUpdate() { update(); emit repaintNeeded(); } void PopupItem::printContent() const { #ifndef QT_NO_PRINTER #ifndef MARBLE_NO_WEBKITWIDGETS QPrinter printer; QPointer dialog = new QPrintDialog(&printer); if (dialog->exec() == QPrintDialog::Accepted) { - m_ui.webView->print(&printer); + m_ui.webView->page()->print(&printer, [=](bool){}); } delete dialog; #endif #endif } void PopupItem::updateBackButton() { #ifndef MARBLE_NO_WEBKITWIDGETS - bool const hasHistory = m_ui.webView->history()->count() > 1; - bool const previousIsHtml = !m_content.isEmpty() && m_ui.webView->history()->currentItemIndex() == 1; - bool const atStart = m_ui.webView->history()->currentItemIndex() <= 1; - bool const currentIsHtml = m_ui.webView->url() == QUrl( "about:blank" ); + bool const hasHistory = m_ui.webView->page()->history()->count() > 1; + bool const previousIsHtml = !m_content.isEmpty() && m_ui.webView->page()->history()->currentItemIndex() == 1; + bool const atStart = m_ui.webView->page()->history()->currentItemIndex() <= 1; + bool const currentIsHtml = m_ui.webView->page()->url() == QUrl( "about:blank" ); + m_ui.goBackButton->setVisible( hasHistory && !currentIsHtml && ( previousIsHtml || !atStart ) ); #endif } void PopupItem::goBack() { #ifndef MARBLE_NO_WEBKITWIDGETS - if ( m_ui.webView->history()->currentItemIndex() == 1 && !m_content.isEmpty() ) { - m_ui.webView->setHtml( m_content, m_baseUrl ); + if ( m_ui.webView->page()->history()->currentItemIndex() == 1 && !m_content.isEmpty() ) { + m_ui.webView->page()->setHtml( m_content, m_baseUrl ); } else { m_ui.webView->back(); } updateBackButton(); #endif } void PopupItem::openUrl(const QUrl &url) { QDesktopServices::openUrl(url); } QPixmap PopupItem::pixmap( const QString &imageId ) const { QPixmap result; if ( !QPixmapCache::find( imageId, result ) ) { QImage bottom = QImage(QLatin1String(":/") + imageId + QLatin1String("_shadow.png")); QImage top = QImage(QLatin1String(":/") + imageId + QLatin1String(".png")); colorize( top, m_backColor ); QPainter painter( &bottom ); painter.drawImage( QPoint(0,0), top ); result = QPixmap::fromImage( bottom ); QPixmapCache::insert( imageId, result ); } return result; } } #include "moc_PopupItem.cpp" diff --git a/src/lib/marble/PopupItem.h b/src/lib/marble/PopupItem.h index bf2f20988..220dd3d88 100644 --- a/src/lib/marble/PopupItem.h +++ b/src/lib/marble/PopupItem.h @@ -1,195 +1,195 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2012 Torsten Rahn // Copyright 2012 Mohammed Nafees // Copyright 2012 Illya Kovalevskyy // #ifndef POPUPITEM_H #define POPUPITEM_H #include #include #include "BillboardGraphicsItem.h" #ifdef MARBLE_NO_WEBKITWIDGETS #include "ui_NullWebPopupWidget.h" #else #include "ui_WebPopupWidget.h" #endif class QPainter; namespace Marble { /** * @brief The PopupItem Class * * This class represents graphics item for information bubble. * Mostly used by @see MapInfoDialog. * - * It has nice API for QWebView and methods for styling it. + * It has nice API for QWebEngineView and methods for styling it. * */ class PopupItem : public QObject, public BillboardGraphicsItem { Q_OBJECT public: explicit PopupItem( QObject* parent = nullptr ); ~PopupItem() override; /** * @brief Print button visibility indicator * * There is a button in the header of item with print icon. - * It used to print the content of QWebView inside. + * It used to print the content of QWebEngineView inside. * This method indicates visibility of this button. * * @see setPrintButtonVisible(); * * @return visibility of the print button */ bool isPrintButtonVisible() const; /** * @brief Sets visibility of the print button * * There is a button in the header of item with print icon. - * It used to print the content of QWebView inside + * It used to print the content of QWebEngineView inside * * This method sets visibility of this button. * * If @p display is `true`, button will be displayed, * otherwise - button won't be displayed * * @param display visibility of the print button */ void setPrintButtonVisible(bool display); /** * @brief Set URL for web window * * There is a small web browser inside. * It can show open websites. * * This method sets @p url for its window. * * @param url new url for web window */ void setUrl( const QUrl &url ); /** * @brief Set content of the popup * * There is a small web browser inside. It can show custom HTML. * This method sets custom @p html for its window * * @param html custom html for popup */ void setContent( const QString &html, const QUrl & baseUrl = QUrl() ); /** * @brief Sets text color of the header * * Frame of the web browser is called bubble. Bubble has * a header - part of the bubble at the top. Usually * it contains the name of the page which can be set via * TITLE html tag in HTML document loaded. * This method sets text @p color of the header. * * @param color text color of the header */ void setTextColor( const QColor &color ); /** * @brief Sets background color of the bubble * * Frame of the web browser is called bubble. This method * sets background @p color of this bubble. * * @param color background color of the bubble */ void setBackgroundColor( const QColor &color ); bool eventFilter( QObject *, QEvent *e ) override; void clearHistory(); private Q_SLOTS: /** * @brief Marks cache as dirty and tells the world its need for repainting. */ void requestUpdate(); /** * @brief Print content of the web browser * * Popup Item has built-in mini-browser. This function * executes print dialog for printing its content. * */ void printContent() const; /** * @brief Updates Back Button (web surfing history) * * When you are browsing the site you may need to visit * the page, you have visited before (Go Back). * * For this action Popup Item has a button Go Back placed * in the left of the header. * * @note it's visible only if web surfing history is not clear or * you are not on its first page. * * @see goBack(); * */ void updateBackButton(); /** * @brief Go Back (web surfing history) * * This method moves you one step backwards in * web surfing history. * */ void goBack(); /** * @brief Opens clicked URL in external browser. * @param url URL to be opened in external browser */ void openUrl(const QUrl &url); protected: void paint( QPainter *painter ) override; Q_SIGNALS: void repaintNeeded(); void hide(); private: QPixmap pixmap( const QString &imageid ) const; static void colorize( QImage &img, const QColor &col ); QWidget* transform( QPoint &point ) const; QWidget *m_widget; Ui::WebPopupWidget m_ui; QString m_content; QColor m_textColor; QColor m_backColor; bool m_needMouseRelease; QUrl m_baseUrl; }; } #endif diff --git a/src/lib/marble/TinyWebBrowser.cpp b/src/lib/marble/TinyWebBrowser.cpp index dbce339d3..0220f386f 100644 --- a/src/lib/marble/TinyWebBrowser.cpp +++ b/src/lib/marble/TinyWebBrowser.cpp @@ -1,106 +1,105 @@ // // This file is part of the Marble Project. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2006-2007 Torsten Rahn // Copyright 2007 Inge Wallin // Copyright 2008 Simon Hausmann // // Self #include "TinyWebBrowser.h" // Qt #include #include #include #include #include #include // Marble #include "MarbleGlobal.h" #include "MarbleDebug.h" #include "MarbleDirs.h" #include "MarbleLocale.h" +#include "MarbleWebView.h" namespace Marble { class TinyWebBrowserPrivate { }; static QString guessWikipediaDomain() { const QString code = MarbleLocale::languageCode(); return QLatin1String("https://") + code + QLatin1String(".m.wikipedia.org/"); } TinyWebBrowser::TinyWebBrowser( QWidget* parent ) - : QWebView( parent ), + : QWebEngineView( parent ), d( nullptr ) { + MarbleWebPage * page = new MarbleWebPage(); + setPage(page); + connect( this, SIGNAL(statusBarMessage(QString)), this, SIGNAL(statusMessage(QString)) ); - page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks ); - connect( this, SIGNAL(linkClicked(QUrl)), + connect( page, SIGNAL(linkClicked(QUrl)), this, SLOT(openExternalLink(QUrl)) ); connect( this, SIGNAL(titleChanged(QString)), this, SLOT(setWindowTitle(QString)) ); - pageAction( QWebPage::OpenLinkInNewWindow )->setEnabled( false ); - pageAction( QWebPage::OpenLinkInNewWindow )->setVisible( false ); + pageAction( QWebEnginePage::OpenLinkInNewWindow )->setEnabled( false ); + pageAction( QWebEnginePage::OpenLinkInNewWindow )->setVisible( false ); } TinyWebBrowser::~TinyWebBrowser() { // not yet needed //delete d; } void TinyWebBrowser::setWikipediaPath( const QString& relativeUrl ) { QUrl url(relativeUrl); if ( url.isRelative() ) url = QUrl( guessWikipediaDomain() ).resolved( url ); load( url ); } void TinyWebBrowser::print() { #ifndef QT_NO_PRINTER QPrinter printer; QPointer dlg = new QPrintDialog( &printer, this ); if ( dlg->exec() ) - QWebView::print( &printer ); + page()->print( &printer, [=](bool){} ); delete dlg; #endif } -QWebView *TinyWebBrowser::createWindow( QWebPage::WebWindowType type ) +QWebEngineView *TinyWebBrowser::createWindow( QWebEnginePage::WebWindowType type ) { + Q_UNUSED(type) TinyWebBrowser *view = new TinyWebBrowser( this ); - - if ( type == QWebPage::WebModalDialog ) { - view->setWindowModality( Qt::WindowModal ); - } - return view; } void TinyWebBrowser::openExternalLink( const QUrl& url ) { QDesktopServices::openUrl( url ); } } // namespace Marble #include "moc_TinyWebBrowser.cpp" diff --git a/src/lib/marble/TinyWebBrowser.h b/src/lib/marble/TinyWebBrowser.h index c6103b22f..0475b2310 100644 --- a/src/lib/marble/TinyWebBrowser.h +++ b/src/lib/marble/TinyWebBrowser.h @@ -1,62 +1,62 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2006-2007 Torsten Rahn // Copyright 2007 Inge Wallin // #ifndef MARBLE_TINYWEBBROWSER_H #define MARBLE_TINYWEBBROWSER_H // Qt -#include +#include // Marble #include "marble_export.h" class QString; class QUrl; namespace Marble { class TinyWebBrowserPrivate; /** - * This class provides a tiny web browser based on QWebView (WebKit). - * It is different from QWebView as it has the button "Open in new Window" + * This class provides a tiny web browser based on QWebEngineView (WebKit). + * It is different from QWebEngineView as it has the button "Open in new Window" * disabled per default and instead opens every link in the default web * browser of the user. */ -class MARBLE_EXPORT TinyWebBrowser : public QWebView +class MARBLE_EXPORT TinyWebBrowser : public QWebEngineView { Q_OBJECT public: explicit TinyWebBrowser( QWidget* parent = nullptr ); ~TinyWebBrowser() override; public Q_SLOTS: void setWikipediaPath( const QString& relativeUrl ); void print(); Q_SIGNALS: void statusMessage( const QString& ); protected: - QWebView *createWindow( QWebPage::WebWindowType type ) override; + QWebEngineView *createWindow( QWebEnginePage::WebWindowType type ) override; private Q_SLOTS: void openExternalLink( const QUrl& ); private: TinyWebBrowserPrivate * const d; }; } #endif diff --git a/src/lib/marble/WebPopupWidget.ui b/src/lib/marble/WebPopupWidget.ui index 8cf710318..e129b73db 100644 --- a/src/lib/marble/WebPopupWidget.ui +++ b/src/lib/marble/WebPopupWidget.ui @@ -1,80 +1,86 @@ WebPopupWidget 0 0 400 300 - - - :/marble/webpopup/icon-arrow-back.png:/marble/webpopup/icon-arrow-back.png true :/marble/webpopup/icon-print.png:/marble/webpopup/icon-print.png true :/marble/webpopup/icon-remove.png:/marble/webpopup/icon-remove.png + + QToolButton::DelayedPopup + true - + + Qt::NoArrow + + + + + MarbleWebView QWidget
MarbleWebView.h
1
diff --git a/src/lib/marble/cloudsync/RouteItemDelegate.cpp b/src/lib/marble/cloudsync/RouteItemDelegate.cpp index 98ad8bb08..586ba229e 100644 --- a/src/lib/marble/cloudsync/RouteItemDelegate.cpp +++ b/src/lib/marble/cloudsync/RouteItemDelegate.cpp @@ -1,297 +1,297 @@ #include "RouteItemDelegate.h" #include "CloudRouteModel.h" #ifdef MARBLE_NO_WEBKITWIDGETS #include #else -#include +#include #endif #include #include #include #include namespace Marble { RouteItemDelegate::RouteItemDelegate( QListView *view, CloudRouteModel *model ) : m_view( view ), m_model( model ), m_buttonWidth( 0 ), m_iconSize( 16 ), m_previewSize( 128 ), m_margin( 8 ) { } void RouteItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const { QStyleOptionViewItem styleOption = option; styleOption.text = QString(); QApplication::style()->drawControl( QStyle::CE_ItemViewItem, &styleOption, painter ); QAbstractTextDocumentLayout::PaintContext paintContext; if ( styleOption.state & QStyle::State_Selected) { paintContext.palette.setColor( QPalette::Text, styleOption.palette.color( QPalette::Active, QPalette::HighlightedText ) ); } QRect const iconRect = position( Preview, option ); QIcon const icon = index.data( Qt::DecorationRole ).value(); painter->drawPixmap( iconRect, icon.pixmap( iconRect.size() ) ); QTextDocument document; QRect const textRect = position( Text, option ); document.setTextWidth( textRect.width() ); document.setDefaultFont( option.font ); document.setHtml( text( index ) ); painter->save(); painter->translate( textRect.topLeft() ); painter->setClipRect( 0, 0, textRect.width(), textRect.height() ); document.documentLayout()->draw( painter, paintContext ); painter->restore(); bool cached = index.data( CloudRouteModel::IsCached ).toBool(); bool downloading = index.data( CloudRouteModel::IsDownloading ).toBool(); bool onCloud = index.data( CloudRouteModel::IsOnCloud ).toBool(); if ( downloading ) { qint64 total = m_model->totalSize(); qint64 progress = m_model->downloadedSize(); QStyleOptionProgressBar progressBarOption; progressBarOption.rect = position( Progressbar, option ); progressBarOption.minimum = 0; progressBarOption.maximum = 100; progressBarOption.progress = ( 100.0 * progress / total ); progressBarOption.text = QString::number(progressBarOption.progress) + QLatin1Char('%'); progressBarOption.textVisible = true; QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption, painter); } else if ( !cached && onCloud ) { QStyleOptionButton downloadButton = button( DownloadButton, option ); QRect downloadRect = position( DownloadButton, option ); downloadButton.rect = downloadRect; QApplication::style()->drawControl( QStyle::CE_PushButton, &downloadButton, painter ); QStyleOptionButton cloudRemoveButton = button( RemoveFromCloudButton, option ); QRect cloudRemoveRect = position( RemoveFromCloudButton, option ); cloudRemoveButton.rect = cloudRemoveRect; QApplication::style()->drawControl( QStyle::CE_PushButton, &cloudRemoveButton, painter ); } else if ( cached && !onCloud ) { QStyleOptionButton openButton = button( OpenButton, option ); QRect openRect = position( OpenButton, option ); openButton.rect = openRect; QApplication::style()->drawControl( QStyle::CE_PushButton, &openButton, painter ); QStyleOptionButton cacheRemoveButton = button( RemoveFromCacheButton, option ); QRect cacheRemoveRect = position( RemoveFromCacheButton, option ); cacheRemoveButton.rect = cacheRemoveRect; QApplication::style()->drawControl( QStyle::CE_PushButton, &cacheRemoveButton, painter ); QStyleOptionButton uploadButton = button( UploadToCloudButton, option ); QRect uploadRect = position( UploadToCloudButton, option ); uploadButton.rect = uploadRect; QApplication::style()->drawControl( QStyle::CE_PushButton, &uploadButton, painter ); } else if ( cached && onCloud ) { QStyleOptionButton openButton = button( OpenButton, option ); QRect openRect = position( OpenButton, option ); openButton.rect = openRect; QApplication::style()->drawControl( QStyle::CE_PushButton, &openButton, painter ); QStyleOptionButton cacheRemoveButton = button( RemoveFromCacheButton, option ); QRect cacheRemoveRect = position( RemoveFromCacheButton, option ); cacheRemoveButton.rect = cacheRemoveRect; QApplication::style()->drawControl( QStyle::CE_PushButton, &cacheRemoveButton, painter ); } } QSize RouteItemDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const { if ( index.column() == 0 ) { QTextDocument doc; doc.setDefaultFont( option.font ); doc.setTextWidth( qMax( 128, m_view->contentsRect().width() - m_previewSize - buttonWidth( option ) ) ); doc.setHtml( text( index ) ); return QSize( qMax( 256, qRound( m_previewSize + buttonWidth( option ) + doc.size().width() + m_margin * 2 ) ), qMax( m_previewSize + m_margin * 2, qRound( doc.size().height() ) ) ); } return QSize(); } bool RouteItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ) { Q_UNUSED( model ); if ( ( event->type() == QEvent::MouseButtonRelease ) ) { QMouseEvent *mouseEvent = static_cast( event ); QPoint pos = mouseEvent->pos(); bool cached = index.data( CloudRouteModel::IsCached ).toBool(); bool onCloud = index.data( CloudRouteModel::IsOnCloud ).toBool(); if( cached && !onCloud ) { QRect uploadRect = position( UploadToCloudButton, option ); if ( uploadRect.contains( pos ) ) { QString timestamp = index.data( CloudRouteModel::Timestamp ).toString(); emit uploadToCloudButtonClicked( timestamp ); return true; } } if ( cached ) { QRect openRect = position( OpenButton, option ); QRect cacheRemoveRect = position( RemoveFromCacheButton, option ); if ( openRect.contains( pos ) ) { QString timestamp = index.data( CloudRouteModel::Timestamp ).toString(); emit openButtonClicked( timestamp ); return true; } else if ( cacheRemoveRect.contains( pos ) ) { QString timestamp = index.data( CloudRouteModel::Timestamp ).toString(); emit removeFromCacheButtonClicked( timestamp ); return true; } } else { QRect downloadRect = position( DownloadButton, option ); QRect cloudRemoveRect = position( RemoveFromCloudButton, option ); if ( downloadRect.contains( pos ) ) { QString timestamp = index.data( CloudRouteModel::Timestamp ).toString(); m_model->setDownloadingItem( index ); emit downloadButtonClicked( timestamp ); return true; } if ( cloudRemoveRect.contains( pos ) ) { QString timestamp = index.data( CloudRouteModel::Timestamp ).toString(); emit deleteButtonClicked( timestamp ); return true; } } } return false; } int RouteItemDelegate::buttonWidth( const QStyleOptionViewItem &option ) const { if ( m_buttonWidth <= 0 ) { int const openWidth = option.fontMetrics.size( 0, tr( "Open" ) ).width(); int const downloadWidth = option.fontMetrics.size( 0, tr( "Load" ) ).width(); int const cacheWidth = option.fontMetrics.size( 0, tr( "Remove from device" ) ).width(); int const cloudWidth = option.fontMetrics.size( 0, tr( "Delete from cloud" ) ).width(); m_buttonWidth = 2 * m_iconSize + qMax( qMax( openWidth, downloadWidth ), qMax( cacheWidth, cloudWidth ) ); } return m_buttonWidth; } QStyleOptionButton RouteItemDelegate::button( Element element, const QStyleOptionViewItem &option ) const { QStyleOptionButton result; result.state = option.state; result.state &= ~QStyle::State_HasFocus; result.palette = option.palette; result.features = QStyleOptionButton::None; switch ( element ) { case OpenButton: result.text = tr( "Open" ); result.icon = QIcon(QStringLiteral(":/marble/document-open.png")); result.iconSize = QSize( m_iconSize, m_iconSize ); break; case DownloadButton: result.text = tr( "Load" ); result.icon = QIcon(QStringLiteral(":/marble/dialog-ok.png")); result.iconSize = QSize( m_iconSize, m_iconSize ); break; case RemoveFromCacheButton: result.text = tr( "Remove from device" ); result.icon = QIcon(QStringLiteral(":/marble/edit-clear.png")); result.iconSize = QSize( m_iconSize, m_iconSize ); break; case RemoveFromCloudButton: result.text = tr( "Delete from cloud" ); result.icon = QIcon(QStringLiteral(":/marble/edit-delete.png")); result.iconSize = QSize( m_iconSize, m_iconSize ); break; case UploadToCloudButton: result.text = tr( "Upload to cloud" ); result.icon = QIcon(QStringLiteral(":/icons/cloud-upload.png")); result.iconSize = QSize( m_iconSize, m_iconSize ); break; default: // Ignored. break; } return result; } QString RouteItemDelegate::text( const QModelIndex& index ) { return QString( "%0" ).arg( index.data( CloudRouteModel::Name ).toString() ); // TODO: Show distance and duration //return QString( "%0
Duration: %1
Distance: %2" ) //.arg( index.data( CloudRouteModel::Name ).toString() ) //.arg( index.data( CloudRouteModel::Duration ).toString() ) //.arg( index.data( CloudRouteModel::Distance ).toString() ); } QRect RouteItemDelegate::position( Element element, const QStyleOptionViewItem& option ) const { int const width = buttonWidth( option ); QPoint const firstColumn = option.rect.topLeft() + QPoint( m_margin, m_margin ); QPoint const secondColumn = firstColumn + QPoint( m_previewSize + m_margin, 0 ); QPoint const thirdColumn = QPoint( option.rect.width() - width - option.decorationSize.width(), firstColumn.y() ); switch (element) { case Text: return QRect( secondColumn, QSize( thirdColumn.x() - secondColumn.x(), option.rect.height() ) ); case OpenButton: case DownloadButton: { QStyleOptionButton optionButton = button( element, option ); QSize size = option.fontMetrics.size( 0, optionButton.text ) + QSize( 4, 4 ); QSize buttonSize = QApplication::style()->sizeFromContents( QStyle::CT_PushButton, &optionButton, size ); buttonSize.setWidth( width ); return QRect( thirdColumn, buttonSize ); } case RemoveFromCacheButton: case RemoveFromCloudButton: { QStyleOptionButton optionButton = button( element, option ); QSize size = option.fontMetrics.size( 0, optionButton.text ) + QSize( 4, 4 ); QSize buttonSize = QApplication::style()->sizeFromContents( QStyle::CT_PushButton, &optionButton, size ); buttonSize.setWidth( width ); return QRect( thirdColumn + QPoint( 0, buttonSize.height() ), buttonSize ); } case Progressbar: { QSize const progressSize = QSize( width, option.fontMetrics.height() + 4 ); return QRect( thirdColumn + QPoint( 0, 10 ), progressSize ); } case Preview: { return QRect( firstColumn, QSize( m_previewSize, m_previewSize) ); } case UploadToCloudButton: { QStyleOptionButton optionButton = button( element, option ); QSize size = option.fontMetrics.size( 0, optionButton.text ) + QSize( 4, 4 ); QSize buttonSize = QApplication::style()->sizeFromContents( QStyle::CT_PushButton, &optionButton, size ); buttonSize.setWidth( width ); return QRect( thirdColumn + QPoint( 0, buttonSize.height() * 2 ), buttonSize ); } } return QRect(); } } #include "moc_RouteItemDelegate.cpp" diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlIconTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlIconTagHandler.cpp index d0c49ec7f..e26bf7247 100644 --- a/src/lib/marble/geodata/handlers/dgml/DgmlIconTagHandler.cpp +++ b/src/lib/marble/geodata/handlers/dgml/DgmlIconTagHandler.cpp @@ -1,73 +1,71 @@ /* Copyright (C) 2008 Nikolas Zimmermann This file is part of the KDE project This library 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 library 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 Library General Public License aint with this library see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // Own #include "DgmlIconTagHandler.h" // Qt #include // Marble #include "DgmlElementDictionary.h" #include "DgmlAttributeDictionary.h" #include "GeoParser.h" #include "GeoSceneHead.h" #include "GeoSceneIcon.h" #include "GeoSceneItem.h" namespace Marble { namespace dgml { DGML_DEFINE_TAG_HANDLER(Icon) GeoNode* DgmlIconTagHandler::parse(GeoParser& parser) const { // Check whether the tag is valid Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Icon))); QString pixmapRelativePath = parser.attribute(dgmlAttr_pixmap).trimmed(); QColor color; - if (pixmapRelativePath.isEmpty()) { - color.setNamedColor(parser.attribute(dgmlAttr_color).trimmed()); - } + color.setNamedColor(parser.attribute(dgmlAttr_color).trimmed()); GeoSceneIcon *icon = nullptr; // Checking for parent item GeoStackItem parentItem = parser.parentElement(); if (parentItem.represents(dgmlTag_Head)) { icon = parentItem.nodeAs()->icon(); icon->setPixmap( pixmapRelativePath ); icon->setColor( color ); } if (parentItem.represents(dgmlTag_Item)) { icon = parentItem.nodeAs()->icon(); icon->setPixmap( pixmapRelativePath ); icon->setColor( color ); } return nullptr; } } }