Merge branch 'master' of https://github.com/qgis/QGIS into processing_parameters_refactoring

Conflicts:
	python/plugins/processing/gui/ExtentSelectionPanel.py
This commit is contained in:
volaya 2016-10-10 09:09:34 +02:00
commit fba87f79f3
201 changed files with 2557 additions and 856 deletions

View File

@ -42,6 +42,8 @@ cmake \
-DCMAKE_PREFIX_PATH=/home/travis/osgeo4travis \
-DWITH_STAGED_PLUGINS=ON \
-DWITH_GRASS=ON \
-DWITH_GRASS7=ON \
-DGRASS_PREFIX7=/home/travis/osgeo4travis/grass-7.0.4 \
-DSUPPRESS_QT_WARNINGS=ON \
-DENABLE_MODELTEST=ON \
-DENABLE_PGTEST=ON \

View File

@ -21,5 +21,5 @@ export CCACHE_TEMPDIR=/tmp
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
xvfb-run ctest -V -E "qgis_openstreetmaptest|qgis_wcsprovidertest|PyQgsWFSProviderGUI|qgis_ziplayertest|qgis_ogcutilstest|$(cat ${DIR}/blacklist.txt | paste -sd '|' -)" -S ./qgis-test-travis.ctest --output-on-failure
xvfb-run ctest -V -E "qgis_openstreetmaptest|qgis_wcsprovidertest|PyQgsWFSProviderGUI|qgis_ziplayertest|$(cat ${DIR}/blacklist.txt | paste -sd '|' -)" -S ./qgis-test-travis.ctest --output-on-failure
# xvfb-run ctest -V -E "qgis_openstreetmaptest|qgis_wcsprovidertest" -S ./qgis-test-travis.ctest --output-on-failure

4
debian/changelog vendored
View File

@ -1,9 +1,9 @@
qgis (2.99.0) UNRELEASED; urgency=medium
* New development version 2.999 after branch of 2.16
* move to qt5/python3
* move to qt5/python3/ninja
-- Jürgen E. Fischer <jef@norbit.de> Fri, 08 Jul 2016 14:12:36 +0200
-- Jürgen E. Fischer <jef@norbit.de> Thu, 06 Oct 2016 13:30:42 +0200
qgis (2.16.0) unstable; urgency=medium

1
debian/compat vendored Normal file
View File

@ -0,0 +1 @@
9

2
debian/compat.in vendored
View File

@ -1,2 +0,0 @@
#stretch sid jessie trusty xenial#9
#jessie#8

94
debian/control vendored
View File

@ -6,35 +6,41 @@ Priority: optional
Build-Depends:
bison,
cmake (>= 2.8),
debhelper (>= 7),
debhelper (>= 9),
dh-python,
flex,
grass-dev,
libexpat1-dev,
libfcgi-dev,
libgdal1-dev | libgdal-dev,
libgdal-dev (>= 1.11),
libgsl-dev,
libgeos-dev (>= 3.0.0),
libgsl0-dev,
libpq-dev,
libproj-dev,
qtbase5-dev,
libqca-qt5-2-dev,
libqwt-qt5-dev,
libspatialite-dev,
libsqlite3-dev,
libspatialindex-dev,
qtbase5-dev, qttools5-dev-tools, qttools5-dev, qtscript5-dev, qtpositioning5-dev,
libqt5svg5-dev, libqt5xmlpatterns5-dev, libqt5webkit5-dev, libqt5opengl5-dev, libqt5sql5-sqlite, libqt5scintilla2-dev,
libqwt-qt5-dev, libqca-qt5-2-dev, libqca-qt5-2-plugins,
python3-dev, python3-all-dev, python3-sip, python3-sip-dev,
pyqt5-dev-tools, pyqt5-dev, pyqt5.qsci-dev,
python3-pyqt5, python3-pyqt5.qsci, python3-pyqt5.qtsql, python3-pyqt5.qtsvg,
python3-gdal,
python3-nose2, python3-yaml, python3-mock, python3-psycopg2, python3-future, python3-termcolor,
pkg-config,
pyqt5-dev,
python3-dev,
python3-all-dev,
python3-sip,
python3-sip-dev,
python3-pyqt5,
git,
txt2tags,
doxygen
doxygen,
gdal-bin,
spawn-fcgi, lighttpd, poppler-utils,
graphviz,
xvfb, xauth,
xfonts-base, xfonts-100dpi, xfonts-75dpi, xfonts-scalable,
libosgearth-dev,
locales, ca-certificates, ninja-build
Build-Conflicts: libqgis-dev, qgis-dev
Standards-Version: 3.8.4
XS-Python-Version: current
Standards-Version: 3.9.7
Vcs-Browser: https://github.com/qgis/QGIS/
Vcs-Git: https://github.com/qgis/QGIS.git
Homepage: http://qgis.org/
@ -64,7 +70,9 @@ Description: Geographic Information System (GIS)
Package: qgis-common
Architecture: all
Depends:
${misc:Depends}
libjs-jquery,
libjs-leaflet,
${misc:Depends}
Description: QGIS - architecture-independent data
QGIS is a Geographic Information System (GIS) which manages, analyzes and
display databases of geographic information.
@ -72,20 +80,20 @@ Description: QGIS - architecture-independent data
This package contains architecture-independent supporting data files for use
with QGIS.
Package: libqgis-app3.0.0
Package: libqgis-app2.99.0
Architecture: any
Section: libs
Depends:
${shlibs:Depends},
${misc:Depends}
Replaces: libqgis{QGIS_ABI}
Replaces: libqgis2.99.0
Description: QGIS - shared app library
QGIS is a Geographic Information System (GIS) which manages, analyzes and
display databases of geographic information.
.
This package contains the shared app library.
Package: libqgis-core3.0.0
Package: libqgis-core2.99.0
Architecture: any
Section: libs
Depends:
@ -97,7 +105,7 @@ Description: QGIS - shared core library
.
This package contains the shared core library.
Package: libqgis-gui3.0.0
Package: libqgis-gui2.99.0
Architecture: any
Section: libs
Depends:
@ -109,7 +117,7 @@ Description: QGIS - shared gui library
.
This package contains the shared gui library.
Package: libqgis-analysis3.0.0
Package: libqgis-analysis2.99.0
Architecture: any
Section: libs
Depends:
@ -121,7 +129,7 @@ Description: QGIS - shared analysis library
.
This package contains the shared analysis library.
Package: libqgis-networkanalysis3.0.0
Package: libqgis-networkanalysis2.99.0
Architecture: any
Section: libs
Depends:
@ -133,7 +141,7 @@ Description: QGIS - shared network analysis library
.
This package contains the shared network analysis library.
Package: libqgisgrass3.0.0
Package: libqgisgrass7-2.99.0
Architecture: any
Section: libs
Depends:
@ -145,13 +153,13 @@ Description: QGIS - shared grass library
.
This package contains the shared grass library.
Package: libqgispython3.0.0
Package: libqgispython2.99.0
Architecture: any
Section: libs
Depends:
${shlibs:Depends},
${misc:Depends}
Replaces: libqgis3.0.0
Replaces: libqgis2.99.0
Description: QGIS - shared Python library
QGIS is a Geographic Information System (GIS) which manages, analyzes and
display databases of geographic information.
@ -170,7 +178,7 @@ Description: QGIS custom widgets for Qt Designer
.
This package contains a library to use specific QGIS widgets in Qt Designer.
Package: libqgis-server{QGIS_ABI}
Package: libqgis-server2.99.0
Architecture: any
Depends:
${shlibs:Depends},
@ -187,18 +195,18 @@ Section: libdevel
Depends:
grass-dev,
libexpat1-dev,
libgdal1-dev,
libgdal-dev (>= 1.11),
libgeos-dev (>= 3.0.0),
libgsl0-dev,
libgsl-dev,
libpq-dev,
libproj-dev,
libqgis-app3.0.0 (= ${binary:Version}),
libqgis-core3.0.0 (= ${binary:Version}),
libqgis-gui3.0.0 (= ${binary:Version}),
libqgis-analysis3.0.0 (= ${binary:Version}),
libqgis-networkanalysis3.0.0 (= ${binary:Version}),
libqgisgrass7.0.4-3.0.0 (= ${binary:Version}),
libqgispython3.0.0 (= ${binary:Version}),
libqgis-app2.99.0 (= ${binary:Version}),
libqgis-core2.99.0 (= ${binary:Version}),
libqgis-gui2.99.0 (= ${binary:Version}),
libqgis-analysis2.99.0 (= ${binary:Version}),
libqgis-networkanalysis2.99.0 (= ${binary:Version}),
libqgisgrass7-2.99.0 (= ${binary:Version}),
libqgispython2.99.0 (= ${binary:Version}),
libsqlite3-dev,
qtbase5-dev, python3-pyqt5, qttools5-dev,
libqt5svg5-dev, pyqt5.qsci-dev,
@ -229,13 +237,13 @@ Architecture: any
Section: debug
Priority: extra
Depends:
libqgis-app{QGIS_ABI} (= ${binary:Version}),
libqgis-core{QGIS_ABI} (= ${binary:Version}),
libqgis-gui{QGIS_ABI} (= ${binary:Version}),
libqgis-analysis{QGIS_ABI} (= ${binary:Version}),
libqgis-networkanalysis{QGIS_ABI} (= ${binary:Version}),
libqgisgrass{GRASSVER}-{QGIS_ABI} (= ${binary:Version}),
libqgispython{QGIS_ABI} (= ${binary:Version}),
libqgis-app2.99.0 (= ${binary:Version}),
libqgis-core2.99.0 (= ${binary:Version}),
libqgis-gui2.99.0 (= ${binary:Version}),
libqgis-analysis2.99.0 (= ${binary:Version}),
libqgis-networkanalysis2.99.0 (= ${binary:Version}),
libqgisgrass7-2.99.0 (= ${binary:Version}),
libqgispython2.99.0 (= ${binary:Version}),
${misc:Depends}
Suggests: gdb
Description: QGIS - debugging symbols
@ -304,7 +312,7 @@ Depends:
python3-six,
python3-yaml,
python3-future,
libqgispython3.0.0,
libqgispython2.99.0,
${shlibs:Depends},
${python:Depends},
${misc:Depends},

16
debian/control.in vendored
View File

@ -6,14 +6,14 @@ Priority: optional
Build-Depends:
bison,
cmake (>= 2.8),
#sid stretch jessie trusty xenial# debhelper (>= 9),
#sid stretch jessie trusty xenial# dh-python,
debhelper (>= 9),
dh-python,
flex,
grass-dev,
libexpat1-dev,
libfcgi-dev,
#sid stretch jessie trusty xenial# libgdal-dev (>= 1.10.1-0~),
#jessie trusty# libgsl0-dev,
libgdal-dev (>= 1.11),
#trusty# libgsl0-dev,
#sid stretch xenial# libgsl-dev,
libgeos-dev (>= 3.0.0),
libpq-dev,
@ -40,12 +40,10 @@ Build-Depends:
xfonts-base, xfonts-100dpi, xfonts-75dpi, xfonts-scalable,
#sid# libosgearth-dev,
#oracle# oracle-instantclient12.1-devel,
locales, ca-certificates
locales, ca-certificates, ninja-build
Build-Conflicts: libqgis-dev, qgis-dev
#sid stretch xenial#Standards-Version: 3.9.7
#jessie#Standards-Version: 3.9.6
#trusty#Standards-Version: 3.8.4
#sid stretch jessie#X-Python-Version: >= 2.7, << 2.8
#trusty xenial#XS-Python-Version: current
Vcs-Browser: https://github.com/qgis/QGIS/
Vcs-Git: https://github.com/qgis/QGIS.git
@ -202,9 +200,9 @@ Section: libdevel
Depends:
grass-dev,
libexpat1-dev,
#sid stretch jessie trusty xenial# libgdal-dev (>= 1.10.1-0~),
libgdal-dev (>= 1.11),
libgeos-dev (>= 3.0.0),
#jessie trusty# libgsl0-dev,
#trusty# libgsl0-dev,
#sid stretch xenial# libgsl-dev,
libpq-dev,
libproj-dev,

22
debian/rules vendored
View File

@ -36,16 +36,16 @@ endif
QT_PLUGINS_DIR = usr/lib/$(DEB_BUILD_MULTIARCH)/qt5/plugins
ifneq ($(DISTRIBUTION),$(findstring $(DISTRIBUTION),"stretch xenial"))
ifneq ($(DISTRIBUTION),$(findstring $(DISTRIBUTION),"trusty stretch xenial"))
DISTRIBUTION := sid
endif
DEB_BUILD_NAME ?= $(DISTRIBUTION)-$(DEB_BUILD_ARCH)
ifeq (,$(DISPLAY))
TESTMAKE=xvfb-run -a -n 1 -s "-screen 0 1280x1024x24 -dpi 96" $(MAKE)
TESTMAKE=xvfb-run -a -n 1 -s "-screen 0 1280x1024x24 -dpi 96" ninja
else
TESTMAKE=$(MAKE)
TESTMAKE=ninja
endif
QGIS_MAJOR=$(shell sed -ne 's/SET(CPACK_PACKAGE_VERSION_MAJOR "\([0-9]*\)")/\1/p' CMakeLists.txt)
@ -56,6 +56,7 @@ GRASS=grass$(subst .,,$(shell pkg-config --modversion grass|cut -d. -f1,2))
GRASSVER=$(subst .,,$(shell pkg-config --modversion grass|cut -d. -f1))
CMAKE_OPTS := \
-G Ninja \
-DBUILDNAME=$(DEB_BUILD_NAME) \
-DCMAKE_VERBOSE_MAKEFILE=1 \
-DCMAKE_INSTALL_PREFIX=/usr \
@ -84,7 +85,8 @@ CMAKE_OPTS := \
-DWITH_QSPATIALITE=TRUE \
-DWITH_PYSPATIALITE=TRUE \
-DQT_PLUGINS_DIR=$(QT_PLUGINS_DIR) \
-DPYTHON_LIBRARY=$(shell python3-config --ldflags | sed -e 's\#-L\(.*\) -L/usr/lib -l\([^ ]*\) .*$$\#\1/lib\2.so\#')
-DPYTHON_LIBRARY=$(shell python3-config --ldflags | sed -e 's\#-L\(.*\) -L/usr/lib -l\([^ ]*\) .*$$\#\1/lib\2.so\#') \
-DDOXYGEN_ON_DEMAND=TRUE
ifneq ($(SHA),)
CMAKE_OPTS += -DSHA=$(SHA)
@ -136,7 +138,7 @@ endif
-DORACLE_INCLUDEDIR=$(ORACLE_INCLUDEDIR)
endif
ifneq (,$(findstring $(DISTRIBUTION),"sid stretch jessie"))
ifneq (,$(findstring $(DISTRIBUTION),"sid stretch"))
CMAKE_OPTS += -DSPATIALINDEX_LIBRARY=/usr/lib/$(DEB_BUILD_MULTIARCH)/libspatialindex.so
endif
@ -154,12 +156,10 @@ else
CMAKE_OPTS += -DENABLE_TESTS=TRUE
endif
ifneq (,$(findstring $(DISTRIBUTION),"jessie stretch trusty sid"))
CPPFLAGS := $(shell dpkg-buildflags --get CPPFLAGS)
CFLAGS := $(shell dpkg-buildflags --get CFLAGS) $(CPPFLAGS)
CXXFLAGS := $(shell dpkg-buildflags --get CXXFLAGS) $(CPPFLAGS)
LDFLAGS := $(shell dpkg-buildflags --get LDFLAGS)
endif
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
INSTALL_PROGRAM += -s
@ -236,6 +236,12 @@ override_dh_clean: cleantemplates
override_dh_auto_configure:
dh_auto_configure -- $(CMAKE_OPTS)
override_dh_auto_build-arch:
ninja -C $(QGIS_BUILDDIR)
override_dh_auto_build-indep:
ninja -C $(QGIS_BUILDDIR) apidoc
override_dh_auto_test: test-stamp
test-stamp:
@ -254,7 +260,7 @@ endif
touch test-stamp
override_dh_auto_install:
dh_auto_install
DESTDIR=$(CURDIR)/debian/tmp ninja -C $(QGIS_BUILDDIR) install
# remove unwanted files
$(RM) $(CURDIR)/debian/tmp/usr/share/qgis/doc/api/installdox

View File

