mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-19 00:07:15 -04:00
Merge pull request #6865 from PeterPetrik/qgsquick_1_canvas_merge
[FEATURE] Introduction of QGIS Quick library
This commit is contained in:
commit
29489e1056
@ -40,6 +40,7 @@ echo "${bold}Running cmake...${endbold}"
|
|||||||
cmake \
|
cmake \
|
||||||
-GNinja \
|
-GNinja \
|
||||||
-DUSE_CCACHE=OFF \
|
-DUSE_CCACHE=OFF \
|
||||||
|
-DWITH_QUICK=ON \
|
||||||
-DWITH_3D=ON \
|
-DWITH_3D=ON \
|
||||||
-DWITH_STAGED_PLUGINS=ON \
|
-DWITH_STAGED_PLUGINS=ON \
|
||||||
-DWITH_GRASS=OFF \
|
-DWITH_GRASS=OFF \
|
||||||
|
@ -33,11 +33,17 @@ RUN apt-get update \
|
|||||||
libqca-qt5-2-dev \
|
libqca-qt5-2-dev \
|
||||||
libqca-qt5-2-plugins \
|
libqca-qt5-2-plugins \
|
||||||
libqt53drender5 \
|
libqt53drender5 \
|
||||||
|
libqt5concurrent5 \
|
||||||
libqt5opengl5-dev \
|
libqt5opengl5-dev \
|
||||||
|
libqt5positioning5 \
|
||||||
|
libqt5qml5 \
|
||||||
|
libqt5quick5 \
|
||||||
|
libqt5quickcontrols2-5 \
|
||||||
libqt5scintilla2-dev \
|
libqt5scintilla2-dev \
|
||||||
libqt5sql5-sqlite \
|
libqt5sql5-sqlite \
|
||||||
libqt5svg5-dev \
|
libqt5svg5-dev \
|
||||||
libqt5webkit5-dev \
|
libqt5webkit5-dev \
|
||||||
|
libqt5xml5 \
|
||||||
libqt5xmlpatterns5-dev \
|
libqt5xmlpatterns5-dev \
|
||||||
libqwt-qt5-dev \
|
libqwt-qt5-dev \
|
||||||
libspatialindex-dev \
|
libspatialindex-dev \
|
||||||
@ -77,6 +83,8 @@ RUN apt-get update \
|
|||||||
qt3d-scene2d-plugin \
|
qt3d-scene2d-plugin \
|
||||||
qt5keychain-dev \
|
qt5keychain-dev \
|
||||||
qtbase5-dev \
|
qtbase5-dev \
|
||||||
|
qtdeclarative5-dev-tools \
|
||||||
|
qtdeclarative5-qtquick2-plugin \
|
||||||
qtpositioning5-dev \
|
qtpositioning5-dev \
|
||||||
qttools5-dev \
|
qttools5-dev \
|
||||||
qttools5-dev-tools \
|
qttools5-dev-tools \
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -30,6 +30,8 @@ desktop.ini
|
|||||||
doc/INSTALL.tex
|
doc/INSTALL.tex
|
||||||
i18n/*.qm
|
i18n/*.qm
|
||||||
Makefile
|
Makefile
|
||||||
|
*.pro.user
|
||||||
|
*.stash
|
||||||
ms-windows/*.exe*
|
ms-windows/*.exe*
|
||||||
ms-windows/Installer-Files/postinstall.bat
|
ms-windows/Installer-Files/postinstall.bat
|
||||||
ms-windows/Installer-Files/preremove.bat
|
ms-windows/Installer-Files/preremove.bat
|
||||||
|
@ -71,6 +71,8 @@ IF(WITH_CORE)
|
|||||||
|
|
||||||
SET (WITH_3D FALSE CACHE BOOL "Determines whether QGIS 3D library should be built")
|
SET (WITH_3D FALSE CACHE BOOL "Determines whether QGIS 3D library should be built")
|
||||||
|
|
||||||
|
SET (WITH_QUICK FALSE CACHE BOOL "Determines whether QGIS Quick library should be built")
|
||||||
|
|
||||||
# server disabled default because it needs FastCGI (which is optional dependency)
|
# server disabled default because it needs FastCGI (which is optional dependency)
|
||||||
SET (WITH_SERVER FALSE CACHE BOOL "Determines whether QGIS server should be built")
|
SET (WITH_SERVER FALSE CACHE BOOL "Determines whether QGIS server should be built")
|
||||||
IF(WITH_SERVER)
|
IF(WITH_SERVER)
|
||||||
@ -322,6 +324,18 @@ IF(WITH_CORE)
|
|||||||
ENDIF (WITH_3D)
|
ENDIF (WITH_3D)
|
||||||
INCLUDE("cmake/modules/ECMQt4To5Porting.cmake")
|
INCLUDE("cmake/modules/ECMQt4To5Porting.cmake")
|
||||||
MESSAGE(STATUS "Found Qt version: ${Qt5Core_VERSION_STRING}")
|
MESSAGE(STATUS "Found Qt version: ${Qt5Core_VERSION_STRING}")
|
||||||
|
IF (WITH_QUICK)
|
||||||
|
FIND_PACKAGE(Qt5Qml REQUIRED)
|
||||||
|
FIND_PACKAGE(Qt5Quick REQUIRED)
|
||||||
|
IF(${CMAKE_SYSTEM_NAME} MATCHES "Android")
|
||||||
|
FIND_PACKAGE(Qt5AndroidExtras)
|
||||||
|
ELSE(${CMAKE_SYSTEM_NAME} MATCHES "Android")
|
||||||
|
FIND_PACKAGE(QtQmlTools REQUIRED)
|
||||||
|
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Android")
|
||||||
|
|
||||||
|
# following variable is used in qgsconfig.h
|
||||||
|
SET (HAVE_QUICK TRUE)
|
||||||
|
ENDIF (WITH_QUICK)
|
||||||
|
|
||||||
IF(WITH_QTWEBKIT)
|
IF(WITH_QTWEBKIT)
|
||||||
SET(OPTIONAL_QTWEBKIT ${Qt5WebKitWidgets_LIBRARIES})
|
SET(OPTIONAL_QTWEBKIT ${Qt5WebKitWidgets_LIBRARIES})
|
||||||
@ -373,6 +387,9 @@ ENDIF(WITH_CORE)
|
|||||||
# build our version of astyle
|
# build our version of astyle
|
||||||
SET (WITH_ASTYLE FALSE CACHE BOOL "If you plan to contribute you should reindent with scripts/prepare-commit.sh (using 'our' astyle)")
|
SET (WITH_ASTYLE FALSE CACHE BOOL "If you plan to contribute you should reindent with scripts/prepare-commit.sh (using 'our' astyle)")
|
||||||
|
|
||||||
|
# QML
|
||||||
|
SET(QML_IMPORT_PATH "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" CACHE PATH "QML directory for QML autocomplete")
|
||||||
|
|
||||||
#############################################################
|
#############################################################
|
||||||
# testing
|
# testing
|
||||||
# whether unit tests should be build
|
# whether unit tests should be build
|
||||||
@ -513,6 +530,7 @@ IF (WITH_CORE)
|
|||||||
SET (DEFAULT_DATA_SUBDIR .)
|
SET (DEFAULT_DATA_SUBDIR .)
|
||||||
SET (DEFAULT_PLUGIN_SUBDIR plugins)
|
SET (DEFAULT_PLUGIN_SUBDIR plugins)
|
||||||
SET (DEFAULT_INCLUDE_SUBDIR include)
|
SET (DEFAULT_INCLUDE_SUBDIR include)
|
||||||
|
SET (DEFAULT_QML_SUBDIR qml)
|
||||||
|
|
||||||
SET (DEFAULT_SERVER_MODULE_SUBDIR server)
|
SET (DEFAULT_SERVER_MODULE_SUBDIR server)
|
||||||
|
|
||||||
@ -583,6 +601,7 @@ IF (WITH_CORE)
|
|||||||
SET (DEFAULT_PLUGIN_SUBDIR ../PlugIns/qgis)
|
SET (DEFAULT_PLUGIN_SUBDIR ../PlugIns/qgis)
|
||||||
SET (QGIS_PLUGIN_SUBDIR_REV ../../MacOS)
|
SET (QGIS_PLUGIN_SUBDIR_REV ../../MacOS)
|
||||||
SET (DEFAULT_INCLUDE_SUBDIR include/qgis)
|
SET (DEFAULT_INCLUDE_SUBDIR include/qgis)
|
||||||
|
SET (DEFAULT_QML_SUBDIR qml)
|
||||||
|
|
||||||
# Set server moodules path to DEFAULT_LIBEXEC_SUBDIR+'/server'
|
# Set server moodules path to DEFAULT_LIBEXEC_SUBDIR+'/server'
|
||||||
SET (DEFAULT_SERVER_MODULE_SUBDIR ${DEFAULT_LIBEXEC_SUBDIR}/server)
|
SET (DEFAULT_SERVER_MODULE_SUBDIR ${DEFAULT_LIBEXEC_SUBDIR}/server)
|
||||||
@ -610,6 +629,7 @@ IF (WITH_CORE)
|
|||||||
SET (DEFAULT_LIBEXEC_SUBDIR lib${LIB_SUFFIX}/qgis)
|
SET (DEFAULT_LIBEXEC_SUBDIR lib${LIB_SUFFIX}/qgis)
|
||||||
SET (DEFAULT_PLUGIN_SUBDIR lib${LIB_SUFFIX}/qgis/plugins)
|
SET (DEFAULT_PLUGIN_SUBDIR lib${LIB_SUFFIX}/qgis/plugins)
|
||||||
SET (DEFAULT_INCLUDE_SUBDIR include/qgis)
|
SET (DEFAULT_INCLUDE_SUBDIR include/qgis)
|
||||||
|
SET (DEFAULT_QML_SUBDIR qml)
|
||||||
|
|
||||||
SET (DEFAULT_SERVER_MODULE_SUBDIR ${DEFAULT_LIBEXEC_SUBDIR}/server)
|
SET (DEFAULT_SERVER_MODULE_SUBDIR ${DEFAULT_LIBEXEC_SUBDIR}/server)
|
||||||
ENDIF (APPLE)
|
ENDIF (APPLE)
|
||||||
@ -658,6 +678,7 @@ SET (QGIS_LIBEXEC_SUBDIR ${DEFAULT_LIBEXEC_SUBDIR} CACHE STRING "Subdirectory wh
|
|||||||
SET (QGIS_DATA_SUBDIR ${DEFAULT_DATA_SUBDIR} CACHE STRING "Subdirectory where QGIS data will be installed")
|
SET (QGIS_DATA_SUBDIR ${DEFAULT_DATA_SUBDIR} CACHE STRING "Subdirectory where QGIS data will be installed")
|
||||||
SET (QGIS_PLUGIN_SUBDIR ${DEFAULT_PLUGIN_SUBDIR} CACHE STRING "Subdirectory where plugins will be installed")
|
SET (QGIS_PLUGIN_SUBDIR ${DEFAULT_PLUGIN_SUBDIR} CACHE STRING "Subdirectory where plugins will be installed")
|
||||||
SET (QGIS_INCLUDE_SUBDIR ${DEFAULT_INCLUDE_SUBDIR} CACHE STRING "Subdirectory where header files will be installed")
|
SET (QGIS_INCLUDE_SUBDIR ${DEFAULT_INCLUDE_SUBDIR} CACHE STRING "Subdirectory where header files will be installed")
|
||||||
|
SET (QGIS_QML_SUBDIR ${DEFAULT_QML_SUBDIR} CACHE STRING "Subdirectory where qml files/libraries will be installed")
|
||||||
|
|
||||||
SET (QGIS_SERVER_MODULE_SUBDIR ${DEFAULT_SERVER_MODULE_SUBDIR} CACHE STRING "Subdirectory where server modules will be installed")
|
SET (QGIS_SERVER_MODULE_SUBDIR ${DEFAULT_SERVER_MODULE_SUBDIR} CACHE STRING "Subdirectory where server modules will be installed")
|
||||||
|
|
||||||
@ -673,6 +694,7 @@ SET (QGIS_LIBEXEC_DIR ${QGIS_LIBEXEC_SUBDIR})
|
|||||||
SET (QGIS_DATA_DIR ${QGIS_DATA_SUBDIR})
|
SET (QGIS_DATA_DIR ${QGIS_DATA_SUBDIR})
|
||||||
SET (QGIS_PLUGIN_DIR ${QGIS_PLUGIN_SUBDIR})
|
SET (QGIS_PLUGIN_DIR ${QGIS_PLUGIN_SUBDIR})
|
||||||
SET (QGIS_INCLUDE_DIR ${QGIS_INCLUDE_SUBDIR})
|
SET (QGIS_INCLUDE_DIR ${QGIS_INCLUDE_SUBDIR})
|
||||||
|
SET (QGIS_QML_DIR ${QGIS_QML_SUBDIR})
|
||||||
|
|
||||||
SET (QGIS_SERVER_MODULE_DIR ${QGIS_SERVER_MODULE_SUBDIR})
|
SET (QGIS_SERVER_MODULE_DIR ${QGIS_SERVER_MODULE_SUBDIR})
|
||||||
|
|
||||||
|
47
cmake/FindQtQmlTools.cmake
Normal file
47
cmake/FindQtQmlTools.cmake
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# Qt QML Tools
|
||||||
|
# ~~~~~~~~~~~~
|
||||||
|
#
|
||||||
|
# To generate qmltypes files required by Qt Creator to allow QML code inspection
|
||||||
|
# (http://doc.qt.io/qtcreator/creator-qml-modules-with-plugins.html#generating-qmltypes-files)
|
||||||
|
# we need to have installed qmlplugindump unity (shipped with Qt 4.8 and later)
|
||||||
|
# http://doc.qt.io/qtcreator/creator-qml-modules-with-plugins.html#dumping-plugins-automatically
|
||||||
|
#
|
||||||
|
# Find the installed version of qmlplugindump utility.
|
||||||
|
# FindQtQmlTools should be called after Qt5 has been found
|
||||||
|
#
|
||||||
|
# This file defines the following variables:
|
||||||
|
#
|
||||||
|
# QMLPLUGINDUMP_FOUND - system has qmlplugindump
|
||||||
|
# QMLPLUGINDUMP_EXECUTABLE - Path to qmlplugindump executable
|
||||||
|
#
|
||||||
|
# Also defines MACRO to create qmltypes file, when QML directory is supplied
|
||||||
|
#
|
||||||
|
# Copyright (c) 2017, Peter Petrik <zilolv at gmail dot com>
|
||||||
|
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||||
|
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||||
|
|
||||||
|
MACRO(FIND_QMLPLUGINDUMP)
|
||||||
|
IF(NOT QMLPLUGINDUMP_EXECUTABLE)
|
||||||
|
IF (MSVC)
|
||||||
|
FIND_PROGRAM(QMLPLUGINDUMP_EXECUTABLE qmlplugindump.exe)
|
||||||
|
ELSE (MSVC)
|
||||||
|
FIND_PROGRAM(QMLPLUGINDUMP_EXECUTABLE qmlplugindump)
|
||||||
|
ENDIF (MSVC)
|
||||||
|
ENDIF(NOT QMLPLUGINDUMP_EXECUTABLE)
|
||||||
|
|
||||||
|
IF (QMLPLUGINDUMP_EXECUTABLE)
|
||||||
|
SET(QMLPLUGINDUMP_FOUND TRUE)
|
||||||
|
MESSAGE(STATUS "Found qmlplugindump: ${QMLPLUGINDUMP_EXECUTABLE}")
|
||||||
|
ELSE()
|
||||||
|
SET(QMLPLUGINDUMP_FOUND FALSE)
|
||||||
|
IF (QMLPLUGINDUMP_FIND_REQUIRED)
|
||||||
|
MESSAGE(FATAL_ERROR "Could not find qmlplugindump")
|
||||||
|
ELSE (QMLPLUGINDUMP_FIND_REQUIRED)
|
||||||
|
MESSAGE(WARNING "Could not find qmlplugindump")
|
||||||
|
ENDIF (QMLPLUGINDUMP_FIND_REQUIRED)
|
||||||
|
ENDIF (QMLPLUGINDUMP_EXECUTABLE)
|
||||||
|
ENDMACRO(FIND_QMLPLUGINDUMP)
|
||||||
|
|
||||||
|
IF (NOT QMLPLUGINDUMP_FOUND)
|
||||||
|
FIND_QMLPLUGINDUMP()
|
||||||
|
ENDIF (NOT QMLPLUGINDUMP_FOUND)
|
@ -25,6 +25,7 @@
|
|||||||
#define QGIS_DATA_SUBDIR "${QGIS_DATA_SUBDIR}"
|
#define QGIS_DATA_SUBDIR "${QGIS_DATA_SUBDIR}"
|
||||||
#define QGIS_LIBEXEC_SUBDIR "${QGIS_LIBEXEC_SUBDIR}"
|
#define QGIS_LIBEXEC_SUBDIR "${QGIS_LIBEXEC_SUBDIR}"
|
||||||
#define QGIS_LIB_SUBDIR "${QGIS_LIB_SUBDIR}"
|
#define QGIS_LIB_SUBDIR "${QGIS_LIB_SUBDIR}"
|
||||||
|
#define QGIS_QML_SUBDIR "${QGIS_QML_SUBDIR}"
|
||||||
#define CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}"
|
#define CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}"
|
||||||
#define CMAKE_SOURCE_DIR "${CMAKE_SOURCE_DIR}"
|
#define CMAKE_SOURCE_DIR "${CMAKE_SOURCE_DIR}"
|
||||||
|
|
||||||
@ -64,5 +65,7 @@
|
|||||||
|
|
||||||
#cmakedefine QGISDEBUG
|
#cmakedefine QGISDEBUG
|
||||||
|
|
||||||
|
#cmakedefine HAVE_QUICK
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -100,6 +100,8 @@ IF(WITH_APIDOC)
|
|||||||
${CMAKE_SOURCE_DIR}/src/3d/symbols
|
${CMAKE_SOURCE_DIR}/src/3d/symbols
|
||||||
${CMAKE_SOURCE_DIR}/src/3d/terrain
|
${CMAKE_SOURCE_DIR}/src/3d/terrain
|
||||||
${CMAKE_SOURCE_DIR}/src/plugins
|
${CMAKE_SOURCE_DIR}/src/plugins
|
||||||
|
${CMAKE_SOURCE_DIR}/src/quickgui
|
||||||
|
${CMAKE_SOURCE_DIR}/src/quickgui/plugin
|
||||||
)
|
)
|
||||||
|
|
||||||
IF(WITH_SERVER_PLUGINS)
|
IF(WITH_SERVER_PLUGINS)
|
||||||
|
@ -71,6 +71,7 @@ Nikos Alexandris
|
|||||||
Paolo Cavallini
|
Paolo Cavallini
|
||||||
Paul Blottiere
|
Paul Blottiere
|
||||||
Paul Ramsey
|
Paul Ramsey
|
||||||
|
Peter Petrik
|
||||||
Pierre Auckenthaler
|
Pierre Auckenthaler
|
||||||
Raymond Nijssen
|
Raymond Nijssen
|
||||||
Richard Duivenvoorde
|
Richard Duivenvoorde
|
||||||
|
@ -45,6 +45,10 @@ website:
|
|||||||
<a href="https://qgis.org/api/1.7">1.7</a> and
|
<a href="https://qgis.org/api/1.7">1.7</a> and
|
||||||
<a href="https://qgis.org/api/1.6">1.6</a>
|
<a href="https://qgis.org/api/1.6">1.6</a>
|
||||||
|
|
||||||
|
\section qgsquick_docs QgsQuick library documentation
|
||||||
|
|
||||||
|
See \ref qgsquick for information about QGIS Quick (QML) components library
|
||||||
|
|
||||||
\section index_maillist Mailing Lists
|
\section index_maillist Mailing Lists
|
||||||
|
|
||||||
For support we encourage you to join our <a
|
For support we encourage you to join our <a
|
||||||
|
@ -37,3 +37,8 @@ Contains classes related to implementation of QGIS plugins.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/** @defgroup quick QgsQuick library
|
||||||
|
|
||||||
|
The QgsQuick library is built on top of the CORE library and Qt Quick/QML framework. It adds reusable GUI Quick Components, mainly for mobile devices.
|
||||||
|
|
||||||
|
*/
|
||||||
|
61
doc/qgsquick.dox
Normal file
61
doc/qgsquick.dox
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*! \page qgsquick QGIS Quick Documentation
|
||||||
|
|
||||||
|
\tableofcontents
|
||||||
|
|
||||||
|
\section qgsquick_overview Overview
|
||||||
|
|
||||||
|
QGIS Quick is a QT Quick based GUI library primarily for mobile/tablet devices. Covering basic GIS components (e.g. MapCanvas, Scalebar),
|
||||||
|
it simplifies creation of a mobile applications for surveys, data gathering or other on-site work. Qt Quick provides tools
|
||||||
|
to create a rich application with a fluid and dynamic user interface. Additionally, Qt Quick Controls 2 provides highly
|
||||||
|
optimized controls for embedded/mobile devices with limited resources.
|
||||||
|
|
||||||
|
QGIS Quick consists of a Qt plugin that provides the QML components and of a shared library that can be used from C++ code.
|
||||||
|
|
||||||
|
\subsection qgsquick_overview_widgets QML Classes
|
||||||
|
\subsubsection qgsquick_overview_widgets_mapcanvas MapCanvas
|
||||||
|
|
||||||
|
\section qgsquick_styling Styling
|
||||||
|
|
||||||
|
Since the QGIS Quick library is meant to be reusable for a wide variety of applications with different styles/themes of the user
|
||||||
|
interface, some effort has been done to allow developers customize the colors and layouts of the components. Individual
|
||||||
|
components either have attributes for customization (e.g. ScaleBar has "barColor", "barBackgroundColor" properties) or more complex
|
||||||
|
components accept a custom styling object (e.g. FeatureForm has "style" property of type FeatureFormStyling with a hierarchy of color
|
||||||
|
and layout properties).
|
||||||
|
|
||||||
|
\section qgsquick_versioning_api Versioning and API stability
|
||||||
|
|
||||||
|
QML engine supports versioning of individual components with libraries - a single component may be available in multiple versions
|
||||||
|
with slightly different set of features. This is allows QML libraries to keep API compatibility with older code.
|
||||||
|
|
||||||
|
QGIS Quick library is currently in version 0.1 and since it is still a very new library, there are no API stability guarantees:
|
||||||
|
the following releases of QGIS may ship updates to components while keeping the same version or even remove some components.
|
||||||
|
Over time we expect that as the library will become stable, we will deliver stable API just like with the other QGIS libraries.
|
||||||
|
|
||||||
|
\section qgsquick_gui Designing scalable applications
|
||||||
|
|
||||||
|
Qt Quick uses pixel sizes for the visual items. When building applications that may run on devices with varying screen DPI,
|
||||||
|
this is a problem as the absolute pixel values make the application look different depending on the screen pixel density.
|
||||||
|
We recommend to use values device independent pixels ("dp"). It is a concept used on mobile devices, where an item of width of 10dp
|
||||||
|
will have always the same physical size (e.g. in millimeters) regardless of the screen density. To set width of an item to 10dp
|
||||||
|
in QML, one would write: "width: 10 * QgsQuick.Utils.dp".
|
||||||
|
|
||||||
|
\section qgsquick_lib Building the library
|
||||||
|
|
||||||
|
The QGIS Quick library is not built by default because QGIS application currently does not use it. In order to build the library
|
||||||
|
please make sure that WITH_QUICK variable in CMake configuration is set to ON.
|
||||||
|
|
||||||
|
It is recommended to build with CMake variable ENABLE_TESTS set to ON because that will also build a small example application
|
||||||
|
that uses Qt Quick components. In the generated project you should see target "qgis_quickapp".
|
||||||
|
|
||||||
|
The built QML plugin is installed to a dedicated directory - see QgsApplication::qmlImportPath(). When using QGIS Quick components,
|
||||||
|
it is necessary to either use QQmlEngine::addImportPath() to add that directory or to specify QML2_IMPORT_PATH environment variable.
|
||||||
|
|
||||||
|
\section qgsquick_demo_app Demo application
|
||||||
|
|
||||||
|
A demo application with some basic componets and functionality is available on https://github.com/lutraconsulting/qgis-quick-demo-app
|
||||||
|
|
||||||
|
The demo application repository contains also instructions on how to build the application, QGIS Quick and other dependencies on Android.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
@ -432,6 +432,14 @@ Returns the path containing qgis_core, qgis_gui, qgispython (and other) librarie
|
|||||||
static QString libexecPath();
|
static QString libexecPath();
|
||||||
%Docstring
|
%Docstring
|
||||||
Returns the path with utility executables (help viewer, crssync, ...)
|
Returns the path with utility executables (help viewer, crssync, ...)
|
||||||
|
%End
|
||||||
|
|
||||||
|
static QString qmlImportPath();
|
||||||
|
%Docstring
|
||||||
|
Returns the path where QML components are installed for QGIS Quick library. Returns
|
||||||
|
empty string when QGIS is built without Quick support
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
%End
|
%End
|
||||||
|
|
||||||
static void setPrefixPath( const QString &prefixPath, bool useDefaultPaths = false );
|
static void setPrefixPath( const QString &prefixPath, bool useDefaultPaths = false );
|
||||||
|
@ -35,3 +35,6 @@ IF (WITH_CUSTOM_WIDGETS)
|
|||||||
ADD_SUBDIRECTORY(customwidgets)
|
ADD_SUBDIRECTORY(customwidgets)
|
||||||
ENDIF (WITH_CUSTOM_WIDGETS)
|
ENDIF (WITH_CUSTOM_WIDGETS)
|
||||||
|
|
||||||
|
IF (WITH_QUICK)
|
||||||
|
ADD_SUBDIRECTORY(quickgui)
|
||||||
|
ENDIF (WITH_QUICK)
|
||||||
|
@ -91,6 +91,7 @@ QString ABISYM( QgsApplication::mPluginPath );
|
|||||||
QString ABISYM( QgsApplication::mPkgDataPath );
|
QString ABISYM( QgsApplication::mPkgDataPath );
|
||||||
QString ABISYM( QgsApplication::mLibraryPath );
|
QString ABISYM( QgsApplication::mLibraryPath );
|
||||||
QString ABISYM( QgsApplication::mLibexecPath );
|
QString ABISYM( QgsApplication::mLibexecPath );
|
||||||
|
QString ABISYM( QgsApplication::mQmlImportPath );
|
||||||
QString ABISYM( QgsApplication::mThemeName );
|
QString ABISYM( QgsApplication::mThemeName );
|
||||||
QString ABISYM( QgsApplication::mUIThemeName );
|
QString ABISYM( QgsApplication::mUIThemeName );
|
||||||
QString ABISYM( QgsApplication::mProfilePath );
|
QString ABISYM( QgsApplication::mProfilePath );
|
||||||
@ -205,6 +206,9 @@ void QgsApplication::init( QString profileFolder )
|
|||||||
ABISYM( mLibexecPath ) = ABISYM( mBuildOutputPath ) + '/' + QGIS_LIBEXEC_SUBDIR + '/' + ABISYM( mCfgIntDir ) + '/';
|
ABISYM( mLibexecPath ) = ABISYM( mBuildOutputPath ) + '/' + QGIS_LIBEXEC_SUBDIR + '/' + ABISYM( mCfgIntDir ) + '/';
|
||||||
#else
|
#else
|
||||||
ABISYM( mLibexecPath ) = ABISYM( mBuildOutputPath ) + '/' + QGIS_LIBEXEC_SUBDIR + '/';
|
ABISYM( mLibexecPath ) = ABISYM( mBuildOutputPath ) + '/' + QGIS_LIBEXEC_SUBDIR + '/';
|
||||||
|
#endif
|
||||||
|
#if defined( HAVE_QUICK )
|
||||||
|
ABISYM( mQmlImportPath ) = ABISYM( mBuildOutputPath ) + '/' + QGIS_QML_SUBDIR + '/';
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -397,6 +401,9 @@ void QgsApplication::setPrefixPath( const QString &prefixPath, bool useDefaultPa
|
|||||||
}
|
}
|
||||||
ABISYM( mLibraryPath ) = ABISYM( mPrefixPath ) + '/' + QGIS_LIB_SUBDIR + '/';
|
ABISYM( mLibraryPath ) = ABISYM( mPrefixPath ) + '/' + QGIS_LIB_SUBDIR + '/';
|
||||||
ABISYM( mLibexecPath ) = ABISYM( mPrefixPath ) + '/' + QGIS_LIBEXEC_SUBDIR + '/';
|
ABISYM( mLibexecPath ) = ABISYM( mPrefixPath ) + '/' + QGIS_LIBEXEC_SUBDIR + '/';
|
||||||
|
#if defined( HAVE_QUICK )
|
||||||
|
ABISYM( mQmlImportPath ) = ABISYM( mPrefixPath ) + '/' + QGIS_QML_SUBDIR + '/';
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsApplication::setPluginPath( const QString &pluginPath )
|
void QgsApplication::setPluginPath( const QString &pluginPath )
|
||||||
@ -1002,6 +1009,11 @@ QString QgsApplication::libexecPath()
|
|||||||
return ABISYM( mLibexecPath );
|
return ABISYM( mLibexecPath );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString QgsApplication::qmlImportPath()
|
||||||
|
{
|
||||||
|
return ABISYM( mQmlImportPath );
|
||||||
|
}
|
||||||
|
|
||||||
QgsApplication::endian_t QgsApplication::endian()
|
QgsApplication::endian_t QgsApplication::endian()
|
||||||
{
|
{
|
||||||
return ( htonl( 1 ) == 1 ) ? XDR : NDR;
|
return ( htonl( 1 ) == 1 ) ? XDR : NDR;
|
||||||
|
@ -406,6 +406,14 @@ class CORE_EXPORT QgsApplication : public QApplication
|
|||||||
//! Returns the path with utility executables (help viewer, crssync, ...)
|
//! Returns the path with utility executables (help viewer, crssync, ...)
|
||||||
static QString libexecPath();
|
static QString libexecPath();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the path where QML components are installed for QGIS Quick library. Returns
|
||||||
|
* empty string when QGIS is built without Quick support
|
||||||
|
*
|
||||||
|
* \since QGIS 3.2
|
||||||
|
*/
|
||||||
|
static QString qmlImportPath();
|
||||||
|
|
||||||
//! Alters prefix path - used by 3rd party apps
|
//! Alters prefix path - used by 3rd party apps
|
||||||
static void setPrefixPath( const QString &prefixPath, bool useDefaultPaths = false );
|
static void setPrefixPath( const QString &prefixPath, bool useDefaultPaths = false );
|
||||||
|
|
||||||
@ -759,6 +767,7 @@ class CORE_EXPORT QgsApplication : public QApplication
|
|||||||
static QString ABISYM( mPkgDataPath );
|
static QString ABISYM( mPkgDataPath );
|
||||||
static QString ABISYM( mLibraryPath );
|
static QString ABISYM( mLibraryPath );
|
||||||
static QString ABISYM( mLibexecPath );
|
static QString ABISYM( mLibexecPath );
|
||||||
|
static QString ABISYM( mQmlImportPath );
|
||||||
static QString ABISYM( mThemeName );
|
static QString ABISYM( mThemeName );
|
||||||
static QStringList ABISYM( mDefaultSvgPaths );
|
static QStringList ABISYM( mDefaultSvgPaths );
|
||||||
static QMap<QString, QString> ABISYM( mSystemEnvVars );
|
static QMap<QString, QString> ABISYM( mSystemEnvVars );
|
||||||
|
@ -25,9 +25,12 @@ QgsRelationManager::QgsRelationManager( QgsProject *project )
|
|||||||
: QObject( project )
|
: QObject( project )
|
||||||
, mProject( project )
|
, mProject( project )
|
||||||
{
|
{
|
||||||
connect( project, &QgsProject::readProject, this, &QgsRelationManager::readProject );
|
if ( mProject )
|
||||||
connect( project, &QgsProject::writeProject, this, &QgsRelationManager::writeProject );
|
{
|
||||||
connect( project, &QgsProject::layersRemoved, this, &QgsRelationManager::layersRemoved );
|
connect( project, &QgsProject::readProject, this, &QgsRelationManager::readProject );
|
||||||
|
connect( project, &QgsProject::writeProject, this, &QgsRelationManager::writeProject );
|
||||||
|
connect( project, &QgsProject::layersRemoved, this, &QgsRelationManager::layersRemoved );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsRelationManager::setRelations( const QList<QgsRelation> &relations )
|
void QgsRelationManager::setRelations( const QList<QgsRelation> &relations )
|
||||||
|
121
src/quickgui/CMakeLists.txt
Normal file
121
src/quickgui/CMakeLists.txt
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
############################################################
|
||||||
|
# sources
|
||||||
|
SET(QGIS_QUICK_GUI_MOC_HDRS
|
||||||
|
qgsquickmapcanvasmap.h
|
||||||
|
qgsquickmapsettings.h
|
||||||
|
qgsquickutils.h
|
||||||
|
)
|
||||||
|
|
||||||
|
SET(QGIS_QUICK_GUI_HDRS
|
||||||
|
)
|
||||||
|
|
||||||
|
SET(QGIS_QUICK_GUI_SRC
|
||||||
|
qgsquickmapcanvasmap.cpp
|
||||||
|
qgsquickmapsettings.cpp
|
||||||
|
qgsquickutils.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES(
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/annotations
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/auth
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/composer
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/fieldformatter
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/geometry
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/layertree
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/layout
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/locator
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/metadata
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/providers/memory
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/raster
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/scalebar
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/symbology
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/effects
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/metadata
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/expression
|
||||||
|
|
||||||
|
${CMAKE_BINARY_DIR}/src/core
|
||||||
|
)
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES(SYSTEM
|
||||||
|
${LIBZIP_INCLUDE_DIRS}
|
||||||
|
${SPATIALINDEX_INCLUDE_DIR}
|
||||||
|
${PROJ_INCLUDE_DIR}
|
||||||
|
${GEOS_INCLUDE_DIR}
|
||||||
|
${GDAL_INCLUDE_DIR}
|
||||||
|
${EXPAT_INCLUDE_DIR}
|
||||||
|
${SQLITE3_INCLUDE_DIR}
|
||||||
|
${SPATIALITE_INCLUDE_DIR}
|
||||||
|
${QCA_INCLUDE_DIR}
|
||||||
|
${QTKEYCHAIN_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
ADD_DEFINITIONS(-DCORE_EXPORT=)
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
# qgis_quick shared library
|
||||||
|
QT5_WRAP_CPP(QGIS_QUICK_GUI_MOC_SRCS ${QGIS_QUICK_GUI_MOC_HDRS})
|
||||||
|
IF(MSVC)
|
||||||
|
SET_SOURCE_FILES_PROPERTIES(${QGIS_QUICK_GUI_MOC_SRCS} PROPERTIES COMPILE_FLAGS "/wd4512 /wd4996" )
|
||||||
|
ELSE(MSVC)
|
||||||
|
SET_SOURCE_FILES_PROPERTIES(${QGIS_QUICK_GUI_MOC_SRCS} PROPERTIES COMPILE_FLAGS "-Wno-deprecated-declarations" )
|
||||||
|
ENDIF(MSVC)
|
||||||
|
|
||||||
|
ADD_LIBRARY(qgis_quick SHARED
|
||||||
|
${QGIS_QUICK_GUI_IMAGE_RCC_SRCS}
|
||||||
|
${QGIS_QUICK_GUI_SRC}
|
||||||
|
${QGIS_QUICK_GUI_MOC_HDRS}
|
||||||
|
${QGIS_QUICK_GUI_MOC_SRCS}
|
||||||
|
${QGIS_QUICK_GUI_HDRS})
|
||||||
|
TARGET_LINK_LIBRARIES(qgis_quick Qt5::Quick Qt5::Qml Qt5::Xml Qt5::Concurrent Qt5::Positioning qgis_core)
|
||||||
|
IF(CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||||
|
TARGET_LINK_LIBRARIES(qgis_quick Qt5::AndroidExtras)
|
||||||
|
ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||||
|
TARGET_COMPILE_DEFINITIONS(qgis_quick PRIVATE "-DQT_NO_FOREACH")
|
||||||
|
|
||||||
|
GENERATE_EXPORT_HEADER(
|
||||||
|
qgis_quick
|
||||||
|
BASE_NAME QUICK
|
||||||
|
EXPORT_FILE_NAME qgis_quick.h
|
||||||
|
)
|
||||||
|
SET(QGIS_CORE_HDRS ${QGIS_QUICK_GUI_HDRS} ${CMAKE_CURRENT_BINARY_DIR}/qgis_core.h)
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
INSTALL(TARGETS qgis_quick
|
||||||
|
RUNTIME DESTINATION ${QGIS_BIN_DIR}
|
||||||
|
LIBRARY DESTINATION ${QGIS_LIB_DIR}
|
||||||
|
ARCHIVE DESTINATION ${QGIS_LIB_DIR}
|
||||||
|
FRAMEWORK DESTINATION ${QGIS_FW_SUBDIR}
|
||||||
|
PUBLIC_HEADER DESTINATION ${QGIS_INCLUDE_DIR})
|
||||||
|
|
||||||
|
IF(NOT APPLE)
|
||||||
|
INSTALL(FILES ${QGIS_QUICK_GUI_HDRS} ${QGIS_QUICK_GUI_MOC_HDRS} DESTINATION ${QGIS_INCLUDE_DIR})
|
||||||
|
ELSE(NOT APPLE)
|
||||||
|
SET_TARGET_PROPERTIES(qgis_quick PROPERTIES
|
||||||
|
CLEAN_DIRECT_OUTPUT 1
|
||||||
|
FRAMEWORK 1
|
||||||
|
FRAMEWORK_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}"
|
||||||
|
MACOSX_FRAMEWORK_INFO_PLIST "${CMAKE_SOURCE_DIR}/mac/framework.info.plist.in"
|
||||||
|
MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${COMPLETE_VERSION}
|
||||||
|
MACOSX_FRAMEWORK_IDENTIFIER org.qgis.qgis3_quick
|
||||||
|
BUILD_WITH_INSTALL_RPATH TRUE
|
||||||
|
PUBLIC_HEADER "${QGIS_QUICK_GUI_HDRS};${QGIS_QUICK_GUI_MOC_HDRS}"
|
||||||
|
LINK_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}"
|
||||||
|
)
|
||||||
|
# generated export header does not get copied with PUBLIC_HEADER files
|
||||||
|
ADD_CUSTOM_COMMAND(TARGET qgis_quick
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy qgis_quick.h
|
||||||
|
"${QGIS_OUTPUT_DIRECTORY}/${QGIS_LIB_SUBDIR}/qgis_core.framework/Headers"
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
DEPENDS qgis_quick.h
|
||||||
|
)
|
||||||
|
ENDIF(NOT APPLE)
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
# qgis_quick_plugin module (QML) library
|
||||||
|
ADD_SUBDIRECTORY(plugin)
|
||||||
|
|
121
src/quickgui/plugin/CMakeLists.txt
Normal file
121
src/quickgui/plugin/CMakeLists.txt
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
############################################################
|
||||||
|
# sources
|
||||||
|
|
||||||
|
SET(QGIS_QUICK_PLUGIN_MOC_HDRS
|
||||||
|
qgsquickplugin.h
|
||||||
|
)
|
||||||
|
|
||||||
|
SET(QGIS_QUICK_PLUGIN_SRC
|
||||||
|
qgsquickplugin.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
SET(QGIS_QUICK_PLUGIN_RESOURCES
|
||||||
|
qgsquickmapcanvas.qml
|
||||||
|
qmldir
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES(
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/annotations
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/auth
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/composer
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/fieldformatter
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/geometry
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/layertree
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/layout
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/locator
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/metadata
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/providers/memory
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/raster
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/scalebar
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/symbology
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/effects
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/metadata
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/expression
|
||||||
|
${CMAKE_SOURCE_DIR}/src/quickgui
|
||||||
|
|
||||||
|
${CMAKE_BINARY_DIR}/src/core
|
||||||
|
${CMAKE_BINARY_DIR}/src/quickgui
|
||||||
|
)
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES(SYSTEM
|
||||||
|
${LIBZIP_INCLUDE_DIRS}
|
||||||
|
${SPATIALINDEX_INCLUDE_DIR}
|
||||||
|
${PROJ_INCLUDE_DIR}
|
||||||
|
${GEOS_INCLUDE_DIR}
|
||||||
|
${GDAL_INCLUDE_DIR}
|
||||||
|
${EXPAT_INCLUDE_DIR}
|
||||||
|
${SQLITE3_INCLUDE_DIR}
|
||||||
|
${SPATIALITE_INCLUDE_DIR}
|
||||||
|
${QCA_INCLUDE_DIR}
|
||||||
|
${QTKEYCHAIN_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
ADD_DEFINITIONS(-DCORE_EXPORT=)
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
# qgis_quick_plugin module (QML) library
|
||||||
|
|
||||||
|
QT5_WRAP_CPP(QGIS_QUICK_PLUGIN_MOC_SRCS ${QGIS_QUICK_PLUGIN_MOC_HDRS})
|
||||||
|
IF(MSVC)
|
||||||
|
SET_SOURCE_FILES_PROPERTIES(${QGIS_QUICK_PLUGIN_MOC_SRCS} PROPERTIES COMPILE_FLAGS "/wd4512 /wd4996" )
|
||||||
|
ELSE(MSVC)
|
||||||
|
SET_SOURCE_FILES_PROPERTIES(${QGIS_QUICK_PLUGIN_MOC_SRCS} PROPERTIES COMPILE_FLAGS "-Wno-deprecated-declarations" )
|
||||||
|
ENDIF(MSVC)
|
||||||
|
|
||||||
|
SET(QGIS_QUICK_PLUGIN_RUNTIME_DIR ${QGIS_OUTPUT_DIRECTORY}/${QGIS_QML_SUBDIR}/QgsQuick)
|
||||||
|
|
||||||
|
ADD_LIBRARY(qgis_quick_plugin MODULE
|
||||||
|
${QGIS_QUICK_PLUGIN_SRC}
|
||||||
|
${QGIS_QUICK_PLUGIN_MOC_HDRS}
|
||||||
|
${QGIS_QUICK_PLUGIN_MOC_SRCS}
|
||||||
|
${QGIS_QUICK_PLUGIN_RESOURCES}
|
||||||
|
)
|
||||||
|
TARGET_LINK_LIBRARIES(qgis_quick_plugin qgis_quick)
|
||||||
|
SET_TARGET_PROPERTIES(qgis_quick_plugin PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${QGIS_QUICK_PLUGIN_RUNTIME_DIR})
|
||||||
|
TARGET_COMPILE_DEFINITIONS(qgis_quick_plugin PRIVATE "-DQUICK_EXPORT=" "-DQT_NO_FOREACH")
|
||||||
|
|
||||||
|
# Copy qml files to output directory, we need qml files in the same directory as the plugin shared library
|
||||||
|
FOREACH(qmlfile ${QGIS_QUICK_PLUGIN_RESOURCES})
|
||||||
|
ADD_CUSTOM_COMMAND(TARGET qgis_quick_plugin
|
||||||
|
PRE_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${qmlfile} ${QGIS_QUICK_PLUGIN_RUNTIME_DIR}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
DEPENDS ${qmlfile}
|
||||||
|
)
|
||||||
|
ENDFOREACH(qmlfile)
|
||||||
|
|
||||||
|
IF(QMLPLUGINDUMP_FOUND)
|
||||||
|
# To create typeinfo file, no qml files must be in the directory, otherwise
|
||||||
|
# bunch of "QObject: Cannot create children for a parent that is in a different thread." errors
|
||||||
|
# appear and typeinfo file is not generated
|
||||||
|
SET(QGIS_QUICK_TYPEINFO_GENERATE_DIR ${CMAKE_CURRENT_BINARY_DIR}/QgsQuick)
|
||||||
|
|
||||||
|
# Extract QML Types Info from our QML plugin. This is useful for development with Qt Creator as it allows
|
||||||
|
# Qt Creator understand also the C++ classes registered in the plugin and thus available in QML code
|
||||||
|
SET(QGIS_QUICK_PLUGIN_TYPEINFO ${QGIS_QUICK_PLUGIN_RUNTIME_DIR}/qgsquick.qmltypes)
|
||||||
|
ADD_CUSTOM_COMMAND(
|
||||||
|
TARGET qgis_quick_plugin
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${QGIS_QUICK_TYPEINFO_GENERATE_DIR}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/qmldir ${QGIS_QUICK_TYPEINFO_GENERATE_DIR}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:qgis_quick_plugin> ${QGIS_QUICK_TYPEINFO_GENERATE_DIR}
|
||||||
|
COMMAND ${QMLPLUGINDUMP_EXECUTABLE}
|
||||||
|
ARGS QgsQuick 0.1 . -v --output ${QGIS_QUICK_PLUGIN_TYPEINFO}
|
||||||
|
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
||||||
|
POST_BUILD
|
||||||
|
)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
SET(QUICK_PLUGIN_INSTALL_DIR ${QGIS_QML_DIR}/QgsQuick)
|
||||||
|
INSTALL(TARGETS qgis_quick_plugin
|
||||||
|
RUNTIME DESTINATION ${QUICK_PLUGIN_INSTALL_DIR}
|
||||||
|
LIBRARY DESTINATION ${QUICK_PLUGIN_INSTALL_DIR}
|
||||||
|
)
|
||||||
|
INSTALL(FILES ${QGIS_QUICK_PLUGIN_RESOURCES} ${QGIS_QUICK_PLUGIN_TYPEINFO}
|
||||||
|
DESTINATION ${QUICK_PLUGIN_INSTALL_DIR}
|
||||||
|
)
|
165
src/quickgui/plugin/qgsquickmapcanvas.qml
Normal file
165
src/quickgui/plugin/qgsquickmapcanvas.qml
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsquickmapcanvas.qml
|
||||||
|
--------------------------------------
|
||||||
|
Date : 10.12.2014
|
||||||
|
Copyright : (C) 2014 by Matthias Kuhn
|
||||||
|
Email : matthias@opengis.ch
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
import QtQuick 2.3
|
||||||
|
import QtQuick.Controls 2.2
|
||||||
|
import QtQml 2.2
|
||||||
|
import QgsQuick 0.1 as QgsQuick
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: mapArea
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mapSettings property contains configuration for rendering of the map.
|
||||||
|
*
|
||||||
|
* It should be used as a primary source of map settings (and project) for
|
||||||
|
* all other components in the application.
|
||||||
|
*
|
||||||
|
* This is a readonly property.
|
||||||
|
*
|
||||||
|
* See also QgsQuickMapCanvasMap::mapSettings
|
||||||
|
*/
|
||||||
|
property alias mapSettings: mapCanvasWrapper.mapSettings
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The isRendering property is set to true while a rendering job is pending for this map canvas map.
|
||||||
|
* It can be used to show a notification icon about an ongoing rendering job.
|
||||||
|
*
|
||||||
|
* This is a readonly property.
|
||||||
|
*
|
||||||
|
* See also QgsQuickMapCanvasMap::mapSettings
|
||||||
|
*/
|
||||||
|
property alias isRendering: mapCanvasWrapper.isRendering
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When the incrementalRendering property is set to true, the automatic refresh of map canvas during rendering is allowed.
|
||||||
|
*/
|
||||||
|
property alias incrementalRendering: mapCanvasWrapper.incrementalRendering
|
||||||
|
|
||||||
|
signal clicked(var mouse)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Freezes the map canvas refreshes.
|
||||||
|
*
|
||||||
|
* In case of repeated geometry changes (animated resizes, pinch, pan...)
|
||||||
|
* triggering refreshes all the time can cause severe performance impacts.
|
||||||
|
*
|
||||||
|
* If freeze is called, an internal counter is incremented and only when the
|
||||||
|
* counter is 0, refreshes will happen.
|
||||||
|
* It is therefore important to call freeze() and unfreeze() exactly the same
|
||||||
|
* number of times.
|
||||||
|
*/
|
||||||
|
function freeze(id) {
|
||||||
|
mapCanvasWrapper.__freezecount[id] = true
|
||||||
|
mapCanvasWrapper.freeze = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function unfreeze(id) {
|
||||||
|
delete mapCanvasWrapper.__freezecount[id]
|
||||||
|
mapCanvasWrapper.freeze = Object.keys(
|
||||||
|
mapCanvasWrapper.__freezecount).length !== 0
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsQuick.MapCanvasMap {
|
||||||
|
id: mapCanvasWrapper
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
property var __freezecount: ({
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
freeze: false
|
||||||
|
}
|
||||||
|
|
||||||
|
PinchArea {
|
||||||
|
id: pinchArea
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
onPinchStarted: {
|
||||||
|
freeze('pinch')
|
||||||
|
}
|
||||||
|
|
||||||
|
onPinchUpdated: {
|
||||||
|
mapCanvasWrapper.zoom(pinch.center, pinch.previousScale / pinch.scale)
|
||||||
|
mapCanvasWrapper.pan(pinch.center, pinch.previousCenter)
|
||||||
|
}
|
||||||
|
|
||||||
|
onPinchFinished: {
|
||||||
|
unfreeze('pinch')
|
||||||
|
mapCanvasWrapper.refresh()
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
|
||||||
|
property point __initialPosition
|
||||||
|
property point __lastPosition
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
onDoubleClicked: {
|
||||||
|
var center = Qt.point(mouse.x, mouse.y)
|
||||||
|
mapCanvasWrapper.zoom(center, 0.8)
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (mouse.button === Qt.RightButton) {
|
||||||
|
var center = Qt.point(mouse.x, mouse.y)
|
||||||
|
mapCanvasWrapper.zoom(center, 1.2)
|
||||||
|
} else {
|
||||||
|
var distance = Math.abs(mouse.x - __initialPosition.x) + Math.abs(
|
||||||
|
mouse.y - __initialPosition.y)
|
||||||
|
|
||||||
|
if (distance < 5 * QgsQuick.Utils.dp)
|
||||||
|
mapArea.clicked(mouse)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onPressed: {
|
||||||
|
__lastPosition = Qt.point(mouse.x, mouse.y)
|
||||||
|
__initialPosition = __lastPosition
|
||||||
|
freeze('pan')
|
||||||
|
}
|
||||||
|
|
||||||
|
onReleased: {
|
||||||
|
unfreeze('pan')
|
||||||
|
}
|
||||||
|
|
||||||
|
onPositionChanged: {
|
||||||
|
var currentPosition = Qt.point(mouse.x, mouse.y)
|
||||||
|
mapCanvasWrapper.pan(currentPosition, __lastPosition)
|
||||||
|
__lastPosition = currentPosition
|
||||||
|
}
|
||||||
|
|
||||||
|
onCanceled: {
|
||||||
|
unfreezePanTimer.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
onWheel: {
|
||||||
|
mapCanvasWrapper.zoom(Qt.point(wheel.x, wheel.y),
|
||||||
|
Math.pow(0.8, wheel.angleDelta.y / 60))
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: unfreezePanTimer
|
||||||
|
interval: 500
|
||||||
|
running: false
|
||||||
|
repeat: false
|
||||||
|
onTriggered: unfreeze('pan')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
65
src/quickgui/plugin/qgsquickplugin.cpp
Normal file
65
src/quickgui/plugin/qgsquickplugin.cpp
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsquickplugin.cpp
|
||||||
|
--------------------------------------
|
||||||
|
Date : Nov 2017
|
||||||
|
Copyright : (C) 2017 by Peter Petrik
|
||||||
|
Email : zilolv at gmail dot com
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <qqml.h>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QQmlEngine>
|
||||||
|
#include <QJSEngine>
|
||||||
|
|
||||||
|
#include "qgsfeature.h"
|
||||||
|
#include "qgslogger.h"
|
||||||
|
#include "qgsmaplayer.h"
|
||||||
|
#include "qgsmessagelog.h"
|
||||||
|
#include "qgspointxy.h"
|
||||||
|
#include "qgsproject.h"
|
||||||
|
#include "qgsrelationmanager.h"
|
||||||
|
#include "qgscoordinatetransformcontext.h"
|
||||||
|
#include "qgsvectorlayer.h"
|
||||||
|
|
||||||
|
#include "qgsquickmapcanvasmap.h"
|
||||||
|
#include "qgsquickmapsettings.h"
|
||||||
|
#include "qgsquickplugin.h"
|
||||||
|
#include "qgsquickutils.h"
|
||||||
|
|
||||||
|
static QObject *_utilsProvider( QQmlEngine *engine, QJSEngine *scriptEngine )
|
||||||
|
{
|
||||||
|
Q_UNUSED( engine )
|
||||||
|
Q_UNUSED( scriptEngine )
|
||||||
|
return new QgsQuickUtils(); // the object will be owned by QML engine and destroyed by the engine on exit
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickPlugin::registerTypes( const char *uri )
|
||||||
|
{
|
||||||
|
qRegisterMetaType< QList<QgsMapLayer *> >( "QList<QgsMapLayer*>" );
|
||||||
|
qRegisterMetaType< QgsAttributes > ( "QgsAttributes" );
|
||||||
|
qRegisterMetaType< QgsCoordinateReferenceSystem >( "QgsCoordinateReferenceSystem" );
|
||||||
|
qRegisterMetaType< QgsCoordinateTransformContext >( "QgsCoordinateTransformContext" );
|
||||||
|
qRegisterMetaType< QgsFeature > ( "QgsFeature" );
|
||||||
|
qRegisterMetaType< QgsFeatureId > ( "QgsFeatureId" );
|
||||||
|
qRegisterMetaType< QgsPoint >( "QgsPoint" );
|
||||||
|
qRegisterMetaType< QgsPointXY >( "QgsPointXY" );
|
||||||
|
|
||||||
|
qmlRegisterType< QgsProject >( uri, 0, 1, "Project" );
|
||||||
|
qmlRegisterType< QgsQuickMapCanvasMap >( uri, 0, 1, "MapCanvasMap" );
|
||||||
|
qmlRegisterType< QgsQuickMapSettings >( uri, 0, 1, "MapSettings" );
|
||||||
|
qmlRegisterType< QgsVectorLayer >( uri, 0, 1, "VectorLayer" );
|
||||||
|
|
||||||
|
qmlRegisterSingletonType< QgsQuickUtils >( uri, 0, 1, "Utils", _utilsProvider );
|
||||||
|
|
||||||
|
qmlRegisterUncreatableType< QgsRelationManager >( uri, 0, 1, "RelationManager", "The relation manager is available from the Project. Try `qgisProject.relationManager`" );
|
||||||
|
qmlRegisterUncreatableType< QgsMessageLog >( uri, 0, 1, "QgsMessageLog", "Expose MessageLevel" );
|
||||||
|
}
|
||||||
|
|
42
src/quickgui/plugin/qgsquickplugin.h
Normal file
42
src/quickgui/plugin/qgsquickplugin.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsquickplugin.h
|
||||||
|
--------------------------------------
|
||||||
|
Date : Nov 2017
|
||||||
|
Copyright : (C) 2017 by Peter Petrik
|
||||||
|
Email : zilolv at gmail dot com
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QGSQUICKPLUGIN_H
|
||||||
|
#define QGSQUICKPLUGIN_H
|
||||||
|
|
||||||
|
#include <QQmlExtensionPlugin>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \ingroup quick
|
||||||
|
*
|
||||||
|
* Qgis Qml Extension Plugin responsible for exposing C++ Qgis classes to QML
|
||||||
|
*
|
||||||
|
* \since QGIS 3.2
|
||||||
|
*/
|
||||||
|
class QgsQuickPlugin : public QQmlExtensionPlugin
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PLUGIN_METADATA( IID "org.qt-project.Qt.QQmlExtensionInterface" )
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the QGIS QML types in the given uri
|
||||||
|
* \param uri an identifier for the plugin generated by the QML engine
|
||||||
|
*/
|
||||||
|
void registerTypes( const char *uri );
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QGSQUICKPLUGIN_H
|
||||||
|
|
18
src/quickgui/plugin/qmldir
Normal file
18
src/quickgui/plugin/qmldir
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# qmldir
|
||||||
|
# --------------------------------------
|
||||||
|
# Date : Nov 2017
|
||||||
|
# Copyright : (C) 2017 by Peter Petrik
|
||||||
|
# Email : zilolv at gmail dot com
|
||||||
|
# *************************************************************************** *
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
|
||||||
|
module QgsQuick
|
||||||
|
plugin qgis_quick_plugin
|
||||||
|
|
||||||
|
MapCanvas 0.1 qgsquickmapcanvas.qml
|
||||||
|
|
||||||
|
typeinfo qgsquick.qmltypes
|
382
src/quickgui/qgsquickmapcanvasmap.cpp
Normal file
382
src/quickgui/qgsquickmapcanvasmap.cpp
Normal file
@ -0,0 +1,382 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsquickmapcanvasmap.cpp
|
||||||
|
--------------------------------------
|
||||||
|
Date : 10.12.2014
|
||||||
|
Copyright : (C) 2014 by Matthias Kuhn
|
||||||
|
Email : matthias (at) opengis.ch
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <QQuickWindow>
|
||||||
|
#include <QScreen>
|
||||||
|
#include <QSGSimpleTextureNode>
|
||||||
|
#include <QtConcurrent>
|
||||||
|
|
||||||
|
#include "qgsmaprendererparalleljob.h"
|
||||||
|
#include "qgsmessagelog.h"
|
||||||
|
#include "qgspallabeling.h"
|
||||||
|
#include "qgsproject.h"
|
||||||
|
#include "qgsvectorlayer.h"
|
||||||
|
#include "qgis.h"
|
||||||
|
|
||||||
|
#include "qgsquickmapcanvasmap.h"
|
||||||
|
#include "qgsquickmapsettings.h"
|
||||||
|
|
||||||
|
|
||||||
|
QgsQuickMapCanvasMap::QgsQuickMapCanvasMap( QQuickItem *parent )
|
||||||
|
: QQuickItem( parent )
|
||||||
|
, mMapSettings( new QgsQuickMapSettings() )
|
||||||
|
{
|
||||||
|
connect( this, &QQuickItem::windowChanged, this, &QgsQuickMapCanvasMap::onWindowChanged );
|
||||||
|
connect( &mRefreshTimer, &QTimer::timeout, this, &QgsQuickMapCanvasMap::refreshMap );
|
||||||
|
connect( &mMapUpdateTimer, &QTimer::timeout, this, &QgsQuickMapCanvasMap::renderJobUpdated );
|
||||||
|
|
||||||
|
connect( mMapSettings.get(), &QgsQuickMapSettings::extentChanged, this, &QgsQuickMapCanvasMap::onExtentChanged );
|
||||||
|
connect( mMapSettings.get(), &QgsQuickMapSettings::layersChanged, this, &QgsQuickMapCanvasMap::onLayersChanged );
|
||||||
|
|
||||||
|
connect( this, &QgsQuickMapCanvasMap::renderStarting, this, &QgsQuickMapCanvasMap::isRenderingChanged );
|
||||||
|
connect( this, &QgsQuickMapCanvasMap::mapCanvasRefreshed, this, &QgsQuickMapCanvasMap::isRenderingChanged );
|
||||||
|
|
||||||
|
mMapUpdateTimer.setSingleShot( false );
|
||||||
|
mMapUpdateTimer.setInterval( 250 );
|
||||||
|
mRefreshTimer.setSingleShot( true );
|
||||||
|
setTransformOrigin( QQuickItem::TopLeft );
|
||||||
|
setFlags( QQuickItem::ItemHasContents );
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsQuickMapSettings *QgsQuickMapCanvasMap::mapSettings() const
|
||||||
|
{
|
||||||
|
return mMapSettings.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapCanvasMap::zoom( QPointF center, qreal scale )
|
||||||
|
{
|
||||||
|
QgsRectangle extent = mMapSettings->extent();
|
||||||
|
QgsPoint oldCenter( extent.center() );
|
||||||
|
QgsPoint mousePos( mMapSettings->screenToCoordinate( center ) );
|
||||||
|
QgsPointXY newCenter( mousePos.x() + ( ( oldCenter.x() - mousePos.x() ) * scale ),
|
||||||
|
mousePos.y() + ( ( oldCenter.y() - mousePos.y() ) * scale ) );
|
||||||
|
|
||||||
|
// same as zoomWithCenter (no coordinate transformations are needed)
|
||||||
|
extent.scale( scale, &newCenter );
|
||||||
|
mMapSettings->setExtent( extent );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapCanvasMap::pan( QPointF oldPos, QPointF newPos )
|
||||||
|
{
|
||||||
|
QgsPoint start = mMapSettings->screenToCoordinate( oldPos.toPoint() );
|
||||||
|
QgsPoint end = mMapSettings->screenToCoordinate( newPos.toPoint() );
|
||||||
|
|
||||||
|
double dx = end.x() - start.x();
|
||||||
|
double dy = end.y() - start.y();
|
||||||
|
|
||||||
|
// modify the extent
|
||||||
|
QgsRectangle extent = mMapSettings->extent();
|
||||||
|
|
||||||
|
extent.setXMinimum( extent.xMinimum() + dx );
|
||||||
|
extent.setXMaximum( extent.xMaximum() + dx );
|
||||||
|
extent.setYMaximum( extent.yMaximum() + dy );
|
||||||
|
extent.setYMinimum( extent.yMinimum() + dy );
|
||||||
|
|
||||||
|
mMapSettings->setExtent( extent );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapCanvasMap::refreshMap()
|
||||||
|
{
|
||||||
|
stopRendering(); // if any...
|
||||||
|
|
||||||
|
QgsMapSettings mapSettings = mMapSettings->mapSettings();
|
||||||
|
|
||||||
|
//build the expression context
|
||||||
|
QgsExpressionContext expressionContext;
|
||||||
|
expressionContext << QgsExpressionContextUtils::globalScope()
|
||||||
|
<< QgsExpressionContextUtils::mapSettingsScope( mapSettings );
|
||||||
|
|
||||||
|
QgsProject *project = mMapSettings->project();
|
||||||
|
if ( project )
|
||||||
|
{
|
||||||
|
expressionContext << QgsExpressionContextUtils::projectScope( project );
|
||||||
|
}
|
||||||
|
|
||||||
|
mapSettings.setExpressionContext( expressionContext );
|
||||||
|
|
||||||
|
// create the renderer job
|
||||||
|
Q_ASSERT( !mJob );
|
||||||
|
mJob = new QgsMapRendererParallelJob( mapSettings );
|
||||||
|
|
||||||
|
if ( mIncrementalRendering )
|
||||||
|
mMapUpdateTimer.start();
|
||||||
|
|
||||||
|
connect( mJob, &QgsMapRendererJob::renderingLayersFinished, this, &QgsQuickMapCanvasMap::renderJobUpdated );
|
||||||
|
connect( mJob, &QgsMapRendererJob::finished, this, &QgsQuickMapCanvasMap::renderJobFinished );
|
||||||
|
mJob->setCache( mCache );
|
||||||
|
|
||||||
|
mJob->start();
|
||||||
|
|
||||||
|
emit renderStarting();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapCanvasMap::renderJobUpdated()
|
||||||
|
{
|
||||||
|
mImage = mJob->renderedImage();
|
||||||
|
mImageMapSettings = mJob->mapSettings();
|
||||||
|
mDirty = true;
|
||||||
|
// Temporarily freeze the canvas, we only need to reset the geometry but not trigger a repaint
|
||||||
|
bool freeze = mFreeze;
|
||||||
|
mFreeze = true;
|
||||||
|
updateTransform();
|
||||||
|
mFreeze = freeze;
|
||||||
|
|
||||||
|
update();
|
||||||
|
emit mapCanvasRefreshed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapCanvasMap::renderJobFinished()
|
||||||
|
{
|
||||||
|
const QgsMapRendererJob::Errors errors = mJob->errors();
|
||||||
|
for ( const QgsMapRendererJob::Error &error : errors )
|
||||||
|
{
|
||||||
|
QgsMessageLog::logMessage( QStringLiteral( "%1 :: %2" ).arg( error.layerID, error.message ), tr( "Rendering" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// take labeling results before emitting renderComplete, so labeling map tools
|
||||||
|
// connected to signal work with correct results
|
||||||
|
delete mLabelingResults;
|
||||||
|
mLabelingResults = mJob->takeLabelingResults();
|
||||||
|
|
||||||
|
mImage = mJob->renderedImage();
|
||||||
|
mImageMapSettings = mJob->mapSettings();
|
||||||
|
|
||||||
|
// now we are in a slot called from mJob - do not delete it immediately
|
||||||
|
// so the class is still valid when the execution returns to the class
|
||||||
|
mJob->deleteLater();
|
||||||
|
mJob = nullptr;
|
||||||
|
mDirty = true;
|
||||||
|
mMapUpdateTimer.stop();
|
||||||
|
|
||||||
|
// Temporarily freeze the canvas, we only need to reset the geometry but not trigger a repaint
|
||||||
|
bool freeze = mFreeze;
|
||||||
|
mFreeze = true;
|
||||||
|
updateTransform();
|
||||||
|
mFreeze = freeze;
|
||||||
|
|
||||||
|
update();
|
||||||
|
emit mapCanvasRefreshed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapCanvasMap::onWindowChanged( QQuickWindow *window )
|
||||||
|
{
|
||||||
|
disconnect( window, &QQuickWindow::screenChanged, this, &QgsQuickMapCanvasMap::onScreenChanged );
|
||||||
|
if ( window )
|
||||||
|
{
|
||||||
|
connect( window, &QQuickWindow::screenChanged, this, &QgsQuickMapCanvasMap::onScreenChanged );
|
||||||
|
onScreenChanged( window->screen() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapCanvasMap::onScreenChanged( QScreen *screen )
|
||||||
|
{
|
||||||
|
if ( screen )
|
||||||
|
mMapSettings->setOutputDpi( screen->physicalDotsPerInch() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapCanvasMap::onExtentChanged()
|
||||||
|
{
|
||||||
|
updateTransform();
|
||||||
|
|
||||||
|
// And trigger a new rendering job
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapCanvasMap::updateTransform()
|
||||||
|
{
|
||||||
|
QgsMapSettings currentMapSettings = mMapSettings->mapSettings();
|
||||||
|
QgsMapToPixel mtp = currentMapSettings.mapToPixel();
|
||||||
|
|
||||||
|
QgsRectangle imageExtent = mImageMapSettings.visibleExtent();
|
||||||
|
QgsRectangle newExtent = currentMapSettings.visibleExtent();
|
||||||
|
QgsPointXY pixelPt = mtp.transform( imageExtent.xMinimum(), imageExtent.yMaximum() );
|
||||||
|
setScale( imageExtent.width() / newExtent.width() );
|
||||||
|
|
||||||
|
setX( pixelPt.x() );
|
||||||
|
setY( pixelPt.y() );
|
||||||
|
}
|
||||||
|
|
||||||
|
int QgsQuickMapCanvasMap::mapUpdateInterval() const
|
||||||
|
{
|
||||||
|
return mMapUpdateTimer.interval();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapCanvasMap::setMapUpdateInterval( int mapUpdateInterval )
|
||||||
|
{
|
||||||
|
if ( mMapUpdateTimer.interval() == mapUpdateInterval )
|
||||||
|
return;
|
||||||
|
|
||||||
|
mMapUpdateTimer.setInterval( mapUpdateInterval );
|
||||||
|
|
||||||
|
emit mapUpdateIntervalChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QgsQuickMapCanvasMap::incrementalRendering() const
|
||||||
|
{
|
||||||
|
return mIncrementalRendering;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapCanvasMap::setIncrementalRendering( bool incrementalRendering )
|
||||||
|
{
|
||||||
|
if ( incrementalRendering == mIncrementalRendering )
|
||||||
|
return;
|
||||||
|
|
||||||
|
mIncrementalRendering = incrementalRendering;
|
||||||
|
emit incrementalRenderingChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QgsQuickMapCanvasMap::freeze() const
|
||||||
|
{
|
||||||
|
return mFreeze;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapCanvasMap::setFreeze( bool freeze )
|
||||||
|
{
|
||||||
|
if ( freeze == mFreeze )
|
||||||
|
return;
|
||||||
|
|
||||||
|
mFreeze = freeze;
|
||||||
|
|
||||||
|
if ( !mFreeze )
|
||||||
|
refresh();
|
||||||
|
|
||||||
|
emit freezeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QgsQuickMapCanvasMap::isRendering() const
|
||||||
|
{
|
||||||
|
return mJob;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSGNode *QgsQuickMapCanvasMap::updatePaintNode( QSGNode *oldNode, QQuickItem::UpdatePaintNodeData * )
|
||||||
|
{
|
||||||
|
if ( mDirty )
|
||||||
|
{
|
||||||
|
delete oldNode;
|
||||||
|
oldNode = nullptr;
|
||||||
|
mDirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSGSimpleTextureNode *node = static_cast<QSGSimpleTextureNode *>( oldNode );
|
||||||
|
if ( !node )
|
||||||
|
{
|
||||||
|
node = new QSGSimpleTextureNode();
|
||||||
|
QSGTexture *texture = window()->createTextureFromImage( mImage );
|
||||||
|
node->setTexture( texture );
|
||||||
|
node->setOwnsTexture( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF rect( boundingRect() );
|
||||||
|
|
||||||
|
// Check for resizes that change the w/h ratio
|
||||||
|
if ( !rect.isEmpty() &&
|
||||||
|
!mImage.size().isEmpty() &&
|
||||||
|
!qgsDoubleNear( rect.width() / rect.height(), mImage.width() / mImage.height() ) )
|
||||||
|
{
|
||||||
|
if ( qgsDoubleNear( rect.height(), mImage.height() ) )
|
||||||
|
{
|
||||||
|
rect.setHeight( rect.width() / mImage.width() * mImage.height() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rect.setWidth( rect.height() / mImage.height() * mImage.width() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
node->setRect( rect );
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapCanvasMap::geometryChanged( const QRectF &newGeometry, const QRectF &oldGeometry )
|
||||||
|
{
|
||||||
|
Q_UNUSED( oldGeometry )
|
||||||
|
// The Qt documentation advices to call the base method here.
|
||||||
|
// However, this introduces instabilities and heavy performance impacts on Android.
|
||||||
|
// It seems on desktop disabling it prevents us from downsizing the window...
|
||||||
|
// Be careful when re-enabling it.
|
||||||
|
// QQuickItem::geometryChanged( newGeometry, oldGeometry );
|
||||||
|
|
||||||
|
mMapSettings->setOutputSize( newGeometry.size().toSize() );
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapCanvasMap::onLayersChanged()
|
||||||
|
{
|
||||||
|
if ( mMapSettings->extent().isEmpty() )
|
||||||
|
zoomToFullExtent();
|
||||||
|
|
||||||
|
for ( const QMetaObject::Connection &conn : qgis::as_const( mLayerConnections ) )
|
||||||
|
{
|
||||||
|
disconnect( conn );
|
||||||
|
}
|
||||||
|
mLayerConnections.clear();
|
||||||
|
|
||||||
|
const QList<QgsMapLayer *> layers = mMapSettings->layers();
|
||||||
|
for ( QgsMapLayer *layer : layers )
|
||||||
|
{
|
||||||
|
mLayerConnections << connect( layer, &QgsMapLayer::repaintRequested, this, &QgsQuickMapCanvasMap::refresh );
|
||||||
|
}
|
||||||
|
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapCanvasMap::destroyJob( QgsMapRendererJob *job )
|
||||||
|
{
|
||||||
|
job->cancel();
|
||||||
|
job->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapCanvasMap::stopRendering()
|
||||||
|
{
|
||||||
|
if ( mJob )
|
||||||
|
{
|
||||||
|
disconnect( mJob, &QgsMapRendererJob::renderingLayersFinished, this, &QgsQuickMapCanvasMap::renderJobUpdated );
|
||||||
|
disconnect( mJob, &QgsMapRendererJob::finished, this, &QgsQuickMapCanvasMap::renderJobFinished );
|
||||||
|
|
||||||
|
mJob->cancelWithoutBlocking();
|
||||||
|
mJob = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapCanvasMap::zoomToFullExtent()
|
||||||
|
{
|
||||||
|
QgsRectangle extent;
|
||||||
|
const QList<QgsMapLayer *> layers = mMapSettings->layers();
|
||||||
|
for ( QgsMapLayer *layer : layers )
|
||||||
|
{
|
||||||
|
if ( mMapSettings->destinationCrs() != layer->crs() )
|
||||||
|
{
|
||||||
|
QgsCoordinateTransform transform( layer->crs(), mMapSettings->destinationCrs(), mMapSettings->transformContext() );
|
||||||
|
extent.combineExtentWith( transform.transformBoundingBox( layer->extent() ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
extent.combineExtentWith( layer->extent() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mMapSettings->setExtent( extent );
|
||||||
|
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapCanvasMap::refresh()
|
||||||
|
{
|
||||||
|
if ( mMapSettings->outputSize().isNull() )
|
||||||
|
return; // the map image size has not been set yet
|
||||||
|
|
||||||
|
if ( !mFreeze )
|
||||||
|
mRefreshTimer.start( 1 );
|
||||||
|
}
|
204
src/quickgui/qgsquickmapcanvasmap.h
Normal file
204
src/quickgui/qgsquickmapcanvasmap.h
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsquickmapcanvasmap.h
|
||||||
|
--------------------------------------
|
||||||
|
Date : 10.12.2014
|
||||||
|
Copyright : (C) 2014 by Matthias Kuhn
|
||||||
|
Email : matthias (at) opengis.ch
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QGSQUICKMAPCANVASMAP_H
|
||||||
|
#define QGSQUICKMAPCANVASMAP_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <QtQuick/QQuickItem>
|
||||||
|
#include <QFutureSynchronizer>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include "qgsmapsettings.h"
|
||||||
|
#include "qgspoint.h"
|
||||||
|
|
||||||
|
#include "qgis_quick.h"
|
||||||
|
#include "qgsquickmapsettings.h"
|
||||||
|
|
||||||
|
class QgsMapRendererParallelJob;
|
||||||
|
class QgsMapRendererCache;
|
||||||
|
class QgsLabelingResults;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \ingroup quick
|
||||||
|
* This class implements a visual Qt Quick Item that does map rendering
|
||||||
|
* according to the current map settings. Client code is expected to use
|
||||||
|
* MapCanvas item rather than using this class directly.
|
||||||
|
*
|
||||||
|
* QgsQuickMapCanvasMap instance internally creates QgsQuickMapSettings in
|
||||||
|
* constructor. The QgsProject should be attached to the QgsQuickMapSettings.
|
||||||
|
* The map settings for other QgsQuick components should be initialized from
|
||||||
|
* QgsQuickMapCanvasMap's mapSettings
|
||||||
|
*
|
||||||
|
* \note QML Type: MapCanvasMap
|
||||||
|
*
|
||||||
|
* \sa QgsQuickMapCanvas
|
||||||
|
*
|
||||||
|
* \since QGIS 3.2
|
||||||
|
*/
|
||||||
|
class QUICK_EXPORT QgsQuickMapCanvasMap : public QQuickItem
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mapSettings property contains configuration for rendering of the map.
|
||||||
|
*
|
||||||
|
* It should be used as a primary source of map settings (and project) for
|
||||||
|
* all other components in the application.
|
||||||
|
*
|
||||||
|
* This is a readonly property.
|
||||||
|
*/
|
||||||
|
Q_PROPERTY( QgsQuickMapSettings *mapSettings READ mapSettings )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When freeze property is set to true, the map canvas does not refresh.
|
||||||
|
* The value temporary changes during the rendering process.
|
||||||
|
*/
|
||||||
|
Q_PROPERTY( bool freeze READ freeze WRITE setFreeze NOTIFY freezeChanged )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The isRendering property is set to true while a rendering job is pending for this map canvas map.
|
||||||
|
* It can be used to show a notification icon about an ongoing rendering job.
|
||||||
|
* This is a readonly property.
|
||||||
|
*/
|
||||||
|
Q_PROPERTY( bool isRendering READ isRendering NOTIFY isRenderingChanged )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interval in milliseconds after which the map canvas will be updated while a rendering job is ongoing.
|
||||||
|
* This only has an effect if incrementalRendering is activated.
|
||||||
|
* Default is 250 [ms].
|
||||||
|
*/
|
||||||
|
Q_PROPERTY( int mapUpdateInterval READ mapUpdateInterval WRITE setMapUpdateInterval NOTIFY mapUpdateIntervalChanged )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When the incrementalRendering property is set to true, the automatic refresh of map canvas during rendering is allowed.
|
||||||
|
*/
|
||||||
|
Q_PROPERTY( bool incrementalRendering READ incrementalRendering WRITE setIncrementalRendering NOTIFY incrementalRenderingChanged )
|
||||||
|
|
||||||
|
public:
|
||||||
|
//! Create map canvas map
|
||||||
|
QgsQuickMapCanvasMap( QQuickItem *parent = nullptr );
|
||||||
|
~QgsQuickMapCanvasMap() = default;
|
||||||
|
|
||||||
|
virtual QSGNode *updatePaintNode( QSGNode *oldNode, QQuickItem::UpdatePaintNodeData * ) override;
|
||||||
|
|
||||||
|
//! \copydoc QgsQuickMapCanvasMap::mapSettings
|
||||||
|
QgsQuickMapSettings *mapSettings() const;
|
||||||
|
|
||||||
|
//! \copydoc QgsQuickMapCanvasMap::freeze
|
||||||
|
bool freeze() const;
|
||||||
|
|
||||||
|
//! \copydoc QgsQuickMapCanvasMap::freeze
|
||||||
|
void setFreeze( bool freeze );
|
||||||
|
|
||||||
|
//! \copydoc QgsQuickMapCanvasMap::isRendering
|
||||||
|
bool isRendering() const;
|
||||||
|
|
||||||
|
//! \copydoc QgsQuickMapCanvasMap::mapUpdateInterval
|
||||||
|
int mapUpdateInterval() const;
|
||||||
|
|
||||||
|
//! \copydoc QgsQuickMapCanvasMap::mapUpdateInterval
|
||||||
|
void setMapUpdateInterval( int mapUpdateInterval );
|
||||||
|
|
||||||
|
//! \copydoc QgsQuickMapCanvasMap::incrementalRendering
|
||||||
|
bool incrementalRendering() const;
|
||||||
|
|
||||||
|
//! \copydoc QgsQuickMapCanvasMap::incrementalRendering
|
||||||
|
void setIncrementalRendering( bool incrementalRendering );
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signal is emitted when a rendering is starting
|
||||||
|
*/
|
||||||
|
void renderStarting();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signal is emitted when a canvas is refreshed
|
||||||
|
*/
|
||||||
|
void mapCanvasRefreshed();
|
||||||
|
|
||||||
|
//! \copydoc QgsQuickMapCanvasMap::freeze
|
||||||
|
void freezeChanged();
|
||||||
|
|
||||||
|
//! \copydoc QgsQuickMapCanvasMap::isRendering
|
||||||
|
void isRenderingChanged();
|
||||||
|
|
||||||
|
//!\copydoc QgsQuickMapCanvasMap::mapUpdateInterval
|
||||||
|
void mapUpdateIntervalChanged();
|
||||||
|
|
||||||
|
//!\copydoc QgsQuickMapCanvasMap::incrementalRendering
|
||||||
|
void incrementalRenderingChanged();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void geometryChanged( const QRectF &newGeometry, const QRectF &oldGeometry ) override;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
//! Stop map rendering
|
||||||
|
void stopRendering();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set map setting's extent (zoom the map) on the center by given scale
|
||||||
|
*/
|
||||||
|
void zoom( QPointF center, qreal scale );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set map setting's extent (pan the map) based on the difference of positions
|
||||||
|
*/
|
||||||
|
void pan( QPointF oldPos, QPointF newPos );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh the map canvas.
|
||||||
|
* Does nothing when output size of map settings is not set
|
||||||
|
*/
|
||||||
|
void refresh();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void refreshMap();
|
||||||
|
void renderJobUpdated();
|
||||||
|
void renderJobFinished();
|
||||||
|
void onWindowChanged( QQuickWindow *window );
|
||||||
|
void onScreenChanged( QScreen *screen );
|
||||||
|
void onExtentChanged();
|
||||||
|
void onLayersChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should only be called by stopRendering()!
|
||||||
|
*/
|
||||||
|
void destroyJob( QgsMapRendererJob *job );
|
||||||
|
QgsMapSettings prepareMapSettings() const;
|
||||||
|
void updateTransform();
|
||||||
|
void zoomToFullExtent();
|
||||||
|
|
||||||
|
std::unique_ptr<QgsQuickMapSettings> mMapSettings;
|
||||||
|
bool mPinching = false;
|
||||||
|
QPoint mPinchStartPoint;
|
||||||
|
QgsMapRendererParallelJob *mJob = nullptr;
|
||||||
|
QgsMapRendererCache *mCache = nullptr;
|
||||||
|
QgsLabelingResults *mLabelingResults = nullptr;
|
||||||
|
QImage mImage;
|
||||||
|
QgsMapSettings mImageMapSettings;
|
||||||
|
QTimer mRefreshTimer;
|
||||||
|
bool mDirty = false;
|
||||||
|
bool mFreeze = false;
|
||||||
|
QList<QMetaObject::Connection> mLayerConnections;
|
||||||
|
QTimer mMapUpdateTimer;
|
||||||
|
bool mIncrementalRendering = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QGSQUICKMAPCANVASMAP_H
|
214
src/quickgui/qgsquickmapsettings.cpp
Normal file
214
src/quickgui/qgsquickmapsettings.cpp
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsquickmapsettings.cpp
|
||||||
|
--------------------------------------
|
||||||
|
Date : 27.12.2014
|
||||||
|
Copyright : (C) 2014 by Matthias Kuhn
|
||||||
|
Email : matthias (at) opengis.ch
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "qgsmaplayer.h"
|
||||||
|
#include "qgsmaplayerstylemanager.h"
|
||||||
|
#include "qgsmessagelog.h"
|
||||||
|
#include "qgsproject.h"
|
||||||
|
#include "qgis.h"
|
||||||
|
|
||||||
|
#include "qgsquickmapsettings.h"
|
||||||
|
|
||||||
|
QgsQuickMapSettings::QgsQuickMapSettings( QObject *parent )
|
||||||
|
: QObject( parent )
|
||||||
|
{
|
||||||
|
// Connect signals for derived values
|
||||||
|
connect( this, &QgsQuickMapSettings::destinationCrsChanged, this, &QgsQuickMapSettings::mapUnitsPerPixelChanged );
|
||||||
|
connect( this, &QgsQuickMapSettings::extentChanged, this, &QgsQuickMapSettings::mapUnitsPerPixelChanged );
|
||||||
|
connect( this, &QgsQuickMapSettings::outputSizeChanged, this, &QgsQuickMapSettings::mapUnitsPerPixelChanged );
|
||||||
|
connect( this, &QgsQuickMapSettings::extentChanged, this, &QgsQuickMapSettings::visibleExtentChanged );
|
||||||
|
connect( this, &QgsQuickMapSettings::rotationChanged, this, &QgsQuickMapSettings::visibleExtentChanged );
|
||||||
|
connect( this, &QgsQuickMapSettings::outputSizeChanged, this, &QgsQuickMapSettings::visibleExtentChanged );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapSettings::setProject( QgsProject *project )
|
||||||
|
{
|
||||||
|
if ( project == mProject )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// If we have already something connected, disconnect it!
|
||||||
|
if ( mProject )
|
||||||
|
{
|
||||||
|
mProject->disconnect( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
mProject = project;
|
||||||
|
|
||||||
|
// Connect all signals
|
||||||
|
if ( mProject )
|
||||||
|
{
|
||||||
|
connect( mProject, &QgsProject::readProject, this, &QgsQuickMapSettings::onReadProject );
|
||||||
|
setDestinationCrs( mProject->crs() );
|
||||||
|
mMapSettings.setTransformContext( mProject->transformContext() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mMapSettings.setTransformContext( QgsCoordinateTransformContext() );
|
||||||
|
}
|
||||||
|
|
||||||
|
emit projectChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsProject *QgsQuickMapSettings::project() const
|
||||||
|
{
|
||||||
|
return mProject;
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsCoordinateTransformContext QgsQuickMapSettings::transformContext() const
|
||||||
|
{
|
||||||
|
return mMapSettings.transformContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsRectangle QgsQuickMapSettings::extent() const
|
||||||
|
{
|
||||||
|
return mMapSettings.extent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapSettings::setExtent( const QgsRectangle &extent )
|
||||||
|
{
|
||||||
|
if ( mMapSettings.extent() == extent )
|
||||||
|
return;
|
||||||
|
|
||||||
|
mMapSettings.setExtent( extent );
|
||||||
|
emit extentChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapSettings::setCenter( const QgsPoint ¢er )
|
||||||
|
{
|
||||||
|
QgsVector delta = QgsPointXY( center ) - mMapSettings.extent().center();
|
||||||
|
|
||||||
|
QgsRectangle e = mMapSettings.extent();
|
||||||
|
e.setXMinimum( e.xMinimum() + delta.x() );
|
||||||
|
e.setXMaximum( e.xMaximum() + delta.x() );
|
||||||
|
e.setYMinimum( e.yMinimum() + delta.y() );
|
||||||
|
e.setYMaximum( e.yMaximum() + delta.y() );
|
||||||
|
|
||||||
|
setExtent( e );
|
||||||
|
}
|
||||||
|
|
||||||
|
double QgsQuickMapSettings::mapUnitsPerPixel() const
|
||||||
|
{
|
||||||
|
return mMapSettings.mapUnitsPerPixel();
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsRectangle QgsQuickMapSettings::visibleExtent() const
|
||||||
|
{
|
||||||
|
return mMapSettings.visibleExtent();
|
||||||
|
}
|
||||||
|
|
||||||
|
QPointF QgsQuickMapSettings::coordinateToScreen( const QgsPoint &point ) const
|
||||||
|
{
|
||||||
|
QgsPointXY pt( point.x(), point.y() );
|
||||||
|
QgsPointXY pp = mMapSettings.mapToPixel().transform( pt );
|
||||||
|
return pp.toQPointF();
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsPoint QgsQuickMapSettings::screenToCoordinate( const QPointF &point ) const
|
||||||
|
{
|
||||||
|
const QgsPointXY pp = mMapSettings.mapToPixel().toMapCoordinates( point.toPoint() );
|
||||||
|
return QgsPoint( pp );
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsMapSettings QgsQuickMapSettings::mapSettings() const
|
||||||
|
{
|
||||||
|
return mMapSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize QgsQuickMapSettings::outputSize() const
|
||||||
|
{
|
||||||
|
return mMapSettings.outputSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapSettings::setOutputSize( const QSize &outputSize )
|
||||||
|
{
|
||||||
|
if ( mMapSettings.outputSize() == outputSize )
|
||||||
|
return;
|
||||||
|
|
||||||
|
mMapSettings.setOutputSize( outputSize );
|
||||||
|
emit outputSizeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
double QgsQuickMapSettings::outputDpi() const
|
||||||
|
{
|
||||||
|
return mMapSettings.outputDpi();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapSettings::setOutputDpi( double outputDpi )
|
||||||
|
{
|
||||||
|
if ( qgsDoubleNear( mMapSettings.outputDpi(), outputDpi ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
mMapSettings.setOutputDpi( outputDpi );
|
||||||
|
emit outputDpiChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsCoordinateReferenceSystem QgsQuickMapSettings::destinationCrs() const
|
||||||
|
{
|
||||||
|
return mMapSettings.destinationCrs();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapSettings::setDestinationCrs( const QgsCoordinateReferenceSystem &destinationCrs )
|
||||||
|
{
|
||||||
|
if ( mMapSettings.destinationCrs() == destinationCrs )
|
||||||
|
return;
|
||||||
|
|
||||||
|
mMapSettings.setDestinationCrs( destinationCrs );
|
||||||
|
emit destinationCrsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QgsMapLayer *> QgsQuickMapSettings::layers() const
|
||||||
|
{
|
||||||
|
return mMapSettings.layers();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapSettings::setLayers( const QList<QgsMapLayer *> &layers )
|
||||||
|
{
|
||||||
|
mMapSettings.setLayers( layers );
|
||||||
|
emit layersChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapSettings::onReadProject( const QDomDocument &doc )
|
||||||
|
{
|
||||||
|
QDomNodeList nodes = doc.elementsByTagName( "mapcanvas" );
|
||||||
|
if ( nodes.count() )
|
||||||
|
{
|
||||||
|
QDomNode node = nodes.item( 0 );
|
||||||
|
|
||||||
|
mMapSettings.readXml( node );
|
||||||
|
|
||||||
|
if ( !qgsDoubleNear( mMapSettings.rotation(), 0 ) )
|
||||||
|
QgsMessageLog::logMessage( tr( "Map Canvas rotation is not supported. Resetting from %1 to 0." ).arg( mMapSettings.rotation() ) );
|
||||||
|
|
||||||
|
mMapSettings.setRotation( 0 );
|
||||||
|
|
||||||
|
emit extentChanged();
|
||||||
|
emit destinationCrsChanged();
|
||||||
|
emit outputSizeChanged();
|
||||||
|
emit outputDpiChanged();
|
||||||
|
emit layersChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double QgsQuickMapSettings::rotation() const
|
||||||
|
{
|
||||||
|
return mMapSettings.rotation();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsQuickMapSettings::setRotation( double rotation )
|
||||||
|
{
|
||||||
|
if ( !qgsDoubleNear( rotation, 0 ) )
|
||||||
|
QgsMessageLog::logMessage( tr( "Map Canvas rotation is not supported. Resetting from %1 to 0." ).arg( rotation ) );
|
||||||
|
}
|
237
src/quickgui/qgsquickmapsettings.h
Normal file
237
src/quickgui/qgsquickmapsettings.h
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsquickmapsettings.h
|
||||||
|
--------------------------------------
|
||||||
|
Date : 27.12.2014
|
||||||
|
Copyright : (C) 2014 by Matthias Kuhn
|
||||||
|
Email : matthias (at) opengis.ch
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QGSQUICKMAPSETTINGS_H
|
||||||
|
#define QGSQUICKMAPSETTINGS_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "qgscoordinatetransformcontext.h"
|
||||||
|
#include "qgsmapsettings.h"
|
||||||
|
#include "qgsmapthemecollection.h"
|
||||||
|
#include "qgspoint.h"
|
||||||
|
#include "qgsrectangle.h"
|
||||||
|
|
||||||
|
#include "qgis_quick.h"
|
||||||
|
|
||||||
|
class QgsProject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \ingroup quick
|
||||||
|
* The QgsQuickMapSettings class encapsulates QgsMapSettings class to offer
|
||||||
|
* settings of configuration of map rendering via QML properties.
|
||||||
|
*
|
||||||
|
* On top of QgsMapSettings functionality, when QgsProject is attached,
|
||||||
|
* it automatically loads its default settings from the project.
|
||||||
|
* QgsProject should be attached before it is read.
|
||||||
|
*
|
||||||
|
* \note QML Type: MapSettings
|
||||||
|
*
|
||||||
|
* \sa QgsMapCanvas
|
||||||
|
*
|
||||||
|
* \since QGIS 3.2
|
||||||
|
*/
|
||||||
|
class QUICK_EXPORT QgsQuickMapSettings : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A project property should be used as a primary source of project all other components
|
||||||
|
* in the application. QgsProject should be attached to QgsQuickMapSettings before
|
||||||
|
* it is read (QgsProject::read)
|
||||||
|
*
|
||||||
|
* When project is read, map settings (CRS, extent, ...) are automatically set from its DOM.
|
||||||
|
*/
|
||||||
|
Q_PROPERTY( QgsProject *project READ project WRITE setProject NOTIFY projectChanged )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Geographical coordinates of the rectangle that should be rendered.
|
||||||
|
* The actual visible extent used for rendering could be slightly different
|
||||||
|
* since the given extent may be expanded in order to fit the aspect ratio
|
||||||
|
* of output size. Use QgsQuickMapSettings::visibleExtent to get the resulting extent.
|
||||||
|
*
|
||||||
|
* Automatically loaded from project on QgsProject::readProject
|
||||||
|
*/
|
||||||
|
Q_PROPERTY( QgsRectangle extent READ extent WRITE setExtent NOTIFY extentChanged )
|
||||||
|
//! \copydoc QgsMapSettings::visibleExtent()
|
||||||
|
Q_PROPERTY( QgsRectangle visibleExtent READ visibleExtent NOTIFY visibleExtentChanged )
|
||||||
|
//! \copydoc QgsMapSettings::mapUnitsPerPixel()
|
||||||
|
Q_PROPERTY( double mapUnitsPerPixel READ mapUnitsPerPixel NOTIFY mapUnitsPerPixelChanged )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The rotation of the resulting map image, in degrees clockwise.
|
||||||
|
* Map canvas rotation support is not implemented, 0 is used
|
||||||
|
*/
|
||||||
|
Q_PROPERTY( double rotation READ rotation WRITE setRotation NOTIFY rotationChanged )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The size of the resulting map image
|
||||||
|
*
|
||||||
|
* Automatically loaded from project on QgsProject::readProject
|
||||||
|
*/
|
||||||
|
Q_PROPERTY( QSize outputSize READ outputSize WRITE setOutputSize NOTIFY outputSizeChanged )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output DPI used for conversion between real world units (e.g. mm) and pixels
|
||||||
|
*
|
||||||
|
* Automatically loaded from project on QgsProject::readProject
|
||||||
|
*/
|
||||||
|
Q_PROPERTY( double outputDpi READ outputDpi WRITE setOutputDpi NOTIFY outputDpiChanged )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CRS of destination coordinate reference system.
|
||||||
|
*
|
||||||
|
* Automatically loaded from project on QgsProject::readProject
|
||||||
|
*/
|
||||||
|
Q_PROPERTY( QgsCoordinateReferenceSystem destinationCrs READ destinationCrs WRITE setDestinationCrs NOTIFY destinationCrsChanged )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set list of layers for map rendering. The layers must be registered in QgsProject.
|
||||||
|
* The layers are stored in the reverse order of how they are rendered (layer with index 0 will be on top)
|
||||||
|
*
|
||||||
|
* \note Any non-spatial layers will be automatically stripped from the list (since they cannot be rendered!).
|
||||||
|
*
|
||||||
|
* Not loaded automatically from the associated project
|
||||||
|
*/
|
||||||
|
Q_PROPERTY( QList<QgsMapLayer *> layers READ layers WRITE setLayers NOTIFY layersChanged )
|
||||||
|
|
||||||
|
public:
|
||||||
|
//! Create new map settings
|
||||||
|
QgsQuickMapSettings( QObject *parent = nullptr );
|
||||||
|
~QgsQuickMapSettings() = default;
|
||||||
|
|
||||||
|
//! Clone map settings
|
||||||
|
QgsMapSettings mapSettings() const;
|
||||||
|
|
||||||
|
//! \copydoc QgsMapSettings::extent()
|
||||||
|
QgsRectangle extent() const;
|
||||||
|
|
||||||
|
//! \copydoc QgsMapSettings::setExtent()
|
||||||
|
void setExtent( const QgsRectangle &extent );
|
||||||
|
|
||||||
|
//! \copydoc QgsQuickMapSettings::project
|
||||||
|
void setProject( QgsProject *project );
|
||||||
|
|
||||||
|
//! \copydoc QgsQuickMapSettings::project
|
||||||
|
QgsProject *project() const;
|
||||||
|
|
||||||
|
//! Move current map extent to have center point defined by \a center
|
||||||
|
Q_INVOKABLE void setCenter( const QgsPoint ¢er );
|
||||||
|
|
||||||
|
//! \copydoc QgsMapSettings::mapUnitsPerPixel()
|
||||||
|
double mapUnitsPerPixel() const;
|
||||||
|
|
||||||
|
//! \copydoc QgsMapSettings::visibleExtent()
|
||||||
|
QgsRectangle visibleExtent() const;
|
||||||
|
|
||||||
|
//! \copydoc QgsMapSettings::transformContext()
|
||||||
|
Q_INVOKABLE QgsCoordinateTransformContext transformContext() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a map coordinate to screen pixel coordinates
|
||||||
|
*
|
||||||
|
* \param point A coordinate in map coordinates
|
||||||
|
*
|
||||||
|
* \return A coordinate in pixel / screen space
|
||||||
|
*/
|
||||||
|
Q_INVOKABLE QPointF coordinateToScreen( const QgsPoint &point ) const;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a screen coordinate to a map coordinate
|
||||||
|
*
|
||||||
|
* \param point A coordinate in pixel / screen coordinates
|
||||||
|
*
|
||||||
|
* \return A coordinate in map coordinates
|
||||||
|
*/
|
||||||
|
Q_INVOKABLE QgsPoint screenToCoordinate( const QPointF &point ) const;
|
||||||
|
|
||||||
|
//! \copydoc QgsMapSettings::setTransformContext()
|
||||||
|
void setTransformContext( const QgsCoordinateTransformContext &context );
|
||||||
|
|
||||||
|
//! \copydoc QgsQuickMapSettings::rotation
|
||||||
|
double rotation() const;
|
||||||
|
|
||||||
|
//! \copydoc QgsQuickMapSettings::rotation
|
||||||
|
void setRotation( double rotation );
|
||||||
|
|
||||||
|
//! \copydoc QgsMapSettings::outputSize()
|
||||||
|
QSize outputSize() const;
|
||||||
|
|
||||||
|
//! \copydoc QgsMapSettings::setOutputSize()
|
||||||
|
void setOutputSize( const QSize &outputSize );
|
||||||
|
|
||||||
|
//! \copydoc QgsMapSettings::outputDpi()
|
||||||
|
double outputDpi() const;
|
||||||
|
|
||||||
|
//! \copydoc QgsMapSettings::setOutputDpi()
|
||||||
|
void setOutputDpi( double outputDpi );
|
||||||
|
|
||||||
|
//! \copydoc QgsMapSettings::destinationCrs()
|
||||||
|
QgsCoordinateReferenceSystem destinationCrs() const;
|
||||||
|
|
||||||
|
//! \copydoc QgsMapSettings::setDestinationCrs()
|
||||||
|
void setDestinationCrs( const QgsCoordinateReferenceSystem &destinationCrs );
|
||||||
|
|
||||||
|
//! \copydoc QgsMapSettings::layers()
|
||||||
|
QList<QgsMapLayer *> layers() const;
|
||||||
|
|
||||||
|
//! \copydoc QgsMapSettings::setLayers()
|
||||||
|
void setLayers( const QList<QgsMapLayer *> &layers );
|
||||||
|
|
||||||
|
signals:
|
||||||
|
//! \copydoc QgsQuickMapSettings::project
|
||||||
|
void projectChanged();
|
||||||
|
|
||||||
|
//! \copydoc QgsQuickMapSettings::extent
|
||||||
|
void extentChanged();
|
||||||
|
|
||||||
|
//! \copydoc QgsQuickMapSettings::destinationCrs
|
||||||
|
void destinationCrsChanged();
|
||||||
|
|
||||||
|
//! \copydoc QgsQuickMapSettings::mapUnitsPerPixel
|
||||||
|
void mapUnitsPerPixelChanged();
|
||||||
|
|
||||||
|
//! \copydoc QgsQuickMapSettings::rotation
|
||||||
|
void rotationChanged();
|
||||||
|
|
||||||
|
//! \copydoc QgsQuickMapSettings::visibleExtent
|
||||||
|
void visibleExtentChanged();
|
||||||
|
|
||||||
|
//! \copydoc QgsQuickMapSettings::outputSize
|
||||||
|
void outputSizeChanged();
|
||||||
|
|
||||||
|
//! \copydoc QgsQuickMapSettings::outputDpi
|
||||||
|
void outputDpiChanged();
|
||||||
|
|
||||||
|
//! \copydoc QgsQuickMapSettings::layers
|
||||||
|
void layersChanged();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read map canvas settings stored in a QGIS project file
|
||||||
|
*
|
||||||
|
* \param doc parsed DOM of a QgsProject
|
||||||
|
*/
|
||||||
|
void onReadProject( const QDomDocument &doc );
|
||||||
|
|
||||||
|
private:
|
||||||
|
QgsProject *mProject = nullptr;
|
||||||
|
QgsMapSettings mMapSettings;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QGSQUICKMAPSETTINGS_H
|
66
src/quickgui/qgsquickutils.cpp
Normal file
66
src/quickgui/qgsquickutils.cpp
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsquickutils.cpp
|
||||||
|
--------------------------------------
|
||||||
|
Date : Nov 2017
|
||||||
|
Copyright : (C) 2017 by Peter Petrik
|
||||||
|
Email : zilolv at gmail dot com
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
#include <QDesktopWidget>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
#include "qgis.h"
|
||||||
|
#include "qgscoordinatereferencesystem.h"
|
||||||
|
#include "qgscoordinatetransform.h"
|
||||||
|
#include "qgsdistancearea.h"
|
||||||
|
#include "qgslogger.h"
|
||||||
|
#include "qgsvectorlayer.h"
|
||||||
|
|
||||||
|
#include "qgsquickmapsettings.h"
|
||||||
|
#include "qgsquickutils.h"
|
||||||
|
#include "qgsunittypes.h"
|
||||||
|
|
||||||
|
|
||||||
|
QgsQuickUtils::QgsQuickUtils( QObject *parent )
|
||||||
|
: QObject( parent )
|
||||||
|
, mScreenDensity( calculateScreenDensity() )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QgsQuickUtils::dumpScreenInfo() const
|
||||||
|
{
|
||||||
|
QRect rec = QApplication::desktop()->screenGeometry();
|
||||||
|
int dpiX = QApplication::desktop()->physicalDpiX();
|
||||||
|
int dpiY = QApplication::desktop()->physicalDpiY();
|
||||||
|
int height = rec.height();
|
||||||
|
int width = rec.width();
|
||||||
|
double sizeX = static_cast<double>( width ) / dpiX * 25.4;
|
||||||
|
double sizeY = static_cast<double>( height ) / dpiY * 25.4;
|
||||||
|
|
||||||
|
QString msg;
|
||||||
|
msg += tr( "screen resolution: %1x%2 px\n" ).arg( width ).arg( height );
|
||||||
|
msg += tr( "screen DPI: %1x%2\n" ).arg( dpiX ).arg( dpiY );
|
||||||
|
msg += tr( "screen size: %1x%2 mm\n" ).arg( QString::number( sizeX, 'f', 0 ), QString::number( sizeY, 'f', 0 ) );
|
||||||
|
msg += tr( "screen density: %1" ).arg( mScreenDensity );
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal QgsQuickUtils::screenDensity() const
|
||||||
|
{
|
||||||
|
return mScreenDensity;
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal QgsQuickUtils::calculateScreenDensity()
|
||||||
|
{
|
||||||
|
// calculate screen density for calculation of real pixel sizes from density-independent pixels
|
||||||
|
int dpiX = QApplication::desktop()->physicalDpiX();
|
||||||
|
int dpiY = QApplication::desktop()->physicalDpiY();
|
||||||
|
int dpi = dpiX < dpiY ? dpiX : dpiY; // In case of asymmetrical DPI. Improbable
|
||||||
|
return dpi / 160.; // 160 DPI is baseline for density-independent pixels in Android
|
||||||
|
}
|
74
src/quickgui/qgsquickutils.h
Normal file
74
src/quickgui/qgsquickutils.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsquickutils.h
|
||||||
|
--------------------------------------
|
||||||
|
Date : Nov 2017
|
||||||
|
Copyright : (C) 2017 by Peter Petrik
|
||||||
|
Email : zilolv at gmail dot com
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QGSQUICKUTILS_H
|
||||||
|
#define QGSQUICKUTILS_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
#include "qgis.h"
|
||||||
|
#include "qgis_quick.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \ingroup quick
|
||||||
|
*
|
||||||
|
* Encapsulating the common utilies for QgsQuick library.
|
||||||
|
*
|
||||||
|
* \note QML Type: Utils (Singleton)
|
||||||
|
*
|
||||||
|
* \since QGIS 3.2
|
||||||
|
*/
|
||||||
|
class QUICK_EXPORT QgsQuickUtils: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "dp" is useful for building building components that work well with different screen densities.
|
||||||
|
* It stands for density-independent pixels. A width of 10dp is going to be the same physical size
|
||||||
|
* on all screens regardless their density. In QML code, all values are specified in screen pixels,
|
||||||
|
* so in order to set a width of 10dp, one would use the following code: "width: 10 * QgsQuick.Utils.dp"
|
||||||
|
*
|
||||||
|
* 1dp is approximately 0.16mm. When screen has 160 DPI (baseline), the value of "dp" is 1.
|
||||||
|
* On high DPI screen the value will be greater, e.g. 1.5.
|
||||||
|
*
|
||||||
|
* This is a readonly property.
|
||||||
|
*/
|
||||||
|
Q_PROPERTY( qreal dp READ screenDensity CONSTANT )
|
||||||
|
|
||||||
|
public:
|
||||||
|
//! Create new utilities
|
||||||
|
QgsQuickUtils( QObject *parent = nullptr );
|
||||||
|
//! dtor
|
||||||
|
~QgsQuickUtils() = default;
|
||||||
|
|
||||||
|
//! \copydoc QgsQuickUtils::dp
|
||||||
|
qreal screenDensity() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string with information about screen size and resolution
|
||||||
|
*
|
||||||
|
* Useful to log for debugging of graphical problems on various display sizes
|
||||||
|
*/
|
||||||
|
QString dumpScreenInfo() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static qreal calculateScreenDensity();
|
||||||
|
|
||||||
|
qreal mScreenDensity;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QGSQUICKUTILS_H
|
@ -46,4 +46,7 @@ IF (ENABLE_TESTS)
|
|||||||
ADD_SUBDIRECTORY(python)
|
ADD_SUBDIRECTORY(python)
|
||||||
ENDIF (WITH_BINDINGS)
|
ENDIF (WITH_BINDINGS)
|
||||||
ADD_SUBDIRECTORY(geometry_checker)
|
ADD_SUBDIRECTORY(geometry_checker)
|
||||||
|
IF (WITH_QUICK)
|
||||||
|
ADD_SUBDIRECTORY(quickgui)
|
||||||
|
ENDIF (WITH_QUICK)
|
||||||
ENDIF (ENABLE_TESTS)
|
ENDIF (ENABLE_TESTS)
|
||||||
|
86
tests/src/quickgui/CMakeLists.txt
Normal file
86
tests/src/quickgui/CMakeLists.txt
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
# Standard includes and utils to compile into all tests.
|
||||||
|
|
||||||
|
#####################################################
|
||||||
|
# Don't forget to include output directory, otherwise
|
||||||
|
# the UI file won't be wrapped!
|
||||||
|
INCLUDE_DIRECTORIES(
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/annotations
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/auth
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/composer
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/fieldformatter
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/geometry
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/layertree
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/layout
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/locator
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/metadata
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/providers/memory
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/raster
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/scalebar
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/symbology
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/effects
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/metadata
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/expression
|
||||||
|
${CMAKE_SOURCE_DIR}/src/native
|
||||||
|
${CMAKE_SOURCE_DIR}/src/quickgui
|
||||||
|
${CMAKE_SOURCE_DIR}/src/test
|
||||||
|
|
||||||
|
${CMAKE_BINARY_DIR}/src/core
|
||||||
|
${CMAKE_BINARY_DIR}/src/native
|
||||||
|
${CMAKE_BINARY_DIR}/src/quickgui
|
||||||
|
)
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES(SYSTEM
|
||||||
|
${LIBZIP_INCLUDE_DIRS}
|
||||||
|
${SPATIALINDEX_INCLUDE_DIR}
|
||||||
|
${PROJ_INCLUDE_DIR}
|
||||||
|
${GEOS_INCLUDE_DIR}
|
||||||
|
${GDAL_INCLUDE_DIR}
|
||||||
|
${EXPAT_INCLUDE_DIR}
|
||||||
|
${SQLITE3_INCLUDE_DIR}
|
||||||
|
${SPATIALITE_INCLUDE_DIR}
|
||||||
|
${QCA_INCLUDE_DIR}
|
||||||
|
${QTKEYCHAIN_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
#note for tests we should not include the moc of our
|
||||||
|
#qtests in the executable file list as the moc is
|
||||||
|
#directly included in the sources
|
||||||
|
#and should not be compiled twice. Trying to include
|
||||||
|
#them in will cause an error at build time
|
||||||
|
|
||||||
|
#No relinking and full RPATH for the install tree
|
||||||
|
#See: http://www.cmake.org/Wiki/CMake_RPATH_handling#No_relinking_and_full_RPATH_for_the_install_tree
|
||||||
|
|
||||||
|
MACRO (ADD_QGIS_TEST testname testsrc)
|
||||||
|
SET(qgis_${testname}_SRCS ${testsrc} ${util_SRCS})
|
||||||
|
ADD_CUSTOM_TARGET(qgis_${testname}moc ALL DEPENDS ${qgis_${testname}_MOC_SRCS})
|
||||||
|
ADD_EXECUTABLE(qgis_${testname} ${qgis_${testname}_SRCS})
|
||||||
|
SET_TARGET_PROPERTIES(qgis_${testname} PROPERTIES AUTOMOC TRUE)
|
||||||
|
TARGET_LINK_LIBRARIES(qgis_${testname}
|
||||||
|
${Qt5Xml_LIBRARIES}
|
||||||
|
${Qt5Core_LIBRARIES}
|
||||||
|
${Qt5Svg_LIBRARIES}
|
||||||
|
${Qt5Test_LIBRARIES}
|
||||||
|
Qt5::Gui
|
||||||
|
Qt5::Qml
|
||||||
|
Qt5::Quick
|
||||||
|
Qt5::Xml
|
||||||
|
qgis_core
|
||||||
|
qgis_quick)
|
||||||
|
|
||||||
|
ADD_TEST(qgis_${testname} ${CMAKE_CURRENT_BINARY_DIR}/../../../output/bin/qgis_${testname} -maxwarnings 10000)
|
||||||
|
ENDMACRO (ADD_QGIS_TEST)
|
||||||
|
|
||||||
|
#############################################################
|
||||||
|
# Tests:
|
||||||
|
|
||||||
|
ADD_QGIS_TEST(qgsquickutils testqgsquickutils.cpp)
|
||||||
|
|
||||||
|
|
||||||
|
#############################################################
|
||||||
|
# Add also test application
|
||||||
|
ADD_SUBDIRECTORY(app)
|
80
tests/src/quickgui/app/CMakeLists.txt
Normal file
80
tests/src/quickgui/app/CMakeLists.txt
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
SET(QGIS_QUICK_APP_MOC_HDRS
|
||||||
|
)
|
||||||
|
|
||||||
|
SET(QGIS_QUICK_APP_SRCS
|
||||||
|
main.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
SET(QGIS_QUICK_APP_QMLS
|
||||||
|
main.qml
|
||||||
|
)
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES(
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/annotations
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/auth
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/composer
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/fieldformatter
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/geometry
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/layertree
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/layout
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/locator
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/metadata
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/providers/memory
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/raster
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/scalebar
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/symbology
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/effects
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/metadata
|
||||||
|
${CMAKE_SOURCE_DIR}/src/core/expression
|
||||||
|
${CMAKE_SOURCE_DIR}/src/native
|
||||||
|
${CMAKE_SOURCE_DIR}/src/quickgui
|
||||||
|
|
||||||
|
${CMAKE_BINARY_DIR}/src/core
|
||||||
|
${CMAKE_BINARY_DIR}/src/native
|
||||||
|
${CMAKE_BINARY_DIR}/src/quickgui
|
||||||
|
)
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES(SYSTEM
|
||||||
|
${LIBZIP_INCLUDE_DIRS}
|
||||||
|
${SPATIALINDEX_INCLUDE_DIR}
|
||||||
|
${PROJ_INCLUDE_DIR}
|
||||||
|
${GEOS_INCLUDE_DIR}
|
||||||
|
${GDAL_INCLUDE_DIR}
|
||||||
|
${EXPAT_INCLUDE_DIR}
|
||||||
|
${SQLITE3_INCLUDE_DIR}
|
||||||
|
${SPATIALITE_INCLUDE_DIR}
|
||||||
|
${QCA_INCLUDE_DIR}
|
||||||
|
${QTKEYCHAIN_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
QT5_WRAP_CPP(QGIS_QUICK_APP_MOC_SRCS ${QGIS_QUICK_APP_MOC_HDRS})
|
||||||
|
QT5_ADD_RESOURCES(QGIS_QUICK_APP_RESOURCES qml.qrc)
|
||||||
|
SET(QGIS_QUICK_APP_NAME qgis_quickapp)
|
||||||
|
ADD_EXECUTABLE(${QGIS_QUICK_APP_NAME}
|
||||||
|
${QGIS_QUICK_APP_RESOURCES}
|
||||||
|
${QGIS_QUICK_APP_QMLS}
|
||||||
|
${QGIS_QUICK_APP_SRCS}
|
||||||
|
${QGIS_QUICK_APP_MOC_SRCS}
|
||||||
|
)
|
||||||
|
|
||||||
|
TARGET_LINK_LIBRARIES(${QGIS_QUICK_APP_NAME} Qt5::Gui Qt5::Qml Qt5::Quick Qt5::Xml qgis_core qgis_quick)
|
||||||
|
SET_TARGET_PROPERTIES(${QGIS_QUICK_APP_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
|
||||||
|
TARGET_COMPILE_DEFINITIONS(${QGIS_QUICK_APP_NAME} PRIVATE "-DQT_NO_FOREACH")
|
||||||
|
ADD_DEPENDENCIES(${QGIS_QUICK_APP_NAME}
|
||||||
|
qgis_quick_plugin
|
||||||
|
ogrprovider
|
||||||
|
gdalprovider
|
||||||
|
spatialiteprovider
|
||||||
|
virtuallayerprovider)
|
||||||
|
|
||||||
|
INSTALL(TARGETS ${QGIS_QUICK_APP_NAME}
|
||||||
|
RUNTIME DESTINATION ${QGIS_BIN_DIR}
|
||||||
|
LIBRARY DESTINATION ${QGIS_LIB_DIR}
|
||||||
|
ARCHIVE DESTINATION ${QGIS_LIB_DIR}
|
||||||
|
FRAMEWORK DESTINATION ${QGIS_FW_SUBDIR}
|
||||||
|
PUBLIC_HEADER DESTINATION ${QGIS_INCLUDE_DIR})
|
||||||
|
|
92
tests/src/quickgui/app/main.cpp
Normal file
92
tests/src/quickgui/app/main.cpp
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
main.cpp
|
||||||
|
--------------------------------------
|
||||||
|
Date : Nov 2017
|
||||||
|
Copyright : (C) 2017 by Peter Petrik
|
||||||
|
Email : zilolv at gmail dot com
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <QCommandLineParser>
|
||||||
|
#include <QQmlApplicationEngine>
|
||||||
|
#include <QQmlComponent>
|
||||||
|
#include <QQmlContext>
|
||||||
|
#include <QQmlError>
|
||||||
|
|
||||||
|
#include "qgis.h"
|
||||||
|
#include "qgsapplication.h"
|
||||||
|
#include "qgsproject.h"
|
||||||
|
#include "qgslayertree.h"
|
||||||
|
#include "qgsmessagelog.h"
|
||||||
|
#include "qgsquickutils.h"
|
||||||
|
#include "qgslogger.h"
|
||||||
|
|
||||||
|
int main( int argc, char *argv[] )
|
||||||
|
{
|
||||||
|
// 1) Initialize QGIS
|
||||||
|
QgsApplication app( argc, argv, true );
|
||||||
|
|
||||||
|
// Set up the QSettings environment must be done after qapp is created
|
||||||
|
QCoreApplication::setOrganizationName( "QGIS" );
|
||||||
|
QCoreApplication::setOrganizationDomain( "qgis.org" );
|
||||||
|
QCoreApplication::setApplicationName( "QgsQuick Test App" );
|
||||||
|
QCoreApplication::setApplicationVersion( Qgis::QGIS_VERSION );
|
||||||
|
|
||||||
|
QCommandLineParser parser;
|
||||||
|
parser.addVersionOption();
|
||||||
|
parser.process( app );
|
||||||
|
|
||||||
|
QgsApplication::init();
|
||||||
|
QgsApplication::initQgis();
|
||||||
|
|
||||||
|
// 2) Load QGIS Project
|
||||||
|
QString dataDir( TEST_DATA_DIR ); // defined in CMakeLists.txt
|
||||||
|
QString projectFile = dataDir + "/quickapp_project.qgs";
|
||||||
|
QgsDebugMsg( QStringLiteral( "project file: %1" ).arg( projectFile ) );
|
||||||
|
QgsProject project;
|
||||||
|
bool res = project.read( projectFile );
|
||||||
|
Q_ASSERT( res );
|
||||||
|
|
||||||
|
QQmlEngine engine;
|
||||||
|
engine.addImportPath( QgsApplication::qmlImportPath() );
|
||||||
|
engine.rootContext()->setContextProperty( "__project", &project );
|
||||||
|
engine.rootContext()->setContextProperty( "__layers", QVariant::fromValue( project.layerTreeRoot()->layerOrder() ) );
|
||||||
|
|
||||||
|
QQmlComponent component( &engine, QUrl( QStringLiteral( "qrc:/main.qml" ) ) );
|
||||||
|
QObject *object = component.create();
|
||||||
|
|
||||||
|
if ( !component.errors().isEmpty() )
|
||||||
|
{
|
||||||
|
QgsDebugMsg( QStringLiteral( "%s" ).arg( QgsApplication::showSettings().toLocal8Bit().data() ) );
|
||||||
|
|
||||||
|
QgsDebugMsg( QStringLiteral( "****************************************" ) );
|
||||||
|
QgsDebugMsg( QStringLiteral( "***** QML errors: *****" ) );
|
||||||
|
QgsDebugMsg( QStringLiteral( "****************************************" ) );
|
||||||
|
const QList<QQmlError> errors = component.errors();
|
||||||
|
for ( const QQmlError &error : errors )
|
||||||
|
{
|
||||||
|
QgsDebugMsg( error.toString() );
|
||||||
|
}
|
||||||
|
QgsDebugMsg( QStringLiteral( "****************************************" ) );
|
||||||
|
QgsDebugMsg( QStringLiteral( "****************************************" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( object == nullptr )
|
||||||
|
{
|
||||||
|
QgsDebugMsg( QStringLiteral( "FATAL ERROR: unable to create main.qml" ) );
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add some data for debugging if needed
|
||||||
|
QgsApplication::messageLog()->logMessage( QgsQuickUtils().dumpScreenInfo() );
|
||||||
|
QgsDebugMsg( QStringLiteral( "data directory: %1" ).arg( dataDir ) );
|
||||||
|
|
||||||
|
return app.exec();
|
||||||
|
}
|
||||||
|
|
40
tests/src/quickgui/app/main.qml
Normal file
40
tests/src/quickgui/app/main.qml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
main.qml
|
||||||
|
--------------------------------------
|
||||||
|
Date : Nov 2017
|
||||||
|
Copyright : (C) 2017 by Peter Petrik
|
||||||
|
Email : zilolv at gmail dot com
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Controls 2.2
|
||||||
|
import QgsQuick 0.1 as QgsQuick
|
||||||
|
import "."
|
||||||
|
|
||||||
|
ApplicationWindow {
|
||||||
|
id: window
|
||||||
|
visible: true
|
||||||
|
visibility: "Maximized"
|
||||||
|
title: qsTr("QGIS Quick Test App")
|
||||||
|
|
||||||
|
QgsQuick.MapCanvas {
|
||||||
|
id: mapCanvas
|
||||||
|
|
||||||
|
height: parent.height
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
mapSettings.project: __project
|
||||||
|
mapSettings.layers: __layers
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
var screenPoint = Qt.point(mouse.x, mouse.y)
|
||||||
|
console.log("clicked:" + screenPoint)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
5
tests/src/quickgui/app/qml.qrc
Normal file
5
tests/src/quickgui/app/qml.qrc
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/">
|
||||||
|
<file>main.qml</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
15
tests/src/quickgui/app/qtquickcontrols2.conf
Normal file
15
tests/src/quickgui/app/qtquickcontrols2.conf
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
; This file can be edited to change the style of the application
|
||||||
|
; See Styling Qt Quick Controls 2 in the documentation for details:
|
||||||
|
; http://doc.qt.io/qt-5/qtquickcontrols2-styles.html
|
||||||
|
|
||||||
|
[Controls]
|
||||||
|
Style=Default
|
||||||
|
|
||||||
|
[Universal]
|
||||||
|
Theme=Light
|
||||||
|
;Accent=Steel
|
||||||
|
|
||||||
|
[Material]
|
||||||
|
Theme=Light
|
||||||
|
;Accent=BlueGrey
|
||||||
|
;Primary=BlueGray
|
53
tests/src/quickgui/testqgsquickutils.cpp
Normal file
53
tests/src/quickgui/testqgsquickutils.cpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
testqgsquickutils.cpp
|
||||||
|
--------------------------------------
|
||||||
|
Date : Nov 2017
|
||||||
|
Copyright : (C) 2017 by Peter Petrik
|
||||||
|
Email : zilolv at gmail dot com
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
#include <QObject>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QDesktopWidget>
|
||||||
|
|
||||||
|
#include "qgsapplication.h"
|
||||||
|
#include "qgstest.h"
|
||||||
|
#include "qgis.h"
|
||||||
|
|
||||||
|
#include "qgsquickutils.h"
|
||||||
|
|
||||||
|
class TestQgsQuickUtils: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
private slots:
|
||||||
|
void init() {} // will be called before each testfunction is executed.
|
||||||
|
void cleanup() {} // will be called after every testfunction.
|
||||||
|
|
||||||
|
void screen_density();
|
||||||
|
|
||||||
|
void dump_screen_info();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QgsQuickUtils utils;
|
||||||
|
};
|
||||||
|
|
||||||
|
void TestQgsQuickUtils::screen_density()
|
||||||
|
{
|
||||||
|
qreal dp = utils.screenDensity();
|
||||||
|
QVERIFY( ( dp > 0 ) && ( dp < 1000 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestQgsQuickUtils::dump_screen_info()
|
||||||
|
{
|
||||||
|
qreal dp = utils.screenDensity();
|
||||||
|
QVERIFY( utils.dumpScreenInfo().contains( QStringLiteral( "%1" ).arg( dp ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
QGSTEST_MAIN( TestQgsQuickUtils )
|
||||||
|
#include "testqgsquickutils.moc"
|
1018
tests/testdata/quickapp_project.qgs
vendored
Normal file
1018
tests/testdata/quickapp_project.qgs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user