mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-22 00:06:12 -05:00
[FEATURE] Introduction of QGIS Quick library
This pull request is a subset of #6490 This adds a new library for creation of applications based on Qt Quick framework. It contains reusable QML / Qt Quick components based on QGIS core library. The initial work introduces MapCanvas To enable compilation of the library, use WITH_QUICK=TRUE Further documentation of the library is located in doc/qgsquick.dox For background information see the associated QEP: qgis/QGIS-Enhancement-Proposals#109 The initial implementation is largely based on the work of Matthias Kuhn and Marco Bernasocchi on QField probject - kudos to them for the great job!
This commit is contained in:
parent
f8165888e4
commit
b1bf9b2809
@ -40,6 +40,7 @@ echo "${bold}Running cmake...${endbold}"
|
||||
cmake \
|
||||
-GNinja \
|
||||
-DUSE_CCACHE=OFF \
|
||||
-DWITH_QUICK=ON \
|
||||
-DWITH_3D=ON \
|
||||
-DWITH_STAGED_PLUGINS=ON \
|
||||
-DWITH_GRASS=OFF \
|
||||
|
@ -33,11 +33,17 @@ RUN apt-get update \
|
||||
libqca-qt5-2-dev \
|
||||
libqca-qt5-2-plugins \
|
||||
libqt53drender5 \
|
||||
libqt5concurrent5 \
|
||||
libqt5opengl5-dev \
|
||||
libqt5positioning5 \
|
||||
libqt5qml5 \
|
||||
libqt5quick5 \
|
||||
libqt5quickcontrols2-5 \
|
||||
libqt5scintilla2-dev \
|
||||
libqt5sql5-sqlite \
|
||||
libqt5svg5-dev \
|
||||
libqt5webkit5-dev \
|
||||
libqt5xml5 \
|
||||
libqt5xmlpatterns5-dev \
|
||||
libqwt-qt5-dev \
|
||||
libspatialindex-dev \
|
||||
@ -77,6 +83,8 @@ RUN apt-get update \
|
||||
qt3d-scene2d-plugin \
|
||||
qt5keychain-dev \
|
||||
qtbase5-dev \
|
||||
qtdeclarative5-dev-tools \
|
||||
qtdeclarative5-qtquick2-plugin \
|
||||
qtpositioning5-dev \
|
||||
qttools5-dev \
|
||||
qttools5-dev-tools \
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -30,6 +30,8 @@ desktop.ini
|
||||
doc/INSTALL.tex
|
||||
i18n/*.qm
|
||||
Makefile
|
||||
*.pro.user
|
||||
*.stash
|
||||
ms-windows/*.exe*
|
||||
ms-windows/Installer-Files/postinstall.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_QUICK FALSE CACHE BOOL "Determines whether QGIS Quick library should be built")
|
||||
|
||||
# server disabled default because it needs FastCGI (which is optional dependency)
|
||||
SET (WITH_SERVER FALSE CACHE BOOL "Determines whether QGIS server should be built")
|
||||
IF(WITH_SERVER)
|
||||
@ -322,6 +324,18 @@ IF(WITH_CORE)
|
||||
ENDIF (WITH_3D)
|
||||
INCLUDE("cmake/modules/ECMQt4To5Porting.cmake")
|
||||
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)
|
||||
SET(OPTIONAL_QTWEBKIT ${Qt5WebKitWidgets_LIBRARIES})
|
||||
@ -373,6 +387,9 @@ ENDIF(WITH_CORE)
|
||||
# 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)")
|
||||
|
||||
# QML
|
||||
SET(QML_IMPORT_PATH "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" CACHE PATH "QML directory for QML autocomplete")
|
||||
|
||||
#############################################################
|
||||
# testing
|
||||
# whether unit tests should be build
|
||||
@ -513,6 +530,7 @@ IF (WITH_CORE)
|
||||
SET (DEFAULT_DATA_SUBDIR .)
|
||||
SET (DEFAULT_PLUGIN_SUBDIR plugins)
|
||||
SET (DEFAULT_INCLUDE_SUBDIR include)
|
||||
SET (DEFAULT_QML_SUBDIR qml)
|
||||
|
||||
SET (DEFAULT_SERVER_MODULE_SUBDIR server)
|
||||
|
||||
@ -583,6 +601,7 @@ IF (WITH_CORE)
|
||||
SET (DEFAULT_PLUGIN_SUBDIR ../PlugIns/qgis)
|
||||
SET (QGIS_PLUGIN_SUBDIR_REV ../../MacOS)
|
||||
SET (DEFAULT_INCLUDE_SUBDIR include/qgis)
|
||||
SET (DEFAULT_QML_SUBDIR qml)
|
||||
|
||||
# Set server moodules path to 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_PLUGIN_SUBDIR lib${LIB_SUFFIX}/qgis/plugins)
|
||||
SET (DEFAULT_INCLUDE_SUBDIR include/qgis)
|
||||
SET (DEFAULT_QML_SUBDIR qml)
|
||||
|
||||
SET (DEFAULT_SERVER_MODULE_SUBDIR ${DEFAULT_LIBEXEC_SUBDIR}/server)
|
||||
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_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_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")
|
||||
|
||||
@ -673,6 +694,7 @@ SET (QGIS_LIBEXEC_DIR ${QGIS_LIBEXEC_SUBDIR})
|
||||
SET (QGIS_DATA_DIR ${QGIS_DATA_SUBDIR})
|
||||
SET (QGIS_PLUGIN_DIR ${QGIS_PLUGIN_SUBDIR})
|
||||
SET (QGIS_INCLUDE_DIR ${QGIS_INCLUDE_SUBDIR})
|
||||
SET (QGIS_QML_DIR ${QGIS_QML_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_LIBEXEC_SUBDIR "${QGIS_LIBEXEC_SUBDIR}"
|
||||
#define QGIS_LIB_SUBDIR "${QGIS_LIB_SUBDIR}"
|
||||
#define QGIS_QML_SUBDIR "${QGIS_QML_SUBDIR}"
|
||||
#define CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}"
|
||||
#define CMAKE_SOURCE_DIR "${CMAKE_SOURCE_DIR}"
|
||||
|
||||
@ -64,5 +65,7 @@
|
||||
|
||||
#cmakedefine QGISDEBUG
|
||||
|
||||
#cmakedefine HAVE_QUICK
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -100,6 +100,8 @@ IF(WITH_APIDOC)
|
||||
${CMAKE_SOURCE_DIR}/src/3d/symbols
|
||||
${CMAKE_SOURCE_DIR}/src/3d/terrain
|
||||
${CMAKE_SOURCE_DIR}/src/plugins
|
||||
${CMAKE_SOURCE_DIR}/src/quickgui
|
||||
${CMAKE_SOURCE_DIR}/src/quickgui/plugin
|
||||
)
|
||||
|
||||
IF(WITH_SERVER_PLUGINS)
|
||||
|
@ -71,6 +71,7 @@ Nikos Alexandris
|
||||
Paolo Cavallini
|
||||
Paul Blottiere
|
||||
Paul Ramsey
|
||||
Peter Petrik
|
||||
Pierre Auckenthaler
|
||||
Raymond Nijssen
|
||||
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.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
|
||||
|
||||
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();
|
||||
%Docstring
|
||||
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
|
||||
|
||||
static void setPrefixPath( const QString &prefixPath, bool useDefaultPaths = false );
|
||||
|
@ -35,3 +35,6 @@ IF (WITH_CUSTOM_WIDGETS)
|
||||
ADD_SUBDIRECTORY(customwidgets)
|
||||
ENDIF (WITH_CUSTOM_WIDGETS)
|
||||
|
||||
IF (WITH_QUICK)
|
||||
ADD_SUBDIRECTORY(quickgui)
|
||||
ENDIF (WITH_QUICK)
|
||||
|
@ -90,6 +90,7 @@ QString ABISYM( QgsApplication::mPluginPath );
|
||||
QString ABISYM( QgsApplication::mPkgDataPath );
|
||||
QString ABISYM( QgsApplication::mLibraryPath );
|
||||
QString ABISYM( QgsApplication::mLibexecPath );
|
||||
QString ABISYM( QgsApplication::mQmlImportPath );
|
||||
QString ABISYM( QgsApplication::mThemeName );
|
||||
QString ABISYM( QgsApplication::mUIThemeName );
|
||||
QString ABISYM( QgsApplication::mProfilePath );
|
||||
@ -204,6 +205,9 @@ void QgsApplication::init( QString profileFolder )
|
||||
ABISYM( mLibexecPath ) = ABISYM( mBuildOutputPath ) + '/' + QGIS_LIBEXEC_SUBDIR + '/' + ABISYM( mCfgIntDir ) + '/';
|
||||
#else
|
||||
ABISYM( mLibexecPath ) = ABISYM( mBuildOutputPath ) + '/' + QGIS_LIBEXEC_SUBDIR + '/';
|
||||
#endif
|
||||
#if defined( HAVE_QUICK )
|
||||
ABISYM( mQmlImportPath ) = ABISYM( mBuildOutputPath ) + '/' + QGIS_QML_SUBDIR + '/';
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@ -396,6 +400,9 @@ void QgsApplication::setPrefixPath( const QString &prefixPath, bool useDefaultPa
|
||||
}
|
||||
ABISYM( mLibraryPath ) = ABISYM( mPrefixPath ) + '/' + QGIS_LIB_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 )
|
||||
@ -1001,6 +1008,11 @@ QString QgsApplication::libexecPath()
|
||||
return ABISYM( mLibexecPath );
|
||||
}
|
||||
|
||||
QString QgsApplication::qmlImportPath()
|
||||
{
|
||||
return ABISYM( mQmlImportPath );
|
||||
}
|
||||
|
||||
QgsApplication::endian_t QgsApplication::endian()
|
||||
{
|
||||
return ( htonl( 1 ) == 1 ) ? XDR : NDR;
|
||||
|
@ -405,6 +405,14 @@ class CORE_EXPORT QgsApplication : public QApplication
|
||||
//! Returns the path with utility executables (help viewer, crssync, ...)
|
||||
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
|
||||
static void setPrefixPath( const QString &prefixPath, bool useDefaultPaths = false );
|
||||
|
||||
@ -752,6 +760,7 @@ class CORE_EXPORT QgsApplication : public QApplication
|
||||
static QString ABISYM( mPkgDataPath );
|
||||
static QString ABISYM( mLibraryPath );
|
||||
static QString ABISYM( mLibexecPath );
|
||||
static QString ABISYM( mQmlImportPath );
|
||||
static QString ABISYM( mThemeName );
|
||||
static QStringList ABISYM( mDefaultSvgPaths );
|
||||
static QMap<QString, QString> ABISYM( mSystemEnvVars );
|
||||
|
@ -25,9 +25,12 @@ QgsRelationManager::QgsRelationManager( QgsProject *project )
|
||||
: QObject( project )
|
||||
, mProject( project )
|
||||
{
|
||||
connect( project, &QgsProject::readProject, this, &QgsRelationManager::readProject );
|
||||
connect( project, &QgsProject::writeProject, this, &QgsRelationManager::writeProject );
|
||||
connect( project, &QgsProject::layersRemoved, this, &QgsRelationManager::layersRemoved );
|
||||
if ( mProject )
|
||||
{
|
||||
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 )
|
||||
|
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}/QgisQuick)
|
||||
|
||||
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}/QgisQuick)
|
||||
|
||||
# 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}/qgisquick.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 QgisQuick 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}/QgisQuick)
|
||||
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}
|
||||
)
|
142
src/quickgui/plugin/qgsquickmapcanvas.qml
Normal file
142
src/quickgui/plugin/qgsquickmapcanvas.qml
Normal file
@ -0,0 +1,142 @@
|
||||
|
||||
/***************************************************************************
|
||||
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 QgisQuick 0.1 as QgsQuick
|
||||
|
||||
Item {
|
||||
id: mapArea
|
||||
property alias mapSettings: mapCanvasWrapper.mapSettings
|
||||
property alias isRendering: mapCanvasWrapper.isRendering
|
||||
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 QgisQuickPlugin::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 QgisQuickPlugin : 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 QgisQuick
|
||||
plugin qgis_quick_plugin
|
||||
|
||||
MapCanvas 0.1 qgsquickmapcanvas.qml
|
||||
|
||||
typeinfo qgisquick.qmltypes
|
394
src/quickgui/qgsquickmapcanvasmap.cpp
Normal file
394
src/quickgui/qgsquickmapcanvasmap.cpp
Normal file
@ -0,0 +1,394 @@
|
||||
/***************************************************************************
|
||||
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 );
|
||||
|
||||
Q_ASSERT( mMapSettings );
|
||||
connect( mMapSettings, &QgsQuickMapSettings::extentChanged, this, &QgsQuickMapCanvasMap::onExtentChanged );
|
||||
connect( mMapSettings, &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
|
||||
{
|
||||
Q_ASSERT( mMapSettings );
|
||||
return mMapSettings;
|
||||
}
|
||||
|
||||
void QgsQuickMapCanvasMap::zoom( QPointF center, qreal scale )
|
||||
{
|
||||
Q_ASSERT( mMapSettings );
|
||||
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 )
|
||||
{
|
||||
Q_ASSERT( mMapSettings );
|
||||
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()
|
||||
{
|
||||
Q_ASSERT( mMapSettings );
|
||||
|
||||
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 )
|
||||
{
|
||||
Q_ASSERT( mMapSettings );
|
||||
if ( screen )
|
||||
mMapSettings->setOutputDpi( screen->physicalDotsPerInch() );
|
||||
}
|
||||
|
||||
void QgsQuickMapCanvasMap::onExtentChanged()
|
||||
{
|
||||
updateTransform();
|
||||
|
||||
// And trigger a new rendering job
|
||||
refresh();
|
||||
}
|
||||
|
||||
void QgsQuickMapCanvasMap::updateTransform()
|
||||
{
|
||||
Q_ASSERT( mMapSettings );
|
||||
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 )
|
||||
Q_ASSERT( mMapSettings );
|
||||
// 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()
|
||||
{
|
||||
Q_ASSERT( mMapSettings );
|
||||
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()
|
||||
{
|
||||
Q_ASSERT( mMapSettings );
|
||||
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()
|
||||
{
|
||||
Q_ASSERT( mMapSettings );
|
||||
if ( mMapSettings->outputSize().isNull() )
|
||||
return; // the map image size has not been set yet
|
||||
|
||||
if ( !mFreeze )
|
||||
mRefreshTimer.start( 1 );
|
||||
}
|
202
src/quickgui/qgsquickmapcanvasmap.h
Normal file
202
src/quickgui/qgsquickmapcanvasmap.h
Normal file
@ -0,0 +1,202 @@
|
||||
/***************************************************************************
|
||||
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 <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();
|
||||
|
||||
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 &p ) const
|
||||
{
|
||||
QgsPointXY pt( p.x(), p.y() );
|
||||
QgsPointXY pp = mMapSettings.mapToPixel().transform( pt );
|
||||
return pp.toQPointF();
|
||||
}
|
||||
|
||||
QgsPoint QgsQuickMapSettings::screenToCoordinate( const QPointF &p ) const
|
||||
{
|
||||
const QgsPointXY pp = mMapSettings.mapToPixel().toMapCoordinates( p.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 p A coordinate in map coordinates
|
||||
*
|
||||
* \return A coordinate in pixel / screen space
|
||||
*/
|
||||
Q_INVOKABLE QPointF coordinateToScreen( const QgsPoint &p ) const;
|
||||
|
||||
|
||||
/**
|
||||
* Convert a screen coordinate to a map coordinate
|
||||
*
|
||||
* \param p A coordinate in pixel / screen coordinates
|
||||
*
|
||||
* \return A coordinate in map coordinates
|
||||
*/
|
||||
Q_INVOKABLE QgsPoint screenToCoordinate( const QPointF &p ) 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
|
71
src/quickgui/qgsquickutils.cpp
Normal file
71
src/quickgui/qgsquickutils.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
/***************************************************************************
|
||||
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 <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QString>
|
||||
#include <QThread>
|
||||
|
||||
#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)
|
||||
ENDIF (WITH_BINDINGS)
|
||||
ADD_SUBDIRECTORY(geometry_checker)
|
||||
IF (WITH_QUICK)
|
||||
ADD_SUBDIRECTORY(quickgui)
|
||||
ENDIF (WITH_QUICK)
|
||||
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 QgisQuick 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