@ -103,7 +103,14 @@ IF(WITH_APIDOC)
STRING(REPLACE ";" " " DOXYGEN_INPUT "${DOXYGEN_INPUT}")
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/cmake_templates/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY)
ADD_CUSTOM_TARGET(apidoc ALL DEPENDS ${QHP_FILES})
SET (DOXYGEN_ON_DEMAND FALSE CACHE BOOL "Determines whether the QGIS API doxygen documentation should be build on demand only")
IF(DOXYGEN_ON_DEMAND)
ADD_CUSTOM_TARGET(apidoc DEPENDS ${QHP_FILES})
ELSE(DOXYGEN_ON_DEMAND)
ADD_CUSTOM_TARGET(apidoc ALL DEPENDS ${QHP_FILES})
ENDIF(DOXYGEN_ON_DEMAND)
ADD_CUSTOM_COMMAND(
OUTPUT ${QHP_FILES}
DEPENDS ${DOXYGEN_FILES}

View File

@ -710,6 +710,9 @@ version instead.</li>
<li>helptext() has been renamed to helpText()</li>
<li>isValid() has been renamed to checkExpression()</li>
<li>acceptVisitor() has been removed</li>
<li>QgsExpression::referencedColumns() returns QSet<QString> instead of QStringList</li>
<li>QgsExpression::Node::referencedColumns() returns QSet<QString> instead of QStringList</li>
<li>QgsExpression::Function::referencedColumns() returns QSet<QString> instead of QStringList</li>
</ul>
\subsection qgis_api_break_3_0_QgsFeature QgsFeature
@ -1087,6 +1090,14 @@ be used instead of a null pointer if no transformation is required.</li>
<li>prepareGeometry() and geometryRequiresPreparation() now take a QgsCoordinateTransform reference, not a pointer. An invalid QgsCoordinateTransform should be used instead of a null pointer if no transformation is required.</li>
</ul>
\subsection qgis_api_break_3_0_QgsPanelWidgetStack QgsPanelWidgetStack
<ul>
<li>addMainPanel() has been renamed to setMainPanel()</li>
<li>mainWidget() has been renamed to mainPanel()</li>
<li>takeMainWidget() has been renamed to takeMainPanel()</li>
</ul>
\subsection qgis_api_break_3_0_QgsPluginLayer QgsPluginLayer
<ul>
@ -1482,6 +1493,8 @@ optional property map passing down layer level properties to the SLD encoders. I
<code>scaleMinDenom</code> and <code>scaleMaxDenom</code> properties.</li>
<li>The RotationField capabitity was removed. This is now handled using data defined rotation at a symbol layer level</li>
<li>setScaleMethodToSymbol was removed. This is now handled using data defined scaling at a symbol layer level</li>
<li>setScaleMethodToSymbol was removed. This is now handled using data defined scaling at a symbol layer level</li>
<li>usedAttributes is now a const method and returns QSet<QString> instead of QStringList</li>
</ul>

View File

@ -7,7 +7,7 @@
<key>CFBundleName</key>
<string>QGIS</string>
<key>CFBundleIdentifier</key>
<string>org.qgis.qgis2</string>
<string>org.qgis.qgis3</string>
<key>CFBundleExecutable</key>
<string>${QGIS_APP_NAME}</string>
<key>CFBundlePackageType</key>

View File

@ -7,7 +7,7 @@
<key>CFBundleName</key>
<string>QGIS Browser</string>
<key>CFBundleIdentifier</key>
<string>org.qgis.qgis2_browser</string>
<string>org.qgis.qgis3_browser</string>
<key>CFBundleExecutable</key>
<string>QGIS Browser</string>
<key>CFBundlePackageType</key>

View File

@ -29,7 +29,7 @@ if "%ARCH%"=="" goto usage
if not "%SHA%"=="" set SHA=-%SHA%
if "%SITE%"=="" set SITE=qgis.org
set BUILDDIR=%CD%\build-nightly-%ARCH%
set BUILDDIR=%CD%\build-%PACKAGENAME%-%ARCH%
if "%OSGEO4W_ROOT%"=="" (
if "%ARCH%"=="x86" (
@ -52,35 +52,36 @@ if not "%PROGRAMFILES(X86)%"=="" set PF86=%PROGRAMFILES(X86)%
if "%PF86%"=="" set PF86=%PROGRAMFILES%
if "%PF86%"=="" (echo PROGRAMFILES not set & goto error)
if "%ARCH%"=="x86" goto devenv_x86
goto devenv_x86_64
if "%ARCH%"=="x86" goto cmake_x86
goto cmake_x86_64
:devenv_x86
:cmake_x86
set GRASS6_VERSION=6.4.4
call "%PF86%\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86
if exist "c:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" call "c:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" /x86 /Release
path %path%;%PF86%\Microsoft Visual Studio 10.0\VC\bin
set CMAKE_COMPILER_PATH=%PF86%\Microsoft Visual Studio 10.0\VC\bin
set CMAKE_OPT=^
-G "Visual Studio 10" ^
-D SIP_BINARY_PATH=%O4W_ROOT%/apps/Python27/sip.exe ^
-D QWT_LIBRARY=%O4W_ROOT%/lib/qwt.lib ^
-D CMAKE_CXX_FLAGS_RELWITHDEBINFO="/MD /ZI /MP /Od /D NDEBUG /D QGISDEBUG" ^
-D CMAKE_PDB_OUTPUT_DIRECTORY_RELWITHDEBINFO=%BUILDDIR%\apps\%PACKAGENAME%\pdb
goto devenv
-D CMAKE_PDB_OUTPUT_DIRECTORY_RELWITHDEBINFO=%BUILDDIR%\apps\%PACKAGENAME%\pdb ^
-D SPATIALINDEX_LIBRARY=%O4W_ROOT%/lib/spatialindex_i.lib
goto cmake
:devenv_x86_64
:cmake_x86_64
set GRASS6_VERSION=6.4.3
call "%PF86%\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" amd64
if exist "c:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" call "c:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" /x64 /Release
path %path%;%PF86%\Microsoft Visual Studio 10.0\VC\bin
set CMAKE_COMPILER_PATH=%PF86%\Microsoft Visual Studio 10.0\VC\bin\amd64
set SETUPAPI_LIBRARY=%PF86%\Microsoft SDKs\Windows\v7.0A\Lib\x64\SetupAPI.Lib
if not exist "%SETUPAPI_LIBRARY%" set SETUPAPI_LIBRARY=%PROGRAMFILES%\Microsoft SDKs\Windows\v7.1\Lib\x64\SetupAPI.lib
if not exist "%SETUPAPI_LIBRARY%" (echo SETUPAPI_LIBRARY not found & goto error)
set CMAKE_OPT=^
-G "Visual Studio 10 Win64" ^
-D SPATIALINDEX_LIBRARY=%O4W_ROOT%/lib/spatialindex-64.lib ^
-D SIP_BINARY_PATH=%O4W_ROOT%/bin/sip.exe ^
-D QWT_LIBRARY=%O4W_ROOT%/lib/qwt5.lib ^
@ -89,7 +90,7 @@ set CMAKE_OPT=^
-D SETUPAPI_LIBRARY="%SETUPAPI_LIBRARY%" ^
-D CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS=TRUE
:devenv
:cmake
for /f "usebackq tokens=1" %%a in (`%OSGEO4W_ROOT%\bin\grass70 --config path`) do set GRASS70_PATH=%%a
for %%i in ("%GRASS70_PATH%") do set GRASS70_VERSION=%%~nxi
set GRASS70_VERSION=%GRASS70_VERSION:grass-=%
@ -153,7 +154,10 @@ if errorlevel 1 goto error
set LIB=%LIB%;%OSGEO4W_ROOT%\lib
set INCLUDE=%INCLUDE%;%OSGEO4W_ROOT%\include
cmake %CMAKE_OPT% ^
cmake -G Ninja ^
-D CMAKE_CXX_COMPILER="%CMAKE_COMPILER_PATH:\=/%/cl.exe" ^
-D CMAKE_C_COMPILER="%CMAKE_COMPILER_PATH:\=/%/cl.exe" ^
-D CMAKE_LINKER="%CMAKE_COMPILER_PATH:\=/%/link.exe" ^
-D BUILDNAME="%PACKAGENAME%-%VERSION%%SHA%-Nightly-VC10-%ARCH%" ^
-D SITE="%SITE%" ^
-D PEDANTIC=TRUE ^
@ -195,7 +199,8 @@ cmake %CMAKE_OPT% ^
-D WITH_INTERNAL_MOCK=FALSE ^
-D WITH_INTERNAL_HTTPLIB2=FALSE ^
-D WITH_INTERNAL_FUTURE=FALSE ^
%SRCDIR%
%CMAKE_OPT% ^
%SRCDIR:\=/%
if errorlevel 1 (echo cmake failed & goto error)
:skipcmake
@ -244,7 +249,7 @@ if exist "%PKGDIR%" (
)
echo INSTALL: %DATE% %TIME%
cmake --build %BUILDDIR% --target INSTALL --config %BUILDCONF%
cmake --build %BUILDDIR% --target install --config %BUILDCONF%
if errorlevel 1 (echo INSTALL failed & goto error)
:package

View File

@ -29,7 +29,7 @@ if "%ARCH%"=="" goto usage
if not "%SHA%"=="" set SHA=-%SHA%
if "%SITE%"=="" set SITE=qgis.org
set BUILDDIR=%CD%\build-%ARCH%
set BUILDDIR=%CD%\build-%PACKAGENAME%-%ARCH%
if "%OSGEO4W_ROOT%"=="" (
if "%ARCH%"=="x86" (
@ -52,22 +52,22 @@ if not "%PROGRAMFILES(X86)%"=="" set PF86=%PROGRAMFILES(X86)%
if "%PF86%"=="" set PF86=%PROGRAMFILES%
if "%PF86%"=="" (echo PROGRAMFILES not set & goto error)
if "%ARCH%"=="x86" goto devenv_x86
goto devenv_x86_64
if "%ARCH%"=="x86" goto cmake_x86
goto cmake_x86_64
:devenv_x86
:cmake_x86
set GRASS6_VERSION=6.4.4
call "%PF86%\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86
if exist "c:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" call "c:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" /x86 /Release
path %path%;%PF86%\Microsoft Visual Studio 10.0\VC\bin
set CMAKE_COMPILER_PATH=%PF86%\Microsoft Visual Studio 10.0\VC\bin
set CMAKE_OPT=^
-G "Visual Studio 10" ^
-D SIP_BINARY_PATH=%O4W_ROOT%/apps/Python27/sip.exe ^
-D QWT_LIBRARY=%O4W_ROOT%/lib/qwt.lib
goto devenv
goto cmake
:devenv_x86_64
:cmake_x86_64
set GRASS6_VERSION=6.4.3
call "%PF86%\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" amd64
if exist "c:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" call "c:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" /x64 /Release
@ -78,14 +78,13 @@ if not exist "%SETUPAPI_LIBRARY%" set SETUPAPI_LIBRARY=%PROGRAMFILES%\Microsoft
if not exist "%SETUPAPI_LIBRARY%" (echo SETUPAPI_LIBRARY not found & goto error)
set CMAKE_OPT=^
-G "Visual Studio 10 Win64" ^
-D SPATIALINDEX_LIBRARY=%O4W_ROOT%/lib/spatialindex-64.lib ^
-D SIP_BINARY_PATH=%O4W_ROOT%/bin/sip.exe ^
-D QWT_LIBRARY=%O4W_ROOT%/lib/qwt5.lib ^
-D SETUPAPI_LIBRARY="%SETUPAPI_LIBRARY%" ^
-D CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS=TRUE
:devenv
:cmake
for /f "usebackq tokens=1" %%a in (`%OSGEO4W_ROOT%\bin\grass70 --config path`) do set GRASS70_PATH=%%a
for %%i in ("%GRASS70_PATH%") do set GRASS70_VERSION=%%~nxi
set GRASS70_VERSION=%GRASS70_VERSION:grass-=%
@ -149,7 +148,7 @@ if errorlevel 1 goto error
set LIB=%LIB%;%OSGEO4W_ROOT%\lib
set INCLUDE=%INCLUDE%;%OSGEO4W_ROOT%\include
cmake %CMAKE_OPT% ^
cmake -G Ninja ^
-D BUILDNAME="%PACKAGENAME%-%VERSION%%SHA%-Release-VC10-%ARCH%" ^
-D SITE="%SITE%" ^
-D PEDANTIC=TRUE ^
@ -189,7 +188,8 @@ cmake %CMAKE_OPT% ^
-D WITH_INTERNAL_PYTZ=FALSE ^
-D WITH_INTERNAL_SIX=FALSE ^
-D WITH_INTERNAL_FUTURE=FALSE ^
%SRCDIR%
%CMAKE_OPT% ^
%SRCDIR:\=/%
if errorlevel 1 (echo cmake failed & goto error)
:skipcmake
@ -229,7 +229,7 @@ if exist "%PKGDIR%" (
)
echo INSTALL: %DATE% %TIME%
cmake --build %BUILDDIR% --target INSTALL --config %BUILDCONF%
cmake --build %BUILDDIR% --target install --config %BUILDCONF%
if errorlevel 1 (echo INSTALL failed & goto error)
echo PACKAGE: %DATE% %TIME%

View File

@ -7,22 +7,22 @@
# Please don't remove this header. #
################################################################################
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS2\Plugins" "coordinatecaptureplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS2\Plugins" "diagramoverlay" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS2\Plugins" "dxf2shpconverterplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS2\Plugins" "evis" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS2\Plugins" "georefplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS2\Plugins" "globeplugin" "false"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS2\Plugins" "gpsimporterplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS2\Plugins" "grassplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS2\Plugins" "heatmapplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS2\Plugins" "interpolationplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS2\Plugins" "offlineeditingplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS2\Plugins" "oracleplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS2\Plugins" "rasterterrainplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS2\Plugins" "roadgraphplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS2\Plugins" "spatialqueryplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS2\Plugins" "topolplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS2\Plugins" "zonalstatisticsplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS3\Plugins" "coordinatecaptureplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS3\Plugins" "diagramoverlay" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS3\Plugins" "dxf2shpconverterplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS3\Plugins" "evis" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS3\Plugins" "georefplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS3\Plugins" "globeplugin" "false"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS3\Plugins" "gpsimporterplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS3\Plugins" "grassplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS3\Plugins" "heatmapplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS3\Plugins" "interpolationplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS3\Plugins" "offlineeditingplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS3\Plugins" "oracleplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS3\Plugins" "rasterterrainplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS3\Plugins" "roadgraphplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS3\Plugins" "spatialqueryplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS3\Plugins" "topolplugin" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS3\Plugins" "zonalstatisticsplugin" "true"
############################### reg2nsis end #################################

View File

@ -7,8 +7,8 @@
# Please don't remove this header. #
################################################################################
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS2\PythonPlugins" "GdalTools" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS2\PythonPlugins" "db_manager" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS2\PythonPlugins" "processing" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS3\PythonPlugins" "GdalTools" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS3\PythonPlugins" "db_manager" "true"
WriteRegStr HKEY_CURRENT_USER "Software\QGIS\QGIS3\PythonPlugins" "processing" "true"
############################### reg2nsis end #################################

View File

@ -44,7 +44,7 @@ class QgsAuthManager : QObject
/** Standard message for when QCA's qca-ossl plugin is missing and system is disabled */
const QString disabledMessage() const;
/** The standard authentication database file in ~/.qgis2/ or defined location
/** The standard authentication database file in ~/.qgis3/ or defined location
* @see QgsApplication::qgisAuthDbFilePath
*/
const QString authenticationDbPath() const;

View File

@ -49,9 +49,14 @@ class QgsComposerMergeCommand : QgsComposerItemCommand
//composer label
ComposerLabelSetText,
ComposerLabelSetId,
ComposerLabelFontColor,
//composer map
ComposerMapRotation,
ComposerMapAnnotationDistance,
ComposerMapGridFramePenColor,
ComposerMapGridFrameFill1Color,
ComposerMapGridFrameFill2Color,
ComposerMapGridAnnotationFontColor,
//composer legend
ComposerLegendText,
LegendColumnCount,
@ -69,8 +74,12 @@ class QgsComposerMergeCommand : QgsComposerItemCommand
LegendBoxSpace,
LegendColumnSpace,
LegendRasterBorderWidth,
LegendFontColor,
LegendRasterBorderColor,
//composer picture
ComposerPictureRotation,
ComposerPictureFillColor,
ComposerPictureOutlineColor,
// composer scalebar
ScaleBarLineWidth,
ScaleBarHeight,
@ -81,6 +90,10 @@ class QgsComposerMergeCommand : QgsComposerItemCommand
ScaleBarMapUnitsSegment,
ScaleBarLabelBarSize,
ScaleBarBoxContentSpace,
ScaleBarFontColor,
ScaleBarFillColor,
ScaleBarFill2Color,
ScaleBarStrokeColor,
// composer table
TableMaximumFeatures,
TableMargin,
@ -90,9 +103,13 @@ class QgsComposerMergeCommand : QgsComposerItemCommand
ShapeOutlineWidth,
//composer arrow
ArrowOutlineWidth,
ArrowHeadFillColor,
ArrowHeadOutlineColor,
ArrowHeadWidth,
//item
ItemOutlineWidth,
ItemOutlineColor,
ItemBackgroundColor,
ItemMove,
ItemRotation,
ItemTransparency,

View File

@ -49,7 +49,11 @@ class QgsComposerMultiFrameMergeCommand: QgsComposerMultiFrameCommand
TableMaximumFeatures,
TableMargin,
TableGridStrokeWidth,
TableCellStyle
TableCellStyle,
TableHeaderFontColor,
TableContentFontColor,
TableGridColor,
TableBackgroundColor,
};
QgsComposerMultiFrameMergeCommand( Context c, QgsComposerMultiFrame* multiFrame, const QString& text );

View File

@ -124,7 +124,7 @@ static void qtgui_UpdatePyArgv(PyObject *argvlist, int argc, char **argv)
static void setUITheme( const QString &themeName );
/**
* @brief All themes found in ~/.qgis2/themes folder.
* @brief All themes found in ~/.qgis3/themes folder.
* The path is to the root folder for the theme
* @note Valid theme folders must contain a style.qss file.
* @return A hash of theme name and theme path. Valid theme folders contain style.qss

View File

@ -128,7 +128,7 @@ class QgsDataDefined
* @param context expression context, used for preparing the expression if required
* @note added in QGIS 2.12
*/
QStringList referencedColumns( const QgsExpressionContext& context = QgsExpressionContext() );
QSet<QString> referencedColumns( const QgsExpressionContext& context = QgsExpressionContext() );
/**
* Get the field which this QgsDataDefined represents. Be aware that this may return

View File

@ -51,7 +51,7 @@ class QgsExpression
*
* TODO QGIS3: Return QSet<QString>
*/
QStringList referencedColumns() const;
QSet<QString> referencedColumns() const;
/**
* Return a list of field name indexes obtained from the provided fields.
@ -301,7 +301,7 @@ class QgsExpression
const QString& group,
const QString& helpText = QString(),
bool usesGeometry = false,
const QStringList& referencedColumns = QStringList(),
const QSet<QString>& referencedColumns = QSet<QString>(),
bool lazyEval = false,
bool handlesNull = false,
bool isContextual = false );
@ -314,7 +314,7 @@ class QgsExpression
const QString& group,
const QString& helpText = QString(),
bool usesGeometry = false,
const QStringList& referencedColumns = QStringList(),
const QSet<QString>& referencedColumns = QSet<QString>(),
bool lazyEval = false,
bool handlesNull = false,
bool isContextual = false );
@ -350,7 +350,7 @@ class QgsExpression
*/
bool lazyEval() const;
virtual QStringList referencedColumns() const;
virtual QSet<QString> referencedColumns() const;
/** Returns whether the function is only available if provided by a QgsExpressionContext object.
* @note added in QGIS 2.12
@ -517,7 +517,7 @@ class QgsExpression
*
* @return A list of columns required to evaluate this expression
*/
virtual QStringList referencedColumns() const = 0;
virtual QSet<QString> referencedColumns() const = 0;
/**
* Abstract virtual method which returns if the geometry is required to evaluate
@ -596,7 +596,7 @@ class QgsExpression
virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context );
virtual QString dump() const;
virtual QStringList referencedColumns() const;
virtual QSet<QString> referencedColumns() const;
virtual bool needsGeometry() const;
virtual QgsExpression::Node* clone() const;
};
@ -616,7 +616,7 @@ class QgsExpression
virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context );
virtual QString dump() const;
virtual QStringList referencedColumns() const;
virtual QSet<QString> referencedColumns() const;
virtual bool needsGeometry() const;
virtual QgsExpression::Node* clone() const;
@ -650,7 +650,7 @@ class QgsExpression
virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context );
virtual QString dump() const;
virtual QStringList referencedColumns() const;
virtual QSet<QString> referencedColumns() const;
virtual bool needsGeometry() const;
virtual QgsExpression::Node* clone() const;
};
@ -670,7 +670,7 @@ class QgsExpression
virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context );
virtual QString dump() const;
virtual QStringList referencedColumns() const;
virtual QSet<QString> referencedColumns() const;
virtual bool needsGeometry() const;
virtual QgsExpression::Node* clone() const;
@ -692,7 +692,7 @@ class QgsExpression
virtual QString dump() const;
virtual QgsExpression::Node* clone() const;
virtual QStringList referencedColumns() const;
virtual QSet<QString> referencedColumns() const;
virtual bool needsGeometry() const;
};
@ -709,7 +709,7 @@ class QgsExpression
virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context );
virtual QString dump() const;
virtual QStringList referencedColumns() const;
virtual QSet<QString> referencedColumns() const;
virtual bool needsGeometry() const;
virtual QgsExpression::Node* clone() const;
@ -741,7 +741,7 @@ class QgsExpression
virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context );
virtual QString dump() const;
virtual QStringList referencedColumns() const;
virtual QSet<QString> referencedColumns() const;
virtual bool needsGeometry() const;
virtual QgsExpression::Node* clone() const;
};

View File

@ -17,7 +17,7 @@ class QgsScopedExpressionFunction : QgsExpression::Function
const QString& group,
const QString& helpText = QString(),
bool usesGeometry = false,
const QStringList& referencedColumns = QStringList(),
const QSet<QString>& referencedColumns = QSet<QString>(),
bool lazyEval = false,
bool handlesNull = false,
bool isContextual = true );

View File

@ -27,6 +27,16 @@ class QgsExpressionFieldBuffer
*/
void removeExpression( int index );
/**
* Renames an expression field at a given index
*
* @param index The index of the expression to change
* @param name New name for field
*
* @note added in 3.0
*/
void renameExpression( int index, const QString& name );
/**
* Changes the expression at a given index
*

View File

@ -122,14 +122,14 @@ class QgsLabelingEngineInterface
//! clears data defined objects from PAL layer settings for a registered layer
virtual void clearActiveLayer( const QString& layerID ) = 0;
//! called when starting rendering of a layer
virtual int prepareLayer( QgsVectorLayer* layer, QStringList& attrNames, QgsRenderContext& ctx ) = 0;
virtual int prepareLayer( QgsVectorLayer* layer, QSet<QString>& attrNames, QgsRenderContext& ctx ) = 0;
//! adds a diagram layer to the labeling engine
//! @note added in QGIS 2.12
virtual int prepareDiagramLayer( QgsVectorLayer *layer, QStringList &attrNames, QgsRenderContext &ctx );
virtual int prepareDiagramLayer( QgsVectorLayer *layer, QSet<QString>& attrNames, QgsRenderContext& ctx );
//! called for every feature
virtual void registerFeature( const QString &layerID, QgsFeature &feat, QgsRenderContext &context ) = 0;
virtual void registerFeature( const QString &layerID, QgsFeature& feat, QgsRenderContext& context ) = 0;
//! called for every diagram feature
virtual void registerDiagramFeature( const QString &layerID, QgsFeature &feat, QgsRenderContext &context );
virtual void registerDiagramFeature( const QString& layerID, QgsFeature& feat, QgsRenderContext& context );
//! called when the map is drawn and labels should be placed
virtual void drawLabeling( QgsRenderContext& context ) = 0;
//! called when we're done with rendering
@ -915,10 +915,10 @@ class QgsPalLabeling : QgsLabelingEngineInterface
//! clears data defined objects from PAL layer settings for a registered layer
virtual void clearActiveLayer( const QString& layerID );
//! hook called when drawing layer before issuing select()
virtual int prepareLayer( QgsVectorLayer* layer, QStringList &attrNames, QgsRenderContext& ctx );
virtual int prepareLayer( QgsVectorLayer* layer, QSet<QString>& attrNames, QgsRenderContext& ctx );
//! adds a diagram layer to the labeling engine
//! @note added in QGIS 2.12
virtual int prepareDiagramLayer( QgsVectorLayer* layer, QStringList& attrNames, QgsRenderContext& ctx );
virtual int prepareDiagramLayer( QgsVectorLayer* layer, QSet<QString>& attrNames, QgsRenderContext& ctx );
/** Register a feature for labelling.
* @param layerID string identifying layer associated with label

View File

@ -171,6 +171,12 @@ class QgsRelation
*/
QString id() const;
/**
* Generate a (project-wide) unique id for this relation
* @note added in QGIS 3.0
*/
void generateId();
/**
* Access the referencing (child) layer's id
* This is the layer which has the field(s) which point to another layer
@ -241,6 +247,15 @@ class QgsRelation
*/
bool isValid() const;
/**
* Compares the two QgsRelation, ignoring the name and the ID.
*
* @param other The other relation
* @return true if they are similar
* @note added in QGIS 3.0
*/
bool hasEqualDefinition( const QgsRelation& other ) const;
protected:
/**
* Updates the validity status of this relation.

View File

@ -90,6 +90,16 @@ class QgsRelationManager : QObject
*/
QList<QgsRelation> referencedRelations( QgsVectorLayer *layer = 0 ) const;
/**
* Discover all the relations available from the current layers.
*
* @param existingRelations the existing relations to filter them out
* @param layers the current layers
* @return the list of discovered relations
* @note added in QGIS 3.0
*/
static QList<QgsRelation> discoverRelations( const QList<QgsRelation>& existingRelations, const QList<QgsVectorLayer*>& layers );
signals:
/** This signal is emitted when the relations were loaded after reading a project */
void relationsLoaded();

View File

@ -371,6 +371,15 @@ class QgsVectorDataProvider : QgsDataProvider
*/
virtual QSet<QgsMapLayerDependency> dependencies() const;
/**
* Discover the available relations with the given layers.
* @param self the layer using this data provider.
* @param layers the other layers.
* @return the list of N-1 relations from this provider.
* @note added in QGIS 3.0
*/
virtual QList<QgsRelation> discoverRelations( const QgsVectorLayer* self, const QList<QgsVectorLayer*>& layers ) const;
signals:
/** Signals an error in this provider */
void raiseError( const QString& msg );

View File

@ -33,7 +33,7 @@ class Qgs25DRenderer : QgsFeatureRenderer
void startRender( QgsRenderContext& context, const QgsFields& fields );
void stopRender( QgsRenderContext& context );
QList<QString> usedAttributes();
QSet<QString> usedAttributes() const;
QgsFeatureRenderer* clone() const;
virtual QgsSymbol* symbolForFeature( QgsFeature& feature, QgsRenderContext& context );

View File

@ -59,7 +59,7 @@ class QgsCategorizedSymbolRenderer : QgsFeatureRenderer
virtual void stopRender( QgsRenderContext& context );
virtual QList<QString> usedAttributes();
virtual QSet<QString> usedAttributes() const;
virtual QString dump() const;

View File

@ -102,7 +102,7 @@ class QgsGraduatedSymbolRenderer : QgsFeatureRenderer
virtual void stopRender( QgsRenderContext& context );
virtual QList<QString> usedAttributes();
virtual QSet<QString> usedAttributes() const;
virtual QString dump() const;

View File

@ -18,7 +18,7 @@ class QgsHeatmapRenderer : QgsFeatureRenderer
//! @note symbol2 in python bindings
virtual QgsSymbolList symbols( QgsRenderContext& context );
virtual QString dump() const;
virtual QList<QString> usedAttributes();
virtual QSet<QString> usedAttributes() const;
static QgsFeatureRenderer* create( QDomElement& element ) /Factory/;
virtual QDomElement save( QDomDocument& doc );
static QgsHeatmapRenderer* convertFromRenderer( const QgsFeatureRenderer* renderer ) /Factory/;

View File

@ -39,7 +39,7 @@ class QgsInvertedPolygonRenderer : QgsFeatureRenderer
virtual QString dump() const;
/** Proxy that will call this method on the embedded renderer. */
virtual QList<QString> usedAttributes();
virtual QSet<QString> usedAttributes() const;
/** Proxy that will call this method on the embedded renderer. */
virtual QgsFeatureRenderer::Capabilities capabilities();
/** Proxy that will call this method on the embedded renderer.

View File

@ -24,7 +24,7 @@ class QgsNullSymbolRenderer : QgsFeatureRenderer
virtual void stopRender( QgsRenderContext& context );
virtual bool willRenderFeature( QgsFeature& feat, QgsRenderContext& context );
virtual QList<QString> usedAttributes();
virtual QSet<QString> usedAttributes() const;
virtual QString dump() const;
virtual QgsFeatureRenderer* clone() const /Factory/;
virtual QgsSymbolList symbols( QgsRenderContext& context );

View File

@ -16,7 +16,7 @@ class QgsPointClusterRenderer : QgsPointDistanceRenderer
virtual void startRender( QgsRenderContext& context, const QgsFields& fields );
void stopRender( QgsRenderContext& context );
QDomElement save( QDomDocument& doc );
virtual QList<QString> usedAttributes();
virtual QSet<QString> usedAttributes() const;
//! Create a renderer from XML element
static QgsFeatureRenderer* create( QDomElement& symbologyElem ) /Factory/;

View File

@ -26,7 +26,7 @@ class QgsPointDisplacementRenderer : QgsPointDistanceRenderer
virtual void startRender( QgsRenderContext& context, const QgsFields& fields );
void stopRender( QgsRenderContext& context );
QDomElement save( QDomDocument& doc );
virtual QList<QString> usedAttributes();
virtual QSet<QString> usedAttributes() const;
//! Create a renderer from XML element
static QgsFeatureRenderer* create( QDomElement& symbologyElem ) /Factory/;

View File

@ -50,7 +50,7 @@ class QgsPointDistanceRenderer : QgsFeatureRenderer
virtual void toSld( QDomDocument& doc, QDomElement &element, QgsStringMap props = QgsStringMap() ) const;
bool renderFeature( QgsFeature& feature, QgsRenderContext& context, int layer = -1, bool selected = false, bool drawVertexMarker = false );
virtual QList<QString> usedAttributes();
virtual QSet<QString> usedAttributes() const;
virtual Capabilities capabilities();
virtual QgsSymbolList symbols( QgsRenderContext& context );
virtual QgsSymbol* symbolForFeature( QgsFeature& feature, QgsRenderContext& context );

View File

@ -119,10 +119,8 @@ class QgsFeatureRenderer
/**
* Returns a set of attributes required for this renderer.
*
* TODO QGIS3: Change QList to QSet
*/
virtual QList<QString> usedAttributes() = 0;
virtual QSet<QString> usedAttributes() const = 0;
/**
* Returns true if this renderer requires the geometry to apply the filter.

View File

@ -340,7 +340,7 @@ class QgsRuleBasedRenderer : QgsFeatureRenderer
virtual QString filter( const QgsFields& fields = QgsFields() );
virtual QList<QString> usedAttributes();
virtual QSet<QString> usedAttributes() const;
virtual bool filterNeedsGeometry() const;

View File

@ -19,7 +19,7 @@ class QgsSingleSymbolRenderer : QgsFeatureRenderer
virtual void stopRender( QgsRenderContext& context );
virtual QList<QString> usedAttributes();
virtual QSet<QString> usedAttributes() const;
QgsSymbol* symbol() const;
void setSymbol( QgsSymbol* s /Transfer/ );

View File

@ -19,26 +19,33 @@ class QgsPanelWidgetStack: public QWidget
QgsPanelWidgetStack( QWidget* parent = nullptr );
/**
* Adds the main widget to the stack and selects it for the user
* Adds the main panel widget to the stack and selects it for the user
* The main widget can not be closed and only the showPanel signal is attached
* to handle children widget opening panels.
* @param panel The panel to set as the first widget in the stack.
* @note a stack can have only one main panel. Any existing main panel
* should be removed by first calling takeMainPanel().
* @see mainPanel()
* @see takeMainPanel()
*/
void addMainPanel( QgsPanelWidget* panel );
void setMainPanel( QgsPanelWidget* panel );
/**
* The main widget that is set in the stack. The main widget can not be closed
* The main panel widget that is set in the stack. The main widget can not be closed
* and doesn't display a back button.
* @return The main QgsPanelWidget that is active in the stack.
* @see setMainPanel()
*/
QgsPanelWidget* mainWidget();
QgsPanelWidget* mainPanel();
/**
* Removes the main widget from the stack and transfers ownsership to the
* Removes the main panel widget from the stack and transfers ownsership to the
* caller.
* @return The main widget that is set in the stack.
* @see mainPanel()
* @see setMainPanel()
*/
QgsPanelWidget* takeMainWidget();
QgsPanelWidget* takeMainPanel();
/**
* Clear the stack of all widgets. Unless the panels autoDelete is set to false
@ -46,15 +53,29 @@ class QgsPanelWidgetStack: public QWidget
*/
void clear();
/**
* Returns the panel currently shown in the stack.
* @note added in QGIS 3.0
*/
QgsPanelWidget* currentPanel();
public slots:
/**
* Accept the current active widget in the stack.
*
* Calls the panelAccepeted signal on the active widget.
* @see acceptAllPanels()
*/
void acceptCurrentPanel();
/**
* Accepts all panel widgets open in the stack in turn until until only the mainPanel()
* remains.
* @see acceptCurrentPanel();
* @note added in QGIS 3.0
*/
void acceptAllPanels();
/**
* Show a panel in the stack widget. Will connect to the panels showPanel event to handle
* nested panels. Auto switches the the given panel for the user.

View File

@ -153,6 +153,10 @@ class GdalToolsDialog(QWidget, Ui_Widget, BasePluginWidget):
self.inSelector.setLayer(None)
return
ncodec = QTextCodec.codecForName(self.lastEncoding)
# GDAL Python3 bindings return fields as str and not bytes
# so no recoding is needed. But this assumes that the underlying
# OGR driver always return a Unicode string. hum...
#ncodec = QTextCodec.codecForName(self.lastEncoding)
for name in names:
self.attributeComboBox.addItem(ncodec.toUnicode(name))
self.attributeComboBox.addItem(name)
#self.attributeComboBox.addItem(ncodec.toUnicode(name))

View File

@ -49,7 +49,7 @@ options(
home=BASEDIR,
plugin=path(BASEDIR),
ui=path(BASEDIR) / 'plugin' / PLUGIN_NAME / 'ui',
install=path('%s/.qgis2/python/plugins/MetaSearch' % USERDIR),
install=path('%s/.qgis3/python/plugins/MetaSearch' % USERDIR),
ext_libs=path('plugin/MetaSearch/ext-libs'),
tmp=path(path('%s/MetaSearch-dist' % USERDIR)),
version=VERSION
@ -86,7 +86,7 @@ def clean():
def install():
"""install plugin into user QGIS environment"""
plugins_dir = path(USERDIR) / '.qgis2/python/plugins'
plugins_dir = path(USERDIR) / '.qgis3/python/plugins'
if os.path.exists(options.base.install):
if os.path.islink(options.base.install):

View File

@ -88,7 +88,7 @@ class warp(GdalAlgorithm):
0.0, None, 0.0))
self.addParameter(ParameterSelection(self.METHOD,
self.tr('Resampling method'), self.METHOD_OPTIONS))
self.addParameter(ParameterExtent(self.RAST_EXT, self.tr('Raster extent')))
self.addParameter(ParameterExtent(self.RAST_EXT, self.tr('Raster extent'), optional=True))
if GdalUtils.version() >= 2000000:
self.addParameter(ParameterCrs(self.EXT_CRS,

View File

@ -19,7 +19,7 @@ export LD_LIBRARY_PATH=/path/to/OTB/install/lib/:$LD_LIBRARY_PATH
Set QGIS environment
---------------------
export QGIS_PREFIX_PATH=/path/to/QGIS/install
export PYTHONPATH=:/usr/share/qgis/python/plugins:~/.qgis2/python/plugins:$PYTHONPATH
export PYTHONPATH=:/usr/share/qgis/python/plugins:~/.qgis3/python/plugins:$PYTHONPATH
# Set LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$QGIS_PREFIX_PATH/lib/:$LD_LIBRARY_PATH
# Add maintenance folder to python path

View File

@ -37,7 +37,7 @@ from osgeo.gdalconst import GA_ReadOnly
from numpy import nan_to_num
from qgis.PyQt.QtCore import QCoreApplication, QMetaObject
from qgis.PyQt.QtWidgets import QDialog, QVBoxLayout, QTextEdit
from qgis.PyQt.QtWidgets import QDialog, QVBoxLayout, QTextEdit, QMessageBox
from processing.core.Processing import Processing
from processing.core.outputs import (
@ -232,6 +232,15 @@ def createTest(text):
if isinstance(out, (OutputNumber, OutputString)):
results[out.name] = str(out)
elif isinstance(out, OutputRaster):
if token is None:
QMessageBox.warning(None,
tr('Error'),
tr('Seems some outputs are temporary '
'files. To create test you need to '
'redirect all algorithm outputs to '
'files'))
return
dataset = gdal.Open(token, GA_ReadOnly)
dataArray = nan_to_num(dataset.ReadAsArray(0))
strhash = hashlib.sha224(dataArray.data).hexdigest()

View File

@ -186,6 +186,7 @@ class GeoDB(object):
passwd=None, service=None, uri=None):
# Regular expression for identifiers without need to quote them
self.re_ident_ok = re.compile(r"^\w+$")
port = str(port)
if uri:
self.uri = uri
@ -199,7 +200,7 @@ class GeoDB(object):
conninfo = self.uri.connectionInfo(False)
err = None
for i in range(4):
expandedConnInfo = uri.connectionInfo(True)
expandedConnInfo = self.uri.connectionInfo(True)
try:
self.con = psycopg2.connect(expandedConnInfo.encode('utf-8'))
if err is not None:

View File

@ -52,17 +52,6 @@ from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecution
from processing.tools import dataobjects, spatialite, postgis
GEOM_TYPE_MAP = {
QgsWkbTypes.NullGeometry: 'none',
QgsWkbTypes.Point: 'Point',
QgsWkbTypes.LineString: 'LineString',
QgsWkbTypes.Polygon: 'Polygon',
QgsWkbTypes.MultiPoint: 'MultiPoint',
QgsWkbTypes.MultiLineString: 'MultiLineString',
QgsWkbTypes.MultiPolygon: 'MultiPolygon',
}
TYPE_MAP = {
str: QVariant.String,
float: QVariant.Double,
@ -561,7 +550,7 @@ class VectorWriter(object):
if self.destination.startswith(self.MEMORY_LAYER_PREFIX):
self.isNotFileBased = True
uri = GEOM_TYPE_MAP[geometryType] + "?uuid=" + str(uuid.uuid4())
uri = QgsWkbTypes.displayString(geometryType) + "?uuid=" + str(uuid.uuid4())
if crs.isValid():
uri += '&crs=' + crs.authid()
fieldsdesc = []
@ -608,7 +597,7 @@ class VectorWriter(object):
if geometryType != QgsWkbTypes.NullGeometry:
_runSQL("SELECT AddGeometryColumn('{schema}', '{table}', 'the_geom', {srid}, '{typmod}', 2)".format(
table=uri.table().lower(), schema=uri.schema(), srid=crs.authid().split(":")[-1],
typmod=GEOM_TYPE_MAP[geometryType].upper()))
typmod=QgsWkbTypes.displayString(geometryType).upper()))
self.layer = QgsVectorLayer(uri.uri(), uri.table(), "postgres")
self.writer = self.layer.dataProvider()
@ -640,7 +629,7 @@ class VectorWriter(object):
if geometryType != QgsWkbTypes.NullGeometry:
_runSQL("SELECT AddGeometryColumn('{table}', 'the_geom', {srid}, '{typmod}', 2)".format(
table=uri.table().lower(), srid=crs.authid().split(":")[-1],
typmod=GEOM_TYPE_MAP[geometryType].upper()))
typmod=QgsWkbTypes.displayString(geometryType).upper()))
self.layer = QgsVectorLayer(uri.uri(), uri.table(), "spatialite")
self.writer = self.layer.dataProvider()

View File

@ -26,7 +26,7 @@ clustering of points.</p>
<h4>Rows and Columns</h4>
<p>Used to change the dimensions of the output raster file. These values are also linked to the <b>Cell size X</b> and <b>Cell size Y</b> values.
Increasing the number of rows or colums will decrease the cell size and increase the file size of the output file. The values in Rows and Columns
Increasing the number of rows or columns will decrease the cell size and increase the file size of the output file. The values in Rows and Columns
are also linked, so doubling the number of rows will automatically double the number of columns and the cell sizes will also be halved. The geographical area of the output raster will remain the same!</p>
<h4>Cell size X and Y</h4>

View File

@ -52,7 +52,7 @@ uncomment code, check syntax, share the code via codepad.org and much more).
<li>Open PyQGIS Cookbook by typing <label>_pyqgis</label>.</li>
<br>
<li>Save and clear the command history accessing from context menu of input pane.
The history will be saved into the file ~/.qgis2/console_history.txt</li>
The history will be saved into the file ~/.qgis3/console_history.txt</li>
<br>
</ul>
</td>

View File

@ -32,7 +32,7 @@ def chunks(l, n):
QCoreApplication.setOrganizationName("QGIS")
QCoreApplication.setOrganizationDomain("qgis.org")
QCoreApplication.setApplicationName("QGIS2")
QCoreApplication.setApplicationName("QGIS3")
s = QSettings()

View File

@ -167,7 +167,7 @@ ELSE(NOT APPLE)
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.qgis2_analysis
MACOSX_FRAMEWORK_IDENTIFIER org.qgis.qgis3_analysis
BUILD_WITH_INSTALL_RPATH TRUE
PUBLIC_HEADER "${QGIS_ANALYSIS_HDRS}"
LINK_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}"

View File

@ -61,7 +61,7 @@ ELSE(NOT APPLE)
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.qgis2_networkanalysis
MACOSX_FRAMEWORK_IDENTIFIER org.qgis.qgis3_networkanalysis
BUILD_WITH_INSTALL_RPATH TRUE
PUBLIC_HEADER "${QGIS_NETWORK_ANALYSIS_HDRS};${QGIS_NETWORK_ANALYSIS_MOC_HDRS}"
LINK_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}"

View File

@ -28,6 +28,7 @@ SET(QGIS_APP_SRCS
qgsdecorationscalebardialog.cpp
qgsdecorationgrid.cpp
qgsdecorationgriddialog.cpp
qgsdiscoverrelationsdlg.cpp
qgsdxfexportdialog.cpp
qgsformannotationdialog.cpp
qgsguivectorlayertools.cpp
@ -207,6 +208,7 @@ SET (QGIS_APP_MOC_HDRS
qgsdecorationgriddialog.h
qgsdelattrdialog.h
qgsdiagramproperties.h
qgsdiscoverrelationsdlg.h
qgsdisplayangle.h
qgsdxfexportdialog.h
qgsfeatureaction.h

View File

@ -67,6 +67,7 @@
#include "qgsvectorlayer.h"
#include "qgscomposerimageexportoptionsdialog.h"
#include "ui_qgssvgexportoptions.h"
#include "qgspanelwidgetstack.h"
#include <QCloseEvent>
#include <QCheckBox>
@ -578,6 +579,8 @@ QgsComposer::QgsComposer( QgisApp *qgis, const QString& title )
mItemDock = new QgsDockWidget( tr( "Item properties" ), this );
mItemDock->setObjectName( "ItemDock" );
mItemDock->setMinimumWidth( minDockWidth );
mItemPropertiesStack = new QgsPanelWidgetStack();
mItemDock->setWidget( mItemPropertiesStack );
mPanelMenu->addAction( mItemDock->toggleViewAction() );
mUndoDock = new QgsDockWidget( tr( "Command history" ), this );
mUndoDock->setObjectName( "CommandDock" );
@ -996,28 +999,27 @@ void QgsComposer::updateStatusAtlasMsg( const QString& message )
void QgsComposer::showItemOptions( QgsComposerItem* item )
{
QWidget* currentWidget = mItemDock->widget();
if ( !item )
{
mItemDock->setWidget( nullptr );
mItemPropertiesStack->takeMainPanel();
return;
}
QMap<QgsComposerItem*, QWidget*>::const_iterator it = mItemWidgetMap.constFind( item );
QMap<QgsComposerItem*, QgsPanelWidget*>::const_iterator it = mItemWidgetMap.constFind( item );
if ( it == mItemWidgetMap.constEnd() )
{
return;
}
QWidget* newWidget = it.value();
if ( !newWidget || newWidget == currentWidget ) //bail out if new widget does not exist or is already there
QgsPanelWidget* newWidget = it.value();
if ( !newWidget || newWidget == mItemPropertiesStack->mainPanel() ) //bail out if new widget does not exist or is already there
{
return;
}
mItemDock->setWidget( newWidget );
( void ) mItemPropertiesStack->takeMainPanel();
newWidget->setDockMode( true );
mItemPropertiesStack->setMainPanel( newWidget );
}
void QgsComposer::on_mActionOptions_triggered()
@ -3774,7 +3776,7 @@ void QgsComposer::addComposerHtmlFrame( QgsComposerHtml* html, QgsComposerFrame*
void QgsComposer::deleteItem( QgsComposerItem* item )
{
QMap<QgsComposerItem*, QWidget*>::const_iterator it = mItemWidgetMap.constFind( item );
QMap<QgsComposerItem*, QgsPanelWidget*>::const_iterator it = mItemWidgetMap.constFind( item );
if ( it == mItemWidgetMap.constEnd() )
{
@ -3800,7 +3802,7 @@ void QgsComposer::setSelectionTool()
bool QgsComposer::containsWmsLayer() const
{
QMap<QgsComposerItem*, QWidget*>::const_iterator item_it = mItemWidgetMap.constBegin();
QMap<QgsComposerItem*, QgsPanelWidget*>::const_iterator item_it = mItemWidgetMap.constBegin();
QgsComposerItem* currentItem = nullptr;
QgsComposerMap* currentMap = nullptr;
@ -3822,7 +3824,7 @@ bool QgsComposer::containsWmsLayer() const
bool QgsComposer::containsAdvancedEffects() const
{
// Check if composer contains any blend modes or flattened layers for transparency
QMap<QgsComposerItem*, QWidget*>::const_iterator item_it = mItemWidgetMap.constBegin();
QMap<QgsComposerItem*, QgsPanelWidget*>::const_iterator item_it = mItemWidgetMap.constBegin();
QgsComposerItem* currentItem = nullptr;
QgsComposerMap* currentMap = nullptr;
@ -3893,7 +3895,7 @@ void QgsComposer::showAdvancedEffectsWarning()
void QgsComposer::cleanupAfterTemplateRead()
{
QMap<QgsComposerItem*, QWidget*>::const_iterator itemIt = mItemWidgetMap.constBegin();
QMap<QgsComposerItem*, QgsPanelWidget*>::const_iterator itemIt = mItemWidgetMap.constBegin();
for ( ; itemIt != mItemWidgetMap.constEnd(); ++itemIt )
{
//update all legends completely

View File

@ -18,6 +18,7 @@
#define QGSCOMPOSER_H
#include "ui_qgscomposerbase.h"
#include "qgspanelwidget.h"
class QgisApp;
class QgsComposerArrow;
class QgsComposerPolygon;
@ -44,6 +45,7 @@ class QgsDockWidget;
class QgsMapLayer;
class QgsFeature;
class QgsVectorLayer;
class QgsPanelWidgetStack;
class QGridLayout;
class QDomNode;
@ -568,7 +570,7 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
QSizeGrip *mSizeGrip;
//! To know which item to show if selection changes
QMap<QgsComposerItem*, QWidget*> mItemWidgetMap;
QMap<QgsComposerItem*, QgsPanelWidget*> mItemWidgetMap;
//! Window menu action to select this window
QAction *mWindowAction;
@ -597,6 +599,7 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
QMap< QgsComposerMap*, int > mMapsToRestore;
QgsDockWidget* mItemDock;
QgsPanelWidgetStack* mItemPropertiesStack;
QgsDockWidget* mUndoDock;
QgsDockWidget* mGeneralDock;
QgsDockWidget* mAtlasDock;

View File

@ -28,6 +28,7 @@
QgsComposerArrowWidget::QgsComposerArrowWidget( QgsComposerArrow* arrow ): QgsComposerItemBaseWidget( nullptr, arrow ), mArrow( arrow )
{
setupUi( this );
setPanelTitle( tr( "Arrow properties" ) );
mRadioButtonGroup = new QButtonGroup( this );
mRadioButtonGroup->addButton( mDefaultMarkerRadioButton );
mRadioButtonGroup->addButton( mNoMarkerRadioButton );
@ -98,7 +99,7 @@ void QgsComposerArrowWidget::on_mArrowHeadFillColorButton_colorChanged( const QC
return;
}
mArrow->beginCommand( tr( "Arrow head fill color" ) );
mArrow->beginCommand( tr( "Arrow head fill color" ), QgsComposerMergeCommand::ArrowHeadFillColor );
mArrow->setArrowHeadFillColor( newColor );
mArrow->update();
mArrow->endCommand();
@ -111,7 +112,7 @@ void QgsComposerArrowWidget::on_mArrowHeadOutlineColorButton_colorChanged( const
return;
}
mArrow->beginCommand( tr( "Arrow head outline color" ) );
mArrow->beginCommand( tr( "Arrow head outline color" ), QgsComposerMergeCommand::ArrowHeadOutlineColor );
mArrow->setArrowHeadOutlineColor( newColor );
mArrow->update();
mArrow->endCommand();

View File

@ -39,6 +39,7 @@ QgsComposerAttributeTableWidget::QgsComposerAttributeTableWidget( QgsComposerAtt
, mFrame( frame )
{
setupUi( this );
setPanelTitle( tr( "Table properties" ) );
blockAllSignals( true );
@ -268,7 +269,7 @@ void QgsComposerAttributeTableWidget::on_mHeaderFontColorButton_colorChanged( co
QgsComposition* composition = mComposerTable->composition();
if ( composition )
{
composition->beginMultiFrameCommand( mComposerTable, tr( "Table header font color" ) );
composition->beginMultiFrameCommand( mComposerTable, tr( "Table header font color" ), QgsComposerMultiFrameMergeCommand::TableHeaderFontColor );
}
mComposerTable->setHeaderFontColor( newColor );
if ( composition )
@ -309,7 +310,7 @@ void QgsComposerAttributeTableWidget::on_mContentFontColorButton_colorChanged( c
QgsComposition* composition = mComposerTable->composition();
if ( composition )
{
composition->beginMultiFrameCommand( mComposerTable, tr( "Table content font color" ) );
composition->beginMultiFrameCommand( mComposerTable, tr( "Table content font color" ), QgsComposerMultiFrameMergeCommand::TableContentFontColor );
}
mComposerTable->setContentFontColor( newColor );
if ( composition )
@ -347,7 +348,7 @@ void QgsComposerAttributeTableWidget::on_mGridColorButton_colorChanged( const QC
QgsComposition* composition = mComposerTable->composition();
if ( composition )
{
composition->beginMultiFrameCommand( mComposerTable, tr( "Table grid color" ) );
composition->beginMultiFrameCommand( mComposerTable, tr( "Table grid color" ), QgsComposerMultiFrameMergeCommand::TableGridColor );
}
mComposerTable->setGridColor( newColor );
if ( composition )
@ -385,7 +386,7 @@ void QgsComposerAttributeTableWidget::on_mBackgroundColorButton_colorChanged( co
QgsComposition* composition = mComposerTable->composition();
if ( composition )
{
composition->beginMultiFrameCommand( mComposerTable, tr( "Table background color" ) );
composition->beginMultiFrameCommand( mComposerTable, tr( "Table background color" ), QgsComposerMultiFrameMergeCommand::TableBackgroundColor );
}
mComposerTable->setBackgroundColor( newColor );
if ( composition )

View File

@ -31,6 +31,7 @@ QgsComposerHtmlWidget::QgsComposerHtmlWidget( QgsComposerHtml* html, QgsComposer
, mFrame( frame )
{
setupUi( this );
setPanelTitle( tr( "HTML properties" ) );
//setup html editor
mHtmlEditor = new QgsCodeEditorHTML( this );

View File

@ -30,18 +30,20 @@
//QgsComposerItemBaseWidget
QgsComposerItemBaseWidget::QgsComposerItemBaseWidget( QWidget* parent, QgsComposerObject *composerObject ): QWidget( parent ), mComposerObject( composerObject )
QgsComposerConfigObject::QgsComposerConfigObject( QWidget* parent, QgsComposerObject *composerObject )
: QObject( parent )
, mComposerObject( composerObject )
{
connect( atlasComposition(), SIGNAL( coverageLayerChanged( QgsVectorLayer* ) ),
this, SLOT( updateDataDefinedButtons() ) );
connect( atlasComposition(), SIGNAL( toggled( bool ) ), this, SLOT( updateDataDefinedButtons() ) );
}
QgsComposerItemBaseWidget::~QgsComposerItemBaseWidget()
QgsComposerConfigObject::~QgsComposerConfigObject()
{
}
void QgsComposerItemBaseWidget::updateDataDefinedProperty()
void QgsComposerConfigObject::updateDataDefinedProperty()
{
//match data defined button to item's data defined property
QgsDataDefinedButton* ddButton = dynamic_cast<QgsDataDefinedButton*>( sender() );
@ -64,7 +66,7 @@ void QgsComposerItemBaseWidget::updateDataDefinedProperty()
mComposerObject->refreshDataDefinedProperty( property );
}
void QgsComposerItemBaseWidget::updateDataDefinedButtons()
void QgsComposerConfigObject::updateDataDefinedButtons()
{
Q_FOREACH ( QgsDataDefinedButton* button, findChildren< QgsDataDefinedButton* >() )
{
@ -72,7 +74,7 @@ void QgsComposerItemBaseWidget::updateDataDefinedButtons()
}
}
void QgsComposerItemBaseWidget::setDataDefinedProperty( const QgsDataDefinedButton *ddBtn, QgsComposerObject::DataDefinedProperty p )
void QgsComposerConfigObject::setDataDefinedProperty( const QgsDataDefinedButton *ddBtn, QgsComposerObject::DataDefinedProperty p )
{
if ( !mComposerObject )
{
@ -83,7 +85,7 @@ void QgsComposerItemBaseWidget::setDataDefinedProperty( const QgsDataDefinedButt
mComposerObject->setDataDefinedProperty( p, map.value( "active" ).toInt(), map.value( "useexpr" ).toInt(), map.value( "expression" ), map.value( "field" ) );
}
void QgsComposerItemBaseWidget::registerDataDefinedButton( QgsDataDefinedButton* button, QgsComposerObject::DataDefinedProperty property,
void QgsComposerConfigObject::registerDataDefinedButton( QgsDataDefinedButton* button, QgsComposerObject::DataDefinedProperty property,
QgsDataDefinedButton::DataType type, const QString& description )
{
button->blockSignals( true );
@ -98,7 +100,7 @@ void QgsComposerItemBaseWidget::registerDataDefinedButton( QgsDataDefinedButton*
button->blockSignals( false );
}
QgsAtlasComposition* QgsComposerItemBaseWidget::atlasComposition() const
QgsAtlasComposition* QgsComposerConfigObject::atlasComposition() const
{
if ( !mComposerObject )
{
@ -115,7 +117,7 @@ QgsAtlasComposition* QgsComposerItemBaseWidget::atlasComposition() const
return &composition->atlasComposition();
}
QgsVectorLayer* QgsComposerItemBaseWidget::atlasCoverageLayer() const
QgsVectorLayer* QgsComposerConfigObject::atlasCoverageLayer() const
{
QgsAtlasComposition* atlasMap = atlasComposition();
@ -140,8 +142,9 @@ void QgsComposerItemWidget::updateVariables()
}
QgsComposerItemWidget::QgsComposerItemWidget( QWidget* parent, QgsComposerItem* item )
: QgsComposerItemBaseWidget( parent, item )
: QWidget( parent )
, mItem( item )
, mConfigObject( new QgsComposerConfigObject( this, item ) )
, mFreezeXPosSpin( false )
, mFreezeYPosSpin( false )
, mFreezeWidthSpin( false )
@ -184,18 +187,6 @@ QgsComposerItemWidget::QgsComposerItemWidget( QWidget* parent, QgsComposerItem*
connect( mItem->composition(), SIGNAL( variablesChanged() ), this, SLOT( updateVariables() ) );
}
QgsComposerItemWidget::QgsComposerItemWidget()
: QgsComposerItemBaseWidget( nullptr, nullptr )
, mItem( nullptr )
, mFreezeXPosSpin( false )
, mFreezeYPosSpin( false )
, mFreezeWidthSpin( false )
, mFreezeHeightSpin( false )
, mFreezePageSpin( false )
{
}
QgsComposerItemWidget::~QgsComposerItemWidget()
{
@ -219,7 +210,7 @@ void QgsComposerItemWidget::on_mFrameColorButton_colorChanged( const QColor& new
{
return;
}
mItem->beginCommand( tr( "Frame color changed" ) );
mItem->beginCommand( tr( "Frame color changed" ), QgsComposerMergeCommand::ItemOutlineColor );
mItem->setFrameOutlineColor( newFrameColor );
mItem->update();
mItem->endCommand();
@ -239,7 +230,7 @@ void QgsComposerItemWidget::on_mBackgroundColorButton_colorChanged( const QColor
{
return;
}
mItem->beginCommand( tr( "Background color changed" ) );
mItem->beginCommand( tr( "Background color changed" ), QgsComposerMergeCommand::ItemBackgroundColor );
mItem->setBackgroundColor( newBackgroundColor );
//if the item is a composer map, we need to regenerate the map image
@ -552,22 +543,22 @@ void QgsComposerItemWidget::setValuesForGuiNonPositionElements()
void QgsComposerItemWidget::populateDataDefinedButtons()
{
registerDataDefinedButton( mXPositionDDBtn, QgsComposerObject::PositionX,
QgsDataDefinedButton::AnyType, QgsDataDefinedButton::doubleDesc() );
registerDataDefinedButton( mYPositionDDBtn, QgsComposerObject::PositionY,
QgsDataDefinedButton::AnyType, QgsDataDefinedButton::doubleDesc() );
registerDataDefinedButton( mWidthDDBtn, QgsComposerObject::ItemWidth,
QgsDataDefinedButton::AnyType, QgsDataDefinedButton::doubleDesc() );
registerDataDefinedButton( mHeightDDBtn, QgsComposerObject::ItemHeight,
QgsDataDefinedButton::AnyType, QgsDataDefinedButton::doubleDesc() );
registerDataDefinedButton( mItemRotationDDBtn, QgsComposerObject::ItemRotation,
QgsDataDefinedButton::AnyType, QgsDataDefinedButton::double180RotDesc() );
registerDataDefinedButton( mTransparencyDDBtn, QgsComposerObject::Transparency,
QgsDataDefinedButton::AnyType, QgsDataDefinedButton::intTranspDesc() );
registerDataDefinedButton( mBlendModeDDBtn, QgsComposerObject::BlendMode,
QgsDataDefinedButton::String, QgsDataDefinedButton::blendModesDesc() );
registerDataDefinedButton( mExcludePrintsDDBtn, QgsComposerObject::ExcludeFromExports,
QgsDataDefinedButton::String, QgsDataDefinedButton::boolDesc() );
mConfigObject->registerDataDefinedButton( mXPositionDDBtn, QgsComposerObject::PositionX,
QgsDataDefinedButton::AnyType, QgsDataDefinedButton::doubleDesc() );
mConfigObject->registerDataDefinedButton( mYPositionDDBtn, QgsComposerObject::PositionY,
QgsDataDefinedButton::AnyType, QgsDataDefinedButton::doubleDesc() );
mConfigObject->registerDataDefinedButton( mWidthDDBtn, QgsComposerObject::ItemWidth,
QgsDataDefinedButton::AnyType, QgsDataDefinedButton::doubleDesc() );
mConfigObject->registerDataDefinedButton( mHeightDDBtn, QgsComposerObject::ItemHeight,
QgsDataDefinedButton::AnyType, QgsDataDefinedButton::doubleDesc() );
mConfigObject->registerDataDefinedButton( mItemRotationDDBtn, QgsComposerObject::ItemRotation,
QgsDataDefinedButton::AnyType, QgsDataDefinedButton::double180RotDesc() );
mConfigObject->registerDataDefinedButton( mTransparencyDDBtn, QgsComposerObject::Transparency,
QgsDataDefinedButton::AnyType, QgsDataDefinedButton::intTranspDesc() );
mConfigObject->registerDataDefinedButton( mBlendModeDDBtn, QgsComposerObject::BlendMode,
QgsDataDefinedButton::String, QgsDataDefinedButton::blendModesDesc() );
mConfigObject->registerDataDefinedButton( mExcludePrintsDDBtn, QgsComposerObject::ExcludeFromExports,
QgsDataDefinedButton::String, QgsDataDefinedButton::boolDesc() );
}
void QgsComposerItemWidget::setValuesForGuiElements()
@ -786,3 +777,25 @@ void QgsComposerItemWidget::on_mExcludeFromPrintsCheckBox_toggled( bool checked
mItem->endCommand();
}
}
QgsComposerItemBaseWidget::QgsComposerItemBaseWidget( QWidget* parent, QgsComposerObject* composerObject )
: QgsPanelWidget( parent )
, mConfigObject( new QgsComposerConfigObject( this, composerObject ) )
{
}
void QgsComposerItemBaseWidget::registerDataDefinedButton( QgsDataDefinedButton* button, QgsComposerObject::DataDefinedProperty property, QgsDataDefinedButton::DataType type, const QString& description )
{
mConfigObject->registerDataDefinedButton( button, property, type, description );
}
QgsVectorLayer* QgsComposerItemBaseWidget::atlasCoverageLayer() const
{
return mConfigObject->atlasCoverageLayer();
}
QgsAtlasComposition* QgsComposerItemBaseWidget::atlasComposition() const
{
return mConfigObject->atlasComposition();
}

View File

@ -20,29 +20,42 @@
#include "ui_qgscomposeritemwidgetbase.h"
#include "qgscomposeritem.h"
#include "qgspanelwidget.h"
class QgsComposerItem;
class QgsAtlasComposition;
class QgsDataDefinedButton;
/** A base class for property widgets for composer items. All composer item widgets should inherit from
* this base class.
// NOTE - the inheritance here is tricky, as we need to avoid the multiple inheritance
// diamond problem and the ideal base object (QgsComposerConfigObject) MUST be a QObject
// because of its slots.
// So here we go:
// QgsComposerItemWidget is just a QWidget which is embedded inside specific item property
// widgets and contains common settings like position and rotation of the items. While the
// actual individual item type widgets MUST be QgsPanelWidgets unfortunately QgsComposerItemWidget
// CANNOT be a QgsPanelWidget and must instead be a generic QWidget (otherwise a QgsPanelWidget
// contains a child QgsPanelWidget, which breaks lots of assumptions made in QgsPanelWidget
// and related classes).
// So QgsComposerItemWidget HAS a QgsComposerConfigObject to handle these common tasks.
// Specific item property widgets (eg QgsComposerMapWidget) should inherit from QgsComposerItemBaseWidget
// (which is a QgsPanelWidget) and also HAS a QgsComposerConfigObject, with protected methods
// which are just proxied through to the QgsComposerConfigObject.
// phew!
// long story short - don't change this without good reason. If you add a new item type, inherit
// from QgsComposerItemWidget and trust that everything else has been done for you.
/** An object for property widgets for composer items. All composer config type widgets should contain
* this object.
*/
class QgsComposerItemBaseWidget: public QWidget
class QgsComposerConfigObject: public QObject
{
Q_OBJECT
public:
QgsComposerItemBaseWidget( QWidget* parent, QgsComposerObject* composerObject );
~QgsComposerItemBaseWidget();
QgsComposerConfigObject( QWidget* parent, QgsComposerObject* composerObject );
~QgsComposerConfigObject();
protected slots:
/** Must be called when a data defined button changes*/
void updateDataDefinedProperty();
//! Updates data defined buttons to reflect current state of atlas (eg coverage layer)
void updateDataDefinedButtons();
protected:
/** Sets a data defined property for the item from its current data defined button settings*/
void setDataDefinedProperty( const QgsDataDefinedButton *ddBtn, QgsComposerObject::DataDefinedProperty p );
@ -61,12 +74,54 @@ class QgsComposerItemBaseWidget: public QWidget
/** Returns the atlas for the composition*/
QgsAtlasComposition *atlasComposition() const;
private slots:
/** Must be called when a data defined button changes*/
void updateDataDefinedProperty();
//! Updates data defined buttons to reflect current state of atlas (eg coverage layer)
void updateDataDefinedButtons();
private:
QgsComposerObject* mComposerObject;
};
/**
* A base class for property widgets for composer items. All composer item widgets should inherit from
* this base class.
*/
class QgsComposerItemBaseWidget: public QgsPanelWidget
{
Q_OBJECT
public:
QgsComposerItemBaseWidget( QWidget* parent, QgsComposerObject* composerObject );
protected:
/** Registers a data defined button, setting up its initial value, connections and description.
* @param button button to register
* @param property correponding data defined property
* @param type valid data types for button
* @param description user visible description for data defined property
*/
void registerDataDefinedButton( QgsDataDefinedButton* button, QgsComposerObject::DataDefinedProperty property,
QgsDataDefinedButton::DataType type, const QString& description );
/** Returns the current atlas coverage layer (if set)*/
QgsVectorLayer* atlasCoverageLayer() const;
/** Returns the atlas for the composition*/
QgsAtlasComposition *atlasComposition() const;
private:
QgsComposerConfigObject* mConfigObject;
};
/** A class to enter generic properties for composer items (e.g. background, outline, frame).
This widget can be embedded into other item widgets*/
class QgsComposerItemWidget: public QgsComposerItemBaseWidget, private Ui::QgsComposerItemWidgetBase
class QgsComposerItemWidget: public QWidget, private Ui::QgsComposerItemWidgetBase
{
Q_OBJECT
public:
@ -132,9 +187,9 @@ class QgsComposerItemWidget: public QgsComposerItemBaseWidget, private Ui::QgsCo
void populateDataDefinedButtons();
private:
QgsComposerItemWidget();
QgsComposerItem* mItem;
QgsComposerConfigObject* mConfigObject;
bool mFreezeXPosSpin;
bool mFreezeYPosSpin;

View File

@ -29,6 +29,7 @@
QgsComposerLabelWidget::QgsComposerLabelWidget( QgsComposerLabel* label ): QgsComposerItemBaseWidget( nullptr, label ), mComposerLabel( label )
{
setupUi( this );
setPanelTitle( tr( "Label properties" ) );
//add widget for general composer item properties
QgsComposerItemWidget* itemPropertiesWidget = new QgsComposerItemWidget( this, label );
@ -124,7 +125,7 @@ void QgsComposerLabelWidget::on_mFontColorButton_colorChanged( const QColor &new
return;
}
mComposerLabel->beginCommand( tr( "Label color changed" ) );
mComposerLabel->beginCommand( tr( "Label color changed" ), QgsComposerMergeCommand::ComposerLabelFontColor );
mComposerLabel->setFontColor( newLabelColor );
mComposerLabel->update();
mComposerLabel->endCommand();

View File

@ -47,6 +47,7 @@ QgsComposerLegendWidget::QgsComposerLegendWidget( QgsComposerLegend* legend )
, mLegend( legend )
{
setupUi( this );
setPanelTitle( tr( "Legend properties" ) );
// setup icons
mAddToolButton->setIcon( QIcon( QgsApplication::iconPath( "symbologyAdd.svg" ) ) );
@ -405,7 +406,7 @@ void QgsComposerLegendWidget::on_mFontColorButton_colorChanged( const QColor& ne
return;
}
mLegend->beginCommand( tr( "Legend font color changed" ) );
mLegend->beginCommand( tr( "Legend font color changed" ), QgsComposerMergeCommand::LegendFontColor );
mLegend->setFontColor( newFontColor );
mLegend->update();
mLegend->endCommand();
@ -623,7 +624,7 @@ void QgsComposerLegendWidget::on_mRasterBorderColorButton_colorChanged( const QC
return;
}
mLegend->beginCommand( tr( "Legend raster border color" ) );
mLegend->beginCommand( tr( "Legend raster border color" ), QgsComposerMergeCommand::LegendRasterBorderColor );
mLegend->setRasterBorderColor( newColor );
mLegend->update();
mLegend->endCommand();

View File

@ -48,6 +48,7 @@ QgsComposerMapWidget::QgsComposerMapWidget( QgsComposerMap* composerMap )
, mComposerMap( composerMap )
{
setupUi( this );
setPanelTitle( tr( "Map properties" ) );
//add widget for general composer item properties
QgsComposerItemWidget* itemPropertiesWidget = new QgsComposerItemWidget( this, composerMap );
@ -291,6 +292,99 @@ void QgsComposerMapWidget::onPresetsChanged()
}
}
void QgsComposerMapWidget::updateGridLineStyleFromWidget()
{
QgsComposerMapGrid* grid = currentGrid();
if ( !grid )
{
return;
}
QgsSymbolSelectorWidget* w = qobject_cast<QgsSymbolSelectorWidget*>( sender() );
grid->setLineSymbol( dynamic_cast< QgsLineSymbol* >( w->symbol()->clone() ) );
mComposerMap->update();
}
void QgsComposerMapWidget::cleanUpGridLineStyleSelector( QgsPanelWidget* container )
{
QgsSymbolSelectorWidget* w = qobject_cast<QgsSymbolSelectorWidget*>( container );
if ( !w )
return;
delete w->symbol();
QgsComposerMapGrid* grid = currentGrid();
if ( !grid )
{
return;
}
updateGridLineSymbolMarker( grid );
mComposerMap->endCommand();
}
void QgsComposerMapWidget::updateGridMarkerStyleFromWidget()
{
QgsComposerMapGrid* grid = currentGrid();
if ( !grid )
{
return;
}
QgsSymbolSelectorWidget* w = qobject_cast<QgsSymbolSelectorWidget*>( sender() );
grid->setMarkerSymbol( dynamic_cast< QgsMarkerSymbol* >( w->symbol()->clone() ) );
mComposerMap->update();
}
void QgsComposerMapWidget::cleanUpGridMarkerStyleSelector( QgsPanelWidget* container )
{
QgsSymbolSelectorWidget* w = qobject_cast<QgsSymbolSelectorWidget*>( container );
if ( !w )
return;
delete w->symbol();
QgsComposerMapGrid* grid = currentGrid();
if ( !grid )
{
return;
}
updateGridMarkerSymbolMarker( grid );
mComposerMap->endCommand();
}
void QgsComposerMapWidget::updateOverviewFrameStyleFromWidget()
{
QgsComposerMapOverview* overview = currentOverview();
if ( !overview )
{
return;
}
QgsSymbolSelectorWidget* w = qobject_cast<QgsSymbolSelectorWidget*>( sender() );
overview->setFrameSymbol( dynamic_cast< QgsFillSymbol* >( w->symbol()->clone() ) );
mComposerMap->update();
}
void QgsComposerMapWidget::cleanUpOverviewFrameStyleSelector( QgsPanelWidget* container )
{
QgsSymbolSelectorWidget* w = qobject_cast<QgsSymbolSelectorWidget*>( container );
if ( !w )
return;
delete w->symbol();
QgsComposerMapOverview* overview = currentOverview();
if ( !overview )
{
return;
}
updateOverviewFrameSymbolMarker( overview );
mComposerMap->endCommand();
}
void QgsComposerMapWidget::on_mAtlasCheckBox_toggled( bool checked )
{
if ( !mComposerMap )
@ -1495,21 +1589,21 @@ void QgsComposerMapWidget::on_mGridLineStyleButton_clicked()
return;
}
QgsLineSymbol* newSymbol = static_cast<QgsLineSymbol*>( grid->lineSymbol()->clone() );
QgsSymbolSelectorDialog d( newSymbol, QgsStyle::defaultStyle(), nullptr, this );
// use the atlas coverage layer, if any
QgsVectorLayer* coverageLayer = atlasCoverageLayer();
if ( d.exec() == QDialog::Accepted )
{
mComposerMap->beginCommand( tr( "Grid line style changed" ) );
grid->setLineSymbol( newSymbol );
updateGridLineSymbolMarker( grid );
mComposerMap->endCommand();
mComposerMap->update();
}
else
{
delete newSymbol;
}
QgsLineSymbol* newSymbol = static_cast<QgsLineSymbol*>( grid->lineSymbol()->clone() );
QgsExpressionContext context = mComposerMap->createExpressionContext();
QgsSymbolSelectorWidget* d = new QgsSymbolSelectorWidget( newSymbol, QgsStyle::defaultStyle(), coverageLayer, nullptr );
QgsSymbolWidgetContext symbolContext;
symbolContext.setExpressionContext( &context );
d->setContext( symbolContext );
connect( d, SIGNAL( widgetChanged() ), this, SLOT( updateGridLineStyleFromWidget() ) );
connect( d, SIGNAL( panelAccepted( QgsPanelWidget* ) ), this, SLOT( cleanUpGridLineStyleSelector( QgsPanelWidget* ) ) );
openPanel( d );
mComposerMap->beginCommand( tr( "Grid line style changed" ) );
}
void QgsComposerMapWidget::on_mGridMarkerStyleButton_clicked()
@ -1520,21 +1614,21 @@ void QgsComposerMapWidget::on_mGridMarkerStyleButton_clicked()
return;
}
QgsMarkerSymbol* newSymbol = static_cast<QgsMarkerSymbol*>( grid->markerSymbol()->clone() );
QgsSymbolSelectorDialog d( newSymbol, QgsStyle::defaultStyle(), nullptr, this );
// use the atlas coverage layer, if any
QgsVectorLayer* coverageLayer = atlasCoverageLayer();
if ( d.exec() == QDialog::Accepted )
{
mComposerMap->beginCommand( tr( "Grid markers style changed" ) );
grid->setMarkerSymbol( newSymbol );
updateGridMarkerSymbolMarker( grid );
mComposerMap->endCommand();
mComposerMap->update();
}
else
{
delete newSymbol;
}
QgsMarkerSymbol* newSymbol = static_cast<QgsMarkerSymbol*>( grid->markerSymbol()->clone() );
QgsExpressionContext context = mComposerMap->createExpressionContext();
QgsSymbolSelectorWidget* d = new QgsSymbolSelectorWidget( newSymbol, QgsStyle::defaultStyle(), coverageLayer, nullptr );
QgsSymbolWidgetContext symbolContext;
symbolContext.setExpressionContext( &context );
d->setContext( symbolContext );
connect( d, SIGNAL( widgetChanged() ), this, SLOT( updateGridMarkerStyleFromWidget() ) );
connect( d, SIGNAL( panelAccepted( QgsPanelWidget* ) ), this, SLOT( cleanUpGridMarkerStyleSelector( QgsPanelWidget* ) ) );
openPanel( d );
mComposerMap->beginCommand( tr( "Grid markers style changed" ) );
}
void QgsComposerMapWidget::on_mIntervalXSpinBox_editingFinished()
@ -1729,7 +1823,7 @@ void QgsComposerMapWidget::on_mGridFramePenColorButton_colorChanged( const QColo
return;
}
mComposerMap->beginCommand( tr( "Grid frame color changed" ) );
mComposerMap->beginCommand( tr( "Grid frame color changed" ), QgsComposerMergeCommand::ComposerMapGridFramePenColor );
grid->setFramePenColor( newColor );
mComposerMap->update();
mComposerMap->endCommand();
@ -1743,7 +1837,7 @@ void QgsComposerMapWidget::on_mGridFrameFill1ColorButton_colorChanged( const QCo
return;
}
mComposerMap->beginCommand( tr( "Grid frame first fill color changed" ) );
mComposerMap->beginCommand( tr( "Grid frame first fill color changed" ), QgsComposerMergeCommand::ComposerMapGridFrameFill1Color );
grid->setFrameFillColor1( newColor );
mComposerMap->update();
mComposerMap->endCommand();
@ -1757,7 +1851,7 @@ void QgsComposerMapWidget::on_mGridFrameFill2ColorButton_colorChanged( const QCo
return;
}
mComposerMap->beginCommand( tr( "Grid frame second fill color changed" ) );
mComposerMap->beginCommand( tr( "Grid frame second fill color changed" ), QgsComposerMergeCommand::ComposerMapGridFrameFill2Color );
grid->setFrameFillColor2( newColor );
mComposerMap->update();
mComposerMap->endCommand();
@ -2076,7 +2170,7 @@ void QgsComposerMapWidget::on_mAnnotationFontColorButton_colorChanged( const QCo
return;
}
mComposerMap->beginCommand( tr( "Annotation color changed" ) );
mComposerMap->beginCommand( tr( "Annotation color changed" ), QgsComposerMergeCommand::ComposerMapGridAnnotationFontColor );
grid->setAnnotationFontColor( color );
mComposerMap->update();
mComposerMap->endCommand();
@ -2462,21 +2556,21 @@ void QgsComposerMapWidget::on_mOverviewFrameStyleButton_clicked()
return;
}
QgsFillSymbol* newSymbol = static_cast<QgsFillSymbol*>( overview->frameSymbol()->clone() );
QgsSymbolSelectorDialog d( newSymbol, QgsStyle::defaultStyle(), nullptr, this );
// use the atlas coverage layer, if any
QgsVectorLayer* coverageLayer = atlasCoverageLayer();
if ( d.exec() == QDialog::Accepted )
{
mComposerMap->beginCommand( tr( "Overview frame style changed" ) );
overview->setFrameSymbol( newSymbol );
updateOverviewFrameSymbolMarker( overview );
mComposerMap->endCommand();
mComposerMap->update();
}
else
{
delete newSymbol;
}
QgsFillSymbol* newSymbol = static_cast<QgsFillSymbol*>( overview->frameSymbol()->clone() );
QgsExpressionContext context = mComposerMap->createExpressionContext();
QgsSymbolSelectorWidget* d = new QgsSymbolSelectorWidget( newSymbol, QgsStyle::defaultStyle(), coverageLayer, nullptr );
QgsSymbolWidgetContext symbolContext;
symbolContext.setExpressionContext( &context );
d->setContext( symbolContext );
connect( d, SIGNAL( widgetChanged() ), this, SLOT( updateOverviewFrameStyleFromWidget() ) );
connect( d, SIGNAL( panelAccepted( QgsPanelWidget* ) ), this, SLOT( cleanUpOverviewFrameStyleSelector( QgsPanelWidget* ) ) );
openPanel( d );
mComposerMap->beginCommand( tr( "Overview frame style changed" ) );
}
void QgsComposerMapWidget::on_mOverviewBlendModeComboBox_currentIndexChanged( int index )

View File

@ -174,6 +174,13 @@ class QgsComposerMapWidget: public QgsComposerItemBaseWidget, private Ui::QgsCom
void onPresetsChanged();
void updateGridLineStyleFromWidget();
void cleanUpGridLineStyleSelector( QgsPanelWidget* container );
void updateGridMarkerStyleFromWidget();
void cleanUpGridMarkerStyleSelector( QgsPanelWidget* container );
void updateOverviewFrameStyleFromWidget();
void cleanUpOverviewFrameStyleSelector( QgsPanelWidget* container );
private:
QgsComposerMap* mComposerMap;

View File

@ -36,6 +36,7 @@
QgsComposerPictureWidget::QgsComposerPictureWidget( QgsComposerPicture* picture ): QgsComposerItemBaseWidget( nullptr, picture ), mPicture( picture ), mPreviewsLoaded( false )
{
setupUi( this );
setPanelTitle( tr( "Picture properties" ) );
mFillColorButton->setAllowAlpha( true );
mFillColorButton->setColorDialogTitle( tr( "Select fill color" ) );
@ -632,7 +633,7 @@ void QgsComposerPictureWidget::loadPicturePreviews( bool collapsed )
void QgsComposerPictureWidget::on_mFillColorButton_colorChanged( const QColor& color )
{
mPicture->beginCommand( tr( "Picture fill color changed" ) );
mPicture->beginCommand( tr( "Picture fill color changed" ), QgsComposerMergeCommand::ComposerPictureFillColor );
mPicture->setSvgFillColor( color );
mPicture->endCommand();
mPicture->update();
@ -640,7 +641,7 @@ void QgsComposerPictureWidget::on_mFillColorButton_colorChanged( const QColor& c
void QgsComposerPictureWidget::on_mOutlineColorButton_colorChanged( const QColor& color )
{
mPicture->beginCommand( tr( "Picture border color changed" ) );
mPicture->beginCommand( tr( "Picture border color changed" ), QgsComposerMergeCommand::ComposerPictureOutlineColor );
mPicture->setSvgBorderColor( color );
mPicture->endCommand();
mPicture->update();

View File

@ -26,6 +26,7 @@ QgsComposerPolygonWidget::QgsComposerPolygonWidget( QgsComposerPolygon* composer
, mComposerPolygon( composerPolygon )
{
setupUi( this );
setPanelTitle( tr( "Polygon properties" ) );
//add widget for general composer item properties
QgsComposerItemWidget* itemPropertiesWidget = new QgsComposerItemWidget( this, composerPolygon );

View File

@ -26,6 +26,7 @@ QgsComposerPolylineWidget::QgsComposerPolylineWidget( QgsComposerPolyline* compo
, mComposerPolyline( composerPolyline )
{
setupUi( this );
setPanelTitle( tr( "Polyline properties" ) );
//add widget for general composer item properties
QgsComposerItemWidget* itemPropertiesWidget = new QgsComposerItemWidget( this, composerPolyline );

View File

@ -27,6 +27,8 @@
QgsComposerScaleBarWidget::QgsComposerScaleBarWidget( QgsComposerScaleBar* scaleBar ): QgsComposerItemBaseWidget( nullptr, scaleBar ), mComposerScaleBar( scaleBar )
{
setupUi( this );
setPanelTitle( tr( "Scalebar properties" ) );
connectUpdateSignal();
//add widget for general composer item properties
@ -261,7 +263,7 @@ void QgsComposerScaleBarWidget::on_mFontColorButton_colorChanged( const QColor&
return;
}
mComposerScaleBar->beginCommand( tr( "Scalebar font color changed" ) );
mComposerScaleBar->beginCommand( tr( "Scalebar font color changed" ), QgsComposerMergeCommand::ScaleBarFontColor );
disconnectUpdateSignal();
mComposerScaleBar->setFontColor( newColor );
mComposerScaleBar->update();
@ -276,7 +278,7 @@ void QgsComposerScaleBarWidget::on_mFillColorButton_colorChanged( const QColor&
return;
}
mComposerScaleBar->beginCommand( tr( "Scalebar color changed" ) );
mComposerScaleBar->beginCommand( tr( "Scalebar color changed" ), QgsComposerMergeCommand::ScaleBarFillColor );
disconnectUpdateSignal();
QBrush newBrush = mComposerScaleBar->brush();
newBrush.setColor( newColor );
@ -293,7 +295,7 @@ void QgsComposerScaleBarWidget::on_mFillColor2Button_colorChanged( const QColor
return;
}
mComposerScaleBar->beginCommand( tr( "Scalebar secondary color changed" ) );
mComposerScaleBar->beginCommand( tr( "Scalebar secondary color changed" ), QgsComposerMergeCommand::ScaleBarFill2Color );
disconnectUpdateSignal();
QBrush newBrush = mComposerScaleBar->brush2();
newBrush.setColor( newColor );
@ -310,7 +312,7 @@ void QgsComposerScaleBarWidget::on_mStrokeColorButton_colorChanged( const QColor
return;
}
mComposerScaleBar->beginCommand( tr( "Scalebar line color changed" ) );
mComposerScaleBar->beginCommand( tr( "Scalebar line color changed" ), QgsComposerMergeCommand::ScaleBarStrokeColor );
disconnectUpdateSignal();
QPen newPen = mComposerScaleBar->pen();
newPen.setColor( newColor );

View File

@ -27,11 +27,12 @@
QgsComposerShapeWidget::QgsComposerShapeWidget( QgsComposerShape* composerShape ): QgsComposerItemBaseWidget( nullptr, composerShape ), mComposerShape( composerShape )
{
setupUi( this );
setPanelTitle( tr( "Shape properties" ) );
//add widget for general composer item properties
QgsComposerItemWidget* itemPropertiesWidget = new QgsComposerItemWidget( this, composerShape );
//shapes don't use background or frame, since the symbol style is set through a QgsSymbolSelectorDialog
//shapes don't use background or frame, since the symbol style is set through a QgsSymbolSelectorWidget
itemPropertiesWidget->showBackgroundGroup( false );
itemPropertiesWidget->showFrameGroup( false );
@ -109,19 +110,16 @@ void QgsComposerShapeWidget::on_mShapeStyleButton_clicked()
QgsFillSymbol* newSymbol = mComposerShape->shapeStyleSymbol()->clone();
QgsExpressionContext context = mComposerShape->createExpressionContext();
QgsSymbolSelectorDialog d( newSymbol, QgsStyle::defaultStyle(), coverageLayer, this );
QgsSymbolSelectorWidget* d = new QgsSymbolSelectorWidget( newSymbol, QgsStyle::defaultStyle(), coverageLayer, nullptr );
QgsSymbolWidgetContext symbolContext;
symbolContext.setExpressionContext( &context );
d.setContext( symbolContext );
d->setContext( symbolContext );
if ( d.exec() == QDialog::Accepted )
{
mComposerShape->beginCommand( tr( "Shape style changed" ) );
mComposerShape->setShapeStyleSymbol( newSymbol );
updateShapeStyle();
mComposerShape->endCommand();
}
delete newSymbol;
connect( d, SIGNAL( widgetChanged() ), this, SLOT( updateSymbolFromWidget() ) );
connect( d, SIGNAL( panelAccepted( QgsPanelWidget* ) ), this, SLOT( cleanUpSymbolSelector( QgsPanelWidget* ) ) );
openPanel( d );
mComposerShape->beginCommand( tr( "Shape style changed" ) );
}
void QgsComposerShapeWidget::updateShapeStyle()
@ -182,5 +180,22 @@ void QgsComposerShapeWidget::toggleRadiusSpin( const QString& shapeText )
}
}
void QgsComposerShapeWidget::updateSymbolFromWidget()
{
QgsSymbolSelectorWidget* w = qobject_cast<QgsSymbolSelectorWidget*>( sender() );
mComposerShape->setShapeStyleSymbol( dynamic_cast< QgsFillSymbol* >( w->symbol() ) );
}
void QgsComposerShapeWidget::cleanUpSymbolSelector( QgsPanelWidget* container )
{
QgsSymbolSelectorWidget* w = qobject_cast<QgsSymbolSelectorWidget*>( container );
if ( !w )
return;
delete w->symbol();
updateShapeStyle();
mComposerShape->endCommand();
}

View File

@ -49,6 +49,8 @@ class QgsComposerShapeWidget: public QgsComposerItemBaseWidget, private Ui::QgsC
/** Enables or disables the rounded radius spin box based on shape type*/
void toggleRadiusSpin( const QString& shapeText );
void updateSymbolFromWidget();
void cleanUpSymbolSelector( QgsPanelWidget* container );
};
#endif // QGSCOMPOSERSHAPEWIDGET_H

View File

@ -186,7 +186,7 @@ const QwtTextLabel *QwtPolarPlot::titleLabel() const
\param legend Legend
\param pos The legend's position. For top/left position the number
of colums will be limited to 1, otherwise it will be set to
of columns will be limited to 1, otherwise it will be set to
unlimited.
\param ratio Ratio between legend and the bounding rect

View File

@ -167,7 +167,7 @@ const QwtTextLabel *QwtPolarPlot::titleLabel() const
\param legend Legend
\param pos The legend's position. For top/left position the number
of colums will be limited to 1, otherwise it will be set to
of columns will be limited to 1, otherwise it will be set to
unlimited.
\param ratio Ratio between legend and the bounding rect

View File

@ -171,7 +171,7 @@ const QwtTextLabel *QwtPolarPlot::titleLabel() const
\param legend Legend
\param pos The legend's position. For top/left position the number
of colums will be limited to 1, otherwise it will be set to
of columns will be limited to 1, otherwise it will be set to
unlimited.
\param ratio Ratio between legend and the bounding rect

View File

@ -7505,7 +7505,7 @@ QgsVectorLayer *QgisApp::pasteToNewMemoryVector()
if ( !feature.hasGeometry() )
continue;
QgsWkbTypes::Type type = QgsWkbTypes::flatType( feature.geometry().wkbType() );
QgsWkbTypes::Type type = feature.geometry().wkbType();
if ( type == QgsWkbTypes::Unknown || type == QgsWkbTypes::NoGeometry )
continue;
@ -7535,7 +7535,7 @@ QgsVectorLayer *QgisApp::pasteToNewMemoryVector()
QgsWkbTypes::Type wkbType = !typeCounts.isEmpty() ? typeCounts.keys().value( 0 ) : QgsWkbTypes::NoGeometry;
QString typeName = wkbType != QgsWkbTypes::NoGeometry ? QString( QgsWkbTypes::displayString( wkbType ) ).remove( "WKB" ) : "none";
QString typeName = wkbType != QgsWkbTypes::NoGeometry ? QgsWkbTypes::displayString( wkbType ) : "none";
if ( features.isEmpty() )
{
@ -7590,7 +7590,7 @@ QgsVectorLayer *QgisApp::pasteToNewMemoryVector()
if ( !feature.hasGeometry() )
continue;
QgsWkbTypes::Type type = QgsWkbTypes::flatType( feature.geometry().wkbType() );
QgsWkbTypes::Type type = feature.geometry().wkbType();
if ( type == QgsWkbTypes::Unknown || type == QgsWkbTypes::NoGeometry )
continue;

View File

@ -0,0 +1,61 @@
/***************************************************************************
qgsdiscoverrelationsdlg.cpp
---------------------
begin : September 2016
copyright : (C) 2016 by Patrick Valsecchi
email : patrick dot valsecchi at camptocamp 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 "qgsdiscoverrelationsdlg.h"
#include "qgsvectorlayer.h"
#include "qgsrelationmanager.h"
#include <QPushButton>
QgsDiscoverRelationsDlg::QgsDiscoverRelationsDlg( const QList<QgsRelation>& existingRelations, const QList<QgsVectorLayer*>& layers, QWidget *parent )
: QDialog( parent )
, mLayers( layers )
{
setupUi( this );
mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( false );
connect( mRelationsTable->selectionModel(), &QItemSelectionModel::selectionChanged, this, &QgsDiscoverRelationsDlg::onSelectionChanged );
mFoundRelations = QgsRelationManager::discoverRelations( existingRelations, layers );
Q_FOREACH ( const QgsRelation& relation, mFoundRelations ) addRelation( relation );
mRelationsTable->resizeColumnsToContents();
}
void QgsDiscoverRelationsDlg::addRelation( const QgsRelation &rel )
{
const int row = mRelationsTable->rowCount();
mRelationsTable->insertRow( row );
mRelationsTable->setItem( row, 0, new QTableWidgetItem( rel.name() ) );
mRelationsTable->setItem( row, 1, new QTableWidgetItem( rel.referencingLayer()->name() ) );
mRelationsTable->setItem( row, 2, new QTableWidgetItem( rel.fieldPairs().at( 0 ).referencingField() ) );
mRelationsTable->setItem( row, 3, new QTableWidgetItem( rel.referencedLayer()->name() ) );
mRelationsTable->setItem( row, 4, new QTableWidgetItem( rel.fieldPairs().at( 0 ).referencedField() ) );
}
QList<QgsRelation> QgsDiscoverRelationsDlg::relations() const
{
QList<QgsRelation> result;
Q_FOREACH ( const QModelIndex& row, mRelationsTable->selectionModel()->selectedRows() )
{
result.append( mFoundRelations.at( row.row() ) );
}
return result;
}
void QgsDiscoverRelationsDlg::onSelectionChanged()
{
mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( mRelationsTable->selectionModel()->hasSelection() );
}

View File

@ -0,0 +1,53 @@
/***************************************************************************
qgsdiscoverrelationsdlg.h
---------------------
begin : September 2016
copyright : (C) 2016 by Patrick Valsecchi
email : patrick dot valsecchi at camptocamp 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 QGSDISCOVERRELATIONSDLG_H
#define QGSDISCOVERRELATIONSDLG_H
#include <QDialog>
#include "ui_qgsdiscoverrelationsdlgbase.h"
#include "qgsrelation.h"
class QgsRelationManager;
class QgsVectorLayer;
/**
* Shows the list of relations discovered from the providers.
*
* The user can select some of them to add them to his project.
*/
class APP_EXPORT QgsDiscoverRelationsDlg : public QDialog, private Ui::QgsDiscoverRelationsDlgBase
{
Q_OBJECT
public:
explicit QgsDiscoverRelationsDlg( const QList<QgsRelation>& existingRelations, const QList<QgsVectorLayer*>& layers, QWidget *parent = nullptr );
/**
* Get the selected relations.
*/
QList<QgsRelation> relations() const;
private slots:
void onSelectionChanged();
private:
QList<QgsVectorLayer*> mLayers;
QList<QgsRelation> mFoundRelations;
void addRelation( const QgsRelation &rel );
};
#endif // QGSDISCOVERRELATIONSDLG_H

View File

@ -226,7 +226,7 @@ void QgsLayerStylingWidget::apply()
QString undoName = "Style Change";
QWidget* current = mWidgetStack->mainWidget();
QWidget* current = mWidgetStack->mainPanel();
bool styleWasChanged = false;
if ( QgsLabelingWidget* widget = qobject_cast<QgsLabelingWidget*>( current ) )
@ -268,8 +268,7 @@ void QgsLayerStylingWidget::apply()
{
emit styleChanged( mCurrentLayer );
QgsProject::instance()->setDirty( true );
mMapCanvas->clearCache();
mMapCanvas->refresh();
mCurrentLayer->triggerRepaint();
}
connect( mCurrentLayer, SIGNAL( styleChanged() ), this, SLOT( updateCurrentWidgetLayer() ) );
}
@ -307,7 +306,7 @@ void QgsLayerStylingWidget::updateCurrentWidgetLayer()
mStackedWidget->setCurrentIndex( mLayerPage );
QgsPanelWidget* current = mWidgetStack->takeMainWidget();
QgsPanelWidget* current = mWidgetStack->takeMainPanel();
if ( current )
{
if ( QgsLabelingWidget* widget = qobject_cast<QgsLabelingWidget*>( current ) )
@ -334,15 +333,14 @@ void QgsLayerStylingWidget::updateCurrentWidgetLayer()
if ( panel )
{
connect( panel, SIGNAL( widgetChanged( QgsPanelWidget* ) ), this, SLOT( autoApply() ) );
panel->setDockMode( true );
mWidgetStack->addMainPanel( panel );
mWidgetStack->setMainPanel( panel );
}
}
// The last widget is always the undo stack.
if ( row == mOptionsListWidget->count() - 1 )
{
mWidgetStack->addMainPanel( mUndoWidget );
mWidgetStack->setMainPanel( mUndoWidget );
}
else if ( mCurrentLayer->type() == QgsMapLayer::VectorLayer )
{
@ -359,7 +357,7 @@ void QgsLayerStylingWidget::updateCurrentWidgetLayer()
QgsPanelWidgetWrapper* wrapper = new QgsPanelWidgetWrapper( styleWidget, mStackedWidget );
wrapper->setDockMode( true );
connect( styleWidget, SIGNAL( showPanel( QgsPanelWidget* ) ), wrapper, SLOT( openPanel( QgsPanelWidget* ) ) );
mWidgetStack->addMainPanel( wrapper );
mWidgetStack->setMainPanel( wrapper );
break;
}
case 1: // Labels
@ -371,7 +369,7 @@ void QgsLayerStylingWidget::updateCurrentWidgetLayer()
connect( mLabelingWidget, SIGNAL( widgetChanged() ), this, SLOT( autoApply() ) );
}
mLabelingWidget->setLayer( vlayer );
mWidgetStack->addMainPanel( mLabelingWidget );
mWidgetStack->setMainPanel( mLabelingWidget );
break;
}
default:
@ -388,14 +386,14 @@ void QgsLayerStylingWidget::updateCurrentWidgetLayer()
mRasterStyleWidget = new QgsRendererRasterPropertiesWidget( rlayer, mMapCanvas, mWidgetStack );
mRasterStyleWidget->setDockMode( true );
connect( mRasterStyleWidget, SIGNAL( widgetChanged() ), this, SLOT( autoApply() ) );
mWidgetStack->addMainPanel( mRasterStyleWidget );
mWidgetStack->setMainPanel( mRasterStyleWidget );
break;
case 1: // Transparency
{
QgsRasterTransparencyWidget* transwidget = new QgsRasterTransparencyWidget( rlayer, mMapCanvas, mWidgetStack );
transwidget->setDockMode( true );
connect( transwidget, SIGNAL( widgetChanged() ), this, SLOT( autoApply() ) );
mWidgetStack->addMainPanel( transwidget );
mWidgetStack->setMainPanel( transwidget );
break;
}
case 2: // Histogram
@ -417,7 +415,7 @@ void QgsLayerStylingWidget::updateCurrentWidgetLayer()
widget->setRendererWidget( name, mRasterStyleWidget->currentRenderWidget() );
widget->setDockMode( true );
mWidgetStack->addMainPanel( widget );
mWidgetStack->setMainPanel( widget );
}
break;
}

View File

@ -13,6 +13,7 @@
* *
***************************************************************************/
#include "qgsdiscoverrelationsdlg.h"
#include "qgsrelationadddlg.h"
#include "qgsrelationmanagerdialog.h"
#include "qgsrelationmanager.h"
@ -46,6 +47,7 @@ void QgsRelationManagerDialog::setLayers( const QList< QgsVectorLayer* >& layers
void QgsRelationManagerDialog::addRelation( const QgsRelation &rel )
{
mRelationsTable->setSortingEnabled( false );
int row = mRelationsTable->rowCount();
mRelationsTable->insertRow( row );
@ -54,7 +56,6 @@ void QgsRelationManagerDialog::addRelation( const QgsRelation &rel )
item->setData( Qt::UserRole, QVariant::fromValue<QgsRelation>( rel ) );
mRelationsTable->setItem( row, 0, item );
item = new QTableWidgetItem( rel.referencingLayer()->name() );
item->setFlags( Qt::ItemIsEditable );
mRelationsTable->setItem( row, 1, item );
@ -74,6 +75,7 @@ void QgsRelationManagerDialog::addRelation( const QgsRelation &rel )
item = new QTableWidgetItem( rel.id() );
item->setFlags( Qt::ItemIsEditable );
mRelationsTable->setItem( row, 5, item );
mRelationsTable->setSortingEnabled( true );
}
void QgsRelationManagerDialog::on_mBtnAddRelation_clicked()
@ -118,6 +120,18 @@ void QgsRelationManagerDialog::on_mBtnAddRelation_clicked()
}
}
void QgsRelationManagerDialog::on_mBtnDiscoverRelations_clicked()
{
QgsDiscoverRelationsDlg discoverDlg( relations(), mLayers, this );
if ( discoverDlg.exec() )
{
Q_FOREACH ( const QgsRelation& relation, discoverDlg.relations() )
{
addRelation( relation );
}
}
}
void QgsRelationManagerDialog::on_mBtnRemoveRelation_clicked()
{
if ( mRelationsTable->currentIndex().isValid() )

View File

@ -39,6 +39,7 @@ class APP_EXPORT QgsRelationManagerDialog : public QWidget, private Ui::QgsRelat
public slots:
void on_mBtnAddRelation_clicked();
void on_mBtnDiscoverRelations_clicked();
void on_mBtnRemoveRelation_clicked();
private:

View File

@ -51,7 +51,7 @@ int main( int argc, char ** argv )
// Set up the QSettings environment must be done after qapp is created
QCoreApplication::setOrganizationName( "QGIS" );
QCoreApplication::setOrganizationDomain( "qgis.org" );
QCoreApplication::setApplicationName( "QGIS2" );
QCoreApplication::setApplicationName( "QGIS3" );
#ifdef Q_OS_MACX
// If the GDAL plugins are bundled with the application and GDAL_DRIVER_PATH

View File

@ -917,7 +917,7 @@ ELSE(NOT APPLE)
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.qgis2_core
MACOSX_FRAMEWORK_IDENTIFIER org.qgis.qgis3_core
BUILD_WITH_INSTALL_RPATH TRUE
PUBLIC_HEADER "${QGIS_CORE_HDRS};${QGIS_CORE_MOC_HDRS}"
LINK_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}"

View File

@ -90,7 +90,7 @@ class CORE_EXPORT QgsAuthManager : public QObject
/** Standard message for when QCA's qca-ossl plugin is missing and system is disabled */
const QString disabledMessage() const;
/** The standard authentication database file in ~/.qgis2/ or defined location
/** The standard authentication database file in ~/.qgis3/ or defined location
* @see QgsApplication::qgisAuthDbFilePath
*/
const QString authenticationDbPath() const { return mAuthDbPath; }

View File

@ -87,9 +87,14 @@ class CORE_EXPORT QgsComposerMergeCommand: public QgsComposerItemCommand
//composer label
ComposerLabelSetText,
ComposerLabelSetId,
ComposerLabelFontColor,
//composer map
ComposerMapRotation,
ComposerMapAnnotationDistance,
ComposerMapGridFramePenColor,
ComposerMapGridFrameFill1Color,
ComposerMapGridFrameFill2Color,
ComposerMapGridAnnotationFontColor,
//composer legend
ComposerLegendText,
LegendColumnCount,
@ -107,8 +112,12 @@ class CORE_EXPORT QgsComposerMergeCommand: public QgsComposerItemCommand
LegendBoxSpace,
LegendColumnSpace,
LegendRasterBorderWidth,
LegendFontColor,
LegendRasterBorderColor,
//composer picture
ComposerPictureRotation,
ComposerPictureFillColor,
ComposerPictureOutlineColor,
// composer scalebar
ScaleBarLineWidth,
ScaleBarHeight,
@ -119,6 +128,10 @@ class CORE_EXPORT QgsComposerMergeCommand: public QgsComposerItemCommand
ScaleBarMapUnitsSegment,
ScaleBarLabelBarSize,
ScaleBarBoxContentSpace,
ScaleBarFontColor,
ScaleBarFillColor,
ScaleBarFill2Color,
ScaleBarStrokeColor,
// composer table
TableMaximumFeatures,
TableMargin,
@ -128,9 +141,13 @@ class CORE_EXPORT QgsComposerMergeCommand: public QgsComposerItemCommand
ShapeOutlineWidth,
//composer arrow
ArrowOutlineWidth,
ArrowHeadFillColor,
ArrowHeadOutlineColor,
ArrowHeadWidth,
//item
ItemOutlineWidth,
ItemOutlineColor,
ItemBackgroundColor,
ItemMove,
ItemRotation,
ItemTransparency,

View File

@ -78,7 +78,11 @@ class CORE_EXPORT QgsComposerMultiFrameMergeCommand: public QgsComposerMultiFram
TableMaximumFeatures,
TableMargin,
TableGridStrokeWidth,
TableCellStyle
TableCellStyle,
TableHeaderFontColor,
TableContentFontColor,
TableGridColor,
TableBackgroundColor,
};
QgsComposerMultiFrameMergeCommand( Context c, QgsComposerMultiFrame* multiFrame, const QString& text );

View File

@ -965,12 +965,11 @@ void QgsDxfExport::writeEntities()
}
renderer->startRender( ctx, vl->fields() );
QStringList attributes = renderer->usedAttributes();
QSet<QString> attributes = renderer->usedAttributes();
if ( vl->fields().exists( layerIt->second ) )
{
QString layerAttr = vl->fields().at( layerIt->second ).name();
if ( !attributes.contains( layerAttr ) )
attributes << layerAttr;
attributes << layerAttr;
}
const QgsAbstractVectorLayerLabeling *labeling = vl->labeling();
@ -1106,7 +1105,7 @@ void QgsDxfExport::writeEntitiesSymbolLevels( QgsVectorLayer* layer )
{
req.setFlags( QgsFeatureRequest::NoGeometry );
}
req.setSubsetOfAttributes( QStringList( renderer->usedAttributes() ), layer->fields() );
req.setSubsetOfAttributes( renderer->usedAttributes(), layer->fields() );
req.setFilterRect( mMapSettings.mapToLayerCoordinates( layer, mExtent ) );
QgsFeatureIterator fit = layer->getFeatures( req );

View File

@ -71,9 +71,9 @@ QVariant QgsAggregateCalculator::calculate( QgsAggregateCalculator::Aggregate ag
}
}
QStringList lst;
QSet<QString> lst;
if ( expression.isNull() )
lst.append( fieldOrExpression );
lst.insert( fieldOrExpression );
else
lst = expression->referencedColumns();

View File

@ -83,7 +83,7 @@ QString QgsApplication::sPlatformName = "desktop";
const char* QgsApplication::QGIS_ORGANIZATION_NAME = "QGIS";
const char* QgsApplication::QGIS_ORGANIZATION_DOMAIN = "qgis.org";
const char* QgsApplication::QGIS_APPLICATION_NAME = "QGIS2";
const char* QgsApplication::QGIS_APPLICATION_NAME = "QGIS3";
/*!
\class QgsApplication
@ -116,10 +116,7 @@ void QgsApplication::init( QString customConfigPath )
}
else
{
// TODO Switch to this for release.
//customConfigPath = QString( "%1/.qgis%2/" ).arg( QDir::homePath() ).arg( Qgis::QGIS_VERSION_INT / 10000 );
// Use qgis-dev for dev versions of QGIS to avoid mixing 2 and 3 API plugins.
customConfigPath = QString( "%1/.qgis%2/" ).arg( QDir::homePath() ).arg( "-dev" );
customConfigPath = QString( "%1/.qgis3/" ).arg( QDir::homePath() );
}
}

View File

@ -87,7 +87,7 @@ class CORE_EXPORT QgsApplication : public QApplication
static void setUITheme( const QString &themeName );
/**
* @brief All themes found in ~/.qgis2/themes folder.
* @brief All themes found in ~/.qgis3/themes folder.
* The path is to the root folder for the theme
* @note Valid theme folders must contain a style.qss file.
* @return A hash of theme name and theme path. Valid theme folders contain style.qss

View File

@ -187,7 +187,7 @@ QgsExpression *QgsDataDefined::expression()
return d->expression;
}
QStringList QgsDataDefined::referencedColumns( const QgsExpressionContext& context )
QSet<QString> QgsDataDefined::referencedColumns( const QgsExpressionContext& context )
{
if ( !d->exprRefColumns.isEmpty() )
{

View File

@ -154,7 +154,7 @@ class CORE_EXPORT QgsDataDefined
* @param context expression context, used for preparing the expression if required
* @note added in QGIS 2.12
*/
QStringList referencedColumns( const QgsExpressionContext& context = QgsExpressionContext() );
QSet<QString> referencedColumns( const QgsExpressionContext& context = QgsExpressionContext() );
/**
* Get the field which this QgsDataDefined represents. Be aware that this may return

View File

@ -80,7 +80,7 @@ class QgsDataDefinedPrivate : public QSharedData
QString field;
bool expressionPrepared;
QStringList exprRefColumns;
QSet<QString> exprRefColumns;
};
/// @endcond

View File

@ -3427,43 +3427,43 @@ const QList<QgsExpression::Function*>& QgsExpression::Functions()
<< new StaticFunction( "scale_exp", 6, fcnExpScale, "Math" )
<< new StaticFunction( "floor", 1, fcnFloor, "Math" )
<< new StaticFunction( "ceil", 1, fcnCeil, "Math" )
<< new StaticFunction( "pi", 0, fcnPi, "Math", QString(), false, QStringList(), false, QStringList() << "$pi" )
<< new StaticFunction( "to_int", 1, fcnToInt, "Conversions", QString(), false, QStringList(), false, QStringList() << "toint" )
<< new StaticFunction( "to_real", 1, fcnToReal, "Conversions", QString(), false, QStringList(), false, QStringList() << "toreal" )
<< new StaticFunction( "to_string", 1, fcnToString, "Conversions", QString(), false, QStringList(), false, QStringList() << "tostring" )
<< new StaticFunction( "to_datetime", 1, fcnToDateTime, "Conversions", QString(), false, QStringList(), false, QStringList() << "todatetime" )
<< new StaticFunction( "to_date", 1, fcnToDate, "Conversions", QString(), false, QStringList(), false, QStringList() << "todate" )
<< new StaticFunction( "to_time", 1, fcnToTime, "Conversions", QString(), false, QStringList(), false, QStringList() << "totime" )
<< new StaticFunction( "to_interval", 1, fcnToInterval, "Conversions", QString(), false, QStringList(), false, QStringList() << "tointerval" )
<< new StaticFunction( "coalesce", -1, fcnCoalesce, "Conditionals", QString(), false, QStringList(), false, QStringList(), true )
<< new StaticFunction( "if", 3, fcnIf, "Conditionals", QString(), False, QStringList(), true )
<< new StaticFunction( "pi", 0, fcnPi, "Math", QString(), false, QSet<QString>(), false, QStringList() << "$pi" )
<< new StaticFunction( "to_int", 1, fcnToInt, "Conversions", QString(), false, QSet<QString>(), false, QStringList() << "toint" )
<< new StaticFunction( "to_real", 1, fcnToReal, "Conversions", QString(), false, QSet<QString>(), false, QStringList() << "toreal" )
<< new StaticFunction( "to_string", 1, fcnToString, "Conversions", QString(), false, QSet<QString>(), false, QStringList() << "tostring" )
<< new StaticFunction( "to_datetime", 1, fcnToDateTime, "Conversions", QString(), false, QSet<QString>(), false, QStringList() << "todatetime" )
<< new StaticFunction( "to_date", 1, fcnToDate, "Conversions", QString(), false, QSet<QString>(), false, QStringList() << "todate" )
<< new StaticFunction( "to_time", 1, fcnToTime, "Conversions", QString(), false, QSet<QString>(), false, QStringList() << "totime" )
<< new StaticFunction( "to_interval", 1, fcnToInterval, "Conversions", QString(), false, QSet<QString>(), false, QStringList() << "tointerval" )
<< new StaticFunction( "coalesce", -1, fcnCoalesce, "Conditionals", QString(), false, QSet<QString>(), false, QStringList(), true )
<< new StaticFunction( "if", 3, fcnIf, "Conditionals", QString(), False, QSet<QString>(), true )
<< new StaticFunction( "aggregate", ParameterList() << Parameter( "layer" ) << Parameter( "aggregate" ) << Parameter( "expression" )
<< Parameter( "filter", true ) << Parameter( "concatenator", true ), fcnAggregate, "Aggregates", QString(), false, QStringList(), true )
<< Parameter( "filter", true ) << Parameter( "concatenator", true ), fcnAggregate, "Aggregates", QString(), false, QSet<QString>(), true )
<< new StaticFunction( "relation_aggregate", ParameterList() << Parameter( "relation" ) << Parameter( "aggregate" ) << Parameter( "expression" ) << Parameter( "concatenator", true ),
fcnAggregateRelation, "Aggregates", QString(), False, QStringList( QgsFeatureRequest::AllAttributes ), true )
fcnAggregateRelation, "Aggregates", QString(), False, QSet<QString>() << QgsFeatureRequest::AllAttributes, true )
<< new StaticFunction( "count", aggParams, fcnAggregateCount, "Aggregates", QString(), False, QStringList(), true )
<< new StaticFunction( "count_distinct", aggParams, fcnAggregateCountDistinct, "Aggregates", QString(), False, QStringList(), true )
<< new StaticFunction( "count_missing", aggParams, fcnAggregateCountMissing, "Aggregates", QString(), False, QStringList(), true )
<< new StaticFunction( "minimum", aggParams, fcnAggregateMin, "Aggregates", QString(), False, QStringList(), true )
<< new StaticFunction( "maximum", aggParams, fcnAggregateMax, "Aggregates", QString(), False, QStringList(), true )
<< new StaticFunction( "sum", aggParams, fcnAggregateSum, "Aggregates", QString(), False, QStringList(), true )
<< new StaticFunction( "mean", aggParams, fcnAggregateMean, "Aggregates", QString(), False, QStringList(), true )
<< new StaticFunction( "median", aggParams, fcnAggregateMedian, "Aggregates", QString(), False, QStringList(), true )
<< new StaticFunction( "stdev", aggParams, fcnAggregateStdev, "Aggregates", QString(), False, QStringList(), true )
<< new StaticFunction( "range", aggParams, fcnAggregateRange, "Aggregates", QString(), False, QStringList(), true )
<< new StaticFunction( "minority", aggParams, fcnAggregateMinority, "Aggregates", QString(), False, QStringList(), true )
<< new StaticFunction( "majority", aggParams, fcnAggregateMajority, "Aggregates", QString(), False, QStringList(), true )
<< new StaticFunction( "q1", aggParams, fcnAggregateQ1, "Aggregates", QString(), False, QStringList(), true )
<< new StaticFunction( "q3", aggParams, fcnAggregateQ3, "Aggregates", QString(), False, QStringList(), true )
<< new StaticFunction( "iqr", aggParams, fcnAggregateIQR, "Aggregates", QString(), False, QStringList(), true )
<< new StaticFunction( "min_length", aggParams, fcnAggregateMinLength, "Aggregates", QString(), False, QStringList(), true )
<< new StaticFunction( "max_length", aggParams, fcnAggregateMaxLength, "Aggregates", QString(), False, QStringList(), true )
<< new StaticFunction( "collect", aggParams, fcnAggregateCollectGeometry, "Aggregates", QString(), False, QStringList(), true )
<< new StaticFunction( "concatenate", aggParams << Parameter( "concatenator", true ), fcnAggregateStringConcat, "Aggregates", QString(), False, QStringList(), true )
<< new StaticFunction( "count", aggParams, fcnAggregateCount, "Aggregates", QString(), False, QSet<QString>(), true )
<< new StaticFunction( "count_distinct", aggParams, fcnAggregateCountDistinct, "Aggregates", QString(), False, QSet<QString>(), true )
<< new StaticFunction( "count_missing", aggParams, fcnAggregateCountMissing, "Aggregates", QString(), False, QSet<QString>(), true )
<< new StaticFunction( "minimum", aggParams, fcnAggregateMin, "Aggregates", QString(), False, QSet<QString>(), true )
<< new StaticFunction( "maximum", aggParams, fcnAggregateMax, "Aggregates", QString(), False, QSet<QString>(), true )
<< new StaticFunction( "sum", aggParams, fcnAggregateSum, "Aggregates", QString(), False, QSet<QString>(), true )
<< new StaticFunction( "mean", aggParams, fcnAggregateMean, "Aggregates", QString(), False, QSet<QString>(), true )
<< new StaticFunction( "median", aggParams, fcnAggregateMedian, "Aggregates", QString(), False, QSet<QString>(), true )
<< new StaticFunction( "stdev", aggParams, fcnAggregateStdev, "Aggregates", QString(), False, QSet<QString>(), true )
<< new StaticFunction( "range", aggParams, fcnAggregateRange, "Aggregates", QString(), False, QSet<QString>(), true )
<< new StaticFunction( "minority", aggParams, fcnAggregateMinority, "Aggregates", QString(), False, QSet<QString>(), true )
<< new StaticFunction( "majority", aggParams, fcnAggregateMajority, "Aggregates", QString(), False, QSet<QString>(), true )
<< new StaticFunction( "q1", aggParams, fcnAggregateQ1, "Aggregates", QString(), False, QSet<QString>(), true )
<< new StaticFunction( "q3", aggParams, fcnAggregateQ3, "Aggregates", QString(), False, QSet<QString>(), true )
<< new StaticFunction( "iqr", aggParams, fcnAggregateIQR, "Aggregates", QString(), False, QSet<QString>(), true )
<< new StaticFunction( "min_length", aggParams, fcnAggregateMinLength, "Aggregates", QString(), False, QSet<QString>(), true )
<< new StaticFunction( "max_length", aggParams, fcnAggregateMaxLength, "Aggregates", QString(), False, QSet<QString>(), true )
<< new StaticFunction( "collect", aggParams, fcnAggregateCollectGeometry, "Aggregates", QString(), False, QSet<QString>(), true )
<< new StaticFunction( "concatenate", aggParams << Parameter( "concatenator", true ), fcnAggregateStringConcat, "Aggregates", QString(), False, QSet<QString>(), true )
<< new StaticFunction( "regexp_match", 2, fcnRegexpMatch, "Conditionals" )
<< new StaticFunction( "now", 0, fcnNow, "Date and Time", QString(), false, QStringList(), false, QStringList() << "$now" )
<< new StaticFunction( "now", 0, fcnNow, "Date and Time", QString(), false, QSet<QString>(), false, QStringList() << "$now" )
<< new StaticFunction( "age", 2, fcnAge, "Date and Time" )
<< new StaticFunction( "year", 1, fcnYear, "Date and Time" )
<< new StaticFunction( "month", 1, fcnMonth, "Date and Time" )
@ -3488,7 +3488,7 @@ const QList<QgsExpression::Function*>& QgsExpression::Functions()
<< new StaticFunction( "regexp_replace", 3, fcnRegexpReplace, "String" )
<< new StaticFunction( "regexp_substr", 2, fcnRegexpSubstr, "String" )
<< new StaticFunction( "substr", 3, fcnSubstr, "String" )
<< new StaticFunction( "concat", -1, fcnConcat, "String", QString(), false, QStringList(), false, QStringList(), true )
<< new StaticFunction( "concat", -1, fcnConcat, "String", QString(), false, QSet<QString>(), false, QStringList(), true )
<< new StaticFunction( "strpos", 2, fcnStrpos, "String" )
<< new StaticFunction( "left", 2, fcnLeft, "String" )
<< new StaticFunction( "right", 2, fcnRight, "String" )
@ -3531,16 +3531,16 @@ const QList<QgsExpression::Function*>& QgsExpression::Functions()
<< new StaticFunction( "make_point_m", 3, fcnMakePointM, "GeometryGroup" )
<< new StaticFunction( "make_line", -1, fcnMakeLine, "GeometryGroup" )
<< new StaticFunction( "make_polygon", -1, fcnMakePolygon, "GeometryGroup" )
<< new StaticFunction( "$x_at", 1, fcnXat, "GeometryGroup", QString(), true, QStringList(), false, QStringList() << "xat" << "x_at" )
<< new StaticFunction( "$y_at", 1, fcnYat, "GeometryGroup", QString(), true, QStringList(), false, QStringList() << "yat" << "y_at" )
<< new StaticFunction( "x_min", 1, fcnXMin, "GeometryGroup", QString(), false, QStringList(), false, QStringList() << "xmin" )
<< new StaticFunction( "x_max", 1, fcnXMax, "GeometryGroup", QString(), false, QStringList(), false, QStringList() << "xmax" )
<< new StaticFunction( "y_min", 1, fcnYMin, "GeometryGroup", QString(), false, QStringList(), false, QStringList() << "ymin" )
<< new StaticFunction( "y_max", 1, fcnYMax, "GeometryGroup", QString(), false, QStringList(), false, QStringList() << "ymax" )
<< new StaticFunction( "geom_from_wkt", 1, fcnGeomFromWKT, "GeometryGroup", QString(), false, QStringList(), false, QStringList() << "geomFromWKT" )
<< new StaticFunction( "geom_from_gml", 1, fcnGeomFromGML, "GeometryGroup", QString(), false, QStringList(), false, QStringList() << "geomFromGML" )
<< new StaticFunction( "$x_at", 1, fcnXat, "GeometryGroup", QString(), true, QSet<QString>(), false, QStringList() << "xat" << "x_at" )
<< new StaticFunction( "$y_at", 1, fcnYat, "GeometryGroup", QString(), true, QSet<QString>(), false, QStringList() << "yat" << "y_at" )
<< new StaticFunction( "x_min", 1, fcnXMin, "GeometryGroup", QString(), false, QSet<QString>(), false, QStringList() << "xmin" )
<< new StaticFunction( "x_max", 1, fcnXMax, "GeometryGroup", QString(), false, QSet<QString>(), false, QStringList() << "xmax" )
<< new StaticFunction( "y_min", 1, fcnYMin, "GeometryGroup", QString(), false, QSet<QString>(), false, QStringList() << "ymin" )
<< new StaticFunction( "y_max", 1, fcnYMax, "GeometryGroup", QString(), false, QSet<QString>(), false, QStringList() << "ymax" )
<< new StaticFunction( "geom_from_wkt", 1, fcnGeomFromWKT, "GeometryGroup", QString(), false, QSet<QString>(), false, QStringList() << "geomFromWKT" )
<< new StaticFunction( "geom_from_gml", 1, fcnGeomFromGML, "GeometryGroup", QString(), false, QSet<QString>(), false, QStringList() << "geomFromGML" )
<< new StaticFunction( "relate", -1, fcnRelate, "GeometryGroup" )
<< new StaticFunction( "intersects_bbox", 2, fcnBbox, "GeometryGroup", QString(), false, QStringList(), false, QStringList() << "bbox" )
<< new StaticFunction( "intersects_bbox", 2, fcnBbox, "GeometryGroup", QString(), false, QSet<QString>(), false, QStringList() << "bbox" )
<< new StaticFunction( "disjoint", 2, fcnDisjoint, "GeometryGroup" )
<< new StaticFunction( "intersects", 2, fcnIntersects, "GeometryGroup" )
<< new StaticFunction( "touches", 2, fcnTouches, "GeometryGroup" )
@ -3584,14 +3584,14 @@ const QList<QgsExpression::Function*>& QgsExpression::Functions()
<< new StaticFunction( "bounds_width", 1, fcnBoundsWidth, "GeometryGroup" )
<< new StaticFunction( "bounds_height", 1, fcnBoundsHeight, "GeometryGroup" )
<< new StaticFunction( "is_closed", 1, fcnIsClosed, "GeometryGroup" )
<< new StaticFunction( "convex_hull", 1, fcnConvexHull, "GeometryGroup", QString(), false, QStringList(), false, QStringList() << "convexHull" )
<< new StaticFunction( "convex_hull", 1, fcnConvexHull, "GeometryGroup", QString(), false, QSet<QString>(), false, QStringList() << "convexHull" )
<< new StaticFunction( "difference", 2, fcnDifference, "GeometryGroup" )
<< new StaticFunction( "distance", 2, fcnDistance, "GeometryGroup" )
<< new StaticFunction( "intersection", 2, fcnIntersection, "GeometryGroup" )
<< new StaticFunction( "sym_difference", 2, fcnSymDifference, "GeometryGroup", QString(), false, QStringList(), false, QStringList() << "symDifference" )
<< new StaticFunction( "sym_difference", 2, fcnSymDifference, "GeometryGroup", QString(), false, QSet<QString>(), false, QStringList() << "symDifference" )
<< new StaticFunction( "combine", 2, fcnCombine, "GeometryGroup" )
<< new StaticFunction( "union", 2, fcnCombine, "GeometryGroup" )
<< new StaticFunction( "geom_to_wkt", -1, fcnGeomToWKT, "GeometryGroup", QString(), false, QStringList(), false, QStringList() << "geomToWKT" )
<< new StaticFunction( "geom_to_wkt", -1, fcnGeomToWKT, "GeometryGroup", QString(), false, QSet<QString>(), false, QStringList() << "geomToWKT" )
<< new StaticFunction( "geometry", 1, fcnGetGeometry, "GeometryGroup", QString(), true )
<< new StaticFunction( "transform", 3, fcnTransformGeometry, "GeometryGroup" )
<< new StaticFunction( "extrude", 3, fcnExtrude, "GeometryGroup", QString() )
@ -3610,16 +3610,16 @@ const QList<QgsExpression::Function*>& QgsExpression::Functions()
<< Parameter( "vertex" ), fcnDistanceToVertex, "GeometryGroup" )
<< new StaticFunction( "$id", 0, fcnFeatureId, "Record" )
<< new StaticFunction( "$currentfeature", 0, fcnFeature, "Record" )
<< new StaticFunction( "uuid", 0, fcnUuid, "Record", QString(), false, QStringList(), false, QStringList() << "$uuid" )
<< new StaticFunction( "get_feature", 3, fcnGetFeature, "Record", QString(), false, QStringList(), false, QStringList() << "getFeature" )
<< new StaticFunction( "uuid", 0, fcnUuid, "Record", QString(), false, QSet<QString>(), false, QStringList() << "$uuid" )
<< new StaticFunction( "get_feature", 3, fcnGetFeature, "Record", QString(), false, QSet<QString>(), false, QStringList() << "getFeature" )
<< new StaticFunction( "layer_property", 2, fcnGetLayerProperty, "General" )
<< new StaticFunction( "var", 1, fcnGetVariable, "General" )
//return all attributes string for referencedColumns - this is caught by
// QgsFeatureRequest::setSubsetOfAttributes and causes all attributes to be fetched by the
// feature request
<< new StaticFunction( "eval", 1, fcnEval, "General", QString(), true, QStringList( QgsFeatureRequest::AllAttributes ) )
<< new StaticFunction( "attribute", 2, fcnAttribute, "Record", QString(), false, QStringList( QgsFeatureRequest::AllAttributes ) )
<< new StaticFunction( "eval", 1, fcnEval, "General", QString(), true, QSet<QString>() << QgsFeatureRequest::AllAttributes )
<< new StaticFunction( "attribute", 2, fcnAttribute, "Record", QString(), false, QSet<QString>() << QgsFeatureRequest::AllAttributes )
// functions for arrays
<< new StaticFunction( "array", -1, fcnArray, "Arrays" )
@ -3800,28 +3800,20 @@ bool QgsExpression::hasParserError() const { return !d->mParserErrorString.isNul
QString QgsExpression::parserErrorString() const { return d->mParserErrorString; }
QStringList QgsExpression::referencedColumns() const
QSet<QString> QgsExpression::referencedColumns() const
{
if ( !d->mRootNode )
return QStringList();
return QSet<QString>();
QStringList columns = d->mRootNode->referencedColumns();
return d->mRootNode->referencedColumns();
}
// filter out duplicates
for ( int i = 0; i < columns.count(); i++ )
{
QString col = columns.at( i );
for ( int j = i + 1; j < columns.count(); j++ )
{
if ( QString::compare( col, columns[j], Qt::CaseInsensitive ) == 0 )
{
// this column is repeated: remove it!
columns.removeAt( j-- );
}
}
}
return columns;
bool QgsExpression::NodeInOperator::needsGeometry() const
{
bool needs = false;
Q_FOREACH ( Node* n, mList->list() )
needs |= n->needsGeometry();
return needs;
}
QSet<int> QgsExpression::referencedAttributeIndexes( const QgsFields& fields ) const
@ -3829,10 +3821,10 @@ QSet<int> QgsExpression::referencedAttributeIndexes( const QgsFields& fields ) c
if ( !d->mRootNode )
return QSet<int>();
QStringList referencedFields = d->mRootNode->referencedColumns();
const QSet<QString> referencedFields = d->mRootNode->referencedColumns();
QSet<int> referencedIndexes;
Q_FOREACH ( const QString& fieldName, referencedFields )
for ( const QString& fieldName : referencedFields )
{
if ( fieldName == QgsFeatureRequest::AllAttributes )
{
@ -4056,6 +4048,13 @@ double QgsExpression::evaluateToDouble( const QString &text, const double fallba
///////////////////////////////////////////////
// nodes
void QgsExpression::NodeList::append( QgsExpression::NamedNode* node )
{
mList.append( node->node );
mNameList.append( node->name.toLower() );
mHasNamedNodes = true;
}
QgsExpression::NodeList* QgsExpression::NodeList::clone() const
{
NodeList* nl = new NodeList;
@ -4603,6 +4602,16 @@ QString QgsExpression::NodeBinaryOperator::dump() const
return fmt.arg( mOpLeft->dump(), BinaryOperatorText[mOp], rdump );
}
QSet<QString> QgsExpression::NodeBinaryOperator::referencedColumns() const
{
return mOpLeft->referencedColumns() + mOpRight->referencedColumns();
}
bool QgsExpression::NodeBinaryOperator::needsGeometry() const
{
return mOpLeft->needsGeometry() || mOpRight->needsGeometry();
}
QgsExpression::Node* QgsExpression::NodeBinaryOperator::clone() const
{
return new NodeBinaryOperator( mOp, mOpLeft->clone(), mOpRight->clone() );
@ -4718,6 +4727,46 @@ QVariant QgsExpression::NodeFunction::eval( QgsExpression *parent, const QgsExpr
return res;
}
QgsExpression::NodeFunction::NodeFunction( int fnIndex, QgsExpression::NodeList* args )
: mFnIndex( fnIndex )
{
const ParameterList& functionParams = Functions()[mFnIndex]->parameters();
if ( !args || functionParams.isEmpty() )
{
// no parameters, or function does not support them
mArgs = args;
}
else
{
mArgs = new NodeList();
int idx = 0;
//first loop through unnamed arguments
while ( idx < args->names().size() && args->names().at( idx ).isEmpty() )
{
mArgs->append( args->list().at( idx )->clone() );
idx++;
}
//next copy named parameters in order expected by function
for ( ; idx < functionParams.count(); ++idx )
{
int nodeIdx = args->names().indexOf( functionParams.at( idx ).name().toLower() );
if ( nodeIdx < 0 )
{
//parameter not found - insert default value for parameter
mArgs->append( new NodeLiteral( functionParams.at( idx ).defaultValue() ) );
}
else
{
mArgs->append( args->list().at( nodeIdx )->clone() );
}
}
delete args;
}
}
bool QgsExpression::NodeFunction::prepare( QgsExpression *parent, const QgsExpressionContext *context )
{
Function* fd = Functions()[mFnIndex];
@ -4742,10 +4791,10 @@ QString QgsExpression::NodeFunction::dump() const
return QString( "%1(%2)" ).arg( fd->name(), mArgs ? mArgs->dump() : QString() ); // function
}
QStringList QgsExpression::NodeFunction::referencedColumns() const
QSet<QString> QgsExpression::NodeFunction::referencedColumns() const
{
Function* fd = Functions()[mFnIndex];
QStringList functionColumns = fd->referencedColumns();
QSet<QString> functionColumns = fd->referencedColumns();
if ( !mArgs )
{
@ -4755,11 +4804,21 @@ QStringList QgsExpression::NodeFunction::referencedColumns() const
Q_FOREACH ( Node* n, mArgs->list() )
{
functionColumns.append( n->referencedColumns() );
functionColumns.unite( n->referencedColumns() );
}
//remove duplicates and return
return functionColumns.toSet().toList();
return functionColumns;
}
bool QgsExpression::NodeFunction::needsGeometry() const
{
bool needs = Functions()[mFnIndex]->usesGeometry();
if ( mArgs )
{
Q_FOREACH ( Node* n, mArgs->list() )
needs |= n->needsGeometry();
}
return needs;
}
QgsExpression::Node* QgsExpression::NodeFunction::clone() const
@ -4767,6 +4826,79 @@ QgsExpression::Node* QgsExpression::NodeFunction::clone() const
return new NodeFunction( mFnIndex, mArgs ? mArgs->clone() : nullptr );
}
bool QgsExpression::NodeFunction::validateParams( int fnIndex, QgsExpression::NodeList* args, QString& error )
{
if ( !args || !args->hasNamedNodes() )
return true;
const ParameterList& functionParams = Functions()[fnIndex]->parameters();
if ( functionParams.isEmpty() )
{
error = QString( "%1 does not supported named parameters" ).arg( Functions()[fnIndex]->name() );
return false;
}
else
{
QSet< int > providedArgs;
QSet< int > handledArgs;
int idx = 0;
//first loop through unnamed arguments
while ( args->names().at( idx ).isEmpty() )
{
providedArgs << idx;
handledArgs << idx;
idx++;
}
//next check named parameters
for ( ; idx < functionParams.count(); ++idx )
{
int nodeIdx = args->names().indexOf( functionParams.at( idx ).name().toLower() );
if ( nodeIdx < 0 )
{
if ( !functionParams.at( idx ).optional() )
{
error = QString( "No value specified for parameter '%1' for %2" ).arg( functionParams.at( idx ).name(), Functions()[fnIndex]->name() );
return false;
}
}
else
{
if ( providedArgs.contains( idx ) )
{
error = QString( "Duplicate parameter specified for '%1' for %2" ).arg( functionParams.at( idx ).name(), Functions()[fnIndex]->name() );
return false;
}
}
providedArgs << idx;
handledArgs << nodeIdx;
}
//last check for bad names
idx = 0;
Q_FOREACH ( const QString& name, args->names() )
{
if ( !name.isEmpty() && !functionParams.contains( name ) )
{
error = QString( "Invalid parameter name '%1' for %2" ).arg( name, Functions()[fnIndex]->name() );
return false;
}
if ( !name.isEmpty() && !handledArgs.contains( idx ) )
{
int functionIdx = functionParams.indexOf( name );
if ( providedArgs.contains( functionIdx ) )
{
error = QString( "Duplicate parameter specified for '%1' for %2" ).arg( functionParams.at( functionIdx ).name(), Functions()[fnIndex]->name() );
return false;
}
}
idx++;
}
}
return true;
}
//
QVariant QgsExpression::NodeLiteral::eval( QgsExpression *parent, const QgsExpressionContext *context )
@ -4924,9 +5056,9 @@ QString QgsExpression::NodeCondition::dump() const
return msg;
}
QStringList QgsExpression::NodeCondition::referencedColumns() const
QSet<QString> QgsExpression::NodeCondition::referencedColumns() const
{
QStringList lst;
QSet<QString> lst;
Q_FOREACH ( WhenThen* cond, mConditions )
{
lst += cond->mWhenExp->referencedColumns() + cond->mThenExp->referencedColumns();
@ -5294,3 +5426,19 @@ const QgsExpression::Node* QgsExpression::rootNode() const
{
return d->mRootNode;
}
QSet<QString> QgsExpression::NodeInOperator::referencedColumns() const
{
QSet<QString> lst( mNode->referencedColumns() );
Q_FOREACH ( const Node* n, mList->list() )
lst.unite( n->referencedColumns() );
return lst;
}
bool QgsExpression::Function::operator==( const QgsExpression::Function& other ) const
{
if ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 )
return true;
return false;
}

View File

@ -183,7 +183,7 @@ class CORE_EXPORT QgsExpression
*
* TODO QGIS3: Return QSet<QString>
*/
QStringList referencedColumns() const;
QSet<QString> referencedColumns() const;
/**
* Return a list of field name indexes obtained from the provided fields.
@ -451,7 +451,7 @@ class CORE_EXPORT QgsExpression
const QString& group,
const QString& helpText = QString(),
bool usesGeometry = false,
const QStringList& referencedColumns = QStringList(),
const QSet<QString>& referencedColumns = QSet<QString>(),
bool lazyEval = false,
bool handlesNull = false,
bool isContextual = false )
@ -475,7 +475,7 @@ class CORE_EXPORT QgsExpression
const QString& group,
const QString& helpText = QString(),
bool usesGeometry = false,
const QStringList& referencedColumns = QStringList(),
const QSet<QString>& referencedColumns = QSet<QString>(),
bool lazyEval = false,
bool handlesNull = false,
bool isContextual = false )
@ -534,7 +534,7 @@ class CORE_EXPORT QgsExpression
* Functions are non lazy default and will be given the node return value when called **/
bool lazyEval() const { return mLazyEval; }
virtual QStringList referencedColumns() const { return mReferencedColumns; }
virtual QSet<QString> referencedColumns() const { return mReferencedColumns; }
/** Returns whether the function is only available if provided by a QgsExpressionContext object.
* @note added in QGIS 2.12
@ -555,13 +555,7 @@ class CORE_EXPORT QgsExpression
*/
virtual QVariant func( const QVariantList& values, const QgsExpressionContext* context, QgsExpression* parent ) = 0;
bool operator==( const Function& other ) const
{
if ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 )
return true;
return false;
}
bool operator==( const Function& other ) const;
virtual bool handlesNull() const { return mHandlesNull; }
@ -572,7 +566,7 @@ class CORE_EXPORT QgsExpression
bool mUsesGeometry;
QString mGroup;
QString mHelpText;
QStringList mReferencedColumns;
QSet<QString> mReferencedColumns;
bool mLazyEval;
bool mHandlesNull;
bool mIsContextual; //if true function is only available through an expression context
@ -594,7 +588,7 @@ class CORE_EXPORT QgsExpression
const QString& group,
const QString& helpText = QString(),
bool usesGeometry = false,
const QStringList& referencedColumns = QStringList(),
const QSet<QString>& referencedColumns = QSet<QString>(),
bool lazyEval = false,
const QStringList& aliases = QStringList(),
bool handlesNull = false )
@ -611,7 +605,7 @@ class CORE_EXPORT QgsExpression
const QString& group,
const QString& helpText = QString(),
bool usesGeometry = false,
const QStringList& referencedColumns = QStringList(),
const QSet<QString>& referencedColumns = QSet<QString>(),
bool lazyEval = false,
const QStringList& aliases = QStringList(),
bool handlesNull = false )
@ -781,7 +775,7 @@ class CORE_EXPORT QgsExpression
*
* @return A list of columns required to evaluate this expression
*/
virtual QStringList referencedColumns() const = 0;
virtual QSet<QString> referencedColumns() const = 0;
/**
* Abstract virtual method which returns if the geometry is required to evaluate
@ -830,7 +824,7 @@ class CORE_EXPORT QgsExpression
/** Adds a named node. Takes ownership of the provided node.
* @note added in QGIS 2.16
*/
void append( NamedNode* node ) { mList.append( node->node ); mNameList.append( node->name.toLower() ); mHasNamedNodes = true; }
void append( NamedNode* node );
/** Returns the number of nodes in the list.
*/
@ -879,7 +873,7 @@ class CORE_EXPORT QgsExpression
virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
virtual QString dump() const override;
virtual QStringList referencedColumns() const override { return mOperand->referencedColumns(); }
virtual QSet<QString> referencedColumns() const override { return mOperand->referencedColumns(); }
virtual bool needsGeometry() const override { return mOperand->needsGeometry(); }
virtual Node* clone() const override;
@ -909,8 +903,8 @@ class CORE_EXPORT QgsExpression
virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
virtual QString dump() const override;
virtual QStringList referencedColumns() const override { return mOpLeft->referencedColumns() + mOpRight->referencedColumns(); }
virtual bool needsGeometry() const override { return mOpLeft->needsGeometry() || mOpRight->needsGeometry(); }
virtual QSet<QString> referencedColumns() const override;
virtual bool needsGeometry() const override;
virtual Node* clone() const override;
int precedence() const;
@ -953,8 +947,8 @@ class CORE_EXPORT QgsExpression
virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
virtual QString dump() const override;
virtual QStringList referencedColumns() const override { QStringList lst( mNode->referencedColumns() ); Q_FOREACH ( const Node* n, mList->list() ) lst.append( n->referencedColumns() ); return lst; }
virtual bool needsGeometry() const override { bool needs = false; Q_FOREACH ( Node* n, mList->list() ) needs |= n->needsGeometry(); return needs; }
virtual QSet<QString> referencedColumns() const override;
virtual bool needsGeometry() const override;
virtual Node* clone() const override;
protected:
@ -968,44 +962,7 @@ class CORE_EXPORT QgsExpression
class CORE_EXPORT NodeFunction : public Node
{
public:
NodeFunction( int fnIndex, NodeList* args ) : mFnIndex( fnIndex )
{
const ParameterList& functionParams = Functions()[mFnIndex]->parameters();
if ( !args || functionParams.isEmpty() )
{
// no parameters, or function does not support them
mArgs = args;
}
else
{
mArgs = new NodeList();
int idx = 0;
//first loop through unnamed arguments
while ( idx < args->names().size() && args->names().at( idx ).isEmpty() )
{
mArgs->append( args->list().at( idx )->clone() );
idx++;
}
//next copy named parameters in order expected by function
for ( ; idx < functionParams.count(); ++idx )
{
int nodeIdx = args->names().indexOf( functionParams.at( idx ).name().toLower() );
if ( nodeIdx < 0 )
{
//parameter not found - insert default value for parameter
mArgs->append( new NodeLiteral( functionParams.at( idx ).defaultValue() ) );
}
else
{
mArgs->append( args->list().at( nodeIdx )->clone() );
}
}
delete args;
}
}
NodeFunction( int fnIndex, NodeList* args );
virtual ~NodeFunction() { delete mArgs; }
@ -1017,83 +974,12 @@ class CORE_EXPORT QgsExpression
virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
virtual QString dump() const override;
virtual QStringList referencedColumns() const override;
virtual bool needsGeometry() const override { bool needs = Functions()[mFnIndex]->usesGeometry(); if ( mArgs ) { Q_FOREACH ( Node* n, mArgs->list() ) needs |= n->needsGeometry(); } return needs; }
virtual QSet<QString> referencedColumns() const override;
virtual bool needsGeometry() const override;
virtual Node* clone() const override;
//! Tests whether the provided argument list is valid for the matching function
static bool validateParams( int fnIndex, NodeList* args, QString& error )
{
if ( !args || !args->hasNamedNodes() )
return true;
const ParameterList& functionParams = Functions()[fnIndex]->parameters();
if ( functionParams.isEmpty() )
{
error = QString( "%1 does not supported named parameters" ).arg( Functions()[fnIndex]->name() );
return false;
}
else
{
QSet< int > providedArgs;
QSet< int > handledArgs;
int idx = 0;
//first loop through unnamed arguments
while ( args->names().at( idx ).isEmpty() )
{
providedArgs << idx;
handledArgs << idx;
idx++;
}
//next check named parameters
for ( ; idx < functionParams.count(); ++idx )
{
int nodeIdx = args->names().indexOf( functionParams.at( idx ).name().toLower() );
if ( nodeIdx < 0 )
{
if ( !functionParams.at( idx ).optional() )
{
error = QString( "No value specified for parameter '%1' for %2" ).arg( functionParams.at( idx ).name(), Functions()[fnIndex]->name() );
return false;
}
}
else
{
if ( providedArgs.contains( idx ) )
{
error = QString( "Duplicate parameter specified for '%1' for %2" ).arg( functionParams.at( idx ).name(), Functions()[fnIndex]->name() );
return false;
}
}
providedArgs << idx;
handledArgs << nodeIdx;
}
//last check for bad names
idx = 0;
Q_FOREACH ( const QString& name, args->names() )
{
if ( !name.isEmpty() && !functionParams.contains( name ) )
{
error = QString( "Invalid parameter name '%1' for %2" ).arg( name, Functions()[fnIndex]->name() );
return false;
}
if ( !name.isEmpty() && !handledArgs.contains( idx ) )
{
int functionIdx = functionParams.indexOf( name );
if ( providedArgs.contains( functionIdx ) )
{
error = QString( "Duplicate parameter specified for '%1' for %2" ).arg( functionParams.at( functionIdx ).name(), Functions()[fnIndex]->name() );
return false;
}
}
idx++;
}
}
return true;
}
static bool validateParams( int fnIndex, NodeList* args, QString& error );
protected:
int mFnIndex;
@ -1118,7 +1004,7 @@ class CORE_EXPORT QgsExpression
virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
virtual QString dump() const override;
virtual QStringList referencedColumns() const override { return QStringList(); }
virtual QSet<QString> referencedColumns() const override { return QSet<QString>(); }
virtual bool needsGeometry() const override { return false; }
virtual Node* clone() const override;
@ -1144,7 +1030,7 @@ class CORE_EXPORT QgsExpression
virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
virtual QString dump() const override;
virtual QStringList referencedColumns() const override { return QStringList( mName ); }
virtual QSet<QString> referencedColumns() const override { return QSet<QString>() << mName; }
virtual bool needsGeometry() const override { return false; }
virtual Node* clone() const override;
@ -1195,7 +1081,7 @@ class CORE_EXPORT QgsExpression
virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
virtual QString dump() const override;
virtual QStringList referencedColumns() const override;
virtual QSet<QString> referencedColumns() const override;
virtual bool needsGeometry() const override;
virtual Node* clone() const override;
@ -1333,6 +1219,8 @@ class CORE_EXPORT QgsExpression
friend class QgsOgcUtils;
};
Q_DECLARE_METATYPE( QgsExpression::Node* )
#endif // QGSEXPRESSION_H

View File

@ -41,12 +41,17 @@ class QgsSymbol;
class CORE_EXPORT QgsScopedExpressionFunction : public QgsExpression::Function
{
public:
/**
* Create a new QgsScopedExpressionFunction
*
* @note Added in QGIS 2.12
*/
QgsScopedExpressionFunction( const QString& fnname,
int params,
const QString& group,
const QString& helpText = QString(),
bool usesGeometry = false,
const QStringList& referencedColumns = QStringList(),
const QSet<QString>& referencedColumns = QSet<QString>(),
bool lazyEval = false,
bool handlesNull = false,
bool isContextual = true )

View File

@ -33,6 +33,11 @@ void QgsExpressionFieldBuffer::removeExpression( int index )
mExpressions.removeAt( index );
}
void QgsExpressionFieldBuffer::renameExpression( int index, const QString& name )
{
mExpressions[index].field.setName( name );
}
void QgsExpressionFieldBuffer::updateExpression( int index, const QString& exp )
{
mExpressions[index].cachedExpression = QgsExpression( exp );

View File

@ -61,6 +61,16 @@ class CORE_EXPORT QgsExpressionFieldBuffer
*/
void removeExpression( int index );
/**
* Renames an expression field at a given index
*
* @param index The index of the expression to change
* @param name New name for field
*
* @note added in 3.0
*/
void renameExpression( int index, const QString& name );
/**
* Changes the expression at a given index
*

View File

@ -216,6 +216,27 @@ QgsFeatureRequest& QgsFeatureRequest::setSubsetOfAttributes( const QStringList&
return *this;
}
QgsFeatureRequest& QgsFeatureRequest::setSubsetOfAttributes( const QSet<QString>& attrNames, const QgsFields& fields )
{
if ( attrNames.contains( QgsFeatureRequest::AllAttributes ) )
{
//attribute string list contains the all attributes flag, so we must fetch all attributes
return *this;
}
mFlags |= SubsetOfAttributes;
mAttrs.clear();
Q_FOREACH ( const QString& attrName, attrNames )
{
int attrNum = fields.lookupField( attrName );
if ( attrNum != -1 && !mAttrs.contains( attrNum ) )
mAttrs.append( attrNum );
}
return *this;
}
QgsFeatureRequest& QgsFeatureRequest::setSimplifyMethod( const QgsSimplifyMethod& simplifyMethod )
{
mSimplifyMethod = simplifyMethod;
@ -387,7 +408,7 @@ QSet<QString> QgsFeatureRequest::OrderBy::usedAttributes() const
{
const OrderByClause& clause = *it;
usedAttributes.unite( clause.expression().referencedColumns().toSet() );
usedAttributes.unite( clause.expression().referencedColumns() );
}
return usedAttributes;

View File

@ -377,6 +377,9 @@ class CORE_EXPORT QgsFeatureRequest
//! Set a subset of attributes by names that will be fetched
QgsFeatureRequest& setSubsetOfAttributes( const QStringList& attrNames, const QgsFields& fields );
//! Set a subset of attributes by names that will be fetched
QgsFeatureRequest& setSubsetOfAttributes( const QSet<QString>& attrNames, const QgsFields& fields );
//! Set a simplification method for geometries that will be fetched
//! @note added in 2.2
QgsFeatureRequest& setSimplifyMethod( const QgsSimplifyMethod& simplifyMethod );

View File

@ -1666,6 +1666,10 @@ static int binaryOperatorFromTagName( const QString& tagName )
static QString binaryOperatorToTagName( QgsExpression::BinaryOperator op )
{
if ( op == QgsExpression::boILike )
{
return "PropertyIsLike";
}
return binaryOperatorsTagNamesMap().key( op, QString() );
}
@ -1752,6 +1756,11 @@ QgsExpression::NodeBinaryOperator* QgsOgcUtils::nodeBinaryOperatorFromOgcFilter(
return nullptr;
}
if ( op == QgsExpression::boLike && element.hasAttribute( "matchCase" ) && element.attribute( "matchCase" ) == "false" )
{
op = QgsExpression::boILike;
}
QDomElement operandElem = element.firstChildElement();
QgsExpression::Node *expr = nodeFromOgcFilter( operandElem, errorMessage ), *leftOp = expr;
if ( !expr )
@ -1772,6 +1781,64 @@ QgsExpression::NodeBinaryOperator* QgsOgcUtils::nodeBinaryOperatorFromOgcFilter(
return nullptr;
}
if ( op == QgsExpression::boLike || op == QgsExpression::boILike )
{
QString wildCard;
if ( element.hasAttribute( "wildCard" ) )
{
wildCard = element.attribute( "wildCard" );
}
QString singleChar;
if ( element.hasAttribute( "singleChar" ) )
{
singleChar = element.attribute( "singleChar" );
}
QString escape = "\\";
if ( element.hasAttribute( "escape" ) )
{
escape = element.attribute( "escape" );
}
// replace
QString oprValue = static_cast<const QgsExpression::NodeLiteral*>( opRight )->value().toString();
if ( !wildCard.isEmpty() && wildCard != "%" )
{
oprValue.replace( '%', "\\%" );
if ( oprValue.startsWith( wildCard ) )
{
oprValue.replace( 0, 1, "%" );
}
QRegExp rx( "[^" + QRegExp::escape( escape ) + "](" + QRegExp::escape( wildCard ) + ")" );
int pos = 0;
while (( pos = rx.indexIn( oprValue, pos ) ) != -1 )
{
oprValue.replace( pos + 1, 1, "%" );
pos += 1;
}
oprValue.replace( escape + wildCard, wildCard );
}
if ( !singleChar.isEmpty() && singleChar != "_" )
{
oprValue.replace( '_', "\\_" );
if ( oprValue.startsWith( singleChar ) )
{
oprValue.replace( 0, 1, "_" );
}
QRegExp rx( "[^" + QRegExp::escape( escape ) + "](" + QRegExp::escape( singleChar ) + ")" );
int pos = 0;
while (( pos = rx.indexIn( oprValue, pos ) ) != -1 )
{
oprValue.replace( pos + 1, 1, "_" );
pos += 1;
}
oprValue.replace( escape + singleChar, singleChar );
}
if ( !escape.isEmpty() && escape != "\\" )
{
oprValue.replace( escape + escape, escape );
}
opRight = new QgsExpression::NodeLiteral( oprValue );
}
expr = new QgsExpression::NodeBinaryOperator( static_cast< QgsExpression::BinaryOperator >( op ), expr, opRight );
}
@ -2289,13 +2356,13 @@ QDomElement QgsOgcUtilsExprToFilter::expressionBinaryOperatorToOgcFilter( const
if ( op == QgsExpression::boILike )
boElem.setAttribute( "matchCase", "false" );
// setup wildcards to <ogc:PropertyIsLike>
// setup wildCards to <ogc:PropertyIsLike>
boElem.setAttribute( "wildCard", "%" );
boElem.setAttribute( "singleChar", "?" );
boElem.setAttribute( "singleChar", "_" );
if ( mFilterVersion == QgsOgcUtils::FILTER_OGC_1_0 )
boElem.setAttribute( "escape", "!" );
boElem.setAttribute( "escape", "\\" );
else
boElem.setAttribute( "escapeChar", "!" );
boElem.setAttribute( "escapeChar", "\\" );
}
boElem.appendChild( leftElem );
@ -2712,6 +2779,8 @@ QDomElement QgsOgcUtilsSQLStatementToFilter::toOgcFilter( const QgsSQLStatement:
opText = "PropertyIsGreaterThan";
else if ( op == QgsSQLStatement::boLike )
opText = "PropertyIsLike";
else if ( op == QgsSQLStatement::boILike )
opText = "PropertyIsLike";
if ( opText.isEmpty() )
{
@ -2727,13 +2796,13 @@ QDomElement QgsOgcUtilsSQLStatementToFilter::toOgcFilter( const QgsSQLStatement:
if ( op == QgsSQLStatement::boILike )
boElem.setAttribute( "matchCase", "false" );
// setup wildcards to <ogc:PropertyIsLike>
// setup wildCards to <ogc:PropertyIsLike>
boElem.setAttribute( "wildCard", "%" );
boElem.setAttribute( "singleChar", "?" );
boElem.setAttribute( "singleChar", "_" );
if ( mFilterVersion == QgsOgcUtils::FILTER_OGC_1_0 )
boElem.setAttribute( "escape", "!" );
boElem.setAttribute( "escape", "\\" );
else
boElem.setAttribute( "escapeChar", "!" );
boElem.setAttribute( "escapeChar", "\\" );
}
boElem.appendChild( leftElem );

Some files were not shown because too many files have changed in this diff Show